C#获取QQ聊天输入框中的内容

// 首先得到输入框的句柄。通过spy++这类工具分析,聊天窗体的类名为“#32770”
// 但当前系统里不只一个类名为“#32770”的窗体,这就需要全体遍历一次。
// 类名为“#32770”标题含“聊天”基本能确定。为保险起见还判断一下所在进程是否为“qq.exe”

 C#获取QQ聊天输入框中的内容代码如下:

 
  

using System.Runtime.InteropServices;

[DllImport("User32.DLL")] public static extern int SendMessage(     IntPtr hWnd, uint Msg, int wParam, int lParam);

public delegate bool WNDENUMPROC(     IntPtr hwnd, int lParam);

[DllImport("user32.dll")] public static extern int EnumWindows(     WNDENUMPROC lpEnumFunc, int lParam);

[DllImport("user32.dll")] public static extern int EnumChildWindows(     IntPtr hWndParent,WNDENUMPROC lpEnumFunc, int lParam);

[DllImport("user32.dll")] public static extern int GetWindowText(     IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")] public static extern int GetClassName(     IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll")] public static extern bool IsWindow(IntPtr hWnd);

[DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.DLL")] public static extern IntPtr FindWindowEx(     IntPtr hwndParent, IntPtr hwndChildAfter,     string lpszClass, string lpszWindow);

[DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(     IntPtr hWnd, out uint dwProcessId);

[DllImport("psapi.dll")] public static extern uint GetModuleBaseName(     IntPtr hProcess, IntPtr hModule,     StringBuilder lpBaseName, uint nSize);

public const uint PROCESS_VM_OPERATION = 0x0008; public const uint PROCESS_VM_READ = 0x0010; public const uint PROCESS_VM_WRITE = 0x0020; public const uint PROCESS_QUERY_INFORMATION = 0x0400;

[DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(     uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

[DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr handle);

[DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

public const int GWL_STYLE = -16; public const int ES_READONLY = 0x800; public const uint MEM_COMMIT = 0x1000; public const uint MEM_RELEASE = 0x8000; public const uint MEM_RESERVE = 0x2000; public const uint PAGE_READWRITE = 4;

[DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(     IntPtr hProcess, IntPtr lpAddress, uint dwSize,     uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll")] public static extern bool VirtualFreeEx(     IntPtr hProcess, IntPtr lpAddress,     uint dwSize, uint dwFreeType);

[DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(     IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer,     int nSize, ref uint vNumberOfBytesRead);

[DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(     IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer,     int nSize, ref uint vNumberOfBytesRead);

private IntPtr richHandle;

public string GetProcessName(uint AProcessId) {       StringBuilder vBuffer = new StringBuilder(256);        IntPtr vProcess = OpenProcess(         PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,         false, AProcessId);     try        {             if (GetModuleBaseName(             vProcess, IntPtr.Zero, vBuffer,             (uint)vBuffer.Capacity) > 0)         {             return vBuffer.ToString();          }         else             return string.Empty;     }        finally     {               CloseHandle(vProcess);       } }

public bool EnumChild(IntPtr hwnd, int lParam) {       if (!IsWindowVisible(hwnd))         return true; // 不可见          StringBuilder vBuffer = new StringBuilder(256);        GetClassName(hwnd, vBuffer, vBuffer.Capacity);         if (vBuffer.ToString().ToLower() == "richedit20a")        {                if ((GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY)             != ES_READONLY) // 非只读         {                        richHandle = hwnd;              return false;             }     }        return true; }

public bool EnumFunc(IntPtr hwnd, int lParam) {        if (!IsWindowVisible(hwnd))         return true; // 不可见          StringBuilder vBuffer = new StringBuilder(256);     GetClassName(hwnd, vBuffer, vBuffer.Capacity);         if (vBuffer.ToString() == "#32770")     {                uint vProcessId;               GetWindowThreadProcessId(hwnd, out vProcessId);         if (GetProcessName(vProcessId).ToLower() == "qq.exe")         {                      GetWindowText(hwnd, vBuffer, vBuffer.Capacity);             // 标题中含"聊天中"             if (vBuffer.ToString().IndexOf("聊天中") >= 0)             {                               EnumChildWindows(hwnd, @EnumChild, lParam);                   return false;                    }               }       }       return true; }

[StructLayout(LayoutKind.Sequential)] public struct GETTEXTLENGTHEX {        public uint flags;        public uint codepage; }

[StructLayout(LayoutKind.Sequential)] public struct GETTEXTEX {       public int cb;      public int flags;       public int codepage;      public IntPtr lpDefaultChar;      public IntPtr lpUsedDefChar; }

public const int GTL_DEFAULT = 0; public const int GT_DEFAULT = 0; public const int WM_USER = 0x0400; public const int EM_GETTEXTEX = WM_USER + 94; public const int EM_GETTEXTLENGTHEX = WM_USER + 95;

public string Process_ReadRichEditText(IntPtr AHandle) {        if (!IsWindow(AHandle))         return string.Empty;           string vReturn = string.Empty;       uint vProcessId;          GetWindowThreadProcessId(AHandle, out vProcessId);     IntPtr vProcess = OpenProcess(         PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,         false, vProcessId);     try     {                uint vNumberOfBytesRead = 0;         IntPtr vPointer = VirtualAllocEx(             vProcess, IntPtr.Zero, 0x1000,             MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);                 GETTEXTLENGTHEX vGetTextLengthEx = new GETTEXTLENGTHEX();           vGetTextLengthEx.flags = GTL_DEFAULT;             vGetTextLengthEx.codepage = 1200; // Unicode           IntPtr vAddress = Marshal.AllocCoTaskMem(             Marshal.SizeOf(vGetTextLengthEx));         Marshal.StructureToPtr(vGetTextLengthEx, vAddress, false);             WriteProcessMemory(vProcess, vPointer, vAddress,                            Marshal.SizeOf(vGetTextLengthEx),                            ref vNumberOfBytesRead);         Marshal.FreeCoTaskMem(vAddress);                       int L = SendMessage(             AHandle, EM_GETTEXTLENGTHEX,             (int)vPointer, 0);         VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);                 if (L <= 0)             return vReturn;                  GETTEXTEX vGetTextEx = new GETTEXTEX();               vGetTextEx.cb = L * 2 + 2;              vGetTextEx.flags = GT_DEFAULT;             vGetTextEx.codepage = 1200; // Unicode              vGetTextEx.lpDefaultChar = IntPtr.Zero;               vGetTextEx.lpUsedDefChar = IntPtr.Zero;                    vPointer = VirtualAllocEx(vProcess, IntPtr.Zero,                   (uint)(Marshal.SizeOf(vGetTextEx) + L * 2 + 2),                   MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);         vAddress = Marshal.AllocCoTaskMem(Marshal.SizeOf(vGetTextEx));                 Marshal.StructureToPtr(             vGetTextEx, vAddress, false);         WriteProcessMemory(vProcess, vPointer, vAddress,                            Marshal.SizeOf(vGetTextEx),                            ref vNumberOfBytesRead);         Marshal.FreeCoTaskMem(vAddress);                SendMessage(AHandle, EM_GETTEXTEX, (int)vPointer,                     (int)vPointer + Marshal.SizeOf(vGetTextEx));         vAddress = Marshal.AllocCoTaskMem(L * 2);                ReadProcessMemory(vProcess,           (IntPtr)((int)vPointer + Marshal.SizeOf(vGetTextEx)),           vAddress, L * 2, ref vNumberOfBytesRead);         vReturn = Marshal.PtrToStringUni(vAddress, L * 2);               Marshal.FreeCoTaskMem(vAddress);                VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);        }        finally        {                CloseHandle(vProcess);     }        return vReturn; }

private void button1_Click(object sender, EventArgs e) {        richHandle = IntPtr.Zero;      EnumWindows(EnumFunc, 0);       if (richHandle == IntPtr.Zero)         return;     Console.WriteLine(Process_ReadRichEditText(richHandle)); }

你可能感兴趣的:(C#获取QQ聊天输入框中的内容)