Thread: How to process accelerator message?

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    235

    Question How to process accelerator message?

    In MSDN I have found:

    "Processing WM_COMMAND Messages

    When an accelerator is used, the window specified in the TranslateAccelerator function receives a WM_COMMAND or WM_SYSCOMMAND message. The low-order word of the wParam parameter contains the identifier of the accelerator. The window procedure examines the identifier to determine the source of the WM_COMMAND message and process the message accordingly.

    Typically, if an accelerator corresponds to a menu item in the application, the accelerator and menu item are assigned the same identifier. If you need to know whether a WM_COMMAND message was generated by an accelerator or by a menu item, you can examine the high-order word of the wParam parameter. If an accelerator generated the message, the high-order word is 1; if a menu item generated the message, the high-order word is 0."

    But it is not clear to me, which message to process if I just press single key like ctrl or combination of ctrl+click or ctrl+0. This is nothing with menu. I need to install hotkey.
    I have more dialog procedures in program and I have tried 3 procedures to break it in case WM_MESSAGE: but the debugger did not break there.

    This is the acclerator table:

    Code:
    IDA_MAIN ACCELERATORS
    BEGIN
        "W", ID_FILE_CLOSE, VIRTKEY, CONTROL
        "O", ID_FILE_OPEN, VIRTKEY, CONTROL
        "S", ID_FILE_SAVE_AS, VIRTKEY, CONTROL
        "C", ID_EDIT_COPY, VIRTKEY, CONTROL
        "X", ID_EDIT_CUT, VIRTKEY, CONTROL
        "V", ID_EDIT_PASTE, VIRTKEY, CONTROL
      VK_F2, ID_EDIT_RENAME, VIRTKEY
        VK_CONTROL, IDA_CTRL, CONTROL, VIRTKEY
    END

    Code:
    int WINAPI WinMain(HINSTANCE hWINAPI, HINSTANCE, LPTSTR cmdline, int cmdshow)
    {
    MSG msg;
    BOOL ret;
    HACCEL accelerators;
    ...
    previousPropertySheetProc =  (DLGPROC)SetWindowLong(wrapper.handles.hPropSheet, DWL_DLGPROC,  (LONG)&MainPropertySheetDlgProc);
    
    if (!accelerators)
        {
        MessageBox(wrapper.handles.hPropSheet,
        "Keyboard Accelerators failed to load. Keyboard shortcuts will not be available.",
        "Warning", MB_ICONWARNING);
        }
    So how to find out in which dialog process I should look for and which message?

    I am using Windows XP and Visual Studio C++ 2010

    Code:
    while (ret = GetMessage(&msg, NULL, 0, 0))
        {
            if (ret < 0)    //did GetMessage() fail?
            {
            MessageBox(wrapper.handles.hPropSheet,
            "Unable to retrieve messages from queue. Click OK to terminate.",
            "Fatal Error", MB_ICONERROR);
            break;
            }
    
            if (TranslateAccelerator(wrapper.handles.hPropSheet, accelerators, &msg) ||
            PropSheet_IsDialogMessage(wrapper.handles.hPropSheet, &msg))
            continue;
    
            // Usually active is the hSheet. If it's not, it's a modeless dialog and
            // it should get a crack, too.
            if ((wrapper.handles.hActivePropSheetPage = GetActiveWindow()) != wrapper.handles.hPropSheet &&
            IsDialogMessage(wrapper.handles.hActivePropSheetPage, &msg))
            continue;
    
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    Last edited by barracuda; 09-14-2015 at 05:25 AM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    This should be in the Windows section.

    >>I have tried 3 procedures to break it in case WM_MESSAGE:

    Accelerators are sent as WM_COMMAND (not WM_MESSAGE)

    You should check the wParam;
    LOWORD(wParam) is the int ID of the command as defined in your resource.h file

    HIWORD(wParam) this is 0 if a menu item was clicked OR 1 if an accelerator was used.

    >>So how to find out in which dialog process I should look for and which message?

    Because only 1 callback receives the WM_COMMAND msg; the callback of the active window when the accelerator key combo was pressed.

    Code:
    case WM_COMMAND:
    //find which control / menu / accelerator generated a msg
    	switch( LOWORD(wParam) ) 
    		
    		case ID_FILE_CLOSE;	
    		//the file close command was clicked 
    
    		//check to see if it was the accelerator
    		if( HIWORD(wParam) == 1)
    		{
    			//accelerator was used
    		}
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    *moved to Windows programming*
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    The problem was different. I did not realized that accelerators are used in different way than I need. I think they are used only for menu. But there is simpler way to do what i need and it is to use WM_KEYDOWN and WM_KEYUP message or

    Code:
    bool ctrlPressed;
    SHORT keystate = GetKeyState(VK_CONTROL);
    if (keystate & PRESSED)
          {
          ctrlPressed = true; 
          }
    I need yet one more thing which I read somewhere, if I recall it, detect if the CRTL key was pressed previously or not: I think it was 30th bit of the keystate.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to Use POSIX for IPC Message To Another Process?
    By dedham_ma_man in forum C Programming
    Replies: 4
    Last Post: 09-28-2007, 03:06 PM
  2. Sending a message to parent from child process
    By maxorator in forum C++ Programming
    Replies: 2
    Last Post: 10-09-2005, 04:23 PM
  3. accelerator keys in win32 API
    By bennyandthejets in forum Windows Programming
    Replies: 2
    Last Post: 11-09-2002, 09:42 PM
  4. accelerator keys
    By bennyandthejets in forum Windows Programming
    Replies: 7
    Last Post: 10-28-2002, 12:52 AM
  5. keyboard accelerator problems
    By luchobiazutti in forum Windows Programming
    Replies: 6
    Last Post: 07-08-2002, 05:17 PM