程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 如何捕捉桌面上的窗口信息

如何捕捉桌面上的窗口信息

編輯:關於C#

今天我為大家帶來一個有趣的例子,有點像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;  
}

運行後你能看到效果的。請看截圖。

好的,這個好玩的東東 就到這裡,稍候我上傳源代碼到資源區。

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved