如何在delphi TFrame上编写调整大小句柄?

时间:2015-01-28 15:11:45

标签: delphi windows-messages

我有一个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消息?

1 个答案:

答案 0 :(得分:3)

这不是帧停止接收WM_SETCURSOR消息,而是他的光标被卡在crSizeNWSE处。当您切换回设置crDefaultScreen.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;

作为额外的好处,您不必编写用于调整框架大小的其他代码。