【问题标题】:Why is CWnd::CreateEx failing to create my window?为什么 CWnd::CreateEx 无法创建我的窗口?
【发布时间】: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


【解决方案1】:

我将问题追溯到此时不应执行的窗口过程挂钩。

【讨论】:

  • 这是很久以前的事了,但你还记得你是如何找到有问题的钩子的吗?我也遇到了同样的问题。
  • 这个特定问题原来是由于 Windows 64 位堆栈限制。钩子并没有像应该的那样被解开。我搜索了 SetWindowsHookEx 调用以找到创建钩子的代码。以下文章有更多关于限制的信息:support.microsoft.com/en-us/kb/2664641
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
相关资源
最近更新 更多