1.WM_COMMAND介绍和用法


 

WM_COMMAND产生的条件:点击菜单, 点击加速键,点击子窗口按钮,点击工具栏按钮。这些时候都有command消息产生。

WM_COMMAND消息中有两个参 数,wparam、lparam,定义如下:

       wParam 高两个字节 通知码

       wParam 低两字节 命令ID

       lParam 发送命令消息的子窗体句柄。

 

对于菜单 和加速键来说,lParam为0,只有控件此项才非0。命令ID也就是资源脚本中定义的菜单项的命令ID或者加速键的命令ID;菜单的通知码为0;加速键 的通知码为1。

       对于Windows菜单中菜单项和加速键,点击后,Windows会向所属的窗体发送WM_SYSCOMMAND,而不是WM_COMMAND消息。注 意,WINDOWS菜单是系统菜单,也就是在标题栏点击鼠标左键的时候弹出的菜单。我们可以捕获WM_CREATE消息,加入自己的操 作:GetSysMenu获取系统菜单句柄,然后对系统菜单进行操作,并且捕获添加菜单项(根据菜单命令ID)ID对应的WM_SYSCOMMAND消息 进行处理。修改系统默认的菜单行为。

子窗体和父窗体:

子窗体被触发时,向父窗体发送一个WM_COMMAND消息,父窗体的窗口函数处理这个消息,进行 相关的处理。lParam表示子窗口句柄,LOWORD(wParam)表示子窗口ID,HIWORD (wParam)表示通知码(例如单击,双击,SETFOCUS等)。

 

 

 

#define IDB_ONE     3301 

#define IDB_TWO     3302 

#define IDB_THREE   3303 

 

然后创建三个按钮:

 

 case WM_CREATE: 

  { 

   //创建三个按钮 

   CreateWindow(L"Button", L"按钮一", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

    35, 10, 120, 60, hwnd, (HMENU)IDB_ONE, hwnd, NULL); 

   CreateWindow(L"Button", L"按钮二", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

    35, 80, 120, 60, hwnd, (HMENU)IDB_TWO, hwnd, NULL); 

   CreateWindow(L"Button", L"按钮三", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

    35, 150, 120, 60, hwnd, (HMENU)IDB_THREE, hwnd, NULL); 

  } 

  break;

 

然后我们来响应WM_COMMAND消息。

 

case WM_COMMAND: 

    { 

        switch(LOWORD(wParam)) 

        { 

        case IDB_ONE: 

MessageBox(hwnd, L"您点击了第一个按钮。", L"提示", MB_OK | MB_ICONINFORMATION);

            break; 

        case IDB_TWO: 

            MessageBox(hwnd, L"您点击了第二个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

            break; 

        case IDB_THREE: 

            MessageBox(hwnd, L"您点击了第三个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

            break; 

        default: 

            break; 

        } 

    } 

   break;

 

看看效果。

 

 

 

 

 

这时候,我希望,当我点击了按钮后,按钮上的文本变成“按钮X已点击”,该怎么做呢?Windows系统是基于消息机制的,所以,首先想到,向控件发送消息,要改变控件相关的文本,应当发送WM_SETTEXT消息。

 

我们把上面的代码改一下。

 

case WM_COMMAND: 

    { 

        switch(LOWORD(wParam)) 

        { 

        case IDB_ONE: 

            //MessageBox(hwnd, L"您点击了第一个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

            SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第一个按鈕已点击"); 

            break; 

        case IDB_TWO: 

            //MessageBox(hwnd, L"您点击了第二个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

            SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第二个按鈕已点击"); 

            break; 

        case IDB_THREE: 

            //MessageBox(hwnd, L"您点击了第三个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

            SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第三个按鈕已点击"); 

            break; 

        default: 

            break; 

        } 

    } 

    break; 

 

前面我们知道,WM_COMMAND消息的lParam保存控件的句柄,所以,我们传给SendMessage的第一个参数是操作目标的句柄,注意,这里不要传WindowProc回调中的参数,因为我们现在要操作的对象是按钮,不是窗口,WindowProc传进到的句柄是指我们注册的窗口,因为我们在WNDCLASS中已经设定了该WindowProc函数。

 

要对按钮进行操作,应当使用WM_COMMAND的lParam中包含的值,强制转换为HWND。

 

运行结果如下图所示。

 

 

 

 

完整的示例如下:

 

 

#include <Windows.h>

 

 

//按钮ID

#define IDB_ONE     3301 

#define IDB_TWO     3302 

#define IDB_THREE   3303 

 

//函数声明

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 

 

LPCWSTR WINDOWS_CLASS = "MyClass";    //类名 

LPCWSTR WINDOWS_TITLE = "测试按钮";   //窗口标题 

 

 

int WINAPI wWinMain(HINSTANCE hThisApp, 

    HINSTANCE hPrevApp, 

    LPWSTR lpCmd, 

    int nShow) 

    WNDCLASSEX wc = { }; 

    wc.cbSize = sizeof(WNDCLASSEX); 

    wc.hbrBackground = (HBRUSH)COLOR_WINDOW; 

    wc.hInstance = hThisApp; 

    wc.lpfnWndProc = (WNDPROC)WindowProc; 

    wc.lpszClassName = WINDOWS_CLASS; 

    wc.style = CS_HREDRAW | CS_VREDRAW; 

    RegisterClassEx(&wc); 

 

 

    HWND hwnd = CreateWindowEx(WS_EX_WINDOWEDGE, 

                    WINDOWS_CLASS, 

                    WINDOWS_TITLE, 

                    WS_OVERLAPPEDWINDOW, 

                    20, 

                    25, 

                    400, 

                    300, 

                    NULL, 

                    NULL, 

                    hThisApp, 

                    NULL); 

    if (hwnd == NULL) 

    {

        return -1;

    }

 

    ShowWindow(hwnd, nShow); 

    UpdateWindow(hwnd); 

 

    MSG msg; 

    while(GetMessage(&msg,NULL,0,0)) 

    { 

        TranslateMessage(&msg); 

        DispatchMessage(&msg); 

    } 

 

    return 0; 

 

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 

    switch(msg) 

    { 

    case WM_DESTROY: 

        PostQuitMessage(0); 

        return 0; 

 

    case WM_CREATE: 

        { 

            //创建三个按钮 

            CreateWindow(L"Button", L"按钮一", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

                35, 10, 160, 60, hwnd, (HMENU)IDB_ONE, hwnd, NULL); 

 

            CreateWindow(L"Button", L"按钮二", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

                35, 80, 160, 60, hwnd, (HMENU)IDB_TWO, hwnd, NULL);

 

            CreateWindow(L"Button", L"按钮三", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 

                35, 150, 160, 60, hwnd, (HMENU)IDB_THREE, hwnd, NULL); 

        } 

        return 0;

 

    case WM_COMMAND: 

        { 

            switch(LOWORD(wParam)) 

            { 

            case IDB_ONE: 

                //MessageBox(hwnd, L"您点击了第一个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

                SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第一个按鈕已点击"); 

                break; 

 

            case IDB_TWO: 

                //MessageBox(hwnd, L"您点击了第二个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

                SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第二个按鈕已点击"); 

                break; 

 

            case IDB_THREE: 

                //MessageBox(hwnd, L"您点击了第三个按钮。", L"提示", MB_OK | MB_ICONINFORMATION); 

                SendMessage((HWND)lParam, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L"第三个按鈕已点击"); 

                break; 

 

            default: 

                break; 

            } 

        } 

        return 0; 

 

    default: 

        return DefWindowProc(hwnd,msg,wParam,lParam); 

    } 

 

    return 0; 

}

————————————————

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM