新規フォームをアクティブにせずに表示するには

解決


yosi  2009-10-03 19:39:48  No: 35811

1つ質問をお願いします。

  Delphi のコード補完ウィンドウのようなものを作ろうと思っています。
  その補完ウィンドウをTFormで作っているのですが、補完ウィンドウを
表示させた後、メインウィンドウにフォーカスを移すという処理を
行うため、画面がちらついてしまいます。
  フォーカスをメインウィンドウに置いたまま、補完ウィンドウを表示
させるにはどうすればよいでしょうか。

※1  補完ウィンドウのFormStyleは、fsStayOnTopに設定しています。
※2  環境はWinXP Home + Delphi6 です。


manbon  2009-10-05 18:50:33  No: 35812

ウィンドウじゃなく、パネルにする。

ウィンドウじゃなく、別アプリにする。

とかの方が簡単にできると思いますが、こういうのはダメでしょうか?


monaa  2009-10-05 20:48:03  No: 35813

ShowWindow + SW_SHOWNOACTIVATE
SetWindowPos + SWP_NOACTIVATE
とかで行けた気がします。
ただし一筋縄ではいかなかったことを記憶してます。
THintWindowを継承させた方が楽な気はしますが。


yosi  2009-10-06 03:33:24  No: 35814

ご回答、どうもありがとうございます。

とりあえず、一番シンプルで分かりやすそうだった
ShowWindow + SW_SHOWNOACTIVATEを試してみました。
処理が無限ループ?に陥ってしまい、「一筋縄ではいかない」
を身をもって実感しました。キーワードが分かりましたので、
一歩前進したような気がします。これから検索して使える処理
がないか試してみます。

manbon様。
実は、最初の頃はそれを考えていました。ただ、エディタの場合、
横に並べた場合、横幅が非常に小さくなるようなことも考えられ、
単語とその単語の属性情報などを表示した場合、画面の右端がみ
えなくなってしまうのではと考え、別ウィンドウにしようとしました。


monaa  2009-10-06 05:14:14  No: 35815

>>処理が無限ループ?に陥ってしまい
いあいあ、そもそもWindowアプリケーションは無限ループです。
直にAPIで表示状態を変更すると、
VCLのShow,Hideのメッセージの流れが変になります。
そのため必要な個所の修正が必要って意味です。
簡単な利用なだけであればさほど問題はありません。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private 宣言 }
    PopForm : TForm;
    btn     : TButton;
    procedure btnClick(Sender: TObject);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnClick(Sender: TObject);
begin
  Timer1.Enabled:=False;
  ShowWindow(PopForm.Handle,SW_HIDE);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetWindowPos(PopForm.Handle,0,Left-100,Top-100,100,100,SWP_SHOWWINDOW or SWP_NOACTIVATE);
  Timer1.Enabled := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Enabled  := False;
  Timer1.Interval := 3000;
  PopForm := TForm.Create(Self);
  PopForm.BorderStyle := bsNone;
  PopForm.Color := clYellow;
  btn := TButton.Create(Self);
  btn.Caption := 'Close';
  btn.Parent  := PopForm;
  btn.OnClick := btnClick;
  SetWindowPos(btn.Handle,0,0,0,100,100,SWP_SHOWWINDOW or SWP_NOACTIVATE);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  beep;
  ShowWindow(PopForm.Handle,SW_HIDE);
end;

end.


Mr.XRAY  2009-10-07 05:10:55  No: 35816

Mr.XRAYです.

>表示させた後、メインウィンドウにフォーカスを移すという処理を
>行うため、画面がちらついてしまいます。

どんな処理をしているのかわかりせんが,以下のように,メインウィンドウであるフォームに
フォーカス移動するか,メインウィンドウのフォームに配置しているコントロールにフォーカス
移動するだけではダメということですか?

思いきっリ外しているのかも知れません.

procedure TForm1.Button1Click(Sender: TObject);
begin
    //FormStyleはオブジェクト・インスペクタでの設定がbetter
    Form2.FormStyle := fsStayOnTop;
    Form2.Show;

    //こんな処理を入れればこのフォームがアクティブ
    Edit1.SetFocus;
    //Form1.SetFocus;
end;


yosi  2009-10-07 15:31:46  No: 35817

monaa様

わざわざコードまで示してくださって、ありがとうございます。
今日職場で試してきます。タイマーを使っている理由がまだよく
分からないのですが、少し試行錯誤して様子を見てみたいと
思います。

Mr.XRAY様

おっしゃるとおりです。実際には、fsStayOnTopを設定した
Form2を、

  Form2.Show;
  Form1.SetFocus;

という形で表示させていました。この場合、一瞬Form2に
フォーカスが移ったあと、Form1に戻るため、
Form2を頻繁に表示させたり消したりすると、ちらつきが
気になってしまいます。


Mr.XRAY  2009-10-07 16:53:05  No: 35818

Mr.XRAYです.

>Form2を頻繁に表示させたり消したりすると、ちらつきが
>気になってしまいます。

Form2の表示,非表示そのものをチラツキと言うのであれば,
これはどうしようもないような気がしますが.


ぽむぽむ  2009-10-07 20:01:37  No: 35819

ListBox 一個で済むものであれば・・・

type
  TPopupList=class(TListBox)
  private
    FCursorIndex: Integer;
  public
    constructor Create(AOwner: TComponent); override;
  protected
    procedure CreateWnd; override;
    procedure CreateParams(var Params:TCreateParams);override;
    procedure Click; override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  end;

constructor TPopupList.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Height := ItemHeight * 6 + BorderWidth * 2;
end;

procedure TPopupList.CreateParams(var Params:TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_TOOLWINDOW;
end;

procedure TPopupList.CreateWnd;
begin
  inherited CreateWnd;
  Windows.SetParent(Handle, 0);
  CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
end;

procedure TPopupList.Click;
begin
  inherited Click;
  Hide;
end;

procedure TPopupList.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  newIdx: Integer;
begin
  newIdx := ItemAtPos(Point(X,Y), True);

  if (newIdx <> FCursorIndex) then begin
    Itemindex := newIdx;
    FCursorIndex := newIdx;
    Repaint;
  end;
  inherited MouseMove(Shift, X, Y);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  pl:TPopupList;
  p:TPoint;
  itm: TListItem;
begin
  p := ClientToScreen(Point(Button1.Left + Button1.Width, Button1.Top + Button1.Height));
  pl := TPopupList.Create(Self);
  pl.Parent := Self;
  pl.Items.Assign(Memo1.Lines);
  pl.OnClick := ListBoxClick;
  pl.Left := p.X;
  pl.Top := p.Y;
  pl.Show;
end;
procedure TForm1.ListBoxClick(Sender: TObject);
begin
  if Sender is TListBox then begin
    if TListBox(Sender).ItemIndex >= 0 then
      Edit1.Text := TListBox(Sender).Items[TListBox(Sender).ItemIndex]
    else
      Edit1.Text := '未選択';
  end;
end;


Mr.XRAY  2009-10-08 22:54:34  No: 35820

Mr.XRAYです.

>Form2を頻繁に表示させたり消したりすると、ちらつきが
>気になってしまいます。

どんなコードかも,具体的な動作仕様も,私にはわかりませんが,
Form2を表示する時に,このForm2(またはこの上のコントロール)に何かを表示
する際に,その表示がチラツクということなのでしょうか.
Form2なのか,Form2に表示するものなのか,切り分けが必要かも知れません


Mr.XRAY  2009-10-08 23:56:20  No: 35821

>Form2を頻繁に表示させたり消したりすると、ちらつきが
>気になってしまいます。

表示するのは,キー操作かマウスでしょうから.
人の手で,例えば1秒間に何十回もできないとは思いますが.
何十回もしたら,Form2の内容を見る余裕が?
この頻繁に,というのはどの程度なのかも問題なのかも.


Mr.XRAY  2009-10-09 10:08:46  No: 35822

Mr.XRAYです.

>Delphi のコード補完ウィンドウのようなものを作ろうと思っています。

ちょっと興味あったのでやってみました.
作ってみてから思ったのですが,単に別のフォームを表示して,リストから選択する
ということのようです.よくやる別の設定画面(別フォーム)を表示する方式と同じようですね.

ただ,違うのは,表示したフォームがポップアップメニューのような感じで現れる
ということのようです.つまり,枠のないフォームとでも言うのでしょうか.

別フォームを表示するだけではつまらないので,少しコードを付け足しています.
ただし,

>Form2を頻繁に表示させたり消したりすると、ちらつきが
>気になってしまいます。

の解決にはならないと思いますので,あくまで,何かの参考になればということです.

http://mrxray.on.coocan.jp/Delphi/plSamples/126_PopUpFormTest.htm


名無し  2009-11-09 05:09:02  No: 35823

解決としておこう


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加