我正尝试通过点击按钮进行表单移动(使用标题栏)。
我认为使用SendMessage会很简单:
Const WM_LBUTTONDOWN As Integer = &H201
Button1.Capture = False
Cursor.Position = Me.Location + New Size(50, 8)
SendMessage(Me.Handle, WM_LBUTTONDOWN, CType(1, IntPtr), IntPtr.Zero)
然而,虽然如果光标在窗体客户区域中,它会发送消息,但它似乎不会将其发送到窗体标题栏(表单以某种方式捕获事件,尽管光标位于标题栏上而不是客户端区域)。
我在按钮上的mousedown和click事件中尝试了上述代码,移动光标然后按下按钮1。
有什么建议吗?
答案 0 :(得分:3)
您需要WM_
NC
LBUTTONDOWN
(并将HTCAPTION
作为wParam
传递)。我仍然不完全确定这会完成你想要做的事情。
通常,允许用户在单击标题栏以外的位置时移动表单的方法是处理WM_NCHITTEST
消息,并在光标位于您所在区域上时返回HTCAPTION
我想开始行动。但是,如果此区域被子控件占用,则还必须从子控件处理WM_NCHITTEST
并返回HTTRANSPARENT
。
顺便提一下,更简单 - 如果稍微不那么正确的方法来完成此操作就像Mehrdad Afshari suggested那样,只需设置表单的Location
属性即可。你向他评论说“它需要继续移动鼠标”,而这正是你能做和应该做的事情。
class MyForm : Form{
Point downAt;
MyForm(){
Label lbl = new Label();
lbl.AutoSize = true;
lbl.BackColor = Color.Blue;
lbl.ForeColor = Color.White;
lbl.Location = new Point(50, 50);
lbl.Text = "Drag me to move this form.";
lbl.Parent = this;
lbl.MouseDown += (s, e)=>downAt = e.Location;
lbl.MouseMove += (s, e)=>{if(lbl.Capture) Location += (Size)e.Location - (Size)downAt;};
}
}
这种方法的问题在于它绕过了用于移动顶层窗口的Windows代码。这意味着如果用户未在“显示属性”对话框中选择“在拖动时显示窗口内容”选项,则这将有效地忽略该设置(它不会显示拖动轮廓)。可能还有其他一些我没想过的缺点。
总的来说,这是一个简单,容易的方法来实现这一点,这是一个完全的.NET解决方案,不依赖于任何平台调用(因此它应该可以移植到Unix上的Mono)。
糟糕。我刚刚意识到我给了你C#示例代码,但你的代码似乎是VB.NET。我想你需要的是:
Sub New()
Dim lbl As New Label
lbl.AutoSize = True
lbl.BackColor = Color.Blue
lbl.ForeColor = Color.White
lbl.Location = New Point(50, 50)
lbl.Text = "Drag me to move this form."
lbl.Parent = Me
AddHandler lbl.MouseDown, Function(ByVal s As Object, ByVal e As MouseEventArgs)
Me.downAt = e.Location
End Function
AddHandler lbl.MouseMove, Function(ByVal s As Object, ByVal e As MouseEventArgs)
If lbl.Capture Then
Me.Location = Me.Location + DirectCast(e.Location, Size) - DirectCast(Me.downAt, Size)
End If
End Function
End Sub
这可能不是在VB.NET中表达这一点的最简洁方式。我使用Reflector来帮助我翻译它。
答案 1 :(得分:2)
LParam
消息的wm_LButtonDown
值接收 client 坐标中的鼠标位置。标题栏位于非客户区域,因此请使用wm_NCLButtonDown
message。我之前看过这个问题作为这个问题的答案给出了,但是我希望有一个更直接的路径:向窗口发送wm_SysCommand
message,并指定sc_Move
标志。 / p>
答案 2 :(得分:2)
Mehrdad是对的,不需要这样做。捕获鼠标,以便您永远不会移动太快。示例代码:
Point mLastPos;
private void button1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
this.Location = new Point(this.Location.X + e.X - mLastPos.X,
this.Location.Y + e.Y - mLastPos.Y);
}
// NOTE: else is intentional!
else mLastPos = e.Location;
}