سؤال

Until I touch the richedit window by mouse its contents are live updated, but hovering the mouse over it turns arrow into hourglass cursor. The window then doesn't react to three or four consequent tries to move it by title bar. When it finally does react to mouse dragging it moves fine but stops refreshing its contents and the title bar becomes empty. Similar effect is when I try to click the client area of the window. This time after a few clicks with no reaction window also stops updating and its title bar turns to (not responding).

When the loop eventually stops the program comes back window updates and comes back 'alive'. What to do to be able to manipulate the window (and see it's updating content) while it's client area is updated ?

#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);
  }
}
هل كانت مفيدة؟

المحلول 2

Found answer this is my revised code, look at PeekMessageW and 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);
  }
}

نصائح أخرى

You are populating the rich edit window in a tight loop, and not servicing your message queue. Unless your process is regularly attending to its message queue, the system thinks that your app has stopped responding. Well, it has stopped responding!

In order to keep your application responsive, you must pump your message queue. I don't really know what your real program is trying to do. If you wanted to put that text into a rich edit, you'd do so with a single EM_REPLACESEL message.

If you really do have a long running task then it belongs on a different thread. Then you have to deal with synchronizing back to the GUI thread. If all you do is call SendMessage then the system takes care of synchronizing that.

The bottom line is that must pump your message queue in a timely fashion.

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