aboutsummaryrefslogtreecommitdiff
path: root/mmc_updater/depends/win32cpp/frame.h
diff options
context:
space:
mode:
Diffstat (limited to 'mmc_updater/depends/win32cpp/frame.h')
-rw-r--r--mmc_updater/depends/win32cpp/frame.h3303
1 files changed, 3303 insertions, 0 deletions
diff --git a/mmc_updater/depends/win32cpp/frame.h b/mmc_updater/depends/win32cpp/frame.h
new file mode 100644
index 00000000..1f439fd7
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/frame.h
@@ -0,0 +1,3303 @@
+// Win32++ Version 7.2
+// Released: 5th AUgust 2011
+//
+// David Nash
+// email: dnash@bigpond.net.au
+// url: https://sourceforge.net/projects/win32-framework
+//
+//
+// Copyright (c) 2005-2011 David Nash
+//
+// Permission is hereby granted, free of charge, to
+// any person obtaining a copy of this software and
+// associated documentation files (the "Software"),
+// to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify,
+// merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom
+// the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice
+// shall be included in all copies or substantial portions
+// of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// frame.h
+// Declaration of the CFrame and CMenuBar classes
+
+// The classes declared in this file support SDI (Single Document Interface)
+// frames on Win32/Win64 operating systems (not Windows CE). For Windows CE,
+// use wceframe.h instead. SDI frames are a simple frame which supports a
+// single view window. Refer to mdi.h for frames that support several
+// child windows.
+
+// CFrame also includes each of the following classes as members:
+// * CReBar for managing the frame's rebar control.
+// * CMenuBar for managing the menu inside the rebar.
+// * CToolBar for managing the frame's toolbar.
+// * CStatusBar for managing the frame's status bar.
+// In each case these members are exposed by a GetXXX function, allowing
+// them to be accessed or sent messages.
+
+// CFrame is responsible for creating a "frame" window. This window has a
+// menu and and several child windows, including a toolbar (usualy hosted
+// within a rebar), a status bar, and a view positioned over the frame
+// window's non-client area. The "view" window is a seperate CWnd object
+// assigned to the frame with the SetView function.
+
+// When compiling an application with these classes, it will need to be linked
+// with Comctl32.lib.
+
+// To create a SDI frame application, inherit a CMainFrame class from CFrame.
+// Use the Frame sample application as the starting point for your own frame
+// applications.
+// Refer to the Notepad and Scribble samples for examples on how to use these
+// classes to create a frame application.
+
+
+#ifndef _WIN32XX_FRAME_H_
+#define _WIN32XX_FRAME_H_
+
+#include "wincore.h"
+#include "dialog.h"
+#include "gdi.h"
+#include "statusbar.h"
+#include "toolbar.h"
+#include "rebar.h"
+#include "default_resource.h"
+
+#ifndef RBN_MINMAX
+ #define RBN_MINMAX (RBN_FIRST - 21)
+#endif
+
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////////////////
+ // Declarations for structures for themes
+ //
+ struct MenuTheme
+ {
+ BOOL UseThemes; // TRUE if themes are used
+ COLORREF clrHot1; // Colour 1 for top menu. Color of selected menu item
+ COLORREF clrHot2; // Colour 2 for top menu. Color of checkbox
+ COLORREF clrPressed1; // Colour 1 for pressed top menu and side bar
+ COLORREF clrPressed2; // Colour 2 for pressed top menu and side bar
+ COLORREF clrOutline; // Colour for border outline
+ };
+
+
+ // Forward declaration of CFrame. Its defined later.
+ class CFrame;
+
+
+ ////////////////////////////////////
+ // Declaration of the CMenuBar class
+ //
+ class CMenuBar : public CToolBar
+ {
+ friend class CFrame;
+
+ public:
+ CMenuBar();
+ virtual ~CMenuBar();
+ virtual void SetMenu(HMENU hMenu);
+ virtual void SetMenuBarTheme(MenuTheme& Theme);
+
+ HMENU GetMenu() const {return m_hTopMenu;}
+ MenuTheme& GetMenuBarTheme() {return m_ThemeMenu;}
+
+ protected:
+ //Overridables
+ virtual void OnCreate();
+ virtual LRESULT OnCustomDraw(NMHDR* pNMHDR);
+ virtual void OnKeyDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam);
+ virtual void OnMenuChar(WPARAM wParam, LPARAM lParam);
+ virtual BOOL OnMenuInput(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseLeave();
+ virtual void OnMouseMove(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam);
+ virtual void OnSysCommand(WPARAM wParam, LPARAM lParam);
+ virtual void OnWindowPosChanged();
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CMenuBar(const CMenuBar&); // Disable copy construction
+ CMenuBar& operator = (const CMenuBar&); // Disable assignment operator
+ void DoAltKey(WORD KeyCode);
+ void DoPopupMenu();
+ void DrawAllMDIButtons(CDC& DrawDC);
+ void DrawMDIButton(CDC& DrawDC, int iButton, UINT uState);
+ void ExitMenu();
+ HWND GetActiveMDIChild();
+ void GrabFocus();
+ BOOL IsMDIChildMaxed() const;
+ BOOL IsMDIFrame() const;
+ void ReleaseFocus();
+ void SetHotItem(int nHot);
+ static LRESULT CALLBACK StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam);
+
+ enum MDIButtonType
+ {
+ MDI_MIN = 0,
+ MDI_RESTORE = 1,
+ MDI_CLOSE = 2,
+ };
+
+ BOOL m_bExitAfter; // Exit after Popup menu ends
+ BOOL m_bKeyMode; // keyboard navigation mode
+ BOOL m_bMenuActive; // popup menu active
+ BOOL m_bSelPopup; // a popup (cascade) menu is selected
+ HMENU m_hPopupMenu; // handle to the popup menu
+ HMENU m_hSelMenu; // handle to the casceded popup menu
+ HMENU m_hTopMenu; // handle to the top level menu
+ HWND m_hPrevFocus; // handle to window which had focus
+ CRect m_MDIRect[3]; // array of CRect for MDI buttons
+ int m_nHotItem; // hot item
+ int m_nMDIButton; // the MDI button (MDIButtonType) pressed
+ CPoint m_OldMousePos; // old Mouse position
+ MenuTheme m_ThemeMenu; // Theme structure
+ CFrame* m_pFrame; // Pointer to the frame
+
+ }; // class CMenuBar
+
+
+
+ //////////////////////////////////
+ // Declaration of the CFrame class
+ //
+ class CFrame : public CWnd
+ {
+ friend class CMenuBar;
+
+ struct ItemData
+ // Each Dropdown menu item has this data
+ {
+ HMENU hMenu;
+ UINT nPos;
+ UINT fType;
+ std::vector<TCHAR> vItemText;
+ HMENU hSubMenu;
+
+ ItemData() : hMenu(0), nPos(0), fType(0), hSubMenu(0) { vItemText.assign(MAX_MENU_STRING, _T('\0')); }
+ LPTSTR GetItemText() {return &vItemText[0];}
+ };
+
+ typedef Shared_Ptr<ItemData> ItemDataPtr;
+
+ public:
+ CFrame();
+ virtual ~CFrame();
+
+ // Override these functions as required
+ virtual void AdjustFrameRect(RECT rcView) const;
+ virtual CRect GetViewRect() const;
+ virtual BOOL IsMDIFrame() const { return FALSE; }
+ virtual void SetStatusIndicators();
+ virtual void SetStatusText();
+ virtual void RecalcLayout();
+ virtual MenuTheme& GetMenuTheme() const { return (MenuTheme&) m_ThemeMenu; }
+ virtual ReBarTheme& GetReBarTheme() const { return (ReBarTheme&)GetReBar().GetReBarTheme(); }
+ virtual ToolBarTheme& GetToolBarTheme() const { return (ToolBarTheme&)GetToolBar().GetToolBarTheme(); }
+
+ // Virtual Attributes
+ // If you need to modify the default behaviour of the menubar, rebar,
+ // statusbar or toolbar, inherit from those classes, and override
+ // the following attribute functions.
+ virtual CMenuBar& GetMenuBar() const { return (CMenuBar&)m_MenuBar; }
+ virtual CReBar& GetReBar() const { return (CReBar&)m_ReBar; }
+ virtual CStatusBar& GetStatusBar() const { return (CStatusBar&)m_StatusBar; }
+ virtual CToolBar& GetToolBar() const { return (CToolBar&)m_ToolBar; }
+
+ // These functions aren't virtual, and shouldn't be overridden
+ HACCEL GetFrameAccel() const { return m_hAccel; }
+ CMenu& GetFrameMenu() const { return (CMenu&)m_Menu; }
+ std::vector<tString> GetMRUEntries() const { return m_vMRUEntries; }
+ tString GetRegistryKeyName() const { return m_tsKeyName; }
+ CWnd* GetView() const { return m_pView; }
+ tString GetMRUEntry(UINT nIndex);
+ void SetFrameMenu(INT ID_MENU);
+ void SetFrameMenu(HMENU hMenu);
+ void SetMenuTheme(MenuTheme& Theme);
+ void SetView(CWnd& wndView);
+ BOOL IsMenuBarUsed() const { return (GetMenuBar() != 0); }
+ BOOL IsReBarSupported() const { return (GetComCtlVersion() >= 470); }
+ BOOL IsReBarUsed() const { return (GetReBar() != 0); }
+
+ protected:
+ // Override these functions as required
+ virtual BOOL AddMenuIcon(int nID_MenuItem, HICON hIcon, int cx = 16, int cy = 16);
+ virtual UINT AddMenuIcons(const std::vector<UINT>& MenuData, COLORREF crMask, UINT ToolBarID, UINT ToolBarDisabledID);
+ virtual void AddMenuBarBand();
+ virtual void AddMRUEntry(LPCTSTR szMRUEntry);
+ virtual void AddToolBarBand(CToolBar& TB, DWORD dwStyle, UINT nID);
+ virtual void AddToolBarButton(UINT nID, BOOL bEnabled = TRUE, LPCTSTR szText = 0);
+ virtual void CreateToolBar();
+ virtual void DrawCheckmark(LPDRAWITEMSTRUCT pdis, CDC& DrawDC);
+ virtual void DrawMenuIcon(LPDRAWITEMSTRUCT pdis, CDC& DrawDC, BOOL bDisabled);
+ virtual void DrawMenuText(CDC& DrawDC, LPCTSTR ItemText, CRect& rc, COLORREF colorText);
+ virtual int GetMenuItemPos(HMENU hMenu, LPCTSTR szItem);
+ virtual BOOL LoadRegistrySettings(LPCTSTR szKeyName);
+ virtual BOOL LoadRegistryMRUSettings(UINT nMaxMRU = 0);
+ virtual void OnActivate(WPARAM wParam, LPARAM lParam);
+ virtual void OnClose();
+ virtual void OnCreate();
+ virtual void OnDestroy();
+ virtual LRESULT OnDrawItem(WPARAM wParam, LPARAM lParam);
+ virtual void OnExitMenuLoop();
+ virtual void OnHelp();
+ virtual void OnInitMenuPopup(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnMeasureItem(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnMenuChar(WPARAM wParam, LPARAM lParam);
+ virtual void OnMenuSelect(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual void OnSetFocus();
+ virtual void OnSysColorChange();
+ virtual LRESULT OnSysCommand(WPARAM wParam, LPARAM lParam);
+ virtual void OnTimer(WPARAM wParam);
+ virtual void OnViewStatusBar();
+ virtual void OnViewToolBar();
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual void RemoveMRUEntry(LPCTSTR szMRUEntry);
+ virtual BOOL SaveRegistrySettings();
+ virtual void SetMenuBarBandSize();
+ virtual UINT SetMenuIcons(const std::vector<UINT>& MenuData, COLORREF crMask, UINT ToolBarID, UINT ToolBarDisabledID);
+ virtual void SetupToolBar();
+ virtual void SetTheme();
+ virtual void SetToolBarImages(COLORREF crMask, UINT ToolBarID, UINT ToolBarHotID, UINT ToolBarDisabledID);
+ virtual void ShowMenu(BOOL bShow);
+ virtual void ShowStatusBar(BOOL bShow);
+ virtual void ShowToolBar(BOOL bShow);
+ virtual void UpdateMRUMenu();
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ enum Constants
+ {
+ ID_STATUS_TIMER = 1,
+ POST_TEXT_GAP = 16, // for owner draw menu item
+ };
+
+ tString m_tsStatusText; // TCHAR std::string for status text
+ BOOL m_bShowIndicatorStatus; // set to TRUE to see indicators in status bar
+ BOOL m_bShowMenuStatus; // set to TRUE to see menu and toolbar updates in status bar
+ BOOL m_bUseReBar; // set to TRUE if ReBars are to be used
+ BOOL m_bUseThemes; // set to TRUE if themes are to be used
+ BOOL m_bUpdateTheme; // set to TRUE to run SetThemes when theme changes
+ BOOL m_bUseToolBar; // set to TRUE if the toolbar is used
+ BOOL m_bUseCustomDraw; // set to TRUE to perform custom drawing on menu items
+ BOOL m_bShowStatusBar; // A flag to indicate if the StatusBar should be displayed
+ BOOL m_bShowToolBar; // A flag to indicate if the ToolBar should be displayed
+ MenuTheme m_ThemeMenu; // Theme structure for popup menus
+ HIMAGELIST m_himlMenu; // Imagelist of menu icons
+ HIMAGELIST m_himlMenuDis; // Imagelist of disabled menu icons
+
+ private:
+ CFrame(const CFrame&); // Disable copy construction
+ CFrame& operator = (const CFrame&); // Disable assignment operator
+ void LoadCommonControls();
+
+ std::vector<ItemDataPtr> m_vMenuItemData;// vector of ItemData pointers
+ std::vector<UINT> m_vMenuIcons; // vector of menu icon resource IDs
+ std::vector<tString> m_vMRUEntries; // Vector of tStrings for MRU entires
+ CDialog m_AboutDialog; // Help about dialog
+ CMenuBar m_MenuBar; // CMenuBar object
+ CReBar m_ReBar; // CReBar object
+ CStatusBar m_StatusBar; // CStatusBar object
+ CToolBar m_ToolBar; // CToolBar object
+ CMenu m_Menu; // handle to the frame menu
+ HACCEL m_hAccel; // handle to the frame's accelerator table
+ CWnd* m_pView; // pointer to the View CWnd object
+ LPCTSTR m_OldStatus[3]; // Array of TCHAR pointers;
+ tString m_tsKeyName; // TCHAR std::string for Registry key name
+ tString m_tsTooltip; // TCHAR std::string for tool tips
+ UINT m_nMaxMRU; // maximum number of MRU entries
+ CRect m_rcPosition; // CRect of the starting window position
+ HWND m_hOldFocus; // The window which had focus prior to the app'a deactivation
+ int m_nOldID; // The previous ToolBar ID displayed in the statusbar
+
+ }; // class CFrame
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ /////////////////////////////////////
+ // Definitions for the CMenuBar class
+ //
+ inline CMenuBar::CMenuBar()
+ {
+ m_bExitAfter = FALSE;
+ m_hTopMenu = NULL;
+ m_nHotItem = -1;
+ m_bSelPopup = FALSE;
+ m_hSelMenu = NULL;
+ m_bMenuActive = FALSE;
+ m_bKeyMode = FALSE;
+ m_hPrevFocus = NULL;
+ m_nMDIButton = 0;
+ m_hPopupMenu = 0;
+
+ ZeroMemory(&m_ThemeMenu, sizeof(MenuTheme));
+ }
+
+ inline CMenuBar::~CMenuBar()
+ {
+ }
+
+ inline void CMenuBar::DoAltKey(WORD KeyCode)
+ {
+ //Handle key pressed with Alt held down
+ UINT ID;
+ if (SendMessage(TB_MAPACCELERATOR, KeyCode, (LPARAM) &ID))
+ {
+ GrabFocus();
+ m_bKeyMode = TRUE;
+ SetHotItem(ID);
+ m_bMenuActive = TRUE;
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ }
+ else
+ ::MessageBeep(MB_OK);
+ }
+
+ inline void CMenuBar::DoPopupMenu()
+ {
+ if (m_bKeyMode)
+ // Simulate a down arrow key press
+ PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
+
+ m_bKeyMode = FALSE;
+ m_bExitAfter = FALSE;
+ m_OldMousePos = GetCursorPos();
+
+ HWND hMaxMDIChild = NULL;
+ if (IsMDIChildMaxed())
+ hMaxMDIChild = GetActiveMDIChild();
+
+ // Load the submenu
+ int nMaxedOffset = IsMDIChildMaxed()? 1:0;
+ m_hPopupMenu = ::GetSubMenu(m_hTopMenu, m_nHotItem - nMaxedOffset);
+ if (IsMDIChildMaxed() && (0 == m_nHotItem) )
+ m_hPopupMenu = ::GetSystemMenu(hMaxMDIChild, FALSE);
+
+ // Retrieve the bounding rectangle for the toolbar button
+ CRect rc = GetItemRect(m_nHotItem);
+
+ // convert rectangle to desktop coordinates
+ ClientToScreen(rc);
+
+ // Position popup above toolbar if it won't fit below
+ TPMPARAMS tpm;
+ tpm.cbSize = sizeof(TPMPARAMS);
+ tpm.rcExclude = rc;
+
+ // Set the hot button
+ SendMessage(TB_SETHOTITEM, m_nHotItem, 0L);
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, MAKELONG(TRUE, 0));
+
+ m_bSelPopup = FALSE;
+ m_hSelMenu = NULL;
+ m_bMenuActive = TRUE;
+
+ // We hook mouse input to process mouse and keyboard input during
+ // the popup menu. Messages are sent to StaticMsgHook.
+
+ // Remove any remaining hook first
+ TLSData* pTLSData = (TLSData*)::TlsGetValue(GetApp()->GetTlsIndex());
+ pTLSData->pMenuBar = this;
+ if (pTLSData->hHook != NULL)
+ ::UnhookWindowsHookEx(pTLSData->hHook);
+
+ // Hook messages about to be processed by the shortcut menu
+ pTLSData->hHook = ::SetWindowsHookEx(WH_MSGFILTER, (HOOKPROC)StaticMsgHook, NULL, ::GetCurrentThreadId());
+
+ // Display the shortcut menu
+ BOOL bRightToLeft = FALSE;
+
+#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500)
+ bRightToLeft = ((GetAncestor()->GetWindowLongPtr(GWL_EXSTYLE)) & WS_EX_LAYOUTRTL);
+#endif
+
+ int xPos = bRightToLeft? rc.right : rc.left;
+ UINT nID = ::TrackPopupMenuEx(m_hPopupMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
+ xPos, rc.bottom, m_hWnd, &tpm);
+
+ // We get here once the TrackPopupMenuEx has ended
+ m_bMenuActive = FALSE;
+
+ // Remove the message hook
+ ::UnhookWindowsHookEx(pTLSData->hHook);
+ pTLSData->hHook = NULL;
+
+ // Process MDI Child system menu
+ if (IsMDIChildMaxed())
+ {
+ if (::GetSystemMenu(hMaxMDIChild, FALSE) == m_hPopupMenu )
+ {
+ if (nID)
+ ::SendMessage(hMaxMDIChild, WM_SYSCOMMAND, nID, 0L);
+ }
+ }
+
+ // Resestablish Focus
+ if (m_bKeyMode)
+ GrabFocus();
+ }
+
+ inline void CMenuBar::DrawAllMDIButtons(CDC& DrawDC)
+ {
+ if (!IsMDIFrame())
+ return;
+
+ if (IsMDIChildMaxed())
+ {
+ int cx = GetSystemMetrics(SM_CXSMICON);
+ int cy = GetSystemMetrics(SM_CYSMICON);
+ CRect rc = GetClientRect();
+ int gap = 4;
+ rc.right -= gap;
+
+ // Assign values to each element of the CRect array
+ for (int i = 0 ; i < 3 ; ++i)
+ {
+ int left = rc.right - (i+1)*cx - gap*(i+1);
+ int top = rc.bottom/2 - cy/2;
+ int right = rc.right - i*cx - gap*(i+1);
+ int bottom = rc.bottom/2 + cy/2;
+ ::SetRect(&m_MDIRect[2 - i], left, top, right, bottom);
+ }
+
+ // Hide the MDI button if it won't fit
+ for (int k = 0 ; k <= 2 ; ++k)
+ {
+
+ if (m_MDIRect[k].left < GetMaxSize().cx)
+ {
+ ::SetRectEmpty(&m_MDIRect[k]);
+ }
+ }
+
+ DrawMDIButton(DrawDC, MDI_MIN, 0);
+ DrawMDIButton(DrawDC, MDI_RESTORE, 0);
+ DrawMDIButton(DrawDC, MDI_CLOSE, 0);
+ }
+ }
+
+ inline void CMenuBar::DrawMDIButton(CDC& DrawDC, int iButton, UINT uState)
+ {
+ if (!IsRectEmpty(&m_MDIRect[iButton]))
+ {
+ switch (uState)
+ {
+ case 0:
+ {
+ // Draw a grey outline
+ DrawDC.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNFACE));
+ DrawDC.MoveTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].top);
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].top);
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ }
+ break;
+ case 1:
+ {
+ // Draw outline, white at top, black on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.MoveTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].top);
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ }
+
+ break;
+ case 2:
+ {
+ // Draw outline, black on top, white on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.MoveTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].bottom);
+ DrawDC.LineTo(m_MDIRect[iButton].right, m_MDIRect[iButton].top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].top);
+ DrawDC.LineTo(m_MDIRect[iButton].left, m_MDIRect[iButton].bottom);
+ }
+ break;
+ }
+
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+
+ switch (iButton)
+ {
+ case MDI_MIN:
+ // Manually Draw Minimise button
+ DrawDC.MoveTo(m_MDIRect[0].left + 4, m_MDIRect[0].bottom -4);
+ DrawDC.LineTo(m_MDIRect[0].right - 4, m_MDIRect[0].bottom - 4);
+
+ DrawDC.MoveTo(m_MDIRect[0].left + 4, m_MDIRect[0].bottom -5);
+ DrawDC.LineTo(m_MDIRect[0].right - 4, m_MDIRect[0].bottom - 5);
+ break;
+ case MDI_RESTORE:
+ // Manually Draw Restore Button
+ DrawDC.MoveTo(m_MDIRect[1].left + 3, m_MDIRect[1].top + 7);
+ DrawDC.LineTo(m_MDIRect[1].left + 3, m_MDIRect[1].bottom -4);
+ DrawDC.LineTo(m_MDIRect[1].right - 6, m_MDIRect[1].bottom -4);
+ DrawDC.LineTo(m_MDIRect[1].right - 6, m_MDIRect[1].top + 7);
+ DrawDC.LineTo(m_MDIRect[1].left + 3, m_MDIRect[1].top + 7);
+
+ DrawDC.MoveTo(m_MDIRect[1].left + 3, m_MDIRect[1].top + 8);
+ DrawDC.LineTo(m_MDIRect[1].right - 6, m_MDIRect[1].top + 8);
+
+ DrawDC.MoveTo(m_MDIRect[1].left + 5, m_MDIRect[1].top + 7);
+ DrawDC.LineTo(m_MDIRect[1].left + 5, m_MDIRect[1].top + 4);
+ DrawDC.LineTo(m_MDIRect[1].right - 4, m_MDIRect[1].top + 4);
+ DrawDC.LineTo(m_MDIRect[1].right - 4, m_MDIRect[1].bottom -6);
+ DrawDC.LineTo(m_MDIRect[1].right - 6, m_MDIRect[1].bottom -6);
+
+ DrawDC.MoveTo(m_MDIRect[1].left + 5, m_MDIRect[1].top + 5);
+ DrawDC.LineTo(m_MDIRect[1].right - 4, m_MDIRect[1].top + 5);
+ break;
+ case MDI_CLOSE:
+ // Manually Draw Close Button
+ DrawDC.MoveTo(m_MDIRect[2].left + 4, m_MDIRect[2].top +5);
+ DrawDC.LineTo(m_MDIRect[2].right - 4, m_MDIRect[2].bottom -3);
+
+ DrawDC.MoveTo(m_MDIRect[2].left + 5, m_MDIRect[2].top +5);
+ DrawDC.LineTo(m_MDIRect[2].right - 4, m_MDIRect[2].bottom -4);
+
+ DrawDC.MoveTo(m_MDIRect[2].left + 4, m_MDIRect[2].top +6);
+ DrawDC.LineTo(m_MDIRect[2].right - 5, m_MDIRect[2].bottom -3);
+
+ DrawDC.MoveTo(m_MDIRect[2].right -5, m_MDIRect[2].top +5);
+ DrawDC.LineTo(m_MDIRect[2].left + 3, m_MDIRect[2].bottom -3);
+
+ DrawDC.MoveTo(m_MDIRect[2].right -5, m_MDIRect[2].top +6);
+ DrawDC.LineTo(m_MDIRect[2].left + 4, m_MDIRect[2].bottom -3);
+
+ DrawDC.MoveTo(m_MDIRect[2].right -6, m_MDIRect[2].top +5);
+ DrawDC.LineTo(m_MDIRect[2].left + 3, m_MDIRect[2].bottom -4);
+ break;
+ }
+ }
+ }
+
+ inline void CMenuBar::ExitMenu()
+ {
+ ReleaseFocus();
+ m_bKeyMode = FALSE;
+ m_bMenuActive = FALSE;
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, (LPARAM) MAKELONG (FALSE, 0));
+ SetHotItem(-1);
+
+ CPoint pt = GetCursorPos();
+ ScreenToClient(pt);
+
+ // Update mouse mouse position for hot tracking
+ SendMessage(WM_MOUSEMOVE, 0L, MAKELONG(pt.x, pt.y));
+ }
+
+ inline HWND CMenuBar::GetActiveMDIChild()
+ {
+ HWND hwndMDIChild = NULL;
+ if (IsMDIFrame())
+ {
+ hwndMDIChild = (HWND)::SendMessage(m_pFrame->GetView()->GetHwnd(), WM_MDIGETACTIVE, 0L, 0L);
+ }
+
+ return hwndMDIChild;
+ }
+
+ inline void CMenuBar::GrabFocus()
+ {
+ if (::GetFocus() != m_hWnd)
+ m_hPrevFocus = ::SetFocus(m_hWnd);
+ ::SetCapture(m_hWnd);
+ ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
+ }
+
+ inline BOOL CMenuBar::IsMDIChildMaxed() const
+ {
+ BOOL bMaxed = FALSE;
+
+ if (IsMDIFrame() && m_pFrame->GetView()->IsWindow())
+ {
+ m_pFrame->GetView()->SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMaxed);
+ }
+
+ return bMaxed;
+ }
+
+ inline BOOL CMenuBar::IsMDIFrame() const
+ {
+ return (m_pFrame->IsMDIFrame());
+ }
+
+ inline void CMenuBar::OnMenuChar(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(lParam);
+
+ if (!m_bMenuActive)
+ DoAltKey(LOWORD(wParam));
+ }
+
+ inline void CMenuBar::OnCreate()
+ {
+ // We must send this message before sending the TB_ADDBITMAP or TB_ADDBUTTONS message
+ SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0L);
+
+ m_pFrame = (CFrame*)GetAncestor();
+ assert(m_pFrame);
+ }
+
+ inline LRESULT CMenuBar::OnCustomDraw(NMHDR* pNMHDR)
+ // CustomDraw is used to render the MenuBar's toolbar buttons
+ {
+ if (m_ThemeMenu.UseThemes)
+ {
+ LPNMTBCUSTOMDRAW lpNMCustomDraw = (LPNMTBCUSTOMDRAW)pNMHDR;
+
+ switch (lpNMCustomDraw->nmcd.dwDrawStage)
+ {
+ // Begin paint cycle
+ case CDDS_PREPAINT:
+ // Send NM_CUSTOMDRAW item draw, and post-paint notification messages.
+ return CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT ;
+
+ // An item is about to be drawn
+ case CDDS_ITEMPREPAINT:
+ {
+ CDC* pDrawDC = FromHandle(lpNMCustomDraw->nmcd.hdc);
+ CRect rcRect = lpNMCustomDraw->nmcd.rc;
+ int nState = lpNMCustomDraw->nmcd.uItemState;
+ DWORD dwItem = (DWORD)lpNMCustomDraw->nmcd.dwItemSpec;
+
+ // Leave a pixel gap above and below the drawn rectangle
+ if (IsAeroThemed())
+ rcRect.InflateRect(0, -2);
+ else
+ rcRect.InflateRect(0, -1);
+
+ if (IsMDIChildMaxed() && (0 == dwItem))
+ // Draw over MDI Max button
+ {
+ HICON hIcon = (HICON)::SendMessage(GetActiveMDIChild(), WM_GETICON, ICON_SMALL, 0L);
+ if (NULL == hIcon)
+ hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
+
+ int cx = ::GetSystemMetrics (SM_CXSMICON);
+ int cy = ::GetSystemMetrics (SM_CYSMICON);
+ int y = 1 + (GetWindowRect().Height() - cy)/2;
+ int x = (rcRect.Width() - cx)/2;
+ pDrawDC->DrawIconEx(x, y, hIcon, cx, cy, 0, NULL, DI_NORMAL);
+
+ pDrawDC->Detach(); // Optional, deletes GDI objects sooner
+ return CDRF_SKIPDEFAULT; // No further drawing
+ }
+
+ else if (nState & (CDIS_HOT | CDIS_SELECTED))
+ {
+ if ((nState & CDIS_SELECTED) || (GetButtonState(dwItem) & TBSTATE_PRESSED))
+ {
+ pDrawDC->GradientFill(m_ThemeMenu.clrPressed1, m_ThemeMenu.clrPressed2, rcRect, FALSE);
+ }
+ else if (nState & CDIS_HOT)
+ {
+ pDrawDC->GradientFill(m_ThemeMenu.clrHot1, m_ThemeMenu.clrHot2, rcRect, FALSE);
+ }
+
+ // Draw border
+ pDrawDC->CreatePen(PS_SOLID, 1, m_ThemeMenu.clrOutline);
+ pDrawDC->MoveTo(rcRect.left, rcRect.bottom);
+ pDrawDC->LineTo(rcRect.left, rcRect.top);
+ pDrawDC->LineTo(rcRect.right-1, rcRect.top);
+ pDrawDC->LineTo(rcRect.right-1, rcRect.bottom);
+ pDrawDC->MoveTo(rcRect.right-1, rcRect.bottom);
+ pDrawDC->LineTo(rcRect.left, rcRect.bottom);
+
+ TCHAR str[80] = _T("");
+ int nLength = (int)SendMessage(TB_GETBUTTONTEXT, lpNMCustomDraw->nmcd.dwItemSpec, 0L);
+ if ((nLength > 0) && (nLength < 80))
+ SendMessage(TB_GETBUTTONTEXT, lpNMCustomDraw->nmcd.dwItemSpec, (LPARAM)str);
+
+ // Draw highlight text
+ pDrawDC->SelectObject(GetFont());
+ rcRect.bottom += 1;
+ int iMode = pDrawDC->SetBkMode(TRANSPARENT);
+ pDrawDC->DrawText(str, lstrlen(str), rcRect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
+
+ pDrawDC->SetBkMode(iMode);
+ pDrawDC->Detach(); // Optional, deletes GDI objects sooner
+ return CDRF_SKIPDEFAULT; // No further drawing
+ }
+ }
+ return CDRF_DODEFAULT ; // Do default drawing
+
+ // Painting cycle has completed
+ case CDDS_POSTPAINT:
+ // Draw MDI Minimise, Restore and Close buttons
+ {
+ CDC* pDrawDC = FromHandle(lpNMCustomDraw->nmcd.hdc);
+ DrawAllMDIButtons(*pDrawDC);
+ pDrawDC->Detach(); // Optional, deletes GDI objects sooner
+ }
+ break;
+ }
+ }
+ return 0L;
+ }
+
+ inline void CMenuBar::OnKeyDown(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(lParam);
+
+ switch (wParam)
+ {
+ case VK_ESCAPE:
+ ExitMenu();
+ break;
+
+ case VK_SPACE:
+ ExitMenu();
+ // Bring up the system menu
+ GetAncestor()->PostMessage(WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE);
+ break;
+
+ // Handle VK_DOWN,VK_UP and VK_RETURN together
+ case VK_DOWN:
+ case VK_UP:
+ case VK_RETURN:
+ // Always use PostMessage for USER_POPUPMENU (not SendMessage)
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ break;
+
+ case VK_LEFT:
+ // Move left to next topmenu item
+ (m_nHotItem > 0)? SetHotItem(m_nHotItem -1) : SetHotItem(GetButtonCount()-1);
+ break;
+
+ case VK_RIGHT:
+ // Move right to next topmenu item
+ (m_nHotItem < GetButtonCount() -1)? SetHotItem(m_nHotItem +1) : SetHotItem(0);
+ break;
+
+ default:
+ // Handle Accelerator keys with Alt toggled down
+ if (m_bKeyMode)
+ {
+ UINT ID;
+ if (SendMessage(TB_MAPACCELERATOR, wParam, (LPARAM) &ID))
+ {
+ m_nHotItem = ID;
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ }
+ else
+ ::MessageBeep(MB_OK);
+ }
+ break;
+ } // switch (wParam)
+ }
+
+ inline void CMenuBar::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ GrabFocus();
+ m_nMDIButton = 0;
+ CPoint pt;
+
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ if (IsMDIFrame())
+ {
+ if (IsMDIChildMaxed())
+ {
+ CClientDC MenuBarDC(this);
+ m_nMDIButton = -1;
+
+ if (m_MDIRect[0].PtInRect(pt)) m_nMDIButton = 0;
+ if (m_MDIRect[1].PtInRect(pt)) m_nMDIButton = 1;
+ if (m_MDIRect[2].PtInRect(pt)) m_nMDIButton = 2;
+
+ if (m_nMDIButton >= 0)
+ {
+ DrawMDIButton(MenuBarDC, MDI_MIN, (0 == m_nMDIButton)? 2 : 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, (1 == m_nMDIButton)? 2 : 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, (2 == m_nMDIButton)? 2 : 0);
+ }
+
+ // Bring up the MDI Child window's system menu when the icon is pressed
+ if (0 == HitTest())
+ {
+ m_nHotItem = 0;
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ }
+ }
+ }
+ }
+
+ inline void CMenuBar::OnLButtonUp(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ CPoint pt;
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ if (IsMDIFrame())
+ {
+ HWND MDIClient = m_pFrame->GetView()->GetHwnd();
+ HWND MDIChild = GetActiveMDIChild();
+
+ if (IsMDIChildMaxed())
+ {
+ CPoint pt = GetCursorPos();
+ ScreenToClient(pt);
+
+ // Process the MDI button action when the left mouse button is up
+ if (m_MDIRect[0].PtInRect(pt))
+ {
+ if (MDI_MIN == m_nMDIButton)
+ ::ShowWindow(MDIChild, SW_MINIMIZE);
+ }
+
+ if (m_MDIRect[1].PtInRect(pt))
+ {
+ if (MDI_RESTORE == m_nMDIButton)
+ ::PostMessage(MDIClient, WM_MDIRESTORE, (WPARAM)MDIChild, 0L);
+ }
+
+ if (m_MDIRect[2].PtInRect(pt))
+ {
+ if (MDI_CLOSE == m_nMDIButton)
+ ::PostMessage(MDIChild, WM_CLOSE, 0L, 0L);
+ }
+ }
+ }
+ m_nMDIButton = 0;
+ ExitMenu();
+ }
+
+ inline BOOL CMenuBar::OnMenuInput(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // When a popup menu is active, StaticMsgHook directs all menu messages here
+ {
+ switch(uMsg)
+ {
+ case WM_KEYDOWN:
+ m_bExitAfter = FALSE;
+ {
+ switch (wParam)
+ {
+ case VK_ESCAPE:
+ // Use default processing if inside a Sub Menu
+ if ((m_hSelMenu) &&(m_hSelMenu != m_hPopupMenu))
+ return FALSE;
+
+ m_bMenuActive = FALSE;
+ m_bKeyMode = TRUE;
+ SendMessage(WM_CANCELMODE, 0L, 0L);
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, MAKELONG(FALSE, 0));
+ SendMessage(TB_SETHOTITEM, m_nHotItem, 0L);
+ break;
+
+ case VK_LEFT:
+ // Use default processing if inside a Sub Menu
+ if ((m_hSelMenu) &&(m_hSelMenu != m_hPopupMenu))
+ return FALSE;
+
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, MAKELONG(FALSE, 0));
+
+ // Move left to next topmenu item
+ (m_nHotItem > 0)? --m_nHotItem : m_nHotItem = GetButtonCount()-1;
+ SendMessage(WM_CANCELMODE, 0L, 0L);
+
+ // Always use PostMessage for USER_POPUPMENU (not SendMessage)
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
+ break;
+
+ case VK_RIGHT:
+ // Use default processing to open Sub Menu
+ if (m_bSelPopup)
+ return FALSE;
+
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, MAKELONG(FALSE, 0));
+
+ // Move right to next topmenu item
+ (m_nHotItem < GetButtonCount()-1)? ++m_nHotItem : m_nHotItem = 0;
+ SendMessage(WM_CANCELMODE, 0L, 0L);
+
+ // Always use PostMessage for USER_POPUPMENU (not SendMessage)
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
+ break;
+
+ case VK_RETURN:
+ m_bExitAfter = TRUE;
+ break;
+
+ } // switch (wParam)
+
+ } // case WM_KEYDOWN
+
+ return FALSE;
+
+ case WM_CHAR:
+ m_bExitAfter = TRUE;
+ return FALSE;
+
+ case WM_LBUTTONDOWN:
+ {
+ m_bExitAfter = TRUE;
+ if (HitTest() >= 0)
+ {
+ // Cancel popup when we hit a button a second time
+ SendMessage(WM_CANCELMODE, 0L, 0L);
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case WM_LBUTTONDBLCLK:
+ // Perform default action for DblClick on MDI Maxed icon
+ if (IsMDIChildMaxed() && (0 == HitTest()))
+ {
+ CWnd* pMDIChild = FromHandle(GetActiveMDIChild());
+ CMenu* pChildMenu = pMDIChild->GetSystemMenu(FALSE);
+
+ UINT nID = pChildMenu->GetDefaultItem(FALSE, 0);
+ if (nID)
+ pMDIChild->PostMessage(WM_SYSCOMMAND, nID, 0L);
+ }
+
+ m_bExitAfter = TRUE;
+ return FALSE;
+
+ case WM_MENUSELECT:
+ {
+ // store info about selected item
+ m_hSelMenu = (HMENU)lParam;
+ m_bSelPopup = ((HIWORD(wParam) & MF_POPUP) != 0);
+
+ // Reflect message back to the frame window
+ GetAncestor()->SendMessage(WM_MENUSELECT, wParam, lParam);
+ }
+ return TRUE;
+
+ case WM_MOUSEMOVE:
+ {
+ CPoint pt;
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ // Skip if mouse hasn't moved
+ if ((pt.x == m_OldMousePos.x) && (pt.y == m_OldMousePos.y))
+ return FALSE;
+
+ m_OldMousePos.x = pt.x;
+ m_OldMousePos.y = pt.y;
+ ScreenToClient(pt);
+
+ // Reflect messages back to the MenuBar for hot tracking
+ SendMessage(WM_MOUSEMOVE, 0L, MAKELPARAM(pt.x, pt.y));
+ }
+ break;
+
+ }
+ return FALSE;
+ }
+
+ inline void CMenuBar::OnMouseLeave()
+ {
+ if (IsMDIFrame())
+ {
+ if (IsMDIChildMaxed())
+ {
+ CClientDC MenuBarDC(this);
+
+ DrawMDIButton(MenuBarDC, MDI_MIN, 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, 0);
+ }
+ }
+ }
+
+ inline void CMenuBar::OnMouseMove(WPARAM wParam, LPARAM lParam)
+ {
+ CPoint pt;
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ if (IsMDIFrame())
+ {
+ if (IsMDIChildMaxed())
+ {
+ CClientDC MenuBarDC(this);
+ int MDIButton = -1;
+ if (m_MDIRect[0].PtInRect(pt)) MDIButton = 0;
+ if (m_MDIRect[1].PtInRect(pt)) MDIButton = 1;
+ if (m_MDIRect[2].PtInRect(pt)) MDIButton = 2;
+
+ if (MK_LBUTTON == wParam) // mouse moved with left mouse button is held down
+ {
+ // toggle the MDI button image pressed/unpressed as required
+ if (MDIButton >= 0)
+ {
+ DrawMDIButton(MenuBarDC, MDI_MIN, ((0 == MDIButton) && (0 == m_nMDIButton))? 2 : 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, ((1 == MDIButton) && (1 == m_nMDIButton))? 2 : 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, ((2 == MDIButton) && (2 == m_nMDIButton))? 2 : 0);
+ }
+ else
+ {
+ DrawMDIButton(MenuBarDC, MDI_MIN, 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, 0);
+ }
+ }
+ else // mouse moved without left mouse button held down</