如何在 win32 gui 应用程序中使用另一个事件循环
Posted
技术标签:
【中文标题】如何在 win32 gui 应用程序中使用另一个事件循环【英文标题】:How to use another event loop in win32 gui application 【发布时间】:2019-06-01 09:53:13 【问题描述】:我是 win32 api 编程新手,我正在尝试使用 win32 api 和 gloox xmpp 库为 windows 平台编写 xmpp 客户端。 gloox 有自己的事件循环,而 windows GUI 也有消息循环。我不是很清楚如何一起使用这两个循环。
来自 gloox 文档:
阻塞与非阻塞连接 对于某些类型的机器人,阻塞连接(默认行为)是理想的。机器人所做的只是对来自服务器的事件做出反应。然而,对于最终用户客户端或任何带有 GUI 的东西来说,这远非完美。
在这些情况下,可以使用非阻塞连接。如果调用 ClientBase::connect( false ),则函数在连接建立后立即返回。然后由程序员负责从套接字开始接收数据。
最简单的方法是定期调用 ClientBase::recv() 并使用所需的超时时间(以微秒为单位)作为参数。默认值 -1 表示调用阻塞,直到收到任何数据,然后自动解析。
窗口消息循环:
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
窗口进程:
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
TCHAR str[100];
StringCbPrintf(str, _countof(str), TEXT("Message ID:%-6x:%s"), msg, GetStringMessage(msg));
OutputDebugString(str);
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (msg)
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("DRAW TEXT ON CLIENT AREA"), -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
return DefWindowProc(hWnd, msg, wParam, lParam);
gloox 阻塞连接
JID jid( "jid@server/resource" );
Client* client = new Client( jid, "password" );
client->registerConnectionListener( this );
client->registerPresenceHandler( this );
client->connect();// here will enter event loop
gloox 非阻塞连接
Client* client = new Client( ... );
ConnectionTCPClient* conn = new ConnectionTCPClient( client, client->logInstance(), server, port );
client->setConnectionImpl( conn );
client->connect( false );
int sock = conn->socket();
[...]
我不是很清楚我该怎么做
定期调用 ClientBase::recv() 并使用所需的超时时间(以微秒为单位)作为参数
有计时器吗?还是多线程编程?还是有更好的解决方案?
任何建议表示赞赏
谢谢
【问题讨论】:
【参考方案1】:最好的 IO 策略是重叠 IO。不幸的是,该方法仅适用于 windows,您选择的跨平台库不支持。
您可以使用 SetTimer() API,并在 WM_TIMER 处理程序中定期调用库的 recv() 方法,超时为零。这将引入额外的延迟(您的 PC 会收到一条消息,但它必须等待下一个计时器事件来处理它),或者如果您使用 20 毫秒等小间隔,则会消耗笔记本电脑或平板电脑的电池。
您可以将阻塞 API 与单独的线程一起使用。在性能方面更高效,但更难实现,您必须将消息和其他事件编组到 GUI 线程。 WM_USER+n 自定义窗口消息通常是最好的方法,顺便说一句。
【讨论】:
以上是关于如何在 win32 gui 应用程序中使用另一个事件循环的主要内容,如果未能解决你的问题,请参考以下文章