Click here to Skip to main content
15,891,431 members
Articles / Desktop Programming / MFC

A set of classes to create the IE-style GUI

Rate me:
Please Sign up or sign in to vote.
4.85/5 (52 votes)
19 Jul 2003CPOL6 min read 572.9K   6.4K   168  
The article gives a sample of how to implement Internet Explorer-style sizable re-bar and menu bar controls.
/////////////////////////////////////////////////////////////////////////////
// MenuBar.h: interface for the CMenuBar class.
//
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2002 by Nikolay Denisov. All rights reserved.
//
// This code is free for personal and commercial use, providing this 
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Please email bug reports, bug fixes, enhancements, requests and
// comments to: acnick@mail.lanck.net
/////////////////////////////////////////////////////////////////////////////

#ifndef __MENUBAR_H__
#define __MENUBAR_H__

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "GlobalData.h"

#include <afxtempl.h>

/////////////////////////////////////////////////////////////////////////////
// CMenuBarButtonXxx - helper classes

class CMenuBarButton
{
// Construction
public:
    CMenuBarButton();
    virtual ~CMenuBarButton();

// Operations
public:
    void DrawButton( CDC* pDC, bool bFrameActive );
    bool HitTest( CPoint pt ) const;
    void SetMDIChild( HWND hWndMDIChild );
    void SetMenuBarRect( LPCRECT lpRect );
    void SetTheme( HTHEME hTheme );
    bool HideButton( bool bHide );
    bool PushButton( bool bPush );
    bool IsPushed() const;

    static CSize GetButtonSize();

// Overrides
public:
    virtual CRect GetButtonRect() const = 0;
    virtual UINT GetSysCommandID() const = 0;
    virtual bool IsEnabled() const;
    virtual bool IsVisible() const;

// Implementation
protected:
    DWORD GetMDIChildStyle() const;

// Implementation data
protected:
    HWND    m_hWndMDIChild;
    CRect   m_rcMenuBar;
    bool    m_bHidden;
    bool    m_bPushed;
    HTHEME  m_hTheme;
};

class CMenuBarButtonMin : public CMenuBarButton
{
// Overrides
public:
    virtual CRect GetButtonRect() const;
    virtual UINT GetSysCommandID() const;
    virtual bool IsEnabled() const;
    virtual bool IsVisible() const;
};

class CMenuBarButtonMax : public CMenuBarButton
{
// Overrides
public:
    virtual CRect GetButtonRect() const;
    virtual UINT GetSysCommandID() const;
    virtual bool IsEnabled() const;
    virtual bool IsVisible() const;
};

class CMenuBarButtonClose : public CMenuBarButton
{
// Overrides
public:
    virtual CRect GetButtonRect() const;
    virtual UINT GetSysCommandID() const;
};

/////////////////////////////////////////////////////////////////////////////
// CMenuBar

template< class TBase > class CFrameWndBase;

class GUILIB_EXT_CLASS CMenuBar : public CToolBar
{
    DECLARE_DYNAMIC( CMenuBar );

    friend CFrameWndBase< CFrameWnd >;
    friend CFrameWndBase< CMDIFrameWnd >;

// Construction
public:
    CMenuBar();
    ~CMenuBar();

// Operations
public:
    bool SetMenu( HMENU hMenu );
    HMENU GetMenu() const;

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMenuBar)
    //}}AFX_VIRTUAL

    virtual void OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler );
    virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const;

// Implementation
protected:
    CReBarCtrl& GetParentReBarCtrl() const;
    int GetParentBandIndex() const;
    void SetButtonWidth( UINT nID, int nWidth );
    void UpdateMenuBar();
    void RepositionSysButtons( CRect rcMenuBar );
    void EnterTrackingMode( int nItem );
    void TrackChevronMenu( CRect& rcChevron, int nItem );
    void TrackPopupMenu();
    void ContinueTracking( bool bSelectFirst );
    void ExitTrackingMode();
    void ShowChevronMenu( int nItem );
    bool IsItemClipped( int nItem ) const;
    bool IsOverChevron( CPoint pt ) const;
    bool OnButtonDown( UINT nFlags, CPoint pt, bool bLeft );

// Implementation
protected:
    void HookMessageProc( UINT message, WPARAM wParam, LPARAM lParam );
    bool FrameOnSysCommand( UINT nID, LPARAM lParam );
    bool FrameOnMenuChar( UINT nChar, UINT nFlags, CMenu* pMenu );
    void FrameOnNcActivate( BOOL bActive );
    void FrameOnInitMenuPopup( CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu );
    void FrameOnMenuSelect( UINT nItemID, UINT nFlags, HMENU hSysMenu );
    void OpenTheme();
    void CloseTheme();

// Static members
protected:
    static HHOOK m_hMsgHook;
    static CMenuBar* m_pMenuBar;
    static LRESULT CALLBACK MessageProc( int code, WPARAM wParam, LPARAM lParam );

// Implementation data
protected:
    CFont   m_fontMenu;
    CPoint  m_ptMouseLast;

    HWND    m_hWndMDIChild;
    HWND    m_hWndOldFocus;
    HMENU   m_hMenu;
    HMENU   m_hMenuTracking;

    int     m_nItem;
    bool    m_bItemTracking;
    bool    m_bItemDropped;
    bool    m_bPrimaryMenu;
    bool    m_bSubmenuItem;
    bool    m_bEscape;
    bool    m_bContinue;
    bool    m_bSelectFirst;
    bool    m_bButtonCapture;
    bool    m_bFrameActive;

    CTypedPtrArray< CPtrArray, CMenuBarButton* > m_aMenuBarButtons;

    HTHEME  m_hTheme;

// Generated message map functions
protected:
    //{{AFX_MSG(CMenuBar)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnDestroy();
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
    afx_msg void OnCaptureChanged(CWnd *pWnd);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg UINT OnGetDlgCode();
    afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
    //}}AFX_MSG

    afx_msg LRESULT OnShowPopupMenu( WPARAM wParam, LPARAM lParam );
    afx_msg LRESULT OnReBarChildSize( WPARAM wParam, LPARAM lParam );
    afx_msg LRESULT OnReBarChevronPushed( WPARAM wParam, LPARAM lParam );
    afx_msg LRESULT OnThemeChanged( WPARAM wParam, LPARAM lParam );

    afx_msg void OnUpdateMenuButton( CCmdUI* pCmdUI );

    // Toolbar control notifications
    afx_msg void OnDropDown( NMHDR* pNMHDR, LRESULT* pResult );
    afx_msg void OnHotItemChange( NMHDR* pNMHDR, LRESULT* pResult );
    afx_msg void OnCustomDraw( NMHDR* pNMHDR, LRESULT* pResult );
    DECLARE_MESSAGE_MAP();
};

/////////////////////////////////////////////////////////////////////////////
#endif  // !__MENUBAR_H__

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions