6

Delphi 2007 では、マウス移動イベントで、マウス カーソルを次のように変更しようとしました。

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;

例えば。ただし、マウスの左ボタンを押したままマウスを動かしても、カーソルが crDrag にも crNoDrop にも変化しません。コードは実行されますが (例: Cursor := crDrag;)、カーソルは変化しません。マウスの左ボタンを押したままマウスを動かすと、カーソルは問題なく変化します。

(私は最初、いくつかのドラッグ アンド ドロップ イベントとプロパティを使用しようとしましたが、すべてが思い通りに動作するようにはなりませんでした。)

編集:望ましい動作を明確にし、コードをフォーマットしました。

編集: Gamecat さん、ありがとうございます。マウスの左ボタンを押したときにカーソルを変更し、マウスを動かしている間は、カーソルが crDrag と crNoDrop の間を行き来する必要があります。

4

2 に答える 2

11

OnMouseDown でマウス カーソルを設定し、OnMouseUp でリセットすると、すべて正常に動作します。

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;

マウスの移動にマウスカーソルを反応させたい場合は、次のようにします。

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;

そうしないと、カーソルがコントロールの上にある場合にカーソルが元に戻りません。

どこでも必ず Screen.Cursor を使用してください。

于 2008-12-18T08:02:44.330 に答える
5

トピックから少し外れますが、おそらく役に立つでしょう。

ネストされたカーソルの変更を許可するグローバル スタックを作成しました。これにより、任意のコードで、呼び出し元または呼び出し先の設定を気にせずに、マウス カーソルを目的の位置に設定できます。

例えば:

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;

どちらのプロシージャも、もう一方のプロシージャが必要とする状態やマウス カーソルを離れる状態を気にする必要はありません。

//===============================================================
//   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;
于 2008-12-18T21:40:09.577 に答える