A timed context menu

Raymond Chen

Raymond

This is sort of in the same spirit as our previous
exercise in writing a timed message box, but this is much
easier.
Here, we use the handy-dandy

WM_CANCELMODE message

to get us out of menu mode.

void CALLBACK
MenuTooLateProc(HWND hwnd, UINT uiMsg, UINT idEvent, DWORD dwTime)
{
  SendMessage(hwnd, WM_CANCELMODE, 0, 0);
}
BOOL
TimedTrackPopupMenuEx(HMENU hMenu, UINT uFlags, int x, int y,
    HWND hwnd, LPTPMPARAMS pTpm, DWORD dwTimeout)
{
    UINT idTimer = SetTimer(NULL, IDT_TOOLATE, dwTimeout, MenuTooLateProc);
    BOOL fResult = TrackPopupMenuEx(hMenu, uFlags, x, y, hwnd, pTpm);
    if (idTimer) KillTimer(NULL, idTimer);
    return fResult;
}

Before displaying the menu, we set a timer. (And we use a thread
timer because we don’t own the hwnd window and therefore
don’t know what timer IDs are safe to use.)
If the timer fires,
we send ourselves a WM_CANCELMODE message to cancel menu mode.
This causes the system to act as if the user had dismissed the
menu without selecting anything, either by hitting ESC or
clicking outside the menu. The call to

the TrackPopupMenuEx function

returns once the user has selected something
(or the timeout has elapsed), at which point we clean up by
destroying our timer before returning.

0 comments

Comments are closed.