WinAPI开发新手求教:点击不同Edit控件触发对应提示实现问题
WinAPI Edit控件点击触发提示问题修复
核心错误排查
- 错误监听
WM_SETFOCUS消息:该消息只会发送给获得焦点的窗口本身,Edit控件是独立子窗口,获得焦点时消息会发送到Edit内置的窗口过程,不会传递到主窗口的WndProc,因此你写的WM_SETFOCUS分支根本接收不到Edit的焦点变化事件。 WM_SETFOCUS分支逻辑顺序错误:你在Edit1的判断结束后直接写了break,后续Edit2、Edit3的判断代码永远不会被执行,属于基础语法逻辑错误。- 消息参数理解错误:就算主窗口收到自身的
WM_SETFOCUS消息,wParam参数是之前持有焦点的窗口句柄,不是子控件的ID,你的判断逻辑完全不成立。 - GDI资源泄漏隐患:全局初始化创建的字体没有释放,会造成GDI资源泄漏,建议把字体创建移到
WM_CREATE中,窗口销毁时调用DeleteObject释放。
修复方案
Edit控件的状态变化会通过WM_COMMAND消息通知父窗口,当Edit获得焦点时,会携带EN_SETFOCUS通知码发送该消息,你只需要在主窗口的WndProc中新增WM_COMMAND消息处理分支即可,代码如下:
#include <windows.h> #define Edit1 501 #define Edit2 502 #define Edit3 503 HWND TextBox1, TextBox2, TextBox3; HFONT HF; LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_COMMAND: { // 高字节为通知码,低字节为控件ID if(HIWORD(wParam) == EN_SETFOCUS) { int editId = LOWORD(wParam); if(editId == Edit1) { MessageBox(NULL, "Edit1 choosed","Edit1",MB_ICONEXCLAMATION|MB_OK); } else if(wParam == Edit2) { MessageBox(NULL, "Edit2 choosed","Edit2",MB_ICONEXCLAMATION|MB_OK); } else if(wParam == Edit3) { MessageBox(NULL, "Edit3 choosed","Edit3",MB_ICONEXCLAMATION|MB_OK); } } break; } case WM_CREATE: { // 字体创建移到WM_CREATE中,避免全局初始化的潜在问题 HF = CreateFont (30, 0, 00, 00, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"); TextBox1 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_RIGHT, 30, 70, 190, 40, hwnd, (HMENU)Edit1, GetModuleHandle(NULL), NULL); SendMessage(TextBox1, WM_SETFONT,( WPARAM ) HF, 0 ); TextBox2 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_RIGHT, 30, 130, 190, 40, hwnd, (HMENU)Edit2, GetModuleHandle(NULL), NULL); SendMessage(TextBox2, WM_SETFONT,( WPARAM ) HF, 0 ); TextBox3 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_RIGHT, 30, 190, 190, 40, hwnd, (HMENU)Edit3, GetModuleHandle(NULL), NULL); SendMessage(TextBox3, WM_SETFONT,( WPARAM ) HF, 0 ); break; } case WM_DESTROY: { // 释放字体资源,避免GDI泄漏 DeleteObject(HF); PostQuitMessage(0); break; } default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG msg; memset(&wc,0,sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszClassName = "WindowClass"; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK); return 0; } hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL,NULL,hInstance,NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK); return 0; } while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
内容的提问来源于stack exchange,提问作者m-kowalski
相关产品推荐
相关产品推荐

