До тех пор, пока я не коснусь окна richedit мышью, его содержимое обновляется в режиме реального времени, но при наведении на него курсора стрелка превращается в курсор песочных часов. Окно не реагирует на три или четыре последовательных попытки переместить его по строке заголовка. Когда он, наконец, реагирует на перетаскивание мышью, он перемещается нормально, но перестает обновлять его содержимое, и строка заголовка становится пустой. Подобный эффект возникает, когда я пытаюсь щелкнуть по клиентской области окна. На этот раз после нескольких щелчков без окна реакции также перестает обновляться, и его строка заголовка превращается в (не отвечает).
Когда цикл в конечном итоге останавливается, программа возвращается к обновлению окна и возвращается «живым». Что нужно сделать, чтобы иметь возможность манипулировать окном (и видеть, как оно обновляет содержимое), пока обновляется его клиентская область?
#include <windows.h>
#include <sstream>
int main() {
using namespace std;
LoadLibrary("Msftedit.dll");
HWND richeditWindow = CreateWindowExW (
WS_EX_TOPMOST,
L"RICHEDIT50W",
L"window text",
WS_SYSMENU | WS_VSCROLL | ES_MULTILINE | ES_NOHIDESEL | WS_VISIBLE,
50, 50, 500, 500,
NULL, NULL, NULL, NULL
);
for (int i = 0 ; i<100000; i++) {
wstringstream wss;
wss << i << L", ";
SendMessageW(richeditWindow, EM_REPLACESEL, FALSE, (LPARAM) wss.str().c_str());
}
MSG msg;
while( GetMessageW( &msg, richeditWindow, 0, 0 ) ) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
Вы заполняете окно расширенного редактирования в узком цикле, а не обслуживаете свою очередь сообщений. Если ваш процесс не регулярно посещает свою очередь сообщений, система считает, что ваше приложение перестало отвечать на запросы. Ну, это перестало отвечать!
Чтобы приложение отвечало на запросы, вы должны прокачать очередь сообщений. Я действительно не знаю, что ваша настоящая программа пытается сделать. Если вы хотите поместить этот текст в расширенное редактирование, вы бы сделали это с одним EM_REPLACESEL
сообщение.
Если у вас действительно есть долгосрочное задание, то оно принадлежит другому потоку. Затем вам придется иметь дело с синхронизацией обратно в поток GUI. Если все, что вы делаете, это вызываете SendMessage, то система позаботится о синхронизации этого.
Суть в том, что вы должны своевременно прокачивать вашу очередь сообщений.
Нашел ответ, это мой пересмотренный код, посмотрите на PeekMessageW
а также DispatchMessageW
,
#include <windows.h>
#include <iostream>
#include <sstream>
int main() {
using namespace std;
LoadLibrary("Msftedit.dll");
HWND richeditWindow = CreateWindowExW (
WS_EX_TOPMOST,
L"RICHEDIT50W",
L"window text",
WS_SYSMENU | WS_VSCROLL | ES_MULTILINE | ES_NOHIDESEL | WS_VISIBLE,
50, 50, 500, 500,
NULL, NULL, NULL, NULL
);
MSG msg;
for (int i = 0 ; i<100000; i++) {
wstringstream wss;
wss << i << L", ";
SendMessageW(richeditWindow, EM_REPLACESEL, FALSE, (LPARAM) wss.str().c_str());
if (PeekMessageW(&msg, richeditWindow, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
while( GetMessageW( &msg, richeditWindow, 0, 0 ) ) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}