扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
设置全局变量:
创新互联客户idc服务中心,提供服务器托管机柜、成都服务器、成都主机托管、成都双线服务器等业务的一站式服务。通过各地的服务中心,我们向成都用户提供优质廉价的产品以及开放、透明、稳定、高性价比的服务,资深网络工程师在机房提供7*24小时标准级技术保障。
Dim drag As Boolean
Dim mousex As Integer
Dim mousey As Integer
假设你想拖动的是Panel1控件,以及此控件上的 Label1(用于显示标题)和PictureBox4(用于显示图标):
Private Sub TitleMove_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown, Label1.MouseDown, PictureBox4.MouseDown
drag = True
mousex = Windows.Forms.Cursor.Position.X - Me.Left
mousey = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub
Private Sub TitleMove_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove, Label1.MouseMove, PictureBox4.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - mousey
Me.Left = Windows.Forms.Cursor.Position.X - mousex
End If
End Sub
Private Sub TitleMove_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp, Label1.MouseUp, PictureBox4.MouseUp
drag = False
End Sub
调用系统API使窗体下拥有阴影效果
using System.Runtime.InteropServices;
然后再窗口类的随便哪个地方加上:
const int CS_DROPSHADOW = 0x20000;
const int GCL_STYLE = (-26);
//声明Win32 API
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetClassLong(IntPtr hwnd,int nIndex,int dwNewLong);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassLong(IntPtr hwnd, int nIndex);
最后在窗体的构造函数中加上:
SetClassLong(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STYLE) | CS_DROPSHADOW);
private const int GWL_STYLE = (-16);
private const int GWL_EXSTYLE = (-20);
private const uint WS_EX_LAYERED = 0x80000;
private const uint WS_EX_TRANSPARENT = 0x20;
private const uint WS_THICKFRAME = 262144;
private const uint WS_BORDER = 8388608;
/// summary使指定 「 see cref="IntPtr"/ 句柄」 窗体 边框样式变为无边框。/summary
public static uint 无边框窗体(IntPtr 句柄) {
uint style = API_窗口.GetWindowLong(句柄, GWL_STYLE);
style = ~WS_BORDER;
style = ~WS_THICKFRAME;
return API_窗口.SetWindowLong(句柄, GWL_STYLE, style); ;
}
API窗口静态类
[DllImport("user32", EntryPoint = "SetWindowLong")]
public static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
[DllImport("user32", EntryPoint = "GetWindowLong")]
public static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
修改窗口位置
/// summary
/// 设置窗体的位置和大小。
/// /summary
/// param name="hWnd"/param
/// param name="hWndInsertAfter"用于标识在z-顺序的此 CWnd 对象之前的 CWnd 对象。
/// para/para如果uFlags参数中设置了SWP_NOZORDER标记则本参数将被忽略。可为下列值之一:
/// para/paraHWND_BOTTOM:值为1,将窗体置于Z序的底部。如果参数hWnd标识了一个顶层窗体,则窗体失去顶级位置,并且被置在其他窗体的底部。
/// para/paraHWND_NOTOPMOST:值为-2,将窗体置于所有非顶层窗体之上(即在所有顶层窗体之后)。如果窗体已经是非顶层窗体则该标志不起作用。
/// para/paraHWND_TOP:值为0,将窗体置于Z序的顶部。
/// para/paraHWND_TOPMOST:值为-1,将窗体置于所有非顶层窗体之上。即使窗体未被激活窗体也将保持顶级位置。/param
/// param name="x"窗体新的x坐标。如hwnd是一个子窗体,则x用父窗体的客户区坐标表示/param
/// param name="y"窗体新的y坐标。如hwnd是一个子窗体,则y用父窗体的客户区坐标表示/param
/// param name="Width"指定新的窗体宽度/param
/// param name="Height"指定新的窗体高度/param
/// param name="wFlags"/param
/// returns/returns
[DllImport("user32.dll", CharSet = CharSet.Ansi, EntryPoint = "SetWindowPos")]
public static extern int SetWindowPos(IntPtr hWnd, hWndInsertAfter hWndInsertAfter, int x, int y, int Width, int Height, wFlags wFlags);
/// summary
/// 调整指定 「 see cref="IntPtr"/ 句柄」 窗体的位置和尺寸。
/// /summary
/// param name="句柄"指定 「 see cref="IntPtr"/ 句柄」 窗体/param
/// param name="x"横坐标/param
/// param name="y"纵坐标/param
/// param name="w"宽/param
/// param name="h"高/param
public static int 调整窗体(IntPtr 句柄, int x, int y, int w, int h) {
return API_窗口.SetWindowPos(句柄, 0, x, y, w, h, wFlags.SWP_NOZORDER);
}
/// summary
/// 调整指定 「 see cref="IntPtr"/ 句柄」 窗体的位置。
/// /summary
/// param name="句柄"指定 「 see cref="IntPtr"/ 句柄」 窗体/param
/// param name="x"横坐标/param
/// param name="y"纵坐标/param
public static int 调整窗体位置(IntPtr 句柄, int x, int y) {
return API_窗口.SetWindowPos(句柄, 0, x, y, 0, 0, wFlags.SWP_NOSIZE | wFlags.SWP_NOZORDER);
}
在VB中,BorderStyle属性为0的窗体没有边框,并且也没有与边框相关的元素。这种窗体具有简洁、占用空间少等优点,用它可以设计出某些富有个性的窗体。但是,由于它没有标题栏,窗体不能移动,同时也不能改变大小,在某些情况下会给使用者造成一定的麻烦。本文介绍在VB中如何用API函数操作无边框窗体。
移动窗体
新建一标准工程,设置Form1的BorderStyle属性为0。此时运行程序后,无法移动窗体。为能移动窗体,在Form1的代码窗口声明下列函数和常数:
Option Explicit
Private Declare Function ReleaseCapture Lib “user32” ()AsLong
Private Declare Function SendMessage Lib “user32”Alias“SendMessageA” (ByVal hwnd As Long, ByVal wMsg As Long,
ByVal wParam As Long, lParam As Any) As Long
Const WM_SYSCOMMAND = H112
Const SC_MOVE = HF012
在Form_MouseDown事件中输入以下代码:
Private Sub Form_MouseDown(Button As Integer, Shift As Integer,XAs Single, Y As Single)
按下鼠标左键
If Button = vbcenterButton Then
为当前的应用程序释放鼠标捕获
ReleaseCapture
移动窗体
SendMessage Me.hwnd, WM_SYSCOMMAND, SC_MOVE, 0
End If
End Sub
注意:此时窗体上不能放置除Shape控件以外的任何控件,否则,在被控件遮住的地方点按鼠标还是无法移动窗体。要使点按控件也能移动窗体,需再添加一个该控件的MouseDown事件过程,代码与上述过程代码相似。
改变窗体的大小
为了改变窗体的大小,需要添加一个Timer控件,以定时捕获鼠标在窗体中的位置。当鼠标位于窗体边缘时,改变鼠标的形状,以通知用户可以进行改变大小的操作。为此,将Timer控件的Interval属性设为100(即每过100毫秒检测一下鼠标位置),其他取默认值。
在Form1的代码窗口中再添加下列两个函数,并定义两个自定义变量和一个字符串变量:
取得窗体位置的函数
Private Declare Function GetWindowRect Lib “user32” (ByVal hwndAsLong, lpRect As RECT) As Long
取得鼠标位置的函数
Private Declare Function GetCursorPos Lib “user32” (lpPointAsPOINTAPI) As Long
鼠标位置变量
Private Type POINTAPI
x As Long
y As Long
End Type
窗体位置变量
Private Type RECT
center As Long
Top As Long
center As Long
Bottom As Long
End Type
所要执行的动作变量,是移动还是改变大小及从哪个方向改变大小
Dim Action As String
在Timer1控件的Timer事件过程中添加以下代码:
Private Sub Timer1_Timer()
Dim MyRect As RECT
Dim MyPoint As POINTAPI
MyRect返回当前窗口位置
Call GetWindowRect(Me.hwnd, MyRect)
MyPoint返回当前鼠标位置
Call GetCursorPos(MyPoint)
Select Case True
鼠标位于窗体左上方
Case MyPoint.x MyRect.center + 5 And MyPoint.y ="" p=""
Screen.MousePointer = vbSizeNWSE
Action = “centerUp”
鼠标位于窗体右下方
Case MyPoint.x MyRect.center - 5 And MyPoint.yMyRect.Bottom - 5
Screen.MousePointer = vbSizeNWSE
Action = “centerDown”
鼠标位于窗体右上方
Case MyPoint.x MyRect.center - 5 And MyPoint.y="" p="" +=""
’45度双向鼠标指针
Screen.MousePointer = vbSizeNESW
Action = “centerUp”
鼠标位于窗体左下方
Case MyPoint.x MyRect.center + 5 And MyPoint.yMyRect.Bottom - 5
Screen.MousePointer = vbSizeNESW
Action = “centerDown”
鼠标位于窗体左边
Case MyPoint.x MyRect.center + 5
水平双向鼠标指针
Screen.MousePointer = vbSizeWE
Action = “center”
鼠标位于窗体右边热门推荐: C++程序设计之四书五经 谈谈JAVA程序的反编译1 2
MyRect.center - 5
Screen.MousePointer = vbSizeWE
Action = “center”
鼠标位于窗体上方
Case MyPoint.y MyRect.Top + 5
垂直双向鼠标指针
Screen.MousePointer = vbSizeNS
Action = “Up”
鼠标位于窗体下方
Case MyPoint.y MyRect.Bottom - 5
Screen.MousePointer = vbSizeNS
Action = “Down”
鼠标位于窗体其他位置
Case Else
默认鼠标指针
Screen.MousePointer = 0
Action = “Move”
End Select
End Sub
当利用SendMessage函数由系统向窗口发送改变大小的信息时,只要将上面移动窗体的语句“SendMessageMe.hwnd,WM_SYSCOMMAND, SC_MOVE, 0”中的第3个参数改为相应的常数即可。
VB中HF001~HF008分别是从左、右、上、左上、右上、下、左下、右下8个方向改变窗体大小的常数。结合移动窗体的代码,将上述Form_MouseDown事件的代码综合如下(也可以把这8个常数声明为自定义常数):
Private Sub Form_MouseDown(Button As Integer, Shift As Integer,xAs Single, y As Single)
按下鼠标左键
If Button = vbcenterButton Then
为当前的应用程序释放鼠标捕获
ReleaseCapture
Select Case Action
Case “center”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF001, 0
Case “center”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF002, 0
Case “Up”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF003, 0
Case “centerUp”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF004, 0
Case “centerUp”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF005, 0
Case “Down”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF006, 0
Case “centerDown”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF007, 0
Case “centerDown”
SendMessage Me.hwnd, WM_SYSCOMMAND, HF008, 0
Case “Move”
SendMessage Me.hwnd, WM_SYSCOMMAND, SC_MOVE, 0
End Select
End If
End Sub
当用户按下左键时,为按下对象的MouseMove事件绑定处理方法,并记录鼠标坐标(窗体左上角为原点,在事件的MouseEventArgs类型的e参数中提供)。此时用户移动鼠标,保持窗体原点与鼠标新坐标的相对位置不变。当用户释放左键时,撤销按下对象的MouseMove事件处理方法
设置窗体的text为空,设置窗体的controlbox属性为false,设置窗体的FormBorderStyle 属性为Sizable,就可以改变窗体大小了,并且可以在任务栏点击。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流