WinAPI EM_STREAMOUT崩溃

时间:2014-02-22 23:03:33

标签: c++ c winapi sendmessage richedit

我正试图从另一个程序中获取Richedit Control的文本。

所以我发现了SendMessage的EM_STREAMOUT。

到目前为止,这是我的代码(也来自另一个Stackoverflow主题):

    DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    std::stringstream *rtf = (std::stringstream*) dwCookie;
    rtf->write((char*)pbBuff, cb);
    *pcb = cb;
    return 0;
}

int main() {
    std::stringstream rtf;

    EDITSTREAM es = {0};
    es.dwCookie = (DWORD_PTR) &rtf;
    es.pfnCallback = &EditStreamOutCallback;
    SendMessage((HWND) 0x00000000000A06E8, EM_STREAMOUT, SF_RTF, (LPARAM)&es);

}

唯一发生的事情是SendMessage返回0 - 所以显然没有读取字节 - 我试图从中获取信息的程序的CPU使用率达到100%。

1 个答案:

答案 0 :(得分:1)

某些消息(如WM_GETTEXT)由Windows为您编组。这就是为什么您可以跨进程边界检索窗口的文本。 EM_STREAMIN/OUT不会自动封送。这就是你的代码崩溃的原因。 EDITSTREAM结构和回调代码必须存在于拥有RichEdit的同一进程的地址空间中。

对于许多需要跨越进程边界的非封送消息,您可以使用VirtualAllocEx()分配输入/输出缓冲区,使用WriteProcessMemory()填充它们,并使用ReadProcessMemory()读取它们。但是因为EDITSTREAM回调代码也需要在同一个进程中,所以最好将整个EM_STREAMOUT逻辑移动到DLL中,然后使用CreateRemoteThread()将其注入目标进程或其他注射技术。您可以使用GetWindowThreadProcessId()来获取拥有RichEdit的进程/线程ID。然后,您的DLL可以使用您选择的任何IPC(进程间通信)机制检索RichEdit数据并将其发送回主应用程序,例如命名管道,邮件槽,WM_COPYDATA消息等。< / p>