你貼的 `WinMain` + `DialogBoxParam` + `CALLBACK _ProcDlgMain` 是**標準 Win32 SDK 對話框程序**,**完全沒有使用 MFC**(無 `CWinApp`、`CDialog`、消息映射宏)。因此,**不需要、也不能**重寫 `PreTranslateMessage`——那是 `CWnd` 的虛函數,屬於 MFC 架構。
在對話框進程 `_ProcDlgMain` 中直接處理 `WM_KEYDOWN`:
LRESULT CALLBACK _ProcDlgMain(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CLOSE:
EndDialog(hwnd, NULL);
break;
case WM_COMMAND:
// ... 你原有的按鈕處理邏輯 ...
break;
case WM_KEYDOWN:
if (wParam == VK_RETURN) {
// 模擬 Tab 鍵切換焦點,觸發下一個控件的 EN_KILLFOCUS 等驗證邏輯
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
return TRUE; // 消息已處理
}
break;
}
return FALSE;
}
case WM_KEYDOWN:
if (wParam == VK_RETURN) {
HWND hEdit = GetDlgItem(hwnd, IDC_EDIT_SCORE); // 資源定義的編輯框 ID
if (GetFocus() == hEdit) { // 確保焦點在編輯框
char buf[32];
GetWindowTextA(hEdit, buf, sizeof(buf));
int score = atoi(buf);
// 這裡處理 score:存入數組、統計、顯示等
// ...
SetWindowTextA(hEdit, ""); // 清空編輯框
return TRUE;
}
}
break;
class CGradeStatisticDlg : public CDialogEx {
DECLARE_DYNAMIC(CGradeStatisticDlg)
public:
CGradeStatisticDlg(CWnd* pParent = nullptr);
enum { IDD = IDD_DIALOG_GRADE }; // 資源編輯器設計的對話框模板
CString m_strScore; // DDX 綁定編輯框
int m_scores[8];
int m_count = 0;
protected:
virtual void DoDataExchange(CDataExchange* pDX) override {
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_SCORE, m_strScore);
}
virtual BOOL PreTranslateMessage(MSG* pMsg) override {
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) {
CWnd* pFocus = GetFocus();
if (pFocus && pFocus->GetDlgCtrlID() == IDC_EDIT_SCORE) {
UpdateData(TRUE); // 從控件取數據到 m_strScore
int score = _ttoi(m_strScore);
if (m_count < 8) m_scores[m_count++] = score;
m_strScore = ""; // 清空
UpdateData(FALSE); // 更新到控件
return TRUE;
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
};
class CMyApp : public CWinApp {
virtual BOOL InitInstance() override {
CGradeStatisticDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
return FALSE;
}
};
CMyApp theApp;
| 維度 | Win32 SDK (你現狀) | MFC |
|---|---|---|
| 學習曲線 | 陡峭(需懂消息循環、資源腳本、手動內存) | 平緩(封裝好、向導生成樣板代碼) |
| 代碼量 | 大(全手寫) | 少(框架代碼+向導) |
| 彈性 | 極高(完全控制) | 中(受框架約束) |
| 適合場景 | 極小工具、嵌入式、學習底層原理 | 企業級桌面應用、課程設計、快速交付 |
int distribution[6] = {}; // 0-59, 60-69, 70-79, 80-89, 90-99, 100
for (int s : scores) {
if (s < 60) distribution[0]++;
else if (s < 70) distribution[1]++;
else if (s < 80) distribution[2]++;
else if (s < 90) distribution[3]++;
else if (s < 100) distribution[4]++;
else distribution[5]++;
}
SetDlgItemInt(hwnd, IDC_STATIC_60, distribution[0], TRUE); // 依次設置
**不要在 Win32 SDK 代碼裡寫 `PreTranslateMessage`**——它屬於 MFC。在你的 `_ProcDlgMain` 處理 `WM_KEYDOWN` + `VK_RETURN` 即可實現「回車錄入、清空、準備下一條」。課程設計核心是**演示數據處理邏輯**,而非炫技框架;用最熟悉、最可控的方式把功能寫穩、界面做美、邏輯講清,分數才不會丟。