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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top