• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 339
  • Last Modified:

System Menu anywhere in dialog with right click

How can I show System Menu anywhere in dialog with right click in a Dialog Based app?
0
bkuyucu
Asked:
bkuyucu
  • 8
  • 4
1 Solution
 
KurtVonCommented:
This seems to work fine

void CTestDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
    CMenu* pSysMenu = GetSystemMenu(FALSE);

    ClientToScreen(&point);
    pSysMenu->TrackPopupMenu(TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
}

The real trick is reponding to the events since this sends a WM_COMMAND instead of a WM_SYSCOMMAND message.  To respond you need to save all the sys command IDs and then catch them in the OnCommand function and change them back to WM_SYSCOMMANDs.  I created a member

CArray<WPARAM, WPARAM> m_wpaSysCommands;

then added

    m_wpaSysCommands.RemoveAll();
    for (int nIndex = 0;nIndex < pSysMenu->GetMenuItemCount();++nIndex)
        m_wpaSysCommands.Add(pSysMenu->GetMenuItemID(nIndex));

before the TrackPopupMenu command above.  In on command just add the following

    for (int nIndex = 0;nIndex < m_wpaSysCommands.GetSize();++nIndex)
    {
         if (wParam == m_wpaSysCommands.GetAt(nIndex))
        {
            m_wpaSysCommands.RemoveAll();
            PostMessage(WM_SYSCOMMAND, wParam, lParam);
            return TRUE;
        }
    }

before the call to the base class.
0
 
bkuyucuAuthor Commented:
I want something more straight. A message combination must result in the system menu to be displayed. For example WM_NCRBUTTONUP + smthg. Cause only posting WM_NCRBUTTONUP did not work.

This is like moving a dialog by clicking anywhere in the client region. U just deceive windows by sending WM_NCLBUTTONDOWN with a parameter HT_CAPTION and coordinates. I want something like this.
Best Regards
0
 
KurtVonCommented:
Well, you could override OnNCHitTest to return HTCAPTION, but that also will allow left button dragging anywhere in the dialog.

Oh, and you could try the posting of WM_NCLBUTTONDOWN with HTSYSMENU.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
bkuyucuAuthor Commented:
I have tried
PostMessage (WM_NCRBUTTONDOWN, HTSYSMENU, MAKELPARAM(point.x,point.y));    
in OnRButtonDown.
This does not work.
For an example of what i want u can look at Windows Cdplayer. When u dblclick on caption bar, title bar disappears and u can right-click anywhere on client region to get system menu.
I traced it with Spy++ for messages going in and out. But couldnt catch the secret.
Thanks for replies.
0
 
KurtVonCommented:
Sorry, that should be WM_NCLBUTTONUP.
0
 
bkuyucuAuthor Commented:
I have tried
PostMessage (WM_NCRBUTTONDOWN, HTSYSMENU, MAKELPARAM(point.x,point.y));    
in OnRButtonDown.
This does not work.
For an example of what i want u can look at Windows Cdplayer. When u dblclick on caption bar, title bar disappears and u can right-click anywhere on client region to get system menu.
I traced it with Spy++ for messages going in and out. But couldnt catch the secret.
Thanks for replies.
0
 
KurtVonCommented:
Sorry, that should be WM_NCLBUTTONUP.
0
 
KurtVonCommented:
Sorry, that should be WM_NCLBUTTONUP.
0
 
KurtVonCommented:
Sorry about the multiple post.
0
 
bkuyucuAuthor Commented:
No problem I think its not related to us. My comment was posted twice too.

So where we are? I tried everything possible so far.
PostMessage (WM_NCLBUTTONUP, HTCAPTION, MAKELPARAM(point.x,point.y));    
or
PostMessage (WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));    
or
PostMessage (WM_NCLBUTTONUP, HTSYSMENU, MAKELPARAM(point.x,point.y));    
or
PostMessage (WM_NCRBUTTONDOWN, HTSYSMENU, MAKELPARAM(point.x,point.y));    
or
PostMessage (WM_NCRBUTTONUP, HTSYSMENU, MAKELPARAM(point.x,point.y));          

I got nothing so far.
Do u have another advice?
0
 
KurtVonCommented:
Nope, the sys menu just doesn't respond to posted messages or NCHitTest faking.  It must be handled externally in some way.

Like I said, the technique I used above works.  I still can't remember when or why I first used it, but retesting this stuff does explain the convolution.  I suspect I just got frustrated and went with the brute force method (actually it was a button message I was responding to in the original code).

I can promise you it works.  I had to tweak it for sub-menus on the system menu, like for NVidia cards, but that code is owned by someone else, and pretty easy to figure out anyway.

If you find more elegant way around it I'd be glad to hear it, but sometimes elegant has to be set aside for a solution that just works.
0
 
KurtVonCommented:
Actually, I take that back.  Except for the positioning, you can always bring up the Sys Menu by faking the sys menu message:

PostMessage(WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE);

Of course, like I said, that only brings it up in the normal sys menu position.  I suppose you could get the handle and move it after it is up, though.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now