Scrollbar and context menu
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7

Thread: Scrollbar and context menu

  1. #1
    Join Date
    Jan 2010
    Posts
    14

    Scrollbar and context menu

    Hi all!

    I created a window that has a vertical scroll bar (by WS_VSCROLL style).

    For some reasons too long to explain here, I have to hide the right button context menu associated with a scrollbar (Scroll here, Pag up, ecc.).

    I know that scrollbar is in non client area but when I move cursor on it my WndProc doesn't receive neither WM_NCRBUTTONUP.

    Any suggestion?

    Thaks!

  2. #2
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,058

    Re: Scrollbar and context menu

    Handle WM_CONTEXTMENU message like in the following example:
    Code:
        switch(message)
        { 
        case WM_CONTEXTMENU:
            // If the user right-clicks in the vertical scrollbar of this window...
            if((HWND)wParam == hWnd)
            {
                if(HTVSCROLL == ::SendMessage(hWnd, WM_NCHITTEST, 0, lParam))
                {
                    // ... do anything else (or nothing), oterwise...
                    break;
                }
            }
            // ... call DefWindowProc.
            return DefWindowProc(hWnd, message, wParam, lParam);
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  3. #3
    Join Date
    Jan 2010
    Posts
    14

    Re: Scrollbar and context menu

    Thanks for your reply.
    I've two other questions.

    1. If in my window ther is a ListBox, must I define a ListBox WNDPROC to handle WM_CONTEXTMENU on it? It's not possibile to handle it from my Dialog WNDPROC?

    2. I've tested your code in a empty project and it works. But in my existing code I must substitute break with return 1 (also with return 0 it doesn't work) to really hide contextmenu. I'm pretty sure that there isn't another DefWindowProc...

    Thanks.

  4. #4
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,058

    Re: Scrollbar and context menu

    Generally, in a window procedure, DefWindowProc must be called in case of messages not handled by the application to let the system do the default processing.
    But, if the window is a DIALOG, its procedure is a little bit different. Typically, the dialog box procedure should return TRUE if it processed the message, and FALSE if it did not. If FALSE is returned, the dialog manager performs the default processing and it's not needed a call to DefWindowProc.

    See
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  5. #5
    Join Date
    Jan 2010
    Posts
    14

    Re: Scrollbar and context menu

    Thanks a lot.
    I've resolved now.

  6. #6
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,058

    Re: Scrollbar and context menu

    You are welcome!

    Just a little bit to clarify point #1.
    A child control (e.g. a listbox) notifies its parent via WM_CONTEXTMENU. However, if the click is in one of its scrollbars, that doesn't happen.
    If we want to get rid of that context menu, we have to subclass the control.
    That means, we have to change the control's default procedure with an application-defined one, like in the following example:
    Code:
    WNDPROC g_pfnDefListBoxProc = NULL;
    // ...
    INT_PTR CALLBACK DialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
       switch(uMsg)
       {
       case WM_INITDIALOG:
          {
             HWND hWndList = ::GetDlgItem(hWndDlg, IDC_MY_LISTBOX);
             g_pfnDefListBoxProc = 
                (WNDPROC)::SetWindowLong(hWndList, GWL_WNDPROC, (LONG)ListBoxProc);
          }
          return TRUE;
       // ...
       }
       return FALSE;
    }
    Code:
    LRESULT CALLBACK ListBoxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
       switch(uMsg)
       {
       case WM_CONTEXTMENU:
          if(HTVSCROLL == ::SendMessage(hWnd, WM_NCHITTEST, 0, lParam))
          {
             // ... do anything else (or nothing).
             return 0;
          }
          break;
       }
       return CallWindowProc(g_pfnDefListBoxProc, hWnd, uMsg, wParam, lParam);
    }
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  7. #7
    Join Date
    Jan 2010
    Posts
    14

    Re: Scrollbar and context menu

    Quote Originally Posted by ovidiucucu View Post
    You are welcome!

    Just a little bit to clarify point #1.
    A child control (e.g. a listbox) notifies its parent via WM_CONTEXTMENU. However, if the click is in one of its scrollbars, that doesn't happen.
    Yes, I've notice this using Spy++ so I had to write a custom ListBox WNDPROC as you have suggest.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center