Warum funktioniert mein Cursor Änderung einer Sanduhr in meinem Finddialog in Delphi?
-
27-09-2019 - |
Frage
Ich bin einfach zu öffnen meinen Finddialog mit:
FindDialog.Execute;
In meinem FindDialog.OnFind Fall, ich will für die Suche durch große Dateien der Cursor in eine Sanduhr ändern, was einige Sekunden dauern kann. So in der OnFind Veranstaltung, die ich dies tun:
Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;
Was passiert ist, während für den Text suchen, der Cursor ändert sich richtig an die Sanduhr (oder rotierenden Kreis in Vista) und dann wieder auf den Zeiger, wenn die Suche abgeschlossen ist.
Dies geschieht jedoch nur auf dem Hauptformular. Es geschieht nicht auf dem Finddialog selbst. Der Standard-Cursor bleibt auf dem Finddialog während der Suche. Während die Suche geschieht, wenn ich die Cursor über das Finddialog bewege sich auf den Standard ändern, und wenn ich es losfahren und über die Hauptform wird es die Sanduhr.
Dies scheint nicht wie das, was geschehen soll. Bin ich etwas falsch zu machen oder muss etwas Besonderes tun, um den Cursor zu bekommen die Sanduhr auf alle Formen sein?
Als Referenz Ich verwende Delphi 2009.
Lösung
Ich glaube, der Grund dafür, etw bekommen hat. zu tun mit Suchen-Dialog (a Common Dialog) keine Form, sondern ein Dialog zu sein.
Sie können versuchen, die Klasse Cursor-Einstellung (keine Auswirkung auf den Kontrollen des Dialogs);
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;
Bearbeiten
Eine Alternative könnte sein, den Finddialog während der Suchzeit und reagiert mit „SetCursor“ zu WM_SETCURSOR Meldungen zu Unterklasse. Wenn wir die weitere Verarbeitung der Meldung verhindern, werden die Steuerelemente auf dem Dialog nicht ihre eigenen Cursor gesetzt.
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;
Andere Tipps
Versuchen Application.ProcessMessages Zugabe; nachdem Sie den Cursor gesetzt.
Wenn dies funktioniert, sollten Sie Ihre Mutter, Hilfe eine alte Dame über die Straße rufen, oder vielleicht einen Baum pflanzen. Andernfalls wird selbst der Teufel noch ein kleines Stück deiner Seele.