向TEdit发送消息后崩溃

Crash after SendMessage to TEdit

本文关键字:崩溃 消息 TEdit      更新时间:2023-10-16

我正试图从另一个程序中获取数据。和它总是给我一个错误!有什么问题吗?

HWND hWnd = FindWindow(NULL, L"MyProgram");
    if (hWnd) 
    {
        HWND TPageControl = FindWindowEx(hWnd, NULL, L"TPageControl", NULL); 
        TPageControl = FindWindowEx(hWnd, TPageControl, L"TPageControl", NULL);
        HWND TTabSheet = FindWindowEx(TPageControl, NULL, L"TTabSheet", NULL); 
        HWND TEdit = FindWindowEx(TTabSheet, NULL, L"TEdit", NULL);
        int editlength = SendMessage(TEdit, WM_GETTEXTLENGTH, 0, NULL);                                     
        TCHAR* Targets = new TCHAR( editlength + 1 );
        int count = SendMessage(TEdit, EM_GETLINE, editlength + 1, (LPARAM) Targets);                   
        std::wcout << Targets << "n";
        //delete Targets;
    }

但如果我在调试,它就起作用了。

您没有遵循EM_GETLINE的文档。第一个参数指定行索引。我假设您正在将此消息发送到单行编辑控件,而它只是被忽略了。第二个参数必须保持缓冲区的长度:

在发送消息之前,请将此缓冲区的第一个字设置为缓冲区的大小(以TCHAR为单位)。

编辑控件的备注也是相关的:

复制的行不包含终止的null字符。

虽然EM_GETLINE的参数会自动跨进程边界封送(就像0W_USER-1范围内消息的所有消息参数一样),但如果您正在处理单行编辑控件:,则可能需要考虑发送WM_GETTEXT

int editlength = SendMessage(TEdit, WM_GETTEXTLENGTH, 0, NULL);
TCHAR* Targets = new TCHAR[editlength + 1];
int count = SendMessage(TEdit, WM_GETTEXT, editlength + 1, (LPARAM) Targets);
// NUL-terminate buffer in case the text did not fit
Targets[count] = _T('');
std::wcout << Targets << "n";

如果您将WM_GETTEXT发送到挂起的应用程序,那么您的应用程序也将挂起。请致电GetWindowText解决此问题。GetWindowText的秘密生活有额外的背景信息。

如果您需要从多行编辑控件中检索特定的行,以下内容更合适。与您的代码相反,它会发送EM_LINEINDEXEM_LINELENGTH消息来检索适当的缓冲区大小:

int characterIndex = SendMessage(TEdit, EM_LINEINDEX, lineIndex, 0);
int lineLength = SendMessage(TEdit, EM_LINELENGTH, characterIndex, 0);
TCHAR* pBuffer = new TCHAR[lineLength + 1];
// Set the size of the buffer
*(WORD*)pBuffer = lineLength + 1;
// Retrieve the line
int characterCount = SendMessage(TEdit, EM_GETLINE, lineIndex, (LPARAM)pBuffer);
// NUL-terminate buffer
pBuffer[characterCount] = _T('');

关于为什么初始代码在调试器下运行时似乎可以工作的一句话:这不是调试器,而是有区别的。这是调试构建。调试配置将用特定的字节模式(对于operator new[]()为0xCD)填充分配的内存。这样做的效果是,发送EM_GETLINE时通过的缓冲区被解释为具有0xCDCD大小(十进制52685)。另一方面,在释放配置中,缓冲区内容通常为0x00,即缓冲区被解释为具有大小0。这并不是说调试构建有效。它只是掩盖了一个错误。

我使用了GetWindowText,它的工作原理就像sharm,我不想使用花哨的计算。实际上,只有才会在多行文本中出现错误,因为缓冲区大小的计算是正确的。MS文档GetWindowText