Cybercartel
Cybercartel

Reputation: 12592

Systray how to track status of a menu when clicked?

I have a systray and I want to track a menu when it's clicked. For example I use InsertMenu(hPopMenu,0xFFFFFFFF,uFlag,IDM_AUTO,_T("Auto")); when the right mouse button is clicked over the systray but it always overide my changes? How can I track which menu the user has clicked? This is my callback function:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    POINT lpClickPoint;
    HMENU hMenu;    // handle to main menu 
    MENUITEMINFO mii = {sizeof(MENUITEMINFO) };
    BOOL status;

    switch (message)
    {
        case WM_USER_SHELLICON: 

            // systray msg callback 
            switch(LOWORD(lParam)) 
            {   
                case WM_RBUTTONDOWN: 

                    UINT uFlag = MF_BYPOSITION|MF_UNCHECKED|MF_STRING;
                    GetCursorPos(&lpClickPoint);
                    hPopMenu = CreatePopupMenu();

                                InsertMenu(hPopMenu,0xFFFFFFFF,uFlag,IDM_AUTO,_T("Auto")); InsertMenu(hPopMenu,0xFFFFFFFF,MF_SEPARATOR,IDM_SEP,_T("SEP"));                                  
InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_EXIT,_T("Exit"));

                    SetForegroundWindow(hWnd);
                    TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,lpClickPoint.x, lpClickPoint.y,0,hWnd,NULL);
                    return TRUE; 
            }
            break;

    case WM_COMMAND:

        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);

        // Parse the menu selections:


               ...
               ...

    }
    break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Upvotes: 0

Views: 245

Answers (2)

user645280
user645280

Reputation:

You're re-creating every mouse click. So, you have to initialize based on current state.

UINT uFlag = MF_BYPOSITION|MF_UNCHECKED|MF_STRING;

becomes:

UINT uFlag;
if( bCheckboxShouldBeCheckedAccordingToYourApplication )
    uFlag = MF_BYPOSITION|MF_CHECKED|MF_STRING;
else
    uFlag = MF_BYPOSITION|MF_UNCHECKED|MF_STRING;

Here, now it's shorter but still actually matches the posed question:

UINT uFlag = MF_BYPOSITION  | (b?8:0) | MF_STRING;

Of course, it's a bit less readable.

Upvotes: 1

Cybercartel
Cybercartel

Reputation: 12592

It works :). Like in the comment I used a variable to store the state and then after the InsertMenu I change the menu state.

MENUITEMINFO mii = {sizeof(MENUITEMINFO) };
mii.fMask = MIIM_STATE;
status = GetMenuItemInfo(hPopMenu, oldmenu, FALSE, &mii);
mii.fState ^= MFS_CHECKED;
status = SetMenuItemInfo(hPopMenu, oldmenu, FALSE, &mii);

Upvotes: 0

Related Questions