Pergunta

Estou simplesmente abrindo meu finddialog com:

FindDialog.Execute;

No meu evento finddialog.onfind, quero alterar o cursor para uma ampulheta para pesquisas através de arquivos grandes, que podem levar alguns segundos. Então, no evento ONFIND, eu faço isso:

Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;

O que acontece é que, ao procurar o texto, o cursor muda adequadamente para a ampulheta (ou círculo rotativo no Vista) e depois volta ao ponteiro quando a pesquisa é concluída.

No entanto, isso só acontece na forma principal. Isso não acontece no próprio finddialog. O cursor padrão permanece no finddialog durante a pesquisa. Enquanto a pesquisa está acontecendo se eu mover o cursor sobre o finddialog, ele muda para o padrão e, se eu o mover para fora e sobre a forma principal, ele se tornará a ampulheta.

Isso não parece o que deveria acontecer. Estou fazendo algo errado ou algo especial precisa ser feito para fazer com que o cursor seja a ampulheta em todas as formas?

Para referência, estou usando o Delphi 2009.

Foi útil?

Solução

Eu acho que a razão para isso tem STH. A ver com a caixa de diálogo Localizar não sendo um formulário, mas uma caixa de diálogo (uma caixa de diálogo comum).

Você pode tentar definir o cursor da classe (não afeta os controles da caixa 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

Uma alternativa pode ser subclasse o FindDialog durante o tempo de pesquisa e responder às mensagens WM_SETCURSOR com "SetCursor". Se impedirmos o processamento adicional da mensagem, os controles na caixa de diálogo não definirão seus próprios 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;

Outras dicas

Tente adicionar Application.processMessages; Depois de definir o cursor.

Se isso funcionar, chame sua mãe, ajude uma velha senhora a atravessar a rua ou talvez plantar uma árvore. Caso contrário, o diabo terá outro pedacinho da sua alma.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top