• 获得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
  • 相关阅读:
    gRPC java 客户端,服务器端通讯使用json格式
    HDTV(1920x1080)码率和视频质量关系的研究 2 (实验结果)
    Fedora 18/19没有注销
    window API一天一练之邮槽
    在C语言环境下使用google protobuf
    Cantor展开式
    LeetCode题解:Rotate List
    不知不觉vs2012 update 4出来了
    http://download.csdn.net/detail/yanzi1225627/6548337
    【虚拟化实战】Cluster设计之一资源池
  • 原文地址:https://www.cnblogs.com/findumars/p/6347994.html
Copyright © 2020-2023  润新知