Search code examples
c++cwinapiresource-files

c++ Keyboard accelerator function not working


I have been training on how to make a keyboard accelerator key but when I try it, it doesn't work.. here is the code:

Resource file::

    #include "resource.h"

    IDM_MAINMENU MENU
    BEGIN
        POPUP "&File"
        BEGIN
            POPUP "&Program"
                BEGIN

                MENUITEM "LED O&N", IDM_PROGRAM_LED_ON
                MENUITEM "LED O&FF", IDM_PROGRAM_LED_OFF
                MENUITEM "LED &BLINK", IDM_PROGRAM_LED_BLINK

                END
            MENUITEM SEPARATOR
            MENUITEM "E&xit", IDM_FILE_EXIT
        END
        POPUP "&Help"
        BEGIN
            MENUITEM "&Info", IDM_INFO
        END

    END


    app_icon   ICON "untitled.ico"

    IDA_ACCEL_TABLE ACCELERATORS
    BEGIN
       "x", IDA_CTRL_X, CONTROL, VIRTKEY
    END

Header file:

        #define  app_icon              1
        #define  IDM_MAINMENU          2
        #define  IDM_FILE_EXIT         3
        #define  IDA_ACCEL_TABLE       4
        #define  IDD_DIALOG            5
        #define  IDA_CTRL_X            6
        #define  IDM_PROGRAM_LED_OFF   7
        #define  IDM_PROGRAM_LED_BLINK 8
        #define  IDM_PROGRAM_LED_ON    9
        #define  IDM_INFO              10

main .exe file::

        #include <windows.h>
        #include "resource.h"
        #include "define.h"

        LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

        int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd){


        window win;
        MSG msg;
        HMENU hMenu;
        hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDM_MAINMENU));
        HACCEL hAccel;
        hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDA_ACCEL_TABLE));

        win.cbClsExtra = NULL;                             //Additional parameters
        win.cbWndExtra = NULL;                            //Additional parameters
        win.hbrBackground = (HBRUSH)COLOR_WINDOW ;                        //Sets background color for the window
        win.hCursor = LoadCursor(NULL, IDC_ARROW);      //The cursor that will appear in the window
        win.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(app_icon));                              //Icon for the window
        win.hInstance = hInst;                        //Handle to the application instance
        win.lpszClassName = "Window Class";          //The unique name of the window class
        win.lpszMenuName = NULL;                    //Used for menus
        win.style = NULL;                          //The look and feel of the window
        win.lpfnWndProc=(WNDPROC)WinProc;         //The callback procedure (more on that later)

        RegisterClass(&win);
        HWND hwnd = CreateWindow("Window Class", "Atmel Microcontroller Programmer", WS_OVERLAPPEDWINDOW, 550, 300, 350, 260, NULL, hMenu, hInst, NULL);
        ShowWindow(hwnd, SW_SHOWNORMAL);

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


            if(!TranslateAccelerator(hwnd, hAccel, &msg)){
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }

        }

        return 0;

        }

        LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){

        switch (message){

        case WM_CREATE:{

            CreateWindow("BUTTON", "LED on", WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 20, 70, 50, hWnd, (HMENU)1, NULL, NULL);
            CreateWindow("BUTTON", "LED off", WS_CHILD | WS_VISIBLE | WS_BORDER, 125, 80, 70, 50, hWnd, (HMENU)2, NULL, NULL);
            CreateWindow("BUTTON", "LED blink", WS_CHILD | WS_VISIBLE | WS_BORDER, 240, 140, 70, 50, hWnd, (HMENU)3, NULL, NULL);
            break;

        }

        case WM_COMMAND:{

        if(wParam == 1){

            system("avrdude");


        }

        if(wParam == 2){

            system("avrdude");


        }

        if(wParam == 3){

            system("avrdude");


        }

        if (wParam == IDA_CTRL_X){

            MessageBeep(message);

        }

            break;
        }

        case WM_DESTROY:{

            PostQuitMessage(0);
            return 0;
            break;

        }

        default:{

            return DefWindowProc(hWnd, message, wParam, lParam);

        }
        }


        }

this is all the files I have been using, but there is also one more header file where I have defined small things and added comments fr me to remember but it is so large, the most important things I defined were the message as MessageBox and the window as WNDCLASS

I know that is to much effort to read all this but I really need help, thanks so so much guys. =D

EDIT

and yep case u r asking I am trying to make a program from the computer to control a circuit I will make from a microcontroller but I didn't yet do the hex program or the circuit this is all I started with.


Solution

  • I believe your error is here:

    if (wParam == IDA_CTRL_X){
        MessageBeep(message);
    }
    

    When the message source for the WM_COMMAND is an accelerator the high word of wParam is 1 and the low word is the accelerator identifier. If it's a menu then the high word is 0 and the low word is the menu identifier. (See reference.)

    So what you have to do is this:

    switch (message)
    {
        case WM_COMMAND:
           wmId    = LOWORD(wParam);
           wmEvent = HIWORD(wParam);
    
           switch(wmId)
           {
             case IDA_CTRL_X:
                MessageBeep(message);
                break; 
           }
        break;
    }