6 votes

Comment modifier le curseur de la souris lorsque le bouton gauche de la souris est enfoncé ?

Dans Delphi 2007, dans un événement de déplacement de la souris, j'essaie de changer le curseur de la souris avec :

procedure TFr_Board_Display.PaintBox_Proxy_BoardMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin

  if left_mouse_button_down then begin  
    if some_condition then begin
      Cursor := crDrag;
    end
    else begin
      Cursor := crNoDrop;
    end;
  end
  else begin
    if some_other_condition then begin
      Cursor := crHandPoint;
    end
    else begin
      Cursor := crDefault;
    end;
  end;
end;

par exemple. Cependant, lorsque le bouton gauche de la souris est enfoncé et que je déplace la souris, le curseur ne passe ni à crDrag ni à crNoDrop. Le code est exécuté (par exemple, Cursor := crDrag ;) mais le curseur ne change pas. Lorsque le bouton gauche de la souris est relevé et que je déplace la souris, le curseur change sans problème.

(Au départ, j'ai essayé d'utiliser certains événements et propriétés de Drag & Drop, mais je n'ai pas réussi à tout faire fonctionner comme je le voulais).

Edit : Clarifié le comportement souhaité, et formaté le code.

Edit : Merci, Gamecat, mais je veux que le curseur change lorsque le bouton gauche de la souris est enfoncé et que, lorsque la souris se déplace, le curseur passe de crDrag à crNoDrop.

11voto

Toon Krijthe Points 36327

Si vous définissez le curseur de la souris dans le OnMouseDown et le réinitialisez dans le OnMouseUp, tout fonctionne bien :

procedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Cursor := crCross;
end;

procedure TForm4.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Cursor := crDefault; // Or you can restore a saved cursor.
end;

Si vous voulez que le curseur de la souris réagisse au déplacement de la souris, utilisez ce qui suit :

procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in Shift then begin
    if X<100 then
      Screen.Cursor := crCross
    else
      Screen.Cursor := crHourGlass;
  end else
    Screen.Cursor := crDefault;  // Or you can restore a saved cursor.
end;

procedure TForm4.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Screen.Cursor := crDefault; // Or you can restore a saved cursor.
end;

Le MouseUp est nécessaire, sinon le curseur ne reviendra pas en arrière s'il survole un contrôle.

Veillez à utiliser Screen.Cursor partout.

5voto

Richard Haven Points 725

Légèrement hors sujet, mais peut-être utile pour vous.

J'ai créé une pile globale pour permettre les changements de curseur imbriqués. Cela permet à n'importe quel morceau de code de régler le curseur de la souris sur ce qu'il veut sans se soucier de ce que son appelant ou son appelé a réglé.

Par exemple :

procedure AskUserWhatToDo;
begin
  PushMouseCursor(crArrow);
  try
     if MessageDlg('Abort?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
        SysUtils.Abort;
  finally
     PopMouseCursor;
  end;
end;

procedure LongProcess;
begin
  PushMouseCursor(crHourglass);
  try
     //  do something
     if QuestionableState then
       AskUserWhatToDo;
     //  do something
  finally
    PopMouseCursor;
  end;
end;

Aucune des deux procédures ne doit se préoccuper de l'état dans lequel l'autre a besoin ou laisse le curseur de la souris.

//===============================================================
//   in a universal utility module (mine is called CraftWindows.pas)

function SetMouseCursor(ACursor : TCursor) : TCursor;
begin
   Result := Screen.Cursor;
   Screen.Cursor := ACursor;
end;

var
   GlobalMouseCursorStack : TList = nil;

procedure PushMouseCursor(ACursor : TCursor);
begin
   if GlobalMouseCursorStack = nil then
       GlobalMouseCursorStack := TList.Create;

   GlobalMouseCursorStack.Add(Pointer(SetMouseCursor(ACursor)));
end;

procedure PopMouseCursor;
begin
   if (GlobalMouseCursorStack <> nil) and (GlobalMouseCursorStack.Count > 0) then
   begin
       SetMouseCursor(TCursor(GlobalMouseCursorStack.Last));
       GlobalMouseCursorStack.Delete(GlobalMouseCursorStack.Count - 1);
   end;
end;

...

finalization
  GlobalMouseCursorStack.Free;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X