MFC 中調用 SendMessage(WM_COPY) 實現編輯框複製功能時,若傳遞錯誤的窗口句柄會導致複製無效。本文分析 hText = 0 導致的失效原因,給出正確獲取控件句柄的方法。
void CMFCApplication2Dlg::OnBnClickedButCopy() {
CEdit* m_Edit = (CEdit *)GetDlgItem(IDC_EDI_TEXT);
m_Edit->SetSel(0, -1); // 全選成功
HWND hText = 0; // 錯誤:句柄為 NULL
CWnd* Text = GetDlgItem(IDC_EDI_TEXT);
::SendMessage(hText, WM_COPY, 0, 0); // 發送給 NULL 句柄,無效
}
HWND hText = 0 顯式設置為 NULL (0)SendMessage(0, WM_COPY, ...) 向無效句柄發送消息,系統忽略CWnd* Text = GetDlgItem(...) 獲取正確控件指針但未使用void CMFCApplication2Dlg::OnBnClickedButCopy() {
CWnd* pEdit = GetDlgItem(IDC_EDI_TEXT);
if (pEdit) {
// 方法 1:使用 CWnd 成員函數 (推薦,類型安全)
pEdit->SendMessage(WM_COPY);
// 方法 2:使用 CWnd::m_hWnd 獲取句柄 (如需 ::SendMessage)
// ::SendMessage(pEdit->m_hWnd, WM_COPY, 0, 0);
// 方法 3:CEdit 專用複製方法 (最語義化)
// ((CEdit*)pEdit)->Copy();
}
}
| 方式 | 代碼 | 優點 | 缺點 |
|---|---|---|---|
| CWnd::SendMessage | pEdit->SendMessage(WM_COPY) | MFC 封裝、自動處理 this 指針、類型安全 | 略微開銷 |
| 全局 ::SendMessage | ::SendMessage(pEdit->m_hWnd, WM_COPY, 0, 0) | 直接調用 WinAPI、無 MFC 依賴 | 需手動獲取 m_hWnd、易傳錯句柄 |
| CEdit::Copy | ((CEdit*)pEdit)->Copy() | 語義明確、封裝了 SetSel+WM_COPY、自動處理只讀狀態 | 需轉型為 CEdit* |
CEdit::Copy():專為編輯控件設計,內部自動處理選中範圍與剪貼板操作if (pEdit) 防止控件未創建導致崩潰HWND h = 0 絕對錯誤,必須從控件對象獲取CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDI_TEXT);
if (pEdit) {
pEdit->SetSel(0, -1); // 全選
pEdit->Copy(); // 複製到剪貼板
}
複製失效根因是 SendMessage 目標句柄為 NULL。MFC 中控件句柄存儲在 CWnd::m_hWnd,應通過 GetDlgItem 獲取控件指針後再取 m_hWnd,或直接調用 CWnd::SendMessage/CEdit::Copy。推薦使用 CEdit::Copy(),語義最清晰且封裝度最高。