DelphiのFindDialogで、カーソルが砂時計に変更されないのはなぜですか?
-
27-09-2019 - |
質問
私は単に私の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を追加してみてください。カーソルを設定した後。
これが機能する場合は、必ずお母さんに電話したり、老婦人が通りを横断したり、木を植えてください。そうでなければ、悪魔はあなたの魂の別の小さな部分を所有します。