c# 外部方法的学习

在讲解如何实现窗口的抖动上,先要了解外部方法的使用。对于一个外部方法的实现过程,具体步骤如下:

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();//获取当前窗体的句柄

举一个窗体抖动的实例来了解外部方法的具体引用

为了实现窗体抖动,我们需要引用三个外部方法来获取当前窗体的一系列参数。

  1. 实现获取当前窗体的功能的外部函数GetForegroundWinddow()

  2. 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);
        }

你可能感兴趣的:(c# 外部方法的学习)