Search code examples
c++winapimfckeyboard-shortcutsmfc-feature-pack

How to get keyboard accelerators for a command ID?


The MFC feature pack seem to magically print the resources keyboard accelerator shortcuts to the tooltip of a menu item. How would I find the key combination for any given command ID (if all I have is the HACCEL handle?).


Solution

  • You can use the CopyAcceleratorTable() function to retrieve the list of accelerators for a given HACCEL handle.

    First, call that function with nullptr and 0 as the second and third arguments to get the size of the list (i.e. the number of accelerators) and then allocate a buffer of ACCEL structures of appropriate size.

    Then you can call CopyAcceleratorTable again with a pointer to that buffer and the previously returned count.

    Now you can iterate through that buffer, using the three fields of each structure to determine what the accelerator key is, what flags it has and what command it represents.

    HACCEL hAcc; // Assuming this is a valid handle ...
    int nAcc = CopyAcceleratorTable(hAcc, nullptr, 0); // Get number of accelerators
    ACCEL *pAccel = new ACCEL[nAcc];                   // Allocate the required buffer
    CopyAcceleratorTable(hAcc, pAccel, nAcc);          // Now copy to that buffer
    for (int a = 0; a < nAcc; ++a) {
        DWORD cmd = pAccel[a].cmd; // The command ID
        WORD  key = pAccel[a].key; // The key code - such as 0x41 for the "A" key
        WORD  flg = pAccel[a].fVirt; // The 'flags' (things like FCONTROL, FALT, etc)
        //...
        // Format and display the data, as required
        //...
    }
    delete[] pAccel; // Don't forget to free the data when you're done!
    

    You can see a description of the values and formats of the three data fields of the ACCEL structure on this page.