核心結論
MFC 核心架構未變:WM_LBUTTONDOWN、OnDraw、訊息對應巨集 (BEGIN_MESSAGE_MAP) 在 VS2012 (MFC 11.0) 完全相容。差異在於 IDE 操作方式、專案結構、新增控制項 (BCGSoft/Ribbon) 及 C++11/14/17 支援。
主要變更對照表
| 項目 | VC++ 6.0 | VS2012 (MFC 11.0) | 遷移影響 |
| 訊息對應 | ClassWizard (Ctrl+W) | 屬性視窗 → 閃電圖示 (事件) / 類別檢視 → 右鍵加入事件處理常式 | 操作習慣改變,功能相同 |
| 資源編輯器 | 獨立對話方塊編輯器 | 整合於 Visual Studio,支援 Ribbon 設計師 | 介面現代化,快捷鍵不同 |
| 專案結構 | .dsw/.dsp | .sln/.vcxproj (MSBuild) | 需轉換專案,原始碼相容 |
| 標準庫 | MSVC6 STL (舊、不標準) | 標準 C++11/14/17 STL | 部分舊代碼需修正 (如 std::auto_ptr 棄用) |
| 新增控制項 | 無 | CMFCRibbonBar, CMFCPropertyGrid, CMFCVisualManager 等 (源自 BCGSoft) | 可打造 Office 2007/2010/2013 風格 UI |
| 繪圖支援 | GDI (CDC, CPen, CBrush) | GDI + GDI+ (需手動引入) + Direct2D (CDirect2D) | 高 DPI 螢幕建議改用 Direct2D |
| Unicode | 選項 (MBCS 預設) | 強制 Unicode (預設) | 字串處理需用 TCHAR/_T() 或 wstring |
WM_LBUTTONDOWN 繪圖遷移實戰
VC6 時代寫法 (仍可編譯)
// MyView.h
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
// MyView.cpp
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) {
CClientDC dc(this);
dc.SetPixel(point, RGB(255,0,0)); // 簡單畫點
CView::OnLButtonDown(nFlags, point);
}
VS2012 推薦寫法 (雙緩衝、高 DPI 感知)
// MyView.h
protected:
std::vector m_points; // 儲存所有點
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnDraw(CDC* pDC);
// MyView.cpp
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT() // VS2012 建議用 ON_WM_PAINT() 而非 ON_WM_DRAW()
END_MESSAGE_MAP()
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) {
m_points.push_back(point);
Invalidate(FALSE); // 觸發 WM_PAINT
CView::OnLButtonDown(nFlags, point);
}
void CMyView::OnDraw(CDC* pDC) {
// 雙緩衝防止閃爍
CMemDC memDC(pDC, this);
CDC& dc = memDC.GetDC();
dc.FillSolidRect(&dc.m_rectDraw, RGB(255,255,255));
CPen pen(PS_SOLID, 2, RGB(255,0,0));
CPen* pOldPen = dc.SelectObject(&pen);
for (const auto& pt : m_points) {
dc.Ellipse(pt.x - 3, pt.y - 3, pt.x + 3, pt.y + 3);
}
dc.SelectObject(pOldPen);
// CMemDC 解構時自動 BitBlt 到螢幕
}
IDE 操作關鍵差異速查
- 加入訊息處理常式
- 類別檢視 → 右鍵類別 → 加入 → 事件處理常式 → 選擇訊息 → 加入並編輯
- 資源符號管理
- 資源檢視 → 右鍵 .rc → 資源符號 (原 Resource.h 手動編輯)
- 屬性頁面
- 專案右鍵 → 屬性 (原 Settings),使用 MSBuild 屬性繼承
- 預編譯標頭
- 預設
pch.h / pch.cpp (原 stdafx.h),#include "pch.h" 必須是每個 .cpp 第一行
- 偵錯視覺化
- 監看視窗支援 STL 容器、智慧指標、CString 直接顯示內容
常見遷移錯誤與修正
| 錯誤 | 原因 | 修正 |
| C2039: 'auto_ptr' is not a member of 'std' | C++11 棄用,C++17 移除 | 改用 std::unique_ptr |
| LNK2001: unresolved external symbol _CString::Format | 專案設定為 MBCS 但代碼用 Unicode | 專案屬性 → 字元集 → 使用 Unicode 字元集 |
| Ribbon 控制項無法顯示 | 未初始化 CMFCVisualManager | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007)); |
| 高 DPI 模糊 | 未宣告 DPI 感知 | Manifest 加入 <dpiAware>True/PM</dpiAware> 或 SetProcessDpiAwarenessContext |
現代化建議
- 啟用 C++17:專案屬性 → C/C++ → 語言 → C++ 標準 →
/std:c++17。
- 使用智慧指標:替換手動
new/delete,MFC 物件可用 std::unique_ptr。
- 採用 Direct2D:
#include ,CDirect2D 系列類別,硬體加速、向量繪圖、高 DPI 原生支援。
- 單元測試:加入 原生單元測試專案 (Microsoft Native Unit Test Framework)。
- 靜態分析:啟用
/analyze 或安裝 CppCoreCheck。
參考資源