Edit文本框支持回车Tab字符输入的方法C++源码
本篇文章属于《518抽奖软件开发日志》系列文章的一部分。我在开发《518抽奖软件》(www.)的时候,要在文本框里输入一行行的名单,要支持回车换行、Tab字符的输入。但是默认对话框上的文本框,是没法输入回车和Tab字符的。而且,从Unix格式的文本里复制文字到文本框的时候,它的换行符跟Windows的不一致,这也是个文本格式兼容问题。解决方法就是窗口子类化技术,用新的窗口过程代替旧的,具体代码如下。
程序代码:
void Tapp::subclass_init() { oldProc = (WNDPROC)SetClassLong(GetDlgItem(m_hLoading, IDC_loading_subclass), GCL_WNDPROC, (LONG)Proc_editBox); } void Tapp::subclass_remove() { if (oldProc) { SetClassLong(GetDlgItem(m_hLoading, IDC_loading_subclass), GCL_WNDPROC, (LONG)oldProc); oldProc = NULL; } } static LRESULT CALLBACK Proc_editBox(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // 在粘贴时,处理换行符不一致 if (uMsg == WM_PASTE) { if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return 0; if (!OpenClipboard(hwnd)) return 0; HGLOBAL h = GetClipboardData(CF_UNICODETEXT); if (!h) { CloseClipboard(); return 0; } WCHAR* p = (WCHAR*)GlobalLock(h); if (!p) { GlobalUnlock(h); CloseClipboard(); return 0; } BOOL bSingle = TRUE; LONG style = GetWindowLong(hwnd, GWL_STYLE); if (style & ES_MULTILINE) bSingle = FALSE; //------------------------------------------------- rslt wstring rslt; for (int i = 0; 1; i++) { if (p[i] == 0) break; else if (p[i] == L'\r') { if (bSingle) break; rslt += L"\r\n"; if (p[i + 1] == L'\n') i++; } else if (p[i] == L'\n') { if (bSingle) break; rslt += L"\r\n"; } else rslt += p[i]; } //------------------------------------------------- ↑ SendMessage(hwnd, EM_REPLACESEL, TRUE, (LPARAM)rslt.c_str()); GlobalUnlock(h); CloseClipboard(); return 0; } // 支持回车、Tab字符输入 else if (uMsg == WM_GETDLGCODE && hwnd == hTextBox) return DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTMESSAGE | DLGC_WANTTAB; // 继续执行旧的窗口过程 return CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam); }