• 捕捉桌面上的窗口信息


    今天我为大家带来一个有趣的例子,有点像Spy++的功能,通过鼠标在屏幕上移动,并实时捕捉指定坐标点处的窗口信息。

    窗口信息包括窗口标题,窗口句柄,窗口类名,以及呈现所捕捉窗口的缩略图。

    现在我们不妨来思考一下,要实现这些功能,我们需要准备哪些技术要点?

    1、获取当前鼠标指针的屏幕坐标,这个用System.Windows.Forms命名空间下的Cursor类的Position属性就可以知道当前鼠标指针的位置,屏幕坐标。

    2、如何从指定坐标处得到窗口,其实就是获得对应窗口的句柄,这里要使用一个API函数WindowFromPoint,它可以返回指定坐标处的窗口的句柄。这个窗口不一定指的就是完整的窗口,在Win32窗口中,一个控件也是一个窗口,桌面也是一个窗口。

    3、获取窗口的标题文本,使用API函数GetWindowText,根据窗口的句柄得到窗口的标题文本。

    4、获取窗口类名,使用API函数GetClassName,得到对应窗口所属的窗口类,这里所指的窗口类就是我们在开发Win32程序时,类似于在WinMain函数中用RegisterClass函数注册的类名。

    5、把窗口内容绘制成缩略图,这个简单,在System.Drawing命名空间下的Graphics类就有一个CopyFromScreen方法,可以从屏幕上复制图像,效果是等效于用BitBlt函数从桌面的DC复制到其他位置一样。

    6、我们并不是复制整个屏幕,而只是对应位置处的窗口,要获得窗口的矩形区域,可以调用API函数GetWindowRect。

    好了,现在技术要点解决了,接下来就是真刀真枪干了。

    首先是导入Win32的API。

    [csharp] view plain copy
     
    1. [DllImport("User32.dll",CallingConvention = CallingConvention.StdCall)]  
    2. public extern static IntPtr WindowFromPoint(int x, int y);  
    3.   
    4. [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall)]  
    5. public extern static int GetClassName(  
    6.     [In] IntPtr hwnd,  
    7.     [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpString,  
    8.     [In] int nMaxCount);  
    9.   
    10. [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall)]  
    11. public extern static int GetWindowText(  
    12.     [In] IntPtr hwnd,  
    13.     [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpString,  
    14.     [In] int nMaxCount);  
    15.   
    16. [DllImport("User32.dll")]  
    17. public extern static bool GetWindowRect(IntPtr hwnd, out RECT lpRect);  


     

    [csharp] view plain copy
     
    1. [StructLayout(LayoutKind.Sequential)]  
    2. public struct RECT  
    3. {  
    4.     public int left;  
    5.     public int top;  
    6.     public int right;  
    7.     public int bottom;  
    8. }  


    在整个桌面上处理鼠标移动事件不容易,这里我换一种思路,用Timer组件,每隔300毫秒获取一次信息,这样,当鼠标在屏幕上移动时,也能实时更新坐标信息。

    [csharp] view plain copy
     
    1. private void MyTimer_Tick(object sender, EventArgs e)  
    2. {  
    3.     IntPtr hwnd = WindowFromPoint(Cursor.Position.X, Cursor.Position.Y);  
    4.     if (hwnd!=IntPtr.Zero)  
    5.     {  
    6.         StringBuilder sbText = new StringBuilder();  
    7.         StringBuilder sbClass = new StringBuilder();  
    8.         try  
    9.         {  
    10.             // 获取窗口标题  
    11.             GetWindowText(hwnd, sbText, 260);  
    12.             // 获取窗口类名  
    13.             GetClassName(hwnd, sbClass, 256);  
    14.         }  
    15.         catch(Exception ex)  
    16.         {  
    17.             lblMessage.Text = ex.Message;  
    18.         }  
    19.         // 显示信息  
    20.         lblCurrentLocation.Text = string.Format("{0}, {1}", Cursor.Position.X, Cursor.Position.Y);  
    21.         lblCurrentHandle.Text = hwnd.ToString();  
    22.         lblWindowText.Text = sbText.ToString();  
    23.         lblClassName.Text = sbClass.ToString();  
    24.         // 绘制屏幕图像  
    25.         DrawToPicBox(hwnd);  
    26.     }  
    27. }  
    28.   
    29. Bitmap bmp = null;  
    30. private void DrawToPicBox(IntPtr hwnd)  
    31. {  
    32.     if (bmp != null)  
    33.     {  
    34.         bmp.Dispose();  
    35.     }  
    36.     RECT rect;  
    37.     if (GetWindowRect(hwnd, out rect))  
    38.     {  
    39.         bmp = new Bitmap(rect.right - rect.left, rect.bottom - rect.top);  
    40.         using (Graphics g = Graphics.FromImage(bmp))  
    41.         {  
    42.             // 将屏幕上的内容复制到Graphics中  
    43.             g.CopyFromScreen(rect.left, rect.top, 0, 0,  
    44.                 new Size(bmp.Width, bmp.Height), CopyPixelOperation.SourceCopy);  
    45.         }  
    46.         this.pictureBox1.Image = bmp;  
    47.     }  
    48. }  
    49.   
    50. private void btnStart_Click(object sender, EventArgs e)  
    51. {  
    52.     MyTimer.Start();  
    53.     btnStart.Enabled = false;  
    54.     btnStop.Enabled = true;  
    55. }  
    56.   
    57. private void btnStop_Click(object sender, EventArgs e)  
    58. {  
    59.     MyTimer.Stop();  
    60.     btnStart.Enabled = true;  
    61.     btnStop.Enabled = false;  
    62. }  


    运行后你能看到效果的。请看截图。

    好的,这个好玩的东东就到这里,稍候我上传源代码到资源区。

  • 相关阅读:
    js-jquery-003-条形码-二维码【QR码】
    js-jquery-002-条形码-一维码
    js-jquery-001-条形码概述
    java-mybaits-00401-Mapper-输入输出
    tools-eclipse-002-常用插件
    java-mybaits-00301-SqlMapConfig
    java-mybaits-00203-DAO-mapper代理开发方法,多参数【推荐】
    java-mybaits-00202-DAO-原始DAO开发方法
    java-mybaits-00201-DAO-SqlSession使用范围
    java-mybaits-00103-入门程序原生的【查、增、删、改】
  • 原文地址:https://www.cnblogs.com/weekbo/p/8682045.html
Copyright © 2020-2023  润新知