获得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));
}
获得QQ聊天输入框中的内容的更多相关文章
- 屏蔽QQ聊天对话框中的广告
原文地址: 怎么在QQ聊天对话框中屏蔽广告_百度经验 http://jingyan.baidu.com/article/48a42057ca12c1a924250402.html QQ已经成为 ...
- Javascript 对输入框中的内容进行 “全选/反选”
<</span>script> document.write("<</span>ul>"); for(var i=0;i<&l ...
- vue时时监听input输入框中 输入内容 写法
Vue input 监听 使用 v-on:input="change" 实现即可 App.vue <template> <div> <md-field ...
- JS简单仿QQ聊天工具的制作
刚接触JS,对其充满了好奇,利用刚学到的一点知识,写了一个简单的仿QQ聊天的东西,其中还有很多的不足之处,有待慢慢提高. 功能:1.在输入框中输入内容,点击发送,即可在上方显示所输入内容. 2.点击‘ ...
- Web聊天应用中的表情插件
聊天应用中的表情插件 用于即时聊天应用的图片表情插件,具有展示表情.插入表情和表情编解码的功能 项目地址 看代码 看demo 原理介绍 web端的即时聊天中看到的表情,其实就是一张张表情图片,通过im ...
- 输入框中的空"",0,null的判断
改了一个小项目,里面有一个小的问题他们是这样提需求的.两个输入框,第一个输入框里面,输入的内容会对第二个输入框中的内容产生影响.具体是这样的:如果第一个输入框中的值不是“0”,那么第二个输入框就不能填 ...
- 八、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天输入框扩展面板的实现
聊天输入框扩展面板的实现 1.项目引言 2.腾讯云后台配置TXIM 3.配置项目并实现IM登录 4.会话好友列表的实现 5.聊天输入框的实现 6.聊天界面容器的实现 7.聊天消息项的实现 8.聊天输入 ...
- 在WEB项目中调用QQ通讯组件打开QQ聊天界面
在很多WEB项目中,需要提供在线服务的功能,加上自己的联系方式,例如:QQ,不用添加QQ好友也可以交谈,那这到底是怎么实现的呢? 对于这个功能,需要提到一个组件,即“QQ通讯组件”.QQ通讯组件是一种 ...
- QQ聊天气泡(图片拉伸不变样)、内容尺寸定制(高度随字数、字体而变)
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; /** QQ聊 ...
随机推荐
- [GeekBand] C++ 基础知识之 The Big Three
本文是GeekBand课程体系中,侯捷老师讲课内容的部分内容总结. 参考书籍如下:Effitive C++ C++ Primer 第五版 http://blog.csdn.net/lwbeyond/a ...
- 怎么样Windows7在配置ASPserverIIS
在百度经验浏览:http://jingyan.baidu.com/article/5553fa82ed97c765a23934f3.html Internet Information Services ...
- Android四个基本组件(2)之Service 服务与Content Provider内容提供商
一.Service 维修: 一Service 这是一个长期的生命周期,没有真正的用户界面程序,它可以被用于开发如监视类别节目. 表中播放歌曲的媒体播放器.在一个媒体播放器的应用中.应该会有多个acti ...
- jquery 源码学习(四)构造jQuery对象-工具函数
jQuery源码分析-03构造jQuery对象-工具函数,需要的朋友可以参考下. 作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原 ...
- C++调用IDL程序的做法(二)
作者:朱金灿 来源:http://blog.csdn.net/clever101 上次提到使用IDLDrawWidget Control 3.0来调用IDL程序,但是我们还有一些问题没有解决,比如C+ ...
- 右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐)
(1)右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐) QTDIR:D:\Software\Qt\Qt5.2.0\5.2.0\msvc2010_op ...
- OpenGl(二)点线设置、多边形镂空
1. 改变点的大小 OpenGL中默认点的大小是1个像素,使用函数glPointSIze可以调整点的大小,入参是GLfloat,相当于是浮点数. 相关代码: void myDisplay(void) ...
- Cocos2d-x3.1颗粒使用
1.头 #include "cocos2d.h" USING_NS_CC; class WaterWaveDemo : public Layer { public: static ...
- python发送电子邮件
或者收发邮件都得小心翼翼的,怕一不小心被有心人瞧见,又得被说说. 为了能发邮件而不被发现,嘿嘿.我就用python写了个邮件发送程序,用控制台控制,不了解的人一定以为哥还在编程工作呢.哈哈. 以下简介 ...
- 如何将任意文件固定在 Win10 的开始屏幕中
虽然Wox和Launchy是我日常启动程序的主力方式,不过开始屏幕的图标方便归类,这是快速启动工具所不能提供的,因此我也会将最常用的程序在开始屏幕上分类固定. 最近需要将一个常用的批处理文件(*.ba ...