¿Por qué el cambio no es mi cursor a un reloj de arena en mi FindDialog en Delphi?
-
27-09-2019 - |
Pregunta
Simplemente estoy abriendo mi FindDialog con:
FindDialog.Execute;
En mi caso FindDialog.OnFind, quiero cambiar el cursor a un reloj de arena para las búsquedas a través de archivos de gran tamaño, que puede tardar unos segundos. Así, en el caso OnFind hago esto:
Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;
Lo que ocurre es la búsqueda del texto, el cursor cambia correctamente al reloj de arena (o un círculo que gira en Vista) y luego de vuelta al puntero cuando se haya completado la búsqueda.
Sin embargo, esto sólo ocurre en el formulario principal. Esto no sucede en el propio FindDialog. El cursor por defecto permanece en la FindDialog durante la búsqueda. Mientras que la búsqueda está sucediendo si muevo el cursor sobre el FindDialog cambia al valor predeterminado, y si lo muevo fuera y sobre la forma principal se convierte en el reloj de arena.
Esto no concuerda con lo que se supone que sucede. ¿Estoy haciendo algo mal o hace algo especial hay que hacer para obtener el cursor a ser el reloj de arena en todas las formas?
A modo de referencia, estoy usando Delphi 2009.
Solución
supongo que la razón de esto tiene algo. que ver con el cuadro de diálogo Buscar, no siendo sino una forma de diálogo (un diálogo común).
Puede intentar establecer el cursor de clase (no tiene un efecto sobre los controles del cuadro de diálogo);
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;
Editar
Una alternativa podría ser la subclase el FindDialog durante el tiempo de búsqueda y responder a los mensajes WM_SETCURSOR con "SetCursor". Si evitamos el procesamiento adicional del mensaje de los controles en el cuadro de diálogo no fijar sus propios cursores.
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;
Otros consejos
Trate de añadir Application.ProcessMessages; después de poner el cursor.
Si esto funciona, asegúrese de llamar a su madre, ayuda a una anciana cruzar la calle, o tal vez plantar un árbol. De lo contrario, el diablo poseerá el otro pequeño pedazo de su alma.