最近做一个抓取qq用户资料的工具,需要获取qq窗口上的消息,以前这种任务是用句柄获取窗口中的信息,现在qq的窗口用的是DirectUI,只有窗口句柄,没有控件句柄,句柄这条路走不通了。不过较新版的qq的部分控件实现了微软的IAccessible接口(称为Microsoft Active Accessibility技术,简称MSAA),可以用另一套函数获取qq窗口的信息。不过要对窗口进行输入还是要靠句柄,上面说过,DirectUI的窗口只有一个句柄,因此模拟输入的时候不需要查找到具体的控件句柄,但要注意获取控件焦点,可能相对传统WinForm的窗口要简单点。
先介绍下和句柄操作相关的函数:
using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError =true)]
static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
根据类名和窗口标题查找句柄
[DllImport("user32.dll", SetLastError =true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle,IntPtr childAfter, string className, string windowTitle);
根据父句柄,前一个句柄,类名和窗口标题查找句柄,这几个信息可以通过VS自带的spy++查询。
[DllImport("user32.dll", EntryPoint ="GetDesktopWindow", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetDesktopWindow();
返回桌面窗口句柄,被我用来当前一个函数的父句柄。
[DllImport("user32.dll")]
public extern static int GetWindowText(IntPtr hWnd,StringBuilder lpString, int nMaxCount);
获取指定窗口的标题,WinForm里的控件都是window,但在我们讨论的情况下window就只是窗口了。需要结合StringBuider类使用,不熟悉的可以去预习下。
[DllImport("User32.dll")]
public static extern int GetClassName(int hWn