我试图在Windows中模仿SFML的PollEvent(Event &event)
功能。我想象的似乎要复杂得多。请注意,我已经在我的类中封装了窗口过程函数。
可能有许多"窗口事件"在我的计划中 - WindowMoved
,WindowResized
等
我的第一次尝试是在类中拥有一个私有数据成员,定义为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功能?
答案 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;
}