在單文檔 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)) 斷言。
CNew 視窗,直接在 CHomeWorkView::OnDraw() 中繪製即可。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)) 時,檢查該視窗是否已正確建立。