Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Command Bars
  New Posts New Posts RSS Feed - TrackPopupMenu
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

TrackPopupMenu

 Post Reply Post Reply
Author
Message
Michl View Drop Down
Senior Member
Senior Member


Joined: 14 September 2007
Status: Offline
Points: 138
Post Options Post Options   Thanks (0) Thanks(0)   Quote Michl Quote  Post ReplyReply Direct Link To This Post Topic: TrackPopupMenu
    Posted: 22 December 2010 at 3:29am
Hi

first of all, I know it is not a very good programming style - but it is windows :)

In a windows(!)-system-callback (this is raising in another worker-thread-context!), I like to view a small popup context window with TrackPopupMenu.

MFC build in function works without assertions. But if I use Codejocks CommandBars the application crashes! I know ToolkitPro is not thread safe, but I don't manipulate data. The question is, ToolkitPro?


BOOL CXTPCommandBars::TrackPopupMenu(CXTPPopupBar* pPopup, UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT rcExclude, CWnd* pWndOwner)
{
    ASSERT(pPopup);
    if (!pPopup)
    {
        return FALSE;
    }

    const MSG& msg = AfxGetThreadState()->m_lastSentMsg;
    if (msg.message == WM_CONTEXTMENU && msg.lParam == MAKELPARAM(-1, -1) && pPopup->GetCommandBars())
        pPopup->GetCommandBars()->ShowKeyboardCues(TRUE);

    if (!pWnd)
        pWnd = pPopup->GetSite();

    pPopup->m_pSite = pWnd ;
    pPopup->m_pOwner = pWndOwner;

    if (pWnd && pWnd->GetExStyle() & (WS_EX_LAYOUTRTL | WS_EX_RIGHT))
        nFlags |= TPM_RIGHTALIGN;

    UINT nReturn = TRUE;
    pPopup->m_pReturnCmd = NULL;

    if (nFlags & TPM_RETURNCMD)
    {
        pPopup->m_pReturnCmd = &nReturn;
        nReturn = 0;
    }
    pPopup->m_bExecOnRButton = nFlags & TPM_RIGHTBUTTON;
    pPopup->m_bIgnoreUpdateHandler = nFlags & TPM_NONOTIFY;

    pPopup->m_popupFlags = 0;
    if (nFlags & TPM_RIGHTALIGN)
        pPopup->m_popupFlags |= xtpPopupLeft;

    if (nFlags & TPM_BOTTOMALIGN)
        pPopup->m_popupFlags |= xtpPopupUp;
    else
        pPopup->m_popupFlags |= xtpPopupDown;

    BOOL bRecurse = nFlags & TPM_RECURSE;
    pPopup->m_bRecursePopup = bRecurse;

    CXTPMouseManager* pMouseManager = XTPMouseManager();

    if (!bRecurse)
    {
        pMouseManager->SendTrackLost();
        ReleaseCapture();
    }
    else
    {
        pMouseManager->SendTrackLostRecurse();
        pMouseManager->LockTrackRecurse(TRUE);
    }
    pMouseManager->IgnoreLButtonUp();

    if (!pPopup->Popup(x, y, rcExclude))
    {
        return FALSE;
    }

    pPopup->PumpMessage();

    if (bRecurse)
    {
        pMouseManager->LockTrackRecurse(FALSE);
    }

    return nReturn;
}


void CXTPPopupBar::PumpMessage()
{
    CXTPMouseManager* pMouseManager = XTPMouseManager();

    while (IsTrackingMode())
    {
        MSG msg;
        if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (pMouseManager->PreviewTackLost(this, &msg))
            {
                SetTrackingMode(FALSE);
                break;
            }

            if (!::GetMessage(&msg, NULL, 0, 0))
                break;

            if (!IsTrackingMode())
            {
                ::PostMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
                break;
            }

            if (msg.message != WM_KICKIDLE && !AfxGetThread()->PreTranslateMessage(&msg))
            {
                // process this message
                ::TranslateMessage(&msg);
                ::DispatchMessage(&msg);
            }
        }
        else
        {
            WaitMessage();
        }
    }
}


AfxGetThread() returns NULL because theApp object was created in main thread. This is correct and highly recommended to avoid simultaneous execution.

What do you mean, Oleg? Make it sense to check pointer and call only PreTranslateMessage in same thread? Or avoid using your TrackPopupMenu because more functions potentially unsafe.

Thanks
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 23 December 2010 at 9:08am
Hi,

If you need GUI you should run GUI-thread. in this case AfxGetThread will return CWinThread you created.

Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
Michl View Drop Down
Senior Member
Senior Member


Joined: 14 September 2007
Status: Offline
Points: 138
Post Options Post Options   Thanks (0) Thanks(0)   Quote Michl Quote  Post ReplyReply Direct Link To This Post Posted: 10 January 2011 at 10:44am
Hello Oleg

Sorry, I was in christmas holidays.

I know that only the main thread should create user interfaces. But our problem don't occur in a (normal) executable application. We developed an ad-snapin extension (.dll)

After you have registered the snapin, windows will be called a COM callback 'AddPages' of interface 'IShellPropSheetExt'. Before, windows must loading the dll and initialize (indirect) MFC (because CWinApp is static object as known). This initialize also the structure wich returns the pointer by calling AfxGetThread(). But this all happens in thread A.

This functions creates an user defined tab (CPropertyPage) which contains a button for extended settings and returns it. Additional a callback function is defined by a message map. This function is calling, but from thread B!???

I don't understand it, too.
I like to know what windows is doing in his own internal message map!? (perhaps saving main property page for crashes)

However, in my oppinion it should be possible to create a standalone popup or window with own message loop. If you are not in gui thread (AfxGetThread() == NULL), you should don't call PreTranslateMessage()!

As you can see, the internal function TrackPopupMenu of MFC works!

What is your oppinion?
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.172 seconds.