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.

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top