【发布时间】:2015-12-29 01:17:57
【问题描述】:
我正在尝试在 Windows 中模仿 SFML 的 PollEvent(Event &event) 函数。它似乎比我想象的要复杂得多。请注意,我已经在我的类中封装了窗口过程函数。
我的程序中可能有很多“窗口事件”——WindowMoved、WindowResized 等。
我的第一次尝试是在类中有一个私有数据成员,定义为WindowEvent *_lastWindowEvent。如果PeekMessage() 在调用DispatchMessage() 之前返回非零值,则将设置此变量。然后,winProc() 将编辑_lastWindowEvent,具体取决于它将收到的消息。
这里的缺点是我注意到winProc() 可以使用MSG 参数调用而不管DispatchMessage(),就像WM_SETCURSOR 消息一样。
然后我想在我的课堂上改用std::queue<WindowEvent>,当winProc()不断向它推送WindowEvents。这里的问题是有时窗口过程函数不断收到消息并且不会返回。当我拖动窗口时会发生这种情况(然后不断调用WM_MOVING 消息以及其他消息)。 DispatchMessage() 之后的代码在我松开鼠标之前不会运行。调整窗口大小时也会发生这种情况。
我有没有搞错什么?您觉得这样的 PollEvent 功能如何实现?
【问题讨论】:
-
Replaying input is not the same as reprocessing it。如果您决定违反合同,您最终会重新发明 Qt 的损坏性。 Qt 被打破,无法重生。你所描述的听起来很像 Trolltech 的,err,Digia 的,等等,Qt 公司(这就是他们本周所说的)的想法。结果证明这是一个可憎的事。
-
@IInspectable - 不确定我刚刚读到什么。你能进一步解释一下吗?
-
如果您将窗口消息存储在您的私有队列中,然后将它们交给处理,它将以微妙的方式失败。上面的链接解释了为什么输入消息失败。您有一次处理消息的机会(在您的窗口过程中)。不要浪费它。
-
那么真正将win32封装在一个类中,包括win过程,是不可能的?
-
完全没有,但您必须满足消息传递系统的要求。您可以将窗口过程作为类成员。但是,根据个人经验,最好将消息循环保持在框架之外。让客户端实现自己的消息循环可能看起来不必要地繁琐且容易出错,但它确实提供了很大的灵活性。如果客户决定调用
MsgWaitForMultipleObjects而不是GetMessage,他们希望框架不会妨碍。