【问题标题】:WinAPI - message loop with own callbackWinAPI - 带有自己回调的消息循环
【发布时间】:2012-04-03 00:30:57
【问题描述】:

通常的 WinAPI 消息循环如下所示:

MSG msg;
while (GetMessage(&msg, hwnd, 0, 0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

是否允许不调用 DispatchMessage() 而是自己处理消息?如果不是,我该如何在避免全局变量和线程问题的同时很好地处理这种行为?

编辑: 我基本上想使用我自己的回调函数,它没有 WndProc 签名。但是我想不出在不使用静态或全局变量的情况下从 WndProc 中调用该函数的方法。 [这需要锁定,我认为这不是您可以使用可能非常频繁调用的回调函数所做的最好的事情。]

感谢您的帮助。

【问题讨论】:

  • avoiding global variables and thread problems 你能解释一下你的意思吗?
  • @Jesse:我希望他指的是与使用非 const 且由多个线程访问的全局变量相关的常见问题。每个使用它们的线程都必须使用锁定机制来访问它们。
  • @Jesse 已编辑。希望现在好多了。
  • 只有多线程才需要加锁;上面的代码有一个线程:对给定线程拥有的 WndProc 的每次调用都在线程返回循环并处理下一条消息之前完全完成,因此您不必在这里处理并发问题。通常,Win32 UI 是使用单个线程编写的,用于通过单个消息循环来管理 UI,因此您只需处理使用 附加 线程进行后台工作的锁定。
  • 只是一个小扳手,但并非所有内容都通过消息循环。 SendMessage() 来自同一个线程(至少)直接转到 WndProc()

标签: c++ c winapi


【解决方案1】:

您可以在那里对消息做出反应,但您仍然需要/想要致电DispatchMessage 并在您的正常 wndproc 中实际处理该消息。我很乐意多说一些关于避免全局和/或线程问题的信息,但如果没有更多关于您想要避免的细节的信息,很难发表评论。

【讨论】:

  • 消息循环所在的函数调用另一个函数,但这可能发生在多个线程/位置。此外,我无法在创建窗口类时将此函数定义为回调,因为它没有正确的签名。我需要一种无需调用 DefWindowProc 即可调用此回调的方法。但与 WndProc 函数通信的唯一方法似乎是通过静态/全局。
  • '他与 WndProc 函数通信的唯一方法似乎是通过静态/全局变量' ??- - 有两个 32 位的 'wParam, lParam' 参数。这些可以包含一个指向您的函数的指针和一个指向任意数量参数的结构指针,或者您可能希望的任何类的实例。
  • @MartinJames:当然,您是对的,但要让您的回答完全解决他的担忧,您需要在其中添加此评论。
  • @MartinJames 但是当我更改 wParam/lParam 变量时,原始消息丢失了?好的,也许我可以制作一个包含原始参数和额外信息的结构并使用指向它的指针。你是这样想的吗?
  • @cooky451 - 基本上,是的,如果需要的话。我不知道您在消息中使用这些参数的目的是什么(如果有的话),所以我没有费心使我的评论过于复杂。
【解决方案2】:

是的,如果您愿意,您可以自己处理消息。我通常将结果字段设置为 0,但 Windows 仅将此字段用于一些消息。

【讨论】:

  • 将结果字段设置为0是什么意思?什么结果字段? - 看来这里有两种意见,所以稍微解释一下就好了。
  • msg结构中有一个int结果字段。
【解决方案3】:

是否允许不调用 DispatchMessage() 而是自己处理消息?如果不是,我怎样才能很好地处理这种行为,同时避免全局变量和线程问题?

如果您计划在 GUI 中使用多个线程,那么创建窗口的每个线程都需要管理自己的消息队列。

从此页面:http://msdn.microsoft.com/en-us/library/ms810439.aspx

消息循环的变化

具有多个线程的应用程序必须在每个线程中包含一个消息循环 创建窗口的线程。消息循环和窗口过程 对于一个窗口,必须由创建该窗口的线程处理。 如果消息循环不在创建的同一线程中 窗口,DispatchMessage 函数将不会获取消息 窗户。结果,窗口将出现但不会显示激活 并且不会重新绘制、移动、接收鼠标消息或通常工作 正如你所期望的那样。

【讨论】:

    猜你喜欢
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    相关资源
    最近更新 更多