简体   繁体   English

WinAPI EM_STREAMOUT崩溃

[英]WinAPI EM_STREAMOUT crash

I'm trying to get the text of a Richedit Control from another program. 我正在尝试从另一个程序获取Richedit控件的文本。

So I found EM_STREAMOUT for SendMessage. 因此,我为SendMessage找到了EM_STREAMOUT。

This is my code so far (also from another Stackoverflow topic): 到目前为止,这是我的代码(也来自另一个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);

}

The only thing that happens is that SendMessage returns 0 - so obviously no bytes were read - and the program of which I'm trying to get the information out of goes up to 100% CPU usage. 唯一发生的是,SendMessage返回0-因此显然没有读取任何字节-并且我尝试从中获取信息的程序的CPU使用率高达100%。

Some messages, like WM_GETTEXT , are marshaled by Windows for you. Windows为您封送了一些消息,例如WM_GETTEXT That is why you can retrieve a window's text across process boundaries. 这就是为什么您可以跨过程边界检索窗口的文本。 EM_STREAMIN/OUT are not auto-marshaled. EM_STREAMIN/OUT未自动封送。 That is why your code is crashing. 这就是为什么您的代码崩溃的原因。 The EDITSTREAM struct and the callback code must exist in the address space of the same process that owns the RichEdit. EDITSTREAM结构和回调代码必须存在于拥有RichEdit的同一进程的地址空间中。

For many non-marshaled messages that need to cross process boundaries, you can allocate input/output buffers using VirtualAllocEx() , fill them using WriteProcessMemory() , and read from them using ReadProcessMemory() . 对于许多需要跨越进程边界的非编组消息,可以使用VirtualAllocEx()分配输入/输出缓冲区,使用WriteProcessMemory()填充它们,并使用ReadProcessMemory()从中读取。 But because the EDITSTREAM callback code needs to be in the same process as well, you are best off moving your entire EM_STREAMOUT logic into a DLL and then inject it into the target process using CreateRemoteThread() or other injection technique. 但是,由于EDITSTREAM回调代码也需要处于同一进程中,因此最好将整个EM_STREAMOUT逻辑移到DLL中,然后使用CreateRemoteThread()或其他注入技术将其注入到目标进程中。 You can use GetWindowThreadProcessId() to get the process/thread IDs that own the RichEdit. 您可以使用GetWindowThreadProcessId()获取拥有RichEdit的进程/线程ID。 Your DLL can then retrieve the RichEdit data and send it back to your main app using any IPC (Inter-Process Communication) mechanism of your choosing, such as a named pipe, a mailslot, the WM_COPYDATA message, etc. 然后,您的DLL可以检索RichEdit数据,并使用您选择的任何IPC(进程间通信)机制将其发送回您的主应用程序,例如命名管道,邮筒, WM_COPYDATA消息等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM