Win32中的PollEvent()

时间:2015-12-29 01:17:57

标签: windows winapi sfml

我试图在Windows中模仿SFML的PollEvent(Event &event)功能。我想象的似乎要复杂得多。请注意,我已经在我的类中封装了窗口过程函数。

可能有许多"窗口事件"在我的计划中 - WindowMovedWindowResized

我的第一次尝试是在类中拥有一个私有数据成员,定义为WindowEvent *_lastWindowEvent。如果PeekMessage()在调用DispatchMessage()之前返回非零值,则会设置此变量。然后,winProc()将根据收到的消息编辑_lastWindowEvent。 这里的缺点是,我注意到winProc()可以使用MSG参数调用,而不管DispatchMessage(),与WM_SETCURSOR消息一样。

然后我考虑在std::queue<WindowEvent>不断向winProc()推送WindowEvent时,在课堂上使用WM_MOVING。这里的问题是有时窗口过程函数不断获取消息并且不会返回。当我拖动移动窗口(然后连续调用DispatchMessage()消息以及其他消息)时会发生这种情况。 $(document).ready(function(){ $("#myButton").click(function(){ $("#myDiv").toggle(); }); }); 之后的代码在我释放鼠标之前不会运行。调整窗口大小时也会发生这种情况。

我有没有把握错误?您如何看待这样的PollEvent功能?

1 个答案:

答案 0 :(得分:-1)

鉴于PollEvent主要用于游戏循环风格设计,您可以在同时为Windows事件循环提供服务时轮询所需内容:

class Window
{
    HWND _hwnd;           // Win32 handle to the window
    RECT _lastWindowSize; // last known window size
    POINT _lastMousePos;  // last known mouse position on window
    BYTE _lastKeyboardState[256]; // last known key state

    std::list<Event> _events; // unprocessed events

public:
    bool PollEvent(Event* pEvent);
};


bool Window::PollEvent(Event* pEvent)
{

   // return any previously queued events
   if (_events.size() > 0)
   {
        *pEvent = _events.pop_front();
        return true;
   }

   // process 1 windows event message
   if (PeekMessage(&msg, _hWnd, 0, 0, PM_REMOVE))
   {
       TranslateMessage(&msg);
       DispatchMessage(&msg);

       if (msg.msg == WM_QUIT)
       { 
           *pEvent = EXIT_EVENT; // special handling for WM_QUIT
           return true;
       }
   }

   // -----------------------------------------
   // poll keyboard state
   BYTE kbState[256];
   GetKeyboardState(kbState);
   bool isKeyboardEvent = false;
   if (memcmp(_lastKeyboardState, kbState, 256) != 0)
   {
        // not shown
        // compute diff of kbState and _lastKeyboardState
        // generate a keyboard event and add to the queue

        Event kbevt;
        kbevt.type = KeyEvent;
        kbevt.code = <computed code based on diff above>
        _events.push_back(kbevt);
   }
   memcpy(_lastKeyboardState, kbState, 256);
   // -----------------------------------------

   // -----------------------------------------
   // poll window size changes
   RECT rectWindowSize;
   int width, height, oldwidth, oldheight;
   GetClientRect(&rectWindowSize);
   width = rectWindowSize.right - rectWindowSize.left;
   height = rectWindowSize.bottom - rectWindowSize.top;
   oldwidth = _lastWindowSize.right - _lastWindowSize.left;
   oldheight = _lastWindowSize.bottom - _lastWindowSize.top;
   if ((width != oldwidth) || (height != oldheight))
   {
       Event sizeEvent;
       sizeEvent.type = SizeEvent;
       sizeEvent.width = width;
       sizeEvent.height = height;
       _events.push_back(kbevt);
   }
   _lastWindowSize = rectWindowSize;
   // -----------------------------------------

   // not shown - computing mouse position, joystick position, text stuff


   // if at least one event was queued - return it now
   if (_events.size() > 0)
   {
        *pEvent = _events.pop_front();
        return true;
   }

   return false;

}