【发布时间】:2013-07-19 21:02:29
【问题描述】:
发现问题:
在调用DispatchMessage( &msg )内发生crash,这个函数的正确使用方法是什么?
下面的旧消息
我正在尝试使用 Microsoft Visual Studio 2012 Ultimate 和随附的 Windows SDK 编译我的第一个 64 位 Windows 应用程序(我过去在其他系统上完成了 64 位程序)并且我遇到了未处理的异常崩溃在运行时,这段代码恰好位于if (msg.message == WM_QUIT) 行,我根本无法弄清楚,该程序在 32 位下运行良好。
程序所做的只是启动然后将此块作为方法运行,它会在崩溃之前到达这一点。
我正在 Windows 7 上编译和运行它。
MSG msg;
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
// No message translation because we don't use WM_CHAR and it would conflict with our
// deadkey handling.
//if ( ExternalWindow && msg.hwnd == HWnd ) {
//WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
//} else {
DispatchMessage( &msg );
//}
if ( msg.message == WM_QUIT ) {
Close = true;
}
}
我正在链接这些库:
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib
很抱歉,我无法提供更深入的信息我对 Windows SDK 相当不熟悉,正如我之前所说,这是我的第一个 64 位 Windows 应用程序(它适用于 32 位,所以我猜它是指针大小/存储问题?)。
编辑:这也是非 unicode,所以它调用 PeekMessageA() 和 DispatchMessageA()。
EDIT2:WndProc() 只是读取用户输入,目前它是一个空函数,我的断点告诉我它没有被调用。 ExternalWindow 为假,HWnd 有效,因为窗口弹出并在崩溃前显示。
EDIT3:这是msg的内容,message、wParam和lParam每次运行都保持不变,显然每次启动时点、时间和窗口位置都会发生变化。
msg {msg=0x0000031f wp=0x0000000000000001 lp=0x0000000000000000}
hdnw 0x00000000004a2594 {unused=-842150451 }
message 799
wParam 1
lParam 0
time 29882662
pt {x=1479 y=581}`
EDIT4:我对函数进行了虚拟化(在第一行返回 void),当然应用程序运行得非常好,只有无法关闭它,但我注意到不再设置窗口标题,所以我猜这个错误与窗口的创建有关,我稍后会发布我的代码。
【问题讨论】:
-
这是一种非常奇怪的消息泵形式。
ExternalWindow和HWnd有什么意义,为什么需要特殊处理?WndProc是什么? -
我已经用 ExternalWindow 和 WndProc 注释掉了这些行,因为它们没有实现并且代码没有命中这些行。我是 winapi 的新手,我是基于在 32 位系统上编译和运行良好的代码库编写的,我正在将它移植到 64 位系统,这是我似乎无法解决的第一个大问题。
-
很难解释,尤其是当您根本不记录异常也不显示堆栈跟踪时。这很可能是机器因为测试您永远不会收到的消息而生您的气。 WM_QUIT 使 GetMessage() 返回 FALSE。所以至少删除那一行,你可能会领先。
-
不幸的是,我没有得到任何类型的堆栈跟踪,它崩溃并指向这一行,并且除了未处理的异常之外没有提供更多信息,我认为这是一个存在于某处的无效指针。我看过其他人的实现,他们和我有相同的循环(仅在 32 位系统上),我需要为 64 位系统采取额外的步骤吗?。
-
谢谢,我已经隔离了这个问题,它是对 DispatchMessage() 的调用,我会进一步调查。任何帮助将不胜感激。
标签: c++ winapi visual-studio-2012 64-bit unhandled-exception