我正在尝试在.NET Windows窗体应用程序的C ++ / CLI库中创建渲染循环,但PeekMessage永远不会收到任何消息。所以我的渲染循环是无限的,表格看起来是冻结的。
我尝试了几种方法,但这是我的最后一次尝试。
开始渲染循环:
Application::Idle += gcnew EventHandler(this, &TECore::AppIdleHandler);
处理它的代码:
void TECore::AppIdleHandler(Object^ object, EventArgs^ e)
{
while (IsAppIdle())
RenderLoopCallBack();
}
bool TECore::IsAppIdle()
{
LPMSG msg = {};
return !PeekMessage(msg, (HWND)_targetForm->Handle.ToInt32(), 0, 0, 0);
}
因此,如果我没有做错任何事情,我会不断检查来自我的Windows句柄的消息(也尝试过使用NULL),否则我会渲染内容。但窗口被冻结,因为我从未收到任何消息,IsAppIdle总是返回true。我无法集中窗户,调整大小或其他任何东西..
非常感谢您的帮助。
编辑1: 如果我在每个帧中执行Application :: DoEvent(),它会工作。但是性能缺点是什么?
编辑2:
我现在很确定我的PeekMessage没有得到任何消息,因为RenderLoop在类库中,而不是直接在WindowForm中。 PeekMessage可以直接在表单代码中正常工作。这是正常的行为吗?也许C#在加载CLI程序集时自动将其加载到另一个线程上?所以我的PeekMessage正在查找错误的帖子?
答案 0 :(得分:0)
我发现了我的问题......只是语法错误。 Intellisense要求将LPMSG作为PeekMessage的第一个参数(之前从未使用过),实际上我需要传递一个MSG指针。所以PeekMessage可能在沉默中失败了......
使用正确的语法,它可以正常工作。
错误的语法
value.toList
正确的语法
bool TECore::IsAppIdle()
{
LPMSG msg = {};
return !PeekMessage(msg, NULL, 0, 0, 0);
}