zoukankan      html  css  js  c++  java
  • 获得QQ聊天输入框中的内容

    // 首先得到输入框的句柄。通过spy++这类工具分析,聊天窗体的类名为“#32770”
    // 但当前系统里不只一个类名为“#32770”的窗体,这就需要全体遍历一次。
    // 类名为“#32770”标题含“聊天”基本能确定。为保险起见还判断一下所在进程是否为“qq.exe”
    uses PsAPI, RichEdit;
    function Process_ReadRichEditText(AHandle: THandle): WideString;
    var
      vGetTextEx: GETTEXTEX;
      vGetTextLengthEx: GETTEXTLENGTHEX;
      L: Integer;
      vProcessId: DWORD;
      vProcess: THandle;
      vPointer: Pointer;
      vNumberOfBytesRead: Cardinal;
    begin
      Result := '';
      if not IsWindow(AHandle) then Exit;
      GetWindowThreadProcessId(AHandle, @vProcessId);
      vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
        PROCESS_VM_WRITE, False, vProcessId);
      try
        vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,
          PAGE_READWRITE);
        vGetTextLengthEx.flags := GTL_DEFAULT;
        vGetTextLengthEx.codepage := 1200; // Unicode
        WriteProcessMemory(vProcess, vPointer, @vGetTextLengthEx,
          SizeOf(vGetTextLengthEx), vNumberOfBytesRead);
        L := SendMessage(AHandle, EM_GETTEXTLENGTHEX, Integer(vPointer), 0);
        VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
        if L <= 0 then Exit;
        vPointer := VirtualAllocEx(vProcess, nil, SizeOf(vGetTextEx) + L * 2 + 2,
          MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
        SetLength(Result, L);
        vGetTextEx.cb := L * 2 + 2;
        vGetTextEx.flags := GT_DEFAULT;
        vGetTextEx.codepage := 1200; // Unicode
        vGetTextEx.lpDefaultChar := nil;
        vGetTextEx.lpUsedDefChar := nil;
        WriteProcessMemory(vProcess, vPointer, @vGetTextEx,
          SizeOf(vGetTextEx), vNumberOfBytesRead);
        SendMessage(AHandle, EM_GETTEXTEX, Integer(vPointer),
          Integer(vPointer) + SizeOf(vGetTextEx));
        ReadProcessMemory(vProcess, Pointer(Integer(vPointer) + SizeOf(vGetTextEx)),
          @Result[1], L * 2, vNumberOfBytesRead);
        VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
      finally
        CloseHandle(vProcess);
      end;
    end; { Process_ReadRichEditText }
    function GetProcessName(AProcessID: THandle): string;
    var
      vBuffer: array[0..MAX_PATH] of Char;
      vProcess: THandle;
    begin
      vProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False,
        AProcessID);
      try
        if GetModuleBaseName(vProcess, 0, vBuffer, SizeOf(vBuffer)) > 0 then
          Result := vBuffer
        else Result := '';
      finally
        CloseHandle(vProcess);
      end;
    end; { GetProcessName }
    function EnumChild(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
    var
      vBuffer: array[0..255] of Char;
    begin
      Result := True;
      if not IsWindowVisible(hwnd) then Exit; // 不可见
      GetClassName(hwnd, vBuffer, SizeOf(vBuffer));
      if SameText(vBuffer, 'RichEdit20A') then
      begin
        if GetWindowLong(hwnd, GWL_STYLE) and ES_READONLY <> ES_READONLY then // 非只读
        begin
          PInteger(lParam)^ := hwnd;
          Result := False;
        end;
      end;
    end; { EnumChild }
    function EnumFunc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
    var
      vBuffer: array[0..255] of Char;
      vProcessId: THandle;
    begin
      Result := True;
      if not IsWindowVisible(hwnd) then Exit; // 不可见
      GetClassName(hwnd, vBuffer, SizeOf(vBuffer));
      if SameText(vBuffer, '#32770') then
      begin
        GetWindowThreadProcessId(hwnd, vProcessId);
        if SameText(GetProcessName(vProcessId), 'qq.exe') then
        begin
          GetWindowText(hwnd, vBuffer, SizeOf(vBuffer));
          if Pos('聊天中', vBuffer) > 0 then // 标题中含"聊天中"
          begin
            EnumChildWindows(hwnd, @EnumChild, lParam);
            Result := False;
          end;
        end;
      end;
    end; { EnumFunc }
    procedure TForm1.Button1Click(Sender: TObject);
    var
      vHandle: THandle;
    begin
      vHandle := 0;
      EnumWindows(@EnumFunc, Integer(@vHandle));
      if vHandle = 0 then Exit;
      Memo1.Text := Process_ReadRichEditText(vHandle);
    end;
    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));
    }


     
    http://blog.csdn.net/zswang/article/details/2009868
  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/findumars/p/6347994.html
Copyright © 2011-2022 走看看