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

    原帖地址:http://blog.csdn.net/zswang/archive/2008/01/02/2009868.aspx
    // 首先得到输入框的句柄。通过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 <= 0return 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 
    * 2ref 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));
    }



  • 相关阅读:
    (转)AJAX开发中常用的Firefox Plugins
    几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比
    Excel Oledb设置
    统计数据库中所有表的基本信息
    sql 分页加排序等写法
    sql 创建索引
    SQL Server复制需要有实际的服务器名称才能连接到服务器 错误解决方案
    转转:解决Error"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系。"
    Reflector7.5.2.1的Bug
    查询数据库所有依赖
  • 原文地址:https://www.cnblogs.com/rainbow57/p/1441829.html
Copyright © 2011-2022 走看看