在讲解如何实现窗口的抖动上,先要了解外部方法的使用。对于一个外部方法的实现过程,具体步骤如下:
1.需要添加引用
using System.Runtime.InteropServices;//提供了各类对com组件的互操作(便于外部调用系统dll文件)
2.声明和实现的连接[DllImport("kernel32",SetLastError=true)]
[DllImport("user32.dll")]
3.声明外部方法
private static extern IntPtr GetForegroundWindow();//intptr类型称为“平台特定的整数类型”用于本机资源,如窗口句柄 //功能:获取当前活动窗体
4.对外部方法的操作
intptr = GetForegroundWindow();//获取当前窗体的句柄
举一个窗体抖动的实例来了解外部方法的具体引用
为了实现窗体抖动,我们需要引用三个外部方法来获取当前窗体的一系列参数。
实现获取当前窗体的功能的外部函数GetForegroundWinddow()
private static extern IntPtr GetForegroundWindow();
函数功能:获取一个前台窗口的句柄(窗口与用户当前的工作)。
返回值:返回值是一个前台窗口的句柄,在某些情况下,如果一个窗口失去激活时,前台窗口可以是null。
private IntPtr intptr;//句柄变量 intptr = GetForegroundWindow();//获取当前窗体的句柄
第二个外部函数:MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);//调整目标窗体的位置和尺寸
函数功能:函数功能:改变指定窗口的位置和大小.对顶窗口来说,位置和大小取决于屏幕的左上角;对子窗口来说,位置和大小取决于父窗口客户区的左上角.对于Owned窗口,位置和大小取决于屏幕左上角.
函数原型:BOOL MoveWindow( HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint );
hWnd指定了窗口的句柄
x指定了CWnd的左边的新位置。
y指定了CWnd的顶部的新位置。
nWidth指定了CWnd的新宽度。
nHeight指定了CWnd的新高度。
bRepaint指定了是否要重画CWnd。如果为TRUE,则CWnd象通常那样在OnPaint消息处理函数中接收到一条WM_PAINT消息。如果这个参数为FALSE,则不会发生任何类型的重画操作。这应用于客户区、非客户区(包括标题条和滚动条)和由于CWnd移动而露出的父窗口的任何部分。当这个参数为FALSE的时候,应用程序必须明确地使CWnd和父窗口中必须重画的部分无效或重画。
窗体的移动(代码如下)
[DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);//调整目标窗体的位置和尺寸 MoveWindow(intptr, rect.Left - intZ, rect.Top - intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true);//调整获取的窗体位置和尺寸
第三个外部函数:GetWindowRect(IntPtr hWnd,out RECT lpRect);//获取窗体相对屏幕的位置
函数功能:该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。
函数原型:BOOL GetWindowRect(HWND hWnd,LPRECT lpRect);
hWnd:窗口句柄。
lpRect:指向一个RECT结构的指针,该结构接收窗口的左上角和右下角的屏幕坐标。
具体实现:
GetWindowRect(intptr, out rect);//获取该窗体的位置和尺寸,传给rect
其实实现窗体的抖动,原理很简单,就是通过外部函数,来获取当前的窗体的句柄,以及尺寸,然后通过改变他的尺寸和位置来获取新的位置和大小。来实现抖动的。
具体实现如下:
[DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow();//intptr类型称为“平台特定的整数类型”用于本机资源,如窗口句柄 //功能:获取当前活动窗体 [DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);//调整目标窗体的位置和尺寸 [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)]//【疑问】起什么作用呢 public static extern bool GetWindowRect(IntPtr hWnd,out RECT lpRect);//获取窗体相对屏幕的位置 [StructLayout(LayoutKind.Sequential)]//指定结构体按顺序布局。 public struct RECT//结构体类型RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } private IntPtr intptr;//句柄变量 private void Form2_Load(object sender, EventArgs e) { timer1.Enabled = true; timer1.Interval = 100; timer1.Start(); button1_Click(sender, e);//【疑问】这样把加载事件里面的参数传入到按钮事件里面有什么作用呢?? //button1_Click(this, e);//这样写也是可以的 } private void button1_Click(object sender, EventArgs e) { timer1.Tick += (sender1, e1) => { findWindows();//委托这个方法去寻找窗体 }; } private void findWindows() { RECT rect = new RECT(); Random rd = new Random(); int intZ = rd.Next(10,20); intptr = GetForegroundWindow();//获取当前窗体的句柄 GetWindowRect(intptr, out rect);//获取该窗体的位置和尺寸,传给rect MoveWindow(intptr, rect.Left - intZ, rect.Top - intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true);//调整获取的窗体位置和尺寸 Thread.Sleep(intZ); MoveWindow(intptr, rect.Left, rect.Top - intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left + intZ, rect.Top + intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left+intZ, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left + intZ, rect.Top + intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left, rect.Top + intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left-intZ, rect.Top + intZ, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left - intZ, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, true); Thread.Sleep(intZ); MoveWindow(intptr, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top, true); }