I have a TPanel with 2 events:
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Panel1.Cursor := crSizeAll; end; procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Panel1.Cursor := crDefault; end;
When I click on the panel (MouseDown event) the cursor does not change to
crSizeAll. What am I doing wrong and how can I resolve this?
You did all right. There is just a simple trick with capturing the mouse input. Once you've pressed Left Mouse Button (LMB) on
TPanel this panel has got mouse unput.
After that happened, your code
Panel1.Cursor := crSizeAll; is beginning to run. As you can see in the sources of VCL,
TControl sends message
CM_CURSORCHANGED to itself to set needed type of cursor. Since
TWinControl is based on
TControl, it handles this message and checks if mouse input has been captured. If this is not so, then
TWinControl sends message
WM_SETCURSOR to itself in order to set new cursor.
But Microsoft clearly stated that message
WM_SETCURSOR has a little restriction:
Sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured.
So, there is no way to change cursor's type if mouse input has been captured. One thing you could do is to call
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ReleaseCapture; Panel1.Cursor := crSizeAll; end;
But I wouldn't recommend do it this way since it breaks the paradigm of mouse input (in my opinion, once LMB was pressed, then it should stay pressed until it released by important reason (f.e. click on button), but you are free to decide how to use
ReleaseCapture on your own).
Test executed by user Zig proved that using
ReleaseCapture method is not appropriate since it forbids generating
OnMouseUp event if mouse cursor gone outside of
TPanel and LMB has been released.