SendMessage发送到TEdit后崩溃

时间:2013-12-04 19:47:34

标签: c++ winapi sendmessage

我正在尝试从其他程序获取数据。而且......它一直给我一个错误!有什么不对吗?

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;
    }

但是,如果我正在调试,它正在工作。

2 个答案:

答案 0 :(得分:3)

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

  

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

编辑控件的备注也很重要:

  

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

虽然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('\0');
std::wcout << Targets << "\n";

如果您要将WM_GETTEXT发送到挂起的应用程序,您的应用程序也会挂起。致电GetWindowText解决此问题。 The secret life of 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('\0');

关于为什么初始代码在调试器下运行时看起来有效的说法:它不是调试器,这会产生影响。这是 Debug Build 。调试配置将使用specific byte patternsoperator new[]()的0xCD)填充已分配的内存。这样做的结果是,发送EM_GETLINE时传递的缓冲区被解释为大小为0xCDCD(十进制为52685)。另一方面,在释放配置中,缓冲区内容通常是0x00,即缓冲区被解释为具有大小0.这并不是说调试构建工作。它只是掩盖了一个错误。

答案 1 :(得分:0)

我使用了GetWindowText,它的工作方式就像我不想使用花式计算那样。错误实际上出现在多行文本上,因为可以正确计算缓冲区大小。 MS Documentation GetWindowText