zoukankan      html  css  js  c++  java
  • 捕捉桌面上的窗口信息

    今天我为大家带来一个有趣的例子,有点像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。

            [DllImport("User32.dll",CallingConvention = CallingConvention.StdCall)]
            public extern static IntPtr WindowFromPoint(int x, int y);
    
            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall)]
            public extern static int GetClassName(
                [In] IntPtr hwnd,
                [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpString,
                [In] int nMaxCount);
    
            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall)]
            public extern static int GetWindowText(
                [In] IntPtr hwnd,
                [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpString,
                [In] int nMaxCount);
    
            [DllImport("User32.dll")]
            public extern static bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
    


     

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }
    


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

            private void MyTimer_Tick(object sender, EventArgs e)
            {
                IntPtr hwnd = WindowFromPoint(Cursor.Position.X, Cursor.Position.Y);
                if (hwnd!=IntPtr.Zero)
                {
                    StringBuilder sbText = new StringBuilder();
                    StringBuilder sbClass = new StringBuilder();
                    try
                    {
                        // 获取窗口标题
                        GetWindowText(hwnd, sbText, 260);
                        // 获取窗口类名
                        GetClassName(hwnd, sbClass, 256);
                    }
                    catch(Exception ex)
                    {
                        lblMessage.Text = ex.Message;
                    }
                    // 显示信息
                    lblCurrentLocation.Text = string.Format("{0}, {1}", Cursor.Position.X, Cursor.Position.Y);
                    lblCurrentHandle.Text = hwnd.ToString();
                    lblWindowText.Text = sbText.ToString();
                    lblClassName.Text = sbClass.ToString();
                    // 绘制屏幕图像
                    DrawToPicBox(hwnd);
                }
            }
    
            Bitmap bmp = null;
            private void DrawToPicBox(IntPtr hwnd)
            {
                if (bmp != null)
                {
                    bmp.Dispose();
                }
                RECT rect;
                if (GetWindowRect(hwnd, out rect))
                {
                    bmp = new Bitmap(rect.right - rect.left, rect.bottom - rect.top);
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        // 将屏幕上的内容复制到Graphics中
                        g.CopyFromScreen(rect.left, rect.top, 0, 0,
                            new Size(bmp.Width, bmp.Height), CopyPixelOperation.SourceCopy);
                    }
                    this.pictureBox1.Image = bmp;
                }
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                MyTimer.Start();
                btnStart.Enabled = false;
                btnStop.Enabled = true;
            }
    
            private void btnStop_Click(object sender, EventArgs e)
            {
                MyTimer.Stop();
                btnStart.Enabled = true;
                btnStop.Enabled = false;
            }
    


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

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

  • 相关阅读:
    树上倍增求LCA(最近公共祖先)
    NOI题库分治算法刷题记录
    NOI题库刷题日志 (贪心篇题解)
    O(nlogn)LIS及LCS算法
    BLOG搬家
    『素数 Prime判定和线性欧拉筛法 The sieve of Euler』
    『扩展欧几里得算法 Extended Euclid』
    『NOIP2018普及组题解』
    P25、面试题1:赋值运算符函数
    字符串转成整数
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3102228.html
Copyright © 2011-2022 走看看