为啥将文本添加到 RichEdit 窗口会冻结它?
Posted
技术标签:
【中文标题】为啥将文本添加到 RichEdit 窗口会冻结它?【英文标题】:why adding text to RichEdit window freezes it?为什么将文本添加到 RichEdit 窗口会冻结它? 【发布时间】:2013-01-24 21:35:02 【问题描述】:在我用鼠标触摸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);
【问题讨论】:
【参考方案1】:您正在一个紧密的循环中填充丰富的编辑窗口,而不是为您的消息队列提供服务。除非您的进程定期处理其消息队列,否则系统会认为您的应用程序已停止响应。好吧,它已经停止响应了!
为了让您的应用程序保持响应,您必须抽取消息队列。我真的不知道您的实际程序正在尝试做什么。如果您想将该文本放入丰富的编辑中,您可以使用单个 EM_REPLACESEL
消息来实现。
如果您确实有一个长时间运行的任务,那么它属于不同的线程。然后你必须处理同步回 GUI 线程。如果您所做的只是调用 SendMessage,那么系统会负责同步。
底线是必须及时抽出您的消息队列。
【讨论】:
【参考方案2】:找到答案这是我修改后的代码,看看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);
【讨论】:
那个代码全错了。您需要检查 PeekMessage 的返回值。那里可能没有消息。如果那里有任何东西,你真的应该清空队列。否则,您将按下键,然后添加更多文本,然后按下键,依此类推。那会好吗?您应该调用翻译消息。但是,您为什么不一口气添加所有文本呢?更重要的是,像这样乱七八糟的队列是混乱和糟糕的形式。在不同的线程中运行循环。另外,如果用户开始打字怎么办。现在他们的文字和你的混在一起了。 是的,我知道代码看起来不专业,但它确实有效,我并不那么着迷于幕后发生的事情,让计算机感受到痛苦,计算机是为人类而不是其他绕路。无论如何,这只是一个例子。 没有任何改进可以解决这个问题。我很难知道我的答案有什么问题。 我已将 PeekMessage 放入 if 语句中。更好的 ?效果一样。 您仍然需要清空队列。一次发送一条消息是不好的。不管怎样,我已经告诉你了。你明白我的回答了吗?以上是关于为啥将文本添加到 RichEdit 窗口会冻结它?的主要内容,如果未能解决你的问题,请参考以下文章