在窗体中按下鼠标左键拖动窗体代码???

ColorSM 2002-03-05 10:47:13
将窗体FormBorderStyle属性设为:none,则窗体将不显示标题栏,此时,我想在窗体(Form)中按下鼠标左键事件中增加拖动窗体的动作(连续改变窗体位置),大家帮忙想想办法吧!!!
...全文
189 点赞 收藏 18
写回复
18 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
ColorSM 2002-03-07
哦这样呀,看起来我还要慢慢消化了。不过受到的启发还真是不少。

回复
qqchen79 2002-03-07
1. Windows消息的定义在VC6/SDK的头文件.h中,可以在Include目录下搜一把。
2. 这是VS.NET加的,在这个程序里删了也没关系。
回复
ColorSM 2002-03-07
Ninputer(装配脑袋):
您好!我试成功了。不过我有几个问题:
1、像
private const int WM_NCLBUTTONDOWN = 0xA1;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_LBUTTONUP = 0x202;
private const int HTCAPTION = 2;
这样的常数值是怎样确定的,如果我也要常握这方面的知识,该如何学习。毕竟我不能每遇到这样的问题总是麻烦大家吧。

2、private System.ComponentModel.Container components = null;
这一句的作用又是什么,我发现"components"只在:
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
中用到。

谢谢,谢谢!!!
回复
ColorSM 2002-03-07
upupup
回复
Ninputer 2002-03-06
'* 提供一个可以拖动(就像窗口的标题栏)的图片框
'* 它将作为程序主窗体的标题栏
Public Class DragablePanel
Inherits System.Windows.Forms.PictureBox

#Region " Component Designer generated code "

Public Sub New(ByVal Container As System.ComponentModel.IContainer)
MyClass.New()

'Required for Windows.Forms Class Composition Designer support
Container.Add(Me)
End Sub

Public Sub New()
MyBase.New()

'This call is required by the Component Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Component overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Component Designer
'It can be modified using the Component Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub

#End Region

'* 传递消息的Win32API函数
Private Declare Ansi Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer _
) As Integer

Private Const WM_NCLBUTTONDOWN = &HA1
Private Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Private Const HTCAPTION = 2

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
'* 调用Win32API
'* 让程序窗口认为自己在被拖动

If m.Msg = WM_LBUTTONDOWN Then
SendMessage(Me.Parent.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0)
Else
MyBase.WndProc(m)
End If

End Sub

End Class
回复
qqchen79 2002-03-06
正常的消息处理而已,不算是消息拦截。
无论是以前VB还是现在的C#,最好有Windows SDK的编程基础,了解整个Windows程序的运行机制。

Windows在特定的时候会询问应用程序当前的鼠标在窗口的什么位置,通过发送WM_NCHITTEST消息,应用可以通知Windows,当前鼠标停留在标题兰(HTCAPTION),而Windows在鼠标在标题栏拖动的时候会拖动整个窗口...
回复
qqchen79 2002-03-06
事实上在学MFC编程的时候我也尝试过手工实现窗口的拖动,但效果移植不是最好,与Windows自己实现的相比,不够平滑,而且必须维护一个相对复杂的逻辑。所以我认为比较好的方法还是直接利用Windows的内部机制来实现,所以需要做的不过是“欺骗”Windows,使其认为整个窗口都是“标题栏”。
回复
ColorSM 2002-03-06
qqchen79(知秋一叶):
  您好!谢谢啦!
  那么你用到的是否是Windows消息拦截呢,如果我想在这方面有所学习不知你对我有什么见意。
  再有不知可否解释一下你的楼上代码。
  非常谢谢!
回复
qqchen79 2002-03-06
至于拖动窗口时是否显示窗口的内容,这是由Windows决定的,可以在:
控制面板——显示属性——效果 中设置。
回复
qqchen79 2002-03-06
把下面这段代码加到VS.NET生成的从Form继承的类当中,就OK了。

private int WM_NCHITTEST = 0x0084;
private int HTCAPTION = 2;

protected override void WndProc(ref Message msg)
{
if (msg.Msg == WM_NCHITTEST)
msg.Result = (IntPtr)HTCAPTION;
else base.WndProc(ref msg);
}
回复
ColorSM 2002-03-06
我还是没有解决。
http://www.csdn.net/expert/topic/489/489472.xml也看了,但没有试成功,大家能不能拿出实际代码供我参考,先行谢谢啦!!!
回复
ColorSM 2002-03-06
嘻嘻,所以说这个世界还是好人多。

Ninputer(装配脑袋),真是多谢了。
回复
ColorSM 2002-03-06
qqchen79(知秋一叶):
那么有什么办法可以使得Windows认为整个窗口都是“标题栏”呢?
回复
Ninputer 2002-03-06
怎么可能C#看得懂而VB看不懂呢?算了,反正受累的总是我
这个控件无论放在窗体什么部位,都能拖动整个窗体
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ToRemove
{
public class DragablePanel : System.Windows.Forms.PictureBox
{
// 传递消息的Win32API函数
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

private const int WM_NCLBUTTONDOWN = 0xA1;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_LBUTTONUP = 0x202;
private const int HTCAPTION = 2;

private System.ComponentModel.Container components = null;

public DragablePanel(System.ComponentModel.IContainer container)
{
container.Add(this);
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

public DragablePanel()
{
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// 调用Win32API
// 让程序窗口认为自己在被拖动

if (m.Msg == WM_LBUTTONDOWN)
SendMessage(this.Parent.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
else
{
base.WndProc(ref m);
}

}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}
回复
ColorSM 2002-03-06
Ninputer(装配脑袋):
可否用 C# 重写以上代码?

我太笨,谢谢!!!
回复
zhaixd 2002-03-05
请看下面这个帖子,我在那个帖子里回答了非常相似的问题http://www.csdn.net/expert/topic/489/489472.xml
回复
DBXP 2002-03-05
不难做到。
在from的MouseMove事件中检查鼠标移动的差值。然后设置窗体的Location属性为Location + 这个差值就可以了。
回复
qqchen79 2002-03-05
在Windows SDK编程中,这种功能很容易实现:只要在收到WM_NCHITTEST消息的时候总是返回HTCAPTION就可以了。
但是对于.NET,我能想到的最好的办法是编写一个MyForm类型,从Form继承,并且override WndProc方法,在收到WM_NCHITTEST消息时返回HTCAPTION。具体的数值可以在Windows.h中找到。
回复
相关推荐
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2002-03-05 10:47
社区公告

让您成为最强悍的C#开发者