MFC 核心對象快速訪問
| 需求 | 方法 | 範例 |
| 主窗口指針 | `AfxGetMainWnd()` | `AfxGetMainWnd()->ShowWindow(SW_SHOWMAXIMIZED);` |
| 應用程序實例句柄 | `AfxGetInstanceHandle()` | `HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON);` |
| 應用程序路徑 | `GetModuleFileName(NULL, buf, MAX_PATH)` | 去除文件名得目錄 |
| 系統目錄 | `GetWindowsDirectory` / `GetSystemDirectory` | |
| 臨時目錄 | `GetTempPath` | |
| 當前工作目錄 | `GetCurrentDirectory` | |
圖標加載與繪制
// 方法 1:SHGetFileInfo (獲取文件關聯圖標、大小圖標、屬性)
SHFILEINFO sfi;
if (SHGetFileInfo(_T("notepad.exe"), 0, &sfi, sizeof(sfi), SHGFI_ICON)) {
pDC->DrawIcon(10, 10, sfi.hIcon);
DestroyIcon(sfi.hIcon); // 使用完必須銷毀
}
// 方法 2:ExtractIcon (簡單加載可執行文件圖標)
HICON hIcon = ExtractIcon(AfxGetInstanceHandle(), _T("notepad.exe"), 0);
if (hIcon && hIcon != (HICON)-1) pDC->DrawIcon(10, 10, hIcon);
自定義消息
// 1. 定義消息值 (WM_USER 以上避免衝突)
#define WM_MY_CUSTOM_MSG (WM_USER + 100)
// 2. 類向導添加消息映射
// ON_MESSAGE(WM_MY_CUSTOM_MSG, OnMyCustomMsg)
// 3. 處理函數簽名
LRESULT CMainFrame::OnMyCustomMsg(WPARAM wParam, LPARAM lParam) {
// wParam, lParam 自定義含義
return 0;
}
// 4. 發送/發布
pWnd->SendMessage(WM_MY_CUSTOM_MSG, wParam, lParam); // 同步
pWnd->PostMessage(WM_MY_CUSTOM_MSG, wParam, lParam); // 異步
窗口樣式與創建控制
修改創建參數:`PreCreateWindow`
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
// 移除最大化按鈕
cs.style &= ~WS_MAXIMIZEBOX;
// 設置初始位置大小
cs.x = 0; cs.y = 0;
cs.cx = GetSystemMetrics(SM_CXSCREEN) / 2;
cs.cy = GetSystemMetrics(SM_CYSCREEN) / 2;
return CMDIFrameWnd::PreCreateWindow(cs);
}
窗口居中顯示
// 相對父窗口居中
CenterWindow();
// 相對屏幕居中
CenterWindow(CWnd::GetDesktopWindow());
// 主框架居中
AfxGetMainWnd()->CenterWindow();
啟動時最大化/最小化
// 主框架:InitInstance 中設置
m_nCmdShow = SW_SHOWMAXIMIZED; // 或 SW_SHOWMINIMIZED, SW_SHOWNORMAL
// MDI 子窗口:PreCreateWindow 設置 WS_MAXIMIZE / WS_MINIMIZE
// 或 OnInitialUpdate 中 ShowWindow(SW_SHOWMAXIMIZED)
限制窗口大小:`OnGetMinMaxInfo`
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) {
lpMMI->ptMinTrackSize = CPoint(400, 300); // 最小
lpMMI->ptMaxTrackSize = CPoint(1024, 768); // 最大
lpMMI->ptMaxPosition = CPoint(0, 0); // 最大化位置
CFrameWnd::OnGetMinMaxInfo(lpMMI);
}
隱藏/顯示窗口
ShowWindow(SW_HIDE); // 隱藏
ShowWindow(SW_SHOW); // 顯示
// 結合 FindWindow 控制其他進程窗口
CWnd* pWnd = CWnd::FindWindow(_T("Notepad"), NULL);
if (pWnd) pWnd->ShowWindow(SW_HIDE);
移動與調整窗口大小
// 僅移動 (保持大小)
SetWindowPos(NULL, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
// 僅調整大小 (保持位置)
CRect rc; GetWindowRect(&rc);
SetWindowPos(NULL, 0, 0, rc.Width()*2, rc.Height()*2, SWP_NOMOVE | SWP_NOZORDER);
// MoveWindow (必須指定位置和大小)
MoveWindow(100, 100, 400, 300);
通用控件視圖類
| 視圖類 | 封裝控件 | 適用場景 |
| `CEditView` | 編輯控件 | 文本編輯器 |
| `CTreeView` | 樹控件 | 資源管理器風格 |
| `CListView` | 列表控件 | 文件列表、詳情視圖 |
| `CRichEditView` | 富文本編輯 | WordPad 風格 |
字回繞編輯視圖
BOOL CMyEditView::PreCreateWindow(CREATESTRUCT& cs) {
BOOL b = CEditView::PreCreateWindow(cs); // 基類會設置樣式
cs.style &= ~(ES_AUTOHSCROLL | WS_HSCROLL); // 關閉水平滾動/自動水平滾動
return b;
}
保持最小化狀態 (防止還原)
BOOL CMainFrame::OnQueryOpen() {
return FALSE; // 攔截 WM_QUERYOPEN,拒絕還原
}
拖動窗口 (點擊客戶區移動)
對話框/視圖:`OnNcHitTest`
UINT CMyDialog::OnNcHitTest(CPoint point) {
UINT hit = CDialog::OnNcHitTest(point);
return (hit == HTCLIENT) ? HTCAPTION : hit; // 讓系統以為點擊標題欄
}
視圖:`OnLButtonDown` 發送 `WM_NCLBUTTONDOWN`
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) {
CView::OnLButtonDown(nFlags, point);
GetParentFrame()->PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
}
修改窗口/控件標題
// 任何窗口 (含控件)
AfxGetMainWnd()->SetWindowText(_T("新標題"));
GetParentFrame()->SetWindowText(_T("MDI 子窗口標題"));
GetDlgItem(IDC_BUTTON)->SetWindowText(_T("按鈕新文本"));
// 高頻修改優化:AfxSetWindowText (內部比較舊值避免閃爍)
// 需包含 afxpriv.h
AfxSetWindowText(hWnd, _T("新文本"));
防止主框架標題顯示活動文檔名
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
cs.style &= ~FWS_ADDTOTITLE; // 移除自動添加文檔名樣式
return CMDIFrameWnd::PreCreateWindow(cs);
}
// MDI 子窗口同理,但需自行 SetWindowText 設置標題
獲取當前處理的消息
void CMainFrame::OnCommonMenuHandler() {
const MSG* pMsg = GetCurrentMessage();
if (pMsg) TRACE(_T("菜單項 ID: %u\n"), pMsg->wParam);
}
獲取工具欄/狀態欄指針
CStatusBar* pStatus = (CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar* pToolBar = (CToolBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
啟用/禁用工具欄提示
void CMainFrame::EnableToolTips(BOOL bEnable) {
ASSERT_VALID(m_wndToolBar);
DWORD style = m_wndToolBar.GetBarStyle();
if (bEnable) style |= CBRS_TOOLTIPS;
else style &= ~CBRS_TOOLTIPS;
m_wndToolBar.SetBarStyle(style);
}
不規則窗口:`SetWindowRgn`
// OnInitDialog 中
CRect rc; GetClientRect(&rc);
m_rgn.CreateEllipticRgn(0, 0, rc.Width(), rc.Height()); // 橢圓區域
SetWindowRgn((HRGN)m_rgn, TRUE);
// OnPaint 繪制球體效果
// OnNcHitTest 返回 HTCAPTION 實現任意處拖動