2013-12-04 4 views
0

Я пытаюсь получить данные из другой программы. И ... это постоянно дает мне ошибку! Здесь что-то не так?Crash after SendMessage to TEdit

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

но если я отлаживаю, он работает.

+1

http://stackoverflow.com/a/3635180/2604492 – Paul

+0

'EM_GETLINE', вероятно, неверное сообщение. Это единственная строка Delphi VCL 'TEdit'. Получите текст с помощью 'WM_GETTEXT'. –

+0

@David Я не думаю, что это элемент управления VCL. «TEdit» - неправильное название; это ведь «HWND». Вы правы, однако, что это однострочный элемент управления редактированием. Код - как указано - не удастся для почти любого многострочного редактирования, из-за неправильного 'WPARAM' для' EM_GETLINE'. – IInspectable

ответ

3

Вы не отвечаете требованиям документации для EM_GETLINE. Первый параметр указывает индекс строки. Я предполагаю, что вы отправляете это сообщение в однострочный элемент управления редактированием, и его просто игнорируют. Второй параметр должен содержать длину буфера:

Перед отправкой сообщения установите первое слово этого буфера в размере в буфере TCHAR.

Замечания для управления редактирования также относятся:

Скопированная строка не содержит завершающий нулевой символ.

Хотя параметры EM_GETLINE получить автоматически выстраивали через границы процессов (как и все параметры для сообщений в диапазоне 0 к W_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_LINEINDEX и EM_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 patterns (0xCD для operator new[]()). Эффект от этого заключается в том, что буфер, переданный при отправке EM_GETLINE, интерпретируется как имеющий размер 0xCDCD (52685 в десятичной форме). С другой стороны, в конфигурации выпуска содержимое буфера обычно равно 0x00, то есть буфер интерпретируется как имеющий размер 0. Это не означает, что работает отладочная сборка. Он просто маскирует ошибку.

+0

Я думал, что сообщение ниже WM_USER было маршалировано. EM_GETLINE должен быть, особенно если OP говорит, что его код работает под отладчиком. – manuell

+0

@manuell True, 'EM_GETLINE' находится под' WM_USER', поэтому вам не нужно выполнять сортировку параметров.Будет обновлен ответ. – IInspectable

+0

@Inspectable Большое спасибо! Теперь работает. – Sergey

Смежные вопросы