이와 같이 버튼을 누르면 메뉴가 펼쳐지는 버튼을 많이 보아 왔을 것 입니다.
Visual Studio 2008에 포함되어 있는 MFC Feature Pack에서 이와 같은 기능을 구현 하는 방법을 설명 하겠습니다.
이 기능은 AFX_WM_RESETTOOLBAR 메세지 핸들러를 이용해서 처리 합니다.
이 메세지는 도구모음이 초기화 될때 발생 하는데 MFC Feature Pack의 구조가 메뉴나 도구모음등의 사용자 인터 페이스의
변경 사항을 레지스트리에 저장해 두었다가 그 값을 로드해서 인터페이스를 표시 하기 때문에 소스를 수정해서 인테페이스를 수정 하더라도 레지스트리의 값을 우선 하기 때문에 적용이 되지 않습니다.
그래서 도구모음을 초기화 시키면 발생하는 메세지를 이용해서 처리 하는게 가장 매끄럽다고 생각 됩니다.
그런데 불행이도 AFX_WM_RESETTOOLBAR 메세지 핸들러는 Visual studio에 기본으로 등록 되어 있지 않기 때문에
직접 코딩을 해서 등록 해야 합니다.
CMainFrame 클래스에 메세지 핸들러의 원형과 메세지맵을 등록합니다.
(MainFrm.h)
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnViewCustomize();
afx_msg LRESULT OnToolbarCreateNew(WPARAM wp, LPARAM lp);
DECLARE_MESSAGE_MAP()
afx_msg LRESULT OnResetToolBar(WPARAM wParam, LPARAM lParam);
(MainFrm.cpp)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
ON_REGISTERED_MESSAGE(AFX_WM_RESETTOOLBAR, OnResetToolBar)
END_MESSAGE_MAP()
그리고 메세지 핸들러의 함수인 OnResetToolBar에 우리의 목적인 드롭다운 버튼을 생성하는 코드를 작성 하면 됩니다.
(MainFrm.cpp)
LRESULT CMainFrame::OnResetToolBar(WPARAM wParam, LPARAM lParam)
{
// wParam을 통해서 리셋되는 도구모음의 리소스 ID가 전달 됩니다.
// 리소스 ID값을 검사 하여 리셋되는 도구모음에 따라서 다른 코드를 적용 하면 됩니다.
UINT uID = (UINT)wParam;
if (uID == IDR_MAINFRAME_256)
{
CMenu MainMenu;
MainMenu.LoadMenu(IDR_MAINFRAME);
CMenu* pMenu = MainMenu.GetSubMenu(0);
// 도구 모음의 버튼을 다른 스타일로 대체 합니다.
// 여기서 CMFCToolBarButton의 파생 클래스인 CMFCToolBarMenuButton을 이용해서 메뉴가 있는 드롭다운 버튼으로 대체 합니다.
m_wndToolBar.ReplaceButton(ID_FILE_NEW, CMFCToolBarMenuButton((UINT)-1, *pMenu, 0, _T("Drop-down button")));
}
return 0;
}
어떤가요? 간단 하지 않습니까? ㅎㅎ
들인 노력에 비하면 결과가 만족 스럽다고 할 수 있네요. MFC Feature Pack이 버그도 좀 있고 MS에서 개발한게 아니라 이미 판매되고 있는 다른 회사의 제품을 포함한 것이어서 좀 아쉽기는 하지만 그래도 나름대로 쓸만 하더군요.