[英]Why doesn't my cursor change to an Hourglass in my FindDialog in Delphi?
I am simply opening my FindDialog with: 我只是打开我的FindDialog:
FindDialog.Execute;
In my FindDialog.OnFind event, I want to change the cursor to an hourglass for searches through large files, which may take a few seconds. 在我的FindDialog.OnFind事件中,我想将光标更改为沙漏以搜索大文件,这可能需要几秒钟。 So in the OnFind event I do this:
所以在OnFind事件中我这样做:
Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;
What happens is while searching for the text, the cursor properly changes to the hourglass (or rotating circle in Vista) and then back to the pointer when the search is completed. 搜索文本时,光标会正确地更改为沙漏(或Vista中的旋转圆圈),然后在搜索完成时返回指针。
However, this only happens on the main form. 但是,这只发生在主窗体上。 It does not happen on the FindDialog itself.
它不会发生在FindDialog本身上。 The default cursor remains on the FindDialog during the search.
搜索期间,默认光标仍保留在FindDialog上。 While the search is happening if I move the cursor over the FindDialog it changes to the default, and if I move it off and over the main form it becomes the hourglass.
如果我将光标移到FindDialog上进行搜索,则会更改为默认值,如果我将其移出主表单,则会成为沙漏。
This does not seem like what is supposed to happen. 这似乎不应该发生。 Am I doing something wrong or does something special need to be done to get the cursor to be the hourglass on all forms?
我做错了什么或者需要做些什么来使光标成为所有表格上的沙漏?
For reference, I'm using Delphi 2009. 作为参考,我正在使用Delphi 2009。
I guess the reason for this has got sth. 我猜这个的原因有点...... to do with Find Dialog being not a form but a Dialog (a Common Dialog).
查找对话框不是表单而是对话框(通用对话框)。
You can try setting the class cursor (does not have an effect on the controls of the dialog); 您可以尝试设置类光标(对对话框的控件没有影响);
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;
An alternative could be to subclass the FindDialog during the search time and respond to WM_SETCURSOR messages with "SetCursor". 另一种方法是在搜索时间内对FindDialog进行子类化,并使用“SetCursor”响应WM_SETCURSOR消息。 If we prevent further processing of the message the controls on the dialog won't set their own cursors.
如果我们阻止进一步处理消息,则对话框上的控件将不会设置自己的游标。
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;
Try adding Application.ProcessMessages; 尝试添加Application.ProcessMessages; after you set the cursor.
设置光标后。
If this works, be sure to call your Mother, help an old lady cross the street, or maybe plant a tree. 如果这样做,一定要打电话给你的母亲,帮助一位老太太过马路,或者种一棵树。 Otherwise, the devil will own another little piece of your soul.
否则,魔鬼将拥有你灵魂的另一小部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.