我有一个TFrame,我希望能够通过单击并拖动右下角来调整大小。功能应该是;
当鼠标在右下角移动时,光标应该改变以反映可以调整帧的大小。如果不在底角,则光标应为标准箭头。
在运行时框架顶部会有控件,因此我无法使用OnMouseMove事件。所以我用这个;
private
procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
procedure TfraApplet.WMSetCursor(var Msg: TWMSetCursor);
var
Point: TPoint;
begin
Point := ScreenToClient(Mouse.CursorPos);
Label1.Caption := 'X:' + IntToStr(Point.X) + ' Y:' + IntToStr(Point.Y);
// Resize area (bottom right)
if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then
Screen.Cursor := crSizeNWSE
else
Screen.Cursor := crDefault;
end;
但是一旦光标设置为crSizeNWSE,我的程序就会停止接收WM_SETCURSOR窗口消息。
当光标未设置为默认箭头时,是否会收到不同的Windows消息?
答案 0 :(得分:3)
这不是帧停止接收WM_SETCURSOR
消息,而是他的光标被卡在crSizeNWSE处。当您切换回设置crDefault
到Screen.Cursor
时,会发生的情况是VCL向帧发送WM_SETCURSOR
以使其设置默认光标。实际上,没有光标设置。如果您希望从上一个更改游标,则必须设置游标,将上一个部分替换为:
// Resize area (bottom right)
if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then begin
winapi.Windows.SetCursor(Screen.Cursors[crSizeNWSE]);
Message.Result := 1;
end else
inherited;
作为替代方案,您可以处理WM_NCHITTEST
以将区域定义为大小调整区域,然后框架的默认窗口过程将在处理WM_SETCURSOR
时设置适当的光标:
procedure TfraApplet.WMNCHitTest(var Message: TWMNCHitTest);
var
Point: TPoint;
begin
Point := ScreenToClient(SmallPointToPoint(Message.Pos));
Label1.Caption := 'X:' + IntToStr(Point.X) + ' Y:' + IntToStr(Point.Y);
// Resize area (bottom right)
if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then
Message.Result := HTBOTTOMRIGHT
else
inherited;
end;
作为额外的好处,您不必编写用于调整框架大小的其他代码。