You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 12:06:06