承接上篇「在主框架視窗建立按鈕」,本文示範如何在 CView 衍生類中動態建立按鈕、處理 WM_CREATE 訊息、探討父視窗對按鈕位置的影響,並說明 WS_VISIBLE 樣式簡化顯示邏輯。
CView 預設無 OnCreate,需透過類別向導加入:
CTestView → Add Windows Message Handler...WM_CREATE → Add and Edit。int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1) return -1;
// 建立按鈕,父視窗指定為 GetParent() (即 CMainFrame)
m_btn.Create(_T("按鈕"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
CRect(0, 0, 100, 100), GetParent(), 123);
return 0;
}
| 建立位置 | 父視窗 (pParentWnd) | 座標基準 | 按鈕顯示位置 |
|---|---|---|---|
| CMainFrame::OnCreate | this (CMainFrame) | 主框架客戶區 (0,0) | 工具列上方、選單下方 |
| CView::OnCreate + this | this (CView) | View 客戶區 (0,0) | View 內部左上角 |
| CView::OnCreate + GetParent() | GetParent() (CMainFrame) | 主框架客戶區 (0,0) | 同 CMainFrame 建立位置 |
結論:按鈕位置由 父視窗的客戶區座標系 決定,與建立程式碼所在類別無關。
// 等同於 Create + ShowWindow(SW_SHOWNORMAL)
m_btn.Create(_T("按鈕"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
CRect(0,0,100,100), GetParent(), 123);
WS_CHILD:子視窗 (必須)。WS_VISIBLE:建立即顯示,省去 ShowWindow。BS_DEFPUSHBUTTON:預設按鈕樣式 (有邊框強調)。m_btn 為 CView 成員變數,生命週期隨 View 物件。CWnd::~CWnd 會自動 DestroyWindow 釋放 HWND。CButton C++ 物件本身不會因視窗銷毀而銷毀,仍可呼叫非視窗相關函式 (如 GetButtonStyle)。| 樣式 | 外觀/行為 |
|---|---|
| BS_PUSHBUTTON | 標準按鈕 |
| BS_DEFPUSHBUTTON | 預設按鈕 (粗邊框) |
| BS_CHECKBOX | 核取方塊 |
| BS_AUTOCHECKBOX | 自動切換勾選狀態 |
| BS_RADIOBUTTON | 單選鈕 |
| BS_AUTORADIOBUTTON | 自動互斥單選 |
| BS_OWNERDRAW | 自繪按鈕 (需處理 WM_DRAWITEM) |