Pourquoi pas mon changement de curseur sur un sablier dans mon FindDialog à Delphes?
-
27-09-2019 - |
Question
Je suis simplement mon FindDialog ouvrais avec:
FindDialog.Execute;
Dans mon cas FindDialog.OnFind, je veux changer le curseur sur un sablier pour les recherches par le biais de gros fichiers, qui peut prendre quelques secondes. Donc, en cas OnFind je fais ceci:
Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;
Qu'est-ce qui se passe est tout en recherchant le texte, le curseur change correctement le sablier (cercle ou tournant dans Vista), puis revenir au pointeur lorsque la recherche est terminée.
Cependant, cela ne se produit sur la principale forme. Il ne se produit pas sur le FindDialog lui-même. Le curseur par défaut reste sur la FindDialog lors de la recherche. Alors que la recherche se passe si je déplace le curseur sur le FindDialog il change la valeur par défaut, et si je me déplace hors tension et sur la forme principale, il devient le sablier.
Cela ne semble pas ce qui est censé se produire. Ai-je fait quelque chose de mal ou ne besoin de quelque chose de spécial à faire pour obtenir le curseur pour être le sablier sur toutes les formes?
Pour référence, j'utilise Delphi 2009.
La solution
Je suppose que la raison a obtenu STH. à voir avec le dialogue de recherche étant pas une forme, mais une boîte de dialogue (une boîte de dialogue commune).
Vous pouvez essayer de régler le curseur de la classe (n'a pas d'effet sur les contrôles de la boîte de dialogue);
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;
EDIT
Une autre solution pourrait être de sous-classe le FindDialog pendant le temps de recherche et de répondre aux messages WM_SETCURSOR avec « SetCursor ». Si nous empêchons un traitement ultérieur du message les commandes de la boîte de dialogue ne placeront pas leurs propres curseurs.
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;
Autres conseils
Essayez d'ajouter Application.ProcessMessages; après avoir défini le curseur.
Si cela fonctionne, assurez-vous d'appeler votre mère, aide une vieille dame traverser la rue, ou peut-être planter un arbre. Dans le cas contraire, le diable possédera un petit morceau de votre âme.