#c #windows #winapi
#c #Windows #winapi
Вопрос:
Существует ли стандартное сообщение, которое можно отправить в окно текстового редактора или определенный вызов WinAPI, который извлечет содержимое редактируемого в данный момент текста?
Например, для извлечения текущего содержимого окна Блокнота. (предполагается, что самый актуальный текст еще не был записан в файл)
Я пытался получить текст с помощью SendMessage
using WM_GETTEXT
, WM_GETTEXTLENGTH
но мне удалось получить только текст заголовка.
Комментарии:
1. Используйте
WM_GETTEXTLENGTH
, чтобы узнать, сколько символов содержится в редакторе, затем выделите буфер такого размера и используйтеWM_GETTEXT
илиGetWindowText()
, чтобы заполнить его фактическим текстом редактора. Если вам нужен только выделенный текст, используйтеEM_GETSEL
/EM_EXGETSEL
впоследствии, чтобы определить начальные / конечные индексы диапазона выбранных символов в этом тексте, а затем скопируйте эти символы в другой буфер.2. Обычно вы перечисляете идентификаторы всех процессов, проверяете, что процесс имеет требуемое имя, например «notepad.exe «. Затем перечислите все потоки для этого процесса. Затем используйте
EnumThreadWindows
API для получения дескрипторов Windows. Затем проверьте тип / класс окна — вам нужны только текстовые поля для редактирования. Наконец, вы можете использоватьchar text[256]; LRESULT result = SendMessage(windowHandle, WM_GETTEXT, sizeof(text), LPARAM(text));
3.
WM_GETTEXT
будет надежно работать в некоторых программах, но в более общем плане вы хотите использовать специальные API, которые использует программное обеспечение «программа чтения с экрана»4. «Есть ли стандартное сообщение» — В общем, нет. «[…] или определенный вызов WinAPI» — Да, Автоматизация пользовательского интерфейса .
5. Для произвольного текстового редактора нет. Самое близкое, что вы получите, — это Автоматизация пользовательского интерфейса
Ответ №1:
В общем, нет стандартного сообщения для этого нет.
Но в Блокноте Windows есть дочерний элемент «Редактировать», который отвечает на WM_GETTEXT
и WM_GETTEXTLENGTH
— сообщения, обычно используемые для извлечения текста из элементов управления вводом.
Вот PoC, демонстрирующий идею:
#include <iostream>
#include <vector>
#include <string.h>
#include <Windows.h>
BOOL CALLBACK enumProc(HWND hwnd, LPARAM) {
std::vector<char> buf(100);
GetClassNameA(hwnd, buf.data(), 100);
if (strcmp(buf.data(), "Notepad")) return TRUE;
hwnd = FindWindowEx(hwnd, NULL, "Edit", NULL);
if (!hwnd) return TRUE;
int textLength = SendMessageA(hwnd, WM_GETTEXTLENGTH, 0, 0) 1;
if (textLength <= 0) return TRUE;
buf.resize(textLength);
SendMessage(hwnd, WM_GETTEXT, textLength, (LPARAM)buf.data());
std::cout << buf.data() << "n";
return TRUE;
}
int main() {
EnumWindows(amp;enumProc, 0);
}
Работает в Windows 10:
Комментарии:
1. Я пробовал использовать WM_GETTEXT — разве он не возвращает только заголовок окна?
2. Вам нужно получить дочерний элемент «Редактировать» — смотрите мой код, он работает.
3. Все, что более продвинуто, чем блокнот, не будет использовать элемент управления редактированием, поэтому мне интересно, насколько полезен этот ответ на самом деле.
4. @JonathanPotter в первом предложении в ответе говорится, что стандартного способа извлечения текста не существует, что, к сожалению, является допустимым ответом.
5. Существует стандартный способ. Это автоматизация пользовательского интерфейса. Но не каждая программа поддерживает это.