CMFCCaptionMenuButton alternative?
I need to create a caption bar button for a CDockablePane
which will call up a menu with various options. I tried to use CMFCCaptionMenuButton
and the button and menu show up but the message map methods for the menu ids don't fire. The MFC documentation states that CMFCCaptionMenuButton
is meant for internal infrastructure and not really for your code.
So assuming that is what my problem is should I be using a CMFCCaptionBarButton
and then making a separate popup menu? Has anyone made a similar caption bar based menu in MFC before?
Here's some slimmed down code snippets in case I just made a stupid mistake in hooking up the events:
BEGIN_MESSAGE_MAP(CDockPane, CDockablePane)
ON_COMMAND(ID_MORPH_BROWSER, OnMorphBrowser)
END_MESSAGE_MAP()
void CDockPane::OnPressButtons(UINT nHit)
{
// only for custom button handling don't call base
// close, maximize, and pin will be handled by default
switch (nHit)
{
case ID_MORPHTEST:
{
CMorphMenuButton* pButton = dynamic_cast<CMorphMenuButton*>(m_arrButtons.GetAt(m_morphIndex));
pButton->ShowMenu(this);
break;
}
}
}
void CDockPane::SetCaptionButtons()
{
CDockablePane::SetCaptionButtons(); // for close, pin etc
m_morphIndex = m_arrButtons.Add(new CMorphMenuButton(ID_MORPHTEST));
}
void CDockPane::OnMorphBrowser()
{
// do stuff on menu item click
}
Edit: Removed p开发者_StackOverflow社区revious code no longer in use
Now that the sound of crickets chirping has dwindled in the background I guess I'll post the workaround I currently have in place:
Instead of inheriting and extending CMFCCaptionMenuButton
I build my class by extending CMFCCaptionButton
. I then create a menu and provide a ShowMenu method to be explicitly called when handling the custom button events as well as overriding GetIconID to return a particular system icon for the button for each menu added to the caption bar ending up with something like this for the example outlined in the question:
#pragma once
// CMorphMenuButton command target
class CMorphMenuButton : public CMFCCaptionButton
{
public:
CMorphMenuButton(UINT nHit);
virtual ~CMorphMenuButton();
virtual CMenuImages::IMAGES_IDS GetIconID (BOOL bHorz, BOOL bMaximized) const;
void ShowMenu(CWnd* pWnd);
private:
CMenu m_dockMenu;
CMenu* m_subMenu;
};
// MorphMenuButton.cpp : implementation file
//
#include "stdafx.h"
#include "MorphMenuButton.h"
// CMorphMenuButton
CMorphMenuButton::CMorphMenuButton(UINT nHit)
: CMFCCaptionButton(nHit)
{
SetMiniFrameButton(); // already defaulted?
m_dockMenu.LoadMenu(IDR_DOCKPANE); // resource ID for dock pane menus
}
CMorphMenuButton::~CMorphMenuButton()
{
m_dockMenu.DestroyMenu();
}
CMenuImages::IMAGES_IDS CMorphMenuButton::GetIconID(BOOL bHorz, BOOL bMaximized) const
{
return CMenuImages::IdArrowForward;
}
void CMorphMenuButton::ShowMenu(CWnd* pWnd)
{
CRect windowRect, buttonRect;
pWnd->GetWindowRect(&windowRect);
buttonRect = GetRect();
CPoint menuPos(windowRect.left + buttonRect.right, windowRect.top + buttonRect.bottom);
m_subMenu = m_dockMenu.GetSubMenu(0);
if (!m_subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, menuPos.x, menuPos.y, pWnd))
{
DWORD id = GetLastError();
wchar_t errMsg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, id, 0, errMsg, sizeof(errMsg), 0);
MessageBox(0, errMsg, L"Error", MB_OK);
}
}
The setting of caption bar buttons and handling of click events for both buttons and menus are the same as defined in the question and this works.
精彩评论