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