若需在用戶雙擊啟動時按住 Ctrl 進入特殊模式,GetCommandLine/__argc/CCommandLineInfo 均無法檢測。正確方法是調用 GetKeyState(VK_CONTROL):
if (GetKeyState(VK_CONTROL) < 0) {
// 進入特殊模式(如恢復默認設置)
}
高位為 1 表示鍵被按下。常用組合鍵如 Ctrl+F8 用於恢復工作區。
// tchar.h 簡化版
#ifdef _UNICODE
typedef wchar_t TCHAR;
#define __T(x) L ## x
#else
typedef char TCHAR;
#define __T(x) x
#endif
Windows API 根據 _UNICODE 映射為 A/W 版本:CreateFile → CreateFileA/W。
STL 已提供 basic_string 模板,string/wstring 為其具體化:
typedef basic_string<char, char_traits<char>, allocator<char>> string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> wstring;
最簡潔的 tstring 定義:
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif
優於重新 typedef basic_string<TCHAR,...>,避免產生額外模板實例(現代編譯器會優化,但語義更清晰)。
tstring s = _T("Hello, world");
_tprintf(_T("s = %s\n"), s.c_str());
c_str() 返回 const TCHAR*,完美匹配 _tprintf。
CString 內部同樣用模板 CStringT<TCHAR, StrTraitMFC<TCHAR>> 實現三種具體化:CStringA/CStringW/CString。
| 特性 | STL tstring | MFC CString |
|---|---|---|
| 初始化 | 需用 _T() | 自動轉換 "foo"/_T("bar") |
轉 LPCTSTR | 顯式 .c_str() | 隱式轉換運算符 |
printf 陷阱 | 無隱式轉換,安全 | 需強轉 (LPCTSTR)s 否則輸出亂碼 |
選擇建議:已用 MFC/ATL 選 CString;純 STL 項目用 tstring;兩者性能差異可忽略。
.NET 不支持原生 union,但可用 StructLayout(LayoutKind.Explicit) + FieldOffset(0) 模擬:
[StructLayout(LayoutKind::Explicit)]
public value struct MyUnion {
[FieldOffset(0)] int i;
[FieldOffset(0)] double d;
};
public ref class CUnionClass {
public:
MyUnion uval; // 或封裝為屬性隱藏 union 細節
};
C# 調用:
var obj = new CUnionClass();
obj.uval.i = 17;
obj.uval.d = 3.14159;
使用 SHGetSpecialFolderPath(ShlObj.h):
TCHAR buf[MAX_PATH];
SHGetSpecialFolderPath(NULL, buf, CSIDL_MYPICTURES, FALSE);
優於直接讀註冊表,兼容所有 Windows 版本。Win2000/XP 在 shell32.dll,舊版需隨程序分發 SHFOLDER.DLL。
封裝類 CSpecialFolder : public CString:
CSpecialFolder mypics(CSIDL_MYPICTURES);
LPCTSTR path = mypics; // 隱式轉換
可枚舉所有 CSIDL_* 常量對應路徑(收藏夾、字體、歷史、回收站等)。