本文匯總三個實用 C++/Windows 開發技巧:文件對話框預設視圖模式控制、.NET 調用 SetForegroundWindow 激活外部視窗、C++ 編譯期封鎖類被繼承。
Spy++ 揭示視窗層級:對話框 → SHELLDLL_DefView (ID=lst2) → SysListView32。難點:WM_INITDIALOG/CDN_INITDONE 時列表尚未建立。解法:PostMessage(WM_USER+1) 延後處理,待消息泵空閒時列表已就緒。再發 WM_COMMAND 給 SHELLDLL_DefView (而非 ListView),命令碼對照表:
| 視圖 | 命令 ID |
|---|---|
| 圖示 | 0x7029 |
| 列表 | 0x702A |
| 詳細資料 | 0x702C (ODM_VIEW_DETAIL) |
| 縮圖 | 0x702D |
| 平鋪 | 0x702E |
無托管對應 API,需 P/Invoke:
[DllImport("user32.dll")] public static extern void SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")] public static extern IntPtr FindWindow(string classname, string title);
// 使用
IntPtr hwnd = FindWindow(null, "目標視窗標題");
SetForegroundWindow(hwnd);
classname/title 二擇一非空。適用於啟動器、監控工具等場景。
方案一:私有建構函數 + 靜態工廠
class MyClass {
public: static MyClass* CreateInstance() { return new MyClass(); }
private: MyClass() {} // 衍生類無法調用
};
缺點:無法棧上建構。方案二:虛繼承密封基類 + friend
class MakeSealed { private: MakeSealed() {} friend class MyClass; };
class MyClass : virtual MakeSealed {}; // 僅 MyClass 可建構 MakeSealed
優點:支援棧上建構、多重繼承安全、可復用 MakeSealed 封鎖其他類。C++20 將引入 [[final]] 屬性標準化此需求。