سؤال

I'm trying to get data from another program. And... it's giving me an error all the time! Is there something wrong?

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

but if i'm debugging, it's working.

هل كانت مفيدة؟

المحلول

You are not following the documentation for EM_GETLINE. The first parameter specifies the line index. I'm assuming you are sending this message to a single-line edit control, and it simply gets ignored. The second parameter must hold the length of the buffer:

Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer.

The remarks for edit controls are also relevant:

The copied line does not contain a terminating null character.

While parameters for EM_GETLINE get automatically marshaled across process boundaries (like all message parameters for messages in the range 0 to W_USER-1), you might want to consider sending WM_GETTEXT instead, if you are dealing with a single-line edit control:

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

If you are sending WM_GETTEXT to a hung application your application will hang as well. Call GetWindowText to work around this. The secret life of GetWindowText has additional background information.

If you need to retrieve a specific line from a multi-line edit control the following is more appropriate. In contrast to your code it sends an EM_LINEINDEX and EM_LINELENGTH message to retrieve the appropriate buffer size:

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');

A word on why the initial code appears to work when run under a debugger: It's not the debugger, that makes a difference. It's the Debug Build that does. A debug configuration will fill allocated memory with specific byte patterns (0xCD for operator new[]()). The effect of this is that the buffer passed when sending EM_GETLINE is interpreted as having size 0xCDCD (52685 in decimal). In a release configuration on the other hand, the buffer contents are usually 0x00, i.e. the buffer is interpreted as having size 0. This is not to say that the debug build works. It merely masks an error.

نصائح أخرى

I used GetWindowText, works like a sharm I did't want to use fancy calculations. The error really only appears on multiline text, since the buffer size would be calculated correctly. MS Documentation GetWindowText

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top