首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

解決 MFC 斷言 ASSERT(::IsWindow(m_hWnd)) 失敗:視窗未建立導致句柄為空

     編輯:程式設計綜合問答

問題背景

在單文檔 MFC 專案中,新增一個繼承自 CWnd 的 CNew 類別,並覆寫 OnPaint 進行繪圖。定義 Clear() 呼叫 InvalidateRect(NULL, TRUE) 觸發重繪。在視圖類別 CHomeWorkView 的選單命令 OnClear 中呼叫 new.Clear(),結果觸發斷言失敗:

_AFXWIN_INLINE void CWnd::InvalidateRect(LPCRECT lpRect, BOOL bErase)
{ ASSERT(::IsWindow(m_hWnd)); ::InvalidateRect(m_hWnd, lpRect, bErase); }

錯誤提示 m_hWnd 為 NULL,表示視窗句柄無效。

原因分析

CNew 物件雖然作為 CHomeWork 的成員變數被定義,但並未真正建立對應的視窗。MFC 中 CWnd 衍生類別必須呼叫 Create 或 CreateEx 才會獲得有效的 m_hWnd。直接呼叫 InvalidateRect 會觸發 ASSERT(::IsWindow(m_hWnd)) 斷言。

解決方案

  1. 若僅需在視圖上繪圖:不必新增 CNew 視窗,直接在 CHomeWorkView::OnDraw() 中繪製即可。
  2. 必須使用獨立視窗:在 CHomeWork::OnCreate 中呼叫 new.Create(...) 建立視窗,確保 m_hWnd 有效。

程式碼範例

// CHomeWork.cpp
int CHomeWork::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // 建立 CNew 視窗
    if (!new.Create(NULL, _T("CNew Window"), WS_CHILD | WS_VISIBLE,
                    CRect(0, 0, 300, 300), this, 1001))
    {
        TRACE0("Failed to create CNew window\n");
        return -1;
    }
    return 0;
}

總結

MFC 視窗物件必須經過 Create 才能獲得有效句柄。成員變數宣告只分配 C++ 物件,不建立系統視窗。遇到 ASSERT(::IsWindow(m_hWnd)) 時,檢查該視窗是否已正確建立。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved