不習慣 MFC 的程式設計師常覺得寫界面很頭疼。本文總結 Windows 原生 SDK 界面開發要點,幫助新手入門。不討論 DUILib 等第三方庫。
主要透過資源編輯器建立對話框資源佈局,調用 DialogBox(模態)或 CreateDialog(非模態)顯示。
DialogBox 會阻塞當前執行緒,直到視窗關閉才繼續後續代碼。適合無父視窗的主對話框。
CreateDialog 返回後代碼繼續執行。若無父視窗,需自行跑訊息迴圈(GetMessage/TranslateMessage/DispatchMessage);若有父視窗,父視窗的訊息迴圈會自動分派給子視窗。
封裝 NOTIFYICONDATA 與 Shell_NotifyIcon,提供顯示/隱藏/氣球提示功能。
// notifyicon.h
class hNotifyIcon {
NOTIFYICONDATA nid;
public:
hNotifyIcon(HWND hWnd, HICON hIcon, LPCTSTR title, LPCTSTR tip=NULL, int timeout=5);
~hNotifyIcon();
BOOL Show();
BOOL Hide();
BOOL Message(LPCTSTR msg, UINT iconFlag); // NIIF_INFO/WARNING/ERROR
BOOL IsShow();
};
// notifyicon.cpp 實現細節略...
使用:hNotifyIcon *tray = new hNotifyIcon(hWnd, hIcon, L"標題", L"提示"); tray->Show();
支援整行選取、核取方塊、多欄。關鍵 API:ListView_SetExtendedListViewStyle、ListView_InsertColumn、ListView_InsertItem、ListView_SetItemText。
DWORD style = ListView_GetExtendedListViewStyle(hList);
style |= LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES;
ListView_SetExtendedListViewStyle(hList, style);
LV_COLUMN lc = {LVCF_TEXT|LVCF_WIDTH, 0, 100, L"列1"};
ListView_InsertColumn(hList, 0, &lc);
LV_ITEM li = {LVIF_TEXT, 0, 0, 0, 0, L"資料1"};
ListView_InsertItem(hList, &li);
ListView_SetItemText(hList, 0, 1, L"資料2");
hwndChild[i],插入分頁項 TabCtrl_InsertItem。
WM_NOTIFY -> TCN_SELCHANGE:切換顯示對應子對話框 ShowWindow(hwndChild[sel], SW_SHOW),其餘 SW_HIDE。
需 ITaskbarList3 介面,XP/Vista 不支援。實現較繁雜,建議參考現成組件或原始碼。
包含 <windowsx.h> 即可使用 Button_GetCheck、Edit_GetText 等巨集簡化 RadioButton、CheckBox、Edit 等操作。
GDI 繁瑣且不支援 PNG/抗鋸齒。GDI+ 使用步驟:
#include <gdiplus.h> #pragma comment(lib, "gdiplus.lib")
ULONG_PTR token; GdiplusStartupInput si; GdiplusStartup(&token, &si, NULL); 放在 WinMain 開頭。
GdiplusShutdown(token); 放在 WinMain 返回前。
WM_PAINT 中使用 Graphics、Image、Pen、Brush 等類別。
Win32 SDK 博大精深,掌握對話框、訊息迴圈、常用控件封裝、GDI+ 繪圖即可應付大多數界面需求。關鍵在於理解模態/非模態區別、資源腳本佈局、訊息分派機制。建議新手從簡單的對話框專案開始,逐步封裝常用控件類別,積累自己的 UI 庫。