首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 在主框架視窗動態建立按鈕控件 (一):CButton 生命週期與 Create/ShowWindow 流程

     編輯:VC 教學

前言

理解 MFC 視窗類別物件 (CWnd 衍生) 與實際 HWND 視窗的關係,是掌握動態建立控件的關鍵。本文以在 CMainFrame 建立按鈕為例,完整說明 CButton 物件建立、Create 關聯 HWND、ShowWindow 顯示、成員變數管理生命週期的完整流程。

CButton 繼承架構

CObject
  └─ CCmdTarget
       └─ CWnd
            └─ CButton

CButton 繼承 CWnd,擁有 m_hWnd 儲存視窗控制代碼,所有視窗操作均委派給此 HWND。

CButton::Create 參數詳細

BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle,
            const RECT& rect, CWnd* pParentWnd, UINT nID);
參數說明
lpszCaption按鈕顯示文字
dwStyle視窗樣式 (WS_CHILD, WS_VISIBLE...) | 按鈕樣式 (BS_PUSHBUTTON...),可位元或組合
rect位置與大小,相對父視窗客戶區座標 (CRect 構造)
pParentWnd父視窗指標,傳遞 this 即為當前框架
nID控件 ID,供命令路由識別

第一嘗試:區域變數導致視窗瞬間消失

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    // ... 工具列/狀態列建立 ...
    CButton btn;                    // 區域變數
    btn.Create(_T("按鈕"), WS_CHILD | BS_DEFPUSHBUTTON,
               CRect(0,0,100,100), this, 123);
    return 0; // btn 離開作用域 → 建構函數 → DestroyWindow → 視窗消失
}

原因:CButton 區域變數在 OnCreate 結束時解構,CWnd::~CWnd 偵測 m_hWnd 有效則呼叫 DestroyWindow,導致剛建立的按鈕視窗被銷毀。

正確做法:成員變數管理生命週期

步驟 1:加入成員變數

ClassView 右鍵 CMainFrame → Add Member Variable... → Type: CButton, Name: m_btn, Access: private。

產生標頭檔宣告:

class CMainFrame : public CFrameWnd
{
private:
    CButton m_btn; // 成員變數,生命週期 = CMainFrame
    // ...
};

步驟 2:OnCreate 中建立並顯示

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

    // ... 工具列/狀態列建立代碼 ...

    // 1. 建立按鈕視窗,關聯 m_btn 物件
    m_btn.Create(_T("按鈕"), WS_CHILD | BS_DEFPUSHBUTTON,
                 CRect(0, 0, 100, 100), this, 123);

    // 2. 顯示按鈕 (若未加 WS_VISIBLE)
    m_btn.ShowWindow(SW_SHOWNORMAL);

    return 0;
}

關鍵觀念釐清

觀念說明
C++ 物件 ≠ HWNDCButton btn; 只是 C++ 物件,未建立視窗。Create 才建立 HWND 並寫入 m_hWnd。
解構 = 銷毀視窗CWnd::~CWnd 若 m_hWnd != NULL 會呼叫 DestroyWindow。
成員變數 = 延長生命將 CButton 宣告為成員變數,視窗隨框架視窗銷毀而銷毀,符合預期。
ShowWindow 必要性未指定 WS_VISIBLE 時,Create 只建立不顯示,必須呼叫 ShowWindow。
this 指標作父視窗在 CMainFrame::OnCreate 中傳 this,按鈕成為框架視窗子視窗,座標相對框架客戶區。

簡化寫法:WS_VISIBLE 一步到位

m_btn.Create(_T("按鈕"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
             CRect(0,0,100,100), this, 123);
// 省去 ShowWindow 呼叫

驗證結果

編譯執行,按鈕出現在主框架客戶區左上角 (0,0),寬高 100x100 像素,位於工具列區域 (因框架客戶區包含工具列)。

總結

動態建立控件三部曲:成員變數宣告 → Create 關聯 HWND → ShowWindow/WS_VISIBLE 顯示。區域變數會導致視窗隨函數結束而銷毀,這是新手最常犯的錯誤。掌握 C++ 物件與 HWND 的生命週期綁定關係,是 MFC 視窗程式設計的核心功力。

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