DelphiのFindDialogで、カーソルが砂時計に変更されないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/2660799

質問

私は単に私のfinddialogを開いています:

FindDialog.Execute;

FindDialog.OnFindイベントでは、大きなファイルを検索するためにカーソルを砂時計に変更して、数秒かかる場合があります。だから、このイベントで私はこれをします:

Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;

テキストの検索中に起こることは、カーソルが砂時計(またはVistaの回転円)に適切に変更され、検索が完了するとポインターに戻ることです。

ただし、これはメインフォームでのみ発生します。 FindDialog自体では発生しません。デフォルトのカーソルは、検索中にFindDialogに残ります。 CursorをFindDialogの上に移動すると検索が行われている間、デフォルトに変更され、メインフォームをオフに移動すると砂時計になります。

これは起こるはずのことのようには見えません。私は何か間違ったことをしているのですか、それともカーソルをあらゆる形の砂時計にするために何か特別なことをする必要がありますか?

参照のために、Delphi 2009を使用しています。

役に立ちましたか?

解決

この理由はSTHを持っていると思います。ダイアログがフォームではなく、ダイアログ(一般的なダイアログ)であることを見つけることです。

クラスカーソルを設定することはできます(ダイアログのコントロールに影響を与えません)。

procedure TForm1.FindDialog1Find(Sender: TObject);
begin
  SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crHourGlass]);
  try
    Screen.Cursor := crHourglass;
    try
//    (code that searches for the text and displays it) ...
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crDefault]);
  end;
end;



編集

別の方法は、検索時間中にFindDialogをサブクラス化し、「SetCursor」を使用してWM_SetCursorメッセージに応答することです。メッセージのさらなる処理を防ぐと、ダイアログ上のコントロールは独自のカーソルを設定しません。

type
  TForm1 = class(TForm)
    FindDialog1: TFindDialog;
    ...
  private
    FSaveWndProc, FWndProc: Pointer;
    procedure FindDlgProc(var Message: TMessage);
    ...
  end;

....
procedure TForm1.FormCreate(Sender: TObject);
begin
  FWndProc := classes.MakeObjectInstance(FindDlgProc);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  classes.FreeObjectInstance(FWndProc);
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
begin
  FSaveWndProc := Pointer(SetWindowLong(FindDialog1.Handle, GWL_WNDPROC,
        Longint(FWndProc)));
  try
    Screen.Cursor := crHourGlass;
    try
//    (code that searches for the text and displays it) ...
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    if Assigned(FWndProc) then
      SetWindowLong(FindDialog1.Handle, GWL_WNDPROC, Longint(FSaveWndProc));
//    SendMessage(FindDialog1.Handle, WM_SETCURSOR, FindDialog1.Handle,
//        MakeLong(HTNOWHERE, WM_MOUSEMOVE));
    SetCursor(Screen.Cursors[crDefault]);
  end;
end;

procedure TForm1.FindDlgProc(var Message: TMessage);
begin
  if Message.Msg = WM_SETCURSOR then begin
    SetCursor(Screen.Cursors[crHourGlass]);
    Message.Result := 1;
    Exit;
  end;
  Message.Result := CallWindowProc(FSaveWndProc, FindDialog1.Handle,
      Message.Msg, Message.WParam, Message.LParam);
end;

他のヒント

application.processmessagesを追加してみてください。カーソルを設定した後。

これが機能する場合は、必ずお母さんに電話したり、老婦人が通りを横断したり、木を植えてください。そうでなければ、悪魔はあなたの魂の別の小さな部分を所有します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top