【发布时间】:2012-11-13 23:18:56
【问题描述】:
我正在处理我们的 32 位 MFC VC2010 应用程序中发生的零星生产问题。该应用程序在 Windows Server 2008 R2 Standard SP1 64 位上运行。
此问题是由未能创建 CWnd 派生类引起的。发生故障时,AfxUnhookWindowCreate 方法在 CWnd::CreateEx 内返回 false。这是因为 pThreadState->m_pWndInit 变量不为 NULL。看起来 _AfxCbtFilterHook 应该在 HCBT_CREATEWND 被挂钩时将其设置为 NULL,但似乎这没有发生。我已注销 CREATESTRUCT 并将其与发生故障的时间与不发生故障的时间进行比较,并且参数基本相同。
是否有人对可能导致此问题的原因或我如何确定原因有任何想法?谢谢!
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
...
if (!PreCreateWindow(cs))
{
PostNcDestroy();
return FALSE;
}
AfxHookWindowCreate(this);
HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
...
if (!AfxUnhookWindowCreate())
PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
...
BOOL AFXAPI AfxUnhookWindowCreate()
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
#ifndef _AFXDLL
if (afxContextIsDLL && pThreadState->m_hHookOldCbtFilter != NULL)
{
::UnhookWindowsHookEx(pThreadState->m_hHookOldCbtFilter);
pThreadState->m_hHookOldCbtFilter = NULL;
}
#endif
if (pThreadState->m_pWndInit != NULL)
{
pThreadState->m_pWndInit = NULL;
return FALSE; // was not successfully hooked
}
return TRUE;
}
LRESULT CALLBACK
_AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
if (code != HCBT_CREATEWND)
{
// wait for HCBT_CREATEWND just pass others on...
return CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code,
wParam, lParam);
}
...
pThreadState->m_pWndInit = NULL;
【问题讨论】:
-
听起来像是线程问题 :-)
-
@user 你是从主线程调用
CWnd::CreateEx吗? -
是的,这发生在主线程上。有时窗口创建成功,有时它不在主线程的同一进程中。
-
如果您创建一个空白窗口(即没有其他事情发生),您是否有同样的问题,或者是 Window 类本身发生了什么导致问题?
-
是的,它仍然在出现空白 CWnd。我将问题追溯到此时不应该执行的窗口过程挂钩。谢谢!
标签: c++ mfc visual-studio-2010 cwnd