Получение текста с помощью SendMessage () C

#c #winapi

#c #winapi

Вопрос:

Я пытаюсь получить текст из текстового поля в определенном окне. Для этого я использую функцию Api SendMessage, я не знаю, правильный ли это способ:

 SendMessage(hwnd, WM_GETTEXT, 0, 0);
  

Но я не знаю, как распечатать текст. Для аргументов 3 и 4 на сайте msdn указано: Дополнительная информация, относящаяся к конкретному сообщению. Поэтому я не знаю, нужно ли мне передавать что-то еще, кроме 0. Я тоже пробовал это:

 SendMessage(hwnd, WM_GETTEXT, sizeof(text), LPARAM(text));
  

Но он печатает имя текстового поля, мне нужно извлечь текст внутри поля?
Как я могу это сделать? Является ли SendMessage () правильной функцией API для использования?

Спасибо.

Редактировать:

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

Комментарии:

1. Текстовые поля не имеют имени. Вы пытаетесь прочитать что-то еще.

2. @Mark Ransom: как я могу проверить, является ли дочернее окно текстовым полем? Спасибо.

Ответ №1:

Вам следует использовать GetWindowText. Более подробная информация здесь.

Комментарии:

1. Все то же самое, я получаю имя текстового поля, а не то, что оно находится здесь внутри

2. @vBx: Хорошо, предположение здесь: под именем текстового поля, я так понимаю, вы имеете в виду третий параметр для CreateWindowEx (или эквивалент)? Фактически это должно быть содержимое текстового поля — когда вы даете текстовому полю имя, это то, что оно отображает в качестве своего содержимого. Аналогично, если вы читаете его название, вы фактически читаете его содержимое. Если он этого не делает, происходит что-то забавное.

3. Если в окне определен заголовок, это то, что GetWindowText() и WM_GETTEXT возвращает. Убедитесь, что вы указываете HWND самого текстового поля, а не его родительского окна.

4. Хорошо, я опускаю сказать, что я перечисляю дочерние окна из окна, и для меня это выглядит как текстовое поле, где вы должны ввести имя. Я извлекаю имя пользователя из окна обмена мгновенными сообщениями, поэтому я не могу сравнить его со строкой, это текстовое поле?

5. @vBx: стандартное имя класса управления редактированием — «Редактировать». Spy отображает идентификаторы в шестнадцатеричном формате, поэтому 000000D3 является шестнадцатеричным для целого значения 211. Если вы хотите жестко прописать шестнадцатеричное число в своем коде, вы должны использовать 0x префикс, т.Е.: 0x000000D3 .

Ответ №2:

Прочитайте документацию MSDN еще раз. В нем НЕ указано «Дополнительная информация, относящаяся к конкретному сообщению» для этих параметров:

wParam Максимальное количество копируемых символов, включая завершающий нулевой символ.

В приложениях ANSI размер строки в буфере может быть уменьшен (как минимум вдвое по сравнению со значением wParam) из-за преобразования из ANSI в Unicode.

lParam Указатель на буфер, который должен принимать текст.

Комментарии:

1. Ну, я взял документацию со страницы SendMessage (), вот как там написано

2. В любом случае, версия corect является второй, но почему я получаю имя текстового поля, а не текст внутри текстового поля?

3. SendMessage() это функция общего назначения, поэтому ее документированные параметры произвольны. Вам нужно посмотреть документацию для конкретного сообщения, чтобы узнать, что представляют параметры. Что касается вашего кода, использование sizeof like you are будет корректно работать только в том случае, если вы отправляете WM_GETTEXT сообщение в окно Ansi, а не в окно Unicode. Используется IsWindowUnicode() , чтобы узнать, использовать ли буфер Ansi или буфер Unicode. Что касается того, почему вы получаете имя текстового поля, либо вы отправляете сообщение не туда HWND с самого начала, либо текстовое поле имеет WS_CAPTION стиль.

4. Я по ошибке получал дескриптор метки … но теперь я не знаю, как получить дескриптор текстового поля, вы знаете, как я могу проверить, является ли дочернее окно текстовым полем?

Ответ №3:

Этот код работает только для локальных:

 char *szText;
szText = (char *)GlobalAlloc(GPTR, 255);
SendMessage(hEditControl, WM_GETTEXT, 255, (LPARAM)szText);
MessageBox(hWnd, szText, "It's your message", MB_OK | MB_TOPMOST);
GlobalFree((HGLOBAL)szText);