Problems with Owner Draw Menus in an out of process ActiveX Document Server

My Document Server is written with C++ MFC and built using VS .NET 2003 and is targetted to WinXP and newer.

I’ve now run out of ideas on how to resolve my owner draw problem when an OLE container attempts to render my shared menus.

Everything is fine when the keyboard is used to activate the menubar items. This is because the container is using WM_NCPAINT etc to create a real screen drawing context. This context is then passed through to the in place frame of my server where it will succeed in drawing the menu items ( WM_DRAWITEM )

When the menu bar item is clicked on with the mouse, however, the container make use of WM_PRINT, WM_PRINTCLIENT to render to a memory HDC. When this HDC is passed to my out of process server via WM_DRAWITEM, I cannot use it since its invalid in my process space.

The end result is a useless blank popup menu. The Items are drawn when the mouse is dragged over it but the initial paint is knackered.

I have observed that all works fine if the application is accessed via a Remote Desktop connection. Analysing the message activity of the container reveals it is no longer using WM_PRINT for the menu click handler.

Does anyone know of any way I might signal the containers in-place window to prevent it using WM_PRINT Perhaps a HWND_BROADCAST message ..

I can get the main menu bar items to render ok if I transmit the items hotkey during the servers COleInPlaceFrame::OnMenuSelect handler. Unfortunately this hack does not work reliably for cascading menus



Answer this question

Problems with Owner Draw Menus in an out of process ActiveX Document Server

  • XNA Rockstar

    Finding the window handle to the most recently created menu popup window

    //First get the parent Popup

    HWND hPopupWnd = ::FindWindow(MAKEINTATOM(0x8000),NULL);

    if( hPopupWnd )

    {

    //Now check if their is a Cascade child to this popup

    CWnd* pWnd = CWnd::FromHandle(s_hPopupWnd);

    CWnd* pCascade = pWnd->FindWindowEx(NULL,pWnd->m_hWnd,MAKEINTATOM(0x8000),NULL);

    while( pCascade ) //Got to find the last Cascade menu window

    {

    pWnd=pCascade;

    //Check for a further cascade

    pCascade = pWnd->FindWindowEx(NULL,pCascade->m_hWnd,MAKEINTATOM(0x8000),NULL);

    }

    hPopupWnd = pWnd->GetSafeHwnd(); //Last Cascade found..

    }


  • ankurtech

    I have found a workaround that appears to fix the problem.

    My solution involves the Document Server creating a memory DC during processing of OnDrawItem when the hDC supplied by the caller is invalid.

    The DC is created by Finding the Menu window handle created by the container application via ::FindWindow() and FindWindowEx()

    All subsequent DrawItem calls make use of this newly created DC and a thread is launched to wait for the Menu window to be made visible.

    When the thread detects the target window has been made visible it performs a BitBlt from the memory DC into the menu window DC.. Job Done


  • George Waters

    JazT wrote:

    I have found a workaround that appears to fix the problem.

    My solution involves the Document Server creating a memory DC during processing of OnDrawItem when the hDC supplied by the caller is invalid.

    The DC is created by Finding the Menu window handle created by the container application via ::FindWindow() and FindWindowEx()

    All subsequent DrawItem calls make use of this newly created DC and a thread is launched to wait for the Menu window to be made visible.

    When the thread detects the target window has been made visible it performs a BitBlt from the memory DC into the menu window DC.. Job Done


  • JUANCARLOSR

    thanks its working,
    Once I have a HWND of CMenu how to repaint that  window

    What message are you sending

    I have problem with that, thanks


  • Steveinbeloit

    Hi, I have very similar problem, can you share your solution in more details
    I'm using 3rd party menu (bcmenu), and have problem with paiting bitmaps,
    until mouse is moved over. (there is no problem when bitmap and text is used
    as menu item, but when I remove text (I want bitmap only menu) the menu is
    not paited correctly until mouse is over)
    I don't want to dig into bcmenu code, and I'd like to figure out how to
    repaint the menu once is popup. How to get HWND of that menu to be able to send message
    thanks


  • toastman


  • VDBA

    JazT wrote:

    My Document Server is written with C++ MFC and built using VS .NET 2003 and is targetted to WinXP and newer.

    I’ve now run out of ideas on how to resolve my owner draw problem when an OLE container attempts to render my shared menus.

    Everything is fine when the keyboard is used to activate the menubar items. This is because the container is using WM_NCPAINT etc to create a real screen drawing context. This context is then passed through to the in place frame of my server where it will succeed in drawing the menu items ( WM_DRAWITEM )

    When the menu bar item is clicked on with the mouse, however, the container make use of WM_PRINT, WM_PRINTCLIENT to render to a memory HDC. When this HDC is passed to my out of process server via WM_DRAWITEM, I cannot use it since its invalid in my process space.

    The end result is a useless blank popup menu. The Items are drawn when the mouse is dragged over it but the initial paint is knackered.

    I have observed that all works fine if the application is accessed via a Remote Desktop connection. Analysing the message activity of the container reveals it is no longer using WM_PRINT for the menu click handler.

    Does anyone know of any way I might signal the containers in-place window to prevent it using WM_PRINT Perhaps a HWND_BROADCAST message ..

    I can get the main menu bar items to render ok if I transmit the items hotkey during the servers COleInPlaceFrame::OnMenuSelect handler. Unfortunately this hack does not work reliably for cascading menus


  • Thomas Mauer

    JazT wrote:

    My Document Server is written with C++ MFC and built using VS .NET 2003 and is targetted to WinXP and newer.

    I’ve now run out of ideas on how to resolve my owner draw problem when an OLE container attempts to render my shared menus.

    Everything is fine when the keyboard is used to activate the menubar items. This is because the container is using WM_NCPAINT etc to create a real screen drawing context. This context is then passed through to the in place frame of my server where it will succeed in drawing the menu items ( WM_DRAWITEM )

    When the menu bar item is clicked on with the mouse, however, the container make use of WM_PRINT, WM_PRINTCLIENT to render to a memory HDC. When this HDC is passed to my out of process server via WM_DRAWITEM, I cannot use it since its invalid in my process space.

    The end result is a useless blank popup menu. The Items are drawn when the mouse is dragged over it but the initial paint is knackered.

    I have observed that all works fine if the application is accessed via a Remote Desktop connection. Analysing the message activity of the container reveals it is no longer using WM_PRINT for the menu click handler.

    Does anyone know of any way I might signal the containers in-place window to prevent it using WM_PRINT Perhaps a HWND_BROADCAST message ..

    I can get the main menu bar items to render ok if I transmit the items hotkey during the servers COleInPlaceFrame::OnMenuSelect handler. Unfortunately this hack does not work reliably for cascading menus


  • Problems with Owner Draw Menus in an out of process ActiveX Document Server