summaryrefslogtreecommitdiffstats
path: root/mmc_updater/depends/win32cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-12-02 00:55:24 +0100
committerPetr Mrázek <peterix@gmail.com>2013-12-02 00:55:24 +0100
commit6aa9bd0f77dcb5128167fae62e32aa5252fe85c6 (patch)
tree632994a61888929af9289927d338bd19a2b3f32c /mmc_updater/depends/win32cpp
parent613699b3626aea750093ab7eaaeccaa28c0e87c6 (diff)
downloadMultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.gz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.lz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.xz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.zip
Renew the updater branch
Now with some actual consensus on what the updater will do!
Diffstat (limited to 'mmc_updater/depends/win32cpp')
-rw-r--r--mmc_updater/depends/win32cpp/controls.h1074
-rw-r--r--mmc_updater/depends/win32cpp/copyright.txt33
-rw-r--r--mmc_updater/depends/win32cpp/cstring.h905
-rw-r--r--mmc_updater/depends/win32cpp/default_resource.h94
-rw-r--r--mmc_updater/depends/win32cpp/default_resource.rc250
-rw-r--r--mmc_updater/depends/win32cpp/dialog.h876
-rw-r--r--mmc_updater/depends/win32cpp/docking.h4214
-rw-r--r--mmc_updater/depends/win32cpp/file.h392
-rw-r--r--mmc_updater/depends/win32cpp/frame.h3303
-rw-r--r--mmc_updater/depends/win32cpp/gdi.h3944
-rw-r--r--mmc_updater/depends/win32cpp/info.txt205
-rw-r--r--mmc_updater/depends/win32cpp/listview.h867
-rw-r--r--mmc_updater/depends/win32cpp/mdi.h783
-rw-r--r--mmc_updater/depends/win32cpp/menu.h600
-rw-r--r--mmc_updater/depends/win32cpp/propertysheet.h960
-rw-r--r--mmc_updater/depends/win32cpp/rebar.h709
-rw-r--r--mmc_updater/depends/win32cpp/release notes.txt116
-rw-r--r--mmc_updater/depends/win32cpp/ribbon.h527
-rw-r--r--mmc_updater/depends/win32cpp/shared_ptr.h199
-rw-r--r--mmc_updater/depends/win32cpp/socket.h778
-rw-r--r--mmc_updater/depends/win32cpp/statusbar.h226
-rw-r--r--mmc_updater/depends/win32cpp/stdcontrols.h1000
-rw-r--r--mmc_updater/depends/win32cpp/tab.h1658
-rw-r--r--mmc_updater/depends/win32cpp/taskdialog.h811
-rw-r--r--mmc_updater/depends/win32cpp/thread.h241
-rw-r--r--mmc_updater/depends/win32cpp/toolbar.h1361
-rw-r--r--mmc_updater/depends/win32cpp/treeview.h624
-rw-r--r--mmc_updater/depends/win32cpp/wceframe.h420
-rw-r--r--mmc_updater/depends/win32cpp/wcestddef.h58
-rw-r--r--mmc_updater/depends/win32cpp/webbrowser.h760
-rw-r--r--mmc_updater/depends/win32cpp/wincore.h2977
-rw-r--r--mmc_updater/depends/win32cpp/winutils.h649
32 files changed, 31614 insertions, 0 deletions
diff --git a/mmc_updater/depends/win32cpp/controls.h b/mmc_updater/depends/win32cpp/controls.h
new file mode 100644
index 00000000..a15c8b5f
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/controls.h
@@ -0,0 +1,1074 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// controls.h
+// Declaration of the following classes:
+// CAnimation, CComboBox, CComboBoxEx, CProgressBar,
+// CScrollBar, CSlider, CSpinButton
+
+
+#ifndef _WIN32XX_CONTROLS_H_
+#define _WIN32XX_CONTROLS_H_
+
+#include "wincore.h"
+
+namespace Win32xx
+{
+ class CAnimation : public CWnd
+ {
+ public:
+ CAnimation() {}
+ virtual ~CAnimation() {}
+
+ BOOL Close() const;
+ BOOL Open(LPTSTR lpszName) const;
+ BOOL Play(UINT wFrom, UINT wTo, UINT cRepeat) const;
+ BOOL Seek(UINT wFrame) const;
+ BOOL Stop() const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = ANIMATE_CLASS; }
+ };
+
+
+ class CComboBox : public CWnd
+ {
+ public:
+ CComboBox() {}
+ virtual ~CComboBox() {}
+
+ int AddString(LPCTSTR lpszString) const;
+ void Clear() const;
+ void Copy() const;
+ void Cut() const;
+ int DeleteString(int nIndex) const;
+ int Dir(UINT attr, LPCTSTR lpszWildCard ) const;
+ int FindString(int nIndexStart, LPCTSTR lpszString) const;
+ int FindStringExact(int nIndexStart, LPCTSTR lpszString) const;
+ int GetCount() const;
+ int GetCurSel() const;
+ CRect GetDroppedControlRect() const;
+ BOOL GetDroppedState() const;
+ int GetDroppedWidth() const;
+ DWORD GetEditSel() const;
+ BOOL GetExtendedUI() const;
+ int GetHorizontalExtent() const;
+ DWORD GetItemData(int nIndex) const;
+ int GetItemHeight(int nIndex) const;
+ int GetLBText(int nIndex, LPTSTR lpszText) const;
+ int GetLBTextLen(int nIndex) const;
+ LCID GetLocale() const;
+ int GetTopIndex() const;
+ int InitStorage(int nItems, int nBytes) const;
+ int InsertString(int nIndex, LPCTSTR lpszString) const;
+ void LimitText(int nMaxChars) const;
+ void Paste() const;
+ void ResetContent() const;
+ int SelectString(int nStartAfter, LPCTSTR lpszString) const;
+ int SetCurSel(int nIndex) const;
+ int SetDroppedWidth(int nWidth) const;
+ BOOL SetEditSel(int nStartChar, int nEndChar) const;
+ int SetExtendedUI(BOOL bExtended = TRUE) const;
+ void SetHorizontalExtent(UINT nExtent ) const;
+ int SetItemData(int nIndex, DWORD dwItemData) const;
+ int SetItemHeight(int nIndex, UINT cyItemHeight) const;
+ LCID SetLocale( LCID NewLocale ) const;
+ int SetTopIndex(int nIndex) const;
+ void ShowDropDown(BOOL bShow = TRUE) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = _T("ComboBox"); }
+ };
+
+
+ class CComboBoxEx : public CWnd
+ {
+ public:
+ CComboBoxEx() {}
+ virtual ~CComboBoxEx() {}
+
+ int DeleteItem(int nIndex ) const;
+ CWnd* GetComboBoxCtrl() const;
+ CWnd* GetEditCtrl() const;
+ DWORD GetExtendedStyle() const;
+ HIMAGELIST GetImageList() const;
+ BOOL GetItem(COMBOBOXEXITEM* pCBItem) const;
+ BOOL HasEditChanged () const;
+ int InsertItem(COMBOBOXEXITEM* lpcCBItem) const;
+ DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyles ) const;
+ HIMAGELIST SetImageList(HIMAGELIST himl) const;
+ BOOL SetItem(PCOMBOBOXEXITEM lpcCBItem) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = WC_COMBOBOXEX; }
+ };
+
+
+ class CProgressBar : public CWnd
+ {
+ public:
+ CProgressBar() {}
+ virtual ~CProgressBar() {}
+
+ int GetPos() const;
+ int GetRange(BOOL fWhichLimit, PPBRANGE ppBRange) const;
+ int OffsetPos(int nIncrement) const;
+ int SetPos(int nNewPos) const;
+ int SetRange(short nMinRange, short nMaxRange) const;
+ int SetStep(int nStepInc) const;
+ int StepIt() const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = PROGRESS_CLASS; }
+ };
+
+
+ class CScrollBar : public CWnd
+ {
+ public:
+ CScrollBar() {}
+ virtual ~CScrollBar() {}
+
+ BOOL EnableScrollBar( UINT nArrowFlags = ESB_ENABLE_BOTH ) const;
+ BOOL GetScrollInfo(LPSCROLLINFO lpsi) const;
+ int GetScrollPos() const;
+ BOOL GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos ) const;
+ BOOL SetScrollInfo(LPSCROLLINFO lpsi, BOOL bRedraw = TRUE ) const;
+ int SetScrollPos(int nPos, BOOL bRedraw) const;
+ BOOL SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw = TRUE ) const;
+ BOOL ShowScrollBar(BOOL bShow) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = _T("SCROLLBAR"); ; }
+ };
+
+
+ class CSlider : public CWnd
+ {
+ public:
+ CSlider() {}
+ virtual ~CSlider() {}
+
+ void ClearSel() const;
+ void ClearTics(BOOL bRedraw = FALSE ) const;
+ CWnd* GetBuddy(BOOL fLocation = TRUE ) const;
+ CRect GetChannelRect() const;
+ int GetLineSize() const;
+ int GetNumTics() const;
+ int GetPageSize() const;
+ int GetPos() const;
+ int GetRangeMax() const;
+ int GetRangeMin() const;
+ int GetSelEnd() const;
+ int GetSelStart() const;
+ int GetThumbLength() const;
+ CRect GetThumbRect() const;
+ int GetTic(int nTic ) const;
+ int GetTicPos(int nTic) const;
+ CWnd* GetToolTips() const;
+ CWnd* SetBuddy(CWnd* pBuddy, BOOL fLocation = TRUE ) const;
+ int SetLineSize(int nSize) const;
+ int SetPageSize(int nSize) const;
+ void SetPos(int nPos, BOOL bRedraw = FALSE) const;
+ void SetRangeMax(int nMax, BOOL bRedraw = FALSE) const;
+ void SetRangeMin(int nMax, BOOL bRedraw = FALSE) const;
+ void SetSelection(int nMin, int nMax, BOOL bRedraw = FALSE) const;
+ BOOL SetTic(int nTic) const;
+ void SetTicFreq(int nFreq) const;
+ int SetTipSide(int nLocation) const;
+ void SetToolTips(CWnd* pToolTip) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc) { wc.lpszClassName = TRACKBAR_CLASS; }
+ };
+
+
+ // Also known as an Up/Down control
+ class CSpinButton : public CWnd
+ {
+ public:
+ CSpinButton() {}
+ virtual ~CSpinButton() {}
+
+ int GetAccel(int cAccels, LPUDACCEL paAccels) const;
+ int GetBase() const;
+ CWnd* GetBuddy() const;
+ int GetPos() const;
+ DWORD GetRange() const;
+ BOOL SetAccel(int cAccels, LPUDACCEL paAccels) const;
+ int SetBase(int nBase) const;
+ CWnd* SetBuddy(CWnd* hwndBuddy) const;
+ int SetPos(int nPos) const;
+ void SetRange(int nLower, int nUpper) const;
+
+ protected:
+ // Overridables
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ };
+
+} // namespace Win32xx
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////////
+ // Definitions for the CAnimation class
+ //
+ inline BOOL CAnimation::Close() const
+ // Closes an AVI clip.
+ {
+ assert(IsWindow());
+ return Animate_Close(m_hWnd);
+ }
+
+ inline BOOL CAnimation::Open(LPTSTR lpszName) const
+ // Opens an AVI clip and displays its first frame in an animation control.
+ {
+ assert(IsWindow());
+ return Animate_Open(m_hWnd, lpszName);
+ }
+
+ inline BOOL CAnimation::Play(UINT wFrom, UINT wTo, UINT cRepeat) const
+ // Plays an AVI clip in an animation control. The control plays the clip
+ // in the background while the thread continues executing.
+ {
+ assert(IsWindow());
+ return Animate_Play(m_hWnd, wFrom, wTo, cRepeat);
+ }
+
+ inline BOOL CAnimation::Seek(UINT wFrame) const
+ // Directs an animation control to display a particular frame of an AVI clip.
+ // The control displays the clip in the background while the thread continues executing.
+ {
+ assert(IsWindow());
+ return Animate_Seek(m_hWnd, wFrame);
+ }
+
+ inline BOOL CAnimation::Stop() const
+ // Stops playing an AVI clip in an animation control.
+ {
+ assert(IsWindow());
+ return Animate_Stop(m_hWnd);
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CComboBox class
+ //
+ inline int CComboBox::AddString(LPCTSTR lpszString) const
+ // Adds a string to the list box of a combo box. If the combo box does not
+ // have the CBS_SORT style, the string is added to the end of the list.
+ // Otherwise, the string is inserted into the list, and the list is sorted.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_ADDSTRING, 0, (LPARAM)lpszString);
+ }
+
+ inline void CComboBox::Clear() const
+ // Deletes the current selection, if any, from the combo box's edit control.
+ {
+ assert(IsWindow());
+ SendMessage(WM_CLEAR, 0, 0);
+ }
+
+ inline void CComboBox::Copy() const
+ // Copies the current selection to the clipboard in CF_TEXT format.
+ {
+ assert(IsWindow());
+ SendMessage(WM_COPY, 0, 0);
+ }
+
+ inline void CComboBox::Cut() const
+ // Deletes the current selection, if any, in the edit control and copies
+ // the deleted text to the clipboard in CF_TEXT format.
+ {
+ assert(IsWindow());
+ SendMessage(WM_CUT, 0, 0);
+ }
+
+ inline int CComboBox::DeleteString(int nIndex) const
+ // Deletes a string in the list box of a combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_DELETESTRING, (WPARAM)nIndex, 0);
+ }
+
+ inline int CComboBox::Dir(UINT attr, LPCTSTR lpszWildCard ) const
+ // Adds the names of directories and files that match a specified string
+ // and set of file attributes.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_DIR, (WPARAM)attr, (LPARAM)lpszWildCard);
+ }
+
+ inline int CComboBox::FindString(int nIndexStart, LPCTSTR lpszString) const
+ // Search the list box of a combo box for an item beginning with the
+ // characters in a specified string.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_FINDSTRING, (WPARAM)nIndexStart, (LPARAM)lpszString);
+ }
+
+ inline int CComboBox::FindStringExact(int nIndexStart, LPCTSTR lpszString) const
+ // Find the first list box string in a combo box that matches the string specified in lpszString.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_FINDSTRINGEXACT, (WPARAM)nIndexStart, (LPARAM)lpszString);
+ }
+
+ inline int CComboBox::GetCount() const
+ // Retrieves the number of items in the list box of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETCOUNT, 0,0);
+ }
+
+ inline int CComboBox::GetCurSel() const
+ // Retrieves the index of the currently selected item, if any, in the list box of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETCURSEL, 0,0);
+ }
+
+ inline CRect CComboBox::GetDroppedControlRect() const
+ // Retrieves the screen coordinates of the combo box in its dropped-down state.
+ {
+ assert(IsWindow());
+ CRect rc;
+ SendMessage(CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline BOOL CComboBox::GetDroppedState() const
+ // Determines whether the list box of the combo box is dropped down.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CB_GETDROPPEDSTATE, 0, 0);
+ }
+
+ inline int CComboBox::GetDroppedWidth() const
+ // Retrieves the minimum allowable width, in pixels, of the list box of the combo box
+ // with the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETDROPPEDWIDTH, 0, 0);
+ }
+
+ inline DWORD CComboBox::GetEditSel() const
+ // Gets the starting and ending character positions of the current selection
+ // in the edit control of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETEDITSEL, 0, 0);
+ }
+
+ inline BOOL CComboBox::GetExtendedUI() const
+ // Determines whether the combo box has the default user interface or the extended user interface.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CB_GETEXTENDEDUI, 0, 0);
+ }
+
+ inline int CComboBox::GetHorizontalExtent() const
+ // Retrieve from the combo box the width, in pixels, by which the list box can
+ // be scrolled horizontally (the scrollable width).
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETHORIZONTALEXTENT, 0, 0);
+ }
+
+ inline DWORD CComboBox::GetItemData(int nIndex) const
+ // Retrieves the application-supplied value associated with the specified item in the combo box.
+ {
+ assert(IsWindow());
+ return (DWORD)SendMessage(CB_GETITEMDATA, (WPARAM)nIndex, 0);
+ }
+
+ inline int CComboBox::GetItemHeight(int nIndex) const
+ // Determines the height of list items or the selection field in the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETITEMHEIGHT, (WPARAM)nIndex, 0);
+ }
+
+ inline int CComboBox::GetLBText(int nIndex, LPTSTR lpszText) const
+ // Retrieves a string from the list of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETLBTEXT, (WPARAM)nIndex, (LPARAM)lpszText);
+ }
+
+ inline int CComboBox::GetLBTextLen(int nIndex) const
+ // Retrieves the length, in characters, of a string in the list of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETLBTEXTLEN, (WPARAM)nIndex, 0);
+ }
+
+ inline LCID CComboBox::GetLocale() const
+ // Retrieves the current locale of the combo box.
+ {
+ assert(IsWindow());
+ return (LCID)SendMessage(CB_GETLOCALE, 0, 0);
+ }
+
+ inline int CComboBox::GetTopIndex() const
+ // Retrieves the zero-based index of the first visible item in the list box portion of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_GETTOPINDEX, 0, 0);
+ }
+
+ inline int CComboBox::InitStorage(int nItems, int nBytes) const
+ // Allocates memory for storing list box items. Use this before adding a
+ // large number of items to the list box portion of a combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_INITSTORAGE, (WPARAM)nItems, (LPARAM)nBytes);
+ }
+
+ inline int CComboBox::InsertString(int nIndex, LPCTSTR lpszString) const
+ // Inserts a string into the list box of the combo box. Unlike the AddString,
+ // a list with the CBS_SORT style is not sorted.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_INSERTSTRING, (WPARAM)nIndex, (LPARAM)lpszString);
+ }
+
+ inline void CComboBox::Paste() const
+ // Copies the current content of the clipboard to the combo box's edit control at the current caret position.
+ {
+ assert(IsWindow());
+ SendMessage(WM_PASTE, 0, 0);
+ }
+
+ inline void CComboBox::LimitText(int nMaxChars) const
+ // Limits the length of the text the user may type into the edit control of the combo box.
+ {
+ assert(IsWindow());
+ SendMessage(CB_LIMITTEXT, (WPARAM)nMaxChars, 0);
+ }
+
+ inline void CComboBox::ResetContent() const
+ // Removes all items from the list box and edit control of the combo box.
+ {
+ assert(IsWindow());
+ SendMessage(CB_RESETCONTENT, 0, 0);
+ }
+
+ inline int CComboBox::SelectString(int nStartAfter, LPCTSTR lpszString) const
+ // Searches the list of a combo box for an item that begins with the characters in a
+ // specified string. If a matching item is found, it is selected and copied to the edit control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SELECTSTRING, (WPARAM)nStartAfter, (LPARAM)lpszString);
+ }
+
+ inline int CComboBox::SetCurSel(int nIndex) const
+ // Selects a string in the list of the combo box. If necessary, the list scrolls the string into view.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETCURSEL, (WPARAM)nIndex, 0);
+ }
+
+ inline int CComboBox::SetDroppedWidth(int nWidth) const
+ // Sets the maximum allowable width, in pixels, of the list box of the combo box with
+ // the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETDROPPEDWIDTH, (WPARAM)nWidth, 0);
+ }
+
+ inline BOOL CComboBox::SetEditSel(int nStartChar, int nEndChar) const
+ // Selects characters in the edit control of the combo box.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CB_SETEDITSEL, 0, (LPARAM)MAKELONG(nStartChar,nEndChar));
+ }
+
+ inline int CComboBox::SetExtendedUI(BOOL bExtended) const
+ // Selects either the default user interface or the extended user interface for the combo box that
+ // has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETEXTENDEDUI, (WPARAM)bExtended, 0);
+ }
+
+ inline void CComboBox::SetHorizontalExtent(UINT nExtent ) const
+ // Sets the width, in pixels, by which the list box can be scrolled horizontally (the scrollable width).
+ {
+ assert(IsWindow());
+ SendMessage(CB_SETHORIZONTALEXTENT, (WPARAM)nExtent, 0);
+ }
+
+ inline int CComboBox::SetItemData(int nIndex, DWORD dwItemData) const
+ // Sets the value associated with the specified item in the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)dwItemData);
+ }
+
+ inline int CComboBox::SetItemHeight(int nIndex, UINT cyItemHeight) const
+ // Sets the height of list items or the selection field in the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETITEMHEIGHT, (WPARAM)nIndex, (LPARAM)cyItemHeight);
+ }
+
+ inline LCID CComboBox::SetLocale( LCID NewLocale ) const
+ // Sets the current locale of the combo box.
+ {
+ assert(IsWindow());
+ return (LCID)SendMessage(CB_SETLOCALE, (WPARAM)NewLocale, 0);
+ }
+
+ inline int CComboBox::SetTopIndex(int nIndex) const
+ // Ensure that a particular item is visible in the list box of the combo box.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CB_SETTOPINDEX, (WPARAM)nIndex, 0);
+ }
+
+ inline void CComboBox::ShowDropDown(BOOL bShow) const
+ // Shows or hides the list box of the combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
+ {
+ assert(IsWindow());
+ SendMessage(CB_SHOWDROPDOWN, (WPARAM)bShow, 0);
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CComboBoxEx class
+ //
+ inline int CComboBoxEx::DeleteItem(int nIndex ) const
+ // Removes an item from the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CBEM_DELETEITEM, (WPARAM)nIndex, 0);
+ }
+
+ inline CWnd* CComboBoxEx::GetComboBoxCtrl() const
+ // Retrieves the handle to the child combo box control.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(CBEM_GETCOMBOCONTROL, 0, 0));
+ }
+
+ inline CWnd* CComboBoxEx::GetEditCtrl() const
+ // Retrieves the handle to the edit control portion of the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0));
+ }
+
+ inline DWORD CComboBoxEx::GetExtendedStyle() const
+ // Retrieves the extended styles that are in use for the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (DWORD)SendMessage(CBEM_GETEXTENDEDSTYLE, 0, 0);
+ }
+
+ inline HIMAGELIST CComboBoxEx::GetImageList() const
+ // Retrieves the handle to an image list assigned to the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (HIMAGELIST)SendMessage(CBEM_GETIMAGELIST, 0, 0);
+ }
+
+ inline BOOL CComboBoxEx::GetItem(COMBOBOXEXITEM* pCBItem) const
+ // Retrieves item information for the given ComboBoxEx item.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CBEM_GETITEM, 0, (LPARAM)pCBItem);
+ }
+
+ inline BOOL CComboBoxEx::HasEditChanged () const
+ // Determines whether or not the user has changed the text of the ComboBoxEx edit control.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CBEM_HASEDITCHANGED, 0, 0);
+ }
+
+ inline int CComboBoxEx::InsertItem(COMBOBOXEXITEM* lpcCBItem) const
+ // Inserts a new item in the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(CBEM_INSERTITEM, 0, (LPARAM)lpcCBItem);
+ }
+
+ inline DWORD CComboBoxEx::SetExtendedStyle(DWORD dwExMask, DWORD dwExStyles ) const
+ // Sets extended styles within the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, (WPARAM)dwExMask, (LPARAM)dwExStyles);
+ }
+
+ inline HIMAGELIST CComboBoxEx::SetImageList(HIMAGELIST himl) const
+ // Sets an image list for the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (HIMAGELIST)SendMessage(CBEM_SETIMAGELIST, 0, (LPARAM)himl);
+ }
+
+ inline BOOL CComboBoxEx::SetItem(PCOMBOBOXEXITEM lpcCBItem) const
+ // Sets the attributes for an item in the ComboBoxEx control.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(CBEM_SETITEM, 0, (LPARAM)lpcCBItem);
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CProgressBar class
+ //
+ inline int CProgressBar::GetPos() const
+ // Retrieves the current position of the progress bar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_GETPOS, 0, 0);
+ }
+
+ inline int CProgressBar::GetRange(BOOL fWhichLimit, PPBRANGE ppBRange) const
+ // Retrieves information about the current high and low limits of the progress bar control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_GETRANGE, (WPARAM)fWhichLimit, (LPARAM) (PPBRANGE) ppBRange);
+ }
+
+ inline int CProgressBar::OffsetPos(int nIncrement) const
+ // Advances the current position of the progress bar by a specified increment and redraws
+ // the bar to reflect the new position.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_DELTAPOS, (WPARAM)nIncrement, 0);
+ }
+
+ inline int CProgressBar::SetPos(int nNewPos) const
+ // Sets the current position for the progress bar and redraws the bar to reflect the new position.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_SETPOS, (WPARAM)nNewPos, 0);
+ }
+
+ inline int CProgressBar::SetRange(short nMinRange, short nMaxRange) const
+ // Sets the minimum and maximum values for the progress bar and redraws the bar to reflect the new range.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_SETRANGE, 0, (LPARAM) MAKELPARAM (nMinRange, nMaxRange));
+ }
+
+ inline int CProgressBar::SetStep(int nStepInc) const
+ // Specifies the step increment for the progress bar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_SETSTEP, (WPARAM)nStepInc, 0);
+ }
+
+ inline int CProgressBar::StepIt() const
+ // Advances the current position for a progress bar by the step increment and
+ // redraws the bar to reflect the new position.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(PBM_STEPIT, 0, 0);
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CScrollBar class
+ //
+ inline BOOL CScrollBar::EnableScrollBar( UINT nArrowFlags ) const
+ // Enables or disables the scroll bar arrows.
+ {
+ assert(IsWindow());
+ return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags);
+ }
+
+ inline BOOL CScrollBar::GetScrollInfo(LPSCROLLINFO lpsi) const
+ // Retrieves the parameters of a scroll bar, including the minimum and maximum
+ // scrolling positions, the page size, and the position of the scroll box (thumb).
+ {
+ assert(IsWindow());
+ return ::GetScrollInfo(m_hWnd, SB_CTL, lpsi);
+ }
+
+ inline int CScrollBar::GetScrollPos() const
+ // Retrieves the current position of the scroll box (thumb) in the scroll bar.
+ {
+ assert(IsWindow());
+ return ::GetScrollPos(m_hWnd, SB_CTL);
+ }
+
+ inline BOOL CScrollBar::GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos ) const
+ // Retrieves the current minimum and maximum scroll box (thumb) positions for the scroll bar.
+ {
+ assert(IsWindow());
+ return ::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos);
+ }
+
+ inline BOOL CScrollBar::SetScrollInfo(LPSCROLLINFO lpsi, BOOL bRedraw ) const
+ // Sets the parameters of the scroll bar, including the minimum and maximum scrolling positions,
+ // the page size, and the position of the scroll box (thumb).
+ {
+ assert(IsWindow());
+ return ::SetScrollInfo(m_hWnd, SB_CTL, lpsi, bRedraw);
+ }
+
+ inline int CScrollBar::SetScrollPos(int nPos, BOOL bRedraw) const
+ // Sets the position of the scroll box (thumb) in the scroll bar and, if requested,
+ // redraws the scroll bar to reflect the new position of the scroll box.
+ {
+ assert(IsWindow());
+ return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw);
+ }
+
+ inline BOOL CScrollBar::SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw ) const
+ // Sets the minimum and maximum scroll box positions for the scroll bar.
+ {
+ assert(IsWindow());
+ return ::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw);
+ }
+
+ inline BOOL CScrollBar::ShowScrollBar(BOOL bShow) const
+ // Shows or hides the scroll bar.
+ {
+ assert(IsWindow());
+ return ::ShowScrollBar(m_hWnd, SB_CTL, bShow);
+ }
+
+ ////////////////////////////////////////
+ // Definitions for the CSlider class
+ //
+ inline void CSlider::ClearSel() const
+ // Clears the current selection range in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_CLEARSEL, 0, 0);
+ }
+
+ inline void CSlider::ClearTics(BOOL bRedraw) const
+ // Removes the current tick marks from the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_CLEARTICS, (WPARAM)bRedraw, 0);
+ }
+
+ inline CWnd* CSlider::GetBuddy(BOOL fLocation) const
+ // Retrieves the handle to the trackbar control buddy window at a given location.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(TBM_GETBUDDY, (WPARAM)fLocation, 0));
+ }
+
+ inline CRect CSlider::GetChannelRect() const
+ // Retrieves the size and position of the bounding rectangle for the trackbar's channel.
+ {
+ assert(IsWindow());
+ CRect rc;
+ SendMessage(TBM_GETCHANNELRECT, 0, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline int CSlider::GetLineSize() const
+ // Retrieves the number of logical positions the trackbar's slider moves in response
+ // to keyboard input from the arrow keys.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETLINESIZE, 0, 0);
+ }
+
+ inline int CSlider::GetNumTics() const
+ // Retrieves the number of tick marks in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETNUMTICS, 0, 0);
+ }
+
+ inline int CSlider::GetPageSize() const
+ // Retrieves the number of logical positions the trackbar's slider moves in response to
+ // keyboard input, or mouse input, such as clicks in the trackbar's channel.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETPAGESIZE, 0, 0);
+ }
+
+ inline int CSlider::GetPos() const
+ // Retrieves the current logical position of the slider in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETPOS, 0, 0);
+ }
+
+ inline int CSlider::GetRangeMax() const
+ // Retrieves the maximum position for the slider in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETRANGEMAX, 0, 0);
+ }
+
+ inline int CSlider::GetRangeMin() const
+ // Retrieves the minimum position for the slider in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETRANGEMIN, 0, 0);
+ }
+
+ inline int CSlider::GetSelEnd() const
+ // Retrieves the ending position of the current selection range in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETSELEND, 0, 0);
+ }
+
+ inline int CSlider::GetSelStart() const
+ // Retrieves the starting position of the current selection range in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETSELSTART, 0, 0);
+ }
+
+ inline int CSlider::GetThumbLength() const
+ // Retrieves the length of the slider in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETTHUMBLENGTH, 0, 0);
+ }
+
+ inline CRect CSlider::GetThumbRect() const
+ // Retrieves the size and position of the bounding rectangle for the slider in the trackbar.
+ {
+ CRect rc;
+ SendMessage(TBM_GETTHUMBRECT, 0, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline int CSlider::GetTic(int nTic ) const
+ // Retrieves the logical position of a tick mark in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETTIC, (WPARAM)nTic, 0);
+ }
+
+ inline int CSlider::GetTicPos(int nTic) const
+ // Retrieves the current physical position of a tick mark in the trackbar.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_GETTICPOS, (WPARAM)nTic, 0);
+ }
+
+ inline CWnd* CSlider::GetToolTips() const
+ // Retrieves the handle to the ToolTip control assigned to the trackbar, if any.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(TBM_GETTOOLTIPS, 0, 0));
+ }
+
+ inline CWnd* CSlider::SetBuddy(CWnd* pBuddy, BOOL fLocation /*= TRUE*/ ) const
+ // Assigns a window as the buddy window for the trackbar control.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(TBM_SETBUDDY, (WPARAM)fLocation, (LPARAM)pBuddy->GetHwnd()));
+ }
+
+ inline int CSlider::SetLineSize(int nSize) const
+ // Sets the number of logical positions the trackbar's slider moves in response to
+ // keyboard input from the arrow keys.
+ {
+ assert(IsWindow());
+ return(int)SendMessage(TBM_SETLINESIZE, 0, (LPARAM)nSize);
+ }
+
+ inline int CSlider::SetPageSize(int nSize) const
+ // Sets the number of logical positions the trackbar's slider moves in response to
+ // keyboard input, or mouse input such as clicks in the trackbar's channel.
+ {
+ assert(IsWindow());
+ return(int)SendMessage(TBM_SETPAGESIZE, 0, (LPARAM)nSize);
+ }
+
+ inline void CSlider::SetPos(int nPos, BOOL bRedraw) const
+ // Sets the current logical position of the slider in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETPOS, (WPARAM)bRedraw, (LPARAM)nPos);
+ }
+
+ inline void CSlider::SetRangeMax(int nMax, BOOL bRedraw) const
+ // Sets the maximum logical position for the slider in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETRANGEMAX, (WPARAM)bRedraw, (LPARAM)nMax);
+ }
+
+ inline void CSlider::SetRangeMin(int nMax, BOOL bRedraw) const
+ // Sets the minimum logical position for the slider in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETRANGEMIN, (WPARAM)bRedraw, (LPARAM)nMax);
+ }
+
+ inline void CSlider::SetSelection(int nMin, int nMax, BOOL bRedraw) const
+ // Sets the starting and ending positions for the available selection range in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETSEL, (WPARAM)bRedraw, (LPARAM)MAKELONG(nMax, nMin));
+ }
+
+ inline BOOL CSlider::SetTic(int nTic) const
+ // Sets a tick mark in the trackbar at the specified logical position.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(TBM_SETTIC, 0, nTic);
+ }
+
+ inline void CSlider::SetTicFreq(int nFreq) const
+ // Sets the interval frequency for tick marks in the trackbar.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETTICFREQ, (WPARAM)nFreq, 0);
+ }
+
+ inline int CSlider::SetTipSide(int nLocation) const
+ // Positions a ToolTip control used by the trackbar control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(TBM_SETTIPSIDE, (WPARAM)nLocation, 0);
+ }
+
+ inline void CSlider::SetToolTips(CWnd* pToolTip) const
+ // Assigns a ToolTip control to the trackbar control.
+ {
+ assert(IsWindow());
+ SendMessage(TBM_SETTOOLTIPS, (WPARAM)pToolTip->GetHwnd(), 0);
+ }
+
+ ////////////////////////////////////////
+ // Definitions for the CSpinButton class
+ //
+ inline int CSpinButton::GetAccel(int cAccels, LPUDACCEL paAccels) const
+ // Retrieves acceleration information for the up-down control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(UDM_GETACCEL, (WPARAM)cAccels, (LPARAM)paAccels);
+ }
+
+ inline int CSpinButton::GetBase() const
+ // Retrieves the current radix base (that is, either base 10 or 16) for the up-down control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(UDM_GETBASE, 0, 0);
+ }
+
+ inline CWnd* CSpinButton::GetBuddy() const
+ // Retrieves the handle to the current buddy window.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(UDM_GETBUDDY, 0, 0));
+ }
+
+ inline int CSpinButton::GetPos() const
+ // Retrieves the current position of the up-down control with 16-bit precision.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(UDM_GETPOS, 0, 0);
+ }
+
+ inline DWORD CSpinButton::GetRange() const
+ // Retrieves the minimum and maximum positions (range) for the up-down control.
+ {
+ assert(IsWindow());
+ return (DWORD)SendMessage(UDM_GETRANGE, 0, 0);
+ }
+
+ inline void CSpinButton::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VISIBLE |UDS_SETBUDDYINT;
+ }
+
+ inline void CSpinButton::PreRegisterClass(WNDCLASS &wc)
+ {
+ wc.lpszClassName = UPDOWN_CLASS;
+ }
+
+ inline BOOL CSpinButton::SetAccel(int cAccels, LPUDACCEL paAccels) const
+ // Sets the acceleration for the up-down control.
+ {
+ assert(IsWindow());
+ return (BOOL)SendMessage(UDM_SETACCEL, (WPARAM)cAccels, (LPARAM)paAccels);
+ }
+
+ inline int CSpinButton::SetBase(int nBase) const
+ // Sets the radix base for the up-down control.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(UDM_SETBASE, (WPARAM)nBase, 0);
+ }
+
+ inline CWnd* CSpinButton::SetBuddy(CWnd* pBuddy) const
+ // Sets the buddy window for the up-down control.
+ {
+ assert(IsWindow());
+ return FromHandle((HWND)SendMessage(UDM_SETBUDDY, (WPARAM)pBuddy->GetHwnd(), 0));
+ }
+
+ inline int CSpinButton::SetPos(int nPos) const
+ // Sets the current position for the up-down control with 16-bit precision.
+ {
+ assert(IsWindow());
+ return (int)SendMessage(UDM_SETPOS, 0, (LPARAM)MAKELONG ((short) nPos, 0));
+ }
+
+ inline void CSpinButton::SetRange(int nLower, int nUpper) const
+ // Sets the minimum and maximum positions (range) for the up-down control.
+ {
+ assert(IsWindow());
+ SendMessage(UDM_SETRANGE, 0, (LPARAM)MAKELONG(nUpper, nLower));
+ }
+
+} // namespace Win32xx
+
+#endif // define _WIN32XX_CONTROLS_H_
+
diff --git a/mmc_updater/depends/win32cpp/copyright.txt b/mmc_updater/depends/win32cpp/copyright.txt
new file mode 100644
index 00000000..d2222fa7
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/copyright.txt
@@ -0,0 +1,33 @@
+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.
diff --git a/mmc_updater/depends/win32cpp/cstring.h b/mmc_updater/depends/win32cpp/cstring.h
new file mode 100644
index 00000000..faf574d5
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/cstring.h
@@ -0,0 +1,905 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+// Acknowledgements:
+// Thanks to Adam Szulc for his initial CString code.
+
+////////////////////////////////////////////////////////
+// cstring.h
+// Declaration of the cstring.h
+
+// This class is intended to provide a simple alternative to the MFC/ATL
+// CString class that ships with Microsoft compilers. The CString class
+// specified here is compatible with other compilers such as Borland 5.5
+// and MinGW.
+
+// Differences between this class and the MFC/ATL CString class
+// ------------------------------------------------------------
+// 1) The constructors for this class accepts only TCHARs. The various text conversion
+// functions can be used to convert from other character types to TCHARs.
+//
+// 2) This class is not reference counted, so these CStrings should be passed as
+// references or const references when used as function arguments. As a result there
+// is no need for functions like LockBuffer and UnLockBuffer.
+//
+// 3) The Format functions only accepts POD (Plain Old Data) arguments. It does not
+// accept arguments which are class or struct objects. In particular it does not
+// accept CString objects, unless these are cast to LPCTSTR.
+// This is demonstrates valid and invalid usage:
+// CString string1(_T("Hello World"));
+// CString string2;
+//
+// // This is invalid, and produces undefined behaviour.
+// string2.Format(_T("String1 is: %s"), string1); // No! you can't do this
+//
+// // This is ok
+// string2.Format(_T("String1 is: %s"), (LPCTSTR)string1); // Yes, this is correct
+//
+// Note: The MFC/ATL CString class uses a non portable hack to make its CString class
+// behave like a POD. Other compilers (such as the MinGW compiler) specifically
+// prohibit the use of non POD types for functions with variable argument lists.
+//
+// 4) This class provides a few additional functions:
+// b_str Returns a BSTR string. This an an alternative for casting to BSTR.
+// c_str Returns a const TCHAR string. This is an alternative for casting to LPCTSTR.
+// GetErrorString Assigns CString to the error string for the specified System Error Code
+// (from ::GetLastErrror() for example).
+// GetString Returns a reference to the underlying std::basic_string<TCHAR>. This
+// reference can be used to modify the string directly.
+
+
+
+#ifndef _WIN32XX_CSTRING_H_
+#define _WIN32XX_CSTRING_H_
+
+
+#include "wincore.h"
+
+
+namespace Win32xx
+{
+
+ class CString
+ {
+ // friend functions allow the left hand side to be something other than CString
+ friend CString operator + (const CString& string1, const CString& string2);
+ friend CString operator + (const CString& string, LPCTSTR pszText);
+ friend CString operator + (const CString& string, TCHAR ch);
+ friend CString operator + (LPCTSTR pszText, const CString& string);
+ friend CString operator + (TCHAR ch, const CString& string);
+
+ public:
+ CString();
+ ~CString();
+ CString(const CString& str);
+ CString(LPCTSTR pszText);
+ CString(TCHAR ch, int nLength = 1);
+ CString(LPCTSTR pszText, int nLength);
+
+ CString& operator = (const CString& str);
+ CString& operator = (const TCHAR ch);
+ CString& operator = (LPCTSTR pszText);
+ BOOL operator == (LPCTSTR pszText);
+ BOOL operator != (LPCTSTR pszText);
+ BOOL operator < (LPCTSTR pszText);
+ BOOL operator > (LPCTSTR pszText);
+ BOOL operator <= (LPCTSTR pszText);
+ BOOL operator >= (LPCTSTR pszText);
+ operator LPCTSTR() const;
+ operator BSTR() const;
+ TCHAR& operator [] (int nIndex);
+ CString& operator += (const CString& str);
+
+ // Attributes
+ BSTR b_str() const { return T2W(m_str.c_str()); } // alternative for casting to BSTR
+ LPCTSTR c_str() const { return m_str.c_str(); } // alternative for casting to LPCTSTR
+ tString& GetString() { return m_str; } // returns a reference to the underlying std::basic_string<TCHAR>
+ int GetLength() const { return (int)m_str.length(); } // returns the length in characters
+
+ // Operations
+ BSTR AllocSysString() const;
+ void AppendFormat(LPCTSTR pszFormat,...);
+ void AppendFormat(UINT nFormatID, ...);
+ int Compare(LPCTSTR pszText) const;
+ int CompareNoCase(LPCTSTR pszText) const;
+ int Delete(int nIndex, int nCount = 1);
+ int Find(TCHAR ch, int nIndex = 0 ) const;
+ int Find(LPCTSTR pszText, int nStart = 0) const;
+ int FindOneOf(LPCTSTR pszText) const;
+ void Format(UINT nID, ...);
+ void Format(LPCTSTR pszFormat,...);
+ void FormatV(LPCTSTR pszFormat, va_list args);
+ void FormatMessage(LPCTSTR pszFormat,...);
+ void FormatMessageV(LPCTSTR pszFormat, va_list args);
+ TCHAR GetAt(int nIndex) const;
+ LPTSTR GetBuffer(int nMinBufLength);
+ void GetErrorString(DWORD dwError);
+ void Empty();
+ int Insert(int nIndex, TCHAR ch);
+ int Insert(int nIndex, const CString& str);
+ BOOL IsEmpty() const;
+ CString Left(int nCount) const;
+ BOOL LoadString(UINT nID);
+ void MakeLower();
+ void MakeReverse();
+ void MakeUpper();
+ CString Mid(int nFirst) const;
+ CString Mid(int nFirst, int nCount) const;
+ void ReleaseBuffer( int nNewLength = -1 );
+ int Remove(LPCTSTR pszText);
+ int Replace(TCHAR chOld, TCHAR chNew);
+ int Replace(const LPCTSTR pszOld, LPCTSTR pszNew);
+ int ReverseFind(LPCTSTR pszText, int nStart = -1) const;
+ CString Right(int nCount) const;
+ void SetAt(int nIndex, TCHAR ch);
+ BSTR SetSysString(BSTR* pBstr) const;
+ CString SpanExcluding(LPCTSTR pszText) const;
+ CString SpanIncluding(LPCTSTR pszText) const;
+ CString Tokenize(LPCTSTR pszTokens, int& iStart) const;
+ void Trim();
+ void TrimLeft();
+ void TrimLeft(TCHAR chTarget);
+ void TrimLeft(LPCTSTR pszTargets);
+ void TrimRight();
+ void TrimRight(TCHAR chTarget);
+ void TrimRight(LPCTSTR pszTargets);
+ void Truncate(int nNewLength);
+
+#ifndef _WIN32_WCE
+ int Collate(LPCTSTR pszText) const;
+ int CollateNoCase(LPCTSTR pszText) const;
+ BOOL GetEnvironmentVariable(LPCTSTR pszVar);
+#endif
+
+ private:
+ tString m_str;
+ std::vector<TCHAR> m_buf;
+ };
+
+ inline CString::CString()
+ {
+ }
+
+ inline CString::~CString()
+ {
+ }
+
+ inline CString::CString(const CString& str)
+ {
+ m_str.assign(str);
+ }
+
+ inline CString::CString(LPCTSTR pszText)
+ {
+ m_str.assign(pszText);
+ }
+
+ inline CString::CString(TCHAR ch, int nLength)
+ {
+ m_str.assign(nLength, ch);
+ }
+
+ inline CString::CString(LPCTSTR pszText, int nLength)
+ {
+ m_str.assign(pszText, nLength);
+ }
+
+ inline CString& CString::operator = (const CString& str)
+ {
+ m_str.assign(str);
+ return *this;
+ }
+
+ inline CString& CString::operator = (const TCHAR ch)
+ {
+ m_str.assign(1, ch);
+ return *this;
+ }
+
+ inline CString& CString::operator = (LPCTSTR pszText)
+ {
+ m_str.assign(pszText);
+ return *this;
+ }
+
+ inline BOOL CString::operator == (LPCTSTR pszText)
+ // Returns TRUE if the strings have the same content
+ {
+ assert(pszText);
+ return (0 == Compare(pszText));
+ }
+
+ inline BOOL CString::operator != (LPCTSTR pszText)
+ // Returns TRUE if the strings have a different content
+ {
+ assert(pszText);
+ return Compare(pszText) != 0;
+ }
+
+ inline BOOL CString::operator < (LPCTSTR pszText)
+ {
+ assert(pszText);
+ return Compare(pszText) < 0;
+ }
+
+ inline BOOL CString::operator > (LPCTSTR pszText)
+ {
+ assert(pszText);
+ return Compare(pszText) > 0;
+ }
+
+ inline BOOL CString::operator <= (LPCTSTR pszText)
+ {
+ assert(pszText);
+ return Compare(pszText) <= 0;
+ }
+
+ inline BOOL CString::operator >= (LPCTSTR pszText)
+ {
+ assert(pszText);
+ return Compare(pszText) >= 0;
+ }
+
+ inline CString::operator LPCTSTR() const
+ {
+ return m_str.c_str();
+ }
+
+ inline TCHAR& CString::operator [] (int nIndex)
+ {
+ assert(nIndex >= 0);
+ assert(nIndex < GetLength());
+ return m_str[nIndex];
+ }
+
+ inline CString& CString::operator += (const CString& str)
+ {
+ m_str.append(str);
+ return *this;
+ }
+
+ inline BSTR CString::AllocSysString() const
+ // Allocates a BSTR from the CString content.
+ {
+ return ::SysAllocStringLen(T2W(m_str.c_str()), (UINT)m_str.size());
+ }
+
+ inline void CString::AppendFormat(LPCTSTR pszFormat,...)
+ // Appends formatted data to an the CString content.
+ {
+ CString str;
+ str.Format(pszFormat);
+ m_str.append(str);
+ }
+
+ inline void CString::AppendFormat(UINT nFormatID, ...)
+ // Appends formatted data to an the CString content.
+ {
+ CString str1;
+ CString str2;
+ if (str1.LoadString(nFormatID))
+ {
+ str2.Format(str1);
+ m_str.append(str2);
+ }
+ }
+
+#ifndef _WIN32_WCE
+ inline int CString::Collate(LPCTSTR pszText) const
+ // Performs a case sensitive comparison of the two strings using locale-specific information.
+ {
+ assert(pszText);
+ return _tcscoll(m_str.c_str(), pszText);
+ }
+
+ inline int CString::CollateNoCase(LPCTSTR pszText) const
+ // Performs a case insensitive comparison of the two strings using locale-specific information.
+ {
+ assert(pszText);
+ return _tcsicoll(m_str.c_str(), pszText);
+ }
+#endif // _WIN32_WCE
+
+ inline int CString::Compare(LPCTSTR pszText) const
+ // Performs a case sensitive comparison of the two strings.
+ {
+ assert(pszText);
+ return m_str.compare(pszText);
+ }
+
+ inline int CString::CompareNoCase(LPCTSTR pszText) const
+ // Performs a case insensitive comparison of the two strings.
+ {
+ assert(pszText);
+ return _tcsicmp(m_str.data(), pszText);
+ }
+
+ inline int CString::Delete(int nIndex, int nCount /* = 1 */)
+ // Deletes a character or characters from the string.
+ {
+ assert(nIndex >= 0);
+ assert(nCount >= 0);
+
+ m_str.erase(nIndex, nCount);
+ return (int)m_str.size();
+ }
+
+ inline void CString::Empty()
+ // Erases the contents of the string.
+ {
+ m_str.erase();
+ }
+
+ inline int CString::Find(TCHAR ch, int nIndex /* = 0 */) const
+ // Finds a character in the string.
+ {
+ assert(nIndex >= 0);
+ return (int)m_str.find(ch, nIndex);
+ }
+
+ inline int CString::Find(LPCTSTR pszText, int nIndex /* = 0 */) const
+ // Finds a substring within the string.
+ {
+ assert(pszText);
+ assert(nIndex >= 0);
+ return (int)m_str.find(pszText, nIndex);
+ }
+
+ inline int CString::FindOneOf(LPCTSTR pszText) const
+ // Finds the first matching character from a set.
+ {
+ assert(pszText);
+ return (int)m_str.find_first_of(pszText);
+ }
+
+ inline void CString::Format(LPCTSTR pszFormat,...)
+ // Formats the string as sprintf does.
+ {
+ va_list args;
+ va_start(args, pszFormat);
+ FormatV(pszFormat, args);
+ va_end(args);
+ }
+
+ inline void CString::Format(UINT nID, ...)
+ // Formats the string as sprintf does.
+ {
+ Empty();
+ CString str;
+ if (str.LoadString(nID))
+ Format(str);
+ }
+
+ inline void CString::FormatV(LPCTSTR pszFormat, va_list args)
+ // Formats the string using a variable list of arguments.
+ {
+ if (pszFormat)
+ {
+ int nResult = -1, nLength = 256;
+
+ // A vector is used to store the TCHAR array
+ std::vector<TCHAR> vBuffer;( nLength+1, _T('\0') );
+
+ while (-1 == nResult)
+ {
+ vBuffer.assign( nLength+1, _T('\0') );
+ nResult = _vsntprintf(&vBuffer[0], nLength, pszFormat, args);
+ nLength *= 2;
+ }
+ m_str.assign(&vBuffer[0]);
+ }
+ }
+
+ inline void CString::FormatMessage(LPCTSTR pszFormat,...)
+ // Formats a message string.
+ {
+ va_list args;
+ va_start(args, pszFormat);
+ FormatMessageV(pszFormat, args);
+ va_end(args);
+ }
+
+ inline void CString::FormatMessageV(LPCTSTR pszFormat, va_list args)
+ // Formats a message string using a variable argument list.
+ {
+ LPTSTR pszTemp = 0;
+ if (pszFormat)
+ {
+ DWORD dwResult = ::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, pszFormat, 0, 0, pszTemp, 0, &args);
+
+ if (0 == dwResult || 0 == pszTemp )
+ throw std::bad_alloc();
+
+ m_str = pszTemp;
+ LocalFree(pszTemp);
+ }
+ }
+
+ inline TCHAR CString::GetAt(int nIndex) const
+ // Returns the character at the specified location within the string.
+ {
+ assert(nIndex >= 0);
+ assert(nIndex < GetLength());
+ return m_str[nIndex];
+ }
+
+ inline LPTSTR CString::GetBuffer(int nMinBufLength)
+ // Creates a buffer of nMinBufLength charaters (+1 extra for NULL termination) and returns
+ // a pointer to this buffer. This buffer can be used by any function which accepts a LPTSTR.
+ // Care must be taken not to exceed the length of the buffer. Use ReleaseBuffer to safely
+ // copy this buffer back to the CString object.
+ //
+ // Note: The buffer uses a vector. Vectors are required to be contiguous in memory under
+ // the current standard, whereas std::strings do not have this requirement.
+ {
+ assert (nMinBufLength >= 0);
+
+ m_buf.assign(nMinBufLength + 1, _T('\0'));
+ tString::iterator it_end;
+
+ if (m_str.length() >= (size_t)nMinBufLength)
+ {
+ it_end = m_str.begin();
+ std::advance(it_end, nMinBufLength);
+ }
+ else
+ it_end = m_str.end();
+
+ std::copy(m_str.begin(), it_end, m_buf.begin());
+
+ return &m_buf[0];
+ }
+
+#ifndef _WIN32_WCE
+ inline BOOL CString::GetEnvironmentVariable(LPCTSTR pszVar)
+ // Sets the string to the value of the specified environment variable.
+ {
+ assert(pszVar);
+ Empty();
+
+ int nLength = ::GetEnvironmentVariable(pszVar, NULL, 0);
+ if (nLength > 0)
+ {
+ std::vector<TCHAR> vBuffer( nLength+1, _T('\0') );
+ ::GetEnvironmentVariable(pszVar, &vBuffer[0], nLength);
+ m_str = &vBuffer[0];
+ }
+
+ return (BOOL)nLength;
+ }
+#endif // _WIN32_WCE
+
+ inline void CString::GetErrorString(DWORD dwError)
+ // Returns the error string for the specified System Error Code (e.g from GetLastErrror).
+ {
+ m_str.erase();
+
+ if (dwError != 0)
+ {
+ TCHAR* pTemp = 0;
+ DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
+ ::FormatMessage(dwFlags, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pTemp, 1, NULL);
+ m_str.assign(pTemp);
+ ::LocalFree(pTemp);
+ }
+ }
+
+ inline int CString::Insert(int nIndex, TCHAR ch)
+ // Inserts a single character or a substring at the given index within the string.
+ {
+ assert(nIndex >= 0);
+ assert(ch);
+
+ m_str.insert(nIndex, &ch, 1);
+ return (int)m_str.size();
+ }
+
+ inline int CString::Insert(int nIndex, const CString& str)
+ // Inserts a single character or a substring at the given index within the string.
+ {
+ assert(nIndex >= 0);
+
+ m_str.insert(nIndex, str);
+ return (int)m_str.size();
+ }
+
+ inline BOOL CString::IsEmpty() const
+ // Returns TRUE if the string is empty
+ {
+ return m_str.empty();
+ }
+
+ inline CString CString::Left(int nCount) const
+ // Extracts the left part of a string.
+ {
+ assert(nCount >= 0);
+
+ CString str;
+ str.m_str.assign(c_str(), 0, nCount);
+ return str;
+ }
+
+ inline BOOL CString::LoadString(UINT nID)
+ // Loads the string from a Windows resource.
+ {
+ assert (GetApp());
+
+ int nSize = 64;
+ TCHAR* pTCharArray = 0;
+ std::vector<TCHAR> vString;
+ int nTChars = nSize;
+
+ Empty();
+
+ // Increase the size of our array in a loop until we load the entire string
+ // The ANSI and _UNICODE versions of LoadString behave differently. This technique works for both.
+ while ( nSize-1 <= nTChars )
+ {
+ nSize = nSize * 4;
+ vString.assign(nSize+1, _T('\0'));
+ pTCharArray = &vString[0];
+ nTChars = ::LoadString (GetApp()->GetResourceHandle(), nID, pTCharArray, nSize);
+ }
+
+ if (nTChars > 0)
+ m_str.assign(pTCharArray);
+
+ return (nTChars != 0);
+ }
+
+ inline void CString::MakeLower()
+ // Converts all the characters in this string to lowercase characters.
+ {
+ std::transform(m_str.begin(), m_str.end(), m_str.begin(), &::tolower);
+ }
+
+ inline void CString::MakeReverse()
+ // Reverses the string.
+ {
+ std::reverse(m_str.begin(), m_str.end());
+ }
+
+ inline void CString::MakeUpper()
+ // Converts all the characters in this string to uppercase characters.
+ {
+ std::transform(m_str.begin(), m_str.end(), m_str.begin(), &::toupper);
+ }
+
+ inline CString CString::Mid(int nFirst) const
+ // Extracts the middle part of a string.
+ {
+ return Mid(nFirst, GetLength());
+ }
+
+ inline CString CString::Mid(int nFirst, int nCount) const
+ // Extracts the middle part of a string.
+ {
+ assert(nFirst >= 0);
+ assert(nCount >= 0);
+
+ CString str;
+ str.m_str.assign(c_str(), nFirst, nFirst + nCount);
+ return str;
+ }
+
+ inline int CString::ReverseFind(LPCTSTR pszText, int nIndex /* = -1 */) const
+ // Search for a substring within the string, starting from the end.
+ {
+ assert(pszText);
+ return (int)m_str.rfind(pszText, nIndex);
+ }
+
+ inline void CString::SetAt(int nIndex, TCHAR ch)
+ // Sets the character at the specificed position to the specified value.
+ {
+ assert(nIndex >= 0);
+ assert(nIndex < GetLength());
+ m_str[nIndex] = ch;
+ }
+
+ inline void CString::ReleaseBuffer( int nNewLength /*= -1*/ )
+ // This copies the contents of the buffer (acquired by GetBuffer) to this CString,
+ // and releases the contents of the buffer. The default length of -1 copies from the
+ // buffer until a null terminator is reached. If the buffer doesn't contain a null
+ // terminator, you must specify the buffer's length.
+ {
+ assert (nNewLength > 0 || -1 == nNewLength);
+ assert (nNewLength < (int)m_buf.size());
+
+ if (-1 == nNewLength)
+ nNewLength = lstrlen(&m_buf[0]);
+ m_str.assign(nNewLength+1, _T('\0'));
+
+ std::vector<TCHAR>::iterator it_end = m_buf.begin();
+ std::advance(it_end, nNewLength);
+
+ std::copy(m_buf.begin(), it_end, m_str.begin());
+ m_buf.clear();
+ }
+
+ inline int CString::Remove(LPCTSTR pszText)
+ // Removes each occurrence of the specified substring from the string.
+ {
+ assert(pszText);
+
+ int nCount = 0;
+ size_t pos = 0;
+ while ((pos = m_str.find(pszText, pos)) != std::string::npos)
+ {
+ m_str.erase(pos, lstrlen(pszText));
+ ++nCount;
+ }
+ return nCount;
+ }
+
+ inline int CString::Replace(TCHAR chOld, TCHAR chNew)
+ // Replaces each occurance of the old character with the new character.
+ {
+ int nCount = 0;
+ tString::iterator it = m_str.begin();
+ while (it != m_str.end())
+ {
+ if (*it == chOld)
+ {
+ *it = chNew;
+ ++nCount;
+ }
+ ++it;
+ }
+ return nCount;
+ }
+
+ inline int CString::Replace(LPCTSTR pszOld, LPCTSTR pszNew)
+ // Replaces each occurance of the old substring with the new substring.
+ {
+ assert(pszOld);
+ assert(pszNew);
+
+ int nCount = 0;
+ size_t pos = 0;
+ while ((pos = m_str.find(pszOld, pos)) != std::string::npos)
+ {
+ m_str.replace(pos, lstrlen(pszOld), pszNew);
+ pos += lstrlen(pszNew);
+ ++nCount;
+ }
+ return nCount;
+ }
+
+ inline CString CString::Right(int nCount) const
+ // Extracts the right part of a string.
+ {
+ assert(nCount >= 0);
+
+ CString str;
+ str.m_str.assign(c_str(), m_str.size() - nCount, nCount);
+ return str;
+ }
+
+ inline BSTR CString::SetSysString(BSTR* pBstr) const
+ // Sets an existing BSTR object to the string.
+ {
+ assert(pBstr);
+
+ if ( !::SysReAllocStringLen(pBstr, T2W(m_str.c_str()), (UINT)m_str.length()) )
+ throw std::bad_alloc();
+
+ return *pBstr;
+ }
+
+ inline CString CString::SpanExcluding(LPCTSTR pszText) const
+ // Extracts characters from the string, starting with the first character,
+ // that are not in the set of characters identified by pszCharSet.
+ {
+ assert (pszText);
+
+ CString str;
+ size_t pos = 0;
+
+ while ((pos = m_str.find_first_not_of(pszText, pos)) != std::string::npos)
+ {
+ str.m_str.append(1, m_str[pos++]);
+ }
+
+ return str;
+ }
+
+ inline CString CString::SpanIncluding(LPCTSTR pszText) const
+ // Extracts a substring that contains only the characters in a set.
+ {
+ assert (pszText);
+
+ CString str;
+ size_t pos = 0;
+
+ while ((pos = m_str.find_first_of(pszText, pos)) != std::string::npos)
+ {
+ str.m_str.append(1, m_str[pos++]);
+ }
+
+ return str;
+ }
+
+ inline CString CString::Tokenize(LPCTSTR pszTokens, int& iStart) const
+ // Extracts specified tokens in a target string.
+ {
+ assert(pszTokens);
+ assert(iStart >= 0);
+
+ CString str;
+ size_t pos1 = m_str.find_first_not_of(pszTokens, iStart);
+ size_t pos2 = m_str.find_first_of(pszTokens, pos1);
+
+ iStart = (int)pos2 + 1;
+ if (pos2 == m_str.npos)
+ iStart = -1;
+
+ if (pos1 != m_str.npos)
+ str.m_str = m_str.substr(pos1, pos2-pos1);
+
+ return str;
+ }
+
+ inline void CString::Trim()
+ // Trims all leading and trailing whitespace characters from the string.
+ {
+ TrimLeft();
+ TrimRight();
+ }
+
+ inline void CString::TrimLeft()
+ // Trims leading whitespace characters from the string.
+ {
+ // This method is supported by the Borland 5.5 compiler
+ tString::iterator iter;
+ for (iter = m_str.begin(); iter < m_str.end(); ++iter)
+ {
+ if (!isspace(*iter))
+ break;
+ }
+
+ m_str.erase(m_str.begin(), iter);
+ }
+
+ inline void CString::TrimLeft(TCHAR chTarget)
+ // Trims the specified character from the beginning of the string.
+ {
+ m_str.erase(0, m_str.find_first_not_of(chTarget));
+ }
+
+ inline void CString::TrimLeft(LPCTSTR pszTargets)
+ // Trims the specified set of characters from the beginning of the string.
+ {
+ assert(pszTargets);
+ m_str.erase(0, m_str.find_first_not_of(pszTargets));
+ }
+
+ inline void CString::TrimRight()
+ // Trims trailing whitespace characters from the string.
+ {
+ // This method is supported by the Borland 5.5 compiler
+ tString::reverse_iterator riter;
+ for (riter = m_str.rbegin(); riter < m_str.rend(); ++riter)
+ {
+ if (!isspace(*riter))
+ break;
+ }
+
+ m_str.erase(riter.base(), m_str.end());
+ }
+
+ inline void CString::TrimRight(TCHAR chTarget)
+ // Trims the specified character from the end of the string.
+ {
+ size_t pos = m_str.find_last_not_of(chTarget);
+ if (pos != std::string::npos)
+ m_str.erase(++pos);
+ }
+
+ inline void CString::TrimRight(LPCTSTR pszTargets)
+ // Trims the specified set of characters from the end of the string.
+ {
+ assert(pszTargets);
+
+ size_t pos = m_str.find_last_not_of(pszTargets);
+ if (pos != std::string::npos)
+ m_str.erase(++pos);
+ }
+
+ inline void CString::Truncate(int nNewLength)
+ // Reduces the length of the string to the specified amount.
+ {
+ if (nNewLength < GetLength())
+ {
+ assert(nNewLength >= 0);
+ m_str.erase(nNewLength);
+ }
+ }
+
+
+ ///////////////////////////////////
+ // Global Functions
+ //
+
+ // friend functions of CString
+ inline CString operator + (const CString& string1, const CString& string2)
+ {
+ CString str(string1);
+ str.m_str.append(string2.m_str);
+ return str;
+ }
+
+ inline CString operator + (const CString& string, LPCTSTR pszText)
+ {
+ CString str(string);
+ str.m_str.append(pszText);
+ return str;
+ }
+
+ inline CString operator + (const CString& string, TCHAR ch)
+ {
+ CString str(string);
+ str.m_str.append(1, ch);
+ return str;
+ }
+
+ inline CString operator + (LPCTSTR pszText, const CString& string)
+ {
+ CString str(pszText);
+ str.m_str.append(string);
+ return str;
+ }
+
+ inline CString operator + (TCHAR ch, const CString& string)
+ {
+ CString str(ch);
+ str.m_str.append(string);
+ return str;
+ }
+
+ // Global LoadString
+ inline CString LoadString(UINT nID)
+ {
+ CString str;
+ str.LoadString(nID);
+ return str;
+ }
+
+
+} // namespace Win32xx
+
+#endif//_WIN32XX_CSTRING_H_
diff --git a/mmc_updater/depends/win32cpp/default_resource.h b/mmc_updater/depends/win32cpp/default_resource.h
new file mode 100644
index 00000000..b616a183
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/default_resource.h
@@ -0,0 +1,94 @@
+// This file contains the resource ID definitions for Win32++.
+
+
+// The resource ID for MENU, ICON, ToolBar Bitmap, Accelerator,
+// and Window Caption
+#define IDW_MAIN 51
+
+// Resource ID for the About dialog
+#define IDW_ABOUT 52
+
+// Resource IDs for menu items
+#define IDW_VIEW_TOOLBAR 53
+#define IDW_VIEW_STATUSBAR 54
+
+// Resource IDs for the Command Bands
+#define IDW_CMD_BANDS 55
+#define IDW_MENUBAR 56
+#define IDW_TOOLBAR 57
+
+// Resource ID for the Accelerator key
+#define IDW_QUIT 58
+
+// Resource IDs for MDI menu items
+#define IDW_MDI_CASCADE 60
+#define IDW_MDI_TILE 61
+#define IDW_MDI_ARRANGE 62
+#define IDW_MDI_CLOSEALL 63
+#define IDW_FIRSTCHILD 64
+#define IDW_CHILD2 65
+#define IDW_CHILD3 66
+#define IDW_CHILD4 67
+#define IDW_CHILD5 68
+#define IDW_CHILD6 69
+#define IDW_CHILD7 70
+#define IDW_CHILD8 71
+#define IDW_CHILD9 72
+#define IDW_CHILD10 73
+
+#define IDW_FILE_MRU_FILE1 75
+#define IDW_FILE_MRU_FILE2 76
+#define IDW_FILE_MRU_FILE3 77
+#define IDW_FILE_MRU_FILE4 78
+#define IDW_FILE_MRU_FILE5 79
+#define IDW_FILE_MRU_FILE6 80
+#define IDW_FILE_MRU_FILE7 81
+#define IDW_FILE_MRU_FILE8 82
+#define IDW_FILE_MRU_FILE9 83
+#define IDW_FILE_MRU_FILE10 84
+#define IDW_FILE_MRU_FILE11 85
+#define IDW_FILE_MRU_FILE12 86
+#define IDW_FILE_MRU_FILE13 87
+#define IDW_FILE_MRU_FILE14 88
+#define IDW_FILE_MRU_FILE15 89
+#define IDW_FILE_MRU_FILE16 90
+
+// Cursor Resources
+#define IDW_SPLITH 91
+#define IDW_SPLITV 92
+#define IDW_TRACK4WAY 93
+
+// Docking Bitmap Resources
+#define IDW_SDBOTTOM 94
+#define IDW_SDCENTER 95
+#define IDW_SDLEFT 96
+#define IDW_SDMIDDLE 97
+#define IDW_SDRIGHT 98
+#define IDW_SDTOP 99
+
+
+// A generic ID for any static control
+#ifndef IDC_STATIC
+ #define IDC_STATIC -1
+#endif
+
+
+
+// Notes about Resource IDs
+// * In general, resource IDs can have values from 1 to 65535. Programs with
+// resource IDs higher than 65535 aren't supported on Windows 95
+//
+// * CMenuBar uses resource IDs beginning from 0 for the top level menu items.
+// Win32++ leaves resource IDs below 51 unallocated for top level menu items.
+//
+// * Windows uses the icon with the lowest resource ID as the application's
+// icon. The application's icon is IDW_MAIN, which is the first resource ID
+// defined by Win32++.
+//
+// * When more than one static control is used in a dialog, the controls should
+// have a unique ID, unless a resource ID of -1 is used.
+//
+// * Users of Win32++ are advised to begin their resource IDs from 120 to
+// allow for possible expansion of Win32++.
+
+
diff --git a/mmc_updater/depends/win32cpp/default_resource.rc b/mmc_updater/depends/win32cpp/default_resource.rc
new file mode 100644
index 00000000..d53479f5
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/default_resource.rc
@@ -0,0 +1,250 @@
+// An example of a resource file
+//
+
+#include "resource.h"
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+1 24 DISCARDABLE "res/Win32++.manifest"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+
+IDW_MAIN MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "New &View", IDM_FILE_NEWVIEW
+ MENUITEM SEPARATOR
+ MENUITEM "Recent Files", IDW_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", IDM_FILE_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "Undo\tCtrl+Z", IDM_EDIT_UNDO
+ MENUITEM "Redo\tShift+Ctrl+Z", IDM_EDIT_REDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cut\tCtrl+X", IDM_EDIT_CUT
+ MENUITEM "Copy\tCtrl+C", IDM_EDIT_COPY
+ MENUITEM "Paste\tCtrl+V", IDM_EDIT_PASTE
+ MENUITEM "Delete\tDel", IDM_EDIT_DELETE
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Tool Bar", IDW_VIEW_TOOLBAR, CHECKED
+ MENUITEM "&Status Bar", IDW_VIEW_STATUSBAR, CHECKED
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About", IDM_HELP_ABOUT
+ END
+END
+
+MDIMENUVIEW MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "New &View", IDM_FILE_NEWVIEW
+ MENUITEM "&Close", IDM_FILE_CLOSE
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", IDM_FILE_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "Undo", IDM_EDIT_UNDO
+ MENUITEM "Redo", IDM_EDIT_REDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cu&t", IDM_EDIT_CUT
+ MENUITEM "&Copy", IDM_EDIT_COPY
+ MENUITEM "&Paste", IDM_EDIT_PASTE
+ MENUITEM "De&lete", IDM_EDIT_DELETE
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Tool Bar", IDW_VIEW_TOOLBAR, CHECKED
+ MENUITEM "Status Bar", IDW_VIEW_STATUSBAR, CHECKED
+ END
+ POPUP "&Color"
+ BEGIN
+ MENUITEM "&Black", IDM_COLOR_BLACK
+ MENUITEM "&Red", IDM_COLOR_RED
+ MENUITEM "&Green", IDM_COLOR_GREEN
+ MENUITEM "B&lue", IDM_COLOR_BLUE
+ MENUITEM "&White", IDM_COLOR_WHITE
+ END
+ POPUP "&Window"
+ BEGIN
+ MENUITEM "&Cascade\tShift+F5", IDW_WINDOW_CASCADE
+ MENUITEM "&Tile\tShift+F4", IDW_WINDOW_TILE
+ MENUITEM "Arrange &Icons", IDW_WINDOW_ARRANGE
+ MENUITEM "Close &All", IDW_WINDOW_CLOSEALL
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "About", IDM_HELP_ABOUT
+ END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDW_MAIN ICON "res/mdi.ico"
+IDI_VIEW ICON "res/view.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDW_MAIN BITMAP "res/toolbar.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDW_ABOUT DIALOGEX 0, 0, 186, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "About"
+FONT 8, "MS Shell Dlg", 400, 0
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,68,49,50,14
+ CTEXT "MDI Frame",IDC_STATIC,60,22,64,11
+ ICON IDW_MAIN,0,4,4,20,20
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDW_MAIN ACCELERATORS
+BEGIN
+ "N", IDM_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "P", IDM_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
+ "S", IDM_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+ "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+ "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ "Z", IDM_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
+ "Y", IDM_EDIT_REDO, VIRTKEY, SHIFT, CONTROL, NOINVERT
+ VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT
+END
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDW_MAIN "MDI Frame"
+END
+
+STRINGTABLE
+BEGIN
+ IDM_FILE_NEW "Create a New Document"
+ IDM_FILE_OPEN "Open Existing Document"
+ IDM_FILE_SAVE "Save the Document"
+ IDM_FILE_SAVEAS "Save the Document with a new name"
+ IDM_FILE_PRINT "Print the Document"
+ IDM_FILE_EXIT "End the Program"
+END
+
+STRINGTABLE
+BEGIN
+ IDM_EDIT_UNDO "Undo the last action"
+ IDM_EDIT_REDO "Redo the previously undone action"
+ IDM_EDIT_CUT "Cut the Selected Contents to the Clipboard"
+ IDM_EDIT_COPY "Copy the Selected Contents to the Clipboard"
+ IDM_EDIT_PASTE "Paste the Clipboard Contents to the Document"
+ IDM_EDIT_DELETE "Erase the selected Contents"
+ IDW_VIEW_TOOLBAR "Show or hide the tool bar"
+ IDW_VIEW_STATUSBAR "Show or hide the status bar"
+END
+
+STRINGTABLE
+BEGIN
+ IDM_HELP_ABOUT "Display Information about this program"
+END
+
+STRINGTABLE
+BEGIN
+ IDW_FIRSTCHILD "Activate this window"
+ IDW_CHILD2 "Activate this window"
+ IDW_CHILD3 "Activate this window"
+ IDW_CHILD4 "Activate this window"
+ IDW_CHILD5 "Activate this window"
+ IDW_CHILD6 "Activate this window"
+ IDW_CHILD7 "Activate this window"
+ IDW_CHILD8 "Activate this window"
+ IDW_CHILD9 "Activate this window"
+ IDW_CHILD10 "Select a window"
+END
+
+STRINGTABLE
+BEGIN
+ IDM_FILE_NEWVIEW "Create View MDI Child"
+ IDM_FILE_CLOSE "Close MDI Window"
+ IDM_COLOR_BLACK "Use Black Printing"
+ IDM_COLOR_RED "Use Red Printing"
+ IDM_COLOR_GREEN "Use Green Printing"
+ IDM_COLOR_BLUE "Use Blue Printing"
+ IDM_COLOR_WHITE "Use White Printing"
+ IDW_WINDOW_CASCADE "Cascade MDI Windows"
+ IDW_WINDOW_TILE "Tile MDI Windows"
+ IDW_WINDOW_ARRANGE "Arrange Icons"
+ IDW_WINDOW_CLOSEALL "Close All MDI Windows"
+END
+
+STRINGTABLE
+BEGIN
+ SC_CLOSE "Close the Window"
+ SC_MAXIMIZE "Maximize the Window"
+ SC_MINIMIZE "Minimize the WIndow"
+ SC_MOVE "Move the Window"
+ SC_NEXTWINDOW "Select Next Window"
+ SC_PREVWINDOW "Select Previous Window"
+ SC_RESTORE "Restore the Window"
+ SC_SIZE "Resize the Window"
+END
+
+STRINGTABLE
+BEGIN
+ IDW_FILE_MRU_FILE1 "Open this document"
+ IDW_FILE_MRU_FILE2 "Open this document"
+ IDW_FILE_MRU_FILE3 "Open this document"
+ IDW_FILE_MRU_FILE4 "Open this document"
+ IDW_FILE_MRU_FILE5 "Open this document"
+ IDW_FILE_MRU_FILE6 "Open this document"
+ IDW_FILE_MRU_FILE7 "Open this document"
+ IDW_FILE_MRU_FILE8 "Open this document"
+ IDW_FILE_MRU_FILE9 "Open this document"
+ IDW_FILE_MRU_FILE10 "Open this document"
+ IDW_FILE_MRU_FILE11 "Open this document"
+ IDW_FILE_MRU_FILE12 "Open this document"
+ IDW_FILE_MRU_FILE13 "Open this document"
+ IDW_FILE_MRU_FILE14 "Open this document"
+ IDW_FILE_MRU_FILE15 "Open this document"
+ IDW_FILE_MRU_FILE16 "Open this document"
+END
+
+
diff --git a/mmc_updater/depends/win32cpp/dialog.h b/mmc_updater/depends/win32cpp/dialog.h
new file mode 100644
index 00000000..e5123304
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/dialog.h
@@ -0,0 +1,876 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// dialog.h
+// Declaration of the CDialog class
+
+// CDialog adds support for dialogs to Win32++. Dialogs are specialised
+// windows which are a parent window for common controls. Common controls
+// are special window types such as buttons, edit controls, tree views,
+// list views, static text etc.
+
+// The layout of a dialog is typically defined in a resource script file
+// (often Resource.rc). While this script file can be constructed manually,
+// it is often created using a resource editor. If your compiler doesn't
+// include a resource editor, you might find ResEdit useful. It is a free
+// resource editor available for download at:
+// http://www.resedit.net/
+
+// CDialog supports modal and modeless dialogs. It also supports the creation
+// of dialogs defined in a resource script file, as well as those defined in
+// a dialog template.
+
+// Use the Dialog generic program as the starting point for your own dialog
+// applications.
+// The DlgSubclass sample demonstrates how to use subclassing to customise
+// the behaviour of common controls in a dialog.
+
+
+#ifndef _WIN32XX_DIALOG_H_
+#define _WIN32XX_DIALOG_H_
+
+#include "wincore.h"
+
+#ifndef SWP_NOCOPYBITS
+ #define SWP_NOCOPYBITS 0x0100
+#endif
+
+namespace Win32xx
+{
+
+ class CDialog : public CWnd
+ {
+ public:
+ CDialog(UINT nResID, CWnd* pParent = NULL);
+ CDialog(LPCTSTR lpszResName, CWnd* pParent = NULL);
+ CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent = NULL);
+ virtual ~CDialog();
+
+ // You probably won't need to override these functions
+ virtual void AttachItem(int nID, CWnd& Wnd);
+ virtual HWND Create(CWnd* pParent = NULL);
+ virtual INT_PTR DoModal();
+ virtual HWND DoModeless();
+ virtual void SetDlgParent(CWnd* pParent);
+ BOOL IsModal() const { return m_IsModal; }
+ BOOL IsIndirect() const { return (NULL != m_lpTemplate); }
+
+ protected:
+ // These are the functions you might wish to override
+ virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual INT_PTR DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void EndDialog(INT_PTR nResult);
+ virtual void OnCancel();
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ // Can't override these functions
+ static INT_PTR CALLBACK StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ #ifndef _WIN32_WCE
+ static LRESULT CALLBACK StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam);
+ #endif
+
+ private:
+ CDialog(const CDialog&); // Disable copy construction
+ CDialog& operator = (const CDialog&); // Disable assignment operator
+
+ BOOL m_IsModal; // a flag for modal dialogs
+ LPCTSTR m_lpszResName; // the resource name for the dialog
+ LPCDLGTEMPLATE m_lpTemplate; // the dialog template for indirect dialogs
+ HWND m_hParent; // handle to the dialogs's parent window
+ };
+
+
+#ifndef _WIN32_WCE
+
+ //////////////////////////////////////
+ // Declaration of the CResizer class
+ //
+ // The CResizer class can be used to rearrange a dialog's child
+ // windows when the dialog is resized.
+
+ // To use CResizer, follow the following steps:
+ // 1) Use Initialize to specify the dialog's CWnd, and min and max size.
+ // 3) Use AddChild for each child window
+ // 4) Call HandleMessage from within DialogProc.
+ //
+
+ // Resize Dialog Styles
+#define RD_STRETCH_WIDTH 0x0001 // The item has a variable width
+#define RD_STRETCH_HEIGHT 0x0002 // The item has a variable height
+
+ // Resize Dialog alignments
+ enum Alignment { topleft, topright, bottomleft, bottomright };
+
+ class CResizer
+ {
+ public:
+ CResizer() : m_pParent(0), m_xScrollPos(0), m_yScrollPos(0) {}
+ virtual ~CResizer() {}
+
+ virtual void AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle);
+ virtual void AddChild(HWND hWnd, Alignment corner, DWORD dwStyle);
+ virtual void HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void Initialize(CWnd* pParent, RECT rcMin, RECT rcMax = CRect(0,0,0,0));
+ virtual void OnHScroll(WPARAM wParam, LPARAM lParam);
+ virtual void OnVScroll(WPARAM wParam, LPARAM lParam);
+ virtual void RecalcLayout();
+ CRect GetMinRect() const { return m_rcMin; }
+ CRect GetMaxRect() const { return m_rcMax; }
+
+ struct ResizeData
+ {
+ CRect rcInit;
+ CRect rcOld;
+ Alignment corner;
+ BOOL bFixedWidth;
+ BOOL bFixedHeight;
+ HWND hWnd;
+ };
+
+ private:
+ CWnd* m_pParent;
+ std::vector<ResizeData> m_vResizeData;
+
+ CRect m_rcInit;
+ CRect m_rcMin;
+ CRect m_rcMax;
+
+ int m_xScrollPos;
+ int m_yScrollPos;
+ };
+
+#endif
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+ ////////////////////////////////////
+ // Definitions for the CDialog class
+ //
+ inline CDialog::CDialog(LPCTSTR lpszResName, CWnd* pParent/* = NULL*/)
+ : m_IsModal(TRUE), m_lpszResName(lpszResName), m_lpTemplate(NULL)
+ {
+ m_hParent = pParent? pParent->GetHwnd() : NULL;
+ ::InitCommonControls();
+ }
+
+ inline CDialog::CDialog(UINT nResID, CWnd* pParent/* = NULL*/)
+ : m_IsModal(TRUE), m_lpszResName(MAKEINTRESOURCE (nResID)), m_lpTemplate(NULL)
+ {
+ m_hParent = pParent? pParent->GetHwnd() : NULL;
+ ::InitCommonControls();
+ }
+
+ //For indirect dialogs - created from a dialog box template in memory.
+ inline CDialog::CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent/* = NULL*/)
+ : m_IsModal(TRUE), m_lpszResName(NULL), m_lpTemplate(lpTemplate)
+ {
+ m_hParent = pParent? pParent->GetHwnd() : NULL;
+ ::InitCommonControls();
+ }
+
+ inline CDialog::~CDialog()
+ {
+ if (m_hWnd != NULL)
+ {
+ if (IsModal())
+ ::EndDialog(m_hWnd, 0);
+ else
+ Destroy();
+ }
+ }
+
+ inline void CDialog::AttachItem(int nID, CWnd& Wnd)
+ // Attach a dialog item to a CWnd
+ {
+ Wnd.AttachDlgItem(nID, this);
+ }
+
+ inline HWND CDialog::Create(CWnd* pParent /* = NULL */)
+ {
+ // Allow a dialog to be used as a child window
+
+ assert(GetApp());
+ SetDlgParent(pParent);
+ return DoModeless();
+ }
+
+ inline INT_PTR CDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // Override this function in your class derrived from CDialog if you wish to handle messages
+ // A typical function might look like this:
+
+ // switch (uMsg)
+ // {
+ // case MESSAGE1: // Some Windows API message
+ // OnMessage1(); // A user defined function
+ // break; // Also do default processing
+ // case MESSAGE2:
+ // OnMessage2();
+ // return x; // Don't do default processing, but instead return
+ // // a value recommended by the Windows API documentation
+ // }
+
+ // Always pass unhandled messages on to DialogProcDefault
+ return DialogProcDefault(uMsg, wParam, lParam);
+ }
+
+ inline INT_PTR CDialog::DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // All DialogProc functions should pass unhandled messages to this function
+ {
+ LRESULT lr = 0;
+
+ switch (uMsg)
+ {
+ case UWM_CLEANUPTEMPS:
+ {
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ pTLSData->vTmpWnds.clear();
+ }
+ break;
+ case WM_INITDIALOG:
+ {
+ // Center the dialog
+ CenterWindow();
+ }
+ return OnInitDialog();
+ case WM_COMMAND:
+ switch (LOWORD (wParam))
+ {
+ case IDOK:
+ OnOK();
+ return TRUE;
+ case IDCANCEL:
+ OnCancel();
+ return TRUE;
+ default:
+ {
+ // Refelect this message if it's from a control
+ CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam);
+ if (pWnd != NULL)
+ lr = pWnd->OnCommand(wParam, lParam);
+
+ // Handle user commands
+ if (!lr)
+ lr = OnCommand(wParam, lParam);
+
+ if (lr) return 0L;
+ }
+ break; // Some commands require default processing
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ // Do Notification reflection if it came from a CWnd object
+ HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom;
+ CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom);
+
+ if (pWndFrom != NULL)
+ lr = pWndFrom->OnNotifyReflect(wParam, lParam);
+ else
+ {
+ // Some controls (eg ListView) have child windows.
+ // Reflect those notifications too.
+ CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom));
+ if (pWndFromParent != NULL)
+ lr = pWndFromParent->OnNotifyReflect(wParam, lParam);
+ }
+
+ // Handle user notifications
+ if (!lr) lr = OnNotify(wParam, lParam);
+
+ // Set the return code for notifications
+ if (IsWindow())
+ SetWindowLongPtr(DWLP_MSGRESULT, (LONG_PTR)lr);
+
+ return (BOOL)lr;
+ }
+
+ case WM_PAINT:
+ {
+ if (::GetUpdateRect(m_hWnd, NULL, FALSE))
+ {
+ CPaintDC dc(this);
+ OnDraw(&dc);
+ }
+ else
+ // RedrawWindow can require repainting without an update rect
+ {
+ CClientDC dc(this);
+ OnDraw(&dc);
+ }
+
+ break;
+ }
+
+ case WM_ERASEBKGND:
+ {
+ CDC dc((HDC)wParam);
+ BOOL bResult = OnEraseBkgnd(&dc);
+ dc.Detach();
+ if (bResult) return TRUE;
+ }
+ break;
+
+ // A set of messages to be reflected back to the control that generated them
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORSCROLLBAR:
+ case WM_CTLCOLORSTATIC:
+ case WM_DRAWITEM:
+ case WM_MEASUREITEM:
+ case WM_DELETEITEM:
+ case WM_COMPAREITEM:
+ case WM_CHARTOITEM:
+ case WM_VKEYTOITEM:
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ case WM_PARENTNOTIFY:
+ return MessageReflect(m_hWnd, uMsg, wParam, lParam);
+
+ } // switch(uMsg)
+ return FALSE;
+
+ } // INT_PTR CALLBACK CDialog::DialogProc(...)
+
+ inline INT_PTR CDialog::DoModal()
+ {
+ // Create a modal dialog
+ // A modal dialog box must be closed by the user before the application continues
+
+ assert( GetApp() ); // Test if Win32++ has been started
+ assert(!::IsWindow(m_hWnd)); // Only one window per CWnd instance allowed
+
+ INT_PTR nResult = 0;
+
+ try
+ {
+ m_IsModal=TRUE;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+
+ #ifndef _WIN32_WCE
+ BOOL IsHookedHere = FALSE;
+ if (NULL == pTLSData->hHook )
+ {
+ pTLSData->hHook = ::SetWindowsHookEx(WH_MSGFILTER, (HOOKPROC)StaticMsgHook, NULL, ::GetCurrentThreadId());
+ IsHookedHere = TRUE;
+ }
+ #endif
+
+ HINSTANCE hInstance = GetApp()->GetInstanceHandle();
+ pTLSData->pCWnd = this;
+
+ // Create a modal dialog
+ if (IsIndirect())
+ nResult = ::DialogBoxIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc);
+ else
+ {
+ if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG))
+ hInstance = GetApp()->GetResourceHandle();
+ nResult = ::DialogBox(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc);
+ }
+
+ // Tidy up
+ m_hWnd = NULL;
+ pTLSData->pCWnd = NULL;
+ GetApp()->CleanupTemps();
+
+ #ifndef _WIN32_WCE
+ if (IsHookedHere)
+ {
+ ::UnhookWindowsHookEx(pTLSData->hHook);
+ pTLSData->hHook = NULL;
+ }
+ #endif
+
+ if (nResult == -1)
+ throw CWinException(_T("Failed to create modal dialog box"));
+
+ }
+
+ catch (const CWinException &e)
+ {
+ TRACE(_T("\n*** Failed to create dialog ***\n"));
+ e.what(); // Display the last error message.
+
+ // eat the exception (don't rethrow)
+ }
+
+ return nResult;
+ }
+
+ inline HWND CDialog::DoModeless()
+ {
+ assert( GetApp() ); // Test if Win32++ has been started
+ assert(!::IsWindow(m_hWnd)); // Only one window per CWnd instance allowed
+
+ try
+ {
+ m_IsModal=FALSE;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+
+ // Store the CWnd pointer in Thread Local Storage
+ pTLSData->pCWnd = this;
+
+ HINSTANCE hInstance = GetApp()->GetInstanceHandle();
+
+ // Create a modeless dialog
+ if (IsIndirect())
+ m_hWnd = ::CreateDialogIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc);
+ else
+ {
+ if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG))
+ hInstance = GetApp()->GetResourceHandle();
+
+ m_hWnd = ::CreateDialog(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc);
+ }
+
+ // Tidy up
+ pTLSData->pCWnd = NULL;
+
+ // Now handle dialog creation failure
+ if (!m_hWnd)
+ throw CWinException(_T("Failed to create dialog"));
+ }
+
+ catch (const CWinException &e)
+ {
+ TRACE(_T("\n*** Failed to create dialog ***\n"));
+ e.what(); // Display the last error message.
+
+ // eat the exception (don't rethrow)
+ }
+
+ return m_hWnd;
+ }
+
+ inline void CDialog::EndDialog(INT_PTR nResult)
+ {
+ assert(::IsWindow(m_hWnd));
+
+ if (IsModal())
+ ::EndDialog(m_hWnd, nResult);
+ else
+ Destroy();
+
+ m_hWnd = NULL;
+ }
+
+ inline void CDialog::OnCancel()
+ {
+ // Override to customize OnCancel behaviour
+ EndDialog(IDCANCEL);
+ }
+
+ inline BOOL CDialog::OnInitDialog()
+ {
+ // Called when the dialog is initialized
+ // Override it in your derived class to automatically perform tasks
+ // The return value is used by WM_INITDIALOG
+
+ return TRUE;
+ }
+
+ inline void CDialog::OnOK()
+ {
+ // Override to customize OnOK behaviour
+ EndDialog(IDOK);
+ }
+
+ inline BOOL CDialog::PreTranslateMessage(MSG* pMsg)
+ {
+ // allow the dialog to translate keyboard input
+ if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))
+ {
+ // Process dialog keystrokes for modeless dialogs
+ if (!IsModal())
+ {
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ if (NULL == pTLSData->hHook)
+ {
+ if (IsDialogMessage(pMsg))
+ return TRUE;
+ }
+ else
+ {
+ // A modal message loop is running so we can't do IsDialogMessage.
+ // Avoid having modal dialogs create other windows, because those
+ // windows will then use the modal dialog's special message loop.
+ }
+ }
+ }
+
+ return FALSE;
+ }
+
+ inline void CDialog::SetDlgParent(CWnd* pParent)
+ // Allows the parent of the dialog to be set before the dialog is created
+ {
+ m_hParent = pParent? pParent->GetHwnd() : NULL;
+ }
+
+ inline INT_PTR CALLBACK CDialog::StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // Find the CWnd pointer mapped to this HWND
+ CDialog* w = (CDialog*)GetApp()->GetCWndFromMap(hWnd);
+ if (0 == w)
+ {
+ // The HWND wasn't in the map, so add it now
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+
+ // Retrieve pointer to CWnd object from Thread Local Storage TLS
+ w = (CDialog*)pTLSData->pCWnd;
+ assert(w);
+ pTLSData->pCWnd = NULL;
+
+ // Store the Window pointer into the HWND map
+ w->m_hWnd = hWnd;
+ w->AddToMap();
+ }
+
+ return w->DialogProc(uMsg, wParam, lParam);
+
+ } // INT_PTR CALLBACK CDialog::StaticDialogProc(...)
+
+#ifndef _WIN32_WCE
+ inline LRESULT CALLBACK CDialog::StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam)
+ {
+ // Used by Modal Dialogs to PreTranslate Messages
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+
+ if (nCode == MSGF_DIALOGBOX)
+ {
+ MSG* lpMsg = (MSG*) lParam;
+
+ // only pre-translate keyboard events
+ if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST))
+ {
+ for (HWND hWnd = lpMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
+ {
+ CDialog* pDialog = (CDialog*)GetApp()->GetCWndFromMap(hWnd);
+ if (pDialog && (lstrcmp(pDialog->GetClassName(), _T("#32770")) == 0)) // only for dialogs
+ {
+ pDialog->PreTranslateMessage(lpMsg);
+ break;
+ }
+ }
+ }
+ }
+
+ return ::CallNextHookEx(pTLSData->hHook, nCode, wParam, lParam);
+ }
+#endif
+
+
+
+#ifndef _WIN32_WCE
+
+ /////////////////////////////////////
+ // Definitions for the CResizer class
+ //
+
+ void inline CResizer::AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle)
+ // Adds a child window (usually a dialog control) to the set of windows managed by
+ // the Resizer.
+ //
+ // The alignment corner should be set to the closest corner of the dialog. Allowed
+ // values are topleft, topright, bottomleft, and bottomright.
+ // Set bFixedWidth to TRUE if the width should be fixed instead of variable.
+ // Set bFixedHeight to TRUE if the height should be fixed instead of variable.
+ {
+ ResizeData rd;
+ rd.corner = corner;
+ rd.bFixedWidth = !(dwStyle & RD_STRETCH_WIDTH);
+ rd.bFixedHeight = !(dwStyle & RD_STRETCH_HEIGHT);
+ CRect rcInit = pWnd->GetWindowRect();
+ m_pParent->ScreenToClient(rcInit);
+ rd.rcInit = rcInit;
+ rd.hWnd = pWnd->GetHwnd();
+
+ m_vResizeData.insert(m_vResizeData.begin(), rd);
+ }
+
+ void inline CResizer::AddChild(HWND hWnd, Alignment corner, DWORD dwStyle)
+ // Adds a child window (usually a dialog control) to the set of windows managed by
+ // the Resizer.
+ {
+ AddChild(FromHandle(hWnd), corner, dwStyle);
+ }
+
+ inline void CResizer::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ RecalcLayout();
+ break;
+
+ case WM_HSCROLL:
+ if (0 == lParam)
+ OnHScroll(wParam, lParam);
+ break;
+
+ case WM_VSCROLL:
+ if (0 == lParam)
+ OnVScroll(wParam, lParam);
+ break;
+ }
+ }
+
+ void inline CResizer::Initialize(CWnd* pParent, RECT rcMin, RECT rcMax)
+ // Sets up the Resizer by specifying the parent window (usually a dialog),
+ // and the minimum and maximum allowed rectangle sizes.
+ {
+ assert (NULL != pParent);
+
+ m_pParent = pParent;
+ m_rcInit = pParent->GetClientRect();
+ m_rcMin = rcMin;
+ m_rcMax = rcMax;
+
+ // Add scroll bar support to the parent window
+ DWORD dwStyle = (DWORD)m_pParent->GetClassLongPtr(GCL_STYLE);
+ dwStyle |= WS_HSCROLL | WS_VSCROLL;
+ m_pParent->SetClassLongPtr(GCL_STYLE, dwStyle);
+ }
+
+ void inline CResizer::OnHScroll(WPARAM wParam, LPARAM /*lParam*/)
+ {
+ int xNewPos;
+
+ switch (LOWORD(wParam))
+ {
+ case SB_PAGEUP: // User clicked the scroll bar shaft left of the scroll box.
+ xNewPos = m_xScrollPos - 50;
+ break;
+
+ case SB_PAGEDOWN: // User clicked the scroll bar shaft right of the scroll box.
+ xNewPos = m_xScrollPos + 50;
+ break;
+
+ case SB_LINEUP: // User clicked the left arrow.
+ xNewPos = m_xScrollPos - 5;
+ break;
+
+ case SB_LINEDOWN: // User clicked the right arrow.
+ xNewPos = m_xScrollPos + 5;
+ break;
+
+ case SB_THUMBPOSITION: // User dragged the scroll box.
+ xNewPos = HIWORD(wParam);
+ break;
+
+ case SB_THUMBTRACK: // User dragging the scroll box.
+ xNewPos = HIWORD(wParam);
+ break;
+
+ default:
+ xNewPos = m_xScrollPos;
+ }
+
+ // Scroll the window.
+ xNewPos = MAX(0, xNewPos);
+ xNewPos = MIN( xNewPos, GetMinRect().Width() - m_pParent->GetClientRect().Width() );
+ int xDelta = xNewPos - m_xScrollPos;
+ m_xScrollPos = xNewPos;
+ m_pParent->ScrollWindow(-xDelta, 0, NULL, NULL);
+
+ // Reset the scroll bar.
+ SCROLLINFO si = {0};
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_POS;
+ si.nPos = m_xScrollPos;
+ m_pParent->SetScrollInfo(SB_HORZ, si, TRUE);
+ }
+
+ void inline CResizer::OnVScroll(WPARAM wParam, LPARAM /*lParam*/)
+ {
+ int yNewPos;
+
+ switch (LOWORD(wParam))
+ {
+ case SB_PAGEUP: // User clicked the scroll bar shaft above the scroll box.
+ yNewPos = m_yScrollPos - 50;
+ break;
+
+ case SB_PAGEDOWN: // User clicked the scroll bar shaft below the scroll box.
+ yNewPos = m_yScrollPos + 50;
+ break;
+
+ case SB_LINEUP: // User clicked the top arrow.
+ yNewPos = m_yScrollPos - 5;
+ break;
+
+ case SB_LINEDOWN: // User clicked the bottom arrow.
+ yNewPos = m_yScrollPos + 5;
+ break;
+
+ case SB_THUMBPOSITION: // User dragged the scroll box.
+ yNewPos = HIWORD(wParam);
+ break;
+
+ case SB_THUMBTRACK: // User dragging the scroll box.
+ yNewPos = HIWORD(wParam);
+ break;
+
+ default:
+ yNewPos = m_yScrollPos;
+ }
+
+ // Scroll the window.
+ yNewPos = MAX(0, yNewPos);
+ yNewPos = MIN( yNewPos, GetMinRect().Height() - m_pParent->GetClientRect().Height() );
+ int yDelta = yNewPos - m_yScrollPos;
+ m_yScrollPos = yNewPos;
+ m_pParent->ScrollWindow(0, -yDelta, NULL, NULL);
+
+ // Reset the scroll bar.
+ SCROLLINFO si = {0};
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_POS;
+ si.nPos = m_yScrollPos;
+ m_pParent->SetScrollInfo(SB_VERT, si, TRUE);
+ }
+
+ void inline CResizer::RecalcLayout()
+ // Repositions the child windows. Call this function when handling
+ // the WM_SIZE message in the parent window.
+ {
+ assert (m_rcInit.Width() > 0 && m_rcInit.Height() > 0);
+ assert (NULL != m_pParent);
+
+ CRect rcCurrent = m_pParent->GetClientRect();
+
+ // Adjust the scrolling if required
+ m_xScrollPos = MIN(m_xScrollPos, MAX(0, m_rcMin.Width() - rcCurrent.Width() ) );
+ m_yScrollPos = MIN(m_yScrollPos, MAX(0, m_rcMin.Height() - rcCurrent.Height()) );
+ SCROLLINFO si = {0};
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
+ si.nMax = m_rcMin.Width();
+ si.nPage = rcCurrent.Width();
+ si.nPos = m_xScrollPos;
+ m_pParent->SetScrollInfo(SB_HORZ, si, TRUE);
+ si.nMax = m_rcMin.Height();
+ si.nPage = rcCurrent.Height();
+ si.nPos = m_yScrollPos;
+ m_pParent->SetScrollInfo(SB_VERT, si, TRUE);
+
+ rcCurrent.right = MAX( rcCurrent.Width(), m_rcMin.Width() );
+ rcCurrent.bottom = MAX( rcCurrent.Height(), m_rcMin.Height() );
+ if (!m_rcMax.IsRectEmpty())
+ {
+ rcCurrent.right = MIN( rcCurrent.Width(), m_rcMax.Width() );
+ rcCurrent.bottom = MIN( rcCurrent.Height(), m_rcMax.Height() );
+ }
+
+ // Declare an iterator to step through the vector
+ std::vector<ResizeData>::iterator iter;
+
+ for (iter = m_vResizeData.begin(); iter < m_vResizeData.end(); ++iter)
+ {
+ int left = 0;
+ int top = 0;
+ int width = 0;
+ int height = 0;
+
+ // Calculate the new size and position of the child window
+ switch( (*iter).corner )
+ {
+ case topleft:
+ width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width();
+ height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();
+ left = (*iter).rcInit.left;
+ top = (*iter).rcInit.top;
+ break;
+ case topright:
+ width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width();
+ height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();
+ left = (*iter).rcInit.right - width - m_rcInit.Width() + rcCurrent.Width();
+ top = (*iter).rcInit.top;
+ break;
+ case bottomleft:
+ width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width();
+ height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();
+ left = (*iter).rcInit.left;
+ top = (*iter).rcInit.bottom - height - m_rcInit.Height() + rcCurrent.Height();
+ break;
+ case bottomright:
+ width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width();
+ height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();
+ left = (*iter).rcInit.right - width - m_rcInit.Width() + rcCurrent.Width();
+ top = (*iter).rcInit.bottom - height - m_rcInit.Height() + rcCurrent.Height();
+ break;
+ }
+
+ // Position the child window.
+ CRect rc(left - m_xScrollPos, top - m_yScrollPos, left + width - m_xScrollPos, top + height - m_yScrollPos);
+ if ( rc != (*iter).rcOld)
+ {
+ CWnd* pWnd = FromHandle((*iter).hWnd);
+ CWnd *pWndPrev = pWnd->GetWindow(GW_HWNDPREV); // Trick to maintain the original tab order.
+ HWND hWnd = pWndPrev ? pWndPrev->GetHwnd():NULL;
+ pWnd->SetWindowPos(hWnd, rc, SWP_NOCOPYBITS);
+ (*iter).rcOld = rc;
+ }
+ }
+ }
+
+#endif // #ifndef _WIN32_WCE
+
+} // namespace Win32xx
+
+
+
+#endif // _WIN32XX_DIALOG_H_
+
diff --git a/mmc_updater/depends/win32cpp/docking.h b/mmc_updater/depends/win32cpp/docking.h
new file mode 100644
index 00000000..9e7c4486
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/docking.h
@@ -0,0 +1,4214 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////
+// docking.h
+// Declaration of the CDocker class
+
+#ifndef _WIN32XX_DOCKING_H_
+#define _WIN32XX_DOCKING_H_
+
+
+#include "wincore.h"
+#include "gdi.h"
+#include "toolbar.h"
+#include "tab.h"
+#include "frame.h"
+#include "default_resource.h"
+
+
+// Docking Styles
+#define DS_DOCKED_LEFT 0x0001 // Dock the child left
+#define DS_DOCKED_RIGHT 0x0002 // Dock the child right
+#define DS_DOCKED_TOP 0x0004 // Dock the child top
+#define DS_DOCKED_BOTTOM 0x0008 // Dock the child bottom
+#define DS_NO_DOCKCHILD_LEFT 0x0010 // Prevent a child docking left
+#define DS_NO_DOCKCHILD_RIGHT 0x0020 // Prevent a child docking right
+#define DS_NO_DOCKCHILD_TOP 0x0040 // Prevent a child docking at the top
+#define DS_NO_DOCKCHILD_BOTTOM 0x0080 // Prevent a child docking at the bottom
+#define DS_NO_RESIZE 0x0100 // Prevent resizing
+#define DS_NO_CAPTION 0x0200 // Prevent display of caption when docked
+#define DS_NO_CLOSE 0x0400 // Prevent closing of a docker while docked
+#define DS_NO_UNDOCK 0x0800 // Prevent undocking and dock closing
+#define DS_CLIENTEDGE 0x1000 // Has a 3D border when docked
+#define DS_FIXED_RESIZE 0x2000 // Perfomed a fixed resize instead of a proportional resize on dock children
+#define DS_DOCKED_CONTAINER 0x4000 // Dock a container within a container
+#define DS_DOCKED_LEFTMOST 0x10000 // Leftmost outer docking
+#define DS_DOCKED_RIGHTMOST 0x20000 // Rightmost outer docking
+#define DS_DOCKED_TOPMOST 0x40000 // Topmost outer docking
+#define DS_DOCKED_BOTTOMMOST 0x80000 // Bottommost outer docking
+
+// Required for Dev-C++
+#ifndef TME_NONCLIENT
+ #define TME_NONCLIENT 0x00000010
+#endif
+#ifndef TME_LEAVE
+ #define TME_LEAVE 0x000000002
+#endif
+#ifndef WM_NCMOUSELEAVE
+ #define WM_NCMOUSELEAVE 0x000002A2
+#endif
+
+namespace Win32xx
+{
+ // Class declarations
+ class CDockContainer;
+ class CDocker;
+
+ typedef Shared_Ptr<CDocker> DockPtr;
+
+ struct ContainerInfo
+ {
+ TCHAR szTitle[MAX_MENU_STRING];
+ int iImage;
+ CDockContainer* pContainer;
+ };
+
+ ///////////////////////////////////////
+ // Declaration of the CDockContainer class
+ // A CDockContainer is a CTab window. A CTab has a view window, and optionally a toolbar control.
+ // A top level CDockContainer can contain other CDockContainers. The view for each container
+ // (including the top level container) along with possibly its toolbar, is displayed
+ // within the container parent's view page.
+ class CDockContainer : public CTab
+ {
+ public:
+
+ // Nested class. This is the Wnd for the window displayed over the client area
+ // of the tab control. The toolbar and view window are child windows of the
+ // viewpage window. Only the ViewPage of the parent CDockContainer is displayed. It's
+ // contents are updated with the view window of the relevant container whenever
+ // a different tab is selected.
+ class CViewPage : public CWnd
+ {
+
+ public:
+ CViewPage() : m_pView(NULL), m_pTab(NULL) {}
+ virtual ~CViewPage() {}
+ virtual CToolBar& GetToolBar() const {return (CToolBar&)m_ToolBar;}
+ virtual CWnd* GetView() const {return m_pView;}
+ virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual void OnCreate();
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual void RecalcLayout();
+ virtual void SetView(CWnd& wndView);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ CWnd* GetTabCtrl() const { return m_pTab;}
+
+ private:
+ CToolBar m_ToolBar;
+ tString m_tsTooltip;
+ CWnd* m_pView;
+ CWnd* m_pTab;
+ };
+
+ public:
+ CDockContainer();
+ virtual ~CDockContainer();
+ virtual void AddContainer(CDockContainer* pContainer);
+ virtual void AddToolBarButton(UINT nID, BOOL bEnabled = TRUE);
+ virtual CDockContainer* GetContainerFromIndex(UINT nPage);
+ virtual CDockContainer* GetContainerFromView(CWnd* pView) const;
+ virtual int GetContainerIndex(CDockContainer* pContainer);
+ virtual SIZE GetMaxTabTextSize();
+ virtual CViewPage& GetViewPage() const { return (CViewPage&)m_ViewPage; }
+ virtual void RecalcLayout();
+ virtual void RemoveContainer(CDockContainer* pWnd);
+ virtual void SelectPage(int nPage);
+ virtual void SetTabSize();
+ virtual void SetupToolBar();
+
+ // Attributes
+ CDockContainer* GetActiveContainer() const {return GetContainerFromView(GetActiveView());}
+ CWnd* GetActiveView() const;
+ std::vector<ContainerInfo>& GetAllContainers() const {return m_pContainerParent->m_vContainerInfo;}
+ CDockContainer* GetContainerParent() const { return m_pContainerParent; }
+ CString& GetDockCaption() const { return (CString&)m_csCaption; }
+ HICON GetTabIcon() const { return m_hTabIcon; }
+ LPCTSTR GetTabText() const { return m_tsTabText.c_str(); }
+ virtual CToolBar& GetToolBar() const { return GetViewPage().GetToolBar(); }
+ CWnd* GetView() const { return GetViewPage().GetView(); }
+ void SetActiveContainer(CDockContainer* pContainer);
+ void SetDockCaption(LPCTSTR szCaption) { m_csCaption = szCaption; }
+ void SetTabIcon(HICON hTabIcon) { m_hTabIcon = hTabIcon; }
+ void SetTabIcon(UINT nID_Icon);
+ void SetTabIcon(int i, HICON hIcon) { CTab::SetTabIcon(i, hIcon); }
+ void SetTabText(LPCTSTR szText) { m_tsTabText = szText; }
+ void SetTabText(UINT nTab, LPCTSTR szText);
+ void SetView(CWnd& Wnd);
+
+ protected:
+ virtual void OnCreate();
+ virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseLeave(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam);
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ std::vector<ContainerInfo> m_vContainerInfo;
+ tString m_tsTabText;
+ CString m_csCaption;
+ CViewPage m_ViewPage;
+ int m_iCurrentPage;
+ CDockContainer* m_pContainerParent;
+ HICON m_hTabIcon;
+ int m_nTabPressed;
+
+ };
+
+ typedef struct DRAGPOS
+ {
+ NMHDR hdr;
+ POINT ptPos;
+ UINT DockZone;
+ } *LPDRAGPOS;
+
+
+ /////////////////////////////////////////
+ // Declaration of the CDocker class
+ // A CDocker window allows other CDocker windows to be "docked" inside it.
+ // A CDocker can dock on the top, left, right or bottom side of a parent CDocker.
+ // There is no theoretical limit to the number of CDockers within CDockers.
+ class CDocker : public CWnd
+ {
+ public:
+ // A nested class for the splitter bar that seperates the docked panes.
+ class CDockBar : public CWnd
+ {
+ public:
+ CDockBar();
+ virtual ~CDockBar();
+ virtual void OnDraw(CDC* pDC);
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void PreRegisterClass(WNDCLASS& wc);
+ virtual void SendNotify(UINT nMessageID);
+ virtual void SetColor(COLORREF color);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ CDocker* GetDock() {return m_pDock;}
+ int GetWidth() {return m_DockBarWidth;}
+ void SetDock(CDocker* pDock) {m_pDock = pDock;}
+ void SetWidth(int nWidth) {m_DockBarWidth = nWidth;}
+
+ private:
+ CDockBar(const CDockBar&); // Disable copy construction
+ CDockBar& operator = (const CDockBar&); // Disable assignment operator
+
+ CDocker* m_pDock;
+ DRAGPOS m_DragPos;
+ CBrush m_brBackground;
+ int m_DockBarWidth;
+ };
+
+ // A nested class for the window inside a CDocker which includes all of this docked client.
+ // It's the remaining part of the CDocker that doesn't belong to the CDocker's children.
+ // The Docker's view window is a child window of CDockClient.
+ class CDockClient : public CWnd
+ {
+ public:
+ CDockClient();
+ virtual ~CDockClient() {}
+ virtual void Draw3DBorder(RECT& Rect);
+ virtual void DrawCaption(WPARAM wParam);
+ virtual void DrawCloseButton(CDC& DrawDC, BOOL bFocus);
+ virtual CRect GetCloseRect();
+ virtual void SendNotify(UINT nMessageID);
+
+ CString& GetCaption() const { return (CString&)m_csCaption; }
+ CWnd* GetView() const { return m_pView; }
+ void SetDock(CDocker* pDock) { m_pDock = pDock;}
+ void SetCaption(LPCTSTR szCaption) { m_csCaption = szCaption; }
+ void SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2);
+ void SetClosePressed() { m_IsClosePressed = TRUE; }
+ void SetView(CWnd& Wnd) { m_pView = &Wnd; }
+
+ protected:
+ virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseActivate(WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseMove(WPARAM wParam, LPARAM lParam);
+ virtual void OnNCCalcSize(WPARAM& wParam, LPARAM& lParam);
+ virtual LRESULT OnNCHitTest(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNCLButtonDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnNCMouseLeave(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNCMouseMove(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNCPaint(WPARAM wParam, LPARAM lParam);
+ virtual void OnWindowPosChanged(WPARAM wParam, LPARAM lParam);
+ virtual void PreRegisterClass(WNDCLASS& wc);
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CDockClient(const CDockClient&); // Disable copy construction
+ CDockClient& operator = (const CDockClient&); // Disable assignment operator
+
+ CString m_csCaption;
+ CPoint m_Oldpt;
+ CDocker* m_pDock;
+ CWnd* m_pView;
+ BOOL m_IsClosePressed;
+ BOOL m_bOldFocus;
+ BOOL m_bCaptionPressed;
+ BOOL m_IsTracking;
+ COLORREF m_Foregnd1;
+ COLORREF m_Backgnd1;
+ COLORREF m_Foregnd2;
+ COLORREF m_Backgnd2;
+ };
+
+ // This nested class is used to indicate where a window could dock by
+ // displaying a blue tinted window.
+ class CDockHint : public CWnd
+ {
+ public:
+ CDockHint();
+ virtual ~CDockHint();
+ virtual RECT CalcHintRectContainer(CDocker* pDockTarget);
+ virtual RECT CalcHintRectInner(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide);
+ virtual RECT CalcHintRectOuter(CDocker* pDockDrag, UINT uDockSide);
+ virtual void DisplayHint(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide);
+ virtual void OnDraw(CDC* pDC);
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void ShowHintWindow(CDocker* pDockTarget, CRect rcHint);
+
+ private:
+ CDockHint(const CDockHint&); // Disable copy construction
+ CDockHint& operator = (const CDockHint&); // Disable assignment operator
+
+ CBitmap m_bmBlueTint;
+ UINT m_uDockSideOld;
+ };
+
+ class CTarget : public CWnd
+ {
+ public:
+ CTarget() {}
+ virtual ~CTarget();
+ virtual void OnDraw(CDC* pDC);
+ virtual void PreCreate(CREATESTRUCT &cs);
+
+ protected:
+ CBitmap m_bmImage;
+
+ private:
+ CTarget(const CTarget&); // Disable copy construction
+ CTarget& operator = (const CTarget&); // Disable assignment operator
+ };
+
+ class CTargetCentre : public CTarget
+ {
+ public:
+ CTargetCentre();
+ virtual ~CTargetCentre();
+ virtual void OnDraw(CDC* pDC);
+ virtual void OnCreate();
+ virtual BOOL CheckTarget(LPDRAGPOS pDragPos);
+ BOOL IsOverContainer() { return m_bIsOverContainer; }
+
+ private:
+ CTargetCentre(const CTargetCentre&); // Disable copy construction
+ CTargetCentre& operator = (const CTargetCentre&); // Disable assignment operator
+
+ BOOL m_bIsOverContainer;
+ CDocker* m_pOldDockTarget;
+ };
+
+ class CTargetLeft : public CTarget
+ {
+ public:
+ CTargetLeft() {m_bmImage.LoadImage(IDW_SDLEFT,0,0,0);}
+ virtual BOOL CheckTarget(LPDRAGPOS pDragPos);
+
+ private:
+ CTargetLeft(const CTargetLeft&); // Disable copy construction
+ CTargetLeft& operator = (const CTargetLeft&); // Disable assignment operator
+ };
+
+ class CTargetTop : public CTarget
+ {
+ public:
+ CTargetTop() {m_bmImage.LoadImage(IDW_SDTOP,0,0,0);}
+ virtual BOOL CheckTarget(LPDRAGPOS pDragPos);
+ private:
+ CTargetTop(const CTargetTop&); // Disable copy construction
+ CTargetTop& operator = (const CTargetTop&); // Disable assignment operator
+ };
+
+ class CTargetRight : public CTarget
+ {
+ public:
+ CTargetRight() {m_bmImage.LoadImage(IDW_SDRIGHT,0,0,0);}
+ virtual BOOL CheckTarget(LPDRAGPOS pDragPos);
+
+ private:
+ CTargetRight(const CTargetRight&); // Disable copy construction
+ CTargetRight& operator = (const CTargetRight&); // Disable assignment operator
+ };
+
+ class CTargetBottom : public CTarget
+ {
+ public:
+ CTargetBottom() {m_bmImage.LoadImage(IDW_SDBOTTOM,0,0,0);}
+ virtual BOOL CheckTarget(LPDRAGPOS pDragPos);
+ };
+
+ friend class CTargetCentre;
+ friend class CTargetLeft;
+ friend class CTargetTop;
+ friend class CTargetRight;
+ friend class CTargetBottom;
+ friend class CDockClient;
+ friend class CDockContainer;
+
+ public:
+ // Operations
+ CDocker();
+ virtual ~CDocker();
+ virtual CDocker* AddDockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, int nDockID = 0);
+ virtual CDocker* AddUndockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, RECT rc, int nDockID = 0);
+ virtual void Close();
+ virtual void CloseAllDockers();
+ virtual void Dock(CDocker* pDocker, UINT uDockSide);
+ virtual void DockInContainer(CDocker* pDock, DWORD dwDockStyle);
+ virtual CDockContainer* GetContainer() const;
+ virtual CDocker* GetActiveDocker() const;
+ virtual CDocker* GetDockAncestor() const;
+ virtual CDocker* GetDockFromID(int n_DockID) const;
+ virtual CDocker* GetDockFromPoint(POINT pt) const;
+ virtual CDocker* GetDockFromView(CWnd* pView) const;
+ virtual CDocker* GetTopmostDocker() const;
+ virtual int GetDockSize() const;
+ virtual CTabbedMDI* GetTabbedMDI() const;
+ virtual int GetTextHeight();
+ virtual void Hide();
+ virtual BOOL LoadRegistrySettings(tString tsRegistryKeyName);
+ virtual void RecalcDockLayout();
+ virtual BOOL SaveRegistrySettings(tString tsRegistryKeyName);
+ virtual void Undock(CPoint pt, BOOL bShowUndocked = TRUE);
+ virtual void UndockContainer(CDockContainer* pContainer, CPoint pt, BOOL bShowUndocked);
+ virtual BOOL VerifyDockers();
+
+ // Attributes
+ virtual CDockBar& GetDockBar() const {return (CDockBar&)m_DockBar;}
+ virtual CDockClient& GetDockClient() const {return (CDockClient&)m_DockClient;}
+ virtual CDockHint& GetDockHint() const {return m_pDockAncestor->m_DockHint;}
+
+
+ std::vector <DockPtr> & GetAllDockers() const {return GetDockAncestor()->m_vAllDockers;}
+ int GetBarWidth() const {return GetDockBar().GetWidth();}
+ CString& GetCaption() const {return GetDockClient().GetCaption();}
+ std::vector <CDocker*> & GetDockChildren() const {return (std::vector <CDocker*> &)m_vDockChildren;}
+ int GetDockID() const {return m_nDockID;}
+ CDocker* GetDockParent() const {return m_pDockParent;}
+ DWORD GetDockStyle() const {return m_DockStyle;}
+ CWnd* GetView() const {return GetDockClient().GetView();}
+ BOOL IsChildOfDocker(CWnd* pWnd) const;
+ BOOL IsDocked() const;
+ BOOL IsDragAutoResize();
+ BOOL IsRelated(CWnd* pWnd) const;
+ BOOL IsUndocked() const;
+ void SetBarColor(COLORREF color) {GetDockBar().SetColor(color);}
+ void SetBarWidth(int nWidth) {GetDockBar().SetWidth(nWidth);}
+ void SetCaption(LPCTSTR szCaption);
+ void SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2);
+ void SetCaptionHeight(int nHeight);
+ void SetDockStyle(DWORD dwDockStyle);
+ void SetDockSize(int DockSize);
+ void SetDragAutoResize(BOOL bAutoResize);
+ void SetView(CWnd& wndView);
+
+ protected:
+ virtual CDocker* NewDockerFromID(int idDock);
+ virtual void OnActivate(WPARAM wParam, LPARAM lParam);
+ virtual void OnCaptionTimer(WPARAM wParam, LPARAM lParam);
+ virtual void OnCreate();
+ virtual void OnDestroy(WPARAM wParam, LPARAM lParam);
+ virtual void OnDockDestroyed(WPARAM wParam, LPARAM lParam);
+ virtual void OnExitSizeMove(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual void OnSetFocus(WPARAM wParam, LPARAM lParam);
+ virtual void OnSysColorChange(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnSysCommand(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnWindowPosChanging(WPARAM wParam, LPARAM lParam);
+ virtual void OnWindowPosChanged(WPARAM wParam, LPARAM lParam);
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CDocker(const CDocker&); // Disable copy construction
+ CDocker& operator = (const CDocker&); // Disable assignment operator
+ void CheckAllTargets(LPDRAGPOS pDragPos);
+ void CloseAllTargets();
+ void DockOuter(CDocker* pDocker, DWORD dwDockStyle);
+ void DrawAllCaptions();
+ void DrawHashBar(HWND hBar, POINT Pos);
+ void ConvertToChild(HWND hWndParent);
+ void ConvertToPopup(RECT rc);
+ void MoveDockChildren(CDocker* pDockTarget);
+ void PromoteFirstChild();
+ void RecalcDockChildLayout(CRect rc);
+ void ResizeDockers(LPDRAGPOS pdp);
+ CDocker* SeparateFromDock();
+ void SendNotify(UINT nMessageID);
+ void SetUndockPosition(CPoint pt);
+ std::vector<CDocker*> SortDockers();
+
+ CDockBar m_DockBar;
+ CDockHint m_DockHint;
+ CDockClient m_DockClient;
+ CTargetCentre m_TargetCentre;
+ CTargetLeft m_TargetLeft;
+ CTargetTop m_TargetTop;
+ CTargetRight m_TargetRight;
+ CPoint m_OldPoint;
+ CTargetBottom m_TargetBottom;
+ CDocker* m_pDockParent;
+ CDocker* m_pDockAncestor;
+ CDocker* m_pDockActive;
+
+ std::vector <CDocker*> m_vDockChildren;
+ std::vector <DockPtr> m_vAllDockers; // Only used in DockAncestor
+
+ CRect m_rcBar;
+ CRect m_rcChild;
+
+ BOOL m_BlockMove;
+ BOOL m_Undocking;
+ BOOL m_bIsClosing;
+ BOOL m_bIsDragging;
+ BOOL m_bDragAutoResize;
+ int m_DockStartSize;
+ int m_nDockID;
+ int m_nTimerCount;
+ int m_NCHeight;
+ DWORD m_dwDockZone;
+ double m_DockSizeRatio;
+ DWORD m_DockStyle;
+ HWND m_hOldFocus;
+
+ }; // class CDocker
+
+ struct DockInfo
+ {
+ DWORD DockStyle;
+ int DockSize;
+ int DockID;
+ int DockParentID;
+ RECT Rect;
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ /////////////////////////////////////////////////////////////
+ // Definitions for the CDockBar class nested within CDocker
+ //
+ inline CDocker::CDockBar::CDockBar() : m_pDock(NULL), m_DockBarWidth(4)
+ {
+ m_brBackground.CreateSolidBrush(RGB(192,192,192));
+ }
+
+ inline CDocker::CDockBar::~CDockBar()
+ {
+ }
+
+ inline void CDocker::CDockBar::OnDraw(CDC* pDC)
+ {
+ CRect rcClient = GetClientRect();
+ pDC->SelectObject(&m_brBackground);
+ pDC->PatBlt(0, 0, rcClient.Width(), rcClient.Height(), PATCOPY);
+ }
+
+ inline void CDocker::CDockBar::PreCreate(CREATESTRUCT &cs)
+ {
+ // Create a child window, initially hidden
+ cs.style = WS_CHILD;
+ }
+
+ inline void CDocker::CDockBar::PreRegisterClass(WNDCLASS& wc)
+ {
+ wc.lpszClassName = _T("Win32++ Bar");
+ wc.hbrBackground = m_brBackground;
+ }
+
+ inline void CDocker::CDockBar::SendNotify(UINT nMessageID)
+ {
+ // Send a splitter bar notification to the parent
+ m_DragPos.hdr.code = nMessageID;
+ m_DragPos.hdr.hwndFrom = m_hWnd;
+ m_DragPos.ptPos = GetCursorPos();
+ m_DragPos.ptPos.x += 1;
+ GetParent()->SendMessage(WM_NOTIFY, 0L, (LPARAM)&m_DragPos);
+ }
+
+ inline void CDocker::CDockBar::SetColor(COLORREF color)
+ {
+ // Useful colors:
+ // GetSysColor(COLOR_BTNFACE) // Default Grey
+ // RGB(196, 215, 250) // Default Blue
+
+ m_brBackground.CreateSolidBrush(color);
+ }
+
+ inline LRESULT CDocker::CDockBar::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ {
+ switch (uMsg)
+ {
+ case WM_SETCURSOR:
+ {
+ if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE))
+ {
+ HCURSOR hCursor;
+ DWORD dwSide = GetDock()->GetDockStyle() & 0xF;
+ if ((dwSide == DS_DOCKED_LEFT) || (dwSide == DS_DOCKED_RIGHT))
+ hCursor = LoadCursor(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_SPLITH));
+ else
+ hCursor = LoadCursor(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_SPLITV));
+
+ if (hCursor) SetCursor(hCursor);
+ else TRACE(_T("**WARNING** Missing cursor resource for slider bar\n"));
+
+ return TRUE;
+ }
+ else
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ return 0;
+
+ case WM_LBUTTONDOWN:
+ {
+ if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE))
+ {
+ SendNotify(UWM_BAR_START);
+ SetCapture();
+ }
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE) && (GetCapture() == this))
+ {
+ SendNotify(UWM_BAR_END);
+ ReleaseCapture();
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ if (!(m_pDock->GetDockStyle() & DS_NO_RESIZE) && (GetCapture() == this))
+ {
+ SendNotify(UWM_BAR_MOVE);
+ }
+ break;
+ }
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CDockClient class nested within CDocker
+ //
+ inline CDocker::CDockClient::CDockClient() : m_pView(0), m_IsClosePressed(FALSE),
+ m_bOldFocus(FALSE), m_bCaptionPressed(FALSE), m_IsTracking(FALSE)
+ {
+ m_Foregnd1 = RGB(32,32,32);
+ m_Backgnd1 = RGB(190,207,227);
+ m_Foregnd2 = GetSysColor(COLOR_BTNTEXT);
+ m_Backgnd2 = GetSysColor(COLOR_BTNFACE);
+ }
+
+ inline void CDocker::CDockClient::Draw3DBorder(RECT& Rect)
+ {
+ // Imitates the drawing of the WS_EX_CLIENTEDGE extended style
+ // This draws a 2 pixel border around the specified Rect
+ CWindowDC dc(this);
+ CRect rcw = Rect;
+ dc.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
+ dc.MoveTo(0, rcw.Height());
+ dc.LineTo(0, 0);
+ dc.LineTo(rcw.Width(), 0);
+ dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DDKSHADOW));
+ dc.MoveTo(1, rcw.Height()-2);
+ dc.LineTo(1, 1);
+ dc.LineTo(rcw.Width()-2, 1);
+ dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DHILIGHT));
+ dc.MoveTo(rcw.Width()-1, 0);
+ dc.LineTo(rcw.Width()-1, rcw.Height()-1);
+ dc.LineTo(0, rcw.Height()-1);
+ dc.CreatePen(PS_SOLID,1, GetSysColor(COLOR_3DLIGHT));
+ dc.MoveTo(rcw.Width()-2, 1);
+ dc.LineTo(rcw.Width()-2, rcw.Height()-2);
+ dc.LineTo(1, rcw.Height()-2);
+ }
+
+ inline CRect CDocker::CDockClient::GetCloseRect()
+ {
+ // Calculate the close rect position in screen co-ordinates
+ CRect rcClose;
+
+ int gap = 4;
+ CRect rc = GetWindowRect();
+ int cx = GetSystemMetrics(SM_CXSMICON);
+ int cy = GetSystemMetrics(SM_CYSMICON);
+
+ rcClose.top = 2 + rc.top + m_pDock->m_NCHeight/2 - cy/2;
+ rcClose.bottom = 2 + rc.top + m_pDock->m_NCHeight/2 + cy/2;
+ rcClose.right = rc.right - gap;
+ rcClose.left = rcClose.right - cx;
+
+#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500)
+ if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
+ {
+ rcClose.left = rc.left + gap;
+ rcClose.right = rcClose.left + cx;
+ }
+#endif
+
+
+ return rcClose;
+ }
+
+ inline void CDocker::CDockClient::DrawCaption(WPARAM wParam)
+ {
+ if (IsWindow() && m_pDock->IsDocked() && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ BOOL bFocus = m_pDock->IsChildOfDocker(GetFocus());
+ m_bOldFocus = FALSE;
+
+ // Acquire the DC for our NonClient painting
+ CDC* pDC;
+ if ((wParam != 1) && (bFocus == m_bOldFocus))
+ pDC = GetDCEx((HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN|DCX_PARENTCLIP);
+ else
+ pDC = GetWindowDC();
+
+ // Create and set up our memory DC
+ CRect rc = GetWindowRect();
+ CMemDC dcMem(pDC);
+ int rcAdjust = (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)? 2 : 0;
+ int Width = MAX(rc.Width() -rcAdjust, 0);
+ int Height = m_pDock->m_NCHeight + rcAdjust;
+ dcMem.CreateCompatibleBitmap(pDC, Width, Height);
+ m_bOldFocus = bFocus;
+
+ // Set the font for the title
+ NONCLIENTMETRICS info = {0};
+ info.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
+ dcMem.CreateFontIndirect(&info.lfStatusFont);
+
+ // Set the Colours
+ if (bFocus)
+ {
+ dcMem.SetTextColor(m_Foregnd1);
+ dcMem.CreateSolidBrush(m_Backgnd1);
+ dcMem.SetBkColor(m_Backgnd1);
+ }
+ else
+ {
+ dcMem.SetTextColor(m_Foregnd2);
+ dcMem.CreateSolidBrush(m_Backgnd2);
+ dcMem.SetBkColor(m_Backgnd2);
+ }
+
+ // Draw the rectangle
+ dcMem.CreatePen(PS_SOLID, 1, RGB(160, 150, 140));
+ dcMem.Rectangle(rcAdjust, rcAdjust, rc.Width() -rcAdjust, m_pDock->m_NCHeight +rcAdjust);
+
+ // Display the caption
+ int cx = (m_pDock->GetDockStyle() & DS_NO_CLOSE)? 0 : GetSystemMetrics(SM_CXSMICON);
+ CRect rcText(4 +rcAdjust, rcAdjust, rc.Width() -4 - cx -rcAdjust, m_pDock->m_NCHeight +rcAdjust);
+ dcMem.DrawText(m_csCaption, m_csCaption.GetLength(), rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
+
+ // Draw the close button
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE))
+ DrawCloseButton(dcMem, bFocus);
+
+ // Draw the 3D border
+ if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ Draw3DBorder(rc);
+
+ // Copy the Memory DC to the window's DC
+ pDC->BitBlt(rcAdjust, rcAdjust, Width, Height, &dcMem, rcAdjust, rcAdjust, SRCCOPY);
+
+ // Required for Win98/WinME
+ pDC->Destroy();
+ }
+ }
+
+ inline void CDocker::CDockClient::DrawCloseButton(CDC& DrawDC, BOOL bFocus)
+ {
+ // The close button isn't displayed on Win95
+ if (GetWinVersion() == 1400) return;
+
+ if (m_pDock->IsDocked() && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ // Determine the close button's drawing position relative to the window
+ CRect rcClose = GetCloseRect();
+ UINT uState = GetCloseRect().PtInRect(GetCursorPos())? m_IsClosePressed && IsLeftButtonDown()? 2 : 1 : 0;
+ ScreenToClient(rcClose);
+
+ if (GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ {
+ rcClose.OffsetRect(2, m_pDock->m_NCHeight+2);
+ if (GetWindowRect().Height() < (m_pDock->m_NCHeight+4))
+ rcClose.OffsetRect(-2, -2);
+ }
+ else
+ rcClose.OffsetRect(0, m_pDock->m_NCHeight-2);
+
+ // Draw the outer highlight for the close button
+ if (!IsRectEmpty(&rcClose))
+ {
+ switch (uState)
+ {
+ case 0:
+ {
+ // Normal button
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(232, 228, 220));
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ break;
+ }
+
+ case 1:
+ {
+ // Popped up button
+ // Draw outline, white at top, black on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ }
+
+ break;
+ case 2:
+ {
+ // Pressed button
+ // Draw outline, black on top, white on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ }
+ break;
+ }
+
+ // Manually Draw Close Button
+ if (bFocus)
+ DrawDC.CreatePen(PS_SOLID, 1, m_Foregnd1);
+ else
+ DrawDC.CreatePen(PS_SOLID, 1, m_Foregnd2);
+
+ DrawDC.MoveTo(rcClose.left + 3, rcClose.top +3);
+ DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.left + 4, rcClose.top +3);
+ DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -3);
+
+ DrawDC.MoveTo(rcClose.left + 3, rcClose.top +4);
+ DrawDC.LineTo(rcClose.right - 3, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -3, rcClose.top +3);
+ DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -3, rcClose.top +4);
+ DrawDC.LineTo(rcClose.left + 3, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -4, rcClose.top +3);
+ DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -3);
+ }
+ }
+ }
+
+ inline void CDocker::CDockClient::OnNCCalcSize(WPARAM& wParam, LPARAM& lParam)
+ {
+ // Sets the non-client area (and hence sets the client area)
+ // This function modifies lParam
+
+ UNREFERENCED_PARAMETER(wParam);
+
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ if (m_pDock->IsDocked())
+ {
+ LPRECT rc = (LPRECT)lParam;
+ rc->top += m_pDock->m_NCHeight;
+ }
+ }
+ }
+
+ inline LRESULT CDocker::CDockClient::OnNCHitTest(WPARAM wParam, LPARAM lParam)
+ {
+ // Identify which part of the non-client area the cursor is over
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ if (m_pDock->IsDocked())
+ {
+ CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+
+ // Indicate if the point is in the close button (except for Win95)
+ if ((GetWinVersion() > 1400) && (GetCloseRect().PtInRect(pt)))
+ return HTCLOSE;
+
+ ScreenToClient(pt);
+
+ // Indicate if the point is in the caption
+ if (pt.y < 0)
+ return HTCAPTION;
+ }
+ }
+ return CWnd::WndProcDefault(WM_NCHITTEST, wParam, lParam);
+ }
+
+ inline LRESULT CDocker::CDockClient::OnNCLButtonDown(WPARAM wParam, LPARAM lParam)
+ {
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ if ((HTCLOSE == wParam) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE))
+ {
+ m_IsClosePressed = TRUE;
+ SetCapture();
+ }
+
+ m_bCaptionPressed = TRUE;
+ m_Oldpt.x = GET_X_LPARAM(lParam);
+ m_Oldpt.y = GET_Y_LPARAM(lParam);
+ if (m_pDock->IsDocked())
+ {
+ CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ ScreenToClient(pt);
+ m_pView->SetFocus();
+
+ // Update the close button
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE))
+ {
+ CWindowDC dc(this);
+ DrawCloseButton(dc, m_bOldFocus);
+ }
+
+ return 0L;
+ }
+ }
+ return CWnd::WndProcDefault(WM_NCLBUTTONDOWN, wParam, lParam);
+ }
+
+ inline void CDocker::CDockClient::OnLButtonUp(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & (DS_NO_CAPTION|DS_NO_CLOSE)))
+ {
+ m_bCaptionPressed = FALSE;
+ if (m_IsClosePressed && GetCloseRect().PtInRect(GetCursorPos()))
+ {
+ // Destroy the docker
+ if (dynamic_cast<CDockContainer*>(m_pDock->GetView()))
+ {
+ CDockContainer* pContainer = ((CDockContainer*)m_pDock->GetView())->GetActiveContainer();
+ CDocker* pDock = m_pDock->GetDockFromView(pContainer);
+ pDock->GetDockClient().SetClosePressed();
+ m_pDock->UndockContainer(pContainer, GetCursorPos(), FALSE);
+ pDock->Destroy();
+ }
+ else
+ {
+ m_pDock->Hide();
+ m_pDock->Destroy();
+ }
+ }
+ }
+ }
+
+ inline void CDocker::CDockClient::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ m_IsClosePressed = FALSE;
+ ReleaseCapture();
+ CWindowDC dc(this);
+ DrawCloseButton(dc, m_bOldFocus);
+ }
+
+ inline void CDocker::CDockClient::OnMouseActivate(WPARAM wParam, LPARAM lParam)
+ // Focus changed, so redraw the captions
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ m_pDock->GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0);
+ }
+ }
+
+ inline void CDocker::CDockClient::OnMouseMove(WPARAM wParam, LPARAM lParam)
+ {
+ OnNCMouseMove(wParam, lParam);
+ }
+
+ inline void CDocker::CDockClient::OnNCMouseLeave(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ m_IsTracking = FALSE;
+ CWindowDC dc(this);
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & (DS_NO_CAPTION|DS_NO_CLOSE)) && m_pDock->IsDocked())
+ DrawCloseButton(dc, m_bOldFocus);
+
+ m_IsTracking = FALSE;
+ }
+
+ inline LRESULT CDocker::CDockClient::OnNCMouseMove(WPARAM wParam, LPARAM lParam)
+ {
+ if (!m_IsTracking)
+ {
+ TRACKMOUSEEVENT TrackMouseEventStruct = {0};
+ TrackMouseEventStruct.cbSize = sizeof(TrackMouseEventStruct);
+ TrackMouseEventStruct.dwFlags = TME_LEAVE|TME_NONCLIENT;
+ TrackMouseEventStruct.hwndTrack = m_hWnd;
+ _TrackMouseEvent(&TrackMouseEventStruct);
+ m_IsTracking = TRUE;
+ }
+
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ if (m_pDock->IsDocked())
+ {
+ // Discard phantom mouse move messages
+ if ( (m_Oldpt.x == GET_X_LPARAM(lParam) ) && (m_Oldpt.y == GET_Y_LPARAM(lParam)))
+ return 0L;
+
+ if (IsLeftButtonDown() && (wParam == HTCAPTION) && (m_bCaptionPressed))
+ {
+ CDocker* pDock = (CDocker*)GetParent();
+ if (pDock)
+ pDock->Undock(GetCursorPos());
+ }
+
+ // Update the close button
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE))
+ {
+ CWindowDC dc(this);
+ DrawCloseButton(dc, m_bOldFocus);
+ }
+ }
+
+ m_bCaptionPressed = FALSE;
+ }
+ return CWnd::WndProcDefault(WM_MOUSEMOVE, wParam, lParam);
+ }
+
+ inline LRESULT CDocker::CDockClient::OnNCPaint(WPARAM wParam, LPARAM lParam)
+ {
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CAPTION))
+ {
+ if (m_pDock->IsDocked())
+ {
+ DefWindowProc(WM_NCPAINT, wParam, lParam);
+ DrawCaption(wParam);
+ return 0;
+ }
+ }
+ return CWnd::WndProcDefault(WM_NCPAINT, wParam, lParam);
+ }
+
+ inline void CDocker::CDockClient::OnWindowPosChanged(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Reposition the View window to cover the DockClient's client area
+ CRect rc = GetClientRect();
+ m_pView->SetWindowPos(NULL, rc, SWP_SHOWWINDOW);
+ }
+
+ inline void CDocker::CDockClient::PreRegisterClass(WNDCLASS& wc)
+ {
+ wc.lpszClassName = _T("Win32++ DockClient");
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ }
+
+ inline void CDocker::CDockClient::PreCreate(CREATESTRUCT& cs)
+ {
+ DWORD dwStyle = m_pDock->GetDockStyle();
+ if (dwStyle & DS_CLIENTEDGE)
+ cs.dwExStyle = WS_EX_CLIENTEDGE;
+
+#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500)
+ if (m_pDock->GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
+ cs.dwExStyle |= WS_EX_LAYOUTRTL;
+#endif
+
+ }
+
+ inline void CDocker::CDockClient::SendNotify(UINT nMessageID)
+ {
+ // Fill the DragPos structure with data
+ DRAGPOS DragPos;
+ DragPos.hdr.code = nMessageID;
+ DragPos.hdr.hwndFrom = m_hWnd;
+ DragPos.ptPos = GetCursorPos();
+
+ // Send a DragPos notification to the docker
+ GetParent()->SendMessage(WM_NOTIFY, 0L, (LPARAM)&DragPos);
+ }
+
+ inline void CDocker::CDockClient::SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF Foregnd2, COLORREF Backgnd2)
+ {
+ // Set the colors used when drawing the caption
+ // m_Foregnd1 Foreground colour (focused). m_Backgnd1 Background colour (focused)
+ // m_Foregnd2 Foreground colour (not focused). m_Backgnd2 Foreground colour (not focused)
+ m_Foregnd1 = Foregnd1;
+ m_Backgnd1 = Backgnd1;
+ m_Foregnd2 = Foregnd2;
+ m_Backgnd2 = Backgnd2;
+ }
+
+ inline LRESULT CDocker::CDockClient::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_LBUTTONUP:
+ {
+ ReleaseCapture();
+ if ((0 != m_pDock) && !(m_pDock->GetDockStyle() & DS_NO_CLOSE))
+ {
+ CWindowDC dc(this);
+ DrawCloseButton(dc, m_bOldFocus);
+ OnLButtonUp(wParam, lParam);
+ }
+ }
+ break;
+
+ case WM_MOUSEACTIVATE:
+ OnMouseActivate(wParam, lParam);
+ break;
+
+ case WM_MOUSEMOVE:
+ OnMouseMove(wParam, lParam);
+ break;
+
+ case WM_NCCALCSIZE:
+ OnNCCalcSize(wParam, lParam);
+ break;
+
+ case WM_NCHITTEST:
+ return OnNCHitTest(wParam, lParam);
+
+ case WM_NCLBUTTONDOWN:
+ return OnNCLButtonDown(wParam, lParam);
+
+ case WM_NCMOUSEMOVE:
+ return OnNCMouseMove(wParam, lParam);
+
+ case WM_NCPAINT:
+ return OnNCPaint(wParam, lParam);
+
+ case WM_NCMOUSELEAVE:
+ OnNCMouseLeave(wParam, lParam);
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ OnWindowPosChanged(wParam, lParam);
+ break;
+ }
+
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+ //////////////////////////////////////////////////////////////
+ // Definitions for the CDockHint class nested within CDocker
+ //
+ inline CDocker::CDockHint::CDockHint() : m_uDockSideOld(0)
+ {
+ }
+
+ inline CDocker::CDockHint::~CDockHint()
+ {
+ }
+
+ inline RECT CDocker::CDockHint::CalcHintRectContainer(CDocker* pDockTarget)
+ {
+ // Calculate the hint window's position for container docking
+ CRect rcHint = pDockTarget->GetDockClient().GetWindowRect();
+ if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ rcHint.InflateRect(-2, -2);
+ pDockTarget->ScreenToClient(rcHint);
+
+ return rcHint;
+ }
+
+ inline RECT CDocker::CDockHint::CalcHintRectInner(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide)
+ {
+ // Calculate the hint window's position for inner docking
+ CRect rcHint = pDockTarget->GetDockClient().GetWindowRect();
+ if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ rcHint.InflateRect(-2, -2);
+ pDockTarget->ScreenToClient(rcHint);
+
+ int Width;
+ CRect rcDockDrag = pDockDrag->GetWindowRect();
+ CRect rcDockTarget = pDockTarget->GetDockClient().GetWindowRect();
+ if ((uDockSide == DS_DOCKED_LEFT) || (uDockSide == DS_DOCKED_RIGHT))
+ {
+ Width = rcDockDrag.Width();
+ if (Width >= (rcDockTarget.Width() - pDockDrag->GetBarWidth()))
+ Width = MAX(rcDockTarget.Width()/2 - pDockDrag->GetBarWidth(), pDockDrag->GetBarWidth());
+ }
+ else
+ {
+ Width = rcDockDrag.Height();
+ if (Width >= (rcDockTarget.Height() - pDockDrag->GetBarWidth()))
+ Width = MAX(rcDockTarget.Height()/2 - pDockDrag->GetBarWidth(), pDockDrag->GetBarWidth());
+ }
+ switch (uDockSide)
+ {
+ case DS_DOCKED_LEFT:
+ rcHint.right = rcHint.left + Width;
+ break;
+ case DS_DOCKED_RIGHT:
+ rcHint.left = rcHint.right - Width;
+ break;
+ case DS_DOCKED_TOP:
+ rcHint.bottom = rcHint.top + Width;
+ break;
+ case DS_DOCKED_BOTTOM:
+ rcHint.top = rcHint.bottom - Width;
+ break;
+ }
+
+ return rcHint;
+ }
+
+ inline RECT CDocker::CDockHint::CalcHintRectOuter(CDocker* pDockDrag, UINT uDockSide)
+ {
+ // Calculate the hint window's position for outer docking
+ CDocker* pDockTarget = pDockDrag->GetDockAncestor();
+ CRect rcHint = pDockTarget->GetClientRect();
+ if (pDockTarget->GetDockClient().GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ rcHint.InflateRect(-2, -2);
+
+ int Width;
+ CRect rcDockDrag = pDockDrag->GetWindowRect();
+ CRect rcDockTarget = pDockTarget->GetDockClient().GetWindowRect();
+
+ // Limit the docked size to half the parent's size if it won't fit inside parent
+ if ((uDockSide == DS_DOCKED_LEFTMOST) || (uDockSide == DS_DOCKED_RIGHTMOST))
+ {
+ Width = rcDockDrag.Width();
+ int BarWidth = pDockDrag->GetBarWidth();
+ if (Width >= pDockTarget->GetDockClient().GetClientRect().Width() - pDockDrag->GetBarWidth())
+ Width = MAX(pDockTarget->GetDockClient().GetClientRect().Width()/2 - BarWidth, BarWidth);
+ }
+ else
+ {
+ Width = rcDockDrag.Height();
+ int BarWidth = pDockDrag->GetBarWidth();
+ if (Width >= pDockTarget->GetDockClient().GetClientRect().Height() - pDockDrag->GetBarWidth())
+ Width = MAX(pDockTarget->GetDockClient().GetClientRect().Height()/2 - BarWidth, BarWidth);
+ }
+ switch (uDockSide)
+ {
+ case DS_DOCKED_LEFTMOST:
+ rcHint.right = rcHint.left + Width;
+ break;
+ case DS_DOCKED_RIGHTMOST:
+ rcHint.left = rcHint.right - Width;
+ break;
+ case DS_DOCKED_TOPMOST:
+ rcHint.bottom = rcHint.top + Width;
+ break;
+ case DS_DOCKED_BOTTOMMOST:
+ rcHint.top = rcHint.bottom - Width;
+ break;
+ }
+
+ return rcHint;
+ }
+
+ inline void CDocker::CDockHint::DisplayHint(CDocker* pDockTarget, CDocker* pDockDrag, UINT uDockSide)
+ {
+ // Ensure a new hint window is created if dock side changes
+ if (uDockSide != m_uDockSideOld)
+ {
+ Destroy();
+ pDockTarget->RedrawWindow( NULL, NULL, RDW_NOERASE | RDW_UPDATENOW );
+ pDockDrag->RedrawWindow();
+ }
+ m_uDockSideOld = uDockSide;
+
+ if (!IsWindow())
+ {
+ CRect rcHint;
+
+ if (uDockSide & 0xF)
+ rcHint = CalcHintRectInner(pDockTarget, pDockDrag, uDockSide);
+ else if (uDockSide & 0xF0000)
+ rcHint = CalcHintRectOuter(pDockDrag, uDockSide);
+ else if (uDockSide & DS_DOCKED_CONTAINER)
+ rcHint = CalcHintRectContainer(pDockTarget);
+ else
+ return;
+
+ ShowHintWindow(pDockTarget, rcHint);
+ }
+ }
+
+ inline void CDocker::CDockHint::OnDraw(CDC* pDC)
+ {
+ // Display the blue tinted bitmap
+ CRect rc = GetClientRect();
+ CMemDC MemDC(pDC);
+ MemDC.SelectObject(&m_bmBlueTint);
+ pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &MemDC, 0, 0, SRCCOPY);
+ }
+
+ inline void CDocker::CDockHint::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_POPUP;
+
+ // WS_EX_TOOLWINDOW prevents the window being displayed on the taskbar
+ cs.dwExStyle = WS_EX_TOOLWINDOW;
+
+ cs.lpszClass = _T("Win32++ DockHint");
+ }
+
+ inline void CDocker::CDockHint::ShowHintWindow(CDocker* pDockTarget, CRect rcHint)
+ {
+ // Save the Dock window's blue tinted bitmap
+ CClientDC dcDesktop(NULL);
+ CMemDC dcMem(&dcDesktop);
+ CRect rcBitmap = rcHint;
+ CRect rcTarget = rcHint;
+ pDockTarget->ClientToScreen(rcTarget);
+
+ m_bmBlueTint.CreateCompatibleBitmap(&dcDesktop, rcBitmap.Width(), rcBitmap.Height());
+ CBitmap* pOldBitmap = dcMem.SelectObject(&m_bmBlueTint);
+ dcMem.BitBlt(0, 0, rcBitmap.Width(), rcBitmap.Height(), &dcDesktop, rcTarget.left, rcTarget.top, SRCCOPY);
+ dcMem.SelectObject(pOldBitmap);
+ TintBitmap(&m_bmBlueTint, -64, -24, +128);
+
+ // Create the Hint window
+ if (!IsWindow())
+ {
+ Create(pDockTarget);
+ }
+
+ pDockTarget->ClientToScreen(rcHint);
+ SetWindowPos(NULL, rcHint, SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE);
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTargetCentre class nested within CDocker
+ //
+ inline CDocker::CTargetCentre::CTargetCentre() : m_bIsOverContainer(FALSE), m_pOldDockTarget(0)
+ {
+ }
+
+ inline CDocker::CTargetCentre::~CTargetCentre()
+ {
+ }
+
+ inline void CDocker::CTargetCentre::OnDraw(CDC* pDC)
+ {
+ CBitmap bmCentre(IDW_SDCENTER);
+ CBitmap bmLeft(IDW_SDLEFT);
+ CBitmap bmRight(IDW_SDRIGHT);
+ CBitmap bmTop(IDW_SDTOP);
+ CBitmap bmBottom(IDW_SDBOTTOM);
+
+ if (bmCentre.GetHandle()) pDC->DrawBitmap(0, 0, 88, 88, bmCentre, RGB(255,0,255));
+ else TRACE(_T("Missing docking resource: Target Centre\n"));
+
+ if (bmLeft.GetHandle()) pDC->DrawBitmap(0, 29, 31, 29, bmLeft, RGB(255,0,255));
+ else TRACE(_T("Missing docking resource: Target Left\n"));
+
+ if (bmTop.GetHandle()) pDC->DrawBitmap(29, 0, 29, 31, bmTop, RGB(255,0,255));
+ else TRACE(_T("Missing docking resource: Target Top\n"));
+
+ if (bmRight.GetHandle()) pDC->DrawBitmap(55, 29, 31, 29, bmRight, RGB(255,0,255));
+ else TRACE(_T("Missing docking resource: Target Right\n"));
+
+ if (bmBottom.GetHandle()) pDC->DrawBitmap(29, 55, 29, 31, bmBottom, RGB(255,0,255));
+ else TRACE(_T("Missing docking resource: Target Bottom\n"));
+
+ if (IsOverContainer())
+ {
+ CBitmap bmMiddle(IDW_SDMIDDLE);
+ pDC->DrawBitmap(31, 31, 25, 26, bmMiddle, RGB(255,0,255));
+ }
+ }
+
+ inline void CDocker::CTargetCentre::OnCreate()
+ {
+ // Use a region to create an irregularly shapped window
+ POINT ptArray[16] = { {0,29}, {22, 29}, {29, 22}, {29, 0},
+ {58, 0}, {58, 22}, {64, 29}, {87, 29},
+ {87, 58}, {64, 58}, {58, 64}, {58, 87},
+ {29, 87}, {29, 64}, {23, 58}, {0, 58} };
+
+ CRgn rgnPoly;
+ rgnPoly.CreatePolygonRgn(ptArray, 16, WINDING);
+ SetWindowRgn(&rgnPoly, FALSE);
+ }
+
+ inline BOOL CDocker::CTargetCentre::CheckTarget(LPDRAGPOS pDragPos)
+ {
+ CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom);
+ if (NULL == pDockDrag) return FALSE;
+
+ CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pDragPos->ptPos);
+ if (NULL == pDockTarget) return FALSE;
+
+ if (!IsWindow()) Create();
+ m_bIsOverContainer = (dynamic_cast<CDockContainer*>(pDockTarget->GetView()) != NULL);
+
+ // Redraw the target if the dock target changes
+ if (m_pOldDockTarget != pDockTarget) Invalidate();
+ m_pOldDockTarget = pDockTarget;
+
+ int cxImage = 88;
+ int cyImage = 88;
+
+ CRect rcTarget = pDockTarget->GetDockClient().GetWindowRect();
+ int xMid = rcTarget.left + (rcTarget.Width() - cxImage)/2;
+ int yMid = rcTarget.top + (rcTarget.Height() - cyImage)/2;
+ SetWindowPos(HWND_TOPMOST, xMid, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW);
+
+ // Create the docking zone rectangles
+ CPoint pt = pDragPos->ptPos;
+ ScreenToClient(pt);
+ CRect rcLeft(0, 29, 31, 58);
+ CRect rcTop(29, 0, 58, 31);
+ CRect rcRight(55, 29, 87, 58);
+ CRect rcBottom(29, 55, 58, 87);
+ CRect rcMiddle(31, 31, 56, 57);
+
+ // Test if our cursor is in one of the docking zones
+ if ((rcLeft.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_LEFT))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_LEFT);
+ pDockDrag->m_dwDockZone = DS_DOCKED_LEFT;
+ return TRUE;
+ }
+ else if ((rcTop.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_TOP))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_TOP);
+ pDockDrag->m_dwDockZone = DS_DOCKED_TOP;
+ return TRUE;
+ }
+ else if ((rcRight.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_RIGHT))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_RIGHT);
+ pDockDrag->m_dwDockZone = DS_DOCKED_RIGHT;
+ return TRUE;
+ }
+ else if ((rcBottom.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_BOTTOM))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_BOTTOM);
+ pDockDrag->m_dwDockZone = DS_DOCKED_BOTTOM;
+ return TRUE;
+ }
+ else if ((rcMiddle.PtInRect(pt)) && (IsOverContainer()))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_CONTAINER);
+ pDockDrag->m_dwDockZone = DS_DOCKED_CONTAINER;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTarget class nested within CDocker
+ // CTarget is the base class for a number of CTargetXXX classes
+ inline CDocker::CTarget::~CTarget()
+ {
+ }
+
+ inline void CDocker::CTarget::OnDraw(CDC* pDC)
+ {
+ BITMAP bm = m_bmImage.GetBitmapData();
+ int cxImage = bm.bmWidth;
+ int cyImage = bm.bmHeight;
+
+ if (m_bmImage)
+ pDC->DrawBitmap(0, 0, cxImage, cyImage, m_bmImage, RGB(255,0,255));
+ else
+ TRACE(_T("Missing docking resource\n"));
+ }
+
+ inline void CDocker::CTarget::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_POPUP;
+ cs.dwExStyle = WS_EX_TOPMOST|WS_EX_TOOLWINDOW;
+ cs.lpszClass = _T("Win32++ DockTargeting");
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTargetLeft class nested within CDocker
+ //
+ inline BOOL CDocker::CTargetLeft::CheckTarget(LPDRAGPOS pDragPos)
+ {
+ CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom);
+ if (NULL == pDockDrag) return FALSE;
+
+ CPoint pt = pDragPos->ptPos;
+ CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker();
+ if (pDockTarget != pDockDrag->GetDockAncestor())
+ {
+ Destroy();
+ return FALSE;
+ }
+
+ BITMAP bm = m_bmImage.GetBitmapData();
+ int cxImage = bm.bmWidth;
+ int cyImage = bm.bmHeight;
+
+ if (!IsWindow())
+ {
+ Create();
+ CRect rc = pDockTarget->GetWindowRect();
+ int yMid = rc.top + (rc.Height() - cyImage)/2;
+ SetWindowPos(HWND_TOPMOST, rc.left + 10, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW);
+ }
+
+ CRect rcLeft(0, 0, cxImage, cyImage);
+ ScreenToClient(pt);
+
+ // Test if our cursor is in one of the docking zones
+ if ((rcLeft.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_LEFT))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_LEFTMOST);
+ pDockDrag->m_dwDockZone = DS_DOCKED_LEFTMOST;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTargetTop class nested within CDocker
+ //
+ inline BOOL CDocker::CTargetTop::CheckTarget(LPDRAGPOS pDragPos)
+ {
+ CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom);
+ if (NULL == pDockDrag) return FALSE;
+
+ CPoint pt = pDragPos->ptPos;
+ CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker();
+ if (pDockTarget != pDockDrag->GetDockAncestor())
+ {
+ Destroy();
+ return FALSE;
+ }
+
+ BITMAP bm = m_bmImage.GetBitmapData();
+ int cxImage = bm.bmWidth;
+ int cyImage = bm.bmHeight;
+
+ if (!IsWindow())
+ {
+ Create();
+ CRect rc = pDockTarget->GetWindowRect();
+ int xMid = rc.left + (rc.Width() - cxImage)/2;
+ SetWindowPos(HWND_TOPMOST, xMid, rc.top + 10, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW);
+ }
+
+ CRect rcTop(0, 0, cxImage, cyImage);
+ ScreenToClient(pt);
+
+ // Test if our cursor is in one of the docking zones
+ if ((rcTop.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_TOP))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_TOPMOST);
+ pDockDrag->m_dwDockZone = DS_DOCKED_TOPMOST;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTargetRight class nested within CDocker
+ //
+ inline BOOL CDocker::CTargetRight::CheckTarget(LPDRAGPOS pDragPos)
+ {
+ CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom);
+ if (NULL == pDockDrag) return FALSE;
+
+ CPoint pt = pDragPos->ptPos;
+ CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker();
+ if (pDockTarget != pDockDrag->GetDockAncestor())
+ {
+ Destroy();
+ return FALSE;
+ }
+
+ BITMAP bm = m_bmImage.GetBitmapData();
+ int cxImage = bm.bmWidth;
+ int cyImage = bm.bmHeight;
+
+ if (!IsWindow())
+ {
+ Create();
+ CRect rc = pDockTarget->GetWindowRect();
+ int yMid = rc.top + (rc.Height() - cyImage)/2;
+ SetWindowPos(HWND_TOPMOST, rc.right - 10 - cxImage, yMid, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW);
+ }
+
+ CRect rcRight(0, 0, cxImage, cyImage);
+ ScreenToClient(pt);
+
+ // Test if our cursor is in one of the docking zones
+ if ((rcRight.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_RIGHT))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_RIGHTMOST);
+ pDockDrag->m_dwDockZone = DS_DOCKED_RIGHTMOST;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ ////////////////////////////////////////////////////////////////
+ // Definitions for the CTargetBottom class nested within CDocker
+ //
+ inline BOOL CDocker::CTargetBottom::CheckTarget(LPDRAGPOS pDragPos)
+ {
+ CDocker* pDockDrag = (CDocker*)FromHandle(pDragPos->hdr.hwndFrom);
+ if (NULL == pDockDrag) return FALSE;
+
+ CPoint pt = pDragPos->ptPos;
+ CDocker* pDockTarget = pDockDrag->GetDockFromPoint(pt)->GetTopmostDocker();
+ if (pDockTarget != pDockDrag->GetDockAncestor())
+ {
+ Destroy();
+ return FALSE;
+ }
+
+ BITMAP bm = m_bmImage.GetBitmapData();
+ int cxImage = bm.bmWidth;
+ int cyImage = bm.bmHeight;
+
+ if (!IsWindow())
+ {
+ Create();
+ CRect rc = pDockTarget->GetWindowRect();
+ int xMid = rc.left + (rc.Width() - cxImage)/2;
+ SetWindowPos(HWND_TOPMOST, xMid, rc.bottom - 10 - cyImage, cxImage, cyImage, SWP_NOACTIVATE|SWP_SHOWWINDOW);
+ }
+ CRect rcBottom(0, 0, cxImage, cyImage);
+ ScreenToClient(pt);
+
+ // Test if our cursor is in one of the docking zones
+ if ((rcBottom.PtInRect(pt)) && !(pDockTarget->GetDockStyle() & DS_NO_DOCKCHILD_BOTTOM))
+ {
+ pDockDrag->m_BlockMove = TRUE;
+ pDockTarget->GetDockHint().DisplayHint(pDockTarget, pDockDrag, DS_DOCKED_BOTTOMMOST);
+ pDockDrag->m_dwDockZone = DS_DOCKED_BOTTOMMOST;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ /////////////////////////////////////////
+ // Definitions for the CDocker class
+ //
+ inline CDocker::CDocker() : m_pDockParent(NULL), m_pDockActive(NULL), m_BlockMove(FALSE), m_Undocking(FALSE),
+ m_bIsClosing(FALSE), m_bIsDragging(FALSE), m_bDragAutoResize(TRUE), m_DockStartSize(0), m_nDockID(0),
+ m_nTimerCount(0), m_NCHeight(0), m_dwDockZone(0), m_DockSizeRatio(1.0), m_DockStyle(0), m_hOldFocus(0)
+ {
+ // Assume this docker is the DockAncestor for now.
+ m_pDockAncestor = this;
+ }
+
+ inline CDocker::~CDocker()
+ {
+ GetDockBar().Destroy();
+
+ std::vector <DockPtr>::iterator iter;
+ if (GetDockAncestor() == this)
+ {
+ // Destroy all dock descendants of this dock ancestor
+ for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter)
+ {
+ (*iter)->Destroy();
+ }
+ }
+ }
+
+ inline CDocker* CDocker::AddDockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, int nDockID /* = 0*/)
+ // This function creates the docker, and adds it to the docker heirachy as docked
+ {
+ // Create the docker window as a child of the frame window.
+ // This pernamently sets the frame window as the docker window's owner,
+ // even when its parent is subsequently changed.
+
+ assert(pDocker);
+
+ // Store the Docker's pointer in the DockAncestor's vector for later deletion
+ GetDockAncestor()->m_vAllDockers.push_back(DockPtr(pDocker));
+
+ pDocker->SetDockStyle(dwDockStyle);
+ pDocker->m_nDockID = nDockID;
+ pDocker->m_pDockAncestor = GetDockAncestor();
+ pDocker->m_pDockParent = this;
+ pDocker->SetDockSize(DockSize);
+ CWnd* pFrame = GetDockAncestor()->GetAncestor();
+ pDocker->Create(pFrame);
+ pDocker->SetParent(this);
+
+ // Dock the docker window
+ if (dwDockStyle & DS_DOCKED_CONTAINER)
+ DockInContainer(pDocker, dwDockStyle);
+ else
+ Dock(pDocker, dwDockStyle);
+
+ // Issue TRACE warnings for any missing resources
+ HMODULE hMod= GetApp()->GetResourceHandle();
+
+ if (!(dwDockStyle & DS_NO_RESIZE))
+ {
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SPLITH), RT_GROUP_CURSOR))
+ TRACE(_T("**WARNING** Horizontal cursor resource missing\n"));
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SPLITV), RT_GROUP_CURSOR))
+ TRACE(_T("**WARNING** Vertical cursor resource missing\n"));
+ }
+
+ if (!(dwDockStyle & DS_NO_UNDOCK))
+ {
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDCENTER), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking center bitmap resource missing\n"));
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDLEFT), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking left bitmap resource missing\n"));
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDRIGHT), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking right bitmap resource missing\n"));
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDTOP), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking top bitmap resource missing\n"));
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDBOTTOM), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking center bottom resource missing\n"));
+ }
+
+ if (dwDockStyle & DS_DOCKED_CONTAINER)
+ {
+ if (!FindResource(hMod, MAKEINTRESOURCE(IDW_SDMIDDLE), RT_BITMAP))
+ TRACE(_T("**WARNING** Docking container bitmap resource missing\n"));
+ }
+
+ return pDocker;
+ }
+
+ inline CDocker* CDocker::AddUndockedChild(CDocker* pDocker, DWORD dwDockStyle, int DockSize, RECT rc, int nDockID /* = 0*/)
+ // This function creates the docker, and adds it to the docker heirachy as undocked
+ {
+ assert(pDocker);
+
+ // Store the Docker's pointer in the DockAncestor's vector for later deletion
+ GetDockAncestor()->m_vAllDockers.push_back(DockPtr(pDocker));
+
+ pDocker->SetDockSize(DockSize);
+ pDocker->SetDockStyle(dwDockStyle & 0XFFFFFF0);
+ pDocker->m_nDockID = nDockID;
+ pDocker->m_pDockAncestor = GetDockAncestor();
+
+ // Initially create the as a child window of the frame
+ // This makes the frame window the owner of our docker
+ CWnd* pFrame = GetDockAncestor()->GetAncestor();
+ pDocker->Create(pFrame);
+ pDocker->SetParent(this);
+
+ // Change the Docker to a POPUP window
+ DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE;
+ pDocker->SetWindowLongPtr(GWL_STYLE, dwStyle);
+ pDocker->SetRedraw(FALSE);
+ pDocker->SetParent(0);
+ pDocker->SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED);
+ pDocker->SetRedraw(TRUE);
+ pDocker->RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_ALLCHILDREN);
+ pDocker->SetWindowText(pDocker->GetCaption().c_str());
+
+ return pDocker;
+ }
+
+ inline void CDocker::CheckAllTargets(LPDRAGPOS pDragPos)
+ // Calls CheckTarget for each possible target zone
+ {
+ if (!GetDockAncestor()->m_TargetCentre.CheckTarget(pDragPos))
+ {
+ if (!GetDockAncestor()->m_TargetLeft.CheckTarget(pDragPos))
+ {
+ if(!GetDockAncestor()->m_TargetTop.CheckTarget(pDragPos))
+ {
+ if(!GetDockAncestor()->m_TargetRight.CheckTarget(pDragPos))
+ {
+ if(!GetDockAncestor()->m_TargetBottom.CheckTarget(pDragPos))
+ {
+ // Not in a docking zone, so clean up
+ NMHDR nmhdr = pDragPos->hdr;
+ CDocker* pDockDrag = (CDocker*)FromHandle(nmhdr.hwndFrom);
+ if (pDockDrag)
+ {
+ if (pDockDrag->m_BlockMove)
+ pDockDrag->RedrawWindow(0, 0, RDW_FRAME|RDW_INVALIDATE);
+
+ GetDockHint().Destroy();
+ pDockDrag->m_dwDockZone = 0;
+ pDockDrag->m_BlockMove = FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ inline BOOL CDocker::VerifyDockers()
+ // A diagnostic routine which verifies the integrity of the docking layout
+ {
+ BOOL bResult = TRUE;
+
+ // Check dock ancestor
+ std::vector<DockPtr>::iterator iter;
+
+ for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter)
+ {
+ if (GetDockAncestor() != (*iter)->m_pDockAncestor)
+ {
+ TRACE(_T("Invalid Dock Ancestor\n"));
+ bResult = FALSE;
+ }
+ }
+
+ // Check presence of dock parent
+ for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter)
+ {
+ if ((*iter)->IsUndocked() && (*iter)->m_pDockParent != 0)
+ {
+ TRACE(_T("Error: Undocked dockers should not have a dock parent\n"));
+ bResult = FALSE;
+ }
+
+ if ((*iter)->IsDocked() && (*iter)->m_pDockParent == 0)
+ {
+ TRACE(_T("Error: Docked dockers should have a dock parent\n"));
+ bResult = FALSE;
+ }
+ }
+
+ // Check dock parent/child relationship
+ for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter)
+ {
+ std::vector<CDocker*>::iterator iterChild;
+ for (iterChild = (*iter)->GetDockChildren().begin(); iterChild != (*iter)->GetDockChildren().end(); ++iterChild)
+ {
+ if ((*iterChild)->m_pDockParent != (*iter).get())
+ {
+ TRACE(_T("Error: Docking parent/Child information mismatch\n"));
+ bResult = FALSE;
+ }
+ if ((*iterChild)->GetParent() != (*iter).get())
+ {
+ TRACE(_T("Error: Incorrect windows child parent relationship\n"));
+ bResult = FALSE;
+ }
+ }
+ }
+
+ // Check dock parent chain
+ for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); ++iter)
+ {
+ CDocker* pDockTopLevel = (*iter)->GetTopmostDocker();
+ if (pDockTopLevel->IsDocked())
+ TRACE(_T("Error: Top level parent should be undocked\n"));
+ }
+
+ return bResult;
+ }
+
+ inline void CDocker::Close()
+ {
+ // Destroy the docker
+ Hide();
+ Destroy();
+ }
+
+ inline void CDocker::CloseAllDockers()
+ {
+ assert(this == GetDockAncestor()); // Must call CloseAllDockers from the DockAncestor
+
+ std::vector <DockPtr>::iterator v;
+
+ SetRedraw(FALSE);
+ std::vector<DockPtr> AllDockers = GetAllDockers();
+ for (v = AllDockers.begin(); v != AllDockers.end(); ++v)
+ {
+ // The CDocker is destroyed when the window is destroyed
+ (*v)->m_bIsClosing = TRUE;
+ (*v)->Destroy(); // Destroy the window
+ }
+
+ GetDockChildren().clear();
+ SetRedraw(TRUE);
+ RecalcDockLayout();
+ }
+
+ inline void CDocker::CloseAllTargets()
+ {
+ GetDockAncestor()->m_TargetCentre.Destroy();
+ GetDockAncestor()->m_TargetLeft.Destroy();
+ GetDockAncestor()->m_TargetTop.Destroy();
+ GetDockAncestor()->m_TargetRight.Destroy();
+ GetDockAncestor()->m_TargetBottom.Destroy();
+ }
+
+ inline void CDocker::Dock(CDocker* pDocker, UINT DockStyle)
+ // Docks the specified docker inside this docker
+ {
+ assert(pDocker);
+
+ pDocker->m_pDockParent = this;
+ pDocker->m_BlockMove = FALSE;
+ pDocker->SetDockStyle(DockStyle);
+ m_vDockChildren.push_back(pDocker);
+ pDocker->ConvertToChild(m_hWnd);
+
+ // Limit the docked size to half the parent's size if it won't fit inside parent
+ if (((DockStyle & 0xF) == DS_DOCKED_LEFT) || ((DockStyle &0xF) == DS_DOCKED_RIGHT))
+ {
+ int Width = GetDockClient().GetWindowRect().Width();
+ int BarWidth = pDocker->GetBarWidth();
+ if (pDocker->m_DockStartSize >= (Width - BarWidth))
+ pDocker->SetDockSize(MAX(Width/2 - BarWidth, BarWidth));
+
+ pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetWindowRect().Width();
+ }
+ else
+ {
+ int Height = GetDockClient().GetWindowRect().Height();
+ int BarWidth = pDocker->GetBarWidth();
+ if (pDocker->m_DockStartSize >= (Height - BarWidth))
+ pDocker->SetDockSize(MAX(Height/2 - BarWidth, BarWidth));
+
+ pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetWindowRect().Height();
+ }
+
+ // Redraw the docked windows
+ GetAncestor()->SetForegroundWindow();
+ GetTopmostDocker()->m_hOldFocus = pDocker->GetView()->GetHwnd();
+ pDocker->GetView()->SetFocus();
+
+ GetTopmostDocker()->SetRedraw(FALSE);
+ RecalcDockLayout();
+ GetTopmostDocker()->SetRedraw(TRUE);
+ GetTopmostDocker()->RedrawWindow();
+ }
+
+ inline void CDocker::DockInContainer(CDocker* pDock, DWORD dwDockStyle)
+ // Add a container to an existing container
+ {
+ if ((dwDockStyle & DS_DOCKED_CONTAINER) && (dynamic_cast<CDockContainer*>(pDock->GetView())))
+ {
+ // Transfer any dock children to this docker
+ pDock->MoveDockChildren(this);
+
+ // Transfer container children to the target container
+ CDockContainer* pContainer = (CDockContainer*)GetView();
+ CDockContainer* pContainerSource = (CDockContainer*)pDock->GetView();
+
+ if (pContainerSource->GetAllContainers().size() > 1)
+ {
+ // The container we're about to add has children, so transfer those first
+ std::vector<ContainerInfo>::reverse_iterator riter;
+ std::vector<ContainerInfo> AllContainers = pContainerSource->GetAllContainers();
+ for ( riter = AllContainers.rbegin() ; riter < AllContainers.rend() -1; ++riter )
+ {
+ // Remove child container from pContainerSource
+ CDockContainer* pContainerChild = (*riter).pContainer;
+ pContainerChild->ShowWindow(SW_HIDE);
+ pContainerSource->RemoveContainer(pContainerChild);
+
+ // Add child container to this container
+ pContainer->AddContainer(pContainerChild);
+
+ CDocker* pDockChild = GetDockFromView(pContainerChild);
+ pDockChild->SetParent(this);
+ pDockChild->m_pDockParent = this;
+ }
+ }
+
+ pContainer->AddContainer((CDockContainer*)pDock->GetView());
+ pDock->m_pDockParent = this;
+ pDock->m_BlockMove = FALSE;
+ pDock->ShowWindow(SW_HIDE);
+ pDock->SetWindowLongPtr(GWL_STYLE, WS_CHILD);
+ pDock->SetDockStyle(dwDockStyle);
+ pDock->SetParent(this);
+ }
+ }
+
+ inline void CDocker::DockOuter(CDocker* pDocker, DWORD dwDockStyle)
+ // Docks the specified docker inside the dock ancestor
+ {
+ assert(pDocker);
+
+ pDocker->m_pDockParent = GetDockAncestor();
+
+ DWORD OuterDocking = dwDockStyle & 0xF0000;
+ DWORD DockSide = OuterDocking / 0x10000;
+ dwDockStyle &= 0xFFF0FFFF;
+ dwDockStyle |= DockSide;
+
+ // Set the dock styles
+ DWORD dwStyle = WS_CHILD | WS_VISIBLE;
+ pDocker->m_BlockMove = FALSE;
+ pDocker->SetWindowLongPtr(GWL_STYLE, dwStyle);
+ pDocker->ShowWindow(SW_HIDE);
+ pDocker->SetDockStyle(dwDockStyle);
+
+ // Set the docking relationships
+ std::vector<CDocker*>::iterator iter = GetDockAncestor()->m_vDockChildren.begin();
+ GetDockAncestor()->m_vDockChildren.insert(iter, pDocker);
+ pDocker->SetParent(GetDockAncestor());
+ pDocker->GetDockBar().SetParent(GetDockAncestor());
+
+ // Limit the docked size to half the parent's size if it won't fit inside parent
+ if (((dwDockStyle & 0xF) == DS_DOCKED_LEFT) || ((dwDockStyle &0xF) == DS_DOCKED_RIGHT))
+ {
+ int Width = GetDockAncestor()->GetDockClient().GetWindowRect().Width();
+ int BarWidth = pDocker->GetBarWidth();
+ if (pDocker->m_DockStartSize >= (Width - BarWidth))
+ pDocker->SetDockSize(MAX(Width/2 - BarWidth, BarWidth));
+
+ pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetDockAncestor()->GetWindowRect().Width();
+ }
+ else
+ {
+ int Height = GetDockAncestor()->GetDockClient().GetWindowRect().Height();
+ int BarWidth = pDocker->GetBarWidth();
+ if (pDocker->m_DockStartSize >= (Height - BarWidth))
+ pDocker->SetDockSize(MAX(Height/2 - BarWidth, BarWidth));
+
+ pDocker->m_DockSizeRatio = ((double)pDocker->m_DockStartSize) / (double)GetDockAncestor()->GetWindowRect().Height();
+ }
+
+ // Redraw the docked windows
+ GetAncestor()->SetFocus();
+ pDocker->GetView()->SetFocus();
+ RecalcDockLayout();
+ }
+
+ inline void CDocker::DrawAllCaptions()
+ {
+ std::vector<DockPtr>::iterator iter;
+ for (iter = GetAllDockers().begin(); iter != GetAllDockers().end(); iter++)
+ {
+ if ((*iter)->IsDocked())
+ (*iter)->GetDockClient().DrawCaption((WPARAM)1);
+ }
+ }
+
+ inline void CDocker::DrawHashBar(HWND hBar, POINT Pos)
+ // Draws a hashed bar while the splitter bar is being dragged
+ {
+ CDocker* pDock = ((CDockBar*)FromHandle(hBar))->GetDock();
+ if (NULL == pDock) return;
+
+ BOOL bVertical = ((pDock->GetDockStyle() & 0xF) == DS_DOCKED_LEFT) || ((pDock->GetDockStyle() & 0xF) == DS_DOCKED_RIGHT);
+
+ CClientDC dcBar(this);
+
+ WORD HashPattern[] = {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA};
+ CBitmap bmHash;
+ CBrush brDithered;
+ bmHash.CreateBitmap(8, 8, 1, 1, HashPattern);
+ brDithered.CreatePatternBrush(&bmHash);
+ dcBar.SelectObject(&brDithered);
+
+ CRect rc = FromHandle(hBar)->GetWindowRect();
+ ScreenToClient(rc);
+ int cx = rc.Width();
+ int cy = rc.Height();
+ int BarWidth = pDock->GetDockBar().GetWidth();
+
+ if (bVertical)
+ dcBar.PatBlt(Pos.x - BarWidth/2, rc.top, BarWidth, cy, PATINVERT);
+ else
+ dcBar.PatBlt(rc.left, Pos.y - BarWidth/2, cx, BarWidth, PATINVERT);
+ }
+
+ inline CDockContainer* CDocker::GetContainer() const
+ {
+ CDockContainer* pContainer = NULL;
+ if (dynamic_cast<CDockContainer*>(GetView()))
+ pContainer = (CDockContainer*)GetView();
+
+ return pContainer;
+ }
+
+ inline CDocker* CDocker::GetActiveDocker() const
+ // Returns the docker whose child window has focus
+ {
+ CWnd* pWnd = GetFocus();
+ CDocker* pDock= NULL;
+ while (pWnd && (pDock == NULL))
+ {
+ if (IsRelated(pWnd))
+ pDock = (CDocker*)pWnd;
+
+ pWnd = pWnd->GetParent();
+ }
+
+ return pDock;
+ }
+
+ inline CDocker* CDocker::GetDockAncestor() const
+ // The GetDockAncestor function retrieves the pointer to the
+ // ancestor (root docker parent) of the Docker.
+ {
+ return m_pDockAncestor;
+ }
+
+ inline CDocker* CDocker::GetDockFromPoint(POINT pt) const
+ // Retrieves the Docker whose view window contains the specified point
+ {
+ // Step 1: Find the top level Docker the point is over
+ CDocker* pDockTop = NULL;
+ CWnd* pAncestor = GetDockAncestor()->GetAncestor();
+
+ // Iterate through all top level windows
+ CWnd* pWnd = GetWindow(GW_HWNDFIRST);
+ while(pWnd)
+ {
+ if (IsRelated(pWnd) || pWnd == pAncestor)
+ {
+ CDocker* pDockTest;
+ if (pWnd == pAncestor)
+ pDockTest = GetDockAncestor();
+ else
+ pDockTest = (CDocker*)pWnd;
+
+ CRect rc = pDockTest->GetClientRect();
+ pDockTest->ClientToScreen(rc);
+ if ((this != pDockTest) && rc.PtInRect(pt))
+ {
+ pDockTop = pDockTest;
+ break;
+ }
+ }
+
+ pWnd = pWnd->GetWindow(GW_HWNDNEXT);
+ }
+
+ // Step 2: Find the docker child whose view window has the point
+ CDocker* pDockTarget = NULL;
+ if (pDockTop)
+ {
+ CDocker* pDockParent = pDockTop;
+ CDocker* pDockTest = pDockParent;
+
+ while (IsRelated(pDockTest))
+ {
+ pDockParent = pDockTest;
+ CPoint ptLocal = pt;
+ pDockParent->ScreenToClient(ptLocal);
+ pDockTest = (CDocker*)pDockParent->ChildWindowFromPoint(ptLocal);
+ assert (pDockTest != pDockParent);
+ }
+
+ CRect rc = pDockParent->GetDockClient().GetWindowRect();
+ if (rc.PtInRect(pt)) pDockTarget = pDockParent;
+ }
+
+ return pDockTarget;
+ }
+
+ inline CDocker* CDocker::GetDockFromID(int n_DockID) const
+ {
+ std::vector <DockPtr>::iterator v;
+
+ if (GetDockAncestor())
+ {
+ for (v = GetDockAncestor()->m_vAllDockers.begin(); v != GetDockAncestor()->m_vAllDockers.end(); v++)
+ {
+ if (n_DockID == (*v)->GetDockID())
+ return (*v).get();
+ }
+ }
+
+ return 0;
+ }
+
+ inline CDocker* CDocker::GetDockFromView(CWnd* pView) const
+ {
+ CDocker* pDock = 0;
+ std::vector<DockPtr>::iterator iter;
+ std::vector<DockPtr> AllDockers = GetAllDockers();
+ for (iter = AllDockers.begin(); iter != AllDockers.end(); ++iter)
+ {
+ if ((*iter)->GetView() == pView)
+ pDock = (*iter).get();
+ }
+
+ return pDock;
+ }
+
+ inline int CDocker::GetDockSize() const
+ {
+ // Returns the size of the docker to be used if it is redocked
+ // Note: This function returns 0 if the docker has the DS_DOCKED_CONTAINER style
+
+ CRect rcParent;
+ if (GetDockParent())
+ rcParent = GetDockParent()->GetWindowRect();
+ else
+ rcParent = GetDockAncestor()->GetWindowRect();
+
+ double DockSize = 0;
+ if ((GetDockStyle() & DS_DOCKED_LEFT) || (GetDockStyle() & DS_DOCKED_RIGHT))
+ DockSize = (double)(rcParent.Width()*m_DockSizeRatio);
+ else if ((GetDockStyle() & DS_DOCKED_TOP) || (GetDockStyle() & DS_DOCKED_BOTTOM))
+ DockSize = (double)(rcParent.Height()*m_DockSizeRatio);
+ else if ((GetDockStyle() & DS_DOCKED_CONTAINER))
+ DockSize = 0;
+
+ return (int)DockSize;
+ }
+
+ inline CDocker* CDocker::GetTopmostDocker() const
+ // Returns the docker's parent at the top of the Z order.
+ // Could be the dock ancestor or an undocked docker.
+ {
+ CDocker* pDockTopLevel = (CDocker* const)this;
+
+ while(pDockTopLevel->GetDockParent())
+ {
+ assert (pDockTopLevel != pDockTopLevel->GetDockParent());
+ pDockTopLevel = pDockTopLevel->GetDockParent();
+ }
+
+ return pDockTopLevel;
+ }
+
+ inline CTabbedMDI* CDocker::GetTabbedMDI() const
+ {
+ CTabbedMDI* pTabbedMDI = NULL;
+ if (dynamic_cast<CTabbedMDI*>(GetView()))
+ pTabbedMDI = (CTabbedMDI*)GetView();
+
+ return pTabbedMDI;
+ }
+
+ inline int CDocker::GetTextHeight()
+ {
+ NONCLIENTMETRICS nm = {0};
+ nm.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &nm, 0);
+ LOGFONT lf = nm.lfStatusFont;
+
+ CClientDC dc(this);
+ dc.CreateFontIndirect(&lf);
+ CSize szText = dc.GetTextExtentPoint32(_T("Text"), lstrlen(_T("Text")));
+ return szText.cy;
+ }
+
+ inline void CDocker::Hide()
+ {
+ // Undocks a docker (if needed) and hides it.
+ // Do unhide the docker, dock it.
+
+ if (IsDocked())
+ {
+ if (dynamic_cast<CDockContainer*>(GetView()))
+ {
+ CDockContainer* pContainer = GetContainer();
+ CDocker* pDock = GetDockFromView(pContainer->GetContainerParent());
+ pDock->UndockContainer(pContainer, GetCursorPos(), FALSE);
+ }
+ else
+ {
+ CDocker* pDockUndockedFrom = SeparateFromDock();
+ pDockUndockedFrom->RecalcDockLayout();
+ }
+ }
+
+ ShowWindow(SW_HIDE);
+ }
+
+ inline BOOL CDocker::IsChildOfDocker(CWnd* pWnd) const
+ // returns true if the specified window is a child of this docker
+ {
+ while ((pWnd != NULL) && (pWnd != GetDockAncestor()))
+ {
+ if (pWnd == (CWnd*)this) return TRUE;
+ if (IsRelated(pWnd)) break;
+ pWnd = pWnd->GetParent();
+ }
+
+ return FALSE;
+ }
+
+ inline BOOL CDocker::IsDocked() const
+ {
+ return (((m_DockStyle&0xF) || (m_DockStyle & DS_DOCKED_CONTAINER)) && !m_Undocking); // Boolean expression
+ }
+
+ inline BOOL CDocker::IsDragAutoResize()
+ {
+ return m_bDragAutoResize;
+ }
+
+ inline BOOL CDocker::IsRelated(CWnd* pWnd) const
+ // Returns TRUE if the hWnd is a docker within this dock family
+ {
+ if (GetDockAncestor() == pWnd) return TRUE;
+
+ std::vector<DockPtr>::iterator iter;
+ for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter)
+ {
+ if ((*iter).get() == pWnd) return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ inline BOOL CDocker::IsUndocked() const
+ {
+ return (!((m_DockStyle&0xF)|| (m_DockStyle & DS_DOCKED_CONTAINER)) && !m_Undocking); // Boolean expression
+ }
+
+ inline BOOL CDocker::LoadRegistrySettings(tString tsRegistryKeyName)
+ // Recreates the docker layout based on information stored in the registry.
+ // Assumes the DockAncestor window is already created.
+ {
+ BOOL bResult = FALSE;
+
+ if (0 != tsRegistryKeyName.size())
+ {
+ std::vector<DockInfo> vDockList;
+ std::vector<int> vActiveContainers;
+ tString tsKey = _T("Software\\") + tsRegistryKeyName + _T("\\Dock Windows");
+ HKEY hKey = 0;
+ RegOpenKeyEx(HKEY_CURRENT_USER, tsKey.c_str(), 0, KEY_READ, &hKey);
+ if (hKey)
+ {
+ DWORD dwType = REG_BINARY;
+ DWORD BufferSize = sizeof(DockInfo);
+ DockInfo di;
+ int i = 0;
+ TCHAR szNumber[20];
+ tString tsSubKey = _T("DockChild");
+ tsSubKey += _itot(i, szNumber, 10);
+
+ // Fill the DockList vector from the registry
+ while (0 == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&di, &BufferSize))
+ {
+ vDockList.push_back(di);
+ i++;
+ tsSubKey = _T("DockChild");
+ tsSubKey += _itot(i, szNumber, 10);
+ }
+
+ dwType = REG_DWORD;
+ BufferSize = sizeof(int);
+ int nID;
+ i = 0;
+ tsSubKey = _T("ActiveContainer");
+ tsSubKey += _itot(i, szNumber, 10);
+ // Fill the DockList vector from the registry
+ while (0 == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&nID, &BufferSize))
+ {
+ vActiveContainers.push_back(nID);
+ i++;
+ tsSubKey = _T("ActiveContainer");
+ tsSubKey += _itot(i, szNumber, 10);
+ }
+
+ RegCloseKey(hKey);
+ if (vDockList.size() > 0) bResult = TRUE;
+ }
+
+ // Add dockers without parents first
+ std::vector<DockInfo>::iterator iter;
+ for (iter = vDockList.begin(); iter < vDockList.end() ; ++iter)
+ {
+ DockInfo di = (*iter);
+ if (di.DockParentID == 0)
+ {
+ CDocker* pDocker = NewDockerFromID(di.DockID);
+ if (pDocker)
+ {
+ if (di.DockStyle & 0xF)
+ AddDockedChild(pDocker, di.DockStyle, di.DockSize, di.DockID);
+ else
+ AddUndockedChild(pDocker, di.DockStyle, di.DockSize, di.Rect, di.DockID);
+ }
+ else
+ {
+ TRACE(_T("Failed to add dockers without parents from registry"));
+ bResult = FALSE;
+ }
+ }
+ }
+
+ // Remove dockers without parents from vDockList
+ for (UINT n = (UINT)vDockList.size(); n > 0; --n)
+ {
+ iter = vDockList.begin() + n-1;
+ if ((*iter).DockParentID == 0)
+ vDockList.erase(iter);
+ }
+
+ // Add remaining dockers
+ while (vDockList.size() > 0)
+ {
+ bool bFound = false;
+ std::vector<DockInfo>::iterator iter;
+ for (iter = vDockList.begin(); iter < vDockList.end(); ++iter)
+ {
+ DockInfo di = *iter;
+ CDocker* pDockParent = GetDockFromID(di.DockParentID);
+
+ if (pDockParent != 0)
+ {
+ CDocker* pDock = NewDockerFromID(di.DockID);
+ if(pDock)
+ {
+ pDockParent->AddDockedChild(pDock, di.DockStyle, di.DockSize, di.DockID);
+ bFound = true;
+ }
+ else
+ {
+ TRACE(_T("Failed to add dockers with parents from registry"));
+ bResult = FALSE;
+ }
+
+ vDockList.erase(iter);
+ break;
+ }
+ }
+
+ if (!bFound)
+ {
+ TRACE(_T("Orphaned dockers stored in registry "));
+ bResult = FALSE;
+ break;
+ }
+ }
+
+ std::vector<int>::iterator iterID;
+ for (iterID = vActiveContainers.begin(); iterID < vActiveContainers.end(); ++iterID)
+ {
+ CDocker* pDocker = GetDockFromID(*iterID);
+ if (pDocker)
+ {
+ CDockContainer* pContainer = pDocker->GetContainer();
+ if (pContainer)
+ {
+ int nPage = pContainer->GetContainerIndex(pContainer);
+ if (nPage >= 0)
+ pContainer->SelectPage(nPage);
+ }
+ }
+ }
+ }
+
+ if (!bResult) CloseAllDockers();
+ return bResult;
+ }
+
+ inline void CDocker::MoveDockChildren(CDocker* pDockTarget)
+ // Used internally by Dock and Undock
+ {
+ assert(pDockTarget);
+
+ // Transfer any dock children from the current docker to the target docker
+ std::vector<CDocker*>::iterator iter;
+ for (iter = GetDockChildren().begin(); iter < GetDockChildren().end(); ++iter)
+ {
+ pDockTarget->GetDockChildren().push_back(*iter);
+ (*iter)->m_pDockParent = pDockTarget;
+ (*iter)->SetParent(pDockTarget);
+ (*iter)->GetDockBar().SetParent(pDockTarget);
+ }
+ GetDockChildren().clear();
+ }
+
+ inline CDocker* CDocker::NewDockerFromID(int nID)
+ // Used in LoadRegistrySettings. Creates a new Docker from the specified ID
+ {
+ UNREFERENCED_PARAMETER(nID);
+
+ // Override this function to create the Docker objects as shown below
+
+ CDocker* pDock = NULL;
+ /* switch(nID)
+ {
+ case ID_CLASSES:
+ pDock = new CDockClasses;
+ break;
+ case ID_FILES:
+ pDock = new CDockFiles;
+ break;
+ default:
+ TRACE(_T("Unknown Dock ID\n"));
+ break;
+ } */
+
+ return pDock;
+ }
+
+ inline void CDocker::OnActivate(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Only top level undocked dockers get this message
+ if (LOWORD(wParam) == WA_INACTIVE)
+ {
+ GetTopmostDocker()->m_hOldFocus = ::GetFocus();
+
+ // Send a notification of focus lost
+ int idCtrl = ::GetDlgCtrlID(m_hOldFocus);
+ NMHDR nhdr={0};
+ nhdr.hwndFrom = m_hOldFocus;
+ nhdr.idFrom = idCtrl;
+ nhdr.code = UWM_FRAMELOSTFOCUS;
+ SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr);
+ }
+ }
+
+ inline void CDocker::OnCaptionTimer(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(lParam);
+
+ if (this == GetDockAncestor())
+ {
+ if (wParam == 1)
+ {
+ DrawAllCaptions();
+ m_nTimerCount++;
+ if (m_nTimerCount == 10)
+ {
+ KillTimer(wParam);
+ m_nTimerCount = 0;
+ }
+ }
+ }
+ }
+
+ inline void CDocker::OnCreate()
+ {
+
+#if defined(WINVER) && defined (WS_EX_LAYOUTRTL) && (WINVER >= 0x0500)
+ if (GetParent()->GetWindowLongPtr(GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
+ {
+ DWORD dwExStyle = GetWindowLongPtr(GWL_EXSTYLE);
+ SetWindowLongPtr(GWL_EXSTYLE, dwExStyle | WS_EX_LAYOUTRTL);
+ }
+#endif
+
+ // Create the various child windows
+ GetDockClient().SetDock(this);
+ GetDockClient().Create(this);
+
+ assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window
+ GetView()->Create(&GetDockClient());
+
+ // Create the slider bar belonging to this docker
+ GetDockBar().SetDock(this);
+ if (GetDockAncestor() != this)
+ GetDockBar().Create(GetParent());
+
+ // Now remove the WS_POPUP style. It was required to allow this window
+ // to be owned by the frame window.
+ SetWindowLongPtr(GWL_STYLE, WS_CHILD);
+ SetParent(GetParent()); // Reinstate the window's parent
+
+ // Set the default colour for the splitter bar
+ COLORREF rgbColour = GetSysColor(COLOR_BTNFACE);
+ CWnd* pFrame = GetDockAncestor()->GetAncestor();
+ ReBarTheme* pTheme = (ReBarTheme*)pFrame->SendMessage(UWM_GETREBARTHEME, 0, 0);
+
+ if (pTheme && pTheme->UseThemes && pTheme->clrBkgnd2 != 0)
+ rgbColour =pTheme->clrBkgnd2;
+
+ SetBarColor(rgbColour);
+
+ // Set the caption height based on text height
+ m_NCHeight = MAX(20, GetTextHeight() + 5);
+ }
+
+ inline void CDocker::OnDestroy(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Destroy any dock children first
+ std::vector<CDocker*>::iterator iter;
+ for (iter = GetDockChildren().begin(); iter < GetDockChildren().end(); ++iter)
+ {
+ (*iter)->Destroy();
+ }
+
+ if (dynamic_cast<CDockContainer*>(GetView()) && IsUndocked())
+ {
+ CDockContainer* pContainer = (CDockContainer*)GetView();
+ if (pContainer->GetAllContainers().size() > 1)
+ {
+ // This container has children, so destroy them now
+ std::vector<ContainerInfo> AllContainers = pContainer->GetAllContainers();
+ std::vector<ContainerInfo>::iterator iter;
+ for (iter = AllContainers.begin(); iter < AllContainers.end(); ++iter)
+ {
+ if ((*iter).pContainer != pContainer)
+ {
+ // Reset container parent before destroying the dock window
+ CDocker* pDock = GetDockFromView((*iter).pContainer);
+ if (pContainer->IsWindow())
+ pContainer->SetParent(&pDock->GetDockClient());
+
+ pDock->Destroy();
+ }
+ }
+ }
+ }
+
+ GetDockBar().Destroy();
+
+ // Post a destroy docker message
+ if ( GetDockAncestor()->IsWindow() )
+ GetDockAncestor()->PostMessage(UWM_DOCK_DESTROYED, (WPARAM)this, 0L);
+ }
+
+ inline void CDocker::OnDockDestroyed(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(lParam);
+
+ CDocker* pDock = (CDocker*)wParam;
+
+ assert( this == GetDockAncestor() );
+ std::vector<DockPtr>::iterator iter;
+ for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter)
+ {
+ if ((*iter).get() == pDock)
+ {
+ GetAllDockers().erase(iter);
+ break;
+ }
+ }
+ }
+
+ inline void CDocker::OnExitSizeMove(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ m_BlockMove = FALSE;
+ m_bIsDragging = FALSE;
+ SendNotify(UWM_DOCK_END);
+ }
+
+ inline LRESULT CDocker::OnNotify(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ LPDRAGPOS pdp = (LPDRAGPOS)lParam;
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case UWM_DOCK_START:
+ {
+ if (IsDocked())
+ {
+ Undock(GetCursorPos());
+ SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pdp->ptPos.x, pdp->ptPos.y));
+ }
+ }
+ break;
+
+ case UWM_DOCK_MOVE:
+ {
+ CheckAllTargets((LPDRAGPOS)lParam);
+ }
+ break;
+
+ case UWM_DOCK_END:
+ {
+ CDocker* pDock = (CDocker*)FromHandle(pdp->hdr.hwndFrom);
+ if (NULL == pDock) break;
+
+ UINT DockZone = pdp->DockZone;
+ CRect rc = pDock->GetWindowRect();
+
+ switch(DockZone)
+ {
+ case DS_DOCKED_LEFT:
+ case DS_DOCKED_RIGHT:
+ pDock->SetDockSize(rc.Width());
+ Dock(pDock, pDock->GetDockStyle() | DockZone);
+ break;
+ case DS_DOCKED_TOP:
+ case DS_DOCKED_BOTTOM:
+ pDock->SetDockSize(rc.Height());
+ Dock(pDock, pDock->GetDockStyle() | DockZone);
+ break;
+ case DS_DOCKED_CONTAINER:
+ {
+ DockInContainer(pDock, pDock->GetDockStyle() | DockZone);
+ CDockContainer* pContainer = (CDockContainer*)GetView();
+ int nPage = pContainer->GetContainerIndex((CDockContainer*)pDock->GetView());
+ pContainer->SelectPage(nPage);
+ }
+ break;
+ case DS_DOCKED_LEFTMOST:
+ case DS_DOCKED_RIGHTMOST:
+ pDock->SetDockSize(rc.Width());
+ DockOuter(pDock, pDock->GetDockStyle() | DockZone);
+ break;
+ case DS_DOCKED_TOPMOST:
+ case DS_DOCKED_BOTTOMMOST:
+ pDock->SetDockSize(rc.Height());
+ DockOuter(pDock, pDock->GetDockStyle() | DockZone);
+ break;
+ }
+
+ GetDockHint().Destroy();
+ CloseAllTargets();
+ }
+ break;
+
+ case UWM_BAR_START:
+ {
+ CPoint pt = pdp->ptPos;
+ ScreenToClient(pt);
+ if (!IsDragAutoResize())
+ DrawHashBar(pdp->hdr.hwndFrom, pt);
+ m_OldPoint = pt;
+ }
+ break;
+
+ case UWM_BAR_MOVE:
+ {
+ CPoint pt = pdp->ptPos;
+ ScreenToClient(pt);
+
+ if (pt != m_OldPoint)
+ {
+ if (IsDragAutoResize())
+ ResizeDockers(pdp);
+ else
+ {
+ DrawHashBar(pdp->hdr.hwndFrom, m_OldPoint);
+ DrawHashBar(pdp->hdr.hwndFrom, pt);
+ }
+
+ m_OldPoint = pt;
+ }
+ }
+ break;
+
+ case UWM_BAR_END:
+ {
+ POINT pt = pdp->ptPos;
+ ScreenToClient(pt);
+
+ if (!IsDragAutoResize())
+ DrawHashBar(pdp->hdr.hwndFrom, pt);
+
+ ResizeDockers(pdp);
+ }
+ break;
+ case NM_SETFOCUS:
+ if (GetDockAncestor()->IsWindow())
+ GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0);
+ break;
+ case UWM_FRAMEGOTFOCUS:
+ if (GetDockAncestor()->IsWindow())
+ GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0);
+ if (GetView()->IsWindow())
+ GetView()->SendMessage(WM_NOTIFY, wParam, lParam);
+ break;
+ case UWM_FRAMELOSTFOCUS:
+ if (GetDockAncestor()->IsWindow())
+ GetDockAncestor()->PostMessage(UWM_DOCK_ACTIVATED, 0, 0);
+ if (GetView()->IsWindow())
+ GetView()->SendMessage(WM_NOTIFY, wParam, lParam);
+ break;
+ }
+ return 0L;
+ }
+
+ inline void CDocker::ResizeDockers(LPDRAGPOS pdp)
+ // Called when the docker's splitter bar is dragged
+ {
+ assert(pdp);
+
+ POINT pt = pdp->ptPos;
+ ScreenToClient(pt);
+
+ CDocker* pDock = ((CDockBar*)FromHandle(pdp->hdr.hwndFrom))->GetDock();
+ if (NULL == pDock) return;
+
+ RECT rcDock = pDock->GetWindowRect();
+ ScreenToClient(rcDock);
+
+ double dBarWidth = pDock->GetDockBar().GetWidth();
+ int iBarWidth = pDock->GetDockBar().GetWidth();
+ int DockSize;
+
+ switch (pDock->GetDockStyle() & 0xF)
+ {
+ case DS_DOCKED_LEFT:
+ DockSize = MAX(pt.x, iBarWidth/2) - rcDock.left - (int)(.5* dBarWidth);
+ DockSize = MAX(-iBarWidth, DockSize);
+ pDock->SetDockSize(DockSize);
+ pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Width());
+ break;
+ case DS_DOCKED_RIGHT:
+ DockSize = rcDock.right - MAX(pt.x, iBarWidth/2) - (int)(.5* dBarWidth);
+ DockSize = MAX(-iBarWidth, DockSize);
+ pDock->SetDockSize(DockSize);
+ pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Width());
+ break;
+ case DS_DOCKED_TOP:
+ DockSize = MAX(pt.y, iBarWidth/2) - rcDock.top - (int)(.5* dBarWidth);
+ DockSize = MAX(-iBarWidth, DockSize);
+ pDock->SetDockSize(DockSize);
+ pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Height());
+ break;
+ case DS_DOCKED_BOTTOM:
+ DockSize = rcDock.bottom - MAX(pt.y, iBarWidth/2) - (int)(.5* dBarWidth);
+ DockSize = MAX(-iBarWidth, DockSize);
+ pDock->SetDockSize(DockSize);
+ pDock->m_DockSizeRatio = ((double)pDock->m_DockStartSize)/((double)pDock->m_pDockParent->GetWindowRect().Height());
+ break;
+ }
+
+ RecalcDockLayout();
+ }
+
+ inline void CDocker::OnSetFocus(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ if (IsUndocked() && m_hOldFocus)
+ ::SetFocus(m_hOldFocus);
+ else
+ // Pass focus on the the view window
+ GetView()->SetFocus();
+
+ if ((this == GetTopmostDocker()) && (this != GetDockAncestor()))
+ {
+ // Send a notification to top level window
+ int idCtrl = ::GetDlgCtrlID(m_hOldFocus);
+ NMHDR nhdr={0};
+ nhdr.hwndFrom = m_hOldFocus;
+ nhdr.idFrom = idCtrl;
+ nhdr.code = NM_SETFOCUS;
+ SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr);
+ }
+ }
+
+ inline void CDocker::OnSysColorChange(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ if (this == GetDockAncestor())
+ {
+ COLORREF rgbColour = GetSysColor(COLOR_BTNFACE);
+ CWnd* pFrame = GetDockAncestor()->GetAncestor();
+ ReBarTheme* pTheme = (ReBarTheme*)pFrame->SendMessage(UWM_GETREBARTHEME, 0, 0);
+
+ if (pTheme && pTheme->UseThemes && pTheme->clrBand2 != 0)
+ rgbColour = pTheme->clrBkgnd2;
+ else
+ rgbColour = GetSysColor(COLOR_BTNFACE);
+
+ // Set the splitter bar colour for each docker decendant
+ std::vector<DockPtr>::iterator iter;
+ for (iter = GetAllDockers().begin(); iter < GetAllDockers().end(); ++iter)
+ (*iter)->SetBarColor(rgbColour);
+
+ // Set the splitter bar colour for the docker ancestor
+ SetBarColor(rgbColour);
+ }
+ }
+
+ inline LRESULT CDocker::OnSysCommand(WPARAM wParam, LPARAM lParam)
+ {
+ switch(wParam&0xFFF0)
+ {
+ case SC_MOVE:
+ // An undocked docker is being moved
+ {
+ BOOL bResult = FALSE;
+ m_bIsDragging = TRUE;
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ if (SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &bResult, 0))
+ {
+ // Turn on DragFullWindows for this move
+ SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, 0, 0);
+
+ // Process this message
+ DefWindowProc(WM_SYSCOMMAND, wParam, lParam);
+
+ // Return DragFullWindows to its previous state
+ SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, bResult, 0, 0);
+ return 0L;
+ }
+ }
+ break;
+ case SC_CLOSE:
+ // The close button is pressed on an undocked docker
+ m_bIsClosing = TRUE;
+ break;
+ }
+ return CWnd::WndProcDefault(WM_SYSCOMMAND, wParam, lParam);
+ }
+
+ inline LRESULT CDocker::OnWindowPosChanging(WPARAM wParam, LPARAM lParam)
+ {
+ // Suspend dock drag moving while over dock zone
+ if (m_BlockMove)
+ {
+ LPWINDOWPOS pWndPos = (LPWINDOWPOS)lParam;
+ pWndPos->flags |= SWP_NOMOVE|SWP_FRAMECHANGED;
+ return 0;
+ }
+
+ return CWnd::WndProcDefault(WM_WINDOWPOSCHANGING, wParam, lParam);
+ }
+
+ inline void CDocker::OnWindowPosChanged(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ if (m_bIsDragging)
+ {
+ // Send a Move notification to the parent
+ if ( IsLeftButtonDown() )
+ {
+ LPWINDOWPOS wPos = (LPWINDOWPOS)lParam;
+ if ((!(wPos->flags & SWP_NOMOVE)) || m_BlockMove)
+ SendNotify(UWM_DOCK_MOVE);
+ }
+ else
+ {
+ CloseAllTargets();
+ m_BlockMove = FALSE;
+ }
+ }
+ else if (this == GetTopmostDocker())
+ {
+ // Reposition the dock children
+ if (IsUndocked() && IsWindowVisible() && !m_bIsClosing) RecalcDockLayout();
+ }
+ }
+
+ inline void CDocker::PreCreate(CREATESTRUCT &cs)
+ {
+ // Specify the WS_POPUP style to have this window owned
+ if (this != GetDockAncestor())
+ cs.style = WS_POPUP;
+
+ cs.dwExStyle = WS_EX_TOOLWINDOW;
+ }
+
+ inline void CDocker::PreRegisterClass(WNDCLASS &wc)
+ {
+ wc.lpszClassName = _T("Win32++ Docker");
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ }
+
+ inline void CDocker::RecalcDockChildLayout(CRect rc)
+ {
+ // This function positions the Docker's dock children, the Dockers client area
+ // and draws the dockbar bars.
+
+ // Notes:
+ // 1) This function is called recursively.
+ // 2) The client area and child dockers are positioned simultaneously with
+ // DeferWindowPos to avoid drawing errors in complex docker arrangements.
+ // 3) The docker's client area contains the docker's caption (if any) and the docker's view window.
+
+ // Note: All top level dockers are undocked, including the dock ancestor.
+ if (IsDocked())
+ {
+ rc.OffsetRect(-rc.left, -rc.top);
+ }
+
+ HDWP hdwp = BeginDeferWindowPos((int)m_vDockChildren.size() +2);
+
+ // Step 1: Calculate the position of each Docker child, DockBar, and Client window.
+ // The Client area = the docker rect minus the area of dock children and the dock bar (splitter bar).
+ for (UINT u = 0; u < m_vDockChildren.size(); ++u)
+ {
+ CRect rcChild = rc;
+ double DockSize = m_vDockChildren[u]->m_DockStartSize;;
+
+ // Calculate the size of the Docker children
+ switch (m_vDockChildren[u]->GetDockStyle() & 0xF)
+ {
+ case DS_DOCKED_LEFT:
+ if (!(GetDockStyle() & DS_FIXED_RESIZE))
+ DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Width()), rcChild.Width());
+ rcChild.right = rcChild.left + (int)DockSize;
+ break;
+ case DS_DOCKED_RIGHT:
+ if (!(GetDockStyle() & DS_FIXED_RESIZE))
+ DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Width()), rcChild.Width());
+ rcChild.left = rcChild.right - (int)DockSize;
+ break;
+ case DS_DOCKED_TOP:
+ if (!(GetDockStyle() & DS_FIXED_RESIZE))
+ DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Height()), rcChild.Height());
+ rcChild.bottom = rcChild.top + (int)DockSize;
+ break;
+ case DS_DOCKED_BOTTOM:
+ if (!(GetDockStyle() & DS_FIXED_RESIZE))
+ DockSize = MIN(m_vDockChildren[u]->m_DockSizeRatio*(GetWindowRect().Height()), rcChild.Height());
+ rcChild.top = rcChild.bottom - (int)DockSize;
+ break;
+ }
+
+ if (m_vDockChildren[u]->IsDocked())
+ {
+ // Position this docker's children
+ hdwp = m_vDockChildren[u]->DeferWindowPos(hdwp, NULL, rcChild, SWP_SHOWWINDOW|SWP_FRAMECHANGED);
+ m_vDockChildren[u]->m_rcChild = rcChild;
+
+ rc.SubtractRect(rc, rcChild);
+
+ // Calculate the dimensions of the splitter bar
+ CRect rcBar = rc;
+ DWORD DockSide = m_vDockChildren[u]->GetDockStyle() & 0xF;
+
+ if (DS_DOCKED_LEFT == DockSide) rcBar.right = rcBar.left + m_vDockChildren[u]->GetBarWidth();
+ if (DS_DOCKED_RIGHT == DockSide) rcBar.left = rcBar.right - m_vDockChildren[u]->GetBarWidth();
+ if (DS_DOCKED_TOP == DockSide) rcBar.bottom = rcBar.top + m_vDockChildren[u]->GetBarWidth();
+ if (DS_DOCKED_BOTTOM == DockSide) rcBar.top = rcBar.bottom - m_vDockChildren[u]->GetBarWidth();
+
+ // Save the splitter bar position. We will reposition it later.
+ m_vDockChildren[u]->m_rcBar = rcBar;
+ rc.SubtractRect(rc, rcBar);
+ }
+ }
+
+ // Step 2: Position the Dock client and dock bar
+ hdwp = GetDockClient().DeferWindowPos(hdwp, NULL, rc, SWP_SHOWWINDOW |SWP_FRAMECHANGED);
+ EndDeferWindowPos(hdwp);
+
+ // Position the dockbar. Only docked dockers have a dock bar.
+ if (IsDocked())
+ {
+ // The SWP_NOCOPYBITS forces a redraw of the dock bar.
+ GetDockBar().SetWindowPos(NULL, m_rcBar, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS );
+ }
+
+ // Step 3: Now recurse through the docker's children. They might have children of their own.
+ for (UINT v = 0; v < m_vDockChildren.size(); ++v)
+ {
+ m_vDockChildren[v]->RecalcDockChildLayout(m_vDockChildren[v]->m_rcChild);
+ }
+ }
+
+ inline void CDocker::RecalcDockLayout()
+ // Repositions the dock children of a top level docker
+ {
+ if (GetDockAncestor()->IsWindow())
+ {
+ CRect rc = GetTopmostDocker()->GetClientRect();
+ GetTopmostDocker()->RecalcDockChildLayout(rc);
+ GetTopmostDocker()->UpdateWindow();
+ }
+ }
+
+ inline std::vector<CDocker*> CDocker::SortDockers()
+ // Returns a vector of sorted dockers, used by SaveRegistrySettings.
+ {
+ std::vector<CDocker*> vSorted;
+ std::vector<CDocker*>::iterator itSort;
+ std::vector<DockPtr>::iterator itAll;
+
+ // Add undocked top level dockers
+ for (itAll = GetAllDockers().begin(); itAll < GetAllDockers().end(); ++itAll)
+ {
+ if (!(*itAll)->GetDockParent())
+ vSorted.push_back((*itAll).get());
+ }
+
+ // Add dock ancestor's children
+ vSorted.insert(vSorted.end(), GetDockAncestor()->GetDockChildren().begin(), GetDockAncestor()->GetDockChildren().end());
+
+ // Add other dock children
+ int index = 0;
+ itSort = vSorted.begin();
+ while (itSort < vSorted.end())
+ {
+ vSorted.insert(vSorted.end(), (*itSort)->GetDockChildren().begin(), (*itSort)->GetDockChildren().end());
+ itSort = vSorted.begin() + (++index);
+ }
+
+ // Add dockers docked in containers
+ std::vector<CDocker*> vDockContainers;
+ for (itSort = vSorted.begin(); itSort< vSorted.end(); ++itSort)
+ {
+ if ((*itSort)->GetContainer())
+ vDockContainers.push_back(*itSort);
+ }
+
+ for (itSort = vDockContainers.begin(); itSort < vDockContainers.end(); ++itSort)
+ {
+ CDockContainer* pContainer = (*itSort)->GetContainer();
+
+ for (UINT i = 1; i < pContainer->GetAllContainers().size(); ++i)
+ {
+ CDockContainer* pChild = pContainer->GetContainerFromIndex(i);
+ CDocker* pDock = GetDockFromView(pChild);
+ vSorted.push_back(pDock);
+ }
+ }
+
+ return vSorted;
+ }
+
+ inline BOOL CDocker::SaveRegistrySettings(tString tsRegistryKeyName)
+ // Stores the docking configuration in the registry
+ // NOTE: This function assumes that each docker has a unique DockID
+ {
+ assert(VerifyDockers());
+
+ std::vector<CDocker*> vSorted = SortDockers();
+ std::vector<CDocker*>::iterator iter;
+ std::vector<DockInfo> vDockInfo;
+
+ if (0 != tsRegistryKeyName.size())
+ {
+ // Fill the DockInfo vector with the docking information
+ for (iter = vSorted.begin(); iter < vSorted.end(); ++iter)
+ {
+ DockInfo di = {0};
+ di.DockID = (*iter)->GetDockID();
+ di.DockStyle = (*iter)->GetDockStyle();
+ di.DockSize = (*iter)->GetDockSize();
+ di.Rect = (*iter)->GetWindowRect();
+ if ((*iter)->GetDockParent())
+ di.DockParentID = (*iter)->GetDockParent()->GetDockID();
+
+ vDockInfo.push_back(di);
+ }
+
+ tString tsKeyName = _T("Software\\") + tsRegistryKeyName;
+ HKEY hKey = NULL;
+ HKEY hKeyDock = NULL;
+
+ try
+ {
+ if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, tsKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
+ throw (CWinException(_T("RegCreateKeyEx Failed")));
+
+ RegDeleteKey(hKey, _T("Dock Windows"));
+ if (ERROR_SUCCESS != RegCreateKeyEx(hKey, _T("Dock Windows"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDock, NULL))
+ throw (CWinException(_T("RegCreateKeyEx Failed")));
+
+ // Add the Dock windows information to the registry
+ for (UINT u = 0; u < vDockInfo.size(); ++u)
+ {
+ DockInfo di = vDockInfo[u];
+ TCHAR szNumber[16];
+ tString tsSubKey = _T("DockChild");
+ tsSubKey += _itot((int)u, szNumber, 10);
+ if(ERROR_SUCCESS != RegSetValueEx(hKeyDock, tsSubKey.c_str(), 0, REG_BINARY, (LPBYTE)&di, sizeof(DockInfo)))
+ throw (CWinException(_T("RegSetValueEx failed")));
+ }
+
+ // Add Active Container to the registry
+ int i = 0;
+ for (iter = vSorted.begin(); iter < vSorted.end(); ++iter)
+ {
+ CDockContainer* pContainer = (*iter)->GetContainer();
+
+ if (pContainer && (pContainer == pContainer->GetActiveContainer()))
+ {
+ TCHAR szNumber[20];
+ tString tsSubKey = _T("ActiveContainer");
+ tsSubKey += _itot(i++, szNumber, 10);
+ int nID = GetDockFromView(pContainer)->GetDockID();
+ if(ERROR_SUCCESS != RegSetValueEx(hKeyDock, tsSubKey.c_str(), 0, REG_DWORD, (LPBYTE)&nID, sizeof(int)))
+ throw (CWinException(_T("RegSetValueEx failed")));
+ }
+ }
+
+ RegCloseKey(hKeyDock);
+ RegCloseKey(hKey);
+ }
+
+ catch (const CWinException& e)
+ {
+ // Roll back the registry changes by deleting the subkeys
+ if (hKey)
+ {
+ if (hKeyDock)
+ {
+ RegDeleteKey(hKeyDock, _T("Dock Windows"));
+ RegCloseKey(hKeyDock);
+ }
+
+ RegDeleteKey(HKEY_CURRENT_USER ,tsKeyName.c_str());
+ RegCloseKey(hKey);
+ }
+
+ e.what();
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ inline void CDocker::SendNotify(UINT nMessageID)
+ // Sends a docking notification to the docker below the cursor
+ {
+ DRAGPOS DragPos;
+ DragPos.hdr.code = nMessageID;
+ DragPos.hdr.hwndFrom = m_hWnd;
+ DragPos.ptPos = GetCursorPos();
+ DragPos.DockZone = m_dwDockZone;
+ m_dwDockZone = 0;
+
+ CDocker* pDock = GetDockFromPoint(DragPos.ptPos);
+
+ if (pDock)
+ pDock->SendMessage(WM_NOTIFY, 0L, (LPARAM)&DragPos);
+ else
+ {
+ if (GetDockHint().IsWindow()) GetDockHint().Destroy();
+ CloseAllTargets();
+ m_BlockMove = FALSE;
+ }
+ }
+
+ inline void CDocker::SetDockStyle(DWORD dwDockStyle)
+ {
+ if (IsWindow())
+ {
+ if ((dwDockStyle & DS_CLIENTEDGE) != (m_DockStyle & DS_CLIENTEDGE))
+ {
+ if (dwDockStyle & DS_CLIENTEDGE)
+ {
+ DWORD dwExStyle = (DWORD)GetDockClient().GetWindowLongPtr(GWL_EXSTYLE)|WS_EX_CLIENTEDGE;
+ GetDockClient().SetWindowLongPtr(GWL_EXSTYLE, dwExStyle);
+ GetDockClient().RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME);
+ }
+ else
+ {
+ DWORD dwExStyle = (DWORD)GetDockClient().GetWindowLongPtr(GWL_EXSTYLE);
+ dwExStyle &= ~WS_EX_CLIENTEDGE;
+ GetDockClient().SetWindowLongPtr(GWL_EXSTYLE, dwExStyle);
+ GetDockClient().RedrawWindow(0, 0, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME);
+ }
+ }
+
+ RecalcDockLayout();
+ }
+
+ m_DockStyle = dwDockStyle;
+ }
+
+ inline void CDocker::SetCaption(LPCTSTR szCaption)
+ // Sets the caption text
+ {
+ GetDockClient().SetCaption(szCaption);
+
+ if (IsWindow())
+ SetWindowText(szCaption);
+ }
+
+ inline void CDocker::SetCaptionColors(COLORREF Foregnd1, COLORREF Backgnd1, COLORREF ForeGnd2, COLORREF BackGnd2)
+ {
+ GetDockClient().SetCaptionColors(Foregnd1, Backgnd1, ForeGnd2, BackGnd2);
+ }
+
+ inline void CDocker::SetCaptionHeight(int nHeight)
+ // Sets the height of the caption
+ {
+ m_NCHeight = nHeight;
+ RedrawWindow();
+ RecalcDockLayout();
+ }
+
+ inline void CDocker::SetDockSize(int DockSize)
+ // Sets the size of a docked docker
+ {
+ if (IsDocked())
+ {
+ assert (m_pDockParent);
+ switch (GetDockStyle() & 0xF)
+ {
+ case DS_DOCKED_LEFT:
+ m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Width());
+ m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Width());
+ break;
+ case DS_DOCKED_RIGHT:
+ m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Width());
+ m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Width());
+ break;
+ case DS_DOCKED_TOP:
+ m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Height());
+ m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Height());
+ break;
+ case DS_DOCKED_BOTTOM:
+ m_DockStartSize = MIN(DockSize,m_pDockParent->GetWindowRect().Height());
+ m_DockSizeRatio = ((double)m_DockStartSize)/((double)m_pDockParent->GetWindowRect().Height());
+ break;
+ }
+
+ RecalcDockLayout();
+ }
+ else
+ {
+ m_DockStartSize = DockSize;
+ m_DockSizeRatio = 1.0;
+ }
+ }
+
+ inline void CDocker::SetDragAutoResize(BOOL bAutoResize)
+ {
+ m_bDragAutoResize = bAutoResize;
+ }
+
+ inline void CDocker::SetView(CWnd& wndView)
+ // Assigns the view window to the docker
+ {
+ CWnd* pWnd = &wndView;
+ GetDockClient().SetView(wndView);
+ if (dynamic_cast<CDockContainer*>(pWnd))
+ {
+ CDockContainer* pContainer = (CDockContainer*)&wndView;
+ SetCaption(pContainer->GetDockCaption().c_str());
+ }
+ }
+
+ inline void CDocker::PromoteFirstChild()
+ // One of the steps required for undocking
+ {
+ // Promote our first child to replace ourself
+ if (m_pDockParent)
+ {
+ for (UINT u = 0 ; u < m_pDockParent->m_vDockChildren.size(); ++u)
+ {
+ if (m_pDockParent->m_vDockChildren[u] == this)
+ {
+ if (m_vDockChildren.size() > 0)
+ // swap our first child for ourself as a child of the parent
+ m_pDockParent->m_vDockChildren[u] = m_vDockChildren[0];
+ else
+ // remove ourself as a child of the parent
+ m_pDockParent->m_vDockChildren.erase(m_pDockParent->m_vDockChildren.begin() + u);
+ break;
+ }
+ }
+ }
+
+ // Transfer styles and data and children to the child docker
+ CDocker* pDockFirstChild = NULL;
+ if (m_vDockChildren.size() > 0)
+ {
+ pDockFirstChild = m_vDockChildren[0];
+ pDockFirstChild->m_DockStyle = (pDockFirstChild->m_DockStyle & 0xFFFFFFF0 ) | (m_DockStyle & 0xF);
+ pDockFirstChild->m_DockStartSize = m_DockStartSize;
+ pDockFirstChild->m_DockSizeRatio = m_DockSizeRatio;
+
+ if (m_pDockParent)
+ {
+ pDockFirstChild->m_pDockParent = m_pDockParent;
+ pDockFirstChild->SetParent(m_pDockParent);
+ pDockFirstChild->GetDockBar().SetParent(m_pDockParent);
+ }
+ else
+ {
+ std::vector<CDocker*>::iterator iter;
+ for (iter = GetDockChildren().begin() + 1; iter < GetDockChildren().end(); ++iter)
+ (*iter)->ShowWindow(SW_HIDE);
+
+ pDockFirstChild->ConvertToPopup(GetWindowRect());
+ pDockFirstChild->GetDockBar().ShowWindow(SW_HIDE);
+ }
+
+ m_vDockChildren.erase(m_vDockChildren.begin());
+ MoveDockChildren(pDockFirstChild);
+ }
+ }
+
+ inline void CDocker::ConvertToChild(HWND hWndParent)
+ {
+ DWORD dwStyle = WS_CHILD | WS_VISIBLE;
+ SetWindowLongPtr(GWL_STYLE, dwStyle);
+ SetParent(FromHandle(hWndParent));
+ GetDockBar().SetParent(FromHandle(hWndParent));
+ }
+
+ inline void CDocker::ConvertToPopup(RECT rc)
+ {
+ // Change the window to an "undocked" style
+ ShowWindow(SW_HIDE);
+ DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
+ SetWindowLongPtr(GWL_STYLE, dwStyle);
+
+ // Change the window's parent and reposition it
+ GetDockBar().ShowWindow(SW_HIDE);
+ SetWindowPos(0, 0, 0, 0, 0, SWP_NOSENDCHANGING|SWP_HIDEWINDOW|SWP_NOREDRAW);
+ m_pDockParent = 0;
+ SetParent(0);
+ SetWindowPos(NULL, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOOWNERZORDER);
+ GetDockClient().SetWindowPos(NULL, GetClientRect(), SWP_SHOWWINDOW);
+
+ SetWindowText(GetCaption().c_str());
+ }
+
+ inline CDocker* CDocker::SeparateFromDock()
+ {
+ // This performs some of the tasks required for undocking.
+ // It is also used when a docker is hidden.
+ CDocker* pDockUndockedFrom = GetDockParent();
+ if (!pDockUndockedFrom && (GetDockChildren().size() > 0))
+ pDockUndockedFrom = GetDockChildren()[0];
+
+ GetTopmostDocker()->m_hOldFocus = 0;
+ PromoteFirstChild();
+ m_pDockParent = 0;
+
+ GetDockBar().ShowWindow(SW_HIDE);
+ m_DockStyle = m_DockStyle & 0xFFFFFFF0;
+ m_DockStyle &= ~DS_DOCKED_CONTAINER;
+
+ return pDockUndockedFrom;
+ }
+
+ inline void CDocker::SetUndockPosition(CPoint pt)
+ {
+ m_Undocking = TRUE;
+ CRect rc;
+ rc = GetDockClient().GetWindowRect();
+ CRect rcTest = rc;
+ rcTest.bottom = MIN(rcTest.bottom, rcTest.top + m_NCHeight);
+ if ( !rcTest.PtInRect(pt))
+ rc.SetRect(pt.x - rc.Width()/2, pt.y - m_NCHeight/2, pt.x + rc.Width()/2, pt.y - m_NCHeight/2 + rc.Height());
+
+ ConvertToPopup(rc);
+ m_Undocking = FALSE;
+
+ // Send the undock notification to the frame
+ NMHDR nmhdr = {0};
+ nmhdr.hwndFrom = m_hWnd;
+ nmhdr.code = UWM_UNDOCKED;
+ nmhdr.idFrom = m_nDockID;
+ CWnd* pFrame = GetDockAncestor()->GetAncestor();
+ pFrame->SendMessage(WM_NOTIFY, m_nDockID, (LPARAM)&nmhdr);
+
+ // Initiate the window move
+ SetCursorPos(pt.x, pt.y);
+ ScreenToClient(pt);
+ PostMessage(WM_SYSCOMMAND, (WPARAM)(SC_MOVE|0x0002), MAKELPARAM(pt.x, pt.y));
+ }
+
+ inline void CDocker::Undock(CPoint pt, BOOL bShowUndocked)
+ {
+ // Return if we shouldn't undock
+ if (GetDockStyle() & DS_NO_UNDOCK) return;
+
+ // Undocking isn't supported on Win95
+ if (1400 == GetWinVersion()) return;
+
+ CDocker* pDockUndockedFrom = SeparateFromDock();
+
+ // Position and draw the undocked window, unless it is about to be closed
+ if (bShowUndocked)
+ {
+ SetUndockPosition(pt);
+ }
+
+ RecalcDockLayout();
+ if ((pDockUndockedFrom) && (pDockUndockedFrom->GetTopmostDocker() != GetTopmostDocker()))
+ pDockUndockedFrom->RecalcDockLayout();
+ }
+
+ inline void CDocker::UndockContainer(CDockContainer* pContainer, CPoint pt, BOOL bShowUndocked)
+ {
+ assert(pContainer);
+ assert(this == GetDockFromView(pContainer->GetContainerParent()));
+
+ // Return if we shouldn't undock
+ if (GetDockFromView(pContainer)->GetDockStyle() & DS_NO_UNDOCK) return;
+
+ // Undocking isn't supported on Win95
+ if (1400 == GetWinVersion()) return;
+
+ GetTopmostDocker()->m_hOldFocus = 0;
+ CDocker* pDockUndockedFrom = GetDockFromView(pContainer->GetContainerParent());
+ pDockUndockedFrom->ShowWindow(SW_HIDE);
+ if (GetView() == pContainer)
+ {
+ // The parent container is being undocked, so we need
+ // to transfer our child containers to a different docker
+
+ // Choose a new docker from among the dockers for child containers
+ CDocker* pDockNew = 0;
+ CDocker* pDockOld = GetDockFromView(pContainer);
+ std::vector<ContainerInfo> AllContainers = pContainer->GetAllContainers();
+ std::vector<ContainerInfo>::iterator iter = AllContainers.begin();
+ while ((0 == pDockNew) && (iter < AllContainers.end()))
+ {
+ if ((*iter).pContainer != pContainer)
+ pDockNew = (CDocker*)FromHandle(::GetParent((*iter).pContainer->GetParent()->GetHwnd()));
+
+ ++iter;
+ }
+
+ if (pDockNew)
+ {
+ // Move containers from the old docker to the new docker
+ CDockContainer* pContainerNew = (CDockContainer*)pDockNew->GetView();
+ for (iter = AllContainers.begin(); iter != AllContainers.end(); ++iter)
+ {
+ if ((*iter).pContainer != pContainer)
+ {
+ CDockContainer* pChildContainer = (CDockContainer*)(*iter).pContainer;
+ pContainer->RemoveContainer(pChildContainer);
+ if (pContainerNew != pChildContainer)
+ {
+ pContainerNew->AddContainer(pChildContainer);
+ CDocker* pDock = GetDockFromView(pChildContainer);
+ pDock->SetParent(pDockNew);
+ pDock->m_pDockParent = pDockNew;
+ }
+ }
+ }
+
+ // Now transfer the old docker's settings to the new one.
+ pDockUndockedFrom = pDockNew;
+ pDockNew->m_DockStyle = pDockOld->m_DockStyle;
+ pDockNew->m_DockStartSize = pDockOld->m_DockStartSize;
+ pDockNew->m_DockSizeRatio = pDockOld->m_DockSizeRatio;
+ if (pDockOld->IsDocked())
+ {
+ pDockNew->m_pDockParent = pDockOld->m_pDockParent;
+ pDockNew->SetParent(pDockOld->GetParent());
+ }
+ else
+ {
+ CRect rc = pDockOld->GetWindowRect();
+ pDockNew->ShowWindow(SW_HIDE);
+ DWORD dwStyle = WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE;
+ pDockNew->SetWindowLongPtr(GWL_STYLE, dwStyle);
+ pDockNew->m_pDockParent = 0;
+ pDockNew->SetParent(0);
+ pDockNew->SetWindowPos(NULL, rc, SWP_SHOWWINDOW|SWP_FRAMECHANGED| SWP_NOOWNERZORDER);
+ }
+ pDockNew->GetDockBar().SetParent(pDockOld->GetParent());
+ pDockNew->GetView()->SetFocus();
+
+ // Transfer the Dock children to the new docker
+ pDockOld->MoveDockChildren(pDockNew);
+
+ // insert pDockNew into its DockParent's DockChildren vector
+ if (pDockNew->m_pDockParent)
+ {
+ std::vector<CDocker*>::iterator p;
+ for (p = pDockNew->m_pDockParent->m_vDockChildren.begin(); p != pDockNew->m_pDockParent->m_vDockChildren.end(); ++p)
+ {
+ if (*p == this)
+ {
+ pDockNew->m_pDockParent->m_vDockChildren.insert(p, pDockNew);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // This is a child container, so simply remove it from the parent
+ CDockContainer* pContainerParent = (CDockContainer*)GetView();
+ pContainerParent->RemoveContainer(pContainer);
+ pContainerParent->SetTabSize();
+ pContainerParent->SetFocus();
+ pContainerParent->GetViewPage().SetParent(pContainerParent);
+ }
+
+ // Finally do the actual undocking
+ CDocker* pDock = GetDockFromView(pContainer);
+ CRect rc = GetDockClient().GetWindowRect();
+ ScreenToClient(rc);
+ pDock->GetDockClient().SetWindowPos(NULL, rc, SWP_SHOWWINDOW);
+ pDock->Undock(pt, bShowUndocked);
+ pDockUndockedFrom->ShowWindow();
+ pDockUndockedFrom->RecalcDockLayout();
+ pDock->BringWindowToTop();
+ }
+
+ inline LRESULT CDocker::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_ACTIVATE:
+ OnActivate(wParam, lParam);
+ break;
+ case WM_SYSCOMMAND:
+ return OnSysCommand(wParam, lParam);
+
+ case WM_EXITSIZEMOVE:
+ OnExitSizeMove(wParam, lParam);
+ break;
+ case WM_WINDOWPOSCHANGING:
+ return OnWindowPosChanging(wParam, lParam);
+
+ case WM_WINDOWPOSCHANGED:
+ OnWindowPosChanged(wParam, lParam);
+ break;
+ case WM_DESTROY:
+ OnDestroy(wParam, lParam);
+ break;
+ case WM_SETFOCUS:
+ OnSetFocus(wParam, lParam);
+ break;
+ case WM_TIMER:
+ OnCaptionTimer(wParam, lParam);
+ break;
+ case UWM_DOCK_DESTROYED:
+ OnDockDestroyed(wParam, lParam);
+ break;
+ case UWM_DOCK_ACTIVATED:
+ DrawAllCaptions();
+ SetTimer(1, 100, NULL);
+ break;
+ case WM_SYSCOLORCHANGE:
+ OnSysColorChange(wParam, lParam);
+ break;
+ case WM_NCLBUTTONDBLCLK :
+ m_bIsDragging = FALSE;
+ break;
+ }
+
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+ //////////////////////////////////////
+ // Declaration of the CDockContainer class
+ inline CDockContainer::CDockContainer() : m_iCurrentPage(0), m_hTabIcon(0), m_nTabPressed(-1)
+ {
+ m_pContainerParent = this;
+ }
+
+ inline CDockContainer::~CDockContainer()
+ {
+ if (m_hTabIcon)
+ DestroyIcon(m_hTabIcon);
+ }
+
+ inline void CDockContainer::AddContainer(CDockContainer* pContainer)
+ {
+ assert(pContainer);
+
+ if (this == m_pContainerParent)
+ {
+ ContainerInfo ci = {0};
+ ci.pContainer = pContainer;
+ lstrcpy(ci.szTitle, pContainer->GetTabText());
+ ci.iImage = ImageList_AddIcon(GetImageList(), pContainer->GetTabIcon());
+ int iNewPage = (int)m_vContainerInfo.size();
+ m_vContainerInfo.push_back(ci);
+
+ if (m_hWnd)
+ {
+ TCITEM tie = {0};
+ tie.mask = TCIF_TEXT | TCIF_IMAGE;
+ tie.iImage = ci.iImage;
+ tie.pszText = m_vContainerInfo[iNewPage].szTitle;
+ TabCtrl_InsertItem(m_hWnd, iNewPage, &tie);
+
+ SetTabSize();
+ }
+
+ pContainer->m_pContainerParent = this;
+ if (pContainer->IsWindow())
+ {
+ // Set the parent container relationships
+ pContainer->GetViewPage().SetParent(this);
+ pContainer->GetViewPage().ShowWindow(SW_HIDE);
+ }
+ }
+ }
+
+ inline void CDockContainer::AddToolBarButton(UINT nID, BOOL bEnabled /* = TRUE */)
+ // Adds Resource IDs to toolbar buttons.
+ // A resource ID of 0 is a separator
+ {
+ GetToolBar().AddButton(nID, bEnabled);
+ }
+
+ inline CDockContainer* CDockContainer::GetContainerFromIndex(UINT nPage)
+ {
+ CDockContainer* pContainer = NULL;
+ if (nPage < m_vContainerInfo.size())
+ pContainer = (CDockContainer*)m_vContainerInfo[nPage].pContainer;
+
+ return pContainer;
+ }
+
+ inline CWnd* CDockContainer::GetActiveView() const
+ // Returns a pointer to the active view window, or NULL if there is no active veiw.
+ {
+ CWnd* pWnd = NULL;
+ if (m_pContainerParent->m_vContainerInfo.size() > 0)
+ {
+ CDockContainer* pActiveContainer = m_pContainerParent->m_vContainerInfo[m_pContainerParent->m_iCurrentPage].pContainer;
+ if (pActiveContainer->GetViewPage().GetView()->IsWindow())
+ pWnd = pActiveContainer->GetViewPage().GetView();
+ }
+
+ return pWnd;
+ }
+
+ inline CDockContainer* CDockContainer::GetContainerFromView(CWnd* pView) const
+ {
+ assert(pView);
+
+ std::vector<ContainerInfo>::iterator iter;
+ CDockContainer* pViewContainer = 0;
+ for (iter = GetAllContainers().begin(); iter != GetAllContainers().end(); ++iter)
+ {
+ CDockContainer* pContainer = (*iter).pContainer;
+ if (pContainer->GetView() == pView)
+ pViewContainer = pContainer;
+ }
+
+ return pViewContainer;
+ }
+
+ inline int CDockContainer::GetContainerIndex(CDockContainer* pContainer)
+ {
+ assert(pContainer);
+ int iReturn = -1;
+
+ for (int i = 0; i < (int)m_pContainerParent->m_vContainerInfo.size(); ++i)
+ {
+ if (m_pContainerParent->m_vContainerInfo[i].pContainer == pContainer)
+ iReturn = i;
+ }
+
+ return iReturn;
+ }
+
+ inline SIZE CDockContainer::GetMaxTabTextSize()
+ {
+ CSize Size;
+
+ // Allocate an iterator for the ContainerInfo vector
+ std::vector<ContainerInfo>::iterator iter;
+
+ for (iter = m_vContainerInfo.begin(); iter != m_vContainerInfo.end(); ++iter)
+ {
+ CSize TempSize;
+ CClientDC dc(this);
+ NONCLIENTMETRICS info = {0};
+ info.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
+ dc.CreateFontIndirect(&info.lfStatusFont);
+ TempSize = dc.GetTextExtentPoint32(iter->szTitle, lstrlen(iter->szTitle));
+ if (TempSize.cx > Size.cx)
+ Size = TempSize;
+ }
+
+ return Size;
+ }
+
+ inline void CDockContainer::SetupToolBar()
+ {
+ // Use this function to set the Resource IDs for the toolbar(s).
+
+/* // Set the Resource IDs for the toolbar buttons
+ AddToolBarButton( IDM_FILE_NEW );
+ AddToolBarButton( IDM_FILE_OPEN );
+ AddToolBarButton( IDM_FILE_SAVE );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_EDIT_CUT );
+ AddToolBarButton( IDM_EDIT_COPY );
+ AddToolBarButton( IDM_EDIT_PASTE );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_FILE_PRINT );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_HELP_ABOUT );
+*/
+ }
+
+ inline void CDockContainer::OnCreate()
+ {
+ assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window
+
+ ContainerInfo ci = {0};
+ ci.pContainer = this;
+ lstrcpy(ci.szTitle, GetTabText());
+ ci.iImage = ImageList_AddIcon(GetImageList(), GetTabIcon());
+ m_vContainerInfo.push_back(ci);
+
+ // Create the page window
+ GetViewPage().Create(this);
+
+ // Create the toolbar
+ GetToolBar().Create(&GetViewPage());
+ DWORD style = (DWORD)GetToolBar().GetWindowLongPtr(GWL_STYLE);
+ style |= CCS_NODIVIDER ;
+ GetToolBar().SetWindowLongPtr(GWL_STYLE, style);
+ SetupToolBar();
+ if (GetToolBar().GetToolBarData().size() > 0)
+ {
+ // Set the toolbar images
+ // A mask of 192,192,192 is compatible with AddBitmap (for Win95)
+ if (!GetToolBar().SendMessage(TB_GETIMAGELIST, 0L, 0L))
+ GetToolBar().SetImages(RGB(192,192,192), IDW_MAIN, 0, 0);
+
+ GetToolBar().SendMessage(TB_AUTOSIZE, 0L, 0L);
+ }
+ else
+ GetToolBar().Destroy();
+
+ SetFixedWidth(TRUE);
+ SetOwnerDraw(TRUE);
+
+ // Add tabs for each container.
+ for (int i = 0; i < (int)m_vContainerInfo.size(); ++i)
+ {
+ // Add tabs for each view.
+ TCITEM tie = {0};
+ tie.mask = TCIF_TEXT | TCIF_IMAGE;
+ tie.iImage = i;
+ tie.pszText = m_vContainerInfo[i].szTitle;
+ TabCtrl_InsertItem(m_hWnd, i, &tie);
+ }
+ }
+
+ inline void CDockContainer::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+ {
+ // Overrides CTab::OnLButtonDown
+
+ UNREFERENCED_PARAMETER(wParam);
+
+ CPoint pt((DWORD)lParam);
+ TCHITTESTINFO info = {0};
+ info.pt = pt;
+ m_nTabPressed = HitTest(info);
+ }
+
+ inline void CDockContainer::OnLButtonUp(WPARAM wParam, LPARAM lParam)
+ {
+ // Overrides CTab::OnLButtonUp and takes no action
+
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+ }
+
+ inline void CDockContainer::OnMouseLeave(WPARAM wParam, LPARAM lParam)
+ {
+ // Overrides CTab::OnMouseLeave
+
+ if (IsLeftButtonDown() && (m_nTabPressed >= 0))
+ {
+ CDocker* pDock = (CDocker*)FromHandle(::GetParent(GetParent()->GetHwnd()));
+ if (dynamic_cast<CDocker*>(pDock))
+ {
+ CDockContainer* pContainer = GetContainerFromIndex(m_iCurrentPage);
+ pDock->UndockContainer(pContainer, GetCursorPos(), TRUE);
+ }
+ }
+
+ m_nTabPressed = -1;
+ CTab::OnMouseLeave(wParam, lParam);
+ }
+
+ inline LRESULT CDockContainer::OnNotifyReflect(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGE:
+ {
+ // Display the newly selected tab page
+ int nPage = GetCurSel();
+ SelectPage(nPage);
+ }
+ break;
+ }
+
+ return 0L;
+ }
+
+ inline void CDockContainer::PreCreate(CREATESTRUCT &cs)
+ {
+ // For Tabs on the bottom, add the TCS_BOTTOM style
+ CTab::PreCreate(cs);
+ cs.style |= TCS_BOTTOM;
+ }
+
+ inline void CDockContainer::RecalcLayout()
+ {
+ if (GetContainerParent() == this)
+ {
+ // Set the tab sizes
+ SetTabSize();
+
+ // Position the View over the tab control's display area
+ CRect rc = GetClientRect();
+ AdjustRect(FALSE, &rc);
+ CDockContainer* pContainer = m_vContainerInfo[m_iCurrentPage].pContainer;
+ pContainer->GetViewPage().SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW);
+ }
+ }
+
+ inline void CDockContainer::RemoveContainer(CDockContainer* pWnd)
+ {
+ assert(pWnd);
+
+ // Remove the tab
+ int iTab = GetContainerIndex(pWnd);
+ if (iTab > 0)
+ {
+ // DeleteItem(iTab);
+ TabCtrl_DeleteItem(m_hWnd, iTab);
+ }
+
+ // Remove the ContainerInfo entry
+ std::vector<ContainerInfo>::iterator iter;
+ int iImage = -1;
+ for (iter = m_vContainerInfo.begin(); iter != m_vContainerInfo.end(); ++iter)
+ {
+ if (iter->pContainer == pWnd)
+ {
+ iImage = (*iter).iImage;
+ if (iImage >= 0)
+ TabCtrl_RemoveImage(m_hWnd, iImage);
+
+ m_vContainerInfo.erase(iter);
+ break;
+ }
+ }
+
+ // Set the parent container relationships
+ pWnd->GetViewPage().SetParent(pWnd);
+ pWnd->m_pContainerParent = pWnd;
+
+ // Display the first page
+ m_iCurrentPage = 0;
+ if (IsWindow())
+ SelectPage(0);
+ }
+
+ inline void CDockContainer::SelectPage(int nPage)
+ {
+ if (this != m_pContainerParent)
+ m_pContainerParent->SelectPage(nPage);
+ else
+ {
+ if ((nPage >= 0) && (nPage < (int)m_vContainerInfo.size() ))
+ {
+ if (GetCurSel() != nPage)
+ SetCurSel(nPage);
+
+ // Create the new container window if required
+ if (!m_vContainerInfo[nPage].pContainer->IsWindow())
+ {
+ CDockContainer* pContainer = m_vContainerInfo[nPage].pContainer;
+ pContainer->Create(GetParent());
+ pContainer->GetViewPage().SetParent(this);
+ }
+
+ // Determine the size of the tab page's view area
+ CRect rc = GetClientRect();
+ AdjustRect(FALSE, &rc);
+
+ // Swap the pages over
+ CDockContainer* pOldContainer = m_vContainerInfo[m_iCurrentPage].pContainer;
+ CDockContainer* pNewContainer = m_vContainerInfo[nPage].pContainer;
+ pOldContainer->GetViewPage().ShowWindow(SW_HIDE);
+ pNewContainer->GetViewPage().SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW);
+ pNewContainer->GetViewPage().GetView()->SetFocus();
+
+ // Adjust the docking caption
+ CDocker* pDock = (CDocker*)FromHandle(::GetParent(::GetParent(m_hWnd)));
+ if (dynamic_cast<CDocker*>(pDock))
+ {
+ pDock->SetCaption(pNewContainer->GetDockCaption().c_str());
+ pDock->RedrawWindow();
+ }
+
+ m_iCurrentPage = nPage;
+ }
+ }
+ }
+
+ inline void CDockContainer::SetActiveContainer(CDockContainer* pContainer)
+ {
+ int nPage = GetContainerIndex(pContainer);
+ assert (0 <= nPage);
+ SelectPage(nPage);
+ }
+
+ inline void CDockContainer::SetTabIcon(UINT nID_Icon)
+ {
+ HICON hIcon = (HICON)LoadImage(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(nID_Icon), IMAGE_ICON, 0, 0, LR_SHARED);
+ SetTabIcon(hIcon);
+ }
+
+ inline void CDockContainer::SetTabSize()
+ {
+ CRect rc = GetClientRect();
+ AdjustRect(FALSE, &rc);
+ if (rc.Width() < 0 )
+ rc.SetRectEmpty();
+
+ int nItemWidth = MIN(25 + GetMaxTabTextSize().cx, (rc.Width()-2)/(int)m_vContainerInfo.size());
+ int nItemHeight = MAX(20, GetTextHeight() + 5);
+ SendMessage(TCM_SETITEMSIZE, 0L, MAKELPARAM(nItemWidth, nItemHeight));
+ }
+
+ inline void CDockContainer::SetTabText(UINT nTab, LPCTSTR szText)
+ {
+ CDockContainer* pContainer = GetContainerParent()->GetContainerFromIndex(nTab);
+ pContainer->SetTabText(szText);
+
+ CTab::SetTabText(nTab, szText);
+ }
+
+ inline void CDockContainer::SetView(CWnd& Wnd)
+ {
+ GetViewPage().SetView(Wnd);
+ }
+
+ inline LRESULT CDockContainer::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ RecalcLayout();
+ return 0;
+
+ // The following are called in CTab::WndProcDefault
+ // case WM_LBUTTONDOWN:
+ // OnLButtonDown(wParam, lParam);
+ // break;
+ // case WM_LBUTTONUP:
+ // OnLButtonUp(wParam, lParam);
+ // break;
+ // case WM_MOUSELEAVE:
+ // OnMouseLeave(wParam, lParam);
+ // break;
+
+ case WM_SETFOCUS:
+ {
+ // Pass focus on to the current view
+ GetActiveView()->SetFocus();
+ }
+ break;
+ }
+
+ // pass unhandled messages on to CTab for processing
+ return CTab::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+ ///////////////////////////////////////////
+ // Declaration of the nested CViewPage class
+ inline BOOL CDockContainer::CViewPage::OnCommand(WPARAM wParam, LPARAM lParam)
+ {
+ CDockContainer* pContainer = (CDockContainer*)GetParent();
+ BOOL bResult = FALSE;
+ if (pContainer && pContainer->GetActiveContainer())
+ bResult = (BOOL)pContainer->GetActiveContainer()->SendMessage(WM_COMMAND, wParam, lParam);
+
+ return bResult;
+ }
+
+ inline void CDockContainer::CViewPage::OnCreate()
+ {
+ if (m_pView)
+ m_pView->Create(this);
+ }
+
+ inline LRESULT CDockContainer::CViewPage::OnNotify(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+
+ // Display tooltips for the toolbar
+ case TTN_GETDISPINFO:
+ {
+ int iIndex = GetToolBar().HitTest();
+ LPNMTTDISPINFO lpDispInfo = (LPNMTTDISPINFO)lParam;
+ if (iIndex >= 0)
+ {
+ int nID = GetToolBar().GetCommandID(iIndex);
+ if (nID > 0)
+ {
+ m_tsTooltip = LoadString(nID);
+ lpDispInfo->lpszText = (LPTSTR)m_tsTooltip.c_str();
+ }
+ else
+ m_tsTooltip = _T("");
+ }
+ }
+ break;
+ } // switch LPNMHDR
+
+ return 0L;
+ }
+
+ inline void CDockContainer::CViewPage::PreRegisterClass(WNDCLASS &wc)
+ {
+ wc.lpszClassName = _T("Win32++ TabPage");
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ }
+
+ inline void CDockContainer::CViewPage::RecalcLayout()
+ {
+ CRect rc = GetClientRect();
+ if (GetToolBar().IsWindow())
+ {
+ GetToolBar().SendMessage(TB_AUTOSIZE, 0L, 0L);
+ CRect rcToolBar = m_ToolBar.GetClientRect();
+ rc.top += rcToolBar.Height();
+ }
+
+ GetView()->SetWindowPos(NULL, rc, SWP_SHOWWINDOW);
+ }
+
+ inline void CDockContainer::CViewPage::SetView(CWnd& wndView)
+ // Sets or changes the View window displayed within the frame
+ {
+ // Assign the view window
+ m_pView = &wndView;
+
+ if (m_hWnd)
+ {
+ if (!m_pView->IsWindow())
+ {
+ // The container is already created, so create and position the new view too
+ GetView()->Create(this);
+ }
+
+ RecalcLayout();
+ }
+ }
+
+ inline LRESULT CDockContainer::CViewPage::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ RecalcLayout();
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ // Send the focus change notifications to the grandparent
+ case NM_KILLFOCUS:
+ case NM_SETFOCUS:
+ case UWM_FRAMELOSTFOCUS:
+ ::SendMessage(::GetParent(::GetParent(m_hWnd)), WM_NOTIFY, wParam, lParam);
+ break;
+ }
+
+ break;
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_DOCKING_H_
+
diff --git a/mmc_updater/depends/win32cpp/file.h b/mmc_updater/depends/win32cpp/file.h
new file mode 100644
index 00000000..4316dc94
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/file.h
@@ -0,0 +1,392 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+#ifndef _WIN32XX_FILE_H_
+#define _WIN32XX_FILE_H_
+
+
+#include "wincore.h"
+
+namespace Win32xx
+{
+
+ class CFile
+ {
+ public:
+ CFile();
+ CFile(HANDLE hFile);
+ CFile(LPCTSTR pszFileName, UINT nOpenFlags);
+ ~CFile();
+ operator HANDLE() const;
+
+ BOOL Close();
+ BOOL Flush();
+ HANDLE GetHandle() const;
+ ULONGLONG GetLength() const;
+ const CString& GetFileName() const;
+ const CString& GetFilePath() const;
+ const CString& GetFileTitle() const;
+ ULONGLONG GetPosition() const;
+ BOOL LockRange(ULONGLONG Pos, ULONGLONG Count);
+ BOOL Open(LPCTSTR pszFileName, UINT nOpenFlags);
+ CString OpenFileDialog(LPCTSTR pszFilePathName = NULL,
+ DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR pszFilter = NULL,
+ CWnd* pOwnerWnd = NULL);
+ UINT Read(void* pBuf, UINT nCount);
+ static BOOL Remove(LPCTSTR pszFileName);
+ static BOOL Rename(LPCTSTR pszOldName, LPCTSTR pszNewName);
+ CString SaveFileDialog(LPCTSTR pszFilePathName = NULL,
+ DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR pszFilter = NULL,
+ LPCTSTR pszDefExt = NULL, CWnd* pOwnerWnd = NULL);
+ ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
+ void SeekToBegin();
+ ULONGLONG SeekToEnd();
+ void SetFilePath(LPCTSTR pszNewName);
+ BOOL SetLength(ULONGLONG NewLen);
+ BOOL UnlockRange(ULONGLONG Pos, ULONGLONG Count);
+ BOOL Write(const void* pBuf, UINT nCount);
+
+ private:
+ CFile(const CFile&); // Disable copy construction
+ CFile& operator = (const CFile&); // Disable assignment operator
+ CString m_FileName;
+ CString m_FilePath;
+ CString m_FileTitle;
+ HANDLE m_hFile;
+ };
+
+}
+
+
+
+namespace Win32xx
+{
+ inline CFile::CFile() : m_hFile(0)
+ {
+ }
+
+ inline CFile::CFile(HANDLE hFile) : m_hFile(hFile)
+ {
+ }
+
+ inline CFile::CFile(LPCTSTR pszFileName, UINT nOpenFlags) : m_hFile(0)
+ {
+ assert(pszFileName);
+ Open(pszFileName, nOpenFlags);
+ assert(m_hFile);
+ }
+
+ inline CFile::~CFile()
+ {
+ Close();
+ }
+
+ inline CFile::operator HANDLE() const
+ {
+ return m_hFile;
+ }
+
+ inline BOOL CFile::Close()
+ // Closes the file associated with this object. Closed file can no longer be read or written to.
+ {
+ BOOL bResult = TRUE;
+ if (m_hFile)
+ bResult = CloseHandle(m_hFile);
+
+ m_hFile = 0;
+ return bResult;
+ }
+
+ inline BOOL CFile::Flush()
+ // Causes any remaining data in the file buffer to be written to the file.
+ {
+ assert(m_hFile);
+ return FlushFileBuffers(m_hFile);
+ }
+
+ inline HANDLE CFile::GetHandle() const
+ {
+ return m_hFile;
+ }
+
+ inline ULONGLONG CFile::GetLength( ) const
+ // Returns the length of the file in bytes.
+ {
+ assert(m_hFile);
+
+ LONG High = 0;
+ DWORD LowPos = SetFilePointer(m_hFile, 0, &High, FILE_END);
+
+ ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
+ return Result;
+ }
+
+ inline const CString& CFile::GetFileName() const
+ // Returns the filename of the file associated with this object.
+ {
+ return (const CString&)m_FileName;
+ }
+
+ inline const CString& CFile::GetFilePath() const
+ // Returns the full filename including the directory of the file associated with this object.
+ {
+ return (const CString&)m_FilePath;
+ }
+
+ inline const CString& CFile::GetFileTitle() const
+ // Returns the filename of the file associated with this object, excluding the path and the file extension
+ {
+ return (const CString&)m_FileTitle;
+ }
+
+ inline ULONGLONG CFile::GetPosition() const
+ // Returns the current value of the file pointer, which can be used in subsequent calls to Seek.
+ {
+ assert(m_hFile);
+ LONG High = 0;
+ DWORD LowPos = SetFilePointer(m_hFile, 0, &High, FILE_CURRENT);
+
+ ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
+ return Result;
+ }
+
+ inline BOOL CFile::LockRange(ULONGLONG Pos, ULONGLONG Count)
+ // Locks a range of bytes in and open file.
+ {
+ assert(m_hFile);
+
+ DWORD dwPosHigh = (DWORD)(Pos >> 32);
+ DWORD dwPosLow = (DWORD)(Pos & 0xFFFFFFFF);
+ DWORD dwCountHigh = (DWORD)(Count >> 32);
+ DWORD dwCountLow = (DWORD)(Count & 0xFFFFFFFF);
+
+ return ::LockFile(m_hFile, dwPosLow, dwPosHigh, dwCountLow, dwCountHigh);
+ }
+
+ inline BOOL CFile::Open(LPCTSTR pszFileName, UINT nOpenFlags)
+ // Prepares a file to be written to or read from.
+ {
+ if (m_hFile) Close();
+
+ m_hFile = ::CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, nOpenFlags, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (INVALID_HANDLE_VALUE == m_hFile)
+ {
+ TRACE(_T("Failed\n"));
+ m_hFile = 0;
+ }
+
+ if (m_hFile)
+ {
+ SetFilePath(pszFileName);
+ }
+
+ return (m_hFile != 0);
+ }
+
+ inline CString CFile::OpenFileDialog(LPCTSTR pszFilePathName, DWORD dwFlags, LPCTSTR pszFilter, CWnd* pOwnerWnd)
+ // Displays the file open dialog.
+ // Returns a CString containing either the selected file name or an empty CString.
+ {
+ CString str;
+ if (pszFilePathName)
+ str = pszFilePathName;
+
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = sizeof(OPENFILENAME);
+
+#if defined OPENFILENAME_SIZE_VERSION_400
+ if (GetWinVersion() < 2500)
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#endif
+
+ ofn.hwndOwner = pOwnerWnd? pOwnerWnd->GetHwnd() : NULL;
+ ofn.hInstance = GetApp()->GetInstanceHandle();
+ ofn.lpstrFilter = pszFilter;
+ ofn.lpstrTitle = _T("Open File");
+ ofn.Flags = dwFlags;
+ ofn.nMaxFile = _MAX_PATH;
+
+ ofn.lpstrFile = (LPTSTR)str.GetBuffer(_MAX_PATH);
+ ::GetOpenFileName(&ofn);
+ str.ReleaseBuffer();
+
+ return str;
+ }
+
+ inline UINT CFile::Read(void* pBuf, UINT nCount)
+ // Reads from the file, storing the contents in the specified buffer.
+ {
+ assert(m_hFile);
+ DWORD dwRead = 0;
+
+ if (!::ReadFile(m_hFile, pBuf, nCount, &dwRead, NULL))
+ dwRead = 0;
+
+ return dwRead;
+ }
+
+ inline BOOL CFile::Rename(LPCTSTR pszOldName, LPCTSTR pszNewName)
+ // Renames the specified file.
+ {
+ return ::MoveFile(pszOldName, pszNewName);
+ }
+
+ inline BOOL CFile::Remove(LPCTSTR pszFileName)
+ // Deletes the specified file.
+ {
+ return ::DeleteFile(pszFileName);
+ }
+
+ inline CString CFile::SaveFileDialog(LPCTSTR pszFilePathName, DWORD dwFlags, LPCTSTR pszFilter, LPCTSTR pszDefExt, CWnd* pOwnerWnd)
+ // Displays the SaveFileDialog.
+ // Returns a CString containing either the selected file name or an empty CString
+ {
+ CString str;
+ if (pszFilePathName)
+ str = pszFilePathName;
+
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = sizeof(OPENFILENAME);
+
+#if defined OPENFILENAME_SIZE_VERSION_400
+ if (GetWinVersion() < 2500)
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#endif
+
+ ofn.hwndOwner = pOwnerWnd? pOwnerWnd->GetHwnd() : NULL;
+ ofn.hInstance = GetApp()->GetInstanceHandle();
+ ofn.lpstrFilter = pszFilter;
+ ofn.lpstrFile = (LPTSTR)pszFilePathName;
+ ofn.lpstrFileTitle = (LPTSTR)pszFilePathName;
+ ofn.lpstrDefExt = pszDefExt;
+ ofn.nMaxFile = lstrlen(pszFilePathName);
+ ofn.lpstrTitle = _T("Save File");
+ ofn.Flags = dwFlags;
+ ofn.nMaxFile = _MAX_PATH;
+ ofn.lpstrFile = (LPTSTR)str.GetBuffer(_MAX_PATH);
+ ::GetSaveFileName(&ofn);
+ str.ReleaseBuffer();
+
+ return str;
+ }
+
+ inline ULONGLONG CFile::Seek(LONGLONG lOff, UINT nFrom)
+ // Positions the current file pointer.
+ // Permitted values for nFrom are: FILE_BEGIN, FILE_CURRENT, or FILE_END.
+ {
+ assert(m_hFile);
+ assert(nFrom == FILE_BEGIN || nFrom == FILE_CURRENT || nFrom == FILE_END);
+
+ LONG High = LONG(lOff >> 32);
+ LONG Low = (LONG)(lOff & 0xFFFFFFFF);
+
+ DWORD LowPos = SetFilePointer(m_hFile, Low, &High, nFrom);
+
+ ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
+ return Result;
+ }
+
+ inline void CFile::SeekToBegin()
+ // Sets the current file pointer to the beginning of the file.
+ {
+ assert(m_hFile);
+ Seek(0, FILE_BEGIN);
+ }
+
+ inline ULONGLONG CFile::SeekToEnd()
+ // Sets the current file pointer to the end of the file.
+ {
+ assert(m_hFile);
+ return Seek(0, FILE_END);
+ }
+
+ inline void CFile::SetFilePath(LPCTSTR pszFileName)
+ // Specifies the full file name, including its path
+ {
+ TCHAR* pFileName = NULL;
+ int nBuffSize = ::GetFullPathName(pszFileName, 0, 0, 0);
+ if (nBuffSize > 0)
+ {
+ TCHAR* pBuff = m_FilePath.GetBuffer(nBuffSize);
+ ::GetFullPathName(pszFileName, nBuffSize, pBuff, &pFileName);
+ m_FilePath.ReleaseBuffer();
+ m_FileName = pFileName;
+ int nPos = m_FileName.ReverseFind(_T("."));
+ if (nPos >= 0)
+ m_FileTitle = m_FileName.Left(nPos);
+ }
+ }
+
+ inline BOOL CFile::SetLength(ULONGLONG NewLen)
+ // Changes the length of the file to the specified value.
+ {
+ assert(m_hFile);
+
+ Seek(NewLen, FILE_BEGIN);
+ return ::SetEndOfFile(m_hFile);
+ }
+
+ inline BOOL CFile::UnlockRange(ULONGLONG Pos, ULONGLONG Count)
+ // Unlocks a range of bytes in an open file.
+ {
+ assert(m_hFile);
+
+ DWORD dwPosHigh = (DWORD)(Pos >> 32);
+ DWORD dwPosLow = (DWORD)(Pos & 0xFFFFFFFF);
+ DWORD dwCountHigh = (DWORD)(Count >> 32);
+ DWORD dwCountLow = (DWORD)(Count & 0xFFFFFFFF);
+
+ return ::UnlockFile(m_hFile, dwPosLow, dwPosHigh, dwCountLow, dwCountHigh);
+ }
+
+ inline BOOL CFile::Write(const void* pBuf, UINT nCount)
+ // Writes the specified buffer to the file.
+ {
+ assert(m_hFile);
+ DWORD dwWritten = 0;
+ BOOL bResult = ::WriteFile(m_hFile, pBuf, nCount, &dwWritten, NULL);
+ if (dwWritten != nCount)
+ bResult = FALSE;
+
+ return bResult;
+ }
+
+
+} // namespace Win32xx
+
+#endif
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
+ {
+ if (MDIButton >= 0)
+ {
+ DrawMDIButton(MenuBarDC, MDI_MIN, (0 == MDIButton)? 1 : 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, (1 == MDIButton)? 1 : 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, (2 == MDIButton)? 1 : 0);
+ }
+ else
+ {
+ DrawMDIButton(MenuBarDC, MDI_MIN, 0);
+ DrawMDIButton(MenuBarDC, MDI_RESTORE, 0);
+ DrawMDIButton(MenuBarDC, MDI_CLOSE, 0);
+ }
+ }
+ }
+ }
+ }
+
+ inline LRESULT CMenuBar::OnNotifyReflect(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_CUSTOMDRAW:
+ {
+ return OnCustomDraw((LPNMHDR) lParam);
+ }
+
+ case TBN_DROPDOWN:
+ // Always use PostMessage for USER_POPUPMENU (not SendMessage)
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ break;
+
+ case TBN_HOTITEMCHANGE:
+ // This is the notification that a hot item change is about to occur
+ // This is used to bring up a new popup menu when required
+ {
+ CPoint pt = GetCursorPos();
+ if (this == WindowFromPoint(pt)) // MenuBar window must be on top
+ {
+ DWORD flag = ((LPNMTBHOTITEM)lParam)->dwFlags;
+ if ((flag & HICF_MOUSE) && !(flag & HICF_LEAVING))
+ {
+ int nButton = HitTest();
+ if ((m_bMenuActive) && (nButton != m_nHotItem))
+ {
+ SendMessage(TB_PRESSBUTTON, m_nHotItem, MAKELONG(FALSE, 0));
+ m_nHotItem = nButton;
+ SendMessage(WM_CANCELMODE, 0L, 0L);
+
+ //Always use PostMessage for USER_POPUPMENU (not SendMessage)
+ PostMessage(UWM_POPUPMENU, 0L, 0L);
+ }
+ m_nHotItem = nButton;
+ }
+
+ // Handle escape from popup menu
+ if ((flag & HICF_LEAVING) && m_bKeyMode)
+ {
+ m_nHotItem = ((LPNMTBHOTITEM)lParam)->idOld;
+ PostMessage(TB_SETHOTITEM, m_nHotItem, 0L);
+ }
+
+ }
+ break;
+ } //case TBN_HOTITEMCHANGE:
+
+ } // switch(((LPNMHDR)lParam)->code)
+ return 0L;
+ } // CMenuBar::OnNotify(...)
+
+ inline void CMenuBar::OnWindowPosChanged()
+ {
+ InvalidateRect(&m_MDIRect[0], TRUE);
+ InvalidateRect(&m_MDIRect[1], TRUE);
+ InvalidateRect(&m_MDIRect[2], TRUE);
+ {
+ CClientDC MenuBarDC(this);
+ DrawAllMDIButtons(MenuBarDC);
+ }
+ }
+
+ inline void CMenuBar::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_LIST | TBSTYLE_FLAT | CCS_NODIVIDER | CCS_NORESIZE;
+ }
+
+ inline void CMenuBar::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = TOOLBARCLASSNAME;
+ }
+
+ inline void CMenuBar::ReleaseFocus()
+ {
+ if (m_hPrevFocus)
+ ::SetFocus(m_hPrevFocus);
+
+ m_hPrevFocus = NULL;
+ ::ReleaseCapture();
+ }
+
+ inline void CMenuBar::SetHotItem(int nHot)
+ {
+ m_nHotItem = nHot;
+ SendMessage(TB_SETHOTITEM, m_nHotItem, 0L);
+ }
+
+ inline void CMenuBar::SetMenu(HMENU hMenu)
+ {
+ assert(::IsWindow(m_hWnd));
+
+ m_hTopMenu = hMenu;
+ int nMaxedOffset = (IsMDIChildMaxed()? 1:0);
+
+ // Remove any existing buttons
+ while (SendMessage(TB_BUTTONCOUNT, 0L, 0L) > 0)
+ {
+ if(!SendMessage(TB_DELETEBUTTON, 0L, 0L))
+ break;
+ }
+
+ // Set the Bitmap size to zero
+ SendMessage(TB_SETBITMAPSIZE, 0L, MAKELPARAM(0, 0));
+
+ if (IsMDIChildMaxed())
+ {
+ // Create an extra button for the MDI child system menu
+ // Later we will custom draw the window icon over this button
+ TBBUTTON tbb = {0};
+ tbb.fsState = TBSTATE_ENABLED;
+ tbb.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE ;
+ tbb.iString = (INT_PTR)_T(" ");
+ SendMessage(TB_ADDBUTTONS, 1, (WPARAM)&tbb);
+ SetButtonText(0, _T(" "));
+ }
+
+ for (int i = 0 ; i < ::GetMenuItemCount(hMenu); ++i)
+ {
+ // Assign the ToolBar Button struct
+ TBBUTTON tbb = {0};
+ tbb.idCommand = i + nMaxedOffset; // Each button needs a unique ID
+ tbb.fsState = TBSTATE_ENABLED;
+ tbb.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN;
+ tbb.iString = (INT_PTR)_T(" ");
+ SendMessage(TB_ADDBUTTONS, 1, (WPARAM)&tbb);
+
+ // Add the menu title to the string table
+ std::vector<TCHAR> vMenuName( MAX_MENU_STRING+1, _T('\0') );
+ TCHAR* szMenuName = &vMenuName[0];
+ GetMenuString(hMenu, i, szMenuName, MAX_MENU_STRING, MF_BYPOSITION);
+ SetButtonText(i + nMaxedOffset, szMenuName);
+ }
+ }
+
+ inline void CMenuBar::SetMenuBarTheme(MenuTheme& Theme)
+ {
+ m_ThemeMenu.UseThemes = Theme.UseThemes;
+ m_ThemeMenu.clrHot1 = Theme.clrHot1;
+ m_ThemeMenu.clrHot2 = Theme.clrHot2;
+ m_ThemeMenu.clrPressed1 = Theme.clrPressed1;
+ m_ThemeMenu.clrPressed2 = Theme.clrPressed2;
+ m_ThemeMenu.clrOutline = Theme.clrOutline;
+
+ if (IsWindow())
+ Invalidate();
+ }
+
+ inline LRESULT CALLBACK CMenuBar::StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam)
+ {
+ assert(GetApp());
+ MSG* pMsg = (MSG*)lParam;
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+ CMenuBar* pMenuBar = (CMenuBar*)pTLSData->pMenuBar;
+
+ if (pMenuBar && (MSGF_MENU == nCode))
+ {
+ // process menu message
+ if (pMenuBar->OnMenuInput(pMsg->message, pMsg->wParam, pMsg->lParam))
+ {
+ return TRUE;
+ }
+ }
+
+ return CallNextHookEx(pTLSData->hHook, nCode, wParam, lParam);
+ }
+
+ inline void CMenuBar::OnSysCommand(WPARAM wParam, LPARAM lParam)
+ {
+ if (SC_KEYMENU == wParam)
+ {
+ if (0 == lParam)
+ {
+ // Alt/F10 key toggled
+ GrabFocus();
+ m_bKeyMode = TRUE;
+ int nMaxedOffset = (IsMDIChildMaxed()? 1:0);
+ SetHotItem(nMaxedOffset);
+ }
+ else
+ // Handle key pressed with Alt held down
+ DoAltKey((WORD)lParam);
+ }
+ }
+
+ inline LRESULT CMenuBar::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_CHAR:
+ return 0L; // Discard these messages
+ case WM_DRAWITEM:
+ m_pFrame->OnDrawItem(wParam, lParam);
+ return TRUE; // handled
+ case WM_EXITMENULOOP:
+ if (m_bExitAfter)
+ ExitMenu();
+ m_pFrame->OnExitMenuLoop();
+ break;
+ case WM_INITMENUPOPUP:
+ m_pFrame->OnInitMenuPopup(wParam, lParam);
+ break;
+ case WM_KEYDOWN:
+ OnKeyDown(wParam, lParam);
+ return 0L; // Discard these messages
+ case WM_KILLFOCUS:
+ ExitMenu();
+ return 0L;
+ case WM_LBUTTONDOWN:
+ // Do default processing first
+ CallWindowProc(GetPrevWindowProc(), uMsg, wParam, lParam);
+
+ OnLButtonDown(wParam, lParam);
+ return 0L;
+ case WM_LBUTTONUP:
+ OnLButtonUp(wParam, lParam);
+ break;
+ case WM_MEASUREITEM:
+ m_pFrame->OnMeasureItem(wParam, lParam);
+ return TRUE; // handled
+ case WM_MOUSELEAVE:
+ OnMouseLeave();
+ break;
+ case WM_MOUSEMOVE:
+ OnMouseMove(wParam, lParam);
+ break;
+ case UWM_POPUPMENU:
+ DoPopupMenu();
+ return 0L;
+ case WM_SYSKEYDOWN:
+ if ((VK_MENU == wParam) || (VK_F10 == wParam))
+ return 0L;
+ break;
+ case WM_SYSKEYUP:
+ if ((VK_MENU == wParam) || (VK_F10 == wParam))
+ {
+ ExitMenu();
+ return 0L;
+ }
+ break;
+ case UWM_GETMENUTHEME:
+ {
+ MenuTheme& tm = GetMenuBarTheme();
+ return (LRESULT)&tm;
+ }
+ case WM_WINDOWPOSCHANGED:
+ OnWindowPosChanged();
+ break;
+ case WM_WINDOWPOSCHANGING:
+ // Bypass CToolBar::WndProcDefault for this message
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+
+ } // switch (uMsg)
+
+ return CToolBar::WndProcDefault(uMsg, wParam, lParam);
+ } // LRESULT CMenuBar::WndProcDefault(...)
+
+
+
+ ///////////////////////////////////
+ // Definitions for the CFrame class
+ //
+ inline CFrame::CFrame() : m_tsStatusText(_T("Ready")), m_bShowIndicatorStatus(TRUE), m_bShowMenuStatus(TRUE),
+ m_bUseReBar(FALSE), m_bUseThemes(TRUE), m_bUpdateTheme(FALSE), m_bUseToolBar(TRUE), m_bUseCustomDraw(TRUE),
+ m_bShowStatusBar(TRUE), m_bShowToolBar(TRUE), m_himlMenu(NULL), m_himlMenuDis(NULL),
+ m_AboutDialog(IDW_ABOUT), m_pView(NULL), m_nMaxMRU(0), m_hOldFocus(0), m_nOldID(-1)
+ {
+ ZeroMemory(&m_ThemeMenu, sizeof(m_ThemeMenu));
+
+ // Do either InitCommonControls or InitCommonControlsEx
+ LoadCommonControls();
+
+ // By default, we use the rebar if we can
+ if (GetComCtlVersion() >= 470)
+ m_bUseReBar = TRUE;
+
+ for (int i = 0 ; i < 3 ; ++i)
+ m_OldStatus[i] = _T('\0');
+ }
+
+ inline CFrame::~CFrame()
+ {
+ if (m_himlMenu) ImageList_Destroy(m_himlMenu);
+ if (m_himlMenuDis) ImageList_Destroy(m_himlMenuDis);
+ }
+
+ inline BOOL CFrame::AddMenuIcon(int nID_MenuItem, HICON hIcon, int cx /*= 16*/, int cy /*= 16*/)
+ {
+ // Get ImageList image size
+ int cxOld = 0;
+ int cyOld = 0;
+ ImageList_GetIconSize(m_himlMenu, &cxOld, &cyOld );
+
+ // Create a new ImageList if required
+ if ((cx != cxOld) || (cy != cyOld) || (NULL == m_himlMenu))
+ {
+ if (m_himlMenu) ImageList_Destroy(m_himlMenu);
+ m_himlMenu = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 1, 0);
+ m_vMenuIcons.clear();
+ }
+
+ if (ImageList_AddIcon(m_himlMenu, hIcon) != -1)
+ {
+ m_vMenuIcons.push_back(nID_MenuItem);
+
+ // Recreate the Disabled imagelist
+ if (m_himlMenuDis) ImageList_Destroy(m_himlMenuDis);
+ m_himlMenuDis = NULL;
+ m_himlMenuDis = CreateDisabledImageList(m_himlMenu);
+
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ inline UINT CFrame::AddMenuIcons(const std::vector<UINT>& MenuData, COLORREF crMask, UINT ToolBarID, UINT ToolBarDisabledID)
+ // Adds the icons from a bitmap resouce to an internal ImageList for use with popup menu items.
+ // Note: If existing are a different size to the new ones, the old ones will be removed!
+ // The ToolBarDisabledID is ignored unless ToolBarID and ToolBarDisabledID bitmaps are the same size.
+ {
+ // Count the MenuData entries excluding seperators
+ int iImages = 0;
+ for (UINT i = 0 ; i < MenuData.size(); ++i)
+ {
+ if (MenuData[i] != 0) // Don't count seperators
+ {
+ ++iImages;
+ }
+ }
+
+ // Load the button images from Resouce ID
+ CBitmap Bitmap(ToolBarID);
+
+ if ((0 == iImages) || (!Bitmap))
+ return (UINT)m_vMenuIcons.size(); // No valid images, so nothing to do!
+
+ BITMAP bm = Bitmap.GetBitmapData();
+ int iImageWidth = bm.bmWidth / iImages;
+ int iImageHeight = bm.bmHeight;
+
+ // Create the ImageList if required
+ if (NULL == m_himlMenu)
+ {
+ m_himlMenu = ImageList_Create(iImageWidth, iImageHeight, ILC_COLOR32 | ILC_MASK, iImages, 0);
+ m_vMenuIcons.clear();
+ }
+ else
+ {
+ int Oldcx;
+ int Oldcy;
+
+ ImageList_GetIconSize(m_himlMenu, &Oldcx, &Oldcy);
+ if (iImageHeight != Oldcy)
+ {
+ TRACE(_T("Unable to add icons. The new icons are a different size to the old ones\n"));
+ return (UINT)m_vMenuIcons.size();
+ }
+ }
+
+ // Add the resource IDs to the m_vMenuIcons vector
+ for (UINT j = 0 ; j < MenuData.size(); ++j)
+ {
+ if (MenuData[j] != 0)
+ {
+ m_vMenuIcons.push_back(MenuData[j]);
+ }
+ }
+
+ // Add the images to the ImageList
+ ImageList_AddMasked(m_himlMenu, Bitmap, crMask);
+
+ // Create the Disabled imagelist
+ if (ToolBarDisabledID)
+ {
+ if (0 != m_himlMenuDis)
+ m_himlMenuDis = ImageList_Create(iImageWidth, iImageHeight, ILC_COLOR32 | ILC_MASK, iImages, 0);
+
+ CBitmap BitmapDisabled(ToolBarDisabledID);
+ BITMAP bmDis = BitmapDisabled.GetBitmapData();
+
+ int iImageWidthDis = bmDis.bmWidth / iImages;
+ int iImageHeightDis = bmDis.bmHeight;
+
+ // Normal and Disabled icons must be the same size
+ if ((iImageWidthDis == iImageWidth) && (iImageHeightDis == iImageHeight))
+ {
+ ImageList_AddMasked(m_himlMenu, BitmapDisabled, crMask);
+ }
+ else
+ {
+ ImageList_Destroy(m_himlMenuDis);
+ m_himlMenuDis = CreateDisabledImageList(m_himlMenu);
+ }
+ }
+ else
+ {
+ if (m_himlMenuDis) ImageList_Destroy(m_himlMenuDis);
+ m_himlMenuDis = CreateDisabledImageList(m_himlMenu);
+ }
+
+ // return the number of menu icons
+ return (UINT)m_vMenuIcons.size();
+ }
+
+ inline void CFrame::AddMenuBarBand()
+ {
+ // Adds a MenuBar to the rebar control
+ REBARBANDINFO rbbi = {0};
+ CSize sz = GetMenuBar().GetMaxSize();
+
+ // Calculate the MenuBar height from the menu font
+ CSize csMenuBar;
+ CClientDC dcMenuBar(&GetMenuBar());
+ dcMenuBar.SelectObject(GetMenuBar().GetFont());
+ csMenuBar = dcMenuBar.GetTextExtentPoint32(_T("\tSomeText"), lstrlen(_T("\tSomeText")));
+ int MenuBar_Height = csMenuBar.cy + 6;
+
+ rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
+ rbbi.cxMinChild = sz.cx;
+ rbbi.cx = sz.cx;
+ rbbi.cyMinChild = MenuBar_Height;
+ rbbi.cyMaxChild = MenuBar_Height;
+ rbbi.fStyle = RBBS_BREAK | RBBS_VARIABLEHEIGHT | RBBS_GRIPPERALWAYS ;
+ rbbi.hwndChild = GetMenuBar();
+ rbbi.wID = IDW_MENUBAR;
+
+ // Note: rbbi.cbSize is set inside the InsertBand function
+ GetReBar().InsertBand(-1, rbbi);
+ SetMenuBarBandSize();
+ GetReBar().SetMenuBar(GetMenuBar());
+
+ if (GetReBar().GetReBarTheme().LockMenuBand)
+ GetReBar().ShowGripper(GetReBar().GetBand(GetMenuBar()), FALSE);
+ }
+
+ inline void CFrame::AddMRUEntry(LPCTSTR szMRUEntry)
+ {
+ // Erase possible duplicate entries from vector
+ RemoveMRUEntry(szMRUEntry);
+
+ // Insert the entry at the beginning of the vector
+ m_vMRUEntries.insert(m_vMRUEntries.begin(), szMRUEntry);
+
+ // Delete excessive MRU entries
+ if (m_vMRUEntries.size() > m_nMaxMRU)
+ m_vMRUEntries.erase(m_vMRUEntries.begin() + m_nMaxMRU, m_vMRUEntries.end());
+
+ UpdateMRUMenu();
+ }
+
+ inline void CFrame::AddToolBarBand(CToolBar& TB, DWORD dwStyle, UINT nID)
+ {
+ // Adds a ToolBar to the rebar control
+
+ // Create the ToolBar Window
+ TB.Create(&GetReBar());
+
+ // Fill the REBARBAND structure
+ REBARBANDINFO rbbi = {0};
+ CSize sz = TB.GetMaxSize();
+
+ rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
+ rbbi.cyMinChild = sz.cy;
+ rbbi.cyMaxChild = sz.cy;
+ rbbi.cx = sz.cx +2;
+ rbbi.cxMinChild = sz.cx +2;
+
+ rbbi.fStyle = dwStyle;
+ rbbi.hwndChild = TB;
+ rbbi.wID = nID;
+
+ // Note: rbbi.cbSize is set inside the InsertBand function
+ GetReBar().InsertBand(-1, rbbi);
+ }
+
+ inline void CFrame::AddToolBarButton(UINT nID, BOOL bEnabled /* = TRUE*/, LPCTSTR szText)
+ // Adds Resource IDs to toolbar buttons.
+ // A resource ID of 0 is a separator
+ {
+ GetToolBar().AddButton(nID, bEnabled);
+
+ if(0 != szText)
+ GetToolBar().SetButtonText(nID, szText);
+
+ if (!IsWindow()) TRACE(_T("Warning ... Resource IDs for toolbars should be added in SetupToolBar\n"));
+ }
+
+ inline void CFrame::AdjustFrameRect(RECT rcView) const
+ // Adjust the size of the frame to accommodate the View window's dimensions
+ {
+ // Adjust for the view styles
+ CRect rc = rcView;
+ DWORD dwStyle = (DWORD)GetView()->GetWindowLongPtr(GWL_STYLE);
+ DWORD dwExStyle = (DWORD)GetView()->GetWindowLongPtr(GWL_EXSTYLE);
+ AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
+
+ // Calculate the new frame height
+ CRect rcFrameBefore = GetWindowRect();
+ CRect rcViewBefore = GetViewRect();
+ int Height = rc.Height() + rcFrameBefore.Height() - rcViewBefore.Height();
+
+ // Adjust for the frame styles
+ dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
+ dwExStyle = (DWORD)GetWindowLongPtr(GWL_EXSTYLE);
+ AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
+
+ // Calculate final rect size, and reposition frame
+ SetWindowPos(NULL, 0, 0, rc.Width(), Height, SWP_NOMOVE);
+ }
+
+ inline void CFrame::CreateToolBar()
+ {
+ if (IsReBarSupported() && m_bUseReBar)
+ AddToolBarBand(GetToolBar(), RBBS_BREAK, IDW_TOOLBAR); // Create the toolbar inside rebar
+ else
+ GetToolBar().Create(this); // Create the toolbar without a rebar
+
+ SetupToolBar();
+
+ if (IsReBarSupported() && m_bUseReBar)
+ {
+ if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().LockMenuBand)
+ {
+ // Hide gripper for single toolbar
+ if (GetReBar().GetBandCount() <= 2)
+ GetReBar().ShowGripper(GetReBar().GetBand(GetToolBar()), FALSE);
+ }
+ }
+
+ if (GetToolBar().GetToolBarData().size() > 0)
+ {
+ // Set the toolbar images (if not already set in SetupToolBar)
+ // A mask of 192,192,192 is compatible with AddBitmap (for Win95)
+ if (!GetToolBar().SendMessage(TB_GETIMAGELIST, 0L, 0L))
+ SetToolBarImages(RGB(192,192,192), IDW_MAIN, 0, 0);
+
+ // Add the icons for popup menu
+ AddMenuIcons(GetToolBar().GetToolBarData(), RGB(192, 192, 192), IDW_MAIN, 0);
+ }
+ else
+ {
+ TRACE(_T("Warning ... No resource IDs assigned to the toolbar\n"));
+ }
+ }
+
+ inline void CFrame::DrawCheckmark(LPDRAWITEMSTRUCT pdis, CDC& DrawDC)
+ // Draws the checkmark or radiocheck transparently
+ {
+ CRect rc = pdis->rcItem;
+ UINT fType = ((ItemData*)pdis->itemData)->fType;
+ MenuTheme tm = GetMenuTheme();
+ CRect rcBk;
+
+ // Draw the checkmark's background rectangle first
+ int Iconx = 16, Icony = 16;
+ if (m_himlMenu) ImageList_GetIconSize(m_himlMenu, &Iconx, &Icony);
+ int BarWidth = Iconx + 8;
+ int left = (BarWidth - Iconx)/2;
+ int top = rc.top + (rc.Height() - Icony)/2;
+ rcBk.SetRect(left, top, left + Iconx, top + Icony);
+
+ if (tm.UseThemes)
+ {
+ DrawDC.CreateSolidBrush(tm.clrHot2);
+ DrawDC.CreatePen(PS_SOLID, 1, tm.clrOutline);
+
+ // Draw the checkmark's background rectangle
+ DrawDC.Rectangle(rcBk.left, rcBk.top, rcBk.right, rcBk.bottom);
+ }
+
+ CMemDC MemDC(FromHandle(pdis->hDC));
+ int cxCheck = ::GetSystemMetrics(SM_CXMENUCHECK);
+ int cyCheck = ::GetSystemMetrics(SM_CYMENUCHECK);
+ MemDC.CreateBitmap(cxCheck, cyCheck, 1, 1, NULL);
+ CRect rcCheck( 0, 0, cxCheck, cyCheck);
+
+ // Copy the check mark bitmap to hdcMem
+ if (MFT_RADIOCHECK == fType)
+ MemDC.DrawFrameControl(rcCheck, DFC_MENU, DFCS_MENUBULLET);
+ else
+ MemDC.DrawFrameControl(rcCheck, DFC_MENU, DFCS_MENUCHECK);
+
+ int xoffset = (rcBk.Width() - rcCheck.Width()-1)/2;
+ int yoffset = (rcBk.Height() - rcCheck.Height()-1)/2;
+
+ if (tm.UseThemes)
+ xoffset += 2;
+
+ // Draw a white or black check mark as required
+ // Unfortunately MaskBlt isn't supported on Win95, 98 or ME, so we do it the hard way
+ CMemDC MaskDC(FromHandle(pdis->hDC));
+ MaskDC.CreateCompatibleBitmap(FromHandle(pdis->hDC), cxCheck, cyCheck);
+ MaskDC.BitBlt(0, 0, cxCheck, cyCheck, &MaskDC, 0, 0, WHITENESS);
+
+ if ((pdis->itemState & ODS_SELECTED) && (!tm.UseThemes))
+ {
+ // Draw a white checkmark
+ MemDC.BitBlt(0, 0, cxCheck, cyCheck, &MemDC, 0, 0, DSTINVERT);
+ MaskDC.BitBlt(0, 0, cxCheck, cyCheck, &MemDC, 0, 0, SRCAND);
+ DrawDC.BitBlt(rcBk.left + xoffset, rcBk.top + yoffset, cxCheck, cyCheck, &MaskDC, 0, 0, SRCPAINT);
+ }
+ else
+ {
+ // Draw a black checkmark
+ int BullitOffset = ((MFT_RADIOCHECK == fType) && tm.UseThemes)? 1 : 0;
+ MaskDC.BitBlt( -BullitOffset, BullitOffset, cxCheck, cyCheck, &MemDC, 0, 0, SRCAND);
+ DrawDC.BitBlt(rcBk.left + xoffset, rcBk.top + yoffset, cxCheck, cyCheck, &MaskDC, 0, 0, SRCAND);
+ }
+ }
+
+ inline void CFrame::DrawMenuIcon(LPDRAWITEMSTRUCT pdis, CDC& DrawDC, BOOL bDisabled)
+ {
+ if (!m_himlMenu)
+ return;
+ // Get icon size
+ int Iconx;
+ int Icony;
+ ImageList_GetIconSize(m_himlMenu, &Iconx, &Icony);
+ int BarWidth = Iconx + 8;
+
+ // get the drawing rectangle
+ CRect rc = pdis->rcItem;
+ int left = (BarWidth - Iconx)/2;
+ int top = rc.top + (rc.Height() - Icony)/2;
+ rc.SetRect(left, top, left + Iconx, top + Icony);
+
+ // get the icon's location in the imagelist
+ int iImage = -1;
+ for (int i = 0 ; i < (int)m_vMenuIcons.size(); ++i)
+ {
+ if (pdis->itemID == m_vMenuIcons[i])
+ iImage = i;
+ }
+
+ // draw the image
+ if (iImage >= 0 )
+ {
+ if ((bDisabled) && (m_himlMenuDis))
+ ImageList_Draw(m_himlMenuDis, iImage, DrawDC, rc.left, rc.top, ILD_TRANSPARENT);
+ else
+ ImageList_Draw(m_himlMenu, iImage, DrawDC, rc.left, rc.top, ILD_TRANSPARENT);
+ }
+ }
+
+ inline void CFrame::DrawMenuText(CDC& DrawDC, LPCTSTR ItemText, CRect& rc, COLORREF colorText)
+ {
+ // find the position of tab character
+ int nTab = -1;
+ for(int i = 0; i < lstrlen(ItemText); ++i)
+ {
+ if(_T('\t') == ItemText[i])
+ {
+ nTab = i;
+ break;
+ }
+ }
+
+ // Draw the item text
+ DrawDC.SetTextColor(colorText);
+ DrawDC.DrawText(ItemText, nTab, rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
+
+ // Draw text after tab, right aligned
+ if(nTab != -1)
+ DrawDC.DrawText( &ItemText[nTab + 1], -1, rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
+ }
+
+ inline int CFrame::GetMenuItemPos(HMENU hMenu, LPCTSTR szItem)
+ // Returns the position of the menu item, given it's name
+ {
+ int nMenuItemCount = GetMenuItemCount(hMenu);
+ MENUITEMINFO mii = {0};
+ mii.cbSize = GetSizeofMenuItemInfo();
+
+ for (int nItem = 0 ; nItem < nMenuItemCount; ++nItem)
+ {
+ std::vector<TCHAR> vTChar( MAX_MENU_STRING+1, _T('\0') );
+ TCHAR* szStr = &vTChar[0];
+
+ std::vector<TCHAR> vStripped( MAX_MENU_STRING+1, _T('\0') );
+ TCHAR* szStripped = &vStripped[0];
+
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = szStr;
+ mii.cch = MAX_MENU_STRING;
+
+ // Fill the contents of szStr from the menu item
+ if (::GetMenuItemInfo(hMenu, nItem, TRUE, &mii) && (lstrlen(szStr) <= MAX_MENU_STRING))
+ {
+ // Strip out any & characters
+ int j = 0;
+ for (int i = 0; i < lstrlen(szStr); ++i)
+ {
+ if (szStr[i] != _T('&'))
+ szStripped[j++] = szStr[i];
+ }
+ szStripped[j] = _T('\0'); // Append null tchar
+
+ // Compare the strings
+ if (0 == lstrcmp(szStripped, szItem))
+ return nItem;
+ }
+ }
+
+ return -1;
+ }
+
+ inline tString CFrame::GetMRUEntry(UINT nIndex)
+ {
+ tString tsPathName;
+ if (nIndex < m_vMRUEntries.size())
+ {
+ tsPathName = m_vMRUEntries[nIndex];
+
+ // Now put the selected entry at Index 0
+ AddMRUEntry(tsPathName.c_str());
+ }
+ return tsPathName;
+ }
+
+ inline CRect CFrame::GetViewRect() const
+ {
+ // Get the frame's client area
+ CRect rcFrame = GetClientRect();
+
+ // Get the statusbar's window area
+ CRect rcStatus;
+ if (GetStatusBar().IsWindowVisible() || !IsWindowVisible())
+ rcStatus = GetStatusBar().GetWindowRect();
+
+ // Get the top rebar or toolbar's window area
+ CRect rcTop;
+ if (IsReBarSupported() && m_bUseReBar)
+ rcTop = GetReBar().GetWindowRect();
+ else
+ if (GetToolBar().IsWindow() && GetToolBar().IsWindowVisible())
+ rcTop = GetToolBar().GetWindowRect();
+
+ // Return client size less the rebar and status windows
+ int top = rcFrame.top + rcTop.Height();
+ int left = rcFrame.left;
+ int right = rcFrame.right;
+ int bottom = rcFrame.Height() - (rcStatus.Height());
+ if ((bottom <= top) ||( right <= left))
+ top = left = right = bottom = 0;
+
+ CRect rcView(left, top, right, bottom);
+ return rcView;
+ }
+
+ inline void CFrame::LoadCommonControls()
+ {
+ HMODULE hComCtl;
+
+ try
+ {
+ // Load the Common Controls DLL
+ hComCtl = ::LoadLibrary(_T("COMCTL32.DLL"));
+ if (!hComCtl)
+ throw CWinException(_T("Failed to load COMCTL32.DLL"));
+
+ if (GetComCtlVersion() > 470)
+ {
+ // Declare a pointer to the InItCommonControlsEx function
+ typedef BOOL WINAPI INIT_EX(INITCOMMONCONTROLSEX*);
+ INIT_EX* pfnInit = (INIT_EX*)::GetProcAddress(hComCtl, "InitCommonControlsEx");
+
+ // Load the full set of common controls
+ INITCOMMONCONTROLSEX InitStruct = {0};
+ InitStruct.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ InitStruct.dwICC = ICC_COOL_CLASSES|ICC_DATE_CLASSES|ICC_INTERNET_CLASSES|ICC_NATIVEFNTCTL_CLASS|
+ ICC_PAGESCROLLER_CLASS|ICC_USEREX_CLASSES|ICC_WIN95_CLASSES;
+
+ // Call InitCommonControlsEx
+ if(!((*pfnInit)(&InitStruct)))
+ throw CWinException(_T("InitCommonControlsEx failed"));
+ }
+ else
+ {
+ ::InitCommonControls();
+ }
+
+ ::FreeLibrary(hComCtl);
+ }
+
+ catch (const CWinException &e)
+ {
+ e.what();
+ if (hComCtl)
+ ::FreeLibrary(hComCtl);
+
+ throw;
+ }
+ }
+
+ inline BOOL CFrame::LoadRegistryMRUSettings(UINT nMaxMRU /*= 0*/)
+ {
+ // Load the MRU list from the registry
+
+ assert(!m_tsKeyName.empty()); // KeyName must be set before calling LoadRegistryMRUSettings
+ HKEY hKey = NULL;
+ BOOL bRet = FALSE;
+
+ try
+ {
+ m_nMaxMRU = MIN(nMaxMRU, 16);
+ std::vector<tString> vMRUEntries;
+ tString tsKey = _T("Software\\") + m_tsKeyName + _T("\\Recent Files");
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, tsKey.c_str(), 0, KEY_READ, &hKey))
+ {
+ for (UINT i = 0; i < m_nMaxMRU; ++i)
+ {
+ DWORD dwType = REG_SZ;
+ DWORD dwBufferSize = 0;
+ TCHAR szSubKey[10] = _T("");
+ wsprintf(szSubKey, _T("File %d\0"), i+1);
+
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, szSubKey, NULL, &dwType, NULL, &dwBufferSize))
+ throw CWinException(_T("RegQueryValueEx failed\n"));
+
+ std::vector<TCHAR> PathName( dwBufferSize, _T('\0') );
+ TCHAR* pTCharArray = &PathName[0];
+
+ // load the entry from the registry
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, szSubKey, NULL, &dwType, (LPBYTE)pTCharArray, &dwBufferSize))
+ throw CWinException(_T("RegQueryValueEx failed\n"));
+
+ if ( lstrlen( pTCharArray ) )
+ vMRUEntries.push_back( pTCharArray );
+ }
+
+ // successfully loaded all MRU values, so store them
+ m_vMRUEntries = vMRUEntries;
+ RegCloseKey(hKey);
+ bRet = TRUE;
+ }
+ }
+
+ catch(const CWinException& e)
+ {
+ TRACE(_T("Failed to load MRU values from registry\n"));
+ e.what();
+
+ if (hKey)
+ RegCloseKey(hKey);
+ }
+
+ return bRet;
+ }
+
+ inline BOOL CFrame::LoadRegistrySettings(LPCTSTR szKeyName)
+ {
+ assert (NULL != szKeyName);
+ m_tsKeyName = szKeyName;
+
+ tString tsKey = _T("Software\\") + m_tsKeyName + _T("\\Frame Settings");
+ HKEY hKey = 0;
+ BOOL bRet = FALSE;
+
+ try
+ {
+ if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, tsKey.c_str(), 0, KEY_READ, &hKey))
+ {
+ DWORD dwType = REG_BINARY;
+ DWORD BufferSize = sizeof(DWORD);
+ DWORD dwTop, dwLeft, dwWidth, dwHeight, dwStatusBar, dwToolBar;
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Top"), NULL, &dwType, (LPBYTE)&dwTop, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Left"), NULL, &dwType, (LPBYTE)&dwLeft, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Width"), NULL, &dwType, (LPBYTE)&dwWidth, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("Height"), NULL, &dwType, (LPBYTE)&dwHeight, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("StatusBar"), NULL, &dwType, (LPBYTE)&dwStatusBar, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("ToolBar"), NULL, &dwType, (LPBYTE)&dwToolBar, &BufferSize))
+ throw CWinException(_T("RegQueryValueEx Failed"));
+
+ m_rcPosition.top = dwTop;
+ m_rcPosition.left = dwLeft;
+ m_rcPosition.bottom = m_rcPosition.top + dwHeight;
+ m_rcPosition.right = m_rcPosition.left + dwWidth;
+ m_bShowStatusBar = dwStatusBar & 1;
+ m_bShowToolBar = dwToolBar & 1;
+
+ RegCloseKey(hKey);
+ bRet = TRUE;
+ }
+ }
+
+ catch (const CWinException& e)
+ {
+ TRACE(_T("Failed to load values from registry, using defaults!\n"));
+ e.what();
+
+ if (hKey)
+ RegCloseKey(hKey);
+ }
+
+ return bRet;
+ }
+
+ inline void CFrame::OnActivate(WPARAM wParam, LPARAM lParam)
+ {
+ // Do default processing first
+ DefWindowProc(WM_ACTIVATE, wParam, lParam);
+
+ if (LOWORD(wParam) == WA_INACTIVE)
+ {
+ // Save the hwnd of the window which currently has focus
+ // (this must be CFrame window itself or a child window
+ if (!IsIconic()) m_hOldFocus = ::GetFocus();
+
+ // Send a notification to the view window
+ int idCtrl = ::GetDlgCtrlID(m_hOldFocus);
+ NMHDR nhdr={0};
+ nhdr.hwndFrom = m_hOldFocus;
+ nhdr.idFrom = idCtrl;
+ nhdr.code = UWM_FRAMELOSTFOCUS;
+ if (GetView()->IsWindow())
+ GetView()->SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr);
+ }
+ else
+ {
+ // Now set the focus to the appropriate child window
+ if (m_hOldFocus) ::SetFocus(m_hOldFocus);
+
+ // Send a notification to the view window
+ int idCtrl = ::GetDlgCtrlID(m_hOldFocus);
+ NMHDR nhdr={0};
+ nhdr.hwndFrom = m_hOldFocus;
+ nhdr.idFrom = idCtrl;
+ nhdr.code = UWM_FRAMEGOTFOCUS;
+ if (GetView()->IsWindow())
+ GetView()->SendMessage(WM_NOTIFY, (WPARAM)idCtrl, (LPARAM)&nhdr);
+ }
+ }
+
+ inline void CFrame::OnClose()
+ {
+ // Called in response to a WM_CLOSE message for the frame.
+ ShowWindow(SW_HIDE);
+ SaveRegistrySettings();
+
+ GetMenuBar().Destroy();
+ GetToolBar().Destroy();
+ GetReBar().Destroy();
+ GetStatusBar().Destroy();
+ GetView()->Destroy();
+ }
+
+ inline void CFrame::OnCreate()
+ {
+ // This is called when the frame window is being created.
+ // Override this in CMainFrame if you wish to modify what happens here
+
+ // Set the icon
+ SetIconLarge(IDW_MAIN);
+ SetIconSmall(IDW_MAIN);
+
+ // Set the keyboard accelerators
+ m_hAccel = LoadAccelerators(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_MAIN));
+ GetApp()->SetAccelerators(m_hAccel, this);
+
+ // Set the Caption
+ SetWindowText(LoadString(IDW_MAIN));
+
+ // Set the theme for the frame elements
+ SetTheme();
+
+ // Create the rebar and menubar
+ if (IsReBarSupported() && m_bUseReBar)
+ {
+ // Create the rebar
+ GetReBar().Create(this);
+
+ // Create the menu inside rebar
+ GetMenuBar().Create(&GetReBar());
+ AddMenuBarBand();
+ }
+
+ // Setup the menu
+ SetFrameMenu(IDW_MAIN);
+ UpdateMRUMenu();
+
+ // Create the ToolBar
+ if (m_bUseToolBar)
+ {
+ CreateToolBar();
+ ShowToolBar(m_bShowToolBar);
+ }
+ else
+ {
+ ::CheckMenuItem(GetFrameMenu(), IDW_VIEW_TOOLBAR, MF_UNCHECKED);
+ ::EnableMenuItem(GetFrameMenu(), IDW_VIEW_TOOLBAR, MF_GRAYED);
+ }
+
+ // Create the status bar
+ GetStatusBar().Create(this);
+ ShowStatusBar(m_bShowStatusBar);
+
+ // Create the view window
+ assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window
+ GetView()->Create(this);
+
+ // Disable XP themes for the menubar
+ if ( m_bUseThemes || (GetWinVersion() < 2600) ) // themes or WinVersion < Vista
+ GetMenuBar().SetWindowTheme(L" ", L" ");
+
+ // Start timer for Status updates
+ if (m_bShowIndicatorStatus || m_bShowMenuStatus)
+ SetTimer(ID_STATUS_TIMER, 200, NULL);
+
+ // Reposition the child windows
+ RecalcLayout();
+ }
+
+ inline void CFrame::OnDestroy()
+ {
+ SetMenu(NULL);
+ KillTimer(ID_STATUS_TIMER);
+ ::PostQuitMessage(0); // Terminates the application
+ }
+
+ inline LRESULT CFrame::OnDrawItem(WPARAM wParam, LPARAM lParam)
+ // OwnerDraw is used to render the popup menu items
+ {
+ LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
+ if (pdis->CtlType != ODT_MENU)
+ return CWnd::WndProcDefault(WM_DRAWITEM, wParam, lParam);
+
+ CRect rc = pdis->rcItem;
+ ItemData* pmd = (ItemData*)pdis->itemData;
+ CDC* pDrawDC = FromHandle(pdis->hDC);
+ MenuTheme tm = GetMenuTheme();
+
+ int Iconx = 16;
+ int Icony = 16;
+ if (m_himlMenu) ImageList_GetIconSize(m_himlMenu, &Iconx, &Icony);
+ int BarWidth = tm.UseThemes? Iconx + 8 : 0;
+
+ // Draw the side bar
+ if (tm.UseThemes)
+ {
+ CRect rcBar = rc;
+ rcBar.right = BarWidth;
+ pDrawDC->GradientFill(tm.clrPressed1, tm.clrPressed2, rcBar, TRUE);
+ }
+
+ if (pmd->fType & MFT_SEPARATOR)
+ {
+ // draw separator
+ CRect rcSep = rc;
+ rcSep.left = BarWidth;
+ if (tm.UseThemes)
+ pDrawDC->SolidFill(RGB(255,255,255), rcSep);
+ else
+ pDrawDC->SolidFill(GetSysColor(COLOR_MENU), rcSep);
+ rcSep.top += (rc.bottom - rc.top)/2;
+ rcSep.left = BarWidth + 2;
+ pDrawDC->DrawEdge(rcSep, EDGE_ETCHED, BF_TOP);
+ }
+ else
+ {
+ // draw menu item
+ BOOL bDisabled = pdis->itemState & ODS_GRAYED;
+ BOOL bSelected = pdis->itemState & ODS_SELECTED;
+ BOOL bChecked = pdis->itemState & ODS_CHECKED;
+ CRect rcDraw = rc;
+
+ if ((bSelected) && (!bDisabled))
+ {
+ // draw selected item background
+ if (tm.UseThemes)
+ {
+ pDrawDC->CreateSolidBrush(tm.clrHot1);
+ pDrawDC->CreatePen(PS_SOLID, 1, tm.clrOutline);
+ pDrawDC->Rectangle(rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom);
+ }
+ else
+ pDrawDC->SolidFill(GetSysColor(COLOR_HIGHLIGHT), rcDraw);
+ }
+ else
+ {
+ // draw non-selected item background
+ rcDraw.left = BarWidth;
+ if (tm.UseThemes)
+ pDrawDC->SolidFill(RGB(255,255,255), rcDraw);
+ else
+ pDrawDC->SolidFill(GetSysColor(COLOR_MENU), rcDraw);
+ }
+
+ if (bChecked)
+ DrawCheckmark(pdis, *pDrawDC);
+ else
+ DrawMenuIcon(pdis, *pDrawDC, bDisabled);
+
+ // Calculate the text rect size
+ rc.left = rc.bottom - rc.top + 2;
+ if (_tcschr(pmd->GetItemText(), _T('\t')))
+ rc.right -= POST_TEXT_GAP; // Add POST_TEXT_GAP if the text includes a tab
+
+ // Draw the text
+ int iMode = pDrawDC->SetBkMode(TRANSPARENT);
+ COLORREF colorText;
+ if (tm.UseThemes)
+ {
+ rc.left += 8;
+ colorText = GetSysColor(bDisabled ? COLOR_GRAYTEXT : COLOR_MENUTEXT);
+ }
+ else
+ colorText = GetSysColor(bDisabled ? COLOR_GRAYTEXT : bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT);
+
+ DrawMenuText(*pDrawDC, pmd->GetItemText(), rc, colorText);
+ pDrawDC->SetBkMode(iMode);
+ }
+
+ pDrawDC->Detach(); // Optional, deletes GDI objects sooner
+ return TRUE;
+ }
+
+ inline void CFrame::OnExitMenuLoop()
+ {
+ if (m_bUseCustomDraw)
+ {
+ for (UINT nItem = 0; nItem < m_vMenuItemData.size(); ++nItem)
+ {
+ // Undo OwnerDraw and put the text back
+ MENUITEMINFO mii = {0};
+ mii.cbSize = GetSizeofMenuItemInfo();
+
+ mii.fMask = MIIM_TYPE | MIIM_DATA;
+ mii.fType = m_vMenuItemData[nItem]->fType;
+ mii.dwTypeData = m_vMenuItemData[nItem]->GetItemText();
+ mii.cch = lstrlen(m_vMenuItemData[nItem]->GetItemText());
+ mii.dwItemData = 0;
+ ::SetMenuItemInfo(m_vMenuItemData[nItem]->hMenu, m_vMenuItemData[nItem]->nPos, TRUE, &mii);
+ }
+
+ m_vMenuItemData.clear();
+ }
+ }
+
+ inline void CFrame::OnHelp()
+ {
+ // Ensure only one dialog displayed even for multiple hits of the F1 button
+ if (!m_AboutDialog.IsWindow())
+ {
+ // Store the window handle that currently has keyboard focus
+ HWND hPrevFocus = ::GetFocus();
+ if (hPrevFocus == GetMenuBar())
+ hPrevFocus = m_hWnd;
+
+ m_AboutDialog.SetDlgParent(this);
+ m_AboutDialog.DoModal();
+
+ ::SetFocus(hPrevFocus);
+ }
+ }
+
+ inline void CFrame::OnInitMenuPopup(WPARAM wParam, LPARAM lParam)
+ {
+ // The system menu shouldn't be owner drawn
+ if (HIWORD(lParam)) return;
+
+ if (m_bUseCustomDraw)
+ {
+ CMenu* pMenu = FromHandle((HMENU)wParam);
+
+ for (UINT i = 0; i < pMenu->GetMenuItemCount(); ++i)
+ {
+ MENUITEMINFO mii = {0};
+ mii.cbSize = GetSizeofMenuItemInfo();
+
+ TCHAR szMenuItem[MAX_MENU_STRING] = _T("");
+
+ // Use old fashioned MIIM_TYPE instead of MIIM_FTYPE for MS VC6 compatibility
+ mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_SUBMENU;
+ mii.dwTypeData = szMenuItem;
+ mii.cch = MAX_MENU_STRING -1;
+
+ // Send message for menu updates
+ UINT menuItem = pMenu->GetMenuItemID(i);
+ SendMessage(UWM_UPDATE_COMMAND, (WPARAM)menuItem, 0);
+
+ // Specify owner-draw for the menu item type
+ if (pMenu->GetMenuItemInfo(i, &mii, TRUE))
+ {
+ if (0 == mii.dwItemData)
+ {
+ ItemData* pItem = new ItemData; // deleted in OnExitMenuLoop
+ pItem->hMenu = *pMenu;
+ pItem->nPos = i;
+ pItem->fType = mii.fType;
+ pItem->hSubMenu = mii.hSubMenu;
+ mii.fType |= MFT_OWNERDRAW;
+ lstrcpyn(pItem->GetItemText(), szMenuItem, MAX_MENU_STRING);
+ mii.dwItemData = (DWORD_PTR)pItem;
+
+ m_vMenuItemData.push_back(ItemDataPtr(pItem)); // Store pItem in m_vMenuItemData
+ pMenu->SetMenuItemInfo(i, &mii, TRUE); // Store pItem in mii
+ }
+ }
+ }
+ }
+ }
+
+ inline LRESULT CFrame::OnMeasureItem(WPARAM wParam, LPARAM lParam)
+ // Called before the Popup menu is displayed, so that the MEASUREITEMSTRUCT
+ // values can be assigned with the menu item's dimensions.
+ {
+ LPMEASUREITEMSTRUCT pmis = (LPMEASUREITEMSTRUCT) lParam;
+ if (pmis->CtlType != ODT_MENU)
+ return CWnd::WndProcDefault(WM_MEASUREITEM, wParam, lParam);
+
+ ItemData* pmd = (ItemData *) pmis->itemData;
+ assert(::IsMenu(pmd->hMenu)); // Does itemData contain a valid ItemData struct?
+ MenuTheme tm = GetMenuTheme();
+
+ if (pmd->fType & MFT_SEPARATOR)
+ {
+ pmis->itemHeight = 7;
+ pmis->itemWidth = 0;
+ }
+
+ else
+ {
+ CClientDC DesktopDC(NULL);
+
+ // Get the font used in menu items
+ NONCLIENTMETRICS nm = {0};
+ nm.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nm), &nm, 0);
+ // Default menu items are bold, so take this into account
+ if ((int)::GetMenuDefaultItem(pmd->hMenu, TRUE, GMDI_USEDISABLED) != -1)
+ nm.lfMenuFont.lfWeight = FW_BOLD;
+
+ TCHAR* pItemText = &(pmd->vItemText[0]);
+ DesktopDC.CreateFontIndirect(&nm.lfMenuFont);
+
+ // Calculate the size of the text
+ CSize size = DesktopDC.GetTextExtentPoint32(pItemText, lstrlen(pItemText));
+
+ // Calculate the size of the icon
+ int Iconx = 16;
+ int Icony = 16;
+ if (m_himlMenu) ImageList_GetIconSize(m_himlMenu, &Iconx, &Icony);
+
+ pmis->itemHeight = 2+ MAX(MAX(size.cy, GetSystemMetrics(SM_CYMENU)-2), Icony+2);
+ pmis->itemWidth = size.cx + MAX(::GetSystemMetrics(SM_CXMENUSIZE), Iconx+2);
+
+ // Allow extra width if the text includes a tab
+ if (_tcschr(pItemText, _T('\t')))
+ pmis->itemWidth += POST_TEXT_GAP;
+
+ // Allow extra width if the menu item has a sub menu
+ if (pmd->hSubMenu)
+ pmis->itemWidth += 10;
+
+ // Allow extra width for themed menu
+ if (tm.UseThemes)
+ pmis->itemWidth += 8;
+ }
+ return TRUE;
+ }
+
+ inline LRESULT CFrame::OnMenuChar(WPARAM wParam, LPARAM lParam)
+ {
+ if ((IsMenuBarUsed()) && (LOWORD(wParam)!= VK_SPACE))
+ {
+ // Activate MenuBar for key pressed with Alt key held down
+ GetMenuBar().OnMenuChar(wParam, lParam);
+ return -1L;
+ }
+ return CWnd::WndProcDefault(WM_MENUCHAR, wParam, lParam);
+ }
+
+ inline void CFrame::OnMenuSelect(WPARAM wParam, LPARAM lParam)
+ {
+ // Set the StatusBar text when we hover over a menu
+ // Only popup submenus have status strings
+ if (m_bShowMenuStatus)
+ {
+ int nID = LOWORD (wParam);
+ CMenu* pMenu = FromHandle((HMENU) lParam);
+
+ if ((pMenu != GetMenu()) && (nID != 0) && !(HIWORD(wParam) & MF_POPUP))
+ m_tsStatusText = LoadString(nID);
+ else
+ m_tsStatusText = _T("Ready");
+
+ SetStatusText();
+ }
+ }
+
+ inline LRESULT CFrame::OnNotify(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case UWM_UNDOCKED:
+ m_hOldFocus = 0;
+ break;
+ case RBN_HEIGHTCHANGE:
+ RecalcLayout();
+ Invalidate();
+ break;
+ // case RBN_LAYOUTCHANGED:
+ // if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().BandsLeft)
+ // GetReBar().MoveBandsLeft();
+ // break;
+ case RBN_MINMAX:
+ if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().ShortBands)
+ return 1L; // Supress maximise or minimise rebar band
+ break;
+
+ // Display tooltips for the toolbar
+ case TTN_GETDISPINFO:
+ if (GetToolBar().IsWindow())
+ {
+ CToolBar* pToolBar = 0;
+ if (IsReBarUsed())
+ {
+ // Get the ToolBar's CWnd
+ CWnd* pWnd = FromHandle(GetReBar().HitTest(GetCursorPos()));
+ if (pWnd && (lstrcmp(pWnd->GetClassName(), _T("ToolbarWindow32")) == 0))
+ {
+ pToolBar = (CToolBar*)pWnd;
+ }
+ }
+
+ if (pToolBar)
+ {
+ LPNMTTDISPINFO lpDispInfo = (LPNMTTDISPINFO)lParam;
+ int iIndex = pToolBar->HitTest();
+ if (iIndex >= 0)
+ {
+ int nID = pToolBar->GetCommandID(iIndex);
+ if (nID > 0)
+ {
+ m_tsTooltip = LoadString(nID);
+ lpDispInfo->lpszText = (LPTSTR)m_tsTooltip.c_str();
+ }
+ else
+ m_tsTooltip = _T("");
+ }
+ }
+ }
+ break;
+ } // switch LPNMHDR
+
+ return 0L;
+
+ } // CFrame::Onotify(...)
+
+ inline void CFrame::OnSetFocus()
+ {
+ SetStatusText();
+ }
+
+ inline void CFrame::OnSysColorChange()
+ {
+ // Honour theme color changes
+ for (int nBand = 0; nBand <= GetReBar().GetBandCount(); ++nBand)
+ {
+ GetReBar().SetBandColor(nBand, GetSysColor(COLOR_BTNTEXT), GetSysColor(COLOR_BTNFACE));
+ }
+
+ // Update the status bar font and text
+ NONCLIENTMETRICS nm = {0};
+ nm.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &nm, 0);
+ LOGFONT lf = nm.lfStatusFont;
+ CFont* pFont = FromHandle(CreateFontIndirect(&lf));
+ GetStatusBar().SetFont(pFont, FALSE);
+ SetStatusText();
+
+ if ((m_bUpdateTheme) && (m_bUseThemes)) SetTheme();
+
+ // Reposition and redraw everything
+ RecalcLayout();
+ RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+ // Forward the message to the view window
+ m_pView->PostMessage(WM_SYSCOLORCHANGE, 0L, 0L);
+ }
+
+ inline LRESULT CFrame::OnSysCommand(WPARAM wParam, LPARAM lParam)
+ {
+ if ((SC_KEYMENU == wParam) && (VK_SPACE != lParam) && IsMenuBarUsed())
+ {
+ GetMenuBar().OnSysCommand(wParam, lParam);
+ return 0L;
+ }
+
+ if (SC_MINIMIZE == wParam)
+ m_hOldFocus = ::GetFocus();
+
+ return CWnd::WndProcDefault(WM_SYSCOMMAND, wParam, lParam);
+ }
+
+ inline void CFrame::OnTimer(WPARAM wParam)
+ {
+ if (ID_STATUS_TIMER == wParam)
+ {
+ if (m_bShowMenuStatus)
+ {
+ // Get the toolbar the point is over
+ CToolBar* pToolBar = 0;
+ if (IsReBarUsed())
+ {
+ // Get the ToolBar's CWnd
+ CWnd* pWnd = FromHandle(GetReBar().HitTest(GetCursorPos()));
+ if (pWnd && (dynamic_cast<CToolBar*>(pWnd)) && !(dynamic_cast<CMenuBar*>(pWnd)))
+ pToolBar = (CToolBar*)pWnd;
+ }
+ else
+ {
+ CPoint pt = GetCursorPos();
+ CWnd* pWnd = WindowFromPoint(GetCursorPos());
+ if (pWnd && (dynamic_cast<CToolBar*>(pWnd)))
+ pToolBar = (CToolBar*)pWnd;
+ }
+
+ if ((pToolBar) && (WindowFromPoint(GetCursorPos()) == pToolBar))
+ {
+ // Which toolbar button is the mouse cursor hovering over?
+ int nButton = pToolBar->HitTest();
+ if (nButton >= 0)
+ {
+ int nID = pToolBar->GetCommandID(nButton);
+ // Only update the statusbar if things have changed
+ if (nID != m_nOldID)
+ {
+ if (nID != 0)
+ m_tsStatusText = LoadString(nID);
+ else
+ m_tsStatusText = _T("Ready");
+
+ if (GetStatusBar().IsWindow())
+ SetStatusText();
+ }
+ m_nOldID = nID;
+ }
+ }
+ else
+ {
+ if (m_nOldID != -1)
+ {
+ m_tsStatusText = _T("Ready");
+ SetStatusText();
+ }
+ m_nOldID = -1;
+ }
+ }
+
+ if (m_bShowIndicatorStatus)
+ SetStatusIndicators();
+ }
+ }
+
+ inline void CFrame::OnViewStatusBar()
+ {
+ m_bShowStatusBar = !m_bShowStatusBar;
+ ShowStatusBar(m_bShowStatusBar);
+ }
+
+ inline void CFrame::OnViewToolBar()
+ {
+ m_bShowToolBar = !m_bShowToolBar;
+ ShowToolBar(m_bShowToolBar);
+ }
+
+ inline void CFrame::PreCreate(CREATESTRUCT& cs)
+ {
+ // Set the frame window styles
+ cs.style = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
+
+ // Set the original window position
+ cs.x = m_rcPosition.left;
+ cs.y = m_rcPosition.top;
+ cs.cx = m_rcPosition.Width();
+ cs.cy = m_rcPosition.Height();
+ }
+
+ inline void CFrame::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = _T("Win32++ Frame");
+ }
+
+ inline void CFrame::RecalcLayout()
+ {
+ CWnd* pView = GetView();
+ if ((!pView) || (!pView->GetHwnd()))
+ return;
+
+ // Resize the status bar
+ if (GetStatusBar().IsWindow() && m_bShowStatusBar)
+ {
+ GetStatusBar().SetWindowPos(NULL, 0, 0, 0, 0, SWP_SHOWWINDOW);
+ GetStatusBar().Invalidate();
+ SetStatusText();
+ }
+
+ // Resize the rebar or toolbar
+ if (IsReBarUsed())
+ {
+ GetReBar().SendMessage(WM_SIZE, 0L, 0L);
+ GetReBar().Invalidate();
+ }
+ else if (m_bUseToolBar && m_bShowToolBar)
+ GetToolBar().SendMessage(TB_AUTOSIZE, 0L, 0L);
+
+ // Resize the View window
+ CRect rClient = GetViewRect();
+ if ((rClient.bottom - rClient.top) >= 0)
+ {
+ int x = rClient.left;
+ int y = rClient.top;
+ int cx = rClient.Width();
+ int cy = rClient.Height();
+
+ pView->SetWindowPos( NULL, x, y, cx, cy, SWP_SHOWWINDOW|SWP_ASYNCWINDOWPOS );
+ }
+
+ // Adjust rebar bands
+ if (IsReBarUsed())
+ {
+ if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().BandsLeft)
+ GetReBar().MoveBandsLeft();
+
+ if (IsMenuBarUsed())
+ SetMenuBarBandSize();
+ }
+ }
+
+ inline void CFrame::RemoveMRUEntry(LPCTSTR szMRUEntry)
+ {
+ std::vector<tString>::iterator it;
+ for (it = m_vMRUEntries.begin(); it != m_vMRUEntries.end(); ++it)
+ {
+ if ((*it) == szMRUEntry)
+ {
+ m_vMRUEntries.erase(it);
+ break;
+ }
+ }
+
+ UpdateMRUMenu();
+ }
+
+ inline BOOL CFrame::SaveRegistrySettings()
+ {
+ // Store the window position in the registry
+ if (!m_tsKeyName.empty())
+ {
+ tString tsKeyName = _T("Software\\") + m_tsKeyName + _T("\\Frame Settings");
+ HKEY hKey = NULL;
+
+ try
+ {
+ if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, tsKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
+ throw CWinException(_T("RegCreateKeyEx failed"));
+
+ WINDOWPLACEMENT Wndpl = {0};
+ Wndpl.length = sizeof(WINDOWPLACEMENT);
+
+ if (GetWindowPlacement(Wndpl))
+ {
+ // Get the Frame's window position
+ CRect rc = Wndpl.rcNormalPosition;
+ DWORD dwTop = MAX(rc.top, 0);
+ DWORD dwLeft = MAX(rc.left, 0);
+ DWORD dwWidth = MAX(rc.Width(), 100);
+ DWORD dwHeight = MAX(rc.Height(), 50);
+
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Top"), 0, REG_DWORD, (LPBYTE)&dwTop, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Left"), 0, REG_DWORD, (LPBYTE)&dwLeft, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Width"), 0, REG_DWORD, (LPBYTE)&dwWidth, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("Height"), 0, REG_DWORD, (LPBYTE)&dwHeight, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ }
+
+ // Store the ToolBar and statusbar states
+ DWORD dwShowToolBar = m_bShowToolBar;
+ DWORD dwShowStatusBar = m_bShowStatusBar;
+
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("ToolBar"), 0, REG_DWORD, (LPBYTE)&dwShowToolBar, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, _T("StatusBar"), 0, REG_DWORD, (LPBYTE)&dwShowStatusBar, sizeof(DWORD)))
+ throw CWinException(_T("RegSetValueEx failed"));
+
+ RegCloseKey(hKey);
+ }
+
+ catch (const CWinException& e)
+ {
+ TRACE(_T("Failed to save registry settings\n"));
+
+ if (hKey)
+ {
+ // Roll back the registry changes by deleting this subkey
+ RegDeleteKey(HKEY_CURRENT_USER ,tsKeyName.c_str());
+ RegCloseKey(hKey);
+ }
+
+ e.what();
+ return FALSE;
+ }
+
+ // Store the MRU entries in the registry
+ if (m_nMaxMRU > 0)
+ {
+ tString tsKeyName = _T("Software\\") + m_tsKeyName + _T("\\Recent Files");
+ HKEY hKey = NULL;
+
+ try
+ {
+ if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, tsKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
+ throw CWinException(_T("RegCreateKeyEx failed"));
+
+ for (UINT i = 0; i < m_nMaxMRU; ++i)
+ {
+ TCHAR szSubKey[10];
+ wsprintf(szSubKey, _T("File %d\0"), i+1);
+ tString tsPathName;
+ if (i < m_vMRUEntries.size())
+ tsPathName = m_vMRUEntries[i];
+
+ if (ERROR_SUCCESS != RegSetValueEx(hKey, szSubKey, 0, REG_SZ, (LPBYTE)tsPathName.c_str(), (1 + lstrlen(tsPathName.c_str()))*sizeof(TCHAR)))
+ throw CWinException(_T("RegSetValueEx failed"));
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ catch (const CWinException& e)
+ {
+ TRACE(_T("Failed to save registry MRU settings\n"));
+
+ if (hKey)
+ {
+ // Roll back the registry changes by deleting this subkey
+ RegDeleteKey(HKEY_CURRENT_USER ,tsKeyName.c_str());
+ RegCloseKey(hKey);
+ }
+
+ e.what();
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+
+ inline void CFrame::SetFrameMenu(INT ID_MENU)
+ {
+ // Sets the frame's menu from a Resouce ID.
+ // A resource ID of 0 removes the menu from the frame.
+ HMENU hMenu = 0;
+ if (ID_MENU != 0)
+ {
+ // Sets the frame's menu from a resource ID.
+ hMenu = ::LoadMenu(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(ID_MENU));
+ assert (hMenu);
+ }
+
+ SetFrameMenu(hMenu);
+ }
+
+ inline void CFrame::SetFrameMenu(HMENU hMenu)
+ {
+ // Sets the frame's menu from a HMENU.
+ m_Menu.Attach(hMenu);
+
+ if (IsMenuBarUsed())
+ {
+ GetMenuBar().SetMenu(GetFrameMenu());
+ BOOL bShow = (hMenu != NULL); // boolean expression
+ ShowMenu(bShow);
+ }
+ else
+ SetMenu(&m_Menu);
+ }
+
+ inline UINT CFrame::SetMenuIcons(const std::vector<UINT>& MenuData, COLORREF crMask, UINT ToolBarID, UINT ToolBarDisabledID)
+ {
+ // Remove any existing menu icons
+ if (m_himlMenu) ImageList_Destroy(m_himlMenu);
+ if (m_himlMenuDis) ImageList_Destroy(m_himlMenuDis);
+ m_himlMenu = NULL;
+ m_himlMenuDis = NULL;
+ m_vMenuIcons.clear();
+
+ // Exit if no ToolBarID is specified
+ if (ToolBarID == 0) return 0;
+
+ // Add the menu icons from the bitmap IDs
+ return AddMenuIcons(MenuData, crMask, ToolBarID, ToolBarDisabledID);
+ }
+
+ inline void CFrame::SetMenuBarBandSize()
+ {
+ // Sets the minimum width of the MenuBar band to the width of the rebar
+ // This prevents other bands from moving to this MenuBar's row.
+
+ CRect rcClient = GetClientRect();
+ CReBar& RB = GetReBar();
+ int nBand = RB.GetBand(GetMenuBar());
+ CRect rcBorder = RB.GetBandBorders(nBand);
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_SIZE;
+ RB.GetBandInfo(nBand, rbbi);
+
+ int Width;
+ if ((GetReBar().GetReBarTheme().UseThemes) && (GetReBar().GetReBarTheme().LockMenuBand))
+ Width = rcClient.Width() - rcBorder.Width() - 2;
+ else
+ Width = GetMenuBar().GetMaxSize().cx;
+
+ rbbi.cxMinChild = Width;
+ rbbi.cx = Width;
+
+ RB.SetBandInfo(nBand, rbbi);
+ }
+
+ inline void CFrame::SetMenuTheme(MenuTheme& Theme)
+ {
+ m_ThemeMenu.UseThemes = Theme.UseThemes;
+ m_ThemeMenu.clrHot1 = Theme.clrHot1;
+ m_ThemeMenu.clrHot2 = Theme.clrHot2;
+ m_ThemeMenu.clrPressed1 = Theme.clrPressed1;
+ m_ThemeMenu.clrPressed2 = Theme.clrPressed2;
+ m_ThemeMenu.clrOutline = Theme.clrOutline;
+
+ GetMenuBar().SetMenuBarTheme(Theme); // Sets the theme for MenuBar buttons
+ Invalidate();
+ }
+
+ inline void CFrame::SetStatusIndicators()
+ {
+ if (::IsWindow(GetStatusBar()))
+ {
+ LPCTSTR Status1 = (::GetKeyState(VK_CAPITAL) & 0x0001)? _T("\tCAP") : _T("");
+ LPCTSTR Status2 = (::GetKeyState(VK_NUMLOCK) & 0x0001)? _T("\tNUM") : _T("");
+ LPCTSTR Status3 = (::GetKeyState(VK_SCROLL) & 0x0001)? _T("\tSCRL"): _T("");
+
+ // Only update indictors if the text has changed
+ if (Status1 != m_OldStatus[0]) GetStatusBar().SetPartText(1, (Status1));
+ if (Status2 != m_OldStatus[1]) GetStatusBar().SetPartText(2, (Status2));
+ if (Status3 != m_OldStatus[2]) GetStatusBar().SetPartText(3, (Status3));
+
+ m_OldStatus[0] = Status1;
+ m_OldStatus[1] = Status2;
+ m_OldStatus[2] = Status3;
+ }
+ }
+
+ inline void CFrame::SetStatusText()
+ {
+ if (::IsWindow(GetStatusBar()))
+ {
+ // Calculate the width of the text indicators
+ CClientDC dcStatus(&GetStatusBar());
+ CSize csCAP = dcStatus.GetTextExtentPoint32(_T("\tCAP"), lstrlen(_T("\tCAP")));
+ CSize csNUM = dcStatus.GetTextExtentPoint32(_T("\tNUM"), lstrlen(_T("\tNUM")));
+ CSize csSCRL = dcStatus.GetTextExtentPoint32(_T("\tSCRL "), lstrlen(_T("\tSCRL ")));
+
+ // Get the coordinates of the parent window's client area.
+ CRect rcClient = GetClientRect();
+ int width = MAX(300, rcClient.right);
+
+ if (m_bShowIndicatorStatus)
+ {
+ // Create 4 panes
+ GetStatusBar().SetPartWidth(0, width - (csCAP.cx+csNUM.cx+csSCRL.cx+20));
+ GetStatusBar().SetPartWidth(1, csCAP.cx);
+ GetStatusBar().SetPartWidth(2, csNUM.cx);
+ GetStatusBar().SetPartWidth(3, csSCRL.cx);
+
+ SetStatusIndicators();
+ }
+
+ // Place text in the 1st pane
+ GetStatusBar().SetPartText(0, m_tsStatusText.c_str());
+ }
+ }
+
+ inline void CFrame::SetTheme()
+ {
+ // Note: To modify theme colors, override this function in CMainframe,
+ // and make any modifications there.
+
+ // Avoid themes if using less than 16 bit colors
+ CClientDC DesktopDC(NULL);
+ if (DesktopDC.GetDeviceCaps(BITSPIXEL) < 16)
+ m_bUseThemes = FALSE;
+
+ BOOL T = TRUE;
+ BOOL F = FALSE;
+
+ if (m_bUseThemes)
+ {
+ // Set a flag redo SetTheme when the theme changes
+ m_bUpdateTheme = TRUE;
+
+ // Detect the XP theme name
+ WCHAR Name[30] = L"";
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));
+ if(hMod)
+ {
+ typedef HRESULT (__stdcall *PFNGETCURRENTTHEMENAME)(LPWSTR pszThemeFileName, int cchMaxNameChars,
+ LPWSTR pszColorBuff, int cchMaxColorChars, LPWSTR pszSizeBuff, int cchMaxSizeChars);
+
+ PFNGETCURRENTTHEMENAME pfn = (PFNGETCURRENTTHEMENAME)GetProcAddress(hMod, "GetCurrentThemeName");
+
+ (*pfn)(0, 0, Name, 30, 0, 0);
+
+ ::FreeLibrary(hMod);
+ }
+
+ enum Themetype{ Modern, Grey, Blue, Silver, Olive };
+
+ int Theme = Grey;
+ if (GetWinVersion() < 2600) // Not for Vista and above
+ {
+ if (0 == wcscmp(L"NormalColor", Name)) Theme = Blue;
+ if (0 == wcscmp(L"Metallic", Name)) Theme = Silver;
+ if (0 == wcscmp(L"HomeStead", Name)) Theme = Olive;
+ }
+ else
+ Theme = Modern;
+
+ switch (Theme)
+ {
+ case Modern:
+ {
+ ToolBarTheme tt = {T, RGB(180, 250, 255), RGB(140, 190, 255), RGB(150, 220, 255), RGB(80, 100, 255), RGB(127, 127, 255)};
+ ReBarTheme tr = {T, RGB(220, 225, 250), RGB(240, 242, 250), RGB(240, 240, 250), RGB(180, 200, 230), F, T, T, T, T, F};
+ MenuTheme tm = {T, RGB(180, 250, 255), RGB(140, 190, 255), RGB(240, 250, 255), RGB(120, 170, 220), RGB(127, 127, 255)};
+
+ GetToolBar().SetToolBarTheme(tt);
+ SetMenuTheme(tm); // Sets the theme for popup menus and MenuBar
+
+ GetReBar().SetReBarTheme(tr);
+ }
+ break;
+
+ case Grey: // A color scheme suitable for 16 bit colors. Suitable for Windows older than XP.
+ {
+ ToolBarTheme tt = {T, RGB(182, 189, 210), RGB(182, 189, 210), RGB(133, 146, 181), RGB(133, 146, 181), RGB(10, 36, 106)};
+ ReBarTheme tr = {T, RGB(212, 208, 200), RGB(212, 208, 200), RGB(230, 226, 222), RGB(220, 218, 208), F, T, T, T, T, F};
+ MenuTheme tm = {T, RGB(182, 189, 210), RGB( 182, 189, 210), RGB(200, 196, 190), RGB(200, 196, 190), RGB(100, 100, 100)};
+
+ GetToolBar().SetToolBarTheme(tt);
+ SetMenuTheme(tm); // Sets the theme for popup menus and MenuBar
+
+ GetReBar().SetReBarTheme(tr);
+ }
+ break;
+ case Blue:
+ {
+ // Used for XP default (blue) color scheme
+ ToolBarTheme tt = {T, RGB(255, 230, 190), RGB(255, 190, 100), RGB(255, 140, 40), RGB(255, 180, 80), RGB(192, 128, 255)};
+ ReBarTheme tr = {T, RGB(150,190,245), RGB(196,215,250), RGB(220,230,250), RGB( 70,130,220), F, T, T, T, T, F};
+ MenuTheme tm = {T, RGB(255, 230, 190), RGB(255, 190, 100), RGB(220,230,250), RGB(150,190,245), RGB(128, 128, 200)};
+
+ GetToolBar().SetToolBarTheme(tt);
+ SetMenuTheme(tm); // Sets the theme for popup menus and MenuBar
+
+ GetReBar().SetReBarTheme(tr);
+ }
+ break;
+
+ case Silver:
+ {
+ // Used for XP Silver color scheme
+ ToolBarTheme tt = {T, RGB(192, 210, 238), RGB(192, 210, 238), RGB(152, 181, 226), RGB(152, 181, 226), RGB(49, 106, 197)};
+ ReBarTheme tr = {T, RGB(225, 220, 240), RGB(240, 240, 245), RGB(245, 240, 255), RGB(160, 155, 180), F, T, T, T, T, F};
+ MenuTheme tm = {T, RGB(196, 215, 250), RGB( 120, 180, 220), RGB(240, 240, 245), RGB(170, 165, 185), RGB(128, 128, 150)};
+
+ GetToolBar().SetToolBarTheme(tt);
+ SetMenuTheme(tm); // Sets the theme for popup menus and MenuBar
+
+ GetReBar().SetReBarTheme(tr);
+ }
+ break;
+
+ case Olive:
+ {
+ // Used for XP Olive color scheme
+ ReBarTheme tr = {T, RGB(215, 216, 182), RGB(242, 242, 230), RGB(249, 255, 227), RGB(178, 191, 145), F, T, T, T, T, F};
+ ToolBarTheme tt = {T, RGB(255, 230, 190), RGB(255, 190, 100), RGB(255, 140, 40), RGB(255, 180, 80), RGB(200, 128, 128)};
+ MenuTheme tm = {T, RGB(255, 230, 190), RGB(255, 190, 100), RGB(249, 255, 227), RGB(178, 191, 145), RGB(128, 128, 128)};
+
+ GetToolBar().SetToolBarTheme(tt);
+ SetMenuTheme(tm); // Sets the theme for popup menus and MenuBar
+
+ GetReBar().SetReBarTheme(tr);
+ }
+ break;
+ }
+ }
+ else
+ {
+ // Use a classic style by default
+ ReBarTheme tr = {T, 0, 0, 0, 0, F, T, T, F, F, F};
+ GetReBar().SetReBarTheme(tr);
+ }
+
+ RecalcLayout();
+ }
+
+ inline void CFrame::SetToolBarImages(COLORREF crMask, UINT ToolBarID, UINT ToolBarHotID, UINT ToolBarDisabledID)
+ // Either sets the imagelist or adds/replaces bitmap depending on ComCtl32.dll version
+ // Assumes the width of the button image = bitmap_size / buttons
+ // Assumes buttons have been already been added via AdddToolBarButton
+ // The colour mask is ignored for 32bit bitmaps, but is required for 24bit bitmaps
+ // The colour mask is often grey RGB(192,192,192) or magenta (255,0,255)
+ // The color mask is ignored for 32bit bitmap resources
+ // The Hot and disabled bitmap resources can be 0
+ {
+ GetToolBar().SetImages(crMask, ToolBarID, ToolBarHotID, ToolBarDisabledID);
+ }
+
+ inline void CFrame::SetupToolBar()
+ {
+ // Use this function to set the Resource IDs for the toolbar(s).
+
+/* // Set the Resource IDs for the toolbar buttons
+ AddToolBarButton( IDM_FILE_NEW );
+ AddToolBarButton( IDM_FILE_OPEN );
+ AddToolBarButton( IDM_FILE_SAVE );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_EDIT_CUT );
+ AddToolBarButton( IDM_EDIT_COPY );
+ AddToolBarButton( IDM_EDIT_PASTE );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_FILE_PRINT );
+ AddToolBarButton( 0 ); // Separator
+ AddToolBarButton( IDM_HELP_ABOUT );
+*/
+ }
+
+ inline void CFrame::SetView(CWnd& wndView)
+ // Sets or changes the View window displayed within the frame
+ {
+ if (m_pView != &wndView)
+ {
+ // Destroy the existing view window (if any)
+ if (m_pView) m_pView->Destroy();
+
+ // Assign the view window
+ m_pView = &wndView;
+
+ if (m_hWnd)
+ {
+ // The frame is already created, so create and position the new view too
+ assert(GetView()); // Use SetView in CMainFrame's constructor to set the view window
+ GetView()->Create(this);
+ RecalcLayout();
+ }
+ }
+ }
+
+ inline void CFrame::ShowMenu(BOOL bShow)
+ {
+ if (bShow)
+ {
+ if (IsReBarUsed())
+ GetReBar().SendMessage(RB_SHOWBAND, GetReBar().GetBand(GetMenuBar()), TRUE);
+ else
+ SetMenu(&m_Menu);
+ }
+ else
+ {
+ if (IsReBarUsed())
+ GetReBar().SendMessage(RB_SHOWBAND, GetReBar().GetBand(GetMenuBar()), FALSE);
+ else
+ SetMenu(NULL);
+ }
+
+ if (GetReBar().IsWindow())
+ {
+ if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().BandsLeft)
+ GetReBar().MoveBandsLeft();
+ }
+
+ // Reposition the Windows
+ RecalcLayout();
+ }
+
+
+
+ inline void CFrame::ShowStatusBar(BOOL bShow)
+ {
+ if (bShow)
+ {
+ m_Menu.CheckMenuItem(IDW_VIEW_STATUSBAR, MF_CHECKED);
+ GetStatusBar().ShowWindow(SW_SHOW);
+ }
+ else
+ {
+ m_Menu.CheckMenuItem(IDW_VIEW_STATUSBAR, MF_UNCHECKED);
+ GetStatusBar().ShowWindow(SW_HIDE);
+ }
+
+ // Reposition the Windows
+ RecalcLayout();
+ }
+
+ inline void CFrame::ShowToolBar(BOOL bShow)
+ {
+ if (bShow)
+ {
+ m_Menu.CheckMenuItem(IDW_VIEW_TOOLBAR, MF_CHECKED);
+ if (IsReBarUsed())
+ GetReBar().SendMessage(RB_SHOWBAND, GetReBar().GetBand(GetToolBar()), TRUE);
+ else
+ GetToolBar().ShowWindow(SW_SHOW);
+ }
+ else
+ {
+ m_Menu.CheckMenuItem(IDW_VIEW_TOOLBAR, MF_UNCHECKED);
+ if (IsReBarUsed())
+ GetReBar().SendMessage(RB_SHOWBAND, GetReBar().GetBand(GetToolBar()), FALSE);
+ else
+ GetToolBar().ShowWindow(SW_HIDE);
+ }
+
+ if (GetReBar().IsWindow())
+ {
+ if (GetReBar().GetReBarTheme().UseThemes && GetReBar().GetReBarTheme().BandsLeft)
+ GetReBar().MoveBandsLeft();
+ }
+
+ // Reposition the Windows
+ RecalcLayout();
+ }
+
+ inline void CFrame::UpdateMRUMenu()
+ {
+ if (0 >= m_nMaxMRU) return;
+
+ // Set the text for the MRU Menu
+ tString tsMRUArray[16];
+ UINT MaxMRUArrayIndex = 0;
+ if (m_vMRUEntries.size() > 0)
+ {
+ for (UINT n = 0; ((n < m_vMRUEntries.size()) && (n <= m_nMaxMRU)); ++n)
+ {
+ tsMRUArray[n] = m_vMRUEntries[n];
+ if (tsMRUArray[n].length() > MAX_MENU_STRING - 10)
+ {
+ // Truncate the string if its too long
+ tsMRUArray[n].erase(0, tsMRUArray[n].length() - MAX_MENU_STRING +10);
+ tsMRUArray[n] = _T("... ") + tsMRUArray[n];
+ }
+
+ // Prefix the string with its number
+ TCHAR tVal[5];
+ wsprintf(tVal, _T("%d "), n+1);
+ tsMRUArray[n] = tVal + tsMRUArray[n];
+ MaxMRUArrayIndex = n;
+ }
+ }
+ else
+ {
+ tsMRUArray[0] = _T("Recent Files");
+ }
+
+ // Set MRU menu items
+ MENUITEMINFO mii = {0};
+ mii.cbSize = GetSizeofMenuItemInfo();
+
+ int nFileItem = 0; // We place the MRU items under the left most menu item
+ CMenu* pFileMenu = GetFrameMenu().GetSubMenu(nFileItem);
+
+ if (pFileMenu)
+ {
+ // Remove all but the first MRU Menu entry
+ for (UINT u = IDW_FILE_MRU_FILE2; u <= IDW_FILE_MRU_FILE1 +16; ++u)
+ {
+ pFileMenu->DeleteMenu(u, MF_BYCOMMAND);
+ }
+
+ int MaxMRUIndex = (int)MIN(MaxMRUArrayIndex, m_nMaxMRU);
+
+ for (int index = MaxMRUIndex; index >= 0; --index)
+ {
+ mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+ mii.fState = (0 == m_vMRUEntries.size())? MFS_GRAYED : 0;
+ mii.fType = MFT_STRING;
+ mii.wID = IDW_FILE_MRU_FILE1 + index;
+ mii.dwTypeData = (LPTSTR)tsMRUArray[index].c_str();
+
+ BOOL bResult;
+ if (index == MaxMRUIndex)
+ // Replace the last MRU entry first
+ bResult = pFileMenu->SetMenuItemInfo(IDW_FILE_MRU_FILE1, &mii, FALSE);
+ else
+ // Insert the other MRU entries next
+ bResult = pFileMenu->InsertMenuItem(IDW_FILE_MRU_FILE1 + index + 1, &mii, FALSE);
+
+ if (!bResult)
+ {
+ TRACE(_T("Failed to set MRU menu item\n"));
+ break;
+ }
+ }
+ }
+
+ DrawMenuBar();
+ }
+
+ inline LRESULT CFrame::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_ACTIVATE:
+ OnActivate(wParam, lParam);
+ return 0L;
+ case WM_CLOSE:
+ OnClose();
+ break;
+ case WM_DESTROY:
+ OnDestroy();
+ return 0L;
+ case WM_ERASEBKGND:
+ return 0L;
+ case WM_HELP:
+ OnHelp();
+ return 0L;
+ case WM_MENUCHAR:
+ return OnMenuChar(wParam, lParam);
+ case WM_MENUSELECT:
+ OnMenuSelect(wParam, lParam);
+ return 0L;
+ case WM_SETFOCUS:
+ OnSetFocus();
+ break;
+ case WM_SIZE:
+ RecalcLayout();
+ return 0L;
+ case WM_SYSCOLORCHANGE:
+ // Changing themes trigger this
+ OnSysColorChange();
+ return 0L;
+ case WM_SYSCOMMAND:
+ return OnSysCommand(wParam, lParam);
+ case WM_TIMER:
+ OnTimer(wParam);
+ return 0L;
+ case WM_DRAWITEM:
+ // Owner draw menu items
+ return OnDrawItem(wParam, lParam);
+ case WM_INITMENUPOPUP:
+ OnInitMenuPopup(wParam, lParam);
+ break;
+ case WM_MEASUREITEM:
+ return OnMeasureItem(wParam, lParam);
+ case WM_EXITMENULOOP:
+ OnExitMenuLoop();
+ break;
+ case UWM_GETMENUTHEME:
+ {
+ MenuTheme& tm = GetMenuTheme();
+ return (LRESULT)&tm;
+ }
+ case UWM_GETREBARTHEME:
+ {
+ ReBarTheme& rm = GetReBarTheme();
+ return (LRESULT)&rm;
+ }
+ case UWM_GETTOOLBARTHEME:
+ {
+ ToolBarTheme& tt = GetToolBarTheme();
+ return (LRESULT)&tt;
+ }
+ } // switch uMsg
+
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ } // LRESULT CFrame::WndProcDefault(...)
+
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_FRAME_H_
diff --git a/mmc_updater/depends/win32cpp/gdi.h b/mmc_updater/depends/win32cpp/gdi.h
new file mode 100644
index 00000000..45141f7b
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/gdi.h
@@ -0,0 +1,3944 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// gdi.h
+// Declaration of the CDC class, and CBitmapInfoPtr class
+
+// The CDC class provides a device context, along with the various associated
+// objects such as Bitmaps, Brushes, Bitmaps, Fonts and Pens. This class
+// handles the creation, selection, de-selection and deletion of these objects
+// automatically. It also automatically deletes or releases the device context
+// itself as appropriate. Any failure to create the new GDI object throws an
+// exception.
+//
+// The CDC class is sufficient for most GDI programming needs. Sometimes
+// however we need to have the GDI object seperated from the device context.
+// Wrapper classes for GDI objects are provided for this purpose. The classes
+// are CBitmap, CBrush, CFont, CPalette, CPen and CRgn. These classes
+// automatically delete the GDI resouce assigned to them when their destructor
+// is called. These wrapper class objects can be attached to the CDC as
+// shown below.
+//
+// Coding Exampe without CDC ...
+// void DrawLine()
+// {
+// HDC hdcClient = ::GetDC(m_hWnd);
+// HDC hdcMem = ::CreateCompatibleDC(hdcClient);
+// HBITMAP hBitmap = ::CreateCompatibleBitmap(hdcClient, cx, cy);
+// HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hBitmap);
+// HPEN hPen = ::CreatePen(PS_SOLID, 1, RGB(255,0,0);
+// HPEN hOldPen = (HPEN)::SelectObject(hdcMem, hPen);
+// ::MoveToEx(hdcMem, 0, 0, NULL);
+// ::LineTo(hdcMem, 50, 50);
+// ::BitBlt(hdcClient, 0, 0, cx, cy, hdcMem, 0, 0);
+// ::SelectObject(hdcMem, hOldPen);
+// ::DeleteObject(hPen);
+// ::SelectObject(hdcMem, hOldBitmap);
+// ::DeleteObject(hBitmap);
+// ::DeleteDC(hdcMem);
+// ::ReleaseDC(m_hWnd, hdcClient);
+// }
+//
+// Coding Example with CDC classes ...
+// void DrawLine()
+// {
+// CClientDC dcClient(this)
+// CMemDC dcMem(&dcClient);
+// CBitmap* pOldBitmap = dcMem.CreateCompatibleBitmap(&dcClient, cx, cy);
+// CPen* pOldPen = CMemDC.CreatePen(PS_SOLID, 1, RGB(255,0,0);
+// CMemDC.MoveTo(0, 0);
+// CMemDC.LineTo(50, 50);
+// dcClient.BitBlt(0, 0, cx, cy, &CMemDC, 0, 0);
+// }
+//
+// Coding Example with CDC classes and CPen ...
+// void DrawLine()
+// {
+// CClientDC dcClient(this)
+// CMemDC CMemDC(&dcClient);
+// CBitmap* pOldBitmap = dcMem.CreateCompatibleBitmap(&dcClient, cx, cy);
+// CPen MyPen(PS_SOLID, 1, RGB(255,0,0));
+// CPen* pOldPen = CMemDC.SelectObject(&MyPen);
+// CMemDC.MoveTo(0, 0);
+// CMemDC.LineTo(50, 50);
+// dcClient.BitBlt(0, 0, cx, cy, &CMemDC, 0, 0);
+// }
+
+// Notes:
+// * When the CDC object drops out of scope, it's destructor is called, releasing
+// or deleting the device context as appropriate.
+// * When the destructor for CBitmap, CBrush, CPalette, CPen and CRgn are called,
+// the destructor is called deleting their GDI object.
+// * When the CDC object' destructor is called, any GDI objects created by one of
+// the CDC member functions (CDC::CreatePen for example) will be deleted.
+// * Bitmaps can only be selected into one device context at a time.
+// * Palettes use SelectPalatte to select them into device the context.
+// * Regions use SelectClipRgn to select them into the device context.
+// * The FromHandle function can be used to convert a GDI handle (HDC, HPEN,
+// HBITMAP etc) to a pointer of the appropriate GDI class (CDC, CPen CBitmap etc).
+// The FromHandle function creates a temporary object unless the HANDLE is already
+// assigned to a GDI class. Temporary objects don't delete their GDI object when
+// their destructor is called.
+// * All the GDI classes are reference counted. This allows functions to safely
+// pass these objects by value, as well as by pointer or by reference.
+
+// The CBitmapInfoPtr class is a convienient wrapper for the BITMAPINFO structure.
+// The size of the BITMAPINFO structure is dependant on the type of HBITMAP, and its
+// space needs to be allocated dynamically. CBitmapInfoPtr automatically allocates
+// and deallocates the memory for the structure. A CBitmapInfoPtr object can be
+// used anywhere in place of a LPBITMAPINFO. LPBITMAPINFO is used in functions like
+// GetDIBits and SetDIBits.
+//
+// Coding example ...
+// CDC MemDC = CreateCompatibleDC(NULL);
+// CBitmapInfoPtr pbmi(hBitmap);
+// MemDC.GetDIBits(hBitmap, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
+
+#ifndef _WIN32XX_GDI_H_
+#define _WIN32XX_GDI_H_
+
+#include "wincore.h"
+
+// Disable macros from Windowsx.h
+#undef CopyRgn
+
+namespace Win32xx
+{
+
+ /////////////////////////////////////////////////////////////////
+ // Declarations for some global functions in the Win32xx namespace
+ //
+#ifndef _WIN32_WCE
+ void GrayScaleBitmap(CBitmap* pbmSource);
+ void TintBitmap(CBitmap* pbmSource, int cRed, int cGreen, int cBlue);
+ HIMAGELIST CreateDisabledImageList(HIMAGELIST himlNormal);
+#endif
+
+ ///////////////////////////////////////////////
+ // Declarations for the CGDIObject class
+ //
+ class CGDIObject
+ {
+ friend CBitmap* FromHandle(HBITMAP hBitmap);
+ friend CBrush* FromHandle(HBRUSH hBrush);
+ friend CDC* FromHandle(HDC hDC);
+ friend CFont* FromHandle(HFONT hFont);
+ friend CPalette* FromHandle(HPALETTE hPalette);
+ friend CPen* FromHandle(HPEN hPen);
+ friend CRgn* FromHandle(HRGN hRgn);
+
+ public:
+ struct DataMembers // A structure that contains the data members for CGDIObject
+ {
+ HGDIOBJ hGDIObject;
+ long Count;
+ BOOL bRemoveObject;
+ };
+ CGDIObject();
+ CGDIObject(const CGDIObject& rhs);
+ virtual ~CGDIObject();
+ CGDIObject& operator = ( const CGDIObject& rhs );
+ void operator = (HGDIOBJ hObject);
+
+ void Attach(HGDIOBJ hObject);
+ HGDIOBJ Detach();
+ HGDIOBJ GetHandle() const;
+ int GetObject(int nCount, LPVOID pObject) const;
+
+ protected:
+ DataMembers* m_pData;
+
+ private:
+ void AddToMap();
+ BOOL RemoveFromMap();
+ void Release();
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CBitmap class
+ //
+ class CBitmap : public CGDIObject
+ {
+ public:
+ CBitmap();
+ CBitmap(HBITMAP hBitmap);
+ CBitmap(LPCTSTR lpstr);
+ CBitmap(int nID);
+ operator HBITMAP() const;
+ ~CBitmap();
+
+ // Create and load methods
+ BOOL LoadBitmap(LPCTSTR lpszName);
+ BOOL LoadBitmap(int nID);
+ BOOL LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad);
+ BOOL LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad);
+ BOOL LoadOEMBitmap(UINT nIDBitmap);
+ HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, LPCVOID lpBits);
+ HBITMAP CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight);
+ HBITMAP CreateDIBSection(CDC* pDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, LPVOID* ppvBits, HANDLE hSection, DWORD dwOffset);
+
+#ifndef _WIN32_WCE
+ HBITMAP CreateDIBitmap(CDC* pDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, LPCVOID lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse);
+ HBITMAP CreateMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0);
+ HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap);
+ int GetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const;
+ int SetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse);
+ CSize GetBitmapDimensionEx() const;
+ CSize SetBitmapDimensionEx(int nWidth, int nHeight);
+#endif // !_WIN32_WCE
+
+ // Attributes
+ BITMAP GetBitmapData() const;
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CBrush class
+ //
+ class CBrush : public CGDIObject
+ {
+ public:
+ CBrush();
+ CBrush(HBRUSH hBrush);
+ CBrush(COLORREF crColor);
+ operator HBRUSH() const;
+ ~CBrush();
+
+ HBRUSH CreateSolidBrush(COLORREF crColor);
+ HBRUSH CreatePatternBrush(CBitmap* pBitmap);
+ LOGBRUSH GetLogBrush() const;
+
+#ifndef _WIN32_WCE
+ HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor);
+ HBRUSH CreateBrushIndirect(LPLOGBRUSH lpLogBrush);
+ HBRUSH CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec);
+ HBRUSH CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT nUsage);
+#endif // !defined(_WIN32_WCE)
+
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CFont class
+ //
+ class CFont : public CGDIObject
+ {
+ public:
+ CFont();
+ CFont(HFONT hFont);
+ CFont(const LOGFONT* lpLogFont);
+ operator HFONT() const;
+ ~CFont();
+
+ // Create methods
+ HFONT CreateFontIndirect(const LOGFONT* lpLogFont);
+ HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL, BOOL bBold = FALSE, BOOL bItalic = FALSE);
+ HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC = NULL);
+
+#ifndef _WIN32_WCE
+ HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
+ int nOrientation, int nWeight, DWORD dwItalic, DWORD dwUnderline,
+ DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision,
+ DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily,
+ LPCTSTR lpszFacename);
+#endif // #ifndef _WIN32_WCE
+
+ // Attributes
+ LOGFONT GetLogFont() const;
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CPalette class
+ //
+ class CPalette : public CGDIObject
+ {
+ public:
+ CPalette();
+ CPalette(HPALETTE hPalette);
+ operator HPALETTE() const;
+ ~CPalette();
+
+ // Create methods
+ HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette);
+
+#ifndef _WIN32_WCE
+ HPALETTE CreateHalftonePalette(CDC* pDC);
+#endif // !_WIN32_WCE
+
+ // Attributes
+ int GetEntryCount() const;
+ UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const;
+ UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors);
+
+ // Operations
+#ifndef _WIN32_WCE
+ BOOL ResizePalette(UINT nNumEntries);
+ void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors);
+#endif // !_WIN32_WCE
+
+ UINT GetNearestPaletteIndex (COLORREF crColor) const;
+
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CPen class
+ //
+ class CPen : public CGDIObject
+ {
+ public:
+ CPen();
+ CPen(HPEN hPen);
+ CPen(int nPenStyle, int nWidth, COLORREF crColor);
+#ifndef _WIN32_WCE
+ CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL);
+#endif // !_WIN32_WCE
+ operator HPEN() const;
+ ~CPen();
+
+ HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor);
+ HPEN CreatePenIndirect(LPLOGPEN lpLogPen);
+ LOGPEN GetLogPen() const;
+
+#ifndef _WIN32_WCE
+ HPEN ExtCreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL);
+ EXTLOGPEN GetExtLogPen() const;
+#endif // !_WIN32_WCE
+
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CRgn class
+ //
+ class CRgn : public CGDIObject
+ {
+ public:
+ CRgn();
+ CRgn(HRGN hRgn);
+ operator HRGN() const;
+ ~CRgn ();
+
+ // Create methods
+ HRGN CreateRectRgn(int x1, int y1, int x2, int y2);
+ HRGN CreateRectRgnIndirect(const RECT& rc);
+ HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData);
+
+#ifndef _WIN32_WCE
+ HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2);
+ HRGN CreateEllipticRgnIndirect(const RECT& rc);
+ HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode);
+ HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode);
+ HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);
+ HRGN CreateFromPath(HDC hDC);
+#endif // !_WIN32_WCE
+
+ // Operations
+ void SetRectRgn(int x1, int y1, int x2, int y2);
+ void SetRectRgn(const RECT& rc);
+ int CombineRgn(CRgn* pRgnSrc1, CRgn* pRgnSrc2, int nCombineMode);
+ int CombineRgn(CRgn* pRgnSrc, int nCombineMode);
+ int CopyRgn(CRgn* pRgnSrc);
+ BOOL EqualRgn(CRgn* pRgn) const;
+ int OffsetRgn(int x, int y);
+ int OffsetRgn(POINT& pt);
+ int GetRgnBox(RECT& rc) const;
+ BOOL PtInRegion(int x, int y) const;
+ BOOL PtInRegion(POINT& pt) const;
+ BOOL RectInRegion(const RECT& rc) const;
+ int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const;
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CDC class
+ //
+ class CDC
+ {
+ friend class CWinApp;
+ friend class CWnd;
+ friend CDC* FromHandle(HDC hDC);
+
+ public:
+ struct DataMembers // A structure that contains the data members for CDC
+ {
+ std::vector<GDIPtr> m_vGDIObjects; // Smart pointers to internally created Bitmaps, Brushes, Fonts, Bitmaps and Regions
+ HDC hDC; // The HDC belonging to this CDC
+ long Count; // Reference count
+ BOOL bRemoveHDC; // Delete/Release the HDC on destruction
+ HWND hWnd; // The HWND of a Window or Client window DC
+ int nSavedDCState; // The save state of the HDC.
+ };
+
+ CDC(); // Constructs a new CDC without assigning a HDC
+ CDC(HDC hDC, HWND hWnd = 0); // Assigns a HDC to a new CDC
+ CDC(const CDC& rhs); // Constructs a new copy of the CDC
+ virtual ~CDC();
+ operator HDC() const { return m_pData->hDC; } // Converts a CDC to a HDC
+ CDC& operator = (const CDC& rhs); // Assigns a CDC to an existing CDC
+
+ void Attach(HDC hDC, HWND hWnd = 0);
+ void Destroy();
+ HDC Detach();
+ HDC GetHDC() const { return m_pData->hDC; }
+ CPalette* SelectPalette(const CPalette* pPalette, BOOL bForceBkgnd);
+ CBitmap* SelectObject(const CBitmap* pBitmap);
+ CBrush* SelectObject(const CBrush* pBrush);
+ CFont* SelectObject(const CFont* pFont);
+ CPalette* SelectObject(const CPalette* pPalette);
+ CPen* SelectObject(const CPen* pPen);
+
+#ifndef _WIN32_WCE
+ void operator = (const HDC hDC);
+#endif
+
+ // Initialization
+ BOOL CreateCompatibleDC(CDC* pDC);
+ BOOL CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData);
+ int GetDeviceCaps(int nIndex) const;
+#ifndef _WIN32_WCE
+ BOOL CreateIC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData);
+#endif
+
+ // Create and Select Bitmaps
+ CBitmap* CreateBitmap(int cx, int cy, UINT Planes, UINT BitsPerPixel, LPCVOID pvColors);
+ CBitmap* CreateCompatibleBitmap(CDC* pDC, int cx, int cy);
+ CBitmap* CreateDIBSection(CDC* pDC, const BITMAPINFO& bmi, UINT iUsage, LPVOID *ppvBits,
+ HANDLE hSection, DWORD dwOffset);
+ BITMAP GetBitmapData() const;
+ CBitmap* LoadBitmap(UINT nID);
+ CBitmap* LoadBitmap(LPCTSTR lpszName);
+ CBitmap* LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad);
+ CBitmap* LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad);
+ CBitmap* LoadOEMBitmap(UINT nIDBitmap); // for OBM_/OCR_/OIC
+
+#ifndef _WIN32_WCE
+ CBitmap* CreateBitmapIndirect(LPBITMAP pBitmap);
+ CBitmap* CreateDIBitmap(CDC* pDC, const BITMAPINFOHEADER& bmih, DWORD fdwInit, LPCVOID lpbInit,
+ BITMAPINFO& bmi, UINT fuUsage);
+ CBitmap* CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/);
+#endif
+
+ // Create and Select Brushes
+ CBrush* CreatePatternBrush(CBitmap* pBitmap);
+ CBrush* CreateSolidBrush(COLORREF rbg);
+ LOGBRUSH GetLogBrush() const;
+
+#ifndef _WIN32_WCE
+ CBrush* CreateBrushIndirect(LPLOGBRUSH pLogBrush);
+ CBrush* CreateHatchBrush(int fnStyle, COLORREF rgb);
+ CBrush* CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec);
+ CBrush* CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT iUsage);
+#endif
+
+ // Create and Select Fonts
+ CFont* CreateFontIndirect(LPLOGFONT plf);
+ LOGFONT GetLogFont() const;
+
+#ifndef _WIN32_WCE
+ CFont* CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight,
+ DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet,
+ DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality,
+ DWORD fdwPitchAndFamily, LPCTSTR lpszFace);
+#endif
+
+ // Create and Select Pens
+ CPen* CreatePen(int nStyle, int nWidth, COLORREF rgb);
+ CPen* CreatePenIndirect(LPLOGPEN pLogPen);
+ LOGPEN GetLogPen() const;
+
+ // Create Select Regions
+ int CreateRectRgn(int left, int top, int right, int bottom);
+ int CreateRectRgnIndirect(const RECT& rc);
+ int CreateFromData(const XFORM* Xform, DWORD nCount, const RGNDATA *pRgnData);
+#ifndef _WIN32_WCE
+ int CreateEllipticRgn(int left, int top, int right, int bottom);
+ int CreateEllipticRgnIndirect(const RECT& rc);
+ int CreatePolygonRgn(LPPOINT ppt, int cPoints, int fnPolyFillMode);
+ int CreatePolyPolygonRgn(LPPOINT ppt, LPINT pPolyCounts, int nCount, int fnPolyFillMode);
+#endif
+
+ // Wrappers for WinAPI functions
+
+ // Point and Line Drawing Functions
+ CPoint GetCurrentPosition() const;
+ CPoint MoveTo(int x, int y) const;
+ CPoint MoveTo(POINT pt) const;
+ BOOL LineTo(int x, int y) const;
+ BOOL LineTo(POINT pt) const;
+ COLORREF GetPixel(int x, int y) const;
+ COLORREF GetPixel(POINT pt) const;
+ COLORREF SetPixel(int x, int y, COLORREF crColor) const;
+ COLORREF SetPixel(POINT pt, COLORREF crColor) const;
+#ifndef _WIN32_WCE
+ BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
+ BOOL Arc(RECT& rc, POINT ptStart, POINT ptEnd) const;
+ BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
+ BOOL ArcTo(RECT& rc, POINT ptStart, POINT ptEnd) const;
+ BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) const;
+ int GetArcDirection() const;
+ int SetArcDirection(int nArcDirection) const;
+ BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) const;
+ BOOL Polyline(LPPOINT lpPoints, int nCount) const;
+ BOOL PolyPolyline(const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount) const;
+ BOOL PolylineTo(const POINT* lpPoints, int nCount) const;
+ BOOL PolyBezier(const POINT* lpPoints, int nCount) const;
+ BOOL PolyBezierTo(const POINT* lpPoints, int nCount) const;
+ BOOL SetPixelV(int x, int y, COLORREF crColor) const;
+ BOOL SetPixelV(POINT pt, COLORREF crColor) const;
+#endif
+
+ // Shape Drawing Functions
+ void DrawFocusRect(const RECT& rc) const;
+ BOOL Ellipse(int x1, int y1, int x2, int y2) const;
+ BOOL Ellipse(const RECT& rc) const;
+ BOOL Polygon(LPPOINT lpPoints, int nCount) const;
+ BOOL Rectangle(int x1, int y1, int x2, int y2) const;
+ BOOL Rectangle(const RECT& rc) const;
+ BOOL RoundRect(int x1, int y1, int x2, int y2, int nWidth, int nHeight) const;
+ BOOL RoundRect(const RECT& rc, int nWidth, int nHeight) const;
+
+#ifndef _WIN32_WCE
+ BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
+ BOOL Chord(const RECT& rc, POINT ptStart, POINT ptEnd) const;
+ BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const;
+ BOOL Pie(const RECT& rc, POINT ptStart, POINT ptEnd) const;
+ BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) const;
+#endif
+
+ // Fill and Image Drawing functions
+ BOOL FillRect(const RECT& rc, CBrush* pBrushr) const;
+ BOOL InvertRect(const RECT& rc) const;
+ BOOL DrawIconEx(int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, CBrush* pFlickerFreeDraw, UINT diFlags) const;
+ BOOL DrawEdge(const RECT& rc, UINT nEdge, UINT nFlags) const;
+ BOOL DrawFrameControl(const RECT& rc, UINT nType, UINT nState) const;
+ BOOL FillRgn(CRgn* pRgn, CBrush* pBrush) const;
+ void GradientFill(COLORREF Color1, COLORREF Color2, const RECT& rc, BOOL bVertical);
+ void SolidFill(COLORREF Color, const RECT& rc);
+
+#ifndef _WIN32_WCE
+ BOOL DrawIcon(int x, int y, HICON hIcon) const;
+ BOOL DrawIcon(POINT point, HICON hIcon) const;
+ BOOL FrameRect(const RECT& rc, CBrush* pBrush) const;
+ BOOL PaintRgn(CRgn* pRgn) const;
+#endif
+
+ // Bitmap Functions
+ void DrawBitmap(int x, int y, int cx, int cy, CBitmap& Bitmap, COLORREF clrMask);
+ int StretchDIBits(int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
+ int nSrcHeight, CONST VOID *lpBits, BITMAPINFO& bi, UINT iUsage, DWORD dwRop) const;
+ BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) const;
+ BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) const;
+ BOOL StretchBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) const;
+
+#ifndef _WIN32_WCE
+ int GetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbi, UINT uUsage) const;
+ int SetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, LPBITMAPINFO lpbi, UINT fuColorUse) const;
+ int GetStretchBltMode() const;
+ int SetStretchBltMode(int iStretchMode) const;
+ BOOL FloodFill(int x, int y, COLORREF crColor) const;
+ BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) const;
+#endif
+
+ // Brush Functions
+#ifdef GetDCBrushColor
+ COLORREF GetDCBrushColor() const;
+ COLORREF SetDCBrushColor(COLORREF crColor) const;
+#endif
+
+ // Clipping Functions
+ int ExcludeClipRect(int Left, int Top, int Right, int BottomRect);
+ int ExcludeClipRect(const RECT& rc);
+ int GetClipBox(RECT& rc);
+ int GetClipRgn(HRGN hrgn);
+ int IntersectClipRect(int Left, int Top, int Right, int Bottom);
+ int IntersectClipRect(const RECT& rc);
+ BOOL RectVisible(const RECT& rc);
+ int SelectClipRgn(CRgn* pRgn);
+
+#ifndef _WIN32_WCE
+ int ExtSelectClipRgn(CRgn* pRgn, int fnMode);
+ int OffsetClipRgn(int nXOffset, int nYOffset);
+ BOOL PtVisible(int X, int Y);
+#endif
+
+ // Co-ordinate Functions
+#ifndef _WIN32_WCE
+ BOOL DPtoLP(LPPOINT lpPoints, int nCount) const;
+ BOOL DPtoLP(RECT& rc) const;
+ BOOL LPtoDP(LPPOINT lpPoints, int nCount) const;
+ BOOL LPtoDP(RECT& rc) const;
+#endif
+
+ // Layout Functions
+ DWORD GetLayout() const;
+ DWORD SetLayout(DWORD dwLayout) const;
+
+ // Mapping functions
+#ifndef _WIN32_WCE
+ int GetMapMode() const;
+ int SetMapMode(int nMapMode) const;
+ BOOL GetViewportOrgEx(LPPOINT lpPoint) const;
+ BOOL SetViewportOrgEx(int x, int y, LPPOINT lpPoint = NULL) const;
+ BOOL SetViewportOrgEx(POINT point, LPPOINT lpPointRet = NULL) const;
+ BOOL OffsetViewportOrgEx(int nWidth, int nHeight, LPPOINT lpPoint = NULL) const;
+ BOOL GetViewportExtEx(LPSIZE lpSize) const;
+ BOOL SetViewportExtEx(int x, int y, LPSIZE lpSize) const;
+ BOOL SetViewportExtEx(SIZE size, LPSIZE lpSizeRet) const;
+ BOOL ScaleViewportExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const;
+ BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint) const;
+ BOOL GetWindowExtEx(LPSIZE lpSize) const;
+ BOOL SetWindowExtEx(int x, int y, LPSIZE lpSize) const;
+ BOOL SetWindowExtEx(SIZE size, LPSIZE lpSizeRet) const;
+ BOOL ScaleWindowExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const;
+ BOOL GetWindowOrgEx(LPPOINT lpPoint) const;
+ BOOL SetWindowOrgEx(int x, int y, LPPOINT lpPoint) const;
+ BOOL SetWindowOrgEx(POINT point, LPPOINT lpPointRet) const;
+ BOOL OffsetWindowOrgEx(int nWidth, int nHeight, LPPOINT lpPoint) const;
+#endif
+
+ // Printer Functions
+ int StartDoc(LPDOCINFO lpDocInfo) const;
+ int EndDoc() const;
+ int StartPage() const;
+ int EndPage() const;
+ int AbortDoc() const;
+ int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) const;
+
+ // Text Functions
+ int DrawText(LPCTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat) const;
+ BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lprc, LPCTSTR lpszString, int nCount = -1, LPINT lpDxWidths = NULL) const;
+ COLORREF GetBkColor() const;
+ int GetBkMode() const;
+ UINT GetTextAlign() const;
+ int GetTextFace(int nCount, LPTSTR lpszFacename) const;
+ COLORREF GetTextColor() const;
+ BOOL GetTextMetrics(TEXTMETRIC& Metrics) const;
+ COLORREF SetBkColor(COLORREF crColor) const;
+ int SetBkMode(int iBkMode) const;
+ UINT SetTextAlign(UINT nFlags) const;
+ COLORREF SetTextColor(COLORREF crColor) const;
+
+#ifndef _WIN32_WCE
+ int DrawTextEx(LPTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat, LPDRAWTEXTPARAMS lpDTParams) const;
+ CSize GetTabbedTextExtent(LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions) const;
+ int GetTextCharacterExtra() const;
+ CSize GetTextExtentPoint32(LPCTSTR lpszString, int nCount) const;
+ BOOL GrayString(CBrush* pBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) const;
+ int SetTextCharacterExtra(int nCharExtra) const;
+ int SetTextJustification(int nBreakExtra, int nBreakCount) const;
+ CSize TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin) const;
+ BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1) const;
+#endif
+
+ private:
+ void AddToMap();
+ static CDC* AddTempHDC(HDC hDC, HWND hWnd);
+ void Release();
+ BOOL RemoveFromMap();
+
+ DataMembers* m_pData; // pointer to the class's data members
+ };
+
+ class CClientDC : public CDC
+ {
+ public:
+ CClientDC(const CWnd* pWnd)
+ {
+ if (pWnd) assert(pWnd->IsWindow());
+ HWND hWnd = pWnd? pWnd->GetHwnd() : GetDesktopWindow();
+ Attach(::GetDC(hWnd), hWnd);
+ }
+ virtual ~CClientDC() {}
+ };
+
+ class CMemDC : public CDC
+ {
+ public:
+ CMemDC(const CDC* pDC)
+ {
+ if (pDC) assert(pDC->GetHDC());
+ HDC hDC = pDC? pDC->GetHDC() : NULL;
+ Attach(::CreateCompatibleDC(hDC));
+ }
+ virtual ~CMemDC() {}
+ };
+
+ class CPaintDC : public CDC
+ {
+ public:
+ CPaintDC(const CWnd* pWnd)
+ {
+ assert(pWnd->IsWindow());
+ m_hWnd = pWnd->GetHwnd();
+ Attach(::BeginPaint(pWnd->GetHwnd(), &m_ps), m_hWnd);
+ }
+
+ virtual ~CPaintDC() { ::EndPaint(m_hWnd, &m_ps); }
+
+ private:
+ HWND m_hWnd;
+ PAINTSTRUCT m_ps;
+ };
+
+ class CWindowDC : public CDC
+ {
+ public:
+ CWindowDC(const CWnd* pWnd)
+ {
+ if (pWnd) assert(pWnd->IsWindow());
+ HWND hWnd = pWnd? pWnd->GetHwnd() : GetDesktopWindow();
+ Attach(::GetWindowDC(hWnd), hWnd);
+ }
+ virtual ~CWindowDC() {}
+ };
+
+#ifndef _WIN32_WCE
+ class CMetaFileDC : public CDC
+ {
+ public:
+ CMetaFileDC() : m_hMF(0), m_hEMF(0) {}
+ virtual ~CMetaFileDC()
+ {
+ if (m_hMF)
+ {
+ ::CloseMetaFile(GetHDC());
+ ::DeleteMetaFile(m_hMF);
+ }
+ if (m_hEMF)
+ {
+ ::CloseEnhMetaFile(GetHDC());
+ ::DeleteEnhMetaFile(m_hEMF);
+ }
+ }
+ void Create(LPCTSTR lpszFilename = NULL) { Attach(::CreateMetaFile(lpszFilename)); }
+ void CreateEnhanced(CDC* pDCRef, LPCTSTR lpszFileName, LPCRECT lpBounds, LPCTSTR lpszDescription)
+ {
+ HDC hDC = pDCRef? pDCRef->GetHDC() : NULL;
+ ::CreateEnhMetaFile(hDC, lpszFileName, lpBounds, lpszDescription);
+ assert(GetHDC());
+ }
+ HMETAFILE Close() { return ::CloseMetaFile(GetHDC()); }
+ HENHMETAFILE CloseEnhanced() { return ::CloseEnhMetaFile(GetHDC()); }
+
+ private:
+ HMETAFILE m_hMF;
+ HENHMETAFILE m_hEMF;
+ };
+#endif
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CBitmapInfoPtr class
+ // The CBitmapInfoPtr class is a convienient wrapper for the BITMAPINFO structure.
+ class CBitmapInfoPtr
+ {
+ public:
+ CBitmapInfoPtr(CBitmap* pBitmap)
+ {
+ BITMAP bmSource = pBitmap->GetBitmapData();
+
+ // Convert the color format to a count of bits.
+ WORD cClrBits = (WORD)(bmSource.bmPlanes * bmSource.bmBitsPixel);
+ if (cClrBits == 1) cClrBits = 1;
+ else if (cClrBits <= 4) cClrBits = 4;
+ else if (cClrBits <= 8) cClrBits = 8;
+ else if (cClrBits <= 16) cClrBits = 16;
+ else if (cClrBits <= 24) cClrBits = 24;
+ else cClrBits = 32;
+
+ // Allocate memory for the BITMAPINFO structure.
+ UINT uQuadSize = (cClrBits == 24)? 0 : sizeof(RGBQUAD) * (int)(1 << cClrBits);
+ m_bmi.assign(sizeof(BITMAPINFOHEADER) + uQuadSize, 0);
+ m_pbmiArray = (LPBITMAPINFO) &m_bmi[0];
+
+ m_pbmiArray->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ m_pbmiArray->bmiHeader.biHeight = bmSource.bmHeight;
+ m_pbmiArray->bmiHeader.biWidth = bmSource.bmWidth;
+ m_pbmiArray->bmiHeader.biPlanes = bmSource.bmPlanes;
+ m_pbmiArray->bmiHeader.biBitCount = bmSource.bmBitsPixel;
+ m_pbmiArray->bmiHeader.biCompression = BI_RGB;
+ if (cClrBits < 24)
+ m_pbmiArray->bmiHeader.biClrUsed = (1<<cClrBits);
+ }
+ LPBITMAPINFO get() const { return m_pbmiArray; }
+ operator LPBITMAPINFO() const { return m_pbmiArray; }
+ LPBITMAPINFO operator->() const { return m_pbmiArray; }
+
+ private:
+ CBitmapInfoPtr(const CBitmapInfoPtr&); // Disable copy construction
+ CBitmapInfoPtr& operator = (const CBitmapInfoPtr&); // Disable assignment operator
+ LPBITMAPINFO m_pbmiArray;
+ std::vector<byte> m_bmi;
+ };
+
+
+ CBitmap* FromHandle(HBITMAP hBitmap);
+ CBrush* FromHandle(HBRUSH hBrush);
+ CFont* FromHandle(HFONT hFont);
+ CPalette* FromHandle(HPALETTE hPalette);
+ CPen* FromHandle(HPEN hPen);
+ CRgn* FromHandle(HRGN hRgn);
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ ///////////////////////////////////////////////
+ // Declarations for the CGDIObject class
+ //
+
+ inline CGDIObject::CGDIObject()
+ // Constructs the CGDIObject
+ {
+ m_pData = new DataMembers;
+ m_pData->hGDIObject = 0;
+ m_pData->Count = 1L;
+ m_pData->bRemoveObject = TRUE;
+ }
+
+ inline CGDIObject::CGDIObject(const CGDIObject& rhs)
+ // Note: A copy of a CGDIObject is a clone of the original.
+ // Both objects manipulate the one HGDIOBJ.
+ {
+ m_pData = rhs.m_pData;
+ InterlockedIncrement(&m_pData->Count);
+ }
+
+ inline CGDIObject::~CGDIObject()
+ // Deconstructs the CGDIObject
+ {
+ Release();
+ }
+
+ inline CGDIObject& CGDIObject::operator = ( const CGDIObject& rhs )
+ // Note: A copy of a CGDIObject is a clone of the original.
+ // Both objects manipulate the one HGDIOBJ.
+ {
+ if (this != &rhs)
+ {
+ InterlockedIncrement(&rhs.m_pData->Count);
+ Release();
+ m_pData = rhs.m_pData;
+ }
+
+ return *this;
+ }
+
+ inline void CGDIObject::operator = (HGDIOBJ hObject)
+ {
+ assert(m_pData);
+ assert (m_pData->hGDIObject == NULL);
+ m_pData->hGDIObject = hObject;
+ }
+
+ inline void CGDIObject::AddToMap()
+ // Store the HDC and CDC pointer in the HDC map
+ {
+ assert( GetApp() );
+ GetApp()->m_csMapLock.Lock();
+
+ assert(m_pData->hGDIObject);
+ assert(!GetApp()->GetCGDIObjectFromMap(m_pData->hGDIObject));
+
+ GetApp()->m_mapGDI.insert(std::make_pair(m_pData->hGDIObject, this));
+ GetApp()->m_csMapLock.Release();
+ }
+
+ inline void CGDIObject::Attach(HGDIOBJ hObject)
+ // Attaches a GDI HANDLE to the CGDIObject.
+ // The HGDIOBJ will be automatically deleted when the destructor is called unless it is detached.
+ {
+ assert(m_pData);
+
+ if (m_pData->hGDIObject != NULL && m_pData->hGDIObject != hObject)
+ {
+ ::DeleteObject(Detach());
+ }
+
+ CGDIObject* pObject = GetApp()->GetCGDIObjectFromMap(hObject);
+ if (pObject)
+ {
+ delete m_pData;
+ m_pData = pObject->m_pData;
+ InterlockedIncrement(&m_pData->Count);
+ }
+ else
+ {
+ m_pData->hGDIObject = hObject;
+ AddToMap();
+ }
+ }
+
+ inline HGDIOBJ CGDIObject::Detach()
+ // Detaches the HGDIOBJ from this object.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject);
+
+ GetApp()->m_csMapLock.Lock();
+ RemoveFromMap();
+ HGDIOBJ hObject = m_pData->hGDIObject;
+ m_pData->hGDIObject = 0;
+
+ if (m_pData->Count)
+ {
+ if (InterlockedDecrement(&m_pData->Count) == 0)
+ {
+ delete m_pData;
+ }
+ }
+
+ GetApp()->m_csMapLock.Release();
+
+ // Assign values to our data members
+ m_pData = new DataMembers;
+ m_pData->hGDIObject = 0;
+ m_pData->Count = 1L;
+ m_pData->bRemoveObject = TRUE;
+
+ return hObject;
+ }
+
+ inline HGDIOBJ CGDIObject::GetHandle() const
+ {
+ assert(m_pData);
+ return m_pData->hGDIObject;
+ }
+
+ inline int CGDIObject::GetObject(int nCount, LPVOID pObject) const
+ {
+ assert(m_pData);
+ return ::GetObject(m_pData->hGDIObject, nCount, pObject);
+ }
+
+ inline void CGDIObject::Release()
+ {
+ assert(m_pData);
+ BOOL bSucceeded = TRUE;
+
+ if (InterlockedDecrement(&m_pData->Count) == 0)
+ {
+ if (m_pData->hGDIObject != NULL)
+ {
+ if (m_pData->bRemoveObject)
+ bSucceeded = ::DeleteObject(m_pData->hGDIObject);
+ else
+ bSucceeded = TRUE;
+ }
+
+ RemoveFromMap();
+ delete m_pData;
+ m_pData = 0;
+ }
+
+ assert(bSucceeded);
+ }
+
+ inline BOOL CGDIObject::RemoveFromMap()
+ {
+ BOOL Success = FALSE;
+
+ if( GetApp() )
+ {
+ // Allocate an iterator for our HDC map
+ std::map<HGDIOBJ, CGDIObject*, CompareGDI>::iterator m;
+
+ CWinApp* pApp = GetApp();
+ if (pApp)
+ {
+ // Erase the CGDIObject pointer entry from the map
+ pApp->m_csMapLock.Lock();
+ m = pApp->m_mapGDI.find(m_pData->hGDIObject);
+ if (m != pApp->m_mapGDI.end())
+ {
+ pApp->m_mapGDI.erase(m);
+ Success = TRUE;
+ }
+
+ pApp->m_csMapLock.Release();
+ }
+ }
+
+ return Success;
+ }
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CBitmap class
+ //
+ inline CBitmap::CBitmap()
+ {
+ }
+
+ inline CBitmap::CBitmap(HBITMAP hBitmap)
+ {
+ assert(m_pData);
+ Attach(hBitmap);
+ }
+
+ inline CBitmap::CBitmap(LPCTSTR lpszName)
+ {
+ LoadBitmap(lpszName);
+ }
+
+ inline CBitmap::CBitmap(int nID)
+ {
+ LoadBitmap(nID);
+ }
+
+ inline CBitmap::operator HBITMAP() const
+ {
+ assert(m_pData);
+ return (HBITMAP)m_pData->hGDIObject;
+ }
+
+ inline CBitmap::~CBitmap()
+ {
+ }
+
+ inline BOOL CBitmap::LoadBitmap(int nID)
+ // Loads a bitmap from a resource using the resource ID.
+ {
+ return LoadBitmap(MAKEINTRESOURCE(nID));
+ }
+
+ inline BOOL CBitmap::LoadBitmap(LPCTSTR lpszName)
+ // Loads a bitmap from a resource using the resource string.
+ {
+ assert(GetApp());
+ assert(m_pData);
+
+ HBITMAP hBitmap = (HBITMAP)::LoadImage(GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+ if (hBitmap)
+ {
+ Attach(hBitmap);
+ }
+ return (0 != hBitmap); // boolean expression
+ }
+
+ inline BOOL CBitmap::LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad)
+ // Loads a bitmap from a resource using the resource ID.
+ {
+ return LoadImage(MAKEINTRESOURCE(nID), cxDesired, cyDesired, fuLoad);
+ }
+
+ inline BOOL CBitmap::LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad)
+ // Loads a bitmap from a resource using the resource string.
+ {
+ assert(GetApp());
+ assert(m_pData);
+
+ HBITMAP hBitmap = (HBITMAP)::LoadImage(GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, cxDesired, cyDesired, fuLoad);
+ if (hBitmap)
+ {
+ Attach(hBitmap);
+ }
+ return (0 != hBitmap); // boolean expression
+ }
+
+ inline BOOL CBitmap::LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
+ // Loads a predefined bitmap
+ // Predefined bitmaps include: OBM_BTNCORNERS, OBM_BTSIZE, OBM_CHECK, OBM_CHECKBOXES, OBM_CLOSE, OBM_COMBO
+ // OBM_DNARROW, OBM_DNARROWD, OBM_DNARROWI, OBM_LFARROW, OBM_LFARROWD, OBM_LFARROWI, OBM_MNARROW,OBM_OLD_CLOSE
+ // OBM_OLD_DNARROW, OBM_OLD_LFARROW, OBM_OLD_REDUCE, OBM_OLD_RESTORE, OBM_OLD_RGARROW, OBM_OLD_UPARROW
+ // OBM_OLD_ZOOM, OBM_REDUCE, OBM_REDUCED, OBM_RESTORE, OBM_RESTORED, OBM_RGARROW, OBM_RGARROWD, OBM_RGARROWI
+ // OBM_SIZE, OBM_UPARROW, OBM_UPARROWD, OBM_UPARROWI, OBM_ZOOM, OBM_ZOOMD
+ {
+ assert(m_pData);
+
+ HBITMAP hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
+ if (hBitmap)
+ {
+ Attach( ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap)) );
+ }
+ return (0 != hBitmap); // boolean expression
+ }
+
+#ifndef _WIN32_WCE
+ inline HBITMAP CBitmap::CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/)
+ // Creates a new bitmap using the bitmap data and colors specified by the bitmap resource and the color mapping information.
+ {
+ assert(GetApp());
+ assert(m_pData);
+ HBITMAP hBitmap = ::CreateMappedBitmap(GetApp()->GetResourceHandle(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+#endif // !_WIN32_WCE
+
+ inline HBITMAP CBitmap::CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, LPCVOID lpBits)
+ // Creates a bitmap with the specified width, height, and color format (color planes and bits-per-pixel).
+ {
+ assert(m_pData);
+ HBITMAP hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+
+#ifndef _WIN32_WCE
+ inline HBITMAP CBitmap::CreateBitmapIndirect(LPBITMAP lpBitmap)
+ // Creates a bitmap with the width, height, and color format specified in the BITMAP structure.
+ {
+ assert(m_pData);
+ HBITMAP hBitmap = ::CreateBitmapIndirect(lpBitmap);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+#endif // !_WIN32_WCE
+
+ inline HBITMAP CBitmap::CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight)
+ // Creates a bitmap compatible with the device that is associated with the specified device context.
+ {
+ assert(m_pData);
+ assert(pDC);
+ HBITMAP hBitmap = ::CreateCompatibleBitmap(pDC->GetHDC(), nWidth, nHeight);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+
+ // Attributes
+ inline BITMAP CBitmap::GetBitmapData() const
+ // Retrieves the BITMAP structure
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ BITMAP bmp = {0};
+ ::GetObject(m_pData->hGDIObject, sizeof(BITMAP), &bmp);
+ return bmp;
+ }
+
+#ifndef _WIN32_WCE
+ inline CSize CBitmap::GetBitmapDimensionEx() const
+ // Retrieves the dimensions of a compatible bitmap.
+ // The retrieved dimensions must have been set by the SetBitmapDimensionEx function.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ CSize Size;
+ ::GetBitmapDimensionEx((HBITMAP)m_pData->hGDIObject, &Size);
+ return Size;
+ }
+
+ inline CSize CBitmap::SetBitmapDimensionEx(int nWidth, int nHeight)
+ // The SetBitmapDimensionEx function assigns preferred dimensions to a bitmap.
+ // These dimensions can be used by applications; however, they are not used by the system.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ CSize Size;
+ ::SetBitmapDimensionEx((HBITMAP)m_pData->hGDIObject, nWidth, nHeight, Size);
+ return Size;
+ }
+
+ // DIB support
+ inline HBITMAP CBitmap::CreateDIBitmap(CDC* pDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
+ // Creates a compatible bitmap (DDB) from a DIB and, optionally, sets the bitmap bits.
+ {
+ assert(m_pData);
+ assert(pDC);
+ HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetHDC(), lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+#endif // !_WIN32_WCE
+
+ inline HBITMAP CBitmap::CreateDIBSection(CDC* pDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
+ // Creates a DIB that applications can write to directly. The function gives you a pointer to the location of the bitmap bit values.
+ // You can supply a handle to a file-mapping object that the function will use to create the bitmap, or you can let the system allocate the memory for the bitmap.
+ {
+ assert(m_pData);
+ assert(pDC);
+ HBITMAP hBitmap = ::CreateDIBSection(pDC->GetHDC(), lpbmi, uColorUse, ppvBits, hSection, dwOffset);
+ Attach(hBitmap);
+ return hBitmap;
+ }
+
+#ifndef _WIN32_WCE
+ inline int CBitmap::GetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
+ // Retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.
+ {
+ assert(m_pData);
+ assert(pDC);
+ assert(m_pData->hGDIObject != NULL);
+ return ::GetDIBits(pDC->GetHDC(), (HBITMAP)m_pData->hGDIObject, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
+ }
+
+ inline int CBitmap::SetDIBits(CDC* pDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
+ // Sets the pixels in a compatible bitmap (DDB) using the color data found in the specified DIB.
+ {
+ assert(m_pData);
+ assert(pDC);
+ assert(m_pData->hGDIObject != NULL);
+ return ::SetDIBits(pDC->GetHDC(), (HBITMAP)m_pData->hGDIObject, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
+ }
+#endif // !_WIN32_WCE
+
+
+ ///////////////////////////////////////////////
+ // Definitions of the CBrush class
+ //
+ inline CBrush::CBrush()
+ {
+ }
+
+ inline CBrush::CBrush(HBRUSH hBrush)
+ {
+ assert(m_pData);
+ Attach(hBrush);
+ }
+
+ inline CBrush::CBrush(COLORREF crColor)
+ {
+ Attach( ::CreateSolidBrush(crColor) );
+ assert (m_pData->hGDIObject);
+ }
+
+ inline CBrush::operator HBRUSH() const
+ {
+ assert(m_pData);
+ return (HBRUSH)m_pData->hGDIObject;
+ }
+
+ inline CBrush::~CBrush()
+ {
+ }
+
+ inline HBRUSH CBrush::CreateSolidBrush(COLORREF crColor)
+ // Creates a logical brush that has the specified solid color.
+ {
+ assert(m_pData);
+ HBRUSH hBrush = ::CreateSolidBrush(crColor);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+#ifndef _WIN32_WCE
+ inline HBRUSH CBrush::CreateHatchBrush(int nIndex, COLORREF crColor)
+ // Creates a logical brush that has the specified hatch pattern and color.
+ {
+ assert(m_pData);
+ HBRUSH hBrush = ::CreateHatchBrush(nIndex, crColor);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+ inline HBRUSH CBrush::CreateBrushIndirect(LPLOGBRUSH lpLogBrush)
+ // Creates a logical brush from style, color, and pattern specified in the LOGPRUSH struct.
+ {
+ assert(m_pData);
+ HBRUSH hBrush = ::CreateBrushIndirect(lpLogBrush);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+ inline HBRUSH CBrush::CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec)
+ // Creates a logical brush that has the pattern specified by the specified device-independent bitmap (DIB).
+ {
+ assert(m_pData);
+ HBRUSH hBrush = ::CreateDIBPatternBrush(hglbDIBPacked, fuColorSpec);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+ inline HBRUSH CBrush::CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT nUsage)
+ // Creates a logical brush that has the pattern specified by the device-independent bitmap (DIB).
+ {
+ assert(m_pData);
+ HBRUSH hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+#endif // !defined(_WIN32_WCE)
+
+ inline HBRUSH CBrush::CreatePatternBrush(CBitmap* pBitmap)
+ // Creates a logical brush with the specified bitmap pattern. The bitmap can be a DIB section bitmap,
+ // which is created by the CreateDIBSection function, or it can be a device-dependent bitmap.
+ {
+ assert(m_pData);
+ assert(pBitmap);
+ HBRUSH hBrush = ::CreatePatternBrush(*pBitmap);
+ Attach(hBrush);
+ return hBrush;
+ }
+
+ inline LOGBRUSH CBrush::GetLogBrush() const
+ // Retrieves the LOGBRUSH structure that defines the style, color, and pattern of a physical brush.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ LOGBRUSH LogBrush = {0};
+ ::GetObject (m_pData->hGDIObject, sizeof(LOGBRUSH), &LogBrush);
+ return LogBrush;
+ }
+
+
+ ///////////////////////////////////////////////
+ // Definitions of the CFont class
+ //
+ inline CFont::CFont()
+ {
+ }
+
+ inline CFont::CFont(HFONT hFont)
+ {
+ assert(m_pData);
+ Attach(hFont);
+ }
+
+ inline CFont::CFont(const LOGFONT* lpLogFont)
+ {
+ assert(m_pData);
+ Attach( ::CreateFontIndirect(lpLogFont) );
+ }
+
+ inline CFont::operator HFONT() const
+ {
+ assert(m_pData);
+ return (HFONT)m_pData->hGDIObject;
+ }
+
+ inline CFont::~CFont()
+ {
+ }
+
+ inline HFONT CFont::CreateFontIndirect(const LOGFONT* lpLogFont)
+ // Creates a logical font that has the specified characteristics.
+ {
+ assert(m_pData);
+ HFONT hFont = ::CreateFontIndirect(lpLogFont);
+ Attach(hFont);
+ return hFont;
+ }
+
+ inline HFONT CFont::CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC /*= NULL*/, BOOL bBold /*= FALSE*/, BOOL bItalic /*= FALSE*/)
+ // Creates a font of a specified typeface and point size.
+ {
+ LOGFONT logFont = { 0 };
+ logFont.lfCharSet = DEFAULT_CHARSET;
+ logFont.lfHeight = nPointSize;
+
+ lstrcpy(logFont.lfFaceName, lpszFaceName);
+
+ if (bBold)
+ logFont.lfWeight = FW_BOLD;
+ if (bItalic)
+ logFont.lfItalic = (BYTE)TRUE;
+
+ return CreatePointFontIndirect(&logFont, pDC);
+ }
+
+ inline HFONT CFont::CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC /* = NULL*/)
+ // Creates a font of a specified typeface and point size.
+ // This function automatically converts the height in lfHeight to logical units using the specified device context.
+ {
+ HDC hDC = pDC? pDC->GetHDC() : NULL;
+ HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(HWND_DESKTOP);
+
+ // convert nPointSize to logical units based on hDC
+ LOGFONT logFont = *lpLogFont;
+
+#ifndef _WIN32_WCE
+ POINT pt = { 0, 0 };
+ pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point
+ ::DPtoLP(hDC1, &pt, 1);
+
+ POINT ptOrg = { 0, 0 };
+ ::DPtoLP(hDC1, &ptOrg, 1);
+
+ logFont.lfHeight = -abs(pt.y - ptOrg.y);
+#else // CE specific
+ // DP and LP are always the same on CE
+ logFont.lfHeight = -abs(((::GetDeviceCaps(hDC1, LOGPIXELSY)* logFont.lfHeight)/ 720));
+#endif // _WIN32_WCE
+
+ if (hDC == NULL)
+ ::ReleaseDC (NULL, hDC1);
+
+ return CreateFontIndirect (&logFont);
+ }
+
+#ifndef _WIN32_WCE
+
+ inline HFONT CFont::CreateFont(int nHeight, int nWidth, int nEscapement,
+ int nOrientation, int nWeight, DWORD dwItalic, DWORD dwUnderline,
+ DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision,
+ DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily,
+ LPCTSTR lpszFacename)
+ // Creates a logical font with the specified characteristics.
+ {
+ HFONT hFont = ::CreateFont(nHeight, nWidth, nEscapement,
+ nOrientation, nWeight, dwItalic, dwUnderline, dwStrikeOut,
+ dwCharSet, dwOutPrecision, dwClipPrecision, dwQuality,
+ dwPitchAndFamily, lpszFacename);
+
+ Attach(hFont);
+ return hFont;
+ }
+#endif // #ifndef _WIN32_WCE
+
+ inline LOGFONT CFont::GetLogFont() const
+ // Retrieves the Logfont structure that contains font attributes.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ LOGFONT LogFont = {0};
+ ::GetObject(m_pData->hGDIObject, sizeof(LOGFONT), &LogFont);
+ return LogFont;
+ }
+
+
+ ///////////////////////////////////////////////
+ // Definitions of the CPalette class
+ //
+ inline CPalette::CPalette()
+ {
+ }
+
+ inline CPalette::CPalette(HPALETTE hPalette)
+ {
+ Attach(hPalette);
+ }
+
+ inline CPalette::operator HPALETTE() const
+ {
+ assert(m_pData);
+ return (HPALETTE)m_pData->hGDIObject;
+ }
+
+ inline CPalette::~CPalette ()
+ {
+ }
+
+ inline HPALETTE CPalette::CreatePalette(LPLOGPALETTE lpLogPalette)
+ // Creates a logical palette from the information in the specified LOGPALETTE structure.
+ {
+ assert(m_pData);
+ HPALETTE hPalette = ::CreatePalette (lpLogPalette);
+ Attach(hPalette);
+ return hPalette;
+ }
+
+#ifndef _WIN32_WCE
+ inline HPALETTE CPalette::CreateHalftonePalette(CDC* pDC)
+ // Creates a halftone palette for the specified device context (DC).
+ {
+ assert(m_pData);
+ assert(pDC);
+ HPALETTE hPalette = ::CreateHalftonePalette(pDC->GetHDC());
+ Attach(hPalette);
+ return hPalette;
+ }
+#endif // !_WIN32_WCE
+
+ inline int CPalette::GetEntryCount() const
+ // Retrieve the number of entries in the palette.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ WORD nEntries = 0;
+ ::GetObject(m_pData->hGDIObject, sizeof(WORD), &nEntries);
+ return (int)nEntries;
+ }
+
+ inline UINT CPalette::GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const
+ // Retrieves a specified range of palette entries from the palette.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::GetPaletteEntries((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
+ }
+
+ inline UINT CPalette::SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
+ // Sets RGB (red, green, blue) color values and flags in a range of entries in the palette.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::SetPaletteEntries((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
+ }
+
+#ifndef _WIN32_WCE
+ inline void CPalette::AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors)
+ // Replaces entries in the palette.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ ::AnimatePalette((HPALETTE)m_pData->hGDIObject, nStartIndex, nNumEntries, lpPaletteColors);
+ }
+
+ inline BOOL CPalette::ResizePalette(UINT nNumEntries)
+ // Increases or decreases the size of the palette based on the specified value.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::ResizePalette((HPALETTE)m_pData->hGDIObject, nNumEntries);
+ }
+#endif // !_WIN32_WCE
+
+ inline UINT CPalette::GetNearestPaletteIndex(COLORREF crColor) const
+ // Retrieves the index for the entry in the palette most closely matching a specified color value.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::GetNearestPaletteIndex((HPALETTE)m_pData->hGDIObject, crColor);
+ }
+
+
+ ///////////////////////////////////////////////
+ // Declarations for the CPen class
+ //
+ inline CPen::CPen()
+ {
+ }
+
+ inline CPen::CPen(HPEN hPen)
+ {
+ Attach(hPen);
+ }
+
+ inline CPen::CPen(int nPenStyle, int nWidth, COLORREF crColor)
+ {
+ assert(m_pData);
+ Attach( ::CreatePen(nPenStyle, nWidth, crColor) );
+ }
+
+#ifndef _WIN32_WCE
+ inline CPen::CPen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount /*= 0*/, const DWORD* lpStyle /*= NULL*/)
+ {
+ assert(m_pData);
+ Attach( ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle) );
+ }
+#endif // !_WIN32_WCE
+
+ inline CPen::operator HPEN () const
+ {
+ assert(m_pData);
+ return (HPEN)m_pData->hGDIObject;
+ }
+
+ inline CPen::~CPen()
+ {
+ }
+
+ inline HPEN CPen::CreatePen(int nPenStyle, int nWidth, COLORREF crColor)
+ // Creates a logical pen that has the specified style, width, and color.
+ {
+ assert(m_pData);
+ HPEN hPen = ::CreatePen(nPenStyle, nWidth, crColor);
+ Attach(hPen);
+ return hPen;
+ }
+
+ inline HPEN CPen::CreatePenIndirect(LPLOGPEN lpLogPen)
+ // Creates a logical cosmetic pen that has the style, width, and color specified in a structure.
+ {
+ assert(m_pData);
+ HPEN hPen = ::CreatePenIndirect(lpLogPen);
+ Attach(hPen);
+ return hPen;
+ }
+
+ inline LOGPEN CPen::GetLogPen() const
+ {
+ // Retrieves the LOGPEN struct that specifies the pen's style, width, and color.
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+
+ LOGPEN LogPen = {0};
+ ::GetObject(m_pData->hGDIObject, sizeof(LOGPEN), &LogPen);
+ return LogPen;
+ }
+
+#ifndef _WIN32_WCE
+ inline HPEN CPen::ExtCreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount /* = 0*/, const DWORD* lpStyle /*= NULL*/)
+ // Creates a logical cosmetic or geometric pen that has the specified style, width, and brush attributes.
+ {
+ assert(m_pData);
+ HPEN hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle);
+ Attach(hPen);
+ return hPen;
+ }
+
+ inline EXTLOGPEN CPen::GetExtLogPen() const
+ // Retrieves the EXTLOGPEN struct that specifies the pen's style, width, color and brush attributes.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+
+ EXTLOGPEN ExLogPen = {0};
+ ::GetObject(m_pData->hGDIObject, sizeof(EXTLOGPEN), &ExLogPen);
+ return ExLogPen;
+ }
+#endif // !_WIN32_WCE
+
+
+ ///////////////////////////////////////////////
+ // Definitions of the CRgn class
+ //
+ inline CRgn::CRgn()
+ {
+ }
+
+ inline CRgn::CRgn(HRGN hRgn)
+ {
+ assert(m_pData);
+ Attach(hRgn);
+ }
+
+ inline CRgn::operator HRGN() const
+ {
+ assert(m_pData);
+ return (HRGN)m_pData->hGDIObject;
+ }
+
+ inline CRgn::~CRgn()
+ {
+ }
+
+ inline HRGN CRgn::CreateRectRgn(int x1, int y1, int x2, int y2)
+ // Creates a rectangular region.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreateRectRgn(x1, y1, x2, y2);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreateRectRgnIndirect(const RECT& rc)
+ // Creates a rectangular region.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreateRectRgnIndirect(&rc);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+#ifndef _WIN32_WCE
+ inline HRGN CRgn::CreateEllipticRgn(int x1, int y1, int x2, int y2)
+ // Creates an elliptical region.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreateEllipticRgnIndirect(const RECT& rc)
+ // Creates an elliptical region.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreateEllipticRgnIndirect(&rc);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
+ // Creates a polygonal region.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
+ // Creates a region consisting of a series of polygons. The polygons can overlap.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
+ // Creates a rectangular region with rounded corners.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline HRGN CRgn::CreateFromPath(HDC hDC)
+ // Creates a region from the path that is selected into the specified device context.
+ // The resulting region uses device coordinates.
+ {
+ assert(m_pData);
+ assert(hDC != NULL);
+ HRGN hRgn = ::PathToRegion(hDC);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+#endif // !_WIN32_WCE
+
+ inline HRGN CRgn::CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
+ // Creates a region from the specified region and transformation data.
+ {
+ assert(m_pData);
+ HRGN hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
+ Attach(hRgn);
+ return hRgn;
+ }
+
+ inline void CRgn::SetRectRgn(int x1, int y1, int x2, int y2)
+ // converts the region into a rectangular region with the specified coordinates.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ ::SetRectRgn((HRGN)m_pData->hGDIObject, x1, y1, x2, y2);
+ }
+
+ inline void CRgn::SetRectRgn(const RECT& rc)
+ // converts the region into a rectangular region with the specified coordinates.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ ::SetRectRgn((HRGN)m_pData->hGDIObject, rc.left, rc.top, rc.right, rc.bottom);
+ }
+
+ inline int CRgn::CombineRgn(CRgn* pRgnSrc1, CRgn* pRgnSrc2, int nCombineMode)
+ // Combines two sepcified regions and stores the result.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ assert(pRgnSrc1);
+ assert(pRgnSrc2);
+ return ::CombineRgn((HRGN)m_pData->hGDIObject, *pRgnSrc1, *pRgnSrc2, nCombineMode);
+ }
+
+ inline int CRgn::CombineRgn(CRgn* pRgnSrc, int nCombineMode)
+ // Combines the sepcified region with the current region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ assert(pRgnSrc);
+ return ::CombineRgn((HRGN)m_pData->hGDIObject, (HRGN)m_pData->hGDIObject, *pRgnSrc, nCombineMode);
+ }
+
+ inline int CRgn::CopyRgn(CRgn* pRgnSrc)
+ // Assigns the specified region to the current region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject == NULL);
+ assert(pRgnSrc);
+ return ::CombineRgn((HRGN)m_pData->hGDIObject, *pRgnSrc, NULL, RGN_COPY);
+ }
+
+ inline BOOL CRgn::EqualRgn(CRgn* pRgn) const
+ // Checks the two specified regions to determine whether they are identical.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ assert(pRgn);
+ return ::EqualRgn((HRGN)m_pData->hGDIObject, *pRgn);
+ }
+
+ inline int CRgn::OffsetRgn(int x, int y)
+ // Moves a region by the specified offsets.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::OffsetRgn((HRGN)m_pData->hGDIObject, x, y);
+ }
+
+ inline int CRgn::OffsetRgn(POINT& pt)
+ // Moves a region by the specified offsets.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::OffsetRgn((HRGN)m_pData->hGDIObject, pt.x, pt.y);
+ }
+
+ inline int CRgn::GetRgnBox(RECT& rc) const
+ // Retrieves the bounding rectangle of the region, and stores it in the specified RECT.
+ // The return value indicates the region's complexity: NULLREGION;SIMPLEREGION; or COMPLEXREGION.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::GetRgnBox((HRGN)m_pData->hGDIObject, &rc);
+ }
+
+ inline int CRgn::GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
+ // Fills the specified buffer with data describing a region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return (int)::GetRegionData((HRGN)m_pData->hGDIObject, nDataSize, lpRgnData);
+ }
+
+ inline BOOL CRgn::PtInRegion(int x, int y) const
+ // Determines whether the specified point is inside the specified region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::PtInRegion((HRGN)m_pData->hGDIObject, x, y);
+ }
+
+ inline BOOL CRgn::PtInRegion(POINT& pt) const
+ // Determines whether the specified point is inside the specified region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::PtInRegion((HRGN)m_pData->hGDIObject, pt.x, pt.y);
+ }
+
+ inline BOOL CRgn::RectInRegion(const RECT& rc) const
+ // Determines whether the specified rect is inside the specified region.
+ {
+ assert(m_pData);
+ assert(m_pData->hGDIObject != NULL);
+ return ::RectInRegion((HRGN)m_pData->hGDIObject, &rc);
+ }
+
+
+ ///////////////////////////////////////////////
+ // Definitions of the CDC class
+ //
+ inline CDC::CDC()
+ {
+ // Allocate memory for our data members
+ m_pData = new DataMembers;
+
+ // Assign values to our data members
+ m_pData->hDC = 0;
+ m_pData->Count = 1L;
+ m_pData->bRemoveHDC = TRUE;
+ m_pData->hWnd = 0;
+ }
+
+ inline CDC::CDC(HDC hDC, HWND hWnd /*= 0*/)
+ // This constructor assigns an existing HDC to the CDC
+ // The HDC WILL be released or deleted when the CDC object is destroyed
+ // The hWnd paramter is only used in WindowsCE. It specifies the HWND of a Window or
+ // Window Client DC
+
+ // Note: this constructor permits a call like this:
+ // CDC MyCDC = SomeHDC;
+ // or
+ // CDC MyCDC = ::CreateCompatibleDC(SomeHDC);
+ // or
+ // CDC MyCDC = ::GetDC(SomeHWND);
+ {
+ UNREFERENCED_PARAMETER(hWnd);
+ assert(hDC);
+
+ CDC* pDC = GetApp()->GetCDCFromMap(hDC);
+ if (pDC)
+ {
+ m_pData = pDC->m_pData;
+ InterlockedIncrement(&m_pData->Count);
+ }
+ else
+ {
+ // Allocate memory for our data members
+ m_pData = new DataMembers;
+
+ // Assign values to our data members
+ m_pData->hDC = hDC;
+ m_pData->Count = 1L;
+ m_pData->bRemoveHDC = TRUE;
+ m_pData->nSavedDCState = ::SaveDC(hDC);
+#ifndef _WIN32_WCE
+ m_pData->hWnd = ::WindowFromDC(hDC);
+#else
+ m_pData->hWnd = hWnd;
+#endif
+ if (m_pData->hWnd)
+ AddToMap();
+ }
+ }
+
+#ifndef _WIN32_WCE
+ inline void CDC::operator = (const HDC hDC)
+ // Note: this assignment operater permits a call like this:
+ // CDC MyCDC;
+ // MyCDC = SomeHDC;
+ {
+ Attach(hDC);
+ }
+#endif
+
+ inline CDC::CDC(const CDC& rhs) // Copy constructor
+ // The copy constructor is called when a temporary copy of the CDC needs to be created.
+ // This can happen when a CDC is passed by value in a function call. Each CDC copy manages
+ // the same Device Context and GDI objects.
+ {
+ m_pData = rhs.m_pData;
+ InterlockedIncrement(&m_pData->Count);
+ }
+
+ inline CDC& CDC::operator = (const CDC& rhs)
+ // Note: A copy of a CDC is a clone of the original.
+ // Both objects manipulate the one HDC
+ {
+ if (this != &rhs)
+ {
+ InterlockedIncrement(&rhs.m_pData->Count);
+ Release();
+ m_pData = rhs.m_pData;
+ }
+
+ return *this;
+ }
+
+ inline CDC::~CDC ()
+ {
+ Release();
+ }
+
+ inline void CDC::AddToMap()
+ // Store the HDC and CDC pointer in the HDC map
+ {
+ assert( GetApp() );
+ assert(m_pData->hDC);
+ GetApp()->m_csMapLock.Lock();
+
+ assert(m_pData->hDC);
+ assert(!GetApp()->GetCDCFromMap(m_pData->hDC));
+
+ GetApp()->m_mapHDC.insert(std::make_pair(m_pData->hDC, this));
+ GetApp()->m_csMapLock.Release();
+ }
+
+ inline void CDC::Attach(HDC hDC, HWND hWnd /* = 0*/)
+ // Attaches a HDC to the CDC object.
+ // The HDC will be automatically deleted or released when the destructor is called.
+ // The hWnd parameter is only used on WindowsCE. It specifies the HWND of a Window or
+ // Window Client DC
+ {
+ UNREFERENCED_PARAMETER(hWnd);
+ assert(m_pData);
+ assert(0 == m_pData->hDC);
+ assert(hDC);
+
+ CDC* pDC = GetApp()->GetCDCFromMap(hDC);
+ if (pDC)
+ {
+ delete m_pData;
+ m_pData = pDC->m_pData;
+ InterlockedIncrement(&m_pData->Count);
+ }
+ else
+ {
+ m_pData->hDC = hDC;
+
+#ifndef _WIN32_WCE
+ m_pData->hWnd = ::WindowFromDC(hDC);
+#else
+ m_pData->hWnd = hWnd;
+#endif
+
+ if (m_pData->hWnd == 0)
+ AddToMap();
+ m_pData->nSavedDCState = ::SaveDC(hDC);
+ }
+ }
+
+ inline HDC CDC::Detach()
+ // Detaches the HDC from this object.
+ {
+ assert(m_pData);
+ assert(m_pData->hDC);
+
+ GetApp()->m_csMapLock.Lock();
+ RemoveFromMap();
+ HDC hDC = m_pData->hDC;
+ m_pData->hDC = 0;
+
+ if (m_pData->Count)
+ {
+ if (InterlockedDecrement(&m_pData->Count) == 0)
+ {
+ delete m_pData;
+ }
+ }
+
+ GetApp()->m_csMapLock.Release();
+
+ // Assign values to our data members
+ m_pData = new DataMembers;
+ m_pData->hDC = 0;
+ m_pData->Count = 1L;
+ m_pData->bRemoveHDC = TRUE;
+ m_pData->hWnd = 0;
+
+ return hDC;
+ }
+
+ // Initialization
+ inline BOOL CDC::CreateCompatibleDC(CDC* pDC)
+ // Returns a memory device context (DC) compatible with the specified device.
+ {
+ assert(m_pData->hDC == NULL);
+ HDC hdcSource = (pDC == NULL)? NULL : pDC->GetHDC();
+ HDC hDC = ::CreateCompatibleDC(hdcSource);
+ if (hDC)
+ {
+ m_pData->hDC = hDC;
+ AddToMap();
+ }
+ return (hDC != NULL); // boolean expression
+ }
+
+ inline BOOL CDC::CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData)
+ // Returns a device context (DC) for a device using the specified name.
+ {
+ assert(m_pData->hDC == NULL);
+ HDC hDC = ::CreateDC(lpszDriver, lpszDevice, lpszOutput, pInitData);
+ if (hDC)
+ {
+ m_pData->hDC = hDC;
+ AddToMap();
+ }
+ return (hDC != NULL); // boolean expression
+ }
+
+#ifndef _WIN32_WCE
+ inline BOOL CDC::CreateIC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, const DEVMODE* pInitData)
+ {
+ assert(m_pData->hDC == NULL);
+ HDC hDC = ::CreateIC(lpszDriver, lpszDevice, lpszOutput, pInitData);
+ if (hDC)
+ {
+ m_pData->hDC = hDC;
+ AddToMap();
+ }
+ return (hDC != NULL); // boolean expression
+ }
+#endif
+
+ inline void CDC::DrawBitmap(int x, int y, int cx, int cy, CBitmap& Bitmap, COLORREF clrMask)
+ // Draws the specified bitmap to the specified DC using the mask colour provided as the transparent colour
+ // Suitable for use with a Window DC or a memory DC
+ {
+ // Create the Image memory DC
+ CMemDC dcImage(this);
+ dcImage.SetBkColor(clrMask);
+ dcImage.SelectObject(&Bitmap);
+
+ // Create the Mask memory DC
+ CMemDC dcMask(this);
+ dcMask.CreateBitmap(cx, cy, 1, 1, NULL);
+ dcMask.BitBlt(0, 0, cx, cy, &dcImage, 0, 0, SRCCOPY);
+
+ // Mask the image to 'this' DC
+ BitBlt(x, y, cx, cy, &dcImage, 0, 0, SRCINVERT);
+ BitBlt(x, y, cx, cy, &dcMask, 0, 0, SRCAND);
+ BitBlt(x, y, cx, cy, &dcImage, 0, 0, SRCINVERT);
+ }
+
+ inline CDC* CDC::AddTempHDC(HDC hDC, HWND hWnd)
+ // Returns the CDC object associated with the device context handle
+ // The HDC is removed when the CDC is destroyed
+ {
+ assert( GetApp() );
+ CDC* pDC = new CDC;
+ pDC->m_pData->hDC = hDC;
+ GetApp()->AddTmpDC(pDC);
+ pDC->m_pData->bRemoveHDC = TRUE;
+ pDC->m_pData->hWnd = hWnd;
+ return pDC;
+ }
+
+ inline void CDC::GradientFill(COLORREF Color1, COLORREF Color2, const RECT& rc, BOOL bVertical)
+ // An efficient color gradient filler compatible with all Windows operating systems
+ {
+ int Width = rc.right - rc.left;
+ int Height = rc.bottom - rc.top;
+
+ int r1 = GetRValue(Color1);
+ int g1 = GetGValue(Color1);
+ int b1 = GetBValue(Color1);
+
+ int r2 = GetRValue(Color2);
+ int g2 = GetGValue(Color2);
+ int b2 = GetBValue(Color2);
+
+ COLORREF OldBkColor = GetBkColor();
+
+ if (bVertical)
+ {
+ for(int i=0; i < Width; ++i)
+ {
+ int r = r1 + (i * (r2-r1) / Width);
+ int g = g1 + (i * (g2-g1) / Width);
+ int b = b1 + (i * (b2-b1) / Width);
+ SetBkColor(RGB(r, g, b));
+ CRect line( i + rc.left, rc.top, i + 1 + rc.left, rc.top+Height);
+ ExtTextOut(0, 0, ETO_OPAQUE, line, NULL, 0, 0);
+ }
+ }
+ else
+ {
+ for(int i=0; i < Height; ++i)
+ {
+ int r = r1 + (i * (r2-r1) / Height);
+ int g = g1 + (i * (g2-g1) / Height);
+ int b = b1 + (i * (b2-b1) / Height);
+ SetBkColor(RGB(r, g, b));
+ CRect line(rc.left, i + rc.top, rc.left+Width, i + 1 + rc.top);
+ ExtTextOut(0, 0, ETO_OPAQUE, line, NULL, 0, 0);
+ }
+ }
+
+ SetBkColor(OldBkColor);
+ }
+
+ inline void CDC::Release()
+ {
+ GetApp()->m_csMapLock.Lock();
+
+ if (m_pData->Count)
+ {
+ if (InterlockedDecrement(&m_pData->Count) == 0)
+ {
+ Destroy();
+ delete m_pData;
+ m_pData = 0;
+ }
+ }
+
+ GetApp()->m_csMapLock.Release();
+ }
+
+ inline BOOL CDC::RemoveFromMap()
+ {
+ BOOL Success = FALSE;
+
+ if( GetApp() )
+ {
+ // Allocate an iterator for our HDC map
+ std::map<HDC, CDC*, CompareHDC>::iterator m;
+
+ CWinApp* pApp = GetApp();
+ if (pApp)
+ {
+ // Erase the CDC pointer entry from the map
+ pApp->m_csMapLock.Lock();
+ m = pApp->m_mapHDC.find(m_pData->hDC);
+ if (m != pApp->m_mapHDC.end())
+ {
+ pApp->m_mapHDC.erase(m);
+ Success = TRUE;
+ }
+
+ pApp->m_csMapLock.Release();
+ }
+ }
+ return Success;
+ }
+
+ inline void CDC::SolidFill(COLORREF Color, const RECT& rc)
+ // Fills a rectangle with a solid color
+ {
+ COLORREF OldColor = SetBkColor(Color);
+ ExtTextOut(0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
+ SetBkColor(OldColor);
+ }
+
+ // Bitmap functions
+ inline CBitmap* CDC::CreateCompatibleBitmap(CDC* pDC, int cx, int cy)
+ // Creates a compatible bitmap and selects it into the device context.
+ {
+ assert(m_pData->hDC);
+ assert(pDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateCompatibleBitmap(pDC, cx, cy);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+
+ inline CBitmap* CDC::CreateBitmap(int cx, int cy, UINT Planes, UINT BitsPerPixel, LPCVOID pvColors)
+ // Creates a bitmap and selects it into the device context.
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateBitmap(cx, cy, Planes, BitsPerPixel, pvColors);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+
+#ifndef _WIN32_WCE
+ inline CBitmap* CDC::CreateBitmapIndirect (LPBITMAP lpBitmap)
+ // Creates a bitmap and selects it into the device context.
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateBitmapIndirect(lpBitmap);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+
+ inline CBitmap* CDC::CreateDIBitmap(CDC* pDC, const BITMAPINFOHEADER& bmih, DWORD fdwInit, LPCVOID lpbInit,
+ BITMAPINFO& bmi, UINT fuUsage)
+ // Creates a bitmap and selects it into the device context.
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+ assert(pDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateDIBitmap(pDC, &bmih, fdwInit, lpbInit, &bmi, fuUsage);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+#endif
+
+ inline CBitmap* CDC::CreateDIBSection(CDC* pDC, const BITMAPINFO& bmi, UINT iUsage, LPVOID *ppvBits,
+ HANDLE hSection, DWORD dwOffset)
+ // Creates a bitmap and selects it into the device context.
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+ assert(pDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateDIBSection(pDC, &bmi, iUsage, ppvBits, hSection, dwOffset);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+
+ inline void CDC::Destroy()
+ // Deletes or releases the device context and returns the CDC object to its
+ // default state, ready for reuse.
+ {
+ if (m_pData->hDC)
+ {
+ RemoveFromMap();
+ if (m_pData->bRemoveHDC)
+ {
+ // Return the DC back to its initial state
+ ::RestoreDC(m_pData->hDC, m_pData->nSavedDCState);
+
+ // We need to release a Window DC, and delete a memory DC
+ if (m_pData->hWnd)
+ ::ReleaseDC(m_pData->hWnd, m_pData->hDC);
+ else
+ if (!::DeleteDC(m_pData->hDC))
+ ::ReleaseDC(NULL, m_pData->hDC);
+
+ m_pData->hDC = 0;
+ m_pData->hWnd = 0;
+ m_pData->bRemoveHDC = TRUE;
+ }
+ }
+
+ // RemoveFromMap();
+ }
+
+ inline BITMAP CDC::GetBitmapData() const
+ // Retrieves the BITMAP information for the current HBITMAP.
+ {
+ assert(m_pData->hDC);
+
+ HBITMAP hbm = (HBITMAP)::GetCurrentObject(m_pData->hDC, OBJ_BITMAP);
+ BITMAP bm = {0};
+ ::GetObject(hbm, sizeof(bm), &bm);
+ return bm;
+ }
+
+ inline CBitmap* CDC::LoadBitmap(UINT nID)
+ // Loads a bitmap from the resource and selects it into the device context
+ {
+ return LoadBitmap(MAKEINTRESOURCE(nID));
+ }
+
+ inline CBitmap* CDC::LoadBitmap(LPCTSTR lpszName)
+ // Loads a bitmap from the resource and selects it into the device context
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ BOOL bResult = pBitmap->LoadBitmap(lpszName);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+
+ return bResult? SelectObject(pBitmap) : NULL;
+ }
+
+ inline CBitmap* CDC::LoadImage(UINT nID, int cxDesired, int cyDesired, UINT fuLoad)
+ // Loads a bitmap from the resource and selects it into the device context
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ return LoadImage(nID, cxDesired, cyDesired, fuLoad);
+ }
+
+ inline CBitmap* CDC::LoadImage(LPCTSTR lpszName, int cxDesired, int cyDesired, UINT fuLoad)
+ // Loads a bitmap from the resource and selects it into the device context
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ BOOL bResult = pBitmap->LoadImage(lpszName, cxDesired, cyDesired, fuLoad);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return bResult? SelectObject(pBitmap) : NULL;
+ }
+
+ inline CBitmap* CDC::LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
+ // Loads a predefined system bitmap and selects it into the device context
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ BOOL bResult = pBitmap->LoadOEMBitmap(nIDBitmap);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return bResult? SelectObject(pBitmap) : NULL;
+ }
+
+#ifndef _WIN32_WCE
+ inline CBitmap* CDC::CreateMappedBitmap(UINT nIDBitmap, UINT nFlags /*= 0*/, LPCOLORMAP lpColorMap /*= NULL*/, int nMapSize /*= 0*/)
+ // creates and selects a new bitmap using the bitmap data and colors specified by the bitmap resource and the color mapping information.
+ // Returns a pointer to the old bitmap selected out of the device context
+ {
+ assert(m_pData->hDC);
+
+ CBitmap* pBitmap = new CBitmap;
+ pBitmap->CreateMappedBitmap(nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
+ m_pData->m_vGDIObjects.push_back(pBitmap);
+ return SelectObject(pBitmap);
+ }
+#endif // !_WIN32_WCE
+
+
+ // Brush functions
+#ifndef _WIN32_WCE
+ inline CBrush* CDC::CreateBrushIndirect(LPLOGBRUSH pLogBrush)
+ // Creates the brush and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateBrushIndirect(pLogBrush);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+
+ inline CBrush* CDC::CreateHatchBrush(int fnStyle, COLORREF rgb)
+ // Creates a brush with the specified hatch pattern and color, and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateHatchBrush(fnStyle, rgb);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+
+ inline CBrush* CDC::CreateDIBPatternBrush(HGLOBAL hglbDIBPacked, UINT fuColorSpec)
+ // Creates a logical from the specified device-independent bitmap (DIB), and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateDIBPatternBrush(hglbDIBPacked, fuColorSpec);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+
+ inline CBrush* CDC::CreateDIBPatternBrushPt(LPCVOID lpPackedDIB, UINT iUsage)
+ // Creates a logical from the specified device-independent bitmap (DIB), and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateDIBPatternBrushPt(lpPackedDIB, iUsage);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+#endif
+
+ inline CBrush* CDC::CreatePatternBrush(CBitmap* pBitmap)
+ // Creates the brush with the specified pattern, and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+ assert(pBitmap);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreatePatternBrush(pBitmap);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+
+ inline CBrush* CDC::CreateSolidBrush(COLORREF rgb)
+ // Creates the brush with the specified color, and selects it into the device context.
+ // Returns a pointer to the old brush selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateSolidBrush(rgb);
+ m_pData->m_vGDIObjects.push_back(pBrush);
+ return SelectObject(pBrush);
+ }
+
+ inline LOGBRUSH CDC::GetLogBrush() const
+ // Retrieves the current brush information
+ {
+ assert(m_pData->hDC);
+
+ HBRUSH hBrush = (HBRUSH)::GetCurrentObject(m_pData->hDC, OBJ_BRUSH);
+ LOGBRUSH lBrush = {0};
+ ::GetObject(hBrush, sizeof(lBrush), &lBrush);
+ return lBrush;
+ }
+
+
+ // Font functions
+#ifndef _WIN32_WCE
+ inline CFont* CDC::CreateFont (
+ int nHeight, // height of font
+ int nWidth, // average character width
+ int nEscapement, // angle of escapement
+ int nOrientation, // base-line orientation angle
+ int fnWeight, // font weight
+ DWORD fdwItalic, // italic attribute option
+ DWORD fdwUnderline, // underline attribute option
+ DWORD fdwStrikeOut, // strikeout attribute option
+ DWORD fdwCharSet, // character set identifier
+ DWORD fdwOutputPrecision, // output precision
+ DWORD fdwClipPrecision, // clipping precision
+ DWORD fdwQuality, // output quality
+ DWORD fdwPitchAndFamily, // pitch and family
+ LPCTSTR lpszFace // typeface name
+ )
+
+ // Creates a logical font with the specified characteristics.
+ // Returns a pointer to the old font selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CFont* pFont = new CFont;
+ pFont->CreateFont (nHeight, nWidth, nEscapement, nOrientation, fnWeight,
+ fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
+ fdwOutputPrecision, fdwClipPrecision, fdwQuality,
+ fdwPitchAndFamily, lpszFace);
+ m_pData->m_vGDIObjects.push_back(pFont);
+ return SelectObject(pFont);
+ }
+#endif
+
+ inline CFont* CDC::CreateFontIndirect(LPLOGFONT plf)
+ // Creates a logical font and selects it into the device context.
+ // Returns a pointer to the old font selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CFont* pFont = new CFont;
+ pFont->CreateFontIndirect(plf);
+ m_pData->m_vGDIObjects.push_back(pFont);
+ return SelectObject(pFont);
+ }
+
+ inline LOGFONT CDC::GetLogFont() const
+ // Retrieves the current font information.
+ {
+ assert(m_pData->hDC);
+
+ HFONT hFont = (HFONT)::GetCurrentObject(m_pData->hDC, OBJ_FONT);
+ LOGFONT lFont = {0};
+ ::GetObject(hFont, sizeof(lFont), &lFont);
+ return lFont;
+ }
+
+ // Pen functions
+ inline CPen* CDC::CreatePen (int nStyle, int nWidth, COLORREF rgb)
+ // Creates the pen and selects it into the device context.
+ // Returns a pointer to the old pen selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CPen* pPen = new CPen;
+ pPen->CreatePen(nStyle, nWidth, rgb);
+ m_pData->m_vGDIObjects.push_back(pPen);
+ return SelectObject(pPen);
+ }
+
+ inline CPen* CDC::CreatePenIndirect (LPLOGPEN pLogPen)
+ // Creates the pen and selects it into the device context.
+ // Returns a pointer to the old pen selected out of the device context.
+ {
+ assert(m_pData->hDC);
+
+ CPen* pPen = new CPen;
+ pPen->CreatePenIndirect(pLogPen);
+ m_pData->m_vGDIObjects.push_back(pPen);
+ return SelectObject(pPen);
+ }
+
+ inline LOGPEN CDC::GetLogPen() const
+ // Retrieves the current pen information as a LOGPEN
+ {
+ assert(m_pData->hDC);
+
+ HPEN hPen = (HPEN)::GetCurrentObject(m_pData->hDC, OBJ_PEN);
+ LOGPEN lPen = {0};
+ ::GetObject(hPen, sizeof(lPen), &lPen);
+ return lPen;
+ }
+
+ // Region functions
+ inline int CDC::CreateRectRgn(int left, int top, int right, int bottom)
+ // Creates a rectangular region from the rectangle co-ordinates.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreateRectRgn(left, top, right, bottom);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+ inline int CDC::CreateRectRgnIndirect(const RECT& rc)
+ // Creates a rectangular region from the rectangle co-ordinates.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreateRectRgnIndirect(rc);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+ inline int CDC::CreateFromData(const XFORM* Xform, DWORD nCount, const RGNDATA *pRgnData)
+ // Creates a region from the specified region data and tranformation data.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ // Notes: GetRegionData can be used to get a region's data
+ // If the XFROM pointer is NULL, the identity transformation is used.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreateFromData(Xform, nCount, pRgnData);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+
+#ifndef _WIN32_WCE
+ inline int CDC::CreateEllipticRgn(int left, int top, int right, int bottom)
+ // Creates the ellyiptical region from the bounding rectangle co-ordinates
+ // and selects it into the device context.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreateEllipticRgn(left, top, right, bottom);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+ inline int CDC::CreateEllipticRgnIndirect(const RECT& rc)
+ // Creates the ellyiptical region from the bounding rectangle co-ordinates
+ // and selects it into the device context.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreateEllipticRgnIndirect(rc);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+ inline int CDC::CreatePolygonRgn(LPPOINT ppt, int cPoints, int fnPolyFillMode)
+ // Creates the polygon region from the array of points and selects it into
+ // the device context. The polygon is presumed closed.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreatePolygonRgn(ppt, cPoints, fnPolyFillMode);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+
+ inline int CDC::CreatePolyPolygonRgn(LPPOINT ppt, LPINT pPolyCounts, int nCount, int fnPolyFillMode)
+ // Creates the polygon region from a series of polygons.The polygons can overlap.
+ // The return value specifies the region's complexity: NULLREGION;SIMPLEREGION;COMPLEXREGION;ERROR.
+ {
+ assert(m_pData->hDC);
+
+ CRgn* pRgn = new CRgn;
+ pRgn->CreatePolyPolygonRgn(ppt, pPolyCounts, nCount, fnPolyFillMode);
+ m_pData->m_vGDIObjects.push_back(pRgn);
+ return SelectClipRgn(pRgn);
+ }
+#endif
+
+
+ // Wrappers for WinAPI functions
+
+ inline int CDC::GetDeviceCaps (int nIndex) const
+ // Retrieves device-specific information for the specified device.
+ {
+ assert(m_pData->hDC);
+ return ::GetDeviceCaps(m_pData->hDC, nIndex);
+ }
+
+ // Brush Functions
+#ifdef GetDCBrushColor
+ inline COLORREF CDC::GetDCBrushColor() const
+ {
+ assert(m_pData->hDC);
+ return ::GetDCBrushColor(m_pData->hDC);
+ }
+
+ inline COLORREF CDC::SetDCBrushColor(COLORREF crColor) const
+ {
+ assert(m_pData->hDC);
+ return ::SetDCBrushColor(m_pData->hDC, crColor);
+ }
+#endif
+
+ // Clipping functions
+ inline int CDC::ExcludeClipRect(int Left, int Top, int Right, int BottomRect)
+ // Creates a new clipping region that consists of the existing clipping region minus the specified rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::ExcludeClipRect(m_pData->hDC, Left, Top, Right, BottomRect);
+ }
+
+ inline int CDC::ExcludeClipRect(const RECT& rc)
+ // Creates a new clipping region that consists of the existing clipping region minus the specified rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::ExcludeClipRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
+ }
+
+ inline int CDC::GetClipBox (RECT& rc)
+ // Retrieves the dimensions of the tightest bounding rectangle that can be drawn around the current visible area on the device.
+ {
+ assert(m_pData->hDC);
+ return ::GetClipBox(m_pData->hDC, &rc);
+ }
+
+ inline int CDC::GetClipRgn(HRGN hrgn)
+ // Retrieves a handle identifying the current application-defined clipping region for the specified device context.
+ // hrgn: A handle to an existing region before the function is called.
+ // After the function returns, this parameter is a handle to a copy of the current clipping region.
+ {
+ assert(m_pData->hDC);
+ return ::GetClipRgn(m_pData->hDC, hrgn);
+ }
+
+ inline int CDC::IntersectClipRect(int Left, int Top, int Right, int Bottom)
+ // Creates a new clipping region from the intersection of the current clipping region and the specified rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::IntersectClipRect(m_pData->hDC, Left, Top, Right, Bottom);
+ }
+
+ inline int CDC::IntersectClipRect(const RECT& rc)
+ // Creates a new clipping region from the intersection of the current clipping region and the specified rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::IntersectClipRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
+ }
+
+ inline BOOL CDC::RectVisible(const RECT& rc)
+ // Determines whether any part of the specified rectangle lies within the clipping region of a device context.
+ {
+ assert(m_pData->hDC);
+ return ::RectVisible (m_pData->hDC, &rc);
+ }
+
+ inline int CDC::SelectClipRgn(CRgn* pRgn)
+ // Selects a region as the current clipping region for the specified device context.
+ // Note: Only a copy of the selected region is used.
+ // To remove a device-context's clipping region, specify a NULL region handle.
+ {
+ assert(m_pData->hDC);
+ return ::SelectClipRgn(m_pData->hDC, pRgn? (HRGN)pRgn->GetHandle() : 0);
+ }
+
+#ifndef _WIN32_WCE
+ inline int CDC::ExtSelectClipRgn(CRgn* pRgn, int fnMode)
+ // Combines the specified region with the current clipping region using the specified mode.
+ {
+ assert(m_pData->hDC);
+ assert(pRgn);
+ return ::ExtSelectClipRgn(m_pData->hDC, *pRgn, fnMode);
+ }
+#endif
+
+ inline CBitmap* CDC::SelectObject(const CBitmap* pBitmap)
+ // Use this to attach an existing bitmap.
+ {
+ assert(m_pData->hDC);
+ assert(pBitmap);
+
+ return FromHandle( (HBITMAP)::SelectObject(m_pData->hDC, *pBitmap) );
+ }
+
+ inline CBrush* CDC::SelectObject(const CBrush* pBrush)
+ // Use this to attach an existing brush.
+ {
+ assert(m_pData->hDC);
+ assert(pBrush);
+
+ return FromHandle( (HBRUSH)::SelectObject(m_pData->hDC, *pBrush) );
+ }
+
+ inline CFont* CDC::SelectObject(const CFont* pFont)
+ // Use this to attach an existing font.
+ {
+ assert(m_pData->hDC);
+ assert(pFont);
+
+ return FromHandle( (HFONT)::SelectObject(m_pData->hDC, *pFont) );
+ }
+
+ inline CPalette* CDC::SelectObject(const CPalette* pPalette)
+ // Use this to attach an existing Palette.
+ {
+ assert(m_pData->hDC);
+ assert(pPalette);
+
+ return FromHandle( (HPALETTE)::SelectObject(m_pData->hDC, *pPalette) );
+ }
+
+ inline CPen* CDC::SelectObject(const CPen* pPen)
+ // Use this to attach an existing pen.
+ {
+ assert(m_pData->hDC);
+ assert(pPen);
+
+ return FromHandle( (HPEN)::SelectObject(m_pData->hDC, *pPen) );
+ }
+
+ inline CPalette* CDC::SelectPalette(const CPalette* pPalette, BOOL bForceBkgnd)
+ // Use this to attach an existing palette.
+ {
+ assert(m_pData->hDC);
+ assert(pPalette);
+
+ return FromHandle( (HPALETTE)::SelectPalette(m_pData->hDC, *pPalette, bForceBkgnd) );
+ }
+#ifndef _WIN32_WCE
+ inline BOOL CDC::PtVisible(int X, int Y)
+ // Determines whether the specified point is within the clipping region of a device context.
+ {
+ assert(m_pData->hDC);
+ return ::PtVisible (m_pData->hDC, X, Y);
+ }
+
+ inline int CDC::OffsetClipRgn(int nXOffset, int nYOffset)
+ // Moves the clipping region of a device context by the specified offsets.
+ {
+ assert(m_pData->hDC);
+ return ::OffsetClipRgn (m_pData->hDC, nXOffset, nYOffset);
+ }
+#endif
+
+ // Point and Line Drawing Functions
+ inline CPoint CDC::GetCurrentPosition() const
+ // Returns the current "MoveToEx" position.
+ {
+ assert(m_pData->hDC);
+ CPoint pt;
+ ::MoveToEx(m_pData->hDC, 0, 0, &pt);
+ ::MoveToEx(m_pData->hDC, pt.x, pt.y, NULL);
+ return pt;
+ }
+
+ inline CPoint CDC::MoveTo(int x, int y) const
+ // Updates the current position to the specified point.
+ {
+ assert(m_pData->hDC);
+ return ::MoveToEx(m_pData->hDC, x, y, NULL);
+ }
+
+ inline CPoint CDC::MoveTo(POINT pt) const
+ // Updates the current position to the specified point
+ {
+ assert(m_pData->hDC);
+ return ::MoveToEx(m_pData->hDC, pt.x, pt.y, NULL);
+ }
+
+ inline BOOL CDC::LineTo(int x, int y) const
+ // Draws a line from the current position up to, but not including, the specified point.
+ {
+ assert(m_pData->hDC);
+ return ::LineTo(m_pData->hDC, x, y);
+ }
+
+ inline BOOL CDC::LineTo(POINT pt) const
+ // Draws a line from the current position up to, but not including, the specified point.
+ {
+ assert(m_pData->hDC);
+ return ::LineTo(m_pData->hDC, pt.x, pt.y);
+ }
+
+#ifndef _WIN32_WCE
+ inline BOOL CDC::Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
+ // Draws an elliptical arc.
+ {
+ assert(m_pData->hDC);
+ return ::Arc(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ inline BOOL CDC::Arc(RECT& rc, POINT ptStart, POINT ptEnd) const
+ // Draws an elliptical arc.
+ {
+ assert(m_pData->hDC);
+ return ::Arc(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
+ ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
+ }
+
+ inline BOOL CDC::ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
+ // Draws an elliptical arc.
+ {
+ assert(m_pData->hDC);
+ return ::ArcTo(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ inline BOOL CDC::ArcTo(RECT& rc, POINT ptStart, POINT ptEnd) const
+ // Draws an elliptical arc.
+ {
+ assert(m_pData->hDC);
+ return ::ArcTo (m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
+ ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
+ }
+
+ inline BOOL CDC::AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) const
+ // Draws a line segment and an arc.
+ {
+ assert(m_pData->hDC);
+ return ::AngleArc(m_pData->hDC, x, y, nRadius, fStartAngle, fSweepAngle);
+ }
+
+ inline int CDC::GetArcDirection() const
+ // Retrieves the current arc direction ( AD_COUNTERCLOCKWISE or AD_CLOCKWISE ).
+ {
+ assert(m_pData->hDC);
+ return ::GetArcDirection(m_pData->hDC);
+ }
+
+ inline int CDC::SetArcDirection(int nArcDirection) const
+ // Sets the current arc direction ( AD_COUNTERCLOCKWISE or AD_CLOCKWISE ).
+ {
+ assert(m_pData->hDC);
+ return ::SetArcDirection(m_pData->hDC, nArcDirection);
+ }
+
+ inline BOOL CDC::PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) const
+ // Draws a set of line segments and Bzier curves.
+ {
+ assert(m_pData->hDC);
+ return ::PolyDraw(m_pData->hDC, lpPoints, lpTypes, nCount);
+ }
+
+ inline BOOL CDC::Polyline(LPPOINT lpPoints, int nCount) const
+ // Draws a series of line segments by connecting the points in the specified array.
+ {
+ assert(m_pData->hDC);
+ return ::Polyline(m_pData->hDC, lpPoints, nCount);
+ }
+
+ inline BOOL CDC::PolyPolyline(const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount) const
+ // Draws multiple series of connected line segments.
+ {
+ assert(m_pData->hDC);
+ return ::PolyPolyline(m_pData->hDC, lpPoints, lpPolyPoints, nCount);
+ }
+
+ inline BOOL CDC::PolylineTo(const POINT* lpPoints, int nCount) const
+ // Draws one or more straight lines.
+ {
+ assert(m_pData->hDC);
+ return ::PolylineTo(m_pData->hDC, lpPoints, nCount);
+ }
+ inline BOOL CDC::PolyBezier(const POINT* lpPoints, int nCount) const
+ // Draws one or more Bzier curves.
+ {
+ assert(m_pData->hDC);
+ return ::PolyBezier(m_pData->hDC, lpPoints, nCount);
+ }
+
+ inline BOOL CDC::PolyBezierTo(const POINT* lpPoints, int nCount) const
+ // Draws one or more Bzier curves.
+ {
+ assert(m_pData->hDC);
+ return ::PolyBezierTo(m_pData->hDC, lpPoints, nCount );
+ }
+
+ inline COLORREF CDC::GetPixel(int x, int y) const
+ // Retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::GetPixel(m_pData->hDC, x, y);
+ }
+
+ inline COLORREF CDC::GetPixel(POINT pt) const
+ // Retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::GetPixel(m_pData->hDC, pt.x, pt.y);
+ }
+
+ inline COLORREF CDC::SetPixel (int x, int y, COLORREF crColor) const
+ // Sets the pixel at the specified coordinates to the specified color.
+ {
+ assert(m_pData->hDC);
+ return ::SetPixel(m_pData->hDC, x, y, crColor);
+ }
+
+ inline COLORREF CDC::SetPixel(POINT pt, COLORREF crColor) const
+ // Sets the pixel at the specified coordinates to the specified color.
+ {
+ assert(m_pData->hDC);
+ return ::SetPixel(m_pData->hDC, pt.x, pt.y, crColor);
+ }
+
+ inline BOOL CDC::SetPixelV(int x, int y, COLORREF crColor) const
+ // Sets the pixel at the specified coordinates to the closest approximation of the specified color.
+ {
+ assert(m_pData->hDC);
+ return ::SetPixelV(m_pData->hDC, x, y, crColor);
+ }
+
+ inline BOOL CDC::SetPixelV(POINT pt, COLORREF crColor) const
+ // Sets the pixel at the specified coordinates to the closest approximation of the specified color.
+ {
+ assert(m_pData->hDC);
+ return ::SetPixelV(m_pData->hDC, pt.x, pt.y, crColor);
+ }
+#endif
+
+ // Shape Drawing Functions
+ inline void CDC::DrawFocusRect(const RECT& rc) const
+ // Draws a rectangle in the style used to indicate that the rectangle has the focus.
+ {
+ assert(m_pData->hDC);
+ ::DrawFocusRect(m_pData->hDC, &rc);
+ }
+
+ inline BOOL CDC::Ellipse(int x1, int y1, int x2, int y2) const
+ // Draws an ellipse. The center of the ellipse is the center of the specified bounding rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::Ellipse(m_pData->hDC, x1, y1, x2, y2);
+ }
+
+ inline BOOL CDC::Ellipse(const RECT& rc) const
+ // Draws an ellipse. The center of the ellipse is the center of the specified bounding rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::Ellipse(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
+ }
+
+ inline BOOL CDC::Polygon(LPPOINT lpPoints, int nCount) const
+ // Draws a polygon consisting of two or more vertices connected by straight lines.
+ {
+ assert(m_pData->hDC);
+ return ::Polygon(m_pData->hDC, lpPoints, nCount);
+ }
+
+ inline BOOL CDC::Rectangle(int x1, int y1, int x2, int y2) const
+ // Draws a rectangle. The rectangle is outlined by using the current pen and filled by using the current brush.
+ {
+ assert(m_pData->hDC);
+ return ::Rectangle(m_pData->hDC, x1, y1, x2, y2);
+ }
+
+ inline BOOL CDC::Rectangle(const RECT& rc) const
+ // Draws a rectangle. The rectangle is outlined by using the current pen and filled by using the current brush.
+ {
+ assert(m_pData->hDC);
+ return ::Rectangle(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom);
+ }
+
+ inline BOOL CDC::RoundRect(int x1, int y1, int x2, int y2, int nWidth, int nHeight) const
+ // Draws a rectangle with rounded corners.
+ {
+ assert(m_pData->hDC);
+ return ::RoundRect(m_pData->hDC, x1, y1, x2, y2, nWidth, nHeight);
+ }
+ inline BOOL CDC::RoundRect(const RECT& rc, int nWidth, int nHeight) const
+ // Draws a rectangle with rounded corners.
+ {
+ assert(m_pData->hDC);
+ return ::RoundRect(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom, nWidth, nHeight );
+ }
+
+#ifndef _WIN32_WCE
+ inline BOOL CDC::Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
+ // Draws a chord (a region bounded by the intersection of an ellipse and a line segment, called a secant).
+ {
+ assert(m_pData->hDC);
+ return ::Chord(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ inline BOOL CDC::Chord(const RECT& rc, POINT ptStart, POINT ptEnd) const
+ // Draws a chord (a region bounded by the intersection of an ellipse and a line segment, called a secant).
+ {
+ assert(m_pData->hDC);
+ return ::Chord(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
+ ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
+ }
+
+ inline BOOL CDC::Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) const
+ // Draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials.
+ {
+ assert(m_pData->hDC);
+ return ::Pie(m_pData->hDC, x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ inline BOOL CDC::Pie(const RECT& rc, POINT ptStart, POINT ptEnd) const
+ // Draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials.
+ {
+ assert(m_pData->hDC);
+ return ::Pie(m_pData->hDC, rc.left, rc.top, rc.right, rc.bottom,
+ ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);
+ }
+
+ inline BOOL CDC::PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) const
+ // Draws a series of closed polygons.
+ {
+ assert(m_pData->hDC);
+ return ::PolyPolygon(m_pData->hDC, lpPoints, lpPolyCounts, nCount);
+ }
+#endif
+
+ // Fill and 3D Drawing functions
+ inline BOOL CDC::FillRect(const RECT& rc, CBrush* pBrush) const
+ // Fills a rectangle by using the specified brush.
+ {
+ assert(m_pData->hDC);
+ assert(pBrush);
+ return (BOOL)::FillRect(m_pData->hDC, &rc, *pBrush);
+ }
+
+ inline BOOL CDC::InvertRect(const RECT& rc) const
+ // Inverts a rectangle in a window by performing a logical NOT operation on the color values for each pixel in the rectangle's interior.
+ {
+ assert(m_pData->hDC);
+ return ::InvertRect( m_pData->hDC, &rc);
+ }
+
+ inline BOOL CDC::DrawIconEx(int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, CBrush* pFlickerFreeDraw, UINT diFlags) const
+ // draws an icon or cursor, performing the specified raster operations, and stretching or compressing the icon or cursor as specified.
+ {
+ assert(m_pData->hDC);
+ HBRUSH hFlickerFreeDraw = pFlickerFreeDraw? (HBRUSH)pFlickerFreeDraw->GetHandle() : NULL;
+ return ::DrawIconEx(m_pData->hDC, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hFlickerFreeDraw, diFlags);
+ }
+
+ inline BOOL CDC::DrawEdge(const RECT& rc, UINT nEdge, UINT nFlags) const
+ // Draws one or more edges of rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::DrawEdge(m_pData->hDC, (LPRECT)&rc, nEdge, nFlags);
+ }
+
+ inline BOOL CDC::DrawFrameControl(const RECT& rc, UINT nType, UINT nState) const
+ // Draws a frame control of the specified type and style.
+ {
+ assert(m_pData->hDC);
+ return ::DrawFrameControl(m_pData->hDC, (LPRECT)&rc, nType, nState);
+ }
+
+ inline BOOL CDC::FillRgn(CRgn* pRgn, CBrush* pBrush) const
+ // Fills a region by using the specified brush.
+ {
+ assert(m_pData->hDC);
+ assert(pRgn);
+ assert(pBrush);
+ return ::FillRgn(m_pData->hDC, *pRgn, *pBrush);
+ }
+
+#ifndef _WIN32_WCE
+ inline BOOL CDC::DrawIcon(int x, int y, HICON hIcon) const
+ // Draws an icon or cursor.
+ {
+ assert(m_pData->hDC);
+ return ::DrawIcon(m_pData->hDC, x, y, hIcon);
+ }
+
+ inline BOOL CDC::DrawIcon(POINT pt, HICON hIcon) const
+ // Draws an icon or cursor.
+ {
+ assert(m_pData->hDC);
+ return ::DrawIcon(m_pData->hDC, pt.x, pt.y, hIcon);
+ }
+
+ inline BOOL CDC::FrameRect(const RECT& rc, CBrush* pBrush) const
+ // Draws a border around the specified rectangle by using the specified brush.
+ {
+ assert(m_pData->hDC);
+ assert(pBrush);
+ return (BOOL)::FrameRect(m_pData->hDC, &rc, *pBrush);
+ }
+
+ inline BOOL CDC::PaintRgn(CRgn* pRgn) const
+ // Paints the specified region by using the brush currently selected into the device context.
+ {
+ assert(m_pData->hDC);
+ assert(pRgn);
+ return ::PaintRgn(m_pData->hDC, *pRgn);
+ }
+#endif
+
+ // Bitmap Functions
+ inline int CDC::StretchDIBits(int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
+ int nSrcHeight, CONST VOID *lpBits, BITMAPINFO& bi, UINT iUsage, DWORD dwRop) const
+ // Copies the color data for a rectangle of pixels in a DIB to the specified destination rectangle.
+ {
+ assert(m_pData->hDC);
+ return ::StretchDIBits(m_pData->hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, &bi, iUsage, dwRop);
+ }
+
+ inline BOOL CDC::PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) const
+ // Paints the specified rectangle using the brush that is currently selected into the device context.
+ {
+ assert(m_pData->hDC);
+ return ::PatBlt(m_pData->hDC, x, y, nWidth, nHeight, dwRop);
+ }
+
+ inline BOOL CDC::BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) const
+ // Performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.
+ {
+ assert(m_pData->hDC);
+ assert(pSrcDC);
+ return ::BitBlt(m_pData->hDC, x, y, nWidth, nHeight, pSrcDC->GetHDC(), xSrc, ySrc, dwRop);
+ }
+
+ inline BOOL CDC::StretchBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) const
+ // Copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary.
+ {
+ assert(m_pData->hDC);
+ assert(pSrcDC);
+ return ::StretchBlt(m_pData->hDC, x, y, nWidth, nHeight, pSrcDC->GetHDC(), xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
+ }
+
+#ifndef _WIN32_WCE
+ inline int CDC::GetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbi, UINT uUsage) const
+ // Retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.
+ {
+ assert(m_pData->hDC);
+ assert(pBitmap);
+ return ::GetDIBits(m_pData->hDC, *pBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage);
+ }
+
+ inline int CDC::SetDIBits(CBitmap* pBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, LPBITMAPINFO lpbi, UINT fuColorUse) const
+ // Sets the pixels in a compatible bitmap (DDB) using the color data found in the specified DIB.
+ {
+ assert(m_pData->hDC);
+ return ::SetDIBits(m_pData->hDC, *pBitmap, uStartScan, cScanLines, lpvBits, lpbi, fuColorUse);
+ }
+
+ inline int CDC::GetStretchBltMode() const
+ // Retrieves the current stretching mode.
+ // Possible modes: BLACKONWHITE, COLORONCOLOR, HALFTONE, STRETCH_ANDSCANS, STRETCH_DELETESCANS, STRETCH_HALFTONE, STRETCH_ORSCANS, WHITEONBLACK
+ {
+ assert(m_pData->hDC);
+ return ::GetStretchBltMode(m_pData->hDC);
+ }
+
+ inline int CDC::SetStretchBltMode(int iStretchMode) const
+ // Sets the stretching mode.
+ // Possible modes: BLACKONWHITE, COLORONCOLOR, HALFTONE, STRETCH_ANDSCANS, STRETCH_DELETESCANS, STRETCH_HALFTONE, STRETCH_ORSCANS, WHITEONBLACK
+ {
+ assert(m_pData->hDC);
+ return ::SetStretchBltMode(m_pData->hDC, iStretchMode);
+ }
+
+ inline BOOL CDC::FloodFill(int x, int y, COLORREF crColor) const
+ // Fills an area of the display surface with the current brush.
+ {
+ assert(m_pData->hDC);
+ return ::FloodFill(m_pData->hDC, x, y, crColor);
+ }
+
+ inline BOOL CDC::ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) const
+ // Fills an area of the display surface with the current brush.
+ // Fill type: FLOODFILLBORDER or FLOODFILLSURFACE
+ {
+ assert(m_pData->hDC);
+ return ::ExtFloodFill(m_pData->hDC, x, y, crColor, nFillType );
+ }
+
+ // co-ordinate functions
+ inline BOOL CDC::DPtoLP(LPPOINT lpPoints, int nCount) const
+ // Converts device coordinates into logical coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::DPtoLP(m_pData->hDC, lpPoints, nCount);
+ }
+
+ inline BOOL CDC::DPtoLP(RECT& rc) const
+ // Converts device coordinates into logical coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::DPtoLP(m_pData->hDC, (LPPOINT)&rc, 2);
+ }
+
+ inline BOOL CDC::LPtoDP(LPPOINT lpPoints, int nCount) const
+ // Converts logical coordinates into device coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::LPtoDP(m_pData->hDC, lpPoints, nCount);
+ }
+
+ inline BOOL CDC::LPtoDP(RECT& rc) const
+ // Converts logical coordinates into device coordinates.
+ {
+ assert(m_pData->hDC);
+ return ::LPtoDP(m_pData->hDC, (LPPOINT)&rc, 2);
+ }
+
+#endif
+
+ // Layout Functions
+ inline DWORD CDC::GetLayout() const
+ // Returns the layout of a device context (LAYOUT_RTL and LAYOUT_BITMAPORIENTATIONPRESERVED).
+ {
+#if defined(WINVER) && defined(GetLayout) && (WINVER >= 0x0500)
+ return ::GetLayout(m_pData->hDC);
+#else
+ return 0;
+#endif
+ }
+
+ inline DWORD CDC::SetLayout(DWORD dwLayout) const
+ // changes the layout of a device context (DC).
+ // dwLayout values: LAYOUT_RTL or LAYOUT_BITMAPORIENTATIONPRESERVED
+ {
+#if defined(WINVER) && defined (SetLayout) && (WINVER >= 0x0500)
+ // Sets the layout of a device context
+ return ::SetLayout(m_pData->hDC, dwLayout);
+#else
+ UNREFERENCED_PARAMETER(dwLayout); // no-op
+ return 0;
+#endif
+ }
+
+ // Mapping Functions
+#ifndef _WIN32_WCE
+ inline int CDC::GetMapMode() const
+ // Rretrieves the current mapping mode.
+ // Possible modes: MM_ANISOTROPIC, MM_HIENGLISH, MM_HIMETRIC, MM_ISOTROPIC, MM_LOENGLISH, MM_LOMETRIC, MM_TEXT, and MM_TWIPS.
+ {
+ assert(m_pData->hDC);
+ return ::GetMapMode(m_pData->hDC);
+ }
+
+ inline BOOL CDC::GetViewportOrgEx(LPPOINT lpPoint) const
+ // Retrieves the x-coordinates and y-coordinates of the viewport origin for the device context.
+ {
+ assert(m_pData->hDC);
+ return ::GetViewportOrgEx(m_pData->hDC, lpPoint);
+ }
+
+ inline int CDC::SetMapMode(int nMapMode) const
+ // Sets the mapping mode of the specified device context.
+ {
+ assert(m_pData->hDC);
+ return ::SetMapMode(m_pData->hDC, nMapMode);
+ }
+
+ inline BOOL CDC::SetViewportOrgEx(int x, int y, LPPOINT lpPoint /* = NULL */) const
+ // Specifies which device point maps to the window origin (0,0).
+ {
+ assert(m_pData->hDC);
+ return ::SetViewportOrgEx(m_pData->hDC, x, y, lpPoint);
+ }
+
+ inline BOOL CDC::SetViewportOrgEx(POINT point, LPPOINT lpPointRet /* = NULL */) const
+ // Specifies which device point maps to the window origin (0,0).
+ {
+ assert(m_pData->hDC);
+ return SetViewportOrgEx(point.x, point.y, lpPointRet);
+ }
+
+ inline BOOL CDC::OffsetViewportOrgEx(int nWidth, int nHeight, LPPOINT lpPoint /* = NULL */) const
+ // Modifies the viewport origin for the device context using the specified horizontal and vertical offsets.
+ {
+ assert(m_pData->hDC);
+ return ::OffsetViewportOrgEx(m_pData->hDC, nWidth, nHeight, lpPoint);
+ }
+
+ inline BOOL CDC::GetViewportExtEx(LPSIZE lpSize) const
+ // Retrieves the x-extent and y-extent of the current viewport for the device context.
+ {
+ assert(m_pData->hDC);
+ return ::GetViewportExtEx(m_pData->hDC, lpSize);
+ }
+
+ inline BOOL CDC::SetViewportExtEx(int x, int y, LPSIZE lpSize ) const
+ // Sets the horizontal and vertical extents of the viewport for the device context by using the specified values.
+ {
+ assert(m_pData->hDC);
+ return ::SetViewportExtEx(m_pData->hDC, x, y, lpSize);
+ }
+
+ inline BOOL CDC::SetViewportExtEx(SIZE size, LPSIZE lpSizeRet ) const
+ // Sets the horizontal and vertical extents of the viewport for the device context by using the specified values.
+ {
+ assert(m_pData->hDC);
+ return SetViewportExtEx(size.cx, size.cy, lpSizeRet);
+ }
+
+ inline BOOL CDC::ScaleViewportExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize ) const
+ // Modifies the viewport for the device context using the ratios formed by the specified multiplicands and divisors.
+ {
+ assert(m_pData->hDC);
+ return ::ScaleViewportExtEx(m_pData->hDC, xNum, xDenom, yNum, yDenom, lpSize);
+ }
+
+ inline BOOL CDC::GetWindowOrgEx(LPPOINT lpPoint) const
+ // Retrieves the x-coordinates and y-coordinates of the window origin for the device context.
+ {
+ assert(m_pData->hDC);
+ return ::GetWindowOrgEx(m_pData->hDC, lpPoint);
+ }
+
+ inline BOOL CDC::SetWindowOrgEx(int x, int y, LPPOINT lpPoint ) const
+ // Specifies which window point maps to the viewport origin (0,0).
+ {
+ assert(m_pData->hDC);
+ return ::SetWindowOrgEx(m_pData->hDC, x, y, lpPoint);
+ }
+
+ inline BOOL CDC::SetWindowOrgEx(POINT point, LPPOINT lpPointRet ) const
+ // Specifies which window point maps to the viewport origin (0,0).
+ {
+ assert(m_pData->hDC);
+ return SetWindowOrgEx(point.x, point.y, lpPointRet);
+ }
+
+ inline BOOL CDC::OffsetWindowOrgEx(int nWidth, int nHeight, LPPOINT lpPoint ) const
+ // Modifies the window origin for the device context using the specified horizontal and vertical offsets.
+ {
+ assert(m_pData->hDC);
+ return ::OffsetWindowOrgEx(m_pData->hDC, nWidth, nHeight, lpPoint);
+ }
+
+ inline BOOL CDC::GetWindowExtEx(LPSIZE lpSize) const
+ // Retrieves the x-extent and y-extent of the window for the device context.
+ {
+ assert(m_pData->hDC);
+ return ::GetWindowExtEx(m_pData->hDC, lpSize);
+ }
+
+ inline BOOL CDC::SetWindowExtEx(int x, int y, LPSIZE lpSize ) const
+ // Sets the horizontal and vertical extents of the window for the device context by using the specified values.
+ {
+ assert(m_pData->hDC);
+ return ::SetWindowExtEx(m_pData->hDC, x, y, lpSize);
+ }
+
+ inline BOOL CDC::SetWindowExtEx(SIZE size, LPSIZE lpSizeRet) const
+ // Sets the horizontal and vertical extents of the window for the device context by using the specified values.
+ {
+ assert(m_pData->hDC);
+ return SetWindowExtEx(size.cx, size.cy, lpSizeRet);
+ }
+
+ inline BOOL CDC::ScaleWindowExtEx(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize) const
+ // Modifies the window for the device context using the ratios formed by the specified multiplicands and divisors.
+ {
+ assert(m_pData->hDC);
+ return ::ScaleWindowExtEx(m_pData->hDC, xNum, xDenom, yNum, yDenom, lpSize);
+ }
+#endif
+
+ // Printer Functions
+ inline int CDC::StartDoc(LPDOCINFO lpDocInfo) const
+ // Starts a print job.
+ {
+ assert(m_pData->hDC);
+ return ::StartDoc(m_pData->hDC, lpDocInfo);
+ }
+
+ inline int CDC::EndDoc() const
+ // Ends a print job.
+ {
+ assert(m_pData->hDC);
+ return ::EndDoc(m_pData->hDC);
+ }
+
+ inline int CDC::StartPage() const
+ // Prepares the printer driver to accept data.
+ {
+ assert(m_pData->hDC);
+ return ::StartPage(m_pData->hDC);
+ }
+
+ inline int CDC::EndPage() const
+ // Notifies the device that the application has finished writing to a page.
+ {
+ assert(m_pData->hDC);
+ return ::EndPage(m_pData->hDC);
+ }
+
+ inline int CDC::AbortDoc() const
+ // Stops the current print job and erases everything drawn since the last call to the StartDoc function.
+ {
+ assert(m_pData->hDC);
+ return ::AbortDoc(m_pData->hDC);
+ }
+
+ inline int CDC::SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) const
+ // Sets the application-defined abort function that allows a print job to be canceled during spooling.
+ {
+ assert(m_pData->hDC);
+ return ::SetAbortProc(m_pData->hDC, lpfn);
+ }
+
+ // Text Functions
+ inline BOOL CDC::ExtTextOut(int x, int y, UINT nOptions, LPCRECT lprc, LPCTSTR lpszString, int nCount /*= -1*/, LPINT lpDxWidths /*=NULL*/) const
+ // Draws text using the currently selected font, background color, and text color
+ {
+ assert(m_pData->hDC);
+
+ if (nCount == -1)
+ nCount = lstrlen (lpszString);
+
+ return ::ExtTextOut(m_pData->hDC, x, y, nOptions, lprc, lpszString, nCount, lpDxWidths );
+ }
+
+ inline int CDC::DrawText(LPCTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat) const
+ // Draws formatted text in the specified rectangle
+ {
+ assert(m_pData->hDC);
+ return ::DrawText(m_pData->hDC, lpszString, nCount, lprc, nFormat );
+ }
+
+ inline UINT CDC::GetTextAlign() const
+ // Retrieves the text-alignment setting
+ // Values: TA_BASELINE, TA_BOTTOM, TA_TOP, TA_CENTER, TA_LEFT, TA_RIGHT, TA_RTLREADING, TA_NOUPDATECP, TA_UPDATECP
+ {
+ assert(m_pData->hDC);
+ return ::GetTextAlign(m_pData->hDC);
+ }
+
+ inline UINT CDC::SetTextAlign(UINT nFlags) const
+ // Sets the text-alignment setting
+ // Values: TA_BASELINE, TA_BOTTOM, TA_TOP, TA_CENTER, TA_LEFT, TA_RIGHT, TA_RTLREADING, TA_NOUPDATECP, TA_UPDATECP
+ {
+ assert(m_pData->hDC);
+ return ::SetTextAlign(m_pData->hDC, nFlags);
+ }
+
+ inline int CDC::GetTextFace(int nCount, LPTSTR lpszFacename) const
+ // Retrieves the typeface name of the font that is selected into the device context
+ {
+ assert(m_pData->hDC);
+ return ::GetTextFace(m_pData->hDC, nCount, lpszFacename);
+ }
+
+ inline BOOL CDC::GetTextMetrics(TEXTMETRIC& Metrics) const
+ // Fills the specified buffer with the metrics for the currently selected font
+ {
+ assert(m_pData->hDC);
+ return ::GetTextMetrics(m_pData->hDC, &Metrics);
+ }
+
+ inline COLORREF CDC::GetBkColor() const
+ // Returns the current background color
+ {
+ assert(m_pData->hDC);
+ return ::GetBkColor(m_pData->hDC);
+ }
+
+ inline COLORREF CDC::SetBkColor(COLORREF crColor) const
+ // Sets the current background color to the specified color value
+ {
+ assert(m_pData->hDC);
+ return ::SetBkColor(m_pData->hDC, crColor);
+ }
+
+ inline COLORREF CDC::GetTextColor() const
+ // Retrieves the current text color
+ {
+ assert(m_pData->hDC);
+ return ::GetTextColor(m_pData->hDC);
+ }
+
+ inline COLORREF CDC::SetTextColor(COLORREF crColor) const
+ // Sets the current text color
+ {
+ assert(m_pData->hDC);
+ return ::SetTextColor(m_pData->hDC, crColor);
+ }
+
+ inline int CDC::GetBkMode() const
+ // returns the current background mix mode (OPAQUE or TRANSPARENT)
+ {
+ assert(m_pData->hDC);
+ return ::GetBkMode(m_pData->hDC);
+ }
+
+ inline int CDC::SetBkMode(int iBkMode) const
+ // Sets the current background mix mode (OPAQUE or TRANSPARENT)
+ {
+ assert(m_pData->hDC);
+ return ::SetBkMode(m_pData->hDC, iBkMode);
+ }
+
+#ifndef _WIN32_WCE
+ inline int CDC::DrawTextEx(LPTSTR lpszString, int nCount, LPRECT lprc, UINT nFormat, LPDRAWTEXTPARAMS lpDTParams) const
+ // Draws formatted text in the specified rectangle with more formatting options
+ {
+ assert(m_pData->hDC);
+ return ::DrawTextEx(m_pData->hDC, lpszString, nCount, lprc, nFormat, lpDTParams);
+ }
+
+ inline CSize CDC::GetTextExtentPoint32(LPCTSTR lpszString, int nCount) const
+ // Computes the width and height of the specified string of text
+ {
+ assert(m_pData->hDC);
+ CSize sz;
+ ::GetTextExtentPoint32(m_pData->hDC, lpszString, nCount, &sz);
+ return sz;
+ }
+
+ inline CSize CDC::GetTabbedTextExtent(LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions) const
+ // Computes the width and height of a character string
+ {
+ assert(m_pData->hDC);
+ DWORD dwSize = ::GetTabbedTextExtent(m_pData->hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions );
+ CSize sz(dwSize);
+ return sz;
+ }
+
+ inline BOOL CDC::GrayString(CBrush* pBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) const
+ // Draws gray text at the specified location
+ {
+ assert(m_pData->hDC);
+ assert(pBrush);
+ return ::GrayString(m_pData->hDC, *pBrush, lpOutputFunc, lpData, nCount, x, y, nWidth, nHeight);
+ }
+
+ inline int CDC::SetTextJustification(int nBreakExtra, int nBreakCount) const
+ // Specifies the amount of space the system should add to the break characters in a string of text
+ {
+ assert(m_pData->hDC);
+ return ::SetTextJustification(m_pData->hDC, nBreakExtra, nBreakCount);
+ }
+
+ inline int CDC::GetTextCharacterExtra() const
+ // Retrieves the current intercharacter spacing for the device context
+ {
+ assert(m_pData->hDC);
+ return ::GetTextCharacterExtra(m_pData->hDC);
+ }
+
+ inline int CDC::SetTextCharacterExtra(int nCharExtra) const
+ // Sets the intercharacter spacing
+ {
+ assert(m_pData->hDC);
+ return ::SetTextCharacterExtra(m_pData->hDC, nCharExtra);
+ }
+
+ inline CSize CDC::TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin) const
+ // Writes a character string at a specified location, expanding tabs to the values specified in an array of tab-stop positions
+ {
+ assert(m_pData->hDC);
+ DWORD dwSize = ::TabbedTextOut(m_pData->hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin );
+ CSize sz(dwSize);
+ return sz;
+ }
+
+ inline BOOL CDC::TextOut(int x, int y, LPCTSTR lpszString, int nCount/* = -1*/) const
+ // Writes a character string at the specified location
+ {
+ assert(m_pData->hDC);
+ if (nCount == -1)
+ nCount = lstrlen (lpszString);
+
+ return ::TextOut(m_pData->hDC, x, y, lpszString, nCount);
+ }
+
+#endif
+
+
+
+ /////////////////////////////////////////////////////////////////
+ // Definitions for some global functions in the Win32xx namespace
+ //
+
+#ifndef _WIN32_WCE
+ inline void TintBitmap (CBitmap* pbmSource, int cRed, int cGreen, int cBlue)
+ // Modifies the colour of the supplied Device Dependant Bitmap, by the colour
+ // correction values specified. The correction values can range from -255 to +255.
+ // This function gains its speed by accessing the bitmap colour information
+ // directly, rather than using GetPixel/SetPixel.
+ {
+ // Create our LPBITMAPINFO object
+ CBitmapInfoPtr pbmi(pbmSource);
+ pbmi->bmiHeader.biBitCount = 24;
+
+ // Create the reference DC for GetDIBits to use
+ CMemDC MemDC(NULL);
+
+ // Use GetDIBits to create a DIB from our DDB, and extract the colour data
+ MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
+ std::vector<byte> vBits(pbmi->bmiHeader.biSizeImage, 0);
+ byte* pByteArray = &vBits[0];
+
+ MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
+ UINT nWidthBytes = pbmi->bmiHeader.biSizeImage/pbmi->bmiHeader.biHeight;
+
+ // Ensure sane colour correction values
+ cBlue = MIN(cBlue, 255);
+ cBlue = MAX(cBlue, -255);
+ cRed = MIN(cRed, 255);
+ cRed = MAX(cRed, -255);
+ cGreen = MIN(cGreen, 255);
+ cGreen = MAX(cGreen, -255);
+
+ // Pre-calculate the RGB modification values
+ int b1 = 256 - cBlue;
+ int g1 = 256 - cGreen;
+ int r1 = 256 - cRed;
+
+ int b2 = 256 + cBlue;
+ int g2 = 256 + cGreen;
+ int r2 = 256 + cRed;
+
+ // Modify the colour
+ int yOffset = 0;
+ int xOffset;
+ int Index;
+ for (int Row=0; Row < pbmi->bmiHeader.biHeight; Row++)
+ {
+ xOffset = 0;
+
+ for (int Column=0; Column < pbmi->bmiHeader.biWidth; Column++)
+ {
+ // Calculate Index
+ Index = yOffset + xOffset;
+
+ // Adjust the colour values
+ if (cBlue > 0)
+ pByteArray[Index] = (BYTE)(cBlue + (((pByteArray[Index] *b1)) >>8));
+ else if (cBlue < 0)
+ pByteArray[Index] = (BYTE)((pByteArray[Index] *b2) >>8);
+
+ if (cGreen > 0)
+ pByteArray[Index+1] = (BYTE)(cGreen + (((pByteArray[Index+1] *g1)) >>8));
+ else if (cGreen < 0)
+ pByteArray[Index+1] = (BYTE)((pByteArray[Index+1] *g2) >>8);
+
+ if (cRed > 0)
+ pByteArray[Index+2] = (BYTE)(cRed + (((pByteArray[Index+2] *r1)) >>8));
+ else if (cRed < 0)
+ pByteArray[Index+2] = (BYTE)((pByteArray[Index+2] *r2) >>8);
+
+ // Increment the horizontal offset
+ xOffset += pbmi->bmiHeader.biBitCount >> 3;
+ }
+
+ // Increment vertical offset
+ yOffset += nWidthBytes;
+ }
+
+ // Save the modified colour back into our source DDB
+ MemDC.SetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
+ }
+
+ inline void GrayScaleBitmap(CBitmap* pbmSource)
+ {
+ // Create our LPBITMAPINFO object
+ CBitmapInfoPtr pbmi(pbmSource);
+
+ // Create the reference DC for GetDIBits to use
+ CMemDC MemDC(NULL);
+
+ // Use GetDIBits to create a DIB from our DDB, and extract the colour data
+ MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, NULL, pbmi, DIB_RGB_COLORS);
+ std::vector<byte> vBits(pbmi->bmiHeader.biSizeImage, 0);
+ byte* pByteArray = &vBits[0];
+
+ MemDC.GetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
+ UINT nWidthBytes = pbmi->bmiHeader.biSizeImage/pbmi->bmiHeader.biHeight;
+
+ int yOffset = 0;
+ int xOffset;
+ int Index;
+
+ for (int Row=0; Row < pbmi->bmiHeader.biHeight; Row++)
+ {
+ xOffset = 0;
+
+ for (int Column=0; Column < pbmi->bmiHeader.biWidth; Column++)
+ {
+ // Calculate Index
+ Index = yOffset + xOffset;
+
+ BYTE byGray = (BYTE) ((pByteArray[Index] + pByteArray[Index+1]*6 + pByteArray[Index+2] *3)/10);
+ pByteArray[Index] = byGray;
+ pByteArray[Index+1] = byGray;
+ pByteArray[Index+2] = byGray;
+
+ // Increment the horizontal offset
+ xOffset += pbmi->bmiHeader.biBitCount >> 3;
+ }
+
+ // Increment vertical offset
+ yOffset += nWidthBytes;
+ }
+
+ // Save the modified colour back into our source DDB
+ MemDC.SetDIBits(pbmSource, 0, pbmi->bmiHeader.biHeight, pByteArray, pbmi, DIB_RGB_COLORS);
+ }
+
+ inline HIMAGELIST CreateDisabledImageList(HIMAGELIST himlNormal)
+ // Returns a greyed image list, created from hImageList
+ {
+ int cx, cy;
+ int nCount = ImageList_GetImageCount(himlNormal);
+ if (0 == nCount)
+ return NULL;
+
+ ImageList_GetIconSize(himlNormal, &cx, &cy);
+
+ // Create the disabled ImageList
+ HIMAGELIST himlDisabled = ImageList_Create(cx, cy, ILC_COLOR24 | ILC_MASK, nCount, 0);
+
+ // Process each image in the ImageList
+ for (int i = 0 ; i < nCount; ++i)
+ {
+ CClientDC DesktopDC(NULL);
+ CMemDC MemDC(NULL);
+ CBitmap* pOldBitmap = MemDC.CreateCompatibleBitmap(&DesktopDC, cx, cx);
+ CRect rc;
+ rc.SetRect(0, 0, cx, cx);
+
+ // Set the mask color to grey for the new ImageList
+ COLORREF crMask = RGB(200, 199, 200);
+ if ( GetDeviceCaps(DesktopDC, BITSPIXEL) < 24)
+ {
+ HPALETTE hPal = (HPALETTE)GetCurrentObject(DesktopDC, OBJ_PAL);
+ UINT Index = GetNearestPaletteIndex(hPal, crMask);
+ if (Index != CLR_INVALID) crMask = PALETTEINDEX(Index);
+ }
+
+ MemDC.SolidFill(crMask, rc);
+
+ // Draw the image on the memory DC
+ ImageList_SetBkColor(himlNormal, crMask);
+ ImageList_Draw(himlNormal, i, MemDC, 0, 0, ILD_NORMAL);
+
+ // Convert colored pixels to gray
+ for (int x = 0 ; x < cx; ++x)
+ {
+ for (int y = 0; y < cy; ++y)
+ {
+ COLORREF clr = ::GetPixel(MemDC, x, y);
+
+ if (clr != crMask)
+ {
+ BYTE byGray = (BYTE) (95 + (GetRValue(clr) *3 + GetGValue(clr)*6 + GetBValue(clr))/20);
+ MemDC.SetPixel(x, y, RGB(byGray, byGray, byGray));
+ }
+
+ }
+ }
+
+ // Detach the bitmap so we can use it.
+ CBitmap* pBitmap = MemDC.SelectObject(pOldBitmap);
+ ImageList_AddMasked(himlDisabled, *pBitmap, crMask);
+ }
+
+ return himlDisabled;
+ }
+#endif
+
+ ////////////////////////////////////////////
+ // Global Function Definitions
+ //
+
+ inline CDC* FromHandle(HDC hDC)
+ // Returns the CDC object associated with the device context handle
+ // If a CDC object doesn't already exist, a temporary CDC object is created.
+ // The HDC belonging to a temporary CDC is not released or destroyed when the
+ // temporary CDC is deconstructed.
+ {
+ assert( GetApp() );
+ CDC* pDC = GetApp()->GetCDCFromMap(hDC);
+ if (hDC != 0 && pDC == 0)
+ {
+ pDC = new CDC;
+ GetApp()->AddTmpDC(pDC);
+ pDC->m_pData->hDC = hDC;
+ pDC->m_pData->bRemoveHDC = FALSE;
+ }
+ return pDC;
+ }
+
+ inline CBitmap* FromHandle(HBITMAP hBitmap)
+ // Returns the CBitmap associated with the Bitmap handle
+ // If a CBitmap object doesn't already exist, a temporary CBitmap object is created.
+ // The HBITMAP belonging to a temporary CBitmap is not released or destroyed
+ // when the temporary CBitmap is deconstructed.
+ {
+ assert( GetApp() );
+ CBitmap* pBitmap = (CBitmap*)GetApp()->GetCGDIObjectFromMap(hBitmap);
+ if (hBitmap != 0 && pBitmap == 0)
+ {
+ pBitmap = new CBitmap;
+ GetApp()->AddTmpGDI(pBitmap);
+ pBitmap->m_pData->hGDIObject = hBitmap;
+ pBitmap->m_pData->bRemoveObject = FALSE;
+ }
+ return pBitmap;
+ }
+
+ inline CBrush* FromHandle(HBRUSH hBrush)
+ // Returns the CBrush associated with the Brush handle
+ // If a CBrush object doesn't already exist, a temporary CBrush object is created.
+ // The HBRUSH belonging to a temporary CBrush is not released or destroyed
+ // when the temporary CBrush is deconstructed.
+ {
+ assert( GetApp() );
+ CBrush* pBrush = (CBrush*)GetApp()->GetCGDIObjectFromMap(hBrush);
+ if (hBrush != 0 && pBrush == 0)
+ {
+ pBrush = new CBrush;
+ GetApp()->AddTmpGDI(pBrush);
+ pBrush->m_pData->hGDIObject = hBrush;
+ pBrush->m_pData->bRemoveObject = FALSE;
+ }
+ return pBrush;
+ }
+
+ inline CFont* FromHandle(HFONT hFont)
+ // Returns the CFont associated with the Font handle
+ // If a CFont object doesn't already exist, a temporary CFont object is created.
+ // The HFONT belonging to a temporary CFont is not released or destroyed
+ // when the temporary CFont is deconstructed.
+ {
+ assert( GetApp() );
+ CFont* pFont = (CFont*)GetApp()->GetCGDIObjectFromMap(hFont);
+ if (hFont != 0 && pFont == 0)
+ {
+ pFont = new CFont;
+ GetApp()->AddTmpGDI(pFont);
+ pFont->m_pData->hGDIObject = hFont;
+ pFont->m_pData->bRemoveObject = FALSE;
+ }
+ return pFont;
+ }
+
+ inline CPalette* FromHandle(HPALETTE hPalette)
+ // Returns the CPalette associated with the palette handle
+ // If a CPalette object doesn't already exist, a temporary CPalette object is created.
+ // The HPALETTE belonging to a temporary CPalette is not released or destroyed
+ // when the temporary CPalette is deconstructed.
+ {
+ assert( GetApp() );
+ CPalette* pPalette = (CPalette*)GetApp()->GetCGDIObjectFromMap(hPalette);
+ if (hPalette != 0 && pPalette == 0)
+ {
+ pPalette = new CPalette;
+ GetApp()->AddTmpGDI(pPalette);
+ pPalette->m_pData->hGDIObject = hPalette;
+ pPalette->m_pData->bRemoveObject = FALSE;
+ }
+ return pPalette;
+ }
+
+ inline CPen* FromHandle(HPEN hPen)
+ // Returns the CPen associated with the HPEN.
+ // If a CPen object doesn't already exist, a temporary CPen object is created.
+ // The HPEN belonging to a temporary CPen is not released or destroyed
+ // when the temporary CPen is deconstructed.
+ {
+ assert( GetApp() );
+ CPen* pPen = (CPen*)GetApp()->GetCGDIObjectFromMap(hPen);
+ if (hPen != 0 && pPen == 0)
+ {
+ pPen = new CPen;
+ GetApp()->AddTmpGDI(pPen);
+ pPen->m_pData->hGDIObject = hPen;
+ pPen->m_pData->bRemoveObject = FALSE;
+ }
+ return pPen;
+ }
+
+ inline CRgn* FromHandle(HRGN hRgn)
+ // Returns the CRgn associated with the HRGN.
+ // If a CRgn object doesn't already exist, a temporary CRgn object is created.
+ // The HRGN belonging to a temporary CRgn is not released or destroyed
+ // when the temporary CRgn is deconstructed.
+ {
+ assert( GetApp() );
+ CRgn* pRgn = (CRgn*)GetApp()->GetCGDIObjectFromMap(hRgn);
+ if (hRgn != 0 && pRgn == 0)
+ {
+ pRgn = new CRgn;
+ GetApp()->AddTmpGDI(pRgn);
+ pRgn->m_pData->hGDIObject = hRgn;
+ pRgn->m_pData->bRemoveObject = FALSE;
+ }
+ return pRgn;
+ }
+
+
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_GDI_H_
+
diff --git a/mmc_updater/depends/win32cpp/info.txt b/mmc_updater/depends/win32cpp/info.txt
new file mode 100644
index 00000000..a4dbda8e
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/info.txt
@@ -0,0 +1,205 @@
+Generic Information about Win32++ Projects
+==========================================
+The various directories may contain the following types of files:
+
+Extension | Description
+----------+------------
+cbp | A project file used by CodeBlocks
+dsp | A project file used by Visual Studio 6
+dsw | A project file used by Visual Studio 6
+sln | A project file used by Visual Studio 2003, VS2005 or VS2008
+vcproj | A project file used by Visual Studio 2003, VS2005 or VS2008
+vcxproj | A project file used by Visual Studio 2010
+filters | A supplementary project file used by Visual Studio 2010
+bdsproj | A project file used by Borland Developer Studio 2006
+bpf | A project file used by Borland Developer Studio 2006
+vcp | A project file used by eMbedded Visual C++
+vcw | A project file used by eMbedded Visual C++
+dev | A project file used by Dev-C++
+cpp | A C++ source file
+h | A C++ header file
+rc | A C++ resouce script file
+jpg | A jpeg resource file
+ico | An icon resource file
+bmp | A bitmap resource file
+cur | A cursor resource file
+manifest | A manifest resource file
+txt | A text file
+xml | An Extensible Markup Language file (defines the ribbon UI)
+
+Supported Compilers and Integrated Development Environments (IDEs)
+==================================================================
+Win32++ supports the following:
+* Borland Compiler Version 5.5
+* Borland Developer Studio 2006
+* Borland Turbo C++ 2006
+* CodeBlocks
+* Dev-C++
+* MinGW GCC Compiler
+* Visual Studio 6
+* Visual Studio.net 2003
+* Visual C++ Toolkit 2003
+* Visual Studio.net 2005
+* Visual Studio.net 2005 Express
+* Visual Studio.net 2008
+* Visual Studio.net 2008 Express
+* Visual Studio.net 2010
+
+CodeBlocks is an IDE. The project files are configured for the following
+compilers:
+* Borland Compiler Version 5.5
+* MinGW GNU compiler
+* Visual C++ Toolkit 2003
+
+Dev-C++ is an IDE which supports the MinGW GNU compiler
+
+Supported Operating Systems
+===========================
+The programs compiled with Win32++ can run on the following operating systems:
+* Win95 (all versions, with or without Internet Explorer 4 installed)
+* Win98 (both versions)
+* WinME
+* Windows NT 4
+* Windows 2000
+* Windows XP
+* Windows XP x64
+* Windows Vista
+* Windows Vista x64
+* Windows 7
+* Windows 7 x64
+* Windows Server 2003
+* Windows Server 2003 x64
+* Windows Server 2008
+* Windows Server 2008 x64
+* Windows CE
+
+Note: Programs compiled with Visual Studio.net 2008 and Visual Studio.net 2008
+Express will not run on Win32 operating systems earlier than Windows 2000.
+
+Win32++ automatically detects if the operating system is capable of using
+rebars. If rebars are not supported by the OS, Win32++ produces a frame without
+rebars.
+
+Win32++ is Unicode compliant and can therefore be used to develop Unicode
+applications. Users are advised that older operating systems (namely Win95,
+Win98 and WinME) don't support Unicode applications.
+
+Win32++ supports 64bit compilers, and can be used to develop 64bit code.
+
+Directory Structure
+===================
+When extracting the files from the zip archive, be sure to preserve the
+directory structure. The directory structure will typically look like this:
+
+.\include
+.\new projects
+.\output
+.\samples
+.\tools
+.\tutorials
+.\WCE samples
+
+The files which form the Win32++ library are contained in the include
+subdirectory.
+
+Components of Win32++
+=====================
+
+ Files | Classes | Operating Systems | Description
+==================+==================+===================+=====================
+controls.h | CAnimation | Win32, Win64 | Adds support for the
+ | CComboBox | and WinCE | following controls:
+ | CComboBoxEx | | Animation, ComboBox,
+ | CProgressBar | | ComboBoxEx, Progress
+ | CScrollBar | | bar, Scroll bar,
+ | CSlider | | Slider, Spin button.
+ | CSpinButton | |
+------------------+------------------+-------------------+---------------------
+dialog.h | CDialog | Win32, Win64 | Adds dialog support.
+ | CResizer | WinCE for CDialog |
+------------------+------------------+-------------------+---------------------
+docking.h | CDocker | Win32, Win64 | Adds support for
+ | CDockContainer | | docking windows and
+ | | | splitter windows.
+------------------+------------------+-------------------+---------------------
+frame.h | CMenubar | Win32, Win64 | Adds support for
+ | CFrame | | frames. Frames use a
+ | | | toolbar and menubar
+ | | | inside a rebar, and
+ | | | a statusbar.
+------------------+------------------+-------------------+---------------------
+gdi.h | CDC | Win32, Win64 | A helper class for
+ | CBitmap | and WinCE | GDI graphics.
+ | CBrush | |
+ | CFont | |
+ | CPalette | |
+ | CPen | |
+ | CRgn | |
+------------------+------------------+-------------------+---------------------
+listView.h | CListView | Win32, Win64 | Adds support for a
+ | | and WinCE | ListView control.
+------------------+------------------+-------------------+---------------------
+mdi.h | CMDIFrame | Win32, Win64 | Adds support for MDI
+ | CMDIChild | | frames.
+------------------+------------------+-------------------+---------------------
+propertysheet.h | CPropertySheet | Win32, Win64 | Adds property sheet
+ | CPropertyPage | and WinCE | support.
+------------------+------------------+-------------------+---------------------
+rebar.h | CRebar | Win32, Win64 | Adds support for a
+ | | and WinCE | Rebar control.
+------------------+------------------+-------------------+---------------------
+ribbon.h | CRibbon | Win32, Win64 | Adds support for the
+ | CRibbonFrame | | Windows 7 ribbon.
+------------------+------------------+-------------------+---------------------
+shared_ptr.h | Shared_Ptr | Win32, Win64, | Add a smart pointer
+ | | and WinCE | for use in vectors.
+------------------+------------------+-------------------+---------------------
+socket.h | CSocket | Win32, Win64 | Adds network
+ | | and WinCE | support.
+------------------+------------------+-------------------+---------------------
+splitter.h | CSplitter | Win32, Win64 | Adds splitter support
+ | | | (depreciated)
+------------------+------------------+-------------------+----------------------
+statusbar.h | CStatusbar | Win32, Win64 | Adds support for a
+ | | and WinCE | Status bar control.
+------------------+------------------+-------------------+---------------------
+stdcontrols.h | CButton | Win32, Win64 | Adds support for
+ | CEdit | and WinCE | Button, Edit,
+ | CListBox | | ListBox and Static
+ | CStatic | | controls.
+------------------+------------------+-------------------+---------------------
+tab.h | CTab | Win32, Win64 | Adds support for tab
+ | CMDITab | | controls, and MDI
+ | | | tab windows.
+------------------+------------------+-------------------+---------------------
+taskdialog.h | CTaskDialog | Win32, Win64 | Adds support for tab
+ | | | task dialogs.
+------------------+------------------+-------------------+---------------------
+thread.h | CThread | Win32, Win64 | Adds support for
+ | | and WinCE | threads.
+------------------+------------------+-------------------+---------------------
+toolbar.h | CToolbar | Win32, Win64 | Adds support for a
+ | | and WinCE | Toolbar control.
+------------------+------------------+-------------------+---------------------
+treeview.h | CTreeView | Win32, Win64 | Adds support for a
+ | | and WinCE | TreeView control.
+------------------+------------------+-------------------+---------------------
+wceframe.h | CWceFrame | WinCE only | Adds support for
+ | CCmdbar | | frames in WinCE.
+------------------+------------------+-------------------+---------------------
+webbrowser.h | CAXWindow | Win32, Win64 | Adds support for a
+ | CWebBrowser | and WinCE | ActiveX container and
+ | | | a WebBrowser window.
+------------------+------------------+-------------------+---------------------
+wincore.h | CCriticalSection | Win32, Win64, | The core set of
+ | CWinApp | and WinCE | classes required for
+ | CWinException | | all Win32++
+ | CWnd | | applications.
+------------------+------------------+-------------------+---------------------
+winutils.h | CPoint | Win32, Win64, | Additional utility
+ | CRect | and WinCE | classes.
+ | CSize | |
+------------------+------------------+-------------------+---------------------
+
+Refer to the help documentation that ships with Win32++ for more information on
+using Win32++. \ No newline at end of file
diff --git a/mmc_updater/depends/win32cpp/listview.h b/mmc_updater/depends/win32cpp/listview.h
new file mode 100644
index 00000000..810e7627
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/listview.h
@@ -0,0 +1,867 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+
+#ifndef _WIN32XX_LISTVIEW_H_
+#define _WIN32XX_LISTVIEW_H_
+
+#include "wincore.h"
+#include "commctrl.h"
+
+namespace Win32xx
+{
+
+ class CListView : public CWnd
+ {
+ public:
+ CListView() {}
+ virtual ~CListView() {}
+ virtual void PreRegisterClass(WNDCLASS &wc);
+
+ // Attributes
+ CSize ApproximateViewRect(CSize sz = CSize(-1, -1), int iCount = -1) const;
+ COLORREF GetBkColor( ) const;
+ BOOL GetBkImage( LVBKIMAGE& lvbkImage ) const;
+ UINT GetCallbackMask( ) const;
+ BOOL GetCheckState( UINT nItem ) const;
+ BOOL GetColumn( int iCol, LVCOLUMN& Column ) const;
+ BOOL GetColumnOrderArray( LPINT piArray, int iCount = -1 );
+ int GetColumnWidth( int iCol ) const;
+ int GetCountPerPage( ) const;
+ HWND GetEditControl( ) const;
+ DWORD GetExtendedStyle( ) const;
+ HWND GetHeader( ) const;
+ HCURSOR GetHotCursor( );
+ int GetHotItem( ) const;
+ DWORD GetHoverTime( ) const;
+ HIMAGELIST GetImageList( int nImageType ) const;
+ BOOL GetItem( LVITEM& lvItem ) const;
+ int GetItemCount( ) const;
+ DWORD_PTR GetItemData( int iItem ) const;
+ BOOL GetItemPosition( int iItem, CPoint& pt ) const;
+ BOOL GetItemRect( int iItem, CRect& rc, UINT nCode ) const;
+ UINT GetItemState( int iItem, UINT nMask ) const;
+ tString GetItemText( int iItem, int iSubItem, UINT nTextMax = 260 ) const;
+ int GetNextItem( int iItem, int iFlags ) const;
+ UINT GetNumberOfWorkAreas( ) const;
+ BOOL GetOrigin( CPoint& pt ) const;
+ UINT GetSelectedCount( ) const;
+ int GetSelectionMark( ) const;
+ int GetStringWidth( LPCTSTR pszString ) const;
+ BOOL GetSubItemRect( int iItem, int iSubItem, int iCode, CRect& rc ) const;
+ COLORREF GetTextBkColor( ) const;
+ COLORREF GetTextColor( ) const;
+ HWND GetToolTips( ) const;
+ int GetTopIndex( ) const;
+ BOOL GetViewRect( CRect& rc ) const;
+ void GetWorkAreas( int iWorkAreas, LPRECT pRectArray ) const;
+ BOOL SetBkColor( COLORREF clrBk ) const;
+ BOOL SetBkImage( LVBKIMAGE& plvbkImage ) const;
+ BOOL SetCallbackMask( UINT nMask ) const;
+ void SetCheckState( int iItem, BOOL fCheck = TRUE ) const;
+ BOOL SetColumn( int iCol, const LVCOLUMN& pColumn ) const;
+ BOOL SetColumnOrderArray( int iCount, LPINT piArray ) const;
+ BOOL SetColumnWidth( int iCol, int cx ) const;
+ DWORD SetExtendedStyle( DWORD dwNewStyle ) const;
+ HCURSOR SetHotCursor( HCURSOR hCursor ) const;
+ int SetHotItem( int nIndex ) const;
+ DWORD SetHoverTime( DWORD dwHoverTime = (DWORD)-1 ) const;
+ CSize SetIconSpacing( int cx, int cy ) const;
+ CSize SetIconSpacing( CSize sz ) const;
+ HIMAGELIST SetImageList( HIMAGELIST himl, int iImageListType ) const;
+ BOOL SetItem( LVITEM& pItem ) const;
+ BOOL SetItem( int iItem, int iSubItem, UINT nMask, LPCTSTR pszText, int iImage,
+ UINT nState, UINT nStateMask, LPARAM lParam, int iIndent ) const;
+ void SetItemCount( int iCount ) const;
+ void SetItemCountEx( int iCount, DWORD dwFlags = LVSICF_NOINVALIDATEALL ) const;
+ BOOL SetItemData( int iItem, DWORD_PTR dwData ) const;
+ BOOL SetItemPosition( int iItem, CPoint& pt ) const;
+ BOOL SetItemState( int iItem, LVITEM& Item ) const;
+ void SetItemState( int iItem, UINT nState, UINT nMask ) const;
+ void SetItemText( int iItem, int iSubItem, LPCTSTR pszText ) const;
+ int SetSelectionMark( int iIndex ) const;
+ BOOL SetTextBkColor( COLORREF clrBkText ) const;
+ BOOL SetTextColor( COLORREF clrText ) const;
+ HWND SetToolTips( HWND hWndToolTip ) const;
+ void SetWorkAreas( int nWorkAreas, CRect& pRectArray ) const;
+ int SubItemHitTest( LVHITTESTINFO& htInfo ) const;
+
+ // Operations
+ BOOL Arrange( UINT nCode ) const;
+ HIMAGELIST CreateDragImage( int iItem, CPoint& pt ) const;
+ BOOL DeleteAllItems( ) const;
+ BOOL DeleteColumn( int iCol ) const;
+ BOOL DeleteItem( int iItem ) const;
+ HWND EditLabel( int iItem ) const;
+ BOOL EnsureVisible( int iItem, BOOL fPartialOK ) const;
+ int FindItem( LVFINDINFO& FindInfo, int iStart = -1 ) const;
+ int HitTest( LVHITTESTINFO& HitTestInfo ) const;
+ int HitTest( CPoint pt, UINT* pFlags = NULL ) const;
+ int InsertColumn( int iCol, const LVCOLUMN& pColumn ) const;
+ int InsertColumn( int iCol, LPCTSTR pszColumnHeading, int iFormat = LVCFMT_LEFT,
+ int iWidth = -1, int iSubItem = -1 ) const;
+ int InsertItem( const LVITEM& pItem ) const;
+ int InsertItem( int iItem, LPCTSTR pszText ) const;
+ int InsertItem( int iItem, LPCTSTR pszText, int iImage ) const;
+ BOOL RedrawItems( int iFirst, int iLast ) const;
+ BOOL Scroll( CSize sz ) const;
+ BOOL SortItems( PFNLVCOMPARE pfnCompare, DWORD_PTR dwData ) const;
+ BOOL Update( int iItem ) const;
+
+ private:
+ CListView(const CListView&); // Disable copy construction
+ CListView& operator = (const CListView&); // Disable assignment operator
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ inline void CListView::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = WC_LISTVIEW;
+ }
+
+ inline CSize CListView::ApproximateViewRect(CSize sz /*= CSize(-1, -1)*/, int iCount /* = -1*/) const
+ // Calculates the approximate width and height required to display a given number of items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CSize( ListView_ApproximateViewRect( m_hWnd, sz.cx, sz.cy, iCount ) );
+ }
+
+ inline COLORREF CListView::GetBkColor( ) const
+ // Retrieves the background color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetBkColor( m_hWnd );
+ }
+
+ inline BOOL CListView::GetBkImage( LVBKIMAGE& lvbkImage ) const
+ // Retrieves the background image in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetBkImage( m_hWnd, &lvbkImage );
+ }
+
+ inline UINT CListView::GetCallbackMask( ) const
+ // Retrieves the callback mask for a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetCallbackMask( m_hWnd );
+ }
+
+ inline BOOL CListView::GetCheckState( UINT nItem ) const
+ // Determines if an item in a list-view control is selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetCheckState( m_hWnd, nItem );
+ }
+
+ inline BOOL CListView::GetColumn( int iCol, LVCOLUMN& Column ) const
+ // Retrieves the attributes of a list-view control's column.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetColumn( m_hWnd, iCol, &Column );
+ }
+
+ inline BOOL CListView::GetColumnOrderArray( LPINT piArray, int iCount /*= -1*/ )
+ // Retrieves the current left-to-right order of columns in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetColumnOrderArray( m_hWnd, iCount, piArray );
+ }
+
+ inline int CListView::GetColumnWidth( int iCol ) const
+ // Retrieves the width of a column in report or list view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetColumnWidth( m_hWnd, iCol );
+ }
+
+ inline int CListView::GetCountPerPage( ) const
+ // Calculates the number of items that can fit vertically in the visible area of a
+ // list-view control when in list or report view. Only fully visible items are counted.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetCountPerPage( m_hWnd );
+ }
+
+ inline HWND CListView::GetEditControl( ) const
+ // Retrieves the handle to the edit control being used to edit a list-view item's text.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetEditControl( m_hWnd );
+ }
+
+ inline DWORD CListView::GetExtendedStyle( ) const
+ // Retrieves the extended styles that are currently in use for a given list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetExtendedListViewStyle( m_hWnd );
+ }
+
+ inline HWND CListView::GetHeader( ) const
+ // Retrieves the handle to the header control used by a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetHeader( m_hWnd );
+ }
+
+ inline HCURSOR CListView::GetHotCursor( )
+ // Retrieves the HCURSOR used when the pointer is over an item while hot tracking is enabled.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetHotCursor( m_hWnd );
+ }
+
+ inline int CListView::GetHotItem( ) const
+ // Retrieves the index of the hot item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetHotItem( m_hWnd );
+ }
+
+ inline DWORD CListView::GetHoverTime( ) const
+ // Retrieves the amount of time that the mouse cursor must hover over an item before it is selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetHoverTime( m_hWnd );
+ }
+
+ inline HIMAGELIST CListView::GetImageList( int nImageType ) const
+ // Retrieves the handle to an image list used for drawing list-view items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetImageList( m_hWnd, nImageType );
+ }
+
+ inline BOOL CListView::GetItem( LVITEM& Item ) const
+ // Retrieves some or all of a list-view item's attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetItem( m_hWnd, &Item );
+ }
+
+ inline int CListView::GetItemCount( ) const
+ // Retrieves the number of items in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetItemCount( m_hWnd );
+ }
+
+ inline DWORD_PTR CListView::GetItemData( int iItem ) const
+ // Retrieves the value(lParam) specific to the item.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.mask = LVIF_PARAM;
+ ListView_GetItem(m_hWnd, &lvi);
+ return lvi.lParam;
+ }
+
+ inline BOOL CListView::GetItemPosition( int iItem, CPoint& pt ) const
+ // Retrieves the position of a list-view item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetItemPosition( m_hWnd, iItem, &pt );
+ }
+
+ inline BOOL CListView::GetItemRect( int iItem, CRect& rc, UINT nCode ) const
+ // Retrieves the bounding rectangle for all or part of an item in the current view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetItemRect( m_hWnd, iItem, &rc, nCode );
+ }
+
+ inline UINT CListView::GetItemState( int iItem, UINT nMask ) const
+ // Retrieves the state of a list-view item.
+
+ // Possible values of nMask:
+ // LVIS_CUT The item is marked for a cut-and-paste operation.
+ // LVIS_DROPHILITED The item is highlighted as a drag-and-drop target.
+ // LVIS_FOCUSED The item has the focus, so it is surrounded by a standard focus rectangle.
+ // LVIS_SELECTED The item is selected.
+ // LVIS_OVERLAYMASK Use this mask to retrieve the item's overlay image index.
+ // LVIS_STATEIMAGEMASK Use this mask to retrieve the item's state image index.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetItemState( m_hWnd, iItem, nMask );
+ }
+
+ inline tString CListView::GetItemText( int iItem, int iSubItem, UINT nTextMax /* = 260 */ ) const
+ // Retrieves the text of a list-view item.
+ // Note: Although the list-view control allows any length string to be stored
+ // as item text, only the first 260 characters are displayed.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ tString t;
+ if (nTextMax > 0)
+ {
+ std::vector<TCHAR> vTChar(nTextMax +1, _T('\0'));
+ TCHAR* pszText = &vTChar.front();
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.iSubItem = iSubItem;
+ lvi.mask = LVIF_TEXT;
+ lvi.cchTextMax = nTextMax;
+ lvi.pszText = pszText;
+ ListView_GetItem( m_hWnd, &lvi );
+ t = lvi.pszText;
+ }
+ return t;
+ }
+
+ inline int CListView::GetNextItem( int iItem, int iFlags ) const
+ // Searches for a list-view item that has the specified properties and
+ // bears the specified relationship to a specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetNextItem( m_hWnd, iItem, iFlags );
+ }
+
+ inline UINT CListView::GetNumberOfWorkAreas( ) const
+ // Retrieves the working areas from a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ UINT nWorkAreas = 0;
+ ListView_GetWorkAreas( m_hWnd, nWorkAreas, NULL );
+ return nWorkAreas;
+ }
+
+ inline BOOL CListView::GetOrigin( CPoint& pt ) const
+ // Retrieves the current view origin for a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetOrigin( m_hWnd, &pt );
+ }
+
+ inline UINT CListView::GetSelectedCount( ) const
+ // Determines the number of selected items in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)::SendMessage( m_hWnd, LVM_GETSELECTEDCOUNT, 0L, 0L );
+ }
+
+ inline int CListView::GetSelectionMark( ) const
+ // Retrieves the selection mark from a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)::SendMessage( m_hWnd, LVM_GETSELECTIONMARK, 0L, 0L );
+ }
+
+ inline int CListView::GetStringWidth( LPCTSTR pszString ) const
+ // Determines the width of a specified string using the specified list-view control's current font.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)::SendMessage( m_hWnd, LVM_GETSTRINGWIDTH, 0L, (LPARAM)pszString );
+ }
+
+ inline BOOL CListView::GetSubItemRect( int iItem, int iSubItem, int iCode, CRect& rc ) const
+ // Retrieves information about the rectangle that surrounds a subitem in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetSubItemRect( m_hWnd, iItem, iSubItem, iCode, &rc );
+ }
+
+ inline COLORREF CListView::GetTextBkColor( ) const
+ // Retrieves the text background color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetTextBkColor( m_hWnd );
+ }
+
+ inline COLORREF CListView::GetTextColor( ) const
+ // Retrieves the text color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetTextColor( m_hWnd );
+ }
+
+ inline HWND CListView::GetToolTips( ) const
+ // Retrieves the ToolTip control that the list-view control uses to display ToolTips.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetToolTips( m_hWnd );
+ }
+
+ inline int CListView::GetTopIndex( ) const
+ // Retrieves the index of the topmost visible item when in list or report view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetTopIndex( m_hWnd );
+ }
+
+ inline BOOL CListView::GetViewRect( CRect& rc ) const
+ // Retrieves the bounding rectangle of all items in the list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_GetViewRect( m_hWnd, &rc );
+ }
+
+ inline void CListView::GetWorkAreas( int iWorkAreas, LPRECT pRectArray ) const
+ // Retrieves the working areas from a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_GetWorkAreas( m_hWnd, iWorkAreas, pRectArray );
+ }
+
+ inline BOOL CListView::SetBkColor( COLORREF clrBk ) const
+ // Sets the background color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetBkColor( m_hWnd, clrBk );
+ }
+
+ inline BOOL CListView::SetBkImage( LVBKIMAGE& lvbkImage ) const
+ // Sets the background image in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetBkImage( m_hWnd, &lvbkImage );
+ }
+
+ inline BOOL CListView::SetCallbackMask( UINT nMask ) const
+ // Changes the callback mask for a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetCallbackMask( m_hWnd, nMask );
+ }
+
+ inline void CListView::SetCheckState( int iItem, BOOL fCheck /*= TRUE*/ ) const
+ // Used to select or deselect an item in a list-view control.
+ // This macro should only be used for list-view controls with the LVS_EX_CHECKBOXES style.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetItemState(m_hWnd, iItem, INDEXTOSTATEIMAGEMASK((fCheck==TRUE)?2:1),LVIS_STATEIMAGEMASK);
+ }
+
+ inline BOOL CListView::SetColumn( int iCol, const LVCOLUMN& Column ) const
+ // Sets the attributes of a list-view column.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetColumn( m_hWnd, iCol, &Column );
+ }
+
+ inline BOOL CListView::SetColumnOrderArray( int iCount, LPINT piArray ) const
+ // Sets the left-to-right order of columns in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetColumnOrderArray( m_hWnd, iCount, piArray );
+ }
+
+ inline BOOL CListView::SetColumnWidth( int iCol, int cx ) const
+ // Used to change the width of a column in report view or the width of all columns in list-view mode.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetColumnWidth( m_hWnd, iCol, cx );
+ }
+
+ inline DWORD CListView::SetExtendedStyle( DWORD dwNewStyle ) const
+ // Sets extended styles for list-view controls.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetExtendedListViewStyle( m_hWnd, dwNewStyle );
+ }
+
+ inline HCURSOR CListView::SetHotCursor( HCURSOR hCursor ) const
+ // Sets the HCURSOR that the list-view control uses when the pointer is
+ // over an item while hot tracking is enabled.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetHotCursor( m_hWnd, hCursor );
+ }
+
+ inline int CListView::SetHotItem( int nIndex ) const
+ // Sets the hot item in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetHotItem( m_hWnd, nIndex );
+ }
+
+ inline DWORD CListView::SetHoverTime( DWORD dwHoverTime /*= (DWORD)-1*/ ) const
+ // Sets the amount of time that the mouse cursor must hover over an item before it is selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetHoverTime( m_hWnd, dwHoverTime );
+ }
+
+ inline CSize CListView::SetIconSpacing( int cx, int cy ) const
+ // Sets the spacing between icons in list-view controls set to the LVS_ICON style.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CSize( ListView_SetIconSpacing( m_hWnd, cx, cy ) );
+ }
+
+ inline CSize CListView::SetIconSpacing( CSize sz ) const
+ // Sets the spacing between icons in list-view controls set to the LVS_ICON style.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CSize( ListView_SetIconSpacing( m_hWnd, sz.cx, sz.cy ) );
+ }
+
+ inline HIMAGELIST CListView::SetImageList( HIMAGELIST himl, int iImageListType ) const
+ // Assigns an image list to a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetImageList( m_hWnd, himl, iImageListType );
+ }
+
+ inline BOOL CListView::SetItem( LVITEM& Item ) const
+ // Sets some or all of a list-view item's attributes.
+
+ // The declaration for TVITEM:
+ // typedef struct _LVITEM {
+ // UINT mask;
+ // int iItem;
+ // int iSubItem;
+ // UINT state;
+ // UINT stateMask;
+ // LPTSTR pszText;
+ // int cchTextMax;
+ // int iImage;
+ // LPARAM lParam;
+ // } LVITEM, *LVITEM&;
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetItem( m_hWnd, &Item );
+ }
+
+ inline BOOL CListView::SetItem( int iItem, int iSubItem, UINT nMask, LPCTSTR pszText, int iImage,
+ UINT nState, UINT nStateMask, LPARAM lParam, int iIndent ) const
+ // Sets some or all of a list-view item's attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.iSubItem = iSubItem;
+ lvi.mask = nMask;
+ lvi.pszText = (LPTSTR)pszText;
+ lvi.iImage = iImage;
+ lvi.state = nState;
+ lvi.stateMask = nStateMask;
+ lvi.lParam = lParam;
+ lvi.iIndent = iIndent;
+
+ return ListView_SetItem( m_hWnd, &lvi);
+ }
+
+ inline void CListView::SetItemCount( int iCount ) const
+ // Causes the list-view control to allocate memory for the specified number of items.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetItemCount( m_hWnd, iCount );
+ }
+
+ inline void CListView::SetItemCountEx( int iCount, DWORD dwFlags /*= LVSICF_NOINVALIDATEALL*/ ) const
+ // Sets the virtual number of items in a virtual list view.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetItemCountEx( m_hWnd, iCount, dwFlags );
+ }
+
+ inline BOOL CListView::SetItemData( int iItem, DWORD_PTR dwData ) const
+ // Sets the value(lParam) specific to the item.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.lParam = dwData;
+ lvi.mask = LVIF_PARAM;
+ return ListView_SetItem(m_hWnd, &lvi);
+ }
+
+ inline BOOL CListView::SetItemPosition( int iItem, CPoint& pt ) const
+ // Moves an item to a specified position in a list-view control (in icon or small icon view).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetItemPosition( m_hWnd, iItem, pt.x, pt.y );
+ }
+
+ inline BOOL CListView::SetItemState( int iItem, LVITEM& Item ) const
+ // Changes the state of an item in a list-view control.
+
+ // Possible values of nMask:
+ // LVIS_CUT The item is marked for a cut-and-paste operation.
+ // LVIS_DROPHILITED The item is highlighted as a drag-and-drop target.
+ // LVIS_FOCUSED The item has the focus, so it is surrounded by a standard focus rectangle.
+ // LVIS_SELECTED The item is selected.
+ // LVIS_OVERLAYMASK Use this mask to retrieve the item's overlay image index.
+ // LVIS_STATEIMAGEMASK Use this mask to retrieve the item's state image index.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, (WPARAM)iItem, (LPARAM)&Item);
+ }
+
+ inline void CListView::SetItemState( int iItem, UINT nState, UINT nMask ) const
+ // Changes the state of an item in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetItemState(m_hWnd, iItem, nState, nMask);
+ }
+
+ inline void CListView::SetItemText( int iItem, int iSubItem, LPCTSTR pszText ) const
+ // Sets the text color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetItemText(m_hWnd, iItem, iSubItem, (LPTSTR)pszText );
+ }
+
+ inline int CListView::SetSelectionMark( int iIndex ) const
+ // Sets the selection mark in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetSelectionMark( m_hWnd, iIndex );
+ }
+
+ inline BOOL CListView::SetTextBkColor( COLORREF clrBkText ) const
+ // Sets the background color of text in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetTextBkColor( m_hWnd, clrBkText );
+ }
+
+ inline BOOL CListView::SetTextColor( COLORREF clrText ) const
+ // Sets the text color of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SetTextColor( m_hWnd, clrText );
+ }
+
+ inline HWND CListView::SetToolTips( HWND hWndToolTip ) const
+ // Sets the ToolTip control that the list-view control will use to display ToolTips.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HWND)::SendMessage(m_hWnd, LVM_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L);
+ }
+
+ inline void CListView::SetWorkAreas( int nWorkAreas, CRect& pRectArray ) const
+ // Sets the working area within a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ ListView_SetWorkAreas( m_hWnd, nWorkAreas, pRectArray );
+ }
+
+ inline int CListView::SubItemHitTest( LVHITTESTINFO& htInfo ) const
+ // Determines which list-view item or subitem is located at a given position.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SubItemHitTest( m_hWnd, &htInfo );
+ }
+
+ // Operations
+
+ inline BOOL CListView::Arrange( UINT nCode ) const
+ // Arranges items in icon view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_Arrange( m_hWnd, nCode );
+ }
+
+ inline HIMAGELIST CListView::CreateDragImage( int iItem, CPoint& pt ) const
+ // Creates a drag image list for the specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_CreateDragImage( m_hWnd, iItem, &pt );
+ }
+
+ inline BOOL CListView::DeleteAllItems( ) const
+ // ListView_DeleteAllItems
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_DeleteAllItems( m_hWnd );
+ }
+
+ inline BOOL CListView::DeleteColumn( int iCol ) const
+ // Removes a column from a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_DeleteColumn( m_hWnd, iCol );
+ }
+
+ inline BOOL CListView::DeleteItem( int iItem ) const
+ // Removes an item from a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_DeleteItem( m_hWnd, iItem );
+ }
+
+ inline HWND CListView::EditLabel( int iItem ) const
+ // Begins in-place editing of the specified list-view item's text.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_EditLabel( m_hWnd, iItem );
+ }
+
+ inline BOOL CListView::EnsureVisible( int iItem, BOOL fPartialOK ) const
+ // Ensures that a list-view item is either entirely or partially visible,
+ // scrolling the list-view control if necessary.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(LVM_ENSUREVISIBLE, (WPARAM)iItem, (LPARAM)fPartialOK );
+ }
+
+ inline int CListView::FindItem( LVFINDINFO& FindInfo, int iStart /*= -1*/ ) const
+ // Searches for a list-view item with the specified characteristics.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_FindItem( m_hWnd, iStart, &FindInfo );
+ }
+
+ inline int CListView::HitTest( LVHITTESTINFO& HitTestInfo ) const
+ // Determines which list-view item, if any, is at a specified position.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_HitTest( m_hWnd, &HitTestInfo );
+ }
+
+ inline int CListView::HitTest( CPoint pt, UINT* pFlags /*= NULL*/ ) const
+ // Determines which list-view item, if any, is at a specified position.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVHITTESTINFO hti = {0};
+ hti.flags = *pFlags;
+ hti.pt = pt;
+ return ListView_HitTest( m_hWnd, &hti );
+ }
+
+ inline int CListView::InsertColumn( int iCol, const LVCOLUMN& Column ) const
+ // Inserts a new column in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_InsertColumn( m_hWnd, iCol, &Column );
+ }
+
+ inline int CListView::InsertColumn( int iCol, LPCTSTR pszColumnHeading, int iFormat /*= LVCFMT_LEFT*/,
+ int iWidth /*= -1*/, int iSubItem /*= -1*/ ) const
+ // Inserts a new column in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVCOLUMN lvc = {0};
+ lvc.mask = LVCF_TEXT|LVCF_ORDER|LVCF_FMT;
+ if (-1 != iWidth)
+ {
+ lvc.mask |= LVCF_WIDTH;
+ lvc.cx = iWidth;
+ }
+ if (-1 != iSubItem)
+ {
+ lvc.mask |= LVCF_SUBITEM;
+ lvc.iSubItem = iSubItem;
+ }
+
+ lvc.iOrder = iCol;
+ lvc.pszText = (LPTSTR)pszColumnHeading;
+ lvc.fmt = iFormat;
+ lvc.iSubItem = iSubItem;
+ return ListView_InsertColumn( m_hWnd, iCol, &lvc );
+ }
+
+ inline int CListView::InsertItem( const LVITEM& Item ) const
+ // Inserts a new item in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_InsertItem( m_hWnd, &Item );
+ }
+
+ inline int CListView::InsertItem( int iItem, LPCTSTR pszText ) const
+ // Inserts a new item in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.pszText = (LPTSTR)pszText;
+ lvi.mask = LVIF_TEXT;
+ return ListView_InsertItem( m_hWnd, &lvi );
+ }
+
+ inline int CListView::InsertItem( int iItem, LPCTSTR pszText, int iImage ) const
+ // Inserts a new item in a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ LVITEM lvi = {0};
+ lvi.iItem = iItem;
+ lvi.pszText = (LPTSTR)pszText;
+ lvi.iImage = iImage;
+ lvi.mask = LVIF_TEXT | LVIF_IMAGE;
+ return ListView_InsertItem( m_hWnd, &lvi );
+ }
+
+ inline BOOL CListView::RedrawItems( int iFirst, int iLast ) const
+ // Forces a list-view control to redraw a range of items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_RedrawItems( m_hWnd, iFirst, iLast );
+ }
+
+ inline BOOL CListView::Scroll( CSize sz ) const
+ // Scrolls the content of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_Scroll( m_hWnd, sz.cx, sz.cy );
+ }
+
+ inline BOOL CListView::SortItems( PFNLVCOMPARE pfnCompare, DWORD_PTR dwData ) const
+ // Uses an application-defined comparison function to sort the items of a list-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_SortItems( m_hWnd, pfnCompare, dwData );
+ }
+
+ inline BOOL CListView::Update( int iItem ) const
+ // Updates a list-view item. If the list-view control has the LVS_AUTOARRANGE style,
+ // the list-view control is rearranged.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ListView_Update( m_hWnd, iItem );
+ }
+
+} // namespace Win32xx
+
+#endif // #ifndef _WIN32XX_LISTVIEW_H_
+
diff --git a/mmc_updater/depends/win32cpp/mdi.h b/mmc_updater/depends/win32cpp/mdi.h
new file mode 100644
index 00000000..0aa35ffc
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/mdi.h
@@ -0,0 +1,783 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// mdi.h
+// Declaration of the CMDIChild and CMDIFrame classes
+
+// The classes defined here add MDI frames support to Win32++. MDI
+// (Multiple Document Interface) frames host one or more child windows. The
+// child windows hosted by a MDI frame can be different types. For example,
+// some MDI child windows could be used to edit text, while others could be
+// used to display a bitmap. Four classes are defined here to support MDI
+// frames:
+
+
+// 1) CMDIFrame. This class inherits from CFrame, and adds the functionality
+// required by MDI frames. It keeps track of the MDI children created and
+// destroyed, and adjusts the menu when a MDI child is activated. Use the
+// AddMDIChild function to add MDI child windows to the MDI frame. Inherit
+// from CMDIFrame to create your own MDI frame.
+//
+// 2) CMDIChild: All MDI child windows (ie. CWnd classes) should inherit from
+// this class. Each MDI child type can have a different frame menu.
+
+// Use the MDIFrame generic application as the starting point for your own MDI
+// frame applications.
+// Refer to the MDIDemo sample for an example on how to use these classes to
+// create a MDI frame application with different types of MDI child windows.
+
+
+#ifndef _WIN32XX_MDI_H_
+#define _WIN32XX_MDI_H_
+
+#include "frame.h"
+#include <vector>
+
+
+
+namespace Win32xx
+{
+ class CMDIChild;
+ class CMDIFrame;
+ typedef Shared_Ptr<CMDIChild> MDIChildPtr;
+
+ /////////////////////////////////////
+ // Declaration of the CMDIChild class
+ //
+ class CMDIChild : public CWnd
+ {
+ friend class CMDIFrame;
+ public:
+ CMDIChild();
+ virtual ~CMDIChild();
+
+ // These are the functions you might wish to override
+ virtual HWND Create(CWnd* pParent = NULL);
+ virtual void RecalcLayout();
+
+ // These functions aren't virtual, and shouldn't be overridden
+ void SetHandles(HMENU MenuName, HACCEL AccelName);
+ CMDIFrame* GetMDIFrame() const;
+ CWnd* GetView() const {return m_pView;}
+ void SetView(CWnd& pwndView);
+ void MDIActivate() const;
+ void MDIDestroy() const;
+ void MDIMaximize() const;
+ void MDIRestore() const;
+
+ protected:
+ // Its unlikely you would need to override these functions
+ virtual LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual void OnCreate();
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CMDIChild(const CMDIChild&); // Disable copy construction
+ CMDIChild& operator = (const CMDIChild&); // Disable assignment operator
+
+ CWnd* m_pView; // pointer to the View CWnd object
+ HMENU m_hChildMenu;
+ HACCEL m_hChildAccel;
+ };
+
+
+ /////////////////////////////////////
+ // Declaration of the CMDIFrame class
+ //
+ class CMDIFrame : public CFrame
+ {
+ friend class CMDIChild; // CMDIChild uses m_hOrigMenu
+ typedef Shared_Ptr<CMDIChild> MDIChildPtr;
+
+ public:
+ class CMDIClient : public CWnd // a nested class within CMDIFrame
+ {
+ public:
+ CMDIClient() {}
+ virtual ~CMDIClient() {}
+ virtual HWND Create(CWnd* pParent = NULL);
+ virtual LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ CMDIFrame* GetMDIFrame() const { return (CMDIFrame*)GetParent(); }
+
+ private:
+ CMDIClient(const CMDIClient&); // Disable copy construction
+ CMDIClient& operator = (const CMDIClient&); // Disable assignment operator
+ };
+
+
+ CMDIFrame();
+ virtual ~CMDIFrame() {}
+
+ virtual CMDIChild* AddMDIChild(MDIChildPtr pMDIChild);
+ virtual CMDIClient& GetMDIClient() const { return (CMDIClient&)m_MDIClient; }
+ virtual BOOL IsMDIFrame() const { return TRUE; }
+ virtual void RemoveMDIChild(HWND hWnd);
+ virtual BOOL RemoveAllMDIChildren();
+ virtual void UpdateCheckMarks();
+
+ // These functions aren't virtual, so don't override them
+ std::vector <MDIChildPtr>& GetAllMDIChildren() {return m_vMDIChild;}
+ CMDIChild* GetActiveMDIChild() const;
+ BOOL IsMDIChildMaxed() const;
+ void MDICascade(int nType = 0) const;
+ void MDIIconArrange() const;
+ void MDIMaximize() const;
+ void MDINext() const;
+ void MDIPrev() const;
+ void MDIRestore() const;
+ void MDITile(int nType = 0) const;
+ void SetActiveMDIChild(CMDIChild* pChild);
+
+ protected:
+ // These are the functions you might wish to override
+ virtual void OnClose();
+ virtual void OnViewStatusBar();
+ virtual void OnViewToolBar();
+ virtual void OnWindowPosChanged();
+ virtual void RecalcLayout();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CMDIFrame(const CMDIFrame&); // Disable copy construction
+ CMDIFrame& operator = (const CMDIFrame&); // Disable assignment operator
+ void AppendMDIMenu(HMENU hMenuWindow);
+ LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void UpdateFrameMenu(HMENU hMenu);
+
+ CMDIClient m_MDIClient;
+ std::vector <MDIChildPtr> m_vMDIChild;
+ HWND m_hActiveMDIChild;
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ /////////////////////////////////////
+ // Definitions for the CMDIFrame class
+ //
+ inline CMDIFrame::CMDIFrame() : m_hActiveMDIChild(NULL)
+ {
+ SetView(GetMDIClient());
+ }
+
+ inline CMDIChild* CMDIFrame::AddMDIChild(MDIChildPtr pMDIChild)
+ {
+ assert(NULL != pMDIChild.get()); // Cannot add Null MDI Child
+
+ m_vMDIChild.push_back(pMDIChild);
+ pMDIChild->Create(GetView());
+
+ return pMDIChild.get();
+ }
+
+ inline void CMDIFrame::AppendMDIMenu(HMENU hMenuWindow)
+ {
+ // Adds the additional menu items the the "Window" submenu when
+ // MDI child windows are created
+
+ if (!IsMenu(hMenuWindow))
+ return;
+
+ // Delete previously appended items
+ int nItems = ::GetMenuItemCount(hMenuWindow);
+ UINT uLastID = ::GetMenuItemID(hMenuWindow, --nItems);
+ if ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10))
+ {
+ while ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10))
+ {
+ ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION);
+ uLastID = ::GetMenuItemID(hMenuWindow, --nItems);
+ }
+ //delete the separator too
+ ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION);
+ }
+
+ int nWindow = 0;
+
+ // Allocate an iterator for our MDIChild vector
+ std::vector <MDIChildPtr>::iterator v;
+
+ for (v = GetAllMDIChildren().begin(); v < GetAllMDIChildren().end(); ++v)
+ {
+ if ((*v)->GetWindowLongPtr(GWL_STYLE) & WS_VISIBLE) // IsWindowVisible is unreliable here
+ {
+ // Add Separator
+ if (0 == nWindow)
+ ::AppendMenu(hMenuWindow, MF_SEPARATOR, 0, NULL);
+
+ // Add a menu entry for each MDI child (up to 9)
+ if (nWindow < 9)
+ {
+ tString tsMenuItem ( (*v)->GetWindowText() );
+
+ if (tsMenuItem.length() > MAX_MENU_STRING -10)
+ {
+ // Truncate the string if its too long
+ tsMenuItem.erase(tsMenuItem.length() - MAX_MENU_STRING +10);
+ tsMenuItem += _T(" ...");
+ }
+
+ TCHAR szMenuString[MAX_MENU_STRING+1];
+ wsprintf(szMenuString, _T("&%d %s"), nWindow+1, tsMenuItem.c_str());
+
+ ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, szMenuString);
+
+ if (GetActiveMDIChild() == (*v).get())
+ ::CheckMenuItem(hMenuWindow, IDW_FIRSTCHILD+nWindow, MF_CHECKED);
+
+ ++nWindow;
+ }
+ else if (9 == nWindow)
+ // For the 10th MDI child, add this menu item and return
+ {
+ ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, _T("&Windows..."));
+ return;
+ }
+ }
+ }
+ }
+
+ inline LRESULT CMDIFrame::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ return ::DefFrameProc(m_hWnd, GetMDIClient(), uMsg, wParam, lParam);
+ }
+
+ inline CMDIChild* CMDIFrame::GetActiveMDIChild() const
+ {
+ return (CMDIChild*)FromHandle(m_hActiveMDIChild);
+ }
+
+ inline BOOL CMDIFrame::IsMDIChildMaxed() const
+ {
+ BOOL bMaxed = FALSE;
+ GetMDIClient().SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMaxed);
+ return bMaxed;
+ }
+
+ inline void CMDIFrame::MDICascade(int nType /* = 0*/) const
+ {
+ // Possible values for nType are:
+ // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being cascaded.
+
+ assert(::IsWindow(m_hWnd));
+ GetView()->SendMessage(WM_MDICASCADE, (WPARAM)nType, 0L);
+ }
+
+ inline void CMDIFrame::MDIIconArrange() const
+ {
+ assert(::IsWindow(m_hWnd));
+ GetView()->SendMessage(WM_MDIICONARRANGE, 0L, 0L);
+ }
+
+ inline void CMDIFrame::MDIMaximize() const
+ {
+ assert(::IsWindow(m_hWnd));
+ GetView()->SendMessage(WM_MDIMAXIMIZE, 0L, 0L);
+ }
+
+ inline void CMDIFrame::MDINext() const
+ {
+ assert(::IsWindow(m_hWnd));
+ HWND hMDIChild = GetActiveMDIChild()->GetHwnd();
+ GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, FALSE);
+ }
+
+ inline void CMDIFrame::MDIPrev() const
+ {
+ assert(::IsWindow(m_hWnd));
+ HWND hMDIChild = GetActiveMDIChild()->GetHwnd();
+ GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, TRUE);
+ }
+
+ inline void CMDIFrame::MDIRestore() const
+ {
+ assert(::IsWindow(m_hWnd));
+ GetView()->SendMessage(WM_MDIRESTORE, 0L, 0L);
+ }
+
+ inline void CMDIFrame::MDITile(int nType /* = 0*/) const
+ {
+ // Possible values for nType are:
+ // MDITILE_HORIZONTAL Tiles MDI child windows so that one window appears above another.
+ // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being tiled.
+ // MDITILE_VERTICAL Tiles MDI child windows so that one window appears beside another.
+
+ assert(::IsWindow(m_hWnd));
+ GetView()->SendMessage(WM_MDITILE, (WPARAM)nType, 0L);
+ }
+
+ inline void CMDIFrame::OnClose()
+ {
+ if (RemoveAllMDIChildren())
+ {
+ CFrame::OnClose();
+ Destroy();
+ }
+ }
+
+ inline void CMDIFrame::OnViewStatusBar()
+ {
+ CFrame::OnViewStatusBar();
+ UpdateCheckMarks();
+ GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
+ }
+
+ inline void CMDIFrame::OnViewToolBar()
+ {
+ CFrame::OnViewToolBar();
+ UpdateCheckMarks();
+ GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
+ }
+
+ inline void CMDIFrame::OnWindowPosChanged()
+ {
+ if (IsMenuBarUsed())
+ {
+ // Refresh MenuBar Window
+ HMENU hMenu= GetMenuBar().GetMenu();
+ GetMenuBar().SetMenu(hMenu);
+ UpdateCheckMarks();
+ }
+ }
+
+ inline BOOL CMDIFrame::PreTranslateMessage(MSG* pMsg)
+ {
+ if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
+ {
+ if (TranslateMDISysAccel(GetView()->GetHwnd(), pMsg))
+ return TRUE;
+ }
+
+ return CFrame::PreTranslateMessage(pMsg);
+ }
+
+ inline void CMDIFrame::RecalcLayout()
+ {
+ CFrame::RecalcLayout();
+
+ if (GetView()->IsWindow())
+ MDIIconArrange();
+ }
+
+ inline BOOL CMDIFrame::RemoveAllMDIChildren()
+ {
+ BOOL bResult = TRUE;
+ int Children = (int)m_vMDIChild.size();
+
+ // Remove the children in reverse order
+ for (int i = Children-1; i >= 0; --i)
+ {
+ if (IDNO == m_vMDIChild[i]->SendMessage(WM_CLOSE, 0L, 0L)) // Also removes the MDI child
+ bResult = FALSE;
+ }
+
+ return bResult;
+ }
+
+ inline void CMDIFrame::RemoveMDIChild(HWND hWnd)
+ {
+ // Allocate an iterator for our HWND map
+ std::vector <MDIChildPtr>::iterator v;
+
+ for (v = m_vMDIChild.begin(); v!= m_vMDIChild.end(); ++v)
+ {
+ if ((*v)->GetHwnd() == hWnd)
+ {
+ m_vMDIChild.erase(v);
+ break;
+ }
+ }
+
+ if (GetActiveMDIChild())
+ {
+ if (GetActiveMDIChild()->m_hChildMenu)
+ UpdateFrameMenu(GetActiveMDIChild()->m_hChildMenu);
+ if (GetActiveMDIChild()->m_hChildAccel)
+ GetApp()->SetAccelerators(GetActiveMDIChild()->m_hChildAccel, this);
+ }
+ else
+ {
+ if (IsMenuBarUsed())
+ GetMenuBar().SetMenu(GetFrameMenu());
+ else
+ SetMenu(FromHandle(GetFrameMenu()));
+
+ GetApp()->SetAccelerators(GetFrameAccel(), this);
+ }
+ }
+
+ inline void CMDIFrame::SetActiveMDIChild(CMDIChild* pChild)
+ {
+ assert ( pChild->IsWindow() );
+
+ GetMDIClient().SendMessage(WM_MDIACTIVATE, (WPARAM)pChild->GetHwnd(), 0L);
+
+ // Verify
+ assert ( m_hActiveMDIChild == pChild->GetHwnd() );
+ }
+
+ inline void CMDIFrame::UpdateCheckMarks()
+ {
+ if ((GetActiveMDIChild()) && GetActiveMDIChild()->m_hChildMenu)
+ {
+ HMENU hMenu = GetActiveMDIChild()->m_hChildMenu;
+
+ UINT uCheck = GetToolBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED;
+ ::CheckMenuItem(hMenu, IDW_VIEW_TOOLBAR, uCheck);
+
+ uCheck = GetStatusBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED;
+ ::CheckMenuItem (hMenu, IDW_VIEW_STATUSBAR, uCheck);
+ }
+ }
+
+ inline void CMDIFrame::UpdateFrameMenu(HMENU hMenu)
+ {
+ int nMenuItems = GetMenuItemCount(hMenu);
+ if (nMenuItems > 0)
+ {
+ // The Window menu is typically second from the right
+ int nWindowItem = MAX (nMenuItems -2, 0);
+ HMENU hMenuWindow = ::GetSubMenu (hMenu, nWindowItem);
+
+ if (hMenuWindow)
+ {
+ if (IsMenuBarUsed())
+ {
+ AppendMDIMenu(hMenuWindow);
+ GetMenuBar().SetMenu(hMenu);
+ }
+ else
+ {
+ GetView()->SendMessage (WM_MDISETMENU, (WPARAM) hMenu, (LPARAM)hMenuWindow);
+ DrawMenuBar();
+ }
+ }
+ }
+ UpdateCheckMarks();
+ }
+
+ inline LRESULT CMDIFrame::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_CLOSE:
+ OnClose();
+ return 0;
+
+ case WM_WINDOWPOSCHANGED:
+ // MDI Child or MDI frame has been resized
+ OnWindowPosChanged();
+ break; // Continue with default processing
+
+ } // switch uMsg
+ return CFrame::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+ inline HWND CMDIFrame::CMDIClient::Create(CWnd* pParent)
+ {
+ assert(pParent != 0);
+
+ CLIENTCREATESTRUCT clientcreate ;
+ clientcreate.hWindowMenu = m_hWnd;
+ clientcreate.idFirstChild = IDW_FIRSTCHILD ;
+ DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES;
+
+ // Create the view window
+ CreateEx(WS_EX_CLIENTEDGE, _T("MDICLient"), TEXT(""), dwStyle, 0, 0, 0, 0, pParent, NULL, (PSTR) &clientcreate);
+
+ return m_hWnd;
+ }
+
+ inline LRESULT CMDIFrame::CMDIClient::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_MDIDESTROY:
+ {
+ // Do default processing first
+ CallWindowProc(GetPrevWindowProc(), uMsg, wParam, lParam);
+
+ // Now remove MDI child
+ GetMDIFrame()->RemoveMDIChild((HWND) wParam);
+ }
+ return 0; // Discard message
+
+ case WM_MDISETMENU:
+ {
+ if (GetMDIFrame()->IsMenuBarUsed())
+ {
+ return 0L;
+ }
+ }
+ break;
+
+ case WM_MDIACTIVATE:
+ {
+ // Suppress redraw to avoid flicker when activating maximised MDI children
+ SendMessage(WM_SETREDRAW, FALSE, 0L);
+ LRESULT lr = CallWindowProc(GetPrevWindowProc(), WM_MDIACTIVATE, wParam, lParam);
+ SendMessage(WM_SETREDRAW, TRUE, 0L);
+ RedrawWindow(0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+ return lr;
+ }
+ }
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+ /////////////////////////////////////
+ //Definitions for the CMDIChild class
+ //
+ inline CMDIChild::CMDIChild() : m_pView(NULL), m_hChildMenu(NULL)
+ {
+ // Set the MDI Child's menu and accelerator in the constructor, like this ...
+ // HMENU hChildMenu = LoadMenu(GetApp()->GetResourceHandle(), _T("MdiMenuView"));
+ // HACCEL hChildAccel = LoadAccelerators(GetApp()->GetResourceHandle(), _T("MDIAccelView"));
+ // SetHandles(hChildMenu, hChildAccel);
+ }
+
+ inline CMDIChild::~CMDIChild()
+ {
+ if (IsWindow())
+ GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L);
+
+ if (m_hChildMenu)
+ ::DestroyMenu(m_hChildMenu);
+ }
+
+ inline HWND CMDIChild::Create(CWnd* pParent /*= NULL*/)
+ // We create the MDI child window and then maximize if required.
+ // This technique avoids unnecessary flicker when creating maximized MDI children.
+ {
+ //Call PreCreate in case its overloaded
+ PreCreate(*m_pcs);
+
+ //Determine if the window should be created maximized
+ BOOL bMax = FALSE;
+ pParent->SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMax);
+ bMax = bMax | (m_pcs->style & WS_MAXIMIZE);
+
+ // Set the Window Class Name
+ TCHAR szClassName[MAX_STRING_SIZE + 1] = _T("Win32++ MDI Child");
+ if (m_pcs->lpszClass)
+ lstrcpyn(szClassName, m_pcs->lpszClass, MAX_STRING_SIZE);
+
+ // Set the window style
+ DWORD dwStyle;
+ dwStyle = m_pcs->style & ~WS_MAXIMIZE;
+ dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW ;
+
+ // Set window size and position
+ int x = CW_USEDEFAULT;
+ int y = CW_USEDEFAULT;
+ int cx = CW_USEDEFAULT;
+ int cy = CW_USEDEFAULT;
+ if(m_pcs->cx && m_pcs->cy)
+ {
+ x = m_pcs->x;
+ y = m_pcs->y;
+ cx = m_pcs->cx;
+ cy = m_pcs->cy;
+ }
+
+ // Set the extended style
+ DWORD dwExStyle = m_pcs->dwExStyle | WS_EX_MDICHILD;
+
+ // Turn off redraw while creating the window
+ pParent->SendMessage(WM_SETREDRAW, FALSE, 0L);
+
+ // Create the window
+ if (!CreateEx(dwExStyle, szClassName, m_pcs->lpszName, dwStyle, x, y,
+ cx, cy, pParent, FromHandle(m_pcs->hMenu), m_pcs->lpCreateParams))
+ throw CWinException(_T("CMDIChild::Create ... CreateEx failed"));
+
+ if (bMax)
+ ShowWindow(SW_MAXIMIZE);
+
+ // Turn redraw back on
+ pParent->SendMessage(WM_SETREDRAW, TRUE, 0L);
+ pParent->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+ // Ensure bits revealed by round corners (XP themes) are redrawn
+ SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
+
+ if (m_hChildMenu)
+ GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
+ if (m_hChildAccel)
+ GetApp()->SetAccelerators(m_hChildAccel, this);
+
+ return m_hWnd;
+ }
+
+ inline CMDIFrame* CMDIChild::GetMDIFrame() const
+ {
+ CMDIFrame* pMDIFrame = (CMDIFrame*)GetParent()->GetParent();
+ assert(dynamic_cast<CMDIFrame*>(pMDIFrame));
+ return pMDIFrame;
+ }
+
+ inline LRESULT CMDIChild::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ return ::DefMDIChildProc(m_hWnd, uMsg, wParam, lParam);
+ }
+
+ inline void CMDIChild::MDIActivate() const
+ {
+ GetParent()->SendMessage(WM_MDIACTIVATE, (WPARAM)m_hWnd, 0L);
+ }
+
+ inline void CMDIChild::MDIDestroy() const
+ {
+ GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L);
+ }
+
+ inline void CMDIChild::MDIMaximize() const
+ {
+ GetParent()->SendMessage(WM_MDIMAXIMIZE, (WPARAM)m_hWnd, 0L);
+ }
+
+ inline void CMDIChild::MDIRestore() const
+ {
+ GetParent()->SendMessage(WM_MDIRESTORE, (WPARAM)m_hWnd, 0L);
+ }
+
+ inline void CMDIChild::OnCreate()
+ {
+ // Create the view window
+ assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window
+ GetView()->Create(this);
+ RecalcLayout();
+ }
+
+ inline void CMDIChild::RecalcLayout()
+ {
+ // Resize the View window
+ CRect rc = GetClientRect();
+ m_pView->SetWindowPos( NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW );
+ }
+
+ inline void CMDIChild::SetHandles(HMENU hMenu, HACCEL hAccel)
+ {
+ m_hChildMenu = hMenu;
+ m_hChildAccel = hAccel;
+
+ // Note: It is valid to call SetChildMenu before the window is created
+ if (IsWindow())
+ {
+ CWnd* pWnd = GetMDIFrame()->GetActiveMDIChild();
+ if (pWnd == this)
+ {
+ if (m_hChildMenu)
+ GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
+
+ if (m_hChildAccel)
+ GetApp()->SetAccelerators(m_hChildAccel, GetMDIFrame());
+ }
+ }
+ }
+
+ inline void CMDIChild::SetView(CWnd& wndView)
+ // Sets or changes the View window displayed within the frame
+ {
+ if (m_pView != &wndView)
+ {
+ // Destroy the existing view window (if any)
+ if (m_pView) m_pView->Destroy();
+
+ // Assign the view window
+ m_pView = &wndView;
+
+ if (m_hWnd)
+ {
+ // The frame is already created, so create and position the new view too
+ assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window
+ GetView()->Create(this);
+ RecalcLayout();
+ }
+ }
+ }
+
+ inline LRESULT CMDIChild::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_MDIACTIVATE:
+ {
+ // This child is being activated
+ if (lParam == (LPARAM) m_hWnd)
+ {
+ GetMDIFrame()->m_hActiveMDIChild = m_hWnd;
+ // Set the menu to child default menu
+ if (m_hChildMenu)
+ GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
+ if (m_hChildAccel)
+ GetApp()->SetAccelerators(m_hChildAccel, this);
+ }
+
+ // No child is being activated
+ if (0 == lParam)
+ {
+ GetMDIFrame()->m_hActiveMDIChild = NULL;
+ // Set the menu to frame's original menu
+ GetMDIFrame()->UpdateFrameMenu(GetMDIFrame()->GetFrameMenu());
+ GetApp()->SetAccelerators(GetMDIFrame()->GetFrameAccel(), this);
+ }
+ }
+ return 0L ;
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ RecalcLayout();
+ break;
+ }
+ }
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_MDI_H_
+
diff --git a/mmc_updater/depends/win32cpp/menu.h b/mmc_updater/depends/win32cpp/menu.h
new file mode 100644
index 00000000..136bafa3
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/menu.h
@@ -0,0 +1,600 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// menu.h
+// Declaration of the CMenu class
+
+// Notes
+// 1) Owner-drawn menus send the WM_MEASUREITEM and WM_DRAWITEM messages
+// to the window that owns the menu. To manage owner drawing for menus,
+// handle these two messages in the CWnd's WndProc function.
+//
+// 2) The CMenu pointer returned by FromHandle might be a temporary pointer. It
+// should be used immediately, not saved for later use.
+//
+// 3) The CMenu pointers returned by FromHandle or GetSubMenu do not need
+// to be deleted. They are automatically deleted by the Win32++.
+//
+// 4) CMenu pointers returned by GetSubMenu are deleted when the parent CMenu is
+// detached, destroyed or deconstructed.
+//
+// 5) The HMENU that is attached to a CMenu object (using the attach function) is
+// automatically deleted when the CMenu object goes out of scope. Detach the
+// HMENU to stop it being deleted when CMenu's destructor is called.
+//
+// 6) Pass CMenu objects by reference or by pointer when passing them as function
+// arguments.
+//
+// 7) In those functions that use a MENUITEMINFO structure, its cbSize member is
+// automatically set to the correct value.
+
+// Program sample
+// --------------
+// void CView::CreatePopup()
+// {
+// CPoint pt = GetCursorPos();
+//
+// // Create the menu
+// CMenu Popup;
+// Popup.CreatePopupMenu();
+//
+// // Add some menu items
+// Popup.AppendMenu(MF_STRING, 101, _T("Menu Item &1"));
+// Popup.AppendMenu(MF_STRING, 102, _T("Menu Item &2"));
+// Popup.AppendMenu(MF_STRING, 103, _T("Menu Item &3"));
+// Popup.AppendMenu(MF_SEPARATOR);
+// Popup.AppendMenu(MF_STRING, 104, _T("Menu Item &4"));
+//
+// // Set menu item states
+// Popup.CheckMenuRadioItem(101, 101, 101, MF_BYCOMMAND);
+// Popup.CheckMenuItem(102, MF_BYCOMMAND | MF_CHECKED);
+// Popup.EnableMenuItem(103, MF_BYCOMMAND | MF_GRAYED);
+// Popup.SetDefaultItem(104);
+//
+// // Display the popup menu
+// Popup.TrackPopupMenu(0, pt.x, pt.y, this);
+// }
+
+
+
+#if !defined(_WIN32XX_MENU_H_) && !defined(_WIN32_WCE)
+#define _WIN32XX_MENU_H_
+
+
+#include "wincore.h"
+#include "gdi.h"
+
+
+namespace Win32xx
+{
+
+ // Forward declarations
+ class CBitmap;
+
+ class CMenu
+ {
+ friend class CWinApp;
+
+ public:
+ //Construction
+ CMenu() : m_hMenu(0), m_IsTmpMenu(FALSE) {}
+ CMenu(UINT nID) : m_IsTmpMenu(FALSE)
+ {
+ m_hMenu = ::LoadMenu(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(nID));
+ }
+ ~CMenu();
+
+ //Initialization
+ void Attach(HMENU hMenu);
+ void CreateMenu();
+ void CreatePopupMenu();
+ void DestroyMenu();
+ HMENU Detach();
+ HMENU GetHandle() const;
+ BOOL LoadMenu(LPCTSTR lpszResourceName);
+ BOOL LoadMenu(UINT uIDResource);
+ BOOL LoadMenuIndirect(const void* lpMenuTemplate);
+
+ //Menu Operations
+ BOOL TrackPopupMenu(UINT uFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = 0);
+ BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, CWnd* pWnd, LPTPMPARAMS lptpm);
+
+ //Menu Item Operations
+ BOOL AppendMenu(UINT uFlags, UINT_PTR uIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
+ BOOL AppendMenu(UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp);
+ UINT CheckMenuItem(UINT uIDCheckItem, UINT uCheck);
+ BOOL CheckMenuRadioItem(UINT uIDFirst, UINT uIDLast, UINT uIDItem, UINT uFlags);
+ BOOL DeleteMenu(UINT uPosition, UINT uFlags);
+ UINT EnableMenuItem(UINT uIDEnableItem, UINT uEnable);
+ UINT GetDefaultItem(UINT gmdiFlags, BOOL fByPos = FALSE);
+ DWORD GetMenuContextHelpId() const;
+
+#if(WINVER >= 0x0500) // Minimum OS required is Win2000
+ BOOL GetMenuInfo(LPMENUINFO lpcmi) const;
+ BOOL SetMenuInfo(LPCMENUINFO lpcmi);
+#endif
+
+ UINT GetMenuItemCount() const;
+ UINT GetMenuItemID(int nPos) const;
+ BOOL GetMenuItemInfo(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos = FALSE);
+ UINT GetMenuState(UINT uID, UINT uFlags) const;
+ int GetMenuString(UINT uIDItem, LPTSTR lpString, int nMaxCount, UINT uFlags) const;
+ int GetMenuString(UINT uIDItem, CString& rString, UINT uFlags) const;
+ CMenu* GetSubMenu(int nPos);
+ BOOL InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
+ BOOL InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp);
+ BOOL InsertMenuItem(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos = FALSE);
+ BOOL ModifyMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
+ BOOL ModifyMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp);
+ BOOL RemoveMenu(UINT uPosition, UINT uFlags);
+ BOOL SetDefaultItem(UINT uItem, BOOL fByPos = FALSE);
+ BOOL SetMenuContextHelpId(DWORD dwContextHelpId);
+ BOOL SetMenuItemBitmaps(UINT uPosition, UINT uFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked);
+ BOOL SetMenuItemInfo(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos = FALSE);
+
+ //Operators
+ BOOL operator != (const CMenu& menu) const;
+ BOOL operator == (const CMenu& menu) const;
+ operator HMENU () const;
+
+ private:
+ CMenu(const CMenu&); // Disable copy construction
+ CMenu& operator = (const CMenu&); // Disable assignment operator
+ void AddToMap();
+ BOOL RemoveFromMap();
+ std::vector<MenuPtr> m_vSubMenus; // A vector of smart pointers to CMenu
+ HMENU m_hMenu;
+ BOOL m_IsTmpMenu;
+ };
+
+ inline CMenu::~CMenu()
+ {
+ if (m_hMenu)
+ {
+ if (!m_IsTmpMenu)
+ {
+ ::DestroyMenu(m_hMenu);
+ }
+
+ RemoveFromMap();
+ }
+
+ m_vSubMenus.clear();
+ }
+
+ inline void CMenu::AddToMap()
+ // Store the HMENU and CMenu pointer in the HMENU map
+ {
+ assert( GetApp() );
+ assert(m_hMenu);
+
+ GetApp()->m_csMapLock.Lock();
+ GetApp()->m_mapHMENU.insert(std::make_pair(m_hMenu, this));
+ GetApp()->m_csMapLock.Release();
+ }
+
+ inline BOOL CMenu::RemoveFromMap()
+ {
+ BOOL Success = FALSE;
+
+ if (GetApp())
+ {
+ // Allocate an iterator for our HDC map
+ std::map<HMENU, CMenu*, CompareHMENU>::iterator m;
+
+ CWinApp* pApp = GetApp();
+ if (pApp)
+ {
+ // Erase the CDC pointer entry from the map
+ pApp->m_csMapLock.Lock();
+ for (m = pApp->m_mapHMENU.begin(); m != pApp->m_mapHMENU.end(); ++m)
+ {
+ if (this == m->second)
+ {
+ pApp->m_mapHMENU.erase(m);
+ Success = TRUE;
+ break;
+ }
+ }
+
+ pApp->m_csMapLock.Release();
+ }
+ }
+
+ return Success;
+ }
+
+
+ inline BOOL CMenu::AppendMenu(UINT uFlags, UINT_PTR uIDNewItem /*= 0*/, LPCTSTR lpszNewItem /*= NULL*/)
+ // Appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::AppendMenu(m_hMenu, uFlags, uIDNewItem, lpszNewItem);
+ }
+
+ inline BOOL CMenu::AppendMenu(UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp)
+ // Appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(pBmp);
+ return ::AppendMenu(m_hMenu, uFlags, uIDNewItem, (LPCTSTR)pBmp->GetHandle());
+ }
+
+ inline void CMenu::Attach(HMENU hMenu)
+ // Attaches an existing menu to this CMenu
+ {
+ if (m_hMenu != NULL && m_hMenu != hMenu)
+ {
+ ::DestroyMenu(Detach());
+ }
+
+ if (hMenu)
+ {
+ m_hMenu = hMenu;
+ AddToMap();
+ }
+ }
+
+ inline UINT CMenu::CheckMenuItem(UINT uIDCheckItem, UINT uCheck)
+ // Sets the state of the specified menu item's check-mark attribute to either selected or clear.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::CheckMenuItem(m_hMenu, uIDCheckItem, uCheck);
+ }
+
+ inline BOOL CMenu::CheckMenuRadioItem(UINT uIDFirst, UINT uIDLast, UINT uIDItem, UINT uFlags)
+ // Checks a specified menu item and makes it a radio item. At the same time, the function clears
+ // all other menu items in the associated group and clears the radio-item type flag for those items.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::CheckMenuRadioItem(m_hMenu, uIDFirst, uIDLast, uIDItem, uFlags);
+ }
+
+ inline void CMenu::CreateMenu()
+ // Creates an empty menu.
+ {
+ assert(NULL == m_hMenu);
+ m_hMenu = ::CreateMenu();
+ AddToMap();
+ }
+
+ inline void CMenu::CreatePopupMenu()
+ // Creates a drop-down menu, submenu, or shortcut menu. The menu is initially empty.
+ {
+ assert(NULL == m_hMenu);
+ m_hMenu = ::CreatePopupMenu();
+ AddToMap();
+ }
+
+ inline BOOL CMenu::DeleteMenu(UINT uPosition, UINT uFlags)
+ // Deletes an item from the specified menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::DeleteMenu(m_hMenu, uPosition, uFlags);
+ }
+
+ inline void CMenu::DestroyMenu()
+ // Destroys the menu and frees any memory that the menu occupies.
+ {
+ if (::IsMenu(m_hMenu))
+ ::DestroyMenu(m_hMenu);
+
+ m_hMenu = 0;
+ RemoveFromMap();
+ m_vSubMenus.clear();
+ }
+
+ inline HMENU CMenu::Detach()
+ // Detaches the HMENU from this CMenu. If the HMENU is not detached it will be
+ // destroyed when this CMenu is deconstructed.
+ {
+ assert(IsMenu(m_hMenu));
+ HMENU hMenu = m_hMenu;
+ m_hMenu = 0;
+ RemoveFromMap();
+ m_vSubMenus.clear();
+ return hMenu;
+ }
+
+ inline HMENU CMenu::GetHandle() const
+ // Returns the HMENU assigned to this CMenu
+ {
+ return m_hMenu;
+ }
+
+ inline UINT CMenu::EnableMenuItem(UINT uIDEnableItem, UINT uEnable)
+ // Enables, disables, or grays the specified menu item.
+ // The uEnable parameter must be a combination of either MF_BYCOMMAND or MF_BYPOSITION
+ // and MF_ENABLED, MF_DISABLED, or MF_GRAYED.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::EnableMenuItem(m_hMenu, uIDEnableItem, uEnable);
+ }
+
+ inline UINT CMenu::GetDefaultItem(UINT gmdiFlags, BOOL fByPos /*= FALSE*/)
+ // Determines the default menu item.
+ // The gmdiFlags parameter specifies how the function searches for menu items.
+ // This parameter can be zero or more of the following values: GMDI_GOINTOPOPUPS; GMDI_USEDISABLED.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuDefaultItem(m_hMenu, fByPos, gmdiFlags);
+ }
+
+ inline DWORD CMenu::GetMenuContextHelpId() const
+ // Retrieves the Help context identifier associated with the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuContextHelpId(m_hMenu);
+ }
+
+#if(WINVER >= 0x0500)
+// minimum OS required : Win2000
+
+ inline BOOL CMenu::GetMenuInfo(LPMENUINFO lpcmi) const
+ // Retrieves the menu information.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuInfo(m_hMenu, lpcmi);
+ }
+
+ inline BOOL CMenu::SetMenuInfo(LPCMENUINFO lpcmi)
+ // Sets the menu information from the specified MENUINFO structure.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::SetMenuInfo(m_hMenu, lpcmi);
+ }
+
+#endif
+
+ inline UINT CMenu::GetMenuItemCount() const
+ // Retrieves the number of menu items.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuItemCount(m_hMenu);
+ }
+
+ inline UINT CMenu::GetMenuItemID(int nPos) const
+ // Retrieves the menu item identifier of a menu item located at the specified position
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuItemID(m_hMenu, nPos);
+ }
+
+ inline BOOL CMenu::GetMenuItemInfo(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos /*= FALSE*/)
+ // retrieves information about the specified menu item.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(lpMenuItemInfo);
+ lpMenuItemInfo->cbSize = GetSizeofMenuItemInfo();
+ return ::GetMenuItemInfo(m_hMenu, uItem, fByPos, lpMenuItemInfo);
+ }
+
+ inline UINT CMenu::GetMenuState(UINT uID, UINT uFlags) const
+ // Retrieves the menu flags associated with the specified menu item.
+ // Possible values for uFlags are: MF_BYCOMMAND (default) or MF_BYPOSITION.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuState(m_hMenu, uID, uFlags);
+ }
+
+ inline int CMenu::GetMenuString(UINT uIDItem, LPTSTR lpString, int nMaxCount, UINT uFlags) const
+ // Copies the text string of the specified menu item into the specified buffer.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(lpString);
+ return ::GetMenuString(m_hMenu, uIDItem, lpString, nMaxCount, uFlags);
+ }
+
+ inline int CMenu::GetMenuString(UINT uIDItem, CString& rString, UINT uFlags) const
+ // Copies the text string of the specified menu item into the specified buffer.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::GetMenuString(m_hMenu, uIDItem, (LPTSTR)rString.c_str(), rString.GetLength(), uFlags);
+ }
+
+ inline CMenu* CMenu::GetSubMenu(int nPos)
+ // Retrieves the CMenu object of a pop-up menu.
+ {
+ assert(IsMenu(m_hMenu));
+ CMenu* pMenu = new CMenu;
+ pMenu->m_hMenu = ::GetSubMenu(m_hMenu, nPos);
+ pMenu->m_IsTmpMenu = TRUE;
+ m_vSubMenus.push_back(pMenu);
+ return pMenu;
+ }
+
+ inline BOOL CMenu::InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem /*= 0*/, LPCTSTR lpszNewItem /*= NULL*/)
+ // Inserts a new menu item into a menu, moving other items down the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::InsertMenu(m_hMenu, uPosition, uFlags, uIDNewItem, lpszNewItem);
+ }
+
+ inline BOOL CMenu::InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp)
+ // Inserts a new menu item into a menu, moving other items down the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::InsertMenu(m_hMenu, uPosition, uFlags, uIDNewItem, (LPCTSTR)pBmp->GetHandle());
+ }
+
+ inline BOOL CMenu::InsertMenuItem(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos /*= FALSE*/)
+ // Inserts a new menu item at the specified position in a menu.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(lpMenuItemInfo);
+ lpMenuItemInfo->cbSize = GetSizeofMenuItemInfo();
+ return ::InsertMenuItem(m_hMenu, uItem, fByPos, lpMenuItemInfo);
+ }
+
+ inline BOOL CMenu::LoadMenu(LPCTSTR lpszResourceName)
+ // Loads the menu from the specified windows resource.
+ {
+ assert(NULL == m_hMenu);
+ assert(lpszResourceName);
+ m_hMenu = ::LoadMenu(GetApp()->GetResourceHandle(), lpszResourceName);
+ if (m_hMenu) AddToMap();
+ return NULL != m_hMenu;
+ }
+
+ inline BOOL CMenu::LoadMenu(UINT uIDResource)
+ // Loads the menu from the specified windows resource.
+ {
+ assert(NULL == m_hMenu);
+ m_hMenu = ::LoadMenu(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(uIDResource));
+ if (m_hMenu) AddToMap();
+ return NULL != m_hMenu;
+ }
+
+ inline BOOL CMenu::LoadMenuIndirect(const void* lpMenuTemplate)
+ // Loads the specified menu template and assigns it to this CMenu.
+ {
+ assert(NULL == m_hMenu);
+ assert(lpMenuTemplate);
+ m_hMenu = ::LoadMenuIndirect(lpMenuTemplate);
+ if (m_hMenu) AddToMap();
+ return NULL != m_hMenu;
+ }
+
+ inline BOOL CMenu::ModifyMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem /*= 0*/, LPCTSTR lpszNewItem /*= NULL*/)
+ // Changes an existing menu item. This function is used to specify the content, appearance, and behavior of the menu item.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::ModifyMenu(m_hMenu, uPosition, uFlags, uIDNewItem, lpszNewItem);
+ }
+
+ inline BOOL CMenu::ModifyMenu(UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, const CBitmap* pBmp)
+ // Changes an existing menu item. This function is used to specify the content, appearance, and behavior of the menu item.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(pBmp);
+ return ::ModifyMenu(m_hMenu, uPosition, uFlags, uIDNewItem, (LPCTSTR)pBmp->GetHandle());
+ }
+
+ inline BOOL CMenu::RemoveMenu(UINT uPosition, UINT uFlags)
+ // Deletes a menu item or detaches a submenu from the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::RemoveMenu(m_hMenu, uPosition, uFlags);
+ }
+
+ inline BOOL CMenu::SetDefaultItem(UINT uItem, BOOL fByPos /*= FALSE*/)
+ // sets the default menu item for the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::SetMenuDefaultItem(m_hMenu, uItem, fByPos);
+ }
+
+ inline BOOL CMenu::SetMenuContextHelpId(DWORD dwContextHelpId)
+ // Associates a Help context identifier with the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId);
+ }
+
+ inline BOOL CMenu::SetMenuItemBitmaps(UINT uPosition, UINT uFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked)
+ // Associates the specified bitmap with a menu item.
+ {
+ assert(IsMenu(m_hMenu));
+ return ::SetMenuItemBitmaps(m_hMenu, uPosition, uFlags, *pBmpUnchecked, *pBmpChecked);
+ }
+
+ inline BOOL CMenu::SetMenuItemInfo(UINT uItem, LPMENUITEMINFO lpMenuItemInfo, BOOL fByPos /*= FALSE*/)
+ // Changes information about a menu item.
+ {
+ assert(IsMenu(m_hMenu));
+ assert(lpMenuItemInfo);
+ lpMenuItemInfo->cbSize = GetSizeofMenuItemInfo();
+ return ::SetMenuItemInfo(m_hMenu, uItem, fByPos, lpMenuItemInfo);
+ }
+
+ inline BOOL CMenu::TrackPopupMenu(UINT uFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect /*= 0*/)
+ // Displays a shortcut menu at the specified location and tracks the selection of items on the menu.
+ {
+ assert(IsMenu(m_hMenu));
+ HWND hWnd = pWnd? pWnd->GetHwnd() : 0;
+ return ::TrackPopupMenu(m_hMenu, uFlags, x, y, 0, hWnd, lpRect);
+ }
+
+ inline BOOL CMenu::TrackPopupMenuEx(UINT uFlags, int x, int y, CWnd* pWnd, LPTPMPARAMS lptpm)
+ // Displays a shortcut menu at the specified location and tracks the selection of items on the shortcut menu.
+ {
+ assert(IsMenu(m_hMenu));
+ HWND hWnd = pWnd? pWnd->GetHwnd() : 0;
+ return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm);
+ }
+
+ inline BOOL CMenu::operator != (const CMenu& menu) const
+ // Returns TRUE if the two menu objects are not equal.
+ {
+ return menu.m_hMenu != m_hMenu;
+ }
+
+ inline BOOL CMenu::operator == (const CMenu& menu) const
+ // Returns TRUE of the two menu object are equal
+ {
+ return menu.m_hMenu == m_hMenu;
+ }
+
+ inline CMenu::operator HMENU () const
+ // Retrieves the menu's handle.
+ {
+ return m_hMenu;
+ }
+
+
+ ///////////////////////////////////////
+ // Global functions
+ //
+
+ inline CMenu* FromHandle(HMENU hMenu)
+ // Returns the CMenu object associated with the menu handle (HMENU).
+ {
+ assert( GetApp() );
+ CMenu* pMenu = GetApp()->GetCMenuFromMap(hMenu);
+ if (::IsMenu(hMenu) && pMenu == 0)
+ {
+ GetApp()->AddTmpMenu(hMenu);
+ pMenu = GetApp()->GetCMenuFromMap(hMenu);
+ }
+ return pMenu;
+ }
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_MENU_H_
+
diff --git a/mmc_updater/depends/win32cpp/propertysheet.h b/mmc_updater/depends/win32cpp/propertysheet.h
new file mode 100644
index 00000000..4048942c
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/propertysheet.h
@@ -0,0 +1,960 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////
+// propertysheet.h
+// Declaration of the following classes:
+// CPropertyPage and CPropertySheet
+
+// These classes add support for property sheets to Win32++. A property sheet
+// will have one or more property pages. These pages are much like dialogs
+// which are presented within a tabbed dialog or within a wizard. The data
+// on a property page can be validated before the next page is presented.
+// Property sheets have three modes of use: Modal, Modeless, and Wizard.
+//
+// Refer to the PropertySheet demo program for an example of how propert sheets
+// can be used.
+
+
+#ifndef _WIN32XX_PROPERTYSHEET_H_
+#define _WIN32XX_PROPERTYSHEET_H_
+
+#include "dialog.h"
+
+#define ID_APPLY_NOW 0x3021
+#define ID_WIZBACK 0x3023
+#define ID_WIZNEXT 0x3024
+#define ID_WIZFINISH 0x3025
+#define ID_HELP 0xE146
+
+#ifndef PROPSHEETHEADER_V1_SIZE
+ #define PROPSHEETHEADER_V1_SIZE 40
+#endif
+
+namespace Win32xx
+{
+ class CPropertyPage;
+ typedef Shared_Ptr<CPropertyPage> PropertyPagePtr;
+
+ class CPropertyPage : public CWnd
+ {
+ public:
+ CPropertyPage (UINT nIDTemplate, LPCTSTR szTitle = NULL);
+ virtual ~CPropertyPage() {}
+
+ virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual INT_PTR DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual int OnApply();
+ virtual void OnCancel();
+ virtual void OnHelp();
+ virtual BOOL OnInitDialog();
+ virtual BOOL OnKillActive();
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual int OnOK();
+ virtual BOOL OnQueryCancel();
+ virtual BOOL OnQuerySiblings(WPARAM wParam, LPARAM lParam);
+ virtual int OnSetActive();
+ virtual int OnWizardBack();
+ virtual INT_PTR OnWizardFinish();
+ virtual int OnWizardNext();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+ static UINT CALLBACK StaticPropSheetPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
+ static INT_PTR CALLBACK StaticDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ void CancelToClose() const;
+ PROPSHEETPAGE GetPSP() const {return m_PSP;}
+ BOOL IsButtonEnabled(int iButton) const;
+ LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) const;
+ void SetModified(BOOL bChanged) const;
+ void SetTitle(LPCTSTR szTitle);
+ void SetWizardButtons(DWORD dwFlags) const;
+
+ protected:
+ PROPSHEETPAGE m_PSP;
+
+ private:
+ CPropertyPage(const CPropertyPage&); // Disable copy construction
+ CPropertyPage& operator = (const CPropertyPage&); // Disable assignment operator
+
+ tString m_Title;
+ };
+
+ class CPropertySheet : public CWnd
+ {
+ public:
+ CPropertySheet(UINT nIDCaption, CWnd* pParent = NULL);
+ CPropertySheet(LPCTSTR pszCaption = NULL, CWnd* pParent = NULL);
+ virtual ~CPropertySheet() {}
+
+ // Operations
+ virtual CPropertyPage* AddPage(CPropertyPage* pPage);
+ virtual HWND Create(CWnd* pParent = 0);
+ virtual INT_PTR CreatePropertySheet(LPCPROPSHEETHEADER ppsph);
+ virtual void DestroyButton(int iButton);
+ virtual void Destroy();
+ virtual int DoModal();
+ virtual void RemovePage(CPropertyPage* pPage);
+
+ // State functions
+ BOOL IsModeless() const;
+ BOOL IsWizard() const;
+
+ //Attributes
+ CPropertyPage* GetActivePage() const;
+ int GetPageCount() const;
+ int GetPageIndex(CPropertyPage* pPage) const;
+ HWND GetTabControl() const;
+ virtual BOOL SetActivePage(int nPage);
+ virtual BOOL SetActivePage(CPropertyPage* pPage);
+ virtual void SetIcon(UINT idIcon);
+ virtual void SetTitle(LPCTSTR szTitle);
+ virtual void SetWizardMode(BOOL bWizard);
+
+ protected:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CPropertySheet(const CPropertySheet&); // Disable copy construction
+ CPropertySheet& operator = (const CPropertySheet&); // Disable assignment operator
+ void BuildPageArray();
+ static void CALLBACK Callback(HWND hwnd, UINT uMsg, LPARAM lParam);
+
+ tString m_Title;
+ std::vector<PropertyPagePtr> m_vPages; // vector of CPropertyPage
+ std::vector<PROPSHEETPAGE> m_vPSP; // vector of PROPSHEETPAGE
+ BOOL m_bInitialUpdate;
+ PROPSHEETHEADER m_PSH;
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
+
+namespace Win32xx
+{
+
+ //////////////////////////////////////////
+ // Definitions for the CPropertyPage class
+ //
+ inline CPropertyPage::CPropertyPage(UINT nIDTemplate, LPCTSTR szTitle /* = NULL*/)
+ {
+ ZeroMemory(&m_PSP, sizeof(PROPSHEETPAGE));
+ SetTitle(szTitle);
+
+ m_PSP.dwSize = sizeof(PROPSHEETPAGE);
+ m_PSP.dwFlags |= PSP_USECALLBACK;
+ m_PSP.hInstance = GetApp()->GetResourceHandle();
+ m_PSP.pszTemplate = MAKEINTRESOURCE(nIDTemplate);
+ m_PSP.pszTitle = m_Title.c_str();
+ m_PSP.pfnDlgProc = (DLGPROC)CPropertyPage::StaticDialogProc;
+ m_PSP.lParam = (LPARAM)this;
+ m_PSP.pfnCallback = CPropertyPage::StaticPropSheetPageProc;
+ }
+
+ inline void CPropertyPage::CancelToClose() const
+ // Disables the Cancel button and changes the text of the OK button to "Close."
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(PSM_CANCELTOCLOSE, 0L, 0L);
+ }
+
+
+ inline INT_PTR CPropertyPage::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // Override this function in your class derrived from CPropertyPage if you wish to handle messages
+ // A typical function might look like this:
+
+ // switch (uMsg)
+ // {
+ // case MESSAGE1: // Some Win32 API message
+ // OnMessage1(); // A user defined function
+ // break; // Also do default processing
+ // case MESSAGE2:
+ // OnMessage2();
+ // return x; // Don't do default processing, but instead return
+ // // a value recommended by the Win32 API documentation
+ // }
+
+ // Always pass unhandled messages on to DialogProcDefault
+ return DialogProcDefault(uMsg, wParam, lParam);
+ }
+
+ inline INT_PTR CPropertyPage::DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // All DialogProc functions should pass unhandled messages to this function
+ {
+ LRESULT lr = 0L;
+
+ switch (uMsg)
+ {
+ case UWM_CLEANUPTEMPS:
+ {
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ pTLSData->vTmpWnds.clear();
+ }
+ break;
+
+ case WM_INITDIALOG:
+ return OnInitDialog();
+
+ case PSM_QUERYSIBLINGS:
+ return (BOOL)OnQuerySiblings(wParam, lParam);
+
+ case WM_COMMAND:
+ {
+ // Refelect this message if it's from a control
+ CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam);
+ if (pWnd != NULL)
+ lr = pWnd->OnCommand(wParam, lParam);
+
+ // Handle user commands
+ if (!lr)
+ lr = OnCommand(wParam, lParam);
+
+ if (lr) return 0L;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ // Do Notification reflection if it came from a CWnd object
+ HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom;
+ CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom);
+
+ if (pWndFrom != NULL)
+ lr = pWndFrom->OnNotifyReflect(wParam, lParam);
+ else
+ {
+ // Some controls (eg ListView) have child windows.
+ // Reflect those notifications too.
+ CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom));
+ if (pWndFromParent != NULL)
+ lr = pWndFromParent->OnNotifyReflect(wParam, lParam);
+ }
+
+ // Handle user notifications
+ if (!lr) lr = OnNotify(wParam, lParam);
+
+ // Set the return code for notifications
+ if (IsWindow())
+ SetWindowLongPtr(DWLP_MSGRESULT, (LONG_PTR)lr);
+
+ return (BOOL)lr;
+ }
+
+ case WM_PAINT:
+ {
+ if (::GetUpdateRect(m_hWnd, NULL, FALSE))
+ {
+ CPaintDC dc(this);
+ OnDraw(&dc);
+ }
+ else
+ // RedrawWindow can require repainting without an update rect
+ {
+ CClientDC dc(this);
+ OnDraw(&dc);
+ }
+
+ break;
+ }
+
+ case WM_ERASEBKGND:
+ {
+ CDC dc((HDC)wParam);
+ BOOL bResult = OnEraseBkgnd(&dc);
+ dc.Detach();
+ if (bResult) return TRUE;
+ }
+ break;
+
+ // A set of messages to be reflected back to the control that generated them
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORSCROLLBAR:
+ case WM_CTLCOLORSTATIC:
+ case WM_DRAWITEM:
+ case WM_MEASUREITEM:
+ case WM_DELETEITEM:
+ case WM_COMPAREITEM:
+ case WM_CHARTOITEM:
+ case WM_VKEYTOITEM:
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ case WM_PARENTNOTIFY:
+ return MessageReflect(m_hWnd, uMsg, wParam, lParam);
+
+ } // switch(uMsg)
+ return FALSE;
+
+ } // INT_PTR CALLBACK CPropertyPage::DialogProc(...)
+
+ inline BOOL CPropertyPage::IsButtonEnabled(int iButton) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return GetParent()->GetDlgItem(iButton)->IsWindowEnabled();
+ }
+
+ inline int CPropertyPage::OnApply()
+ {
+ // This function is called for each page when the Apply button is pressed
+ // Override this function in your derived class if required.
+
+ // The possible return values are:
+ // PSNRET_NOERROR. The changes made to this page are valid and have been applied
+ // PSNRET_INVALID. The property sheet will not be destroyed, and focus will be returned to this page.
+ // PSNRET_INVALID_NOCHANGEPAGE. The property sheet will not be destroyed, and focus will be returned;
+
+ return PSNRET_NOERROR;
+ }
+
+ inline void CPropertyPage::OnCancel()
+ {
+ // This function is called for each page when the Cancel button is pressed
+ // Override this function in your derived class if required.
+ }
+
+ inline void CPropertyPage::OnHelp()
+ {
+ // This function is called in response to the PSN_HELP notification.
+ SendMessage(m_hWnd, WM_COMMAND, ID_HELP, 0L);
+ }
+
+ inline BOOL CPropertyPage::OnQueryCancel()
+ {
+ // Called when the cancel button is pressed, and before the cancel has taken place
+ // Returns TRUE to prevent the cancel operation, or FALSE to allow it.
+
+ return FALSE; // Allow cancel to proceed
+ }
+
+ inline BOOL CPropertyPage::OnQuerySiblings(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Responds to a query request from the Property Sheet.
+ // The values for wParam and lParam are the ones set by
+ // the CPropertySheet::QuerySiblings call
+
+ // return FALSE to allow other siblings to be queried, or
+ // return TRUE to stop query at this page.
+
+ return FALSE;
+ }
+
+ inline BOOL CPropertyPage::OnInitDialog()
+ {
+ // Called when the property page is created
+ // Override this function in your derived class if required.
+
+ return TRUE; // Pass Keyboard control to handle in WPARAM
+ }
+
+ inline BOOL CPropertyPage::OnKillActive()
+ {
+ // This is called in response to a PSN_KILLACTIVE notification, which
+ // is sent whenever the OK or Apply button is pressed.
+ // It provides an opportunity to validate the page contents before it's closed.
+ // Return TRUE to prevent the page from losing the activation, or FALSE to allow it.
+
+ return FALSE;
+ }
+
+ inline int CPropertyPage::OnOK()
+ {
+ // Called for each page when the OK button is pressed
+ // Override this function in your derived class if required.
+
+ // The possible return values are:
+ // PSNRET_NOERROR. The changes made to this page are valid and have been applied
+ // PSNRET_INVALID. The property sheet will not be destroyed, and focus will be returned to this page.
+ // PSNRET_INVALID_NOCHANGEPAGE. The property sheet will not be destroyed, and focus will be returned;
+
+ return PSNRET_NOERROR;
+ }
+
+ inline LRESULT CPropertyPage::OnNotify(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ LPPSHNOTIFY pNotify = (LPPSHNOTIFY)lParam;
+ switch(pNotify->hdr.code)
+ {
+ case PSN_SETACTIVE:
+ return OnSetActive();
+ case PSN_KILLACTIVE:
+ return OnKillActive();
+ case PSN_APPLY:
+ if (pNotify->lParam)
+ return OnOK();
+ else
+ return OnApply();
+ case PSN_RESET:
+ OnCancel();
+ return FALSE;
+ case PSN_QUERYCANCEL:
+ return OnQueryCancel();
+ case PSN_WIZNEXT:
+ return OnWizardNext();
+ case PSN_WIZBACK:
+ return OnWizardBack();
+ case PSN_WIZFINISH:
+ return OnWizardFinish();
+ case PSN_HELP:
+ OnHelp();
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ inline int CPropertyPage::OnSetActive()
+ {
+ // Called when a page becomes active
+ // Override this function in your derived class if required.
+
+ // Returns zero to accept the activation, or -1 to activate the next or the previous page (depending
+ // on whether the user clicked the Next or Back button). To set the activation to a particular page,
+ // return the resource identifier of the page.
+
+ return 0;
+ }
+
+ inline int CPropertyPage::OnWizardBack()
+ {
+ // This function is called when the Back button is pressed on a wizard page
+ // Override this function in your derived class if required.
+
+ // Returns 0 to allow the wizard to go to the previous page. Returns -1 to prevent the wizard
+ // from changing pages. To display a particular page, return its dialog resource identifier.
+
+ return 0;
+ }
+
+ inline INT_PTR CPropertyPage::OnWizardFinish()
+ {
+ // This function is called when the Finish button is pressed on a wizard page
+ // Override this function in your derived class if required.
+
+ // Return Value:
+ // Return non-zero to prevent the wizard from finishing.
+ // Version 5.80. and later. Return a window handle to prevent the wizard from finishing. The wizard will set the focus to that window. The window must be owned by the wizard page.
+ // Return 0 to allow the wizard to finish.
+
+ return 0; // Allow wizard to finish
+ }
+
+ inline int CPropertyPage::OnWizardNext()
+ {
+ // This function is called when the Next button is pressed on a wizard page
+ // Override this function in your derived class if required.
+
+ // Return 0 to allow the wizard to go to the next page. Return -1 to prevent the wizard from
+ // changing pages. To display a particular page, return its dialog resource identifier.
+
+ return 0;
+ }
+
+ inline BOOL CPropertyPage::PreTranslateMessage(MSG* pMsg)
+ {
+ // allow the tab control to translate keyboard input
+ if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&
+ (pMsg->wParam == VK_TAB || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT))
+ {
+ CWnd* pWndParent = GetParent();
+ if (pWndParent->SendMessage(PSM_ISDIALOGMESSAGE, 0L, (LPARAM)pMsg))
+ return TRUE;
+ }
+
+ // allow the dialog to translate keyboard input
+ if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))
+ {
+ if (IsDialogMessage(pMsg))
+ return TRUE;
+ }
+
+ return CWnd::PreTranslateMessage(pMsg);
+ }
+
+ inline LRESULT CPropertyPage::QuerySiblings(WPARAM wParam, LPARAM lParam) const
+ {
+ // Sent to a property sheet, which then forwards the message to each of its pages.
+ // Set wParam and lParam to values you want passed to the property pages.
+ // Returns the nonzero value from a page in the property sheet, or zero if no page returns a nonzero value.
+
+ assert(::IsWindow(m_hWnd));
+ return GetParent()->SendMessage(PSM_QUERYSIBLINGS, wParam, lParam);
+ }
+
+ inline void CPropertyPage::SetModified(BOOL bChanged) const
+ {
+ // The property sheet will enable the Apply button if bChanged is TRUE.
+
+ assert(::IsWindow(m_hWnd));
+
+ if (bChanged)
+ GetParent()->SendMessage(PSM_CHANGED, (WPARAM)m_hWnd, 0L);
+ else
+ GetParent()->SendMessage(PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);
+ }
+
+ inline void CPropertyPage::SetTitle(LPCTSTR szTitle)
+ {
+ if (szTitle)
+ {
+ m_Title = szTitle;
+ m_PSP.dwFlags |= PSP_USETITLE;
+ }
+ else
+ {
+ m_Title.erase();
+ m_PSP.dwFlags &= ~PSP_USETITLE;
+ }
+
+ m_PSP.pszTitle = m_Title.c_str();
+ }
+
+ inline void CPropertyPage::SetWizardButtons(DWORD dwFlags) const
+ {
+ // dwFlags: A value that specifies which wizard buttons are enabled. You can combine one or more of the following flags.
+ // PSWIZB_BACK Enable the Back button. If this flag is not set, the Back button is displayed as disabled.
+ // PSWIZB_DISABLEDFINISH Display a disabled Finish button.
+ // PSWIZB_FINISH Display an enabled Finish button.
+ // PSWIZB_NEXT Enable the Next button. If this flag is not set, the Next button is displayed as disabled.
+
+ assert (::IsWindow(m_hWnd));
+ PropSheet_SetWizButtons(::GetParent(m_hWnd), dwFlags);
+ }
+
+ inline UINT CALLBACK CPropertyPage::StaticPropSheetPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
+ {
+ assert( GetApp() );
+ UNREFERENCED_PARAMETER(hwnd);
+
+ // Note: the hwnd is always NULL
+
+ switch (uMsg)
+ {
+ case PSPCB_CREATE:
+ {
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+
+ // Store the CPropertyPage pointer in Thread Local Storage
+ pTLSData->pCWnd = (CWnd*)ppsp->lParam;
+ }
+ break;
+ }
+
+ return TRUE;
+ }
+
+ inline INT_PTR CALLBACK CPropertyPage::StaticDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ assert( GetApp() );
+
+ // Find matching CWnd pointer for this HWND
+ CPropertyPage* pPage = (CPropertyPage*)GetApp()->GetCWndFromMap(hwndDlg);
+ if (0 == pPage)
+ {
+ // matching CWnd pointer not found, so add it to HWNDMap now
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ pPage = (CPropertyPage*)pTLSData->pCWnd;
+
+ // Set the hWnd members and call DialogProc for this message
+ pPage->m_hWnd = hwndDlg;
+ pPage->AddToMap();
+ }
+
+ return pPage->DialogProc(uMsg, wParam, lParam);
+ }
+
+
+ ///////////////////////////////////////////
+ // Definitions for the CPropertySheet class
+ //
+ inline CPropertySheet::CPropertySheet(UINT nIDCaption, CWnd* pParent /* = NULL*/)
+ {
+ ZeroMemory(&m_PSH, sizeof (PROPSHEETHEADER));
+ SetTitle(LoadString(nIDCaption));
+ m_bInitialUpdate = FALSE;
+
+#ifdef _WIN32_WCE
+ m_PSH.dwSize = sizeof(PROPSHEETHEADER);
+#else
+ if (GetComCtlVersion() >= 471)
+ m_PSH.dwSize = sizeof(PROPSHEETHEADER);
+ else
+ m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;
+#endif
+
+ m_PSH.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK;
+ m_PSH.hwndParent = pParent? pParent->GetHwnd() : 0;
+ m_PSH.hInstance = GetApp()->GetInstanceHandle();
+ m_PSH.pfnCallback = (PFNPROPSHEETCALLBACK)CPropertySheet::Callback;
+ }
+
+ inline CPropertySheet::CPropertySheet(LPCTSTR pszCaption /*= NULL*/, CWnd* pParent /* = NULL*/)
+ {
+ ZeroMemory(&m_PSH, sizeof (PROPSHEETHEADER));
+ SetTitle(pszCaption);
+ m_bInitialUpdate = FALSE;
+
+#ifdef _WIN32_WCE
+ m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;
+#else
+ if (GetComCtlVersion() >= 471)
+ m_PSH.dwSize = sizeof(PROPSHEETHEADER);
+ else
+ m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;
+#endif
+
+ m_PSH.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK;
+ m_PSH.hwndParent = pParent? pParent->GetHwnd() : 0;;
+ m_PSH.hInstance = GetApp()->GetInstanceHandle();
+ m_PSH.pfnCallback = (PFNPROPSHEETCALLBACK)CPropertySheet::Callback;
+ }
+
+ inline CPropertyPage* CPropertySheet::AddPage(CPropertyPage* pPage)
+ // Adds a Property Page to the Property Sheet
+ {
+ assert(NULL != pPage);
+
+ m_vPages.push_back(PropertyPagePtr(pPage));
+
+ if (m_hWnd)
+ {
+ // property sheet already exists, so add page to it
+ PROPSHEETPAGE psp = pPage->GetPSP();
+ HPROPSHEETPAGE hpsp = ::CreatePropertySheetPage(&psp);
+ PropSheet_AddPage(m_hWnd, hpsp);
+ }
+
+ m_PSH.nPages = (int)m_vPages.size();
+
+ return pPage;
+ }
+
+ inline void CPropertySheet::BuildPageArray()
+ // Builds the PROPSHEETPAGE array
+ {
+ m_vPSP.clear();
+ std::vector<PropertyPagePtr>::iterator iter;
+ for (iter = m_vPages.begin(); iter < m_vPages.end(); ++iter)
+ m_vPSP.push_back((*iter)->GetPSP());
+
+ PROPSHEETPAGE* pPSPArray = &m_vPSP.front(); // Array of PROPSHEETPAGE
+ m_PSH.ppsp = pPSPArray;
+ }
+
+ inline void CALLBACK CPropertySheet::Callback(HWND hwnd, UINT uMsg, LPARAM lParam)
+ {
+ assert( GetApp() );
+
+ switch(uMsg)
+ {
+ //called before the dialog is created, hwnd = NULL, lParam points to dialog resource
+ case PSCB_PRECREATE:
+ {
+ LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
+
+ if(!(lpTemplate->style & WS_SYSMENU))
+ {
+ lpTemplate->style |= WS_SYSMENU;
+ }
+ }
+ break;
+
+ //called after the dialog is created
+ case PSCB_INITIALIZED:
+ {
+ // Retrieve pointer to CWnd object from Thread Local Storage
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+
+ CPropertySheet* w = (CPropertySheet*)pTLSData->pCWnd;
+ assert(w);
+
+ w->Attach(hwnd);
+ w->OnCreate();
+ }
+ break;
+ }
+ }
+
+
+ inline HWND CPropertySheet::Create(CWnd* pParent /*= 0*/)
+ // Creates a modeless Property Sheet
+ {
+ assert( GetApp() );
+
+ if (pParent)
+ {
+ m_PSH.hwndParent = pParent->GetHwnd();
+ }
+
+ BuildPageArray();
+ PROPSHEETPAGE* pPSPArray = &m_vPSP.front();
+ m_PSH.ppsp = pPSPArray;
+
+ // Create a modeless Property Sheet
+ m_PSH.dwFlags &= ~PSH_WIZARD;
+ m_PSH.dwFlags |= PSH_MODELESS;
+ HWND hWnd = (HWND)CreatePropertySheet(&m_PSH);
+
+ return hWnd;
+ }
+
+ inline INT_PTR CPropertySheet::CreatePropertySheet(LPCPROPSHEETHEADER ppsph)
+ {
+ assert( GetApp() );
+
+ INT_PTR ipResult = 0;
+
+ // Only one window per CWnd instance allowed
+ assert(!::IsWindow(m_hWnd));
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+
+ // Store the 'this' pointer in Thread Local Storage
+ pTLSData->pCWnd = this;
+
+ // Create the property sheet
+ ipResult = PropertySheet(ppsph);
+
+ return ipResult;
+ }
+
+ inline void CPropertySheet::DestroyButton(int IDButton)
+ {
+ assert(::IsWindow(m_hWnd));
+
+ HWND hwndButton = ::GetDlgItem(m_hWnd, IDButton);
+ if (hwndButton != NULL)
+ {
+ // Hide and disable the button
+ ::ShowWindow(hwndButton, SW_HIDE);
+ ::EnableWindow(hwndButton, FALSE);
+ }
+ }
+
+ inline void CPropertySheet::Destroy()
+ {
+ CWnd::Destroy();
+ m_vPages.clear();
+ }
+
+ inline int CPropertySheet::DoModal()
+ {
+ assert( GetApp() );
+
+ BuildPageArray();
+ PROPSHEETPAGE* pPSPArray = &m_vPSP.front();
+ m_PSH.ppsp = pPSPArray;
+
+ // Create the Property Sheet
+ int nResult = (int)CreatePropertySheet(&m_PSH);
+
+ m_vPages.clear();
+
+ return nResult;
+ }
+
+ inline CPropertyPage* CPropertySheet::GetActivePage() const
+ {
+ assert(::IsWindow(m_hWnd));
+
+ CPropertyPage* pPage = NULL;
+ if (m_hWnd != NULL)
+ {
+ HWND hPage = (HWND)SendMessage(PSM_GETCURRENTPAGEHWND, 0L, 0L);
+ pPage = (CPropertyPage*)FromHandle(hPage);
+ }
+
+ return pPage;
+ }
+
+ inline int CPropertySheet::GetPageCount() const
+ // Returns the number of Property Pages in this Property Sheet
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)m_vPages.size();
+ }
+
+ inline int CPropertySheet::GetPageIndex(CPropertyPage* pPage) const
+ {
+ assert(::IsWindow(m_hWnd));
+
+ for (int i = 0; i < GetPageCount(); i++)
+ {
+ if (m_vPages[i].get() == pPage)
+ return i;
+ }
+ return -1;
+ }
+
+ inline HWND CPropertySheet::GetTabControl() const
+ // Returns the handle to the Property Sheet's tab control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HWND)SendMessage(PSM_GETTABCONTROL, 0L, 0L);
+ }
+
+ inline BOOL CPropertySheet::IsModeless() const
+ {
+ return (m_PSH.dwFlags & PSH_MODELESS);
+ }
+
+ inline BOOL CPropertySheet::IsWizard() const
+ {
+ return (m_PSH.dwFlags & PSH_WIZARD);
+ }
+
+ inline void CPropertySheet::RemovePage(CPropertyPage* pPage)
+ // Removes a Property Page from the Property Sheet
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int nPage = GetPageIndex(pPage);
+ if (m_hWnd != NULL)
+ SendMessage(m_hWnd, PSM_REMOVEPAGE, nPage, 0L);
+
+ m_vPages.erase(m_vPages.begin() + nPage, m_vPages.begin() + nPage+1);
+ m_PSH.nPages = (int)m_vPages.size();
+ }
+
+ inline BOOL CPropertySheet::PreTranslateMessage(MSG* pMsg)
+ {
+ // allow sheet to translate Ctrl+Tab, Shift+Ctrl+Tab, Ctrl+PageUp, and Ctrl+PageDown
+ if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&
+ (pMsg->wParam == VK_TAB || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT))
+ {
+ if (SendMessage(PSM_ISDIALOGMESSAGE, 0L, (LPARAM)pMsg))
+ return TRUE;
+ }
+
+ // allow the dialog to translate keyboard input
+ if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))
+ {
+ return GetActivePage()->PreTranslateMessage(pMsg);
+ }
+
+ return CWnd::PreTranslateMessage(pMsg);
+ }
+
+ inline BOOL CPropertySheet::SetActivePage(int nPage)
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(m_hWnd, PSM_SETCURSEL, nPage, 0L);
+ }
+
+ inline BOOL CPropertySheet::SetActivePage(CPropertyPage* pPage)
+ {
+ assert(::IsWindow(m_hWnd));
+ int nPage = GetPageIndex(pPage);
+ if ((nPage >= 0))
+ return SetActivePage(nPage);
+
+ return FALSE;
+ }
+
+ inline void CPropertySheet::SetIcon(UINT idIcon)
+ {
+ m_PSH.pszIcon = MAKEINTRESOURCE(idIcon);
+ m_PSH.dwFlags |= PSH_USEICONID;
+ }
+
+ inline void CPropertySheet::SetTitle(LPCTSTR szTitle)
+ {
+ if (szTitle)
+ m_Title = szTitle;
+ else
+ m_Title.erase();
+
+ m_PSH.pszCaption = m_Title.c_str();
+ }
+
+ inline void CPropertySheet::SetWizardMode(BOOL bWizard)
+ {
+ if (bWizard)
+ m_PSH.dwFlags |= PSH_WIZARD;
+ else
+ m_PSH.dwFlags &= ~PSH_WIZARD;
+ }
+
+ inline LRESULT CPropertySheet::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ LPWINDOWPOS lpWinPos = (LPWINDOWPOS)lParam;
+ if (lpWinPos->flags & SWP_SHOWWINDOW)
+ {
+ if (!m_bInitialUpdate)
+ // The first window positioning with the window visible
+ OnInitialUpdate();
+ m_bInitialUpdate = TRUE;
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ m_bInitialUpdate = FALSE;
+ break;
+
+ case WM_SYSCOMMAND:
+ if ((SC_CLOSE == wParam) && (m_PSH.dwFlags & PSH_MODELESS))
+ {
+ Destroy();
+ return 0L;
+ }
+ break;
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+}
+
+#endif // _WIN32XX_PROPERTYSHEET_H_
diff --git a/mmc_updater/depends/win32cpp/rebar.h b/mmc_updater/depends/win32cpp/rebar.h
new file mode 100644
index 00000000..1a339dca
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/rebar.h
@@ -0,0 +1,709 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+#ifndef _WIN32XX_REBAR_H_
+#define _WIN32XX_REBAR_H_
+
+#include "wincore.h"
+#include "gdi.h"
+
+
+namespace Win32xx
+{
+
+ struct ReBarTheme
+ {
+ BOOL UseThemes; // TRUE if themes are used
+ COLORREF clrBkgnd1; // Colour 1 for rebar background
+ COLORREF clrBkgnd2; // Colour 2 for rebar background
+ COLORREF clrBand1; // Colour 1 for rebar band background. Use NULL if not required
+ COLORREF clrBand2; // Colour 2 for rebar band background. Use NULL if not required
+ BOOL FlatStyle; // Bands are rendered with flat rather than raised style
+ BOOL BandsLeft; // Position bands left on rearrange
+ BOOL LockMenuBand; // Lock MenuBar's band in dedicated top row, without gripper
+ BOOL RoundBorders; // Use rounded band borders
+ BOOL ShortBands; // Allows bands to be shorter than maximum available width
+ BOOL UseLines; // Displays horizontal lines between bands
+ };
+
+ ////////////////////////////////////
+ // Declaration of the CReBar class
+ //
+ class CReBar : public CWnd
+ {
+ public:
+ CReBar();
+ virtual ~CReBar();
+
+ // Operations
+ BOOL DeleteBand(const int nBand) const;
+ int HitTest(RBHITTESTINFO& rbht);
+ HWND HitTest(POINT pt);
+ int IDToIndex(UINT uBandID) const;
+ BOOL InsertBand(const int nBand, REBARBANDINFO& rbbi) const;
+ BOOL IsBandVisible(int nBand) const;
+ void MaximizeBand(UINT uBand, BOOL fIdeal = FALSE);
+ void MinimizeBand(UINT uBand);
+ BOOL MoveBand(UINT uFrom, UINT uTo);
+ void MoveBandsLeft();
+ BOOL ResizeBand(const int nBand, const CSize& sz) const;
+ BOOL ShowGripper(int nBand, BOOL fShow) const;
+ BOOL ShowBand(int nBand, BOOL fShow) const;
+ BOOL SizeToRect(CRect& rect) const;
+
+ // Attributes
+ int GetBand(const HWND hWnd) const;
+ CRect GetBandBorders(int nBand) const;
+ int GetBandCount() const;
+ BOOL GetBandInfo(const int nBand, REBARBANDINFO& rbbi) const;
+ CRect GetBandRect(int i) const;
+ UINT GetBarHeight() const;
+ BOOL GetBarInfo(REBARINFO& rbi) const;
+ HWND GetMenuBar() {return m_hMenuBar;}
+ ReBarTheme& GetReBarTheme() {return m_Theme;}
+ UINT GetRowCount() const;
+ int GetRowHeight(int nRow) const;
+ UINT GetSizeofRBBI() const;
+ HWND GetToolTips() const;
+ BOOL SetBandBitmap(const int nBand, const CBitmap* pBackground) const;
+ BOOL SetBandColor(const int nBand, const COLORREF clrFore, const COLORREF clrBack) const;
+ BOOL SetBandInfo(const int nBand, REBARBANDINFO& rbbi) const;
+ BOOL SetBarInfo(REBARINFO& rbi) const;
+ void SetMenuBar(HWND hMenuBar) {m_hMenuBar = hMenuBar;}
+ void SetReBarTheme(ReBarTheme& Theme);
+
+ protected:
+ //Overridables
+ virtual BOOL OnEraseBkgnd(CDC* pDC);
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CReBar(const CReBar&); // Disable copy construction
+ CReBar& operator = (const CReBar&); // Disable assignment operator
+
+ ReBarTheme m_Theme;
+ BOOL m_bIsDragging;
+ HWND m_hMenuBar;
+ LPARAM m_Orig_lParam;
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ ///////////////////////////////////
+ // Definitions for the CReBar class
+ //
+ inline CReBar::CReBar() : m_bIsDragging(FALSE), m_hMenuBar(0), m_Orig_lParam(0L)
+ {
+ ZeroMemory(&m_Theme, sizeof(ReBarTheme));
+ }
+
+ inline CReBar::~CReBar()
+ {
+ }
+
+ inline BOOL CReBar::DeleteBand(int nBand) const
+ // Deletes a band from a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(RB_DELETEBAND, nBand, 0L);
+ }
+
+ inline int CReBar::GetBand(HWND hWnd) const
+ // Returns the zero based band number for this window handle
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int nResult = -1;
+ if (NULL == hWnd) return nResult;
+
+ for (int nBand = 0; nBand < GetBandCount(); ++nBand)
+ {
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_CHILD;
+ GetBandInfo(nBand, rbbi);
+ if (rbbi.hwndChild == hWnd)
+ nResult = nBand;
+ }
+
+ return nResult;
+ }
+
+ inline CRect CReBar::GetBandBorders(int nBand) const
+ // Retrieves the borders of a band.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ CRect rc;
+ SendMessage(RB_GETBANDBORDERS, nBand, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline int CReBar::GetBandCount() const
+ // Retrieves the count of bands currently in the rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(RB_GETBANDCOUNT, 0L, 0L);
+ }
+
+ inline BOOL CReBar::GetBandInfo(int nBand, REBARBANDINFO& rbbi) const
+ // Retrieves information about a specified band in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(nBand >= 0);
+
+ // REBARBANDINFO describes individual BAND characteristics
+ rbbi.cbSize = GetSizeofRBBI();
+ return (BOOL)SendMessage(RB_GETBANDINFO, nBand, (LPARAM)&rbbi);
+ }
+
+ inline CRect CReBar::GetBandRect(int i) const
+ // Retrieves the bounding rectangle for a given band in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ SendMessage(RB_GETRECT, i, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline UINT CReBar::GetBarHeight() const
+ // Retrieves the height of the rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)SendMessage(RB_GETBARHEIGHT, 0L, 0L);
+ }
+
+ inline BOOL CReBar::GetBarInfo(REBARINFO& rbi) const
+ // Retrieves information about the rebar control and the image list it uses.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ // REBARINFO describes overall rebar control characteristics
+ rbi.cbSize = GetSizeofRBBI();
+ return (BOOL)SendMessage(RB_GETBARINFO, 0L, (LPARAM)&rbi);
+ }
+
+ inline UINT CReBar::GetRowCount() const
+ // Retrieves the number of rows of bands in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)SendMessage(RB_GETROWCOUNT, 0L, 0L);
+ }
+
+ inline int CReBar::GetRowHeight(int nRow) const
+ // Retrieves the height of a specified row in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(RB_GETROWHEIGHT, nRow, 0L);
+ }
+
+ inline UINT CReBar::GetSizeofRBBI() const
+ // The size of the REBARBANDINFO struct changes according to _WIN32_WINNT
+ // sizeof(REBARBANDINFO) can report an incorrect size for older Window versions,
+ // or newer Window version without XP themes enabled.
+ // Use this function to get a safe size for REBARBANDINFO.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ UINT uSizeof = sizeof(REBARBANDINFO);
+
+ #if defined REBARBANDINFO_V6_SIZE // only defined for VS2008 or higher
+ #if !defined (_WIN32_WINNT) || _WIN32_WINNT >= 0x0600
+ if ((GetWinVersion() < 2600) || (GetComCtlVersion() < 610)) // Vista and Vista themes?
+ uSizeof = REBARBANDINFO_V6_SIZE;
+ #endif
+ #endif
+
+ return uSizeof;
+ }
+
+ inline HWND CReBar::GetToolTips() const
+ // Retrieves the handle to any ToolTip control associated with the rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HWND)SendMessage(RB_GETTOOLTIPS, 0L, 0L);
+ }
+
+ inline int CReBar::HitTest(RBHITTESTINFO& rbht)
+ // Determines which portion of a rebar band is at a given point on the screen,
+ // if a rebar band exists at that point.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(RB_HITTEST, 0L, (LPARAM)&rbht);
+ }
+
+ inline HWND CReBar::HitTest(POINT pt)
+ // Return the child HWND at the given point
+ {
+ assert(::IsWindow(m_hWnd));
+
+ // Convert the point to client co-ordinates
+ ScreenToClient(pt);
+
+ // Get the rebar band with the point
+ RBHITTESTINFO rbhti = {0};
+ rbhti.pt = pt;
+ int iBand = HitTest(rbhti);
+
+ if (iBand >= 0)
+ {
+ // Get the rebar band's hWnd
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_CHILD;
+ GetBandInfo(iBand, rbbi);
+
+ return rbbi.hwndChild;
+ }
+ else
+ return NULL;
+ }
+
+ inline int CReBar::IDToIndex(UINT uBandID) const
+ // Converts a band identifier to a band index in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(RB_IDTOINDEX, (WPARAM)uBandID, 0L);
+ }
+
+ inline BOOL CReBar::InsertBand(int nBand, REBARBANDINFO& rbbi) const
+ // Inserts a new band in a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ rbbi.cbSize = GetSizeofRBBI();
+ return (BOOL)SendMessage(RB_INSERTBAND, nBand, (LPARAM)&rbbi);
+ }
+
+ inline BOOL CReBar::IsBandVisible(int nBand) const
+ // Returns true if the band is visible
+ {
+ assert(::IsWindow(m_hWnd));
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_STYLE;
+ GetBandInfo(nBand, rbbi);
+
+ return !(rbbi.fStyle & RBBS_HIDDEN);
+ }
+
+ inline BOOL CReBar::OnEraseBkgnd(CDC* pDC)
+ {
+ BOOL Erase = TRUE;
+ if (!m_Theme.UseThemes)
+ Erase = FALSE;
+
+ if (!m_Theme.clrBkgnd1 && !m_Theme.clrBkgnd2 && !m_Theme.clrBand1 && !m_Theme.clrBand2)
+ Erase = FALSE;
+
+ if (Erase)
+ {
+ CRect rcReBar = GetClientRect();
+ int BarWidth = rcReBar.Width();
+ int BarHeight = rcReBar.Height();
+
+ // Create and set up our memory DC
+ CMemDC MemDC(pDC);
+ MemDC.CreateCompatibleBitmap(pDC, BarWidth, BarHeight);
+
+ // Draw to ReBar background to the memory DC
+ rcReBar.right = 600;
+ MemDC.GradientFill(m_Theme.clrBkgnd1, m_Theme.clrBkgnd2, rcReBar, TRUE);
+ if (BarWidth >= 600)
+ {
+ rcReBar.left = 600;
+ rcReBar.right = BarWidth;
+ MemDC.SolidFill(m_Theme.clrBkgnd2, rcReBar);
+ }
+
+ if (m_Theme.clrBand1 || m_Theme.clrBand2)
+ {
+ // Draw the individual band backgrounds
+ for (int nBand = 0 ; nBand < GetBandCount(); ++nBand)
+ {
+ if (IsBandVisible(nBand))
+ {
+ if (nBand != GetBand(m_hMenuBar))
+ {
+ // Determine the size of this band
+ CRect rcBand = GetBandRect(nBand);
+
+ // Determine the size of the child window
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_CHILD ;
+ GetBandInfo(nBand, rbbi);
+ CRect rcChild;
+ ::GetWindowRect(rbbi.hwndChild, &rcChild);
+ int ChildWidth = rcChild.right - rcChild.left;
+
+ // Determine our drawing rectangle
+ CRect rcDraw = rcBand;
+ rcDraw.bottom = rcDraw.top + (rcBand.bottom - rcBand.top)/2;
+ int xPad = IsXPThemed()? 2: 0;
+ rcDraw.left -= xPad;
+
+ // Fill the Source CDC with the band's background
+ CMemDC SourceDC(pDC);
+ SourceDC.CreateCompatibleBitmap(pDC, BarWidth, BarHeight);
+ CRect rcBorder = GetBandBorders(nBand);
+ rcDraw.right = rcBand.left + ChildWidth + rcBorder.left;
+ SourceDC.SolidFill(m_Theme.clrBand1, rcDraw);
+ rcDraw.top = rcDraw.bottom;
+ rcDraw.bottom = rcBand.bottom;
+ SourceDC.GradientFill(m_Theme.clrBand1, m_Theme.clrBand2, rcDraw, FALSE);
+
+ // Set Curve amount for rounded edges
+ int Curve = m_Theme.RoundBorders? 12 : 0;
+
+ // Create our mask for rounded edges using RoundRect
+ CMemDC MaskDC(pDC);
+ MaskDC.CreateCompatibleBitmap(pDC, BarWidth, BarHeight);
+
+ rcDraw.top = rcBand.top;
+ if (!m_Theme.FlatStyle)
+ ::InflateRect(&rcDraw, 1, 1);
+
+ int left = rcDraw.left;
+ int right = rcDraw.right;
+ int top = rcDraw.top;
+ int bottom = rcDraw.bottom;
+ int cx = rcDraw.right - rcBand.left + xPad;
+ int cy = rcDraw.bottom - rcBand.top;
+
+ if (m_Theme.FlatStyle)
+ {
+ MaskDC.SolidFill(RGB(0,0,0), rcDraw);
+ MaskDC.BitBlt(left, top, cx, cy, &MaskDC, left, top, PATINVERT);
+ MaskDC.RoundRect(left, top, right, bottom, Curve, Curve);
+ }
+ else
+ {
+ MaskDC.SolidFill(RGB(0,0,0), rcDraw);
+ MaskDC.RoundRect(left, top, right, bottom, Curve, Curve);
+ MaskDC.BitBlt(left, top, cx, cy, &MaskDC, left, top, PATINVERT);
+ }
+
+ // Copy Source DC to Memory DC using the RoundRect mask
+ MemDC.BitBlt(left, top, cx, cy, &SourceDC, left, top, SRCINVERT);
+ MemDC.BitBlt(left, top, cx, cy, &MaskDC, left, top, SRCAND);
+ MemDC.BitBlt(left, top, cx, cy, &SourceDC, left, top, SRCINVERT);
+
+ // Extra drawing to prevent jagged edge while moving bands
+ if (m_bIsDragging)
+ {
+ CClientDC ReBarDC(this);
+ ReBarDC.BitBlt(rcDraw.right - ChildWidth, rcDraw.top, ChildWidth, cy, &MemDC, rcDraw.right - ChildWidth, rcDraw.top, SRCCOPY);
+ }
+ }
+ }
+ }
+ }
+
+ if (m_Theme.UseLines)
+ {
+ // Draw lines between bands
+ for (int j = 0; j < GetBandCount()-1; ++j)
+ {
+ rcReBar = GetBandRect(j);
+ rcReBar.left = MAX(0, rcReBar.left - 4);
+ rcReBar.bottom +=2;
+ MemDC.DrawEdge(rcReBar, EDGE_ETCHED, BF_BOTTOM | BF_ADJUST);
+ }
+ }
+
+ // Copy the Memory DC to the window's DC
+ pDC->BitBlt(0, 0, BarWidth, BarHeight, &MemDC, 0, 0, SRCCOPY);
+ }
+
+ return Erase;
+ }
+
+ inline void CReBar::PreCreate(CREATESTRUCT &cs)
+ // Sets the CREATESTRUCT paramaters prior to window creation
+ {
+ cs.style = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
+ CCS_NODIVIDER | RBS_VARHEIGHT | RBS_BANDBORDERS ;
+
+ cs.cy = 100;
+ }
+
+ inline void CReBar::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = REBARCLASSNAME;
+ }
+
+ inline void CReBar::MaximizeBand(UINT uBand, BOOL fIdeal /*= FALSE*/)
+ // Resizes a band in a rebar control to either its ideal or largest size.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(RB_MAXIMIZEBAND, (WPARAM)uBand, (LPARAM)fIdeal);
+ }
+
+ inline void CReBar::MinimizeBand(UINT uBand)
+ // Resizes a band in a rebar control to its smallest size.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(RB_MINIMIZEBAND, (WPARAM)uBand, 0L);
+ }
+
+ inline BOOL CReBar::MoveBand(UINT uFrom, UINT uTo)
+ // Moves a band from one index to another.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(RB_MOVEBAND, (WPARAM)uFrom, (LPARAM)uTo);
+ }
+
+ inline void CReBar::MoveBandsLeft()
+ // Repositions the bands so they are left justified
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int OldrcTop = -1;
+ for (int nBand = GetBandCount() -1; nBand >= 0; --nBand)
+ {
+ CRect rc = GetBandRect(nBand);
+ if (rc.top != OldrcTop)
+ {
+ // Maximize the last band on each row
+ if (IsBandVisible(nBand))
+ {
+ ::SendMessage(GetHwnd(), RB_MAXIMIZEBAND, nBand, 0L);
+ OldrcTop = rc.top;
+ }
+ }
+ }
+ }
+
+ inline BOOL CReBar::ResizeBand(int nBand, const CSize& sz) const
+ // Sets a band's size
+ {
+ assert(::IsWindow(m_hWnd));
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_SIZE;
+
+ GetBandInfo(nBand, rbbi);
+ rbbi.cx = sz.cx + 2;
+ rbbi.cxMinChild = sz.cx + 2;
+ rbbi.cyMinChild = sz.cy;
+ rbbi.cyMaxChild = sz.cy;
+
+ return SetBandInfo(nBand, rbbi );
+ }
+
+ inline BOOL CReBar::SetBandBitmap(int nBand, const CBitmap* pBackground) const
+ // Sets the band's bitmaps
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pBackground);
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_STYLE;
+ GetBandInfo(nBand, rbbi);
+ rbbi.fMask |= RBBIM_BACKGROUND;
+ rbbi.hbmBack = *pBackground;
+
+ return (BOOL)SendMessage(RB_SETBANDINFO, nBand, (LPARAM)&rbbi);
+ }
+
+ inline BOOL CReBar::SetBandColor(int nBand, COLORREF clrFore, COLORREF clrBack) const
+ // Sets the band's color
+ // Note: No effect with XP themes enabled
+ // No effect if a bitmap has been set
+ {
+ assert(::IsWindow(m_hWnd));
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_COLORS;
+ rbbi.clrFore = clrFore;
+ rbbi.clrBack = clrBack;
+
+ return (BOOL)SendMessage(RB_SETBANDINFO, nBand, (LPARAM)&rbbi);
+ }
+
+ inline BOOL CReBar::SetBandInfo(int nBand, REBARBANDINFO& rbbi) const
+ // Sets the characteristics of a rebar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(nBand >= 0);
+
+ // REBARBANDINFO describes individual BAND characteristics0
+ rbbi.cbSize = GetSizeofRBBI();
+ return (BOOL)SendMessage(RB_SETBANDINFO, nBand, (LPARAM)&rbbi);
+ }
+
+ inline BOOL CReBar::SetBarInfo(REBARINFO& rbi) const
+ // REBARINFO associates an image list with the rebar
+ // A band will also need to set RBBIM_IMAGE
+ {
+ assert(::IsWindow(m_hWnd));
+
+ rbi.cbSize = GetSizeofRBBI();
+ return (BOOL)SendMessage(RB_SETBARINFO, 0L, (LPARAM)&rbi);
+ }
+
+ inline void CReBar::SetReBarTheme(ReBarTheme& Theme)
+ {
+ m_Theme.UseThemes = Theme.UseThemes;
+ m_Theme.clrBkgnd1 = Theme.clrBkgnd1;
+ m_Theme.clrBkgnd2 = Theme.clrBkgnd2;
+ m_Theme.clrBand1 = Theme.clrBand1;
+ m_Theme.clrBand2 = Theme.clrBand2;
+ m_Theme.BandsLeft = Theme.BandsLeft;
+ m_Theme.LockMenuBand = Theme.LockMenuBand;
+ m_Theme.ShortBands = Theme.ShortBands;
+ m_Theme.UseLines = Theme.UseLines;
+ m_Theme.FlatStyle = Theme.FlatStyle;
+ m_Theme.RoundBorders = Theme.RoundBorders;
+
+ if (IsWindow())
+ {
+ if (m_Theme.LockMenuBand)
+ ShowGripper(GetBand(m_hMenuBar), FALSE);
+ else
+ ShowGripper(GetBand(m_hMenuBar), TRUE);
+
+ Invalidate();
+ }
+ }
+
+ inline BOOL CReBar::ShowBand(int nBand, BOOL fShow) const
+ // Show or hide a band
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(RB_SHOWBAND, (WPARAM)nBand, (LPARAM)fShow);
+ }
+
+ inline BOOL CReBar::ShowGripper(int nBand, BOOL fShow) const
+ // Show or hide the band's gripper
+ {
+ assert(::IsWindow(m_hWnd));
+
+ REBARBANDINFO rbbi = {0};
+ rbbi.cbSize = GetSizeofRBBI();
+ rbbi.fMask = RBBIM_STYLE;
+ GetBandInfo(nBand, rbbi);
+ if (fShow)
+ {
+ rbbi.fStyle |= RBBS_GRIPPERALWAYS;
+ rbbi.fStyle &= ~RBBS_NOGRIPPER;
+ }
+ else
+ {
+ rbbi.fStyle &= ~RBBS_GRIPPERALWAYS;
+ rbbi.fStyle |= RBBS_NOGRIPPER;
+ }
+
+ return SetBandInfo(nBand, rbbi);
+ }
+
+ inline BOOL CReBar::SizeToRect(CRect& rect) const
+ // Attempts to find the best layout of the bands for the given rectangle.
+ // The rebar bands will be arranged and wrapped as necessary to fit the rectangle.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(RB_SIZETORECT, 0, (LPARAM) (LPRECT)rect);
+ }
+
+ inline LRESULT CReBar::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_MOUSEMOVE:
+ if (m_Theme.UseThemes && m_Theme.LockMenuBand)
+ {
+ // We want to lock the first row in place, but allow other bands to move!
+ // Use move messages to limit the resizing of bands
+ int y = GET_Y_LPARAM(lParam);
+
+ if (y <= GetRowHeight(0))
+ return 0L; // throw this message away
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ m_Orig_lParam = lParam; // Store the x,y position
+ m_bIsDragging = TRUE;
+ break;
+ case WM_LBUTTONUP:
+ if (m_Theme.UseThemes && m_Theme.LockMenuBand)
+ {
+ // Use move messages to limit the resizing of bands
+ int y = GET_Y_LPARAM(lParam);
+
+ if (y <= GetRowHeight(0))
+ {
+ // Use x,y from WM_LBUTTONDOWN for WM_LBUTTONUP position
+ lParam = m_Orig_lParam;
+ }
+ }
+ m_bIsDragging = FALSE;
+ break;
+ case UWM_GETREBARTHEME:
+ {
+ ReBarTheme& rm = GetReBarTheme();
+ return (LRESULT)&rm;
+ }
+ case UWM_TOOLBAR_RESIZE:
+ {
+ HWND hToolBar = (HWND)wParam;
+ LPSIZE pToolBarSize = (LPSIZE)lParam;
+ ResizeBand(GetBand(hToolBar), *pToolBarSize);
+ }
+ break;
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+} // namespace Win32xx
+
+#endif // #ifndef _WIN32XX_REBAR_H_
diff --git a/mmc_updater/depends/win32cpp/release notes.txt b/mmc_updater/depends/win32cpp/release notes.txt
new file mode 100644
index 00000000..bc3114da
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/release notes.txt
@@ -0,0 +1,116 @@
+About Win32++
+-------------
+Win32++ is simple and easy to understand framework for developing Win32
+applications using C++. It brings an object oriented approach to programming
+directly with the Win32 API. Each window created is a C++ class object capable
+of having its own window procedure for routing messages.
+
+Win32++ supports the following compilers and development environments:
+* Borland C++ Compiler 5.5
+* Borland Developer Studio 2006
+* Dev-C++
+* Microsoft Visual C++ Toolkit 2003
+* Microsoft Visual C++ 2005 Express Edition
+* Microsoft Visual C++ 2008 Express Edition
+* Microsoft Visual C++ 2010 Express Edition
+* Microsoft Visual Studio 6.0
+* Microsoft Visual Studio.net 2003
+* Microsoft Visual Studio.net 2005
+* Microsoft Visual Studio.net 2008
+* Microsoft Visual Studio.net 2010
+* MinGW compiler
+
+Win32++ supports the following operating systems
+* Windows 95
+* Windows 98
+* Windows ME
+* Windows NT 4
+* Windows 2000
+* Windows XP (32bit and 64bit)
+* Windows 2003 Server (32bit and 64bit)
+* Windows Vista (32bit and 64bit)
+* Windows 2008 Server (32bit and 64bit)
+* Windows 7 (32 bit and 64 bit)
+* Windows CE from WCE400 (Windows mobile 2003) to WCE600 (Windows mobile 6)
+
+
+Features
+--------
+Win32++ code has the following features
+ * Object Orientated
+ * Subclassing support
+ * Notification reflection and message reflection
+ * Unicode compliant, with multilingual support
+ * Multi-threaded support.
+ * Tracing
+ * 64 bit support
+ * Windows 7 ribbon support
+ * Themes support
+ * Network support (including IP version 6)
+ * Docking windows
+ * Tabbed MDIs
+
+Frames produced by Win32++ include the following:
+ * Rebar
+ * Menubar
+ * Toolbar
+ * Status bar
+ * Tool tips
+
+About the file downloads
+------------------------
+The file download from Sourceforge includes the following:
+ * The Win32++ library itself
+ * Help for the library
+ * A set of tutorials
+ * A collection of sample applications
+
+The sample applications include:
+ * Browser - An Internet browser application with an event sink.
+ * Dialog - An example of a simple dialog application.
+ * DialogDemo - An interative dialog application demonstrating slider controls and progress bars.
+ * DialogResizing - An example of a resizable dialog.
+ * DialogTab - A dialog application with a tab control.
+ * DirectX - A simple DirectX application.
+ * DLL - Shows how to run Win32++ from within a DLL
+ * Dock - An example of a simple docking application.
+ * DockContainer - An example of a docking application which incorporates containers.
+ * DockTabbedMDI - An example of a docking application with containers and a tabbed MDI.
+ * Explorer - A Windows Explorer-like application.
+ * FastGDI - An application which demonstrates direct manipulation of a bitmap's colour.
+ * FormDemo - An example of a modeless dialog within a frame.
+ * Frame - A simple frame application.
+ * GDIPlus - Demonstrates how to use GDI+ with Win32++.
+ * MDIFrame - A simple MDI frame application.
+ * MDIFrameDemo - Demonstrates some additional features of MDI frames.
+ * MDIFrameSplitter - Demonstrates how to implement splitter windows in MDI Child windows.
+ * Networking - Demonstrates the use of networking.
+ * Notepad - A simple text editor with printing.
+ * Performance - Measures Win32++'s message handling speed.
+ * Picture - A simple picture rendering application.
+ * PropertySheets - A demonstration of property sheets.
+ * RibbonFrame - Demonstrates how to use the Windows 7 ribbon with a frame.
+ * RibbonSimple - Demonstrates how to use the Windwos 7 ribbon with a simple window.
+ * Scribble - A simple drawing application.
+ * Simple - Creates a simple window.
+ * Splitter - Demonstrates how to use dockers to create splitter windows.
+ * TabDemo - Demonstrates the use of a CTab control in a frame.
+ * TaskDialog - Demonstrates the use of task dialogs (available on Vista and above).
+ * Themes - Demonstrates how to customise the colours for rebar and toolbar controls.
+ * Threads - Demonstrates multi-threaded Windows.
+ * Tray - Demonstrates how to "minimise" an application to the system tray.
+ * WinCE samples - A small collection of samples for Windows CE
+
+Getting Started
+---------------
+Each file download includes the project files for Dev-C++, CodeBlocks and the
+various compilers from Microsoft. CodeBlocks is an IDE (Integrated Development
+Environment) that supports GNU GCC, Borland Developer Studio 2006 and Microsoft
+C++ Toolkit 2003.
+
+You can start with one of the sample programs, and add your code. Alternatively
+you can start with the projects and sample code provided in the "new projects"
+folder.
+
+For additional information on getting started, refer to the help included
+in the documentation. \ No newline at end of file
diff --git a/mmc_updater/depends/win32cpp/ribbon.h b/mmc_updater/depends/win32cpp/ribbon.h
new file mode 100644
index 00000000..9f6dac5c
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/ribbon.h
@@ -0,0 +1,527 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////
+// ribbon.h
+// Declaration of the following classes:
+// CRibbon and CRibbonFrame
+//
+
+#ifndef _WIN32XX_RIBBON_H_
+#define _WIN32XX_RIBBON_H_
+
+
+// Notes: 1) The Windows 7 SDK must be installed and its directories added to the IDE
+// 2) The ribbon only works on OS Windows 7 and above
+
+//#include <strsafe.h>
+#include <UIRibbon.h> // Contained within the Windows 7 SDK
+#include <UIRibbonPropertyHelpers.h>
+
+namespace Win32xx
+{
+ // Defines the callback entry-point methods for the Ribbon framework.
+ class CRibbon : public IUICommandHandler, public IUIApplication
+ {
+ public:
+ CRibbon() : m_cRef(1), m_pRibbonFramework(NULL) {}
+ ~CRibbon();
+
+ // IUnknown methods.
+ STDMETHOD_(ULONG, AddRef());
+ STDMETHOD_(ULONG, Release());
+ STDMETHOD(QueryInterface(REFIID iid, void** ppv));
+
+ // IUIApplication methods
+ STDMETHOD(OnCreateUICommand)(UINT nCmdID, __in UI_COMMANDTYPE typeID,
+ __deref_out IUICommandHandler** ppCommandHandler);
+
+ STDMETHOD(OnDestroyUICommand)(UINT32 commandId, __in UI_COMMANDTYPE typeID,
+ __in_opt IUICommandHandler* commandHandler);
+
+ STDMETHOD(OnViewChanged)(UINT viewId, __in UI_VIEWTYPE typeId, __in IUnknown* pView,
+ UI_VIEWVERB verb, INT uReasonCode);
+
+ // IUICommandHandle methods
+ STDMETHODIMP Execute(UINT nCmdID, UI_EXECUTIONVERB verb, __in_opt const PROPERTYKEY* key, __in_opt const PROPVARIANT* ppropvarValue,
+ __in_opt IUISimplePropertySet* pCommandExecutionProperties);
+
+ STDMETHODIMP UpdateProperty(UINT nCmdID, __in REFPROPERTYKEY key, __in_opt const PROPVARIANT* ppropvarCurrentValue,
+ __out PROPVARIANT* ppropvarNewValue);
+
+ bool virtual CreateRibbon(CWnd* pWnd);
+ void virtual DestroyRibbon();
+ IUIFramework* GetRibbonFramework() { return m_pRibbonFramework; }
+
+ private:
+ IUIFramework* m_pRibbonFramework;
+ LONG m_cRef; // Reference count.
+
+ };
+
+
+ class CRibbonFrame : public CFrame, public CRibbon
+ {
+ public:
+ // A nested class for the MRU item properties
+ class CRecentFiles : public IUISimplePropertySet
+ {
+ public:
+ CRecentFiles(PWSTR wszFullPath);
+ ~CRecentFiles() {}
+
+ // IUnknown methods.
+ STDMETHODIMP_(ULONG) AddRef();
+ STDMETHODIMP_(ULONG) Release();
+ STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
+
+ // IUISimplePropertySet methods
+ STDMETHODIMP GetValue(__in REFPROPERTYKEY key, __out PROPVARIANT *value);
+
+ private:
+ LONG m_cRef; // Reference count.
+ WCHAR m_wszDisplayName[MAX_PATH];
+ WCHAR m_wszFullPath[MAX_PATH];
+ };
+
+ typedef Shared_Ptr<CRecentFiles> RecentFilesPtr;
+
+ CRibbonFrame() : m_uRibbonHeight(0) {}
+ virtual ~CRibbonFrame() {}
+ virtual CRect GetViewRect() const;
+ virtual void OnCreate();
+ virtual void OnDestroy();
+ virtual STDMETHODIMP OnViewChanged(UINT32 viewId, UI_VIEWTYPE typeId, IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode);
+ virtual HRESULT PopulateRibbonRecentItems(__deref_out PROPVARIANT* pvarValue);
+ virtual void UpdateMRUMenu();
+
+ UINT GetRibbonHeight() const { return m_uRibbonHeight; }
+
+ private:
+ std::vector<RecentFilesPtr> m_vRecentFiles;
+ void SetRibbonHeight(UINT uRibbonHeight) { m_uRibbonHeight = uRibbonHeight; }
+ UINT m_uRibbonHeight;
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+ //////////////////////////////////////////////
+ // Definitions for the CRibbon class
+ //
+
+ inline CRibbon::~CRibbon()
+ {
+ // Reference count must be 1 or we have a leak!
+ assert(m_cRef == 1);
+ }
+
+ // IUnknown method implementations.
+ inline STDMETHODIMP_(ULONG) CRibbon::AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ inline STDMETHODIMP_(ULONG) CRibbon::Release()
+ {
+ LONG cRef = InterlockedDecrement(&m_cRef);
+ return cRef;
+ }
+
+ inline STDMETHODIMP CRibbon::Execute(UINT nCmdID, UI_EXECUTIONVERB verb, __in_opt const PROPERTYKEY* key, __in_opt const PROPVARIANT* ppropvarValue,
+ __in_opt IUISimplePropertySet* pCommandExecutionProperties)
+ {
+ UNREFERENCED_PARAMETER (nCmdID);
+ UNREFERENCED_PARAMETER (verb);
+ UNREFERENCED_PARAMETER (key);
+ UNREFERENCED_PARAMETER (ppropvarValue);
+ UNREFERENCED_PARAMETER (pCommandExecutionProperties);
+
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CRibbon::QueryInterface(REFIID iid, void** ppv)
+ {
+ if (iid == __uuidof(IUnknown))
+ {
+ *ppv = static_cast<IUnknown*>(static_cast<IUIApplication*>(this));
+ }
+ else if (iid == __uuidof(IUICommandHandler))
+ {
+ *ppv = static_cast<IUICommandHandler*>(this);
+ }
+ else if (iid == __uuidof(IUIApplication))
+ {
+ *ppv = static_cast<IUIApplication*>(this);
+ }
+ else
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+ // Called by the Ribbon framework for each command specified in markup, to bind the Command to an IUICommandHandler.
+ inline STDMETHODIMP CRibbon::OnCreateUICommand(UINT nCmdID, __in UI_COMMANDTYPE typeID,
+ __deref_out IUICommandHandler** ppCommandHandler)
+ {
+ UNREFERENCED_PARAMETER(typeID);
+ UNREFERENCED_PARAMETER(nCmdID);
+
+ // By default we use the single command handler provided as part of CRibbon.
+ // Override this function to account for multiple command handlers.
+
+ return QueryInterface(IID_PPV_ARGS(ppCommandHandler));
+ }
+
+ // Called when the state of the Ribbon changes, for example, created, destroyed, or resized.
+ inline STDMETHODIMP CRibbon::OnViewChanged(UINT viewId, __in UI_VIEWTYPE typeId, __in IUnknown* pView,
+ UI_VIEWVERB verb, INT uReasonCode)
+ {
+ UNREFERENCED_PARAMETER(viewId);
+ UNREFERENCED_PARAMETER(typeId);
+ UNREFERENCED_PARAMETER(pView);
+ UNREFERENCED_PARAMETER(verb);
+ UNREFERENCED_PARAMETER(uReasonCode);
+
+
+ return E_NOTIMPL;
+ }
+
+ // Called by the Ribbon framework for each command at the time of ribbon destruction.
+ inline STDMETHODIMP CRibbon::OnDestroyUICommand(UINT32 nCmdID, __in UI_COMMANDTYPE typeID,
+ __in_opt IUICommandHandler* commandHandler)
+ {
+ UNREFERENCED_PARAMETER(commandHandler);
+ UNREFERENCED_PARAMETER(typeID);
+ UNREFERENCED_PARAMETER(nCmdID);
+
+ return E_NOTIMPL;
+ }
+
+ // Called by the Ribbon framework when a command property (PKEY) needs to be updated.
+ inline STDMETHODIMP CRibbon::UpdateProperty(UINT nCmdID, __in REFPROPERTYKEY key, __in_opt const PROPVARIANT* ppropvarCurrentValue,
+ __out PROPVARIANT* ppropvarNewValue)
+ {
+ UNREFERENCED_PARAMETER(nCmdID);
+ UNREFERENCED_PARAMETER(key);
+ UNREFERENCED_PARAMETER(ppropvarCurrentValue);
+ UNREFERENCED_PARAMETER(ppropvarNewValue);
+
+ return E_NOTIMPL;
+ }
+
+ inline bool CRibbon::CreateRibbon(CWnd* pWnd)
+ {
+ ::CoInitialize(NULL);
+
+ // Instantiate the Ribbon framework object.
+ ::CoCreateInstance(CLSID_UIRibbonFramework, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pRibbonFramework));
+
+ // Connect the host application to the Ribbon framework.
+ HRESULT hr = m_pRibbonFramework->Initialize(pWnd->GetHwnd(), this);
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ // Load the binary markup. APPLICATION_RIBBON is the default name generated by uicc.
+ hr = m_pRibbonFramework->LoadUI(GetModuleHandle(NULL), L"APPLICATION_RIBBON");
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ inline void CRibbon::DestroyRibbon()
+ {
+ if (m_pRibbonFramework)
+ {
+ m_pRibbonFramework->Destroy();
+ m_pRibbonFramework->Release();
+ m_pRibbonFramework = NULL;
+ }
+ }
+
+
+ //////////////////////////////////////////////
+ // Definitions for the CRibbonFrame class
+ //
+
+ inline CRect CRibbonFrame::GetViewRect() const
+ {
+ // Get the frame's client area
+ CRect rcFrame = GetClientRect();
+
+ // Get the statusbar's window area
+ CRect rcStatus;
+ if (GetStatusBar().IsWindowVisible() || !IsWindowVisible())
+ rcStatus = GetStatusBar().GetWindowRect();
+
+ // Get the top rebar or toolbar's window area
+ CRect rcTop;
+ if (IsReBarSupported() && m_bUseReBar)
+ rcTop = GetReBar().GetWindowRect();
+ else
+ if (m_bUseToolBar && GetToolBar().IsWindowVisible())
+ rcTop = GetToolBar().GetWindowRect();
+
+ // Return client size less the rebar and status windows
+ int top = rcFrame.top + rcTop.Height() + m_uRibbonHeight;
+ int left = rcFrame.left;
+ int right = rcFrame.right;
+ int bottom = rcFrame.Height() - (rcStatus.Height());
+ if ((bottom <= top) ||( right <= left))
+ top = left = right = bottom = 0;
+
+ CRect rcView(left, top, right, bottom);
+ return rcView;
+ }
+
+ inline void CRibbonFrame::OnCreate()
+ {
+ // OnCreate is called automatically during window creation when a
+ // WM_CREATE message received.
+
+ // Tasks such as setting the icon, creating child windows, or anything
+ // associated with creating windows are normally performed here.
+
+ if (GetWinVersion() >= 2601) // WinVersion >= Windows 7
+ {
+ m_bUseReBar = FALSE; // Don't use rebars
+ m_bUseToolBar = FALSE; // Don't use a toolbar
+
+ CFrame::OnCreate();
+
+ if (CreateRibbon(this))
+ TRACE(_T("Ribbon Created Succesfully\n"));
+ else
+ throw CWinException(_T("Failed to create ribbon"));
+ }
+ else
+ {
+ CFrame::OnCreate();
+ }
+ }
+
+ inline void CRibbonFrame::OnDestroy()
+ {
+ DestroyRibbon();
+ CFrame::OnDestroy();
+ }
+
+ inline STDMETHODIMP CRibbonFrame::OnViewChanged(UINT32 viewId, UI_VIEWTYPE typeId, IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode)
+ {
+ UNREFERENCED_PARAMETER(viewId);
+ UNREFERENCED_PARAMETER(uReasonCode);
+
+ HRESULT hr = E_NOTIMPL;
+
+ // Checks to see if the view that was changed was a Ribbon view.
+ if (UI_VIEWTYPE_RIBBON == typeId)
+ {
+ switch (verb)
+ {
+ // The view was newly created.
+ case UI_VIEWVERB_CREATE:
+ hr = S_OK;
+ break;
+
+ // The view has been resized. For the Ribbon view, the application should
+ // call GetHeight to determine the height of the ribbon.
+ case UI_VIEWVERB_SIZE:
+ {
+ IUIRibbon* pRibbon = NULL;
+ UINT uRibbonHeight;
+
+ hr = pView->QueryInterface(IID_PPV_ARGS(&pRibbon));
+ if (SUCCEEDED(hr))
+ {
+ // Call to the framework to determine the desired height of the Ribbon.
+ hr = pRibbon->GetHeight(&uRibbonHeight);
+ SetRibbonHeight(uRibbonHeight);
+ pRibbon->Release();
+
+ RecalcLayout();
+ // Use the ribbon height to position controls in the client area of the window.
+ }
+ }
+ break;
+ // The view was destroyed.
+ case UI_VIEWVERB_DESTROY:
+ hr = S_OK;
+ break;
+ }
+ }
+
+ return hr;
+ }
+
+ inline HRESULT CRibbonFrame::PopulateRibbonRecentItems(__deref_out PROPVARIANT* pvarValue)
+ {
+ LONG iCurrentFile = 0;
+ std::vector<tString> FileNames = GetMRUEntries();
+ std::vector<tString>::iterator iter;
+ int iFileCount = FileNames.size();
+ HRESULT hr = E_FAIL;
+ SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, iFileCount);
+ m_vRecentFiles.clear();
+
+ if (psa != NULL)
+ {
+ for (iter = FileNames.begin(); iter < FileNames.end(); ++iter)
+ {
+ tString strCurrentFile = (*iter);
+ WCHAR wszCurrentFile[MAX_PATH] = {0L};
+ lstrcpynW(wszCurrentFile, T2W(strCurrentFile.c_str()), MAX_PATH);
+
+ CRecentFiles* pRecentFiles = new CRecentFiles(wszCurrentFile);
+ m_vRecentFiles.push_back(RecentFilesPtr(pRecentFiles));
+ hr = SafeArrayPutElement(psa, &iCurrentFile, static_cast<void*>(pRecentFiles));
+ ++iCurrentFile;
+ }
+
+ SAFEARRAYBOUND sab = {iCurrentFile,0};
+ SafeArrayRedim(psa, &sab);
+ hr = UIInitPropertyFromIUnknownArray(UI_PKEY_RecentItems, psa, pvarValue);
+
+ SafeArrayDestroy(psa); // Calls release for each element in the array
+ }
+
+ return hr;
+ }
+
+ inline void CRibbonFrame::UpdateMRUMenu()
+ {
+ // Suppress UpdateMRUMenu when ribbon is used
+ if (0 != GetRibbonFramework()) return;
+
+ CFrame::UpdateMRUMenu();
+ }
+
+
+ ////////////////////////////////////////////////////////
+ // Declaration of the nested CRecentFiles class
+ //
+ inline CRibbonFrame::CRecentFiles::CRecentFiles(PWSTR wszFullPath) : m_cRef(1)
+ {
+ SHFILEINFOW sfi;
+ DWORD_PTR dwPtr = NULL;
+ m_wszFullPath[0] = L'\0';
+ m_wszDisplayName[0] = L'\0';
+
+ if (NULL != lstrcpynW(m_wszFullPath, wszFullPath, MAX_PATH))
+ {
+ dwPtr = ::SHGetFileInfoW(wszFullPath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME | SHGFI_USEFILEATTRIBUTES);
+
+ if (dwPtr != NULL)
+ {
+ lstrcpynW(m_wszDisplayName, sfi.szDisplayName, MAX_PATH);
+ }
+ else // Provide a reasonable fallback.
+ {
+ lstrcpynW(m_wszDisplayName, m_wszFullPath, MAX_PATH);
+ }
+ }
+ }
+
+ inline STDMETHODIMP_(ULONG) CRibbonFrame::CRecentFiles::AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ inline STDMETHODIMP_(ULONG) CRibbonFrame::CRecentFiles::Release()
+ {
+ return InterlockedDecrement(&m_cRef);
+ }
+
+ inline STDMETHODIMP CRibbonFrame::CRecentFiles::QueryInterface(REFIID iid, void** ppv)
+ {
+ if (!ppv)
+ {
+ return E_POINTER;
+ }
+
+ if (iid == __uuidof(IUnknown))
+ {
+ *ppv = static_cast<IUnknown*>(this);
+ }
+ else if (iid == __uuidof(IUISimplePropertySet))
+ {
+ *ppv = static_cast<IUISimplePropertySet*>(this);
+ }
+ else
+ {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+ // IUISimplePropertySet methods.
+ inline STDMETHODIMP CRibbonFrame::CRecentFiles::GetValue(__in REFPROPERTYKEY key, __out PROPVARIANT *ppropvar)
+ {
+ HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
+
+ if (key == UI_PKEY_Label)
+ {
+ hr = UIInitPropertyFromString(key, m_wszDisplayName, ppropvar);
+ }
+ else if (key == UI_PKEY_LabelDescription)
+ {
+ hr = UIInitPropertyFromString(key, m_wszDisplayName, ppropvar);
+ }
+
+ return hr;
+ }
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_RIBBON_H_
+
diff --git a/mmc_updater/depends/win32cpp/shared_ptr.h b/mmc_updater/depends/win32cpp/shared_ptr.h
new file mode 100644
index 00000000..0d2f8b0c
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/shared_ptr.h
@@ -0,0 +1,199 @@
+// 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.
+//
+// This software was developed from code available in the public domain
+// and has no copyright.
+
+
+// About Shared_Ptr:
+// Shared_Ptr wraps a reference-counted smart pointer around a dynamically
+// allocated object. Unlike auto_ptr, the Shared_Ptr can be used as a smart
+// pointer for objects stored in containers like std::vector. Do not use
+// Shared_Ptr (or shared_ptr or auto_ptr) for dynamically allocated arrays.
+// See below for advice on how to wrap dynamically allocated arrays in a
+// vector.
+//
+// The next standard of C++ will also contain a shared_ptr. Some modern
+// compilers already have a shared_ptr available as std::tr1::shared_ptr. If
+// your compiler already provides a shared_ptr, or if you have Boost, you
+// should use that smart pointer instead. This class has been provided for
+// those users who don't have easy access to an "official" shared_ptr.
+// Note that this class is "Shared_Ptr", a slightly different name to the
+// future "shared_ptr" to avoid naming conflicts.
+
+// Advantages of Shared_Ptr (or shared_ptr where available):
+// - Shared_Ptr can be safely copied. This makes then suitable for containers.
+// - Shared_Ptr automatically calls delete for the wrapped pointer when
+// its last copy goes out of scope.
+// - Shared_Ptr simplifies exception safety.
+//
+// Without smart pointers, it can be quite challenging to ensure that every
+// dynamically allocated pointer (i.e. use of new) is deleted in the event of
+// all possible exceptions. In addition to the exceptions we throw ourselves,
+// "new" itself will throw an exception it it fails, as does the STL (Standard
+// Template Library which includes vector and string). Without smart pointers
+// we often need to resort to additional try/catch blocks simply to avoid
+// memory leaks when exceptions occur.
+
+// Examples:
+// Shared_Ptr<CWnd> w1(new CWnd);
+// or
+// Shared_Ptr<CWnd> w1 = new CWnd;
+// or
+// typedef Shared_Ptr<CWnd> CWndPtr;
+// CWndPtr w1 = new CWnd;
+// or
+// typedef Shared_Ptr<CWnd> CWndPtr;
+// CWndPtr w1(new CWnd);
+//
+// And with a vector
+// typedef Shared_Ptr<CWnd> CWndPtr;
+// std::vector<CWndPtr> MyVector;
+// MyVector.push_back(new CWnd);
+// or
+// typedef Shared_Ptr<CWnd> CWndPtr;
+// CWnd* pWnd = new CWnd;
+// std::vector<CWndPtr> MyVector;
+// MyVector.push_back(pWnd);
+//
+
+// How to handle dynamically allocated arrays:
+// While we could create a smart pointer for arrays, we don't need to because
+// std::vector already handles this for us. Consider the following example:
+// int nLength = ::GetWindowTextLength(m_hWnd);
+// pTChar = new TCHAR[nLength+1];
+// memset(pTChar, 0, (nLength+1)*sizeof(TCHAR));
+// ::GetWindowText(m_hWnd, m_pTChar, nLength+1);
+// ....
+// delete[] pTChar;
+//
+// This can be improved by using a vector instead of an array
+// int nLength = ::GetWindowTextLength(m_hWnd);
+// std::vector<TCHAR> vTChar( nLength+1, _T('\0') );
+// TCHAR* pTCharArray = &vTChar.front();
+// ::GetWindowText(m_hWnd, pTCharArray, nLength+1);
+//
+// This works because the memory in a vector is always contiguous. Note that
+// this is NOT always true of std::string.
+
+
+// Summing up:
+// In my opinion, "naked" pointers for dynamically created objects should be
+// avoided in modern C++ code. That's to say that calls to "new" should be
+// wrapped in some sort of smart pointer wherever possible. This eliminates
+// the possibility of memory leaks (particularly in the event of exceptions).
+// It also elminiates the need for delete in user's code.
+
+#ifndef _WIN32XX_SHARED_PTR_
+#define _WIN32XX_SHARED_PTR_
+
+namespace Win32xx
+{
+
+ template <class T1>
+ class Shared_Ptr
+ {
+ public:
+ Shared_Ptr() : m_ptr(NULL), m_count(NULL) { }
+ Shared_Ptr(T1 * p) : m_ptr(p), m_count(NULL)
+ {
+ try
+ {
+ if (m_ptr) m_count = new long(0);
+ inc_ref();
+ }
+ // catch the unlikely event of 'new long(0)' throwing an exception
+ catch (const std::bad_alloc&)
+ {
+ delete m_ptr;
+ throw;
+ }
+ }
+ Shared_Ptr(const Shared_Ptr& rhs) : m_ptr(rhs.m_ptr), m_count(rhs.m_count) { inc_ref(); }
+ ~Shared_Ptr()
+ {
+ if(m_count && 0 == dec_ref())
+ {
+ // Note: This code doesn't handle a pointer to an array.
+ // We would need delete[] m_ptr to handle that.
+ delete m_ptr;
+ delete m_count;
+ }
+ }
+
+ T1* get() const { return m_ptr; }
+ long use_count() const { return m_count? *m_count : 0; }
+ bool unique() const { return (m_count && (*m_count == 1)); }
+
+ void swap(Shared_Ptr& rhs)
+ {
+ std::swap(m_ptr, rhs.m_ptr);
+ std::swap(m_count, rhs.m_count);
+ }
+
+ Shared_Ptr& operator=(const Shared_Ptr& rhs)
+ {
+ Shared_Ptr tmp(rhs);
+ this->swap(tmp);
+ return *this;
+ }
+
+ T1* operator->() const
+ {
+ assert(m_ptr);
+ return m_ptr;
+ }
+
+ T1& operator*() const
+ {
+ assert (m_ptr);
+ return *m_ptr;
+ }
+
+ bool operator== (const Shared_Ptr& rhs) const
+ {
+ return ( *m_ptr == *rhs.m_ptr);
+ }
+
+ bool operator!= (const Shared_Ptr& rhs) const
+ {
+ return ( *m_ptr != *rhs.m_ptr);
+ }
+
+ bool operator< (const Shared_Ptr& rhs) const
+ {
+ return ( *m_ptr < *rhs.m_ptr );
+ }
+
+ bool operator> (const Shared_Ptr& rhs) const
+ {
+ return ( *m_ptr > *rhs.m_ptr );
+ }
+
+ private:
+ void inc_ref()
+ {
+ if(m_count)
+ InterlockedIncrement(m_count);
+ }
+
+ int dec_ref()
+ {
+ assert (m_count);
+ return InterlockedDecrement(m_count);
+ }
+
+ T1* m_ptr;
+ long* m_count;
+ };
+
+}
+
+#endif // _WIN32XX_SHARED_PTR_
diff --git a/mmc_updater/depends/win32cpp/socket.h b/mmc_updater/depends/win32cpp/socket.h
new file mode 100644
index 00000000..63a7770f
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/socket.h
@@ -0,0 +1,778 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// socket.h
+// Declaration of the CSocket class
+//
+// The CSocket class represents a network socket. It encapsualtes many of
+// the Windows Socket SPI fuctions, providing an object-oriented approach
+// to network programming. After StartEvents is called, CSocket monitors
+// the socket and responds automatically to network events. This event
+// monitoring, for example, automatically calls OnReceive when there is
+// data on the socket to be read, and OnAccept when a server should accept
+// a connection from a client.
+
+// Users of this class should be aware that functions like OnReceive,
+// OnAccept, etc. are called on a different thread from the one CSocket is
+// instanciated on. The thread for these functions needs to respond quickly
+// to other network events, so it shouldn't be delayed. It also doesn't run
+// a message loop, so it can't be used to create windows. For these reasons
+// it might be best to use PostMessage in response to these functions in a
+// windows environment.
+
+// Refer to the network samples for an example of how to use this class to
+// create a TCP client & server, and a UDP client and server.
+
+// To compile programs with CSocket, link with ws3_32.lib for Win32,
+// and ws2.lib for Windows CE. Windows 95 systems will need to install the
+// "Windows Sockets 2.0 for Windows 95". It's available from:
+// http://support.microsoft.com/kb/182108/EN-US/
+
+// For a TCP server, inherit a class from CSocket and override OnAccept, OnDisconnect
+// and OnRecieve. Create one instance of this class and use it as a listening socket.
+// The purpose of the listening socket is to detect connections from clients and accept them.
+// For the listening socket, we do the following:
+// 1) Create the socket.
+// 2) Bind an IP address to the socket.
+// 3) Listen on the socket for incoming connection requests.
+// 4) Use StartNotifyRevents to receive notification of network events.
+// 5) Override OnAccept to accept requests on a newly created data CSocket object.
+// 6) Create a new data socket for each client connection accepted.
+// 7) The server socket uses the 'accept' function to accept an incoming connection
+// from this new data socket.
+
+// The purpose of the data socket is to send data to, and recieve data from the client.
+// There will be one data socket for each client accepted by the server.
+// To use it we do the following:
+// * To recieve data from the client, override OnReceive and use Receive.
+// * To send data to use Send.
+// * OnDisconnect can be used to detect when the client is disconnected.
+
+// For a TCP client, inherit from CSocket and override OnReceive and OnDisconnect.
+// Create an instance of this inherited class, and perform the following steps:
+// 1) Create the socket.
+// 2) Connect to the server.
+// 3) Use StartNotifyRevents to receive notification of network events.
+// We are now ready to send and recieve data from the server.
+// * Use Send to send data to the server.
+// * Override OnReceive and use Recieve to receive data from the server
+// * OnDisconnect can be used to detect when the client is disconnected from the server.
+
+// Notes regarding IPv6 support
+// * IPv6 is supported on Windows Vista and above. Windows XP with SP2 provides
+// "experimental" support, which can be enabled by entering "ipv6 install"
+// at a command prompt.
+// * IPv6 is not supported by all compilters and devlopment environments. In
+// particular, it is not supported by Dev-C++ or Borland 5.5. A modern
+// Platform SDK needs to be added to Visual Studio 6 for it to support IPv6.
+// * IsIPV6Supported returns false if either the operating system or the
+// development environment fails to support IPv6.
+//
+
+#ifndef _WIN32XX_SOCKET_H_
+#define _WIN32XX_SOCKET_H_
+
+
+#include "wincore.h"
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <process.h>
+
+
+#define THREAD_TIMEOUT 100
+
+
+namespace Win32xx
+{
+
+ typedef int WINAPI GETADDRINFO(LPCSTR, LPCSTR, const struct addrinfo*, struct addrinfo**);
+ typedef void WINAPI FREEADDRINFO(struct addrinfo*);
+
+ class CSocket
+ {
+ public:
+ CSocket();
+ virtual ~CSocket();
+
+ // Operations
+ virtual void Accept(CSocket& rClientSock, struct sockaddr* addr, int* addrlen);
+ virtual int Bind(LPCTSTR addr, LPCTSTR port);
+ virtual int Bind(const struct sockaddr* name, int namelen);
+ virtual int Connect(LPCTSTR addr, LPCTSTR port);
+ virtual int Connect(const struct sockaddr* name, int namelen);
+ virtual BOOL Create( int family, int type, int protocol = IPPROTO_IP);
+ virtual void Disconnect();
+ virtual void FreeAddrInfo( struct addrinfo* ai );
+ virtual int GetAddrInfo( LPCTSTR nodename, LPCTSTR servname, const struct addrinfo* hints, struct addrinfo** res);
+ virtual LPCTSTR GetLastError();
+ virtual int ioCtlSocket(long cmd, u_long* argp);
+ virtual BOOL IsIPV6Supported();
+ virtual int Listen(int backlog = SOMAXCONN);
+ virtual int Receive(TCHAR* buf, int len, int flags);
+ virtual int ReceiveFrom(TCHAR* buf, int len, int flags, struct sockaddr* from, int* fromlen);
+ virtual int Send(LPCTSTR buf, int len, int flags);
+ virtual int SendTo(LPCTSTR send, int len, int flags, LPCTSTR addr, LPCTSTR port);
+ virtual int SendTo(LPCTSTR buf, int len, int flags, const struct sockaddr* to, int tolen);
+
+ virtual void StartEvents();
+ virtual void StopEvents();
+
+ // Attributes
+ virtual int GetPeerName(struct sockaddr* name, int* namelen);
+ virtual int GetSockName(struct sockaddr* name, int* namelen);
+ SOCKET& GetSocket() { return m_Socket; }
+ virtual int GetSockOpt(int level, int optname, char* optval, int* optlen);
+ virtual int SetSockOpt(int level, int optname, const char* optval, int optlen);
+
+ // Override these functions to monitor events
+ virtual void OnAccept() {}
+ virtual void OnAddresListChange() {}
+ virtual void OnDisconnect() {}
+ virtual void OnConnect() {}
+ virtual void OnOutOfBand() {}
+ virtual void OnQualityOfService() {}
+ virtual void OnReceive() {}
+ virtual void OnRoutingChange() {}
+ virtual void OnSend() {}
+
+
+
+ // Allow CSocket to be used as a SOCKET
+ operator SOCKET() const {return m_Socket;}
+
+ private:
+ CSocket(const CSocket&); // Disable copy construction
+ CSocket& operator = (const CSocket&); // Disable assignment operator
+ static UINT WINAPI EventThread(LPVOID thread_data);
+
+ tString m_tsErrorMessage;
+ SOCKET m_Socket;
+ HMODULE m_hWS2_32;
+ HANDLE m_hEventThread; // Handle to the thread
+ HANDLE m_StopRequest; // An event to signal the event thread should stop
+ HANDLE m_Stopped; // An event to signal the event thread is stopped
+
+ GETADDRINFO* m_pfnGetAddrInfo; // pointer for the GetAddrInfo function
+ FREEADDRINFO* m_pfnFreeAddrInfo; // pointer for the FreeAddrInfo function
+ };
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ inline CSocket::CSocket() : m_Socket(INVALID_SOCKET), m_hEventThread(0)
+ {
+ // Initialise the Windows Socket services
+ WSADATA wsaData;
+
+ if (0 != ::WSAStartup(MAKEWORD(2,2), &wsaData))
+ throw CWinException(_T("WSAStartup failed"));
+
+ m_hWS2_32 = ::LoadLibrary(_T("WS2_32.dll"));
+ if (0 == m_hWS2_32)
+ throw CWinException(_T("Failed to load WS2_2.dll"));
+
+ m_pfnGetAddrInfo = (GETADDRINFO*) GetProcAddress(m_hWS2_32, "getaddrinfo");
+ m_pfnFreeAddrInfo = (FREEADDRINFO*) GetProcAddress(m_hWS2_32, "freeaddrinfo");
+
+ m_StopRequest = ::CreateEvent(0, TRUE, FALSE, 0);
+ m_Stopped = ::CreateEvent(0, TRUE, FALSE, 0);
+ }
+
+ inline CSocket::~CSocket()
+ {
+ Disconnect();
+
+ // Close handles
+ ::CloseHandle(m_StopRequest);
+ ::CloseHandle(m_Stopped);
+
+ // Terminate the Windows Socket services
+ ::WSACleanup();
+
+ ::FreeLibrary(m_hWS2_32);
+ }
+
+ inline void CSocket::Accept(CSocket& rClientSock, struct sockaddr* addr, int* addrlen)
+ {
+ // The accept function permits an incoming connection attempt on the socket.
+
+ rClientSock.m_Socket = ::accept(m_Socket, addr, addrlen);
+ if (INVALID_SOCKET == rClientSock.GetSocket())
+ TRACE(_T("Accept failed\n"));
+ }
+
+ inline int CSocket::Bind(LPCTSTR addr, LPCTSTR port)
+ // The bind function associates a local address with the socket.
+ {
+ int RetVal = 0;
+
+ if (IsIPV6Supported())
+ {
+
+#ifdef GetAddrInfo // Skip the following code block for older development environments
+
+ ADDRINFO Hints= {0};
+ Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+ ADDRINFO *AddrInfo;
+
+ RetVal = GetAddrInfo(addr, port, &Hints, &AddrInfo);
+ if (RetVal != 0)
+ {
+ TRACE( _T("GetAddrInfo failed\n"));
+ return RetVal;
+ }
+
+ // Bind the IP address to the listening socket
+ RetVal = ::bind( m_Socket, AddrInfo->ai_addr, (int)AddrInfo->ai_addrlen );
+ if ( RetVal == SOCKET_ERROR )
+ {
+ TRACE(_T("Bind failed\n"));
+ return RetVal;
+ }
+
+ // Free the address information allocated by GetAddrInfo
+ FreeAddrInfo(AddrInfo);
+
+#endif
+
+ }
+ else
+ {
+ sockaddr_in clientService;
+ clientService.sin_family = AF_INET;
+ clientService.sin_addr.s_addr = inet_addr( T2A(addr) );
+ int nPort = -1;
+ nPort = atoi( T2A(port) );
+ if (-1 == nPort)
+ {
+ TRACE(_T("Invalid port number\n"));
+ return SOCKET_ERROR;
+ }
+ clientService.sin_port = htons( (u_short)nPort );
+
+ RetVal = ::bind( m_Socket, (SOCKADDR*) &clientService, sizeof(clientService) );
+ if ( 0 != RetVal )
+ TRACE(_T("Bind failed\n"));
+ }
+
+ return RetVal;
+ }
+
+ inline int CSocket::Bind(const struct sockaddr* name, int namelen)
+ {
+ // The bind function associates a local address with the socket.
+
+ int Result = ::bind (m_Socket, name, namelen);
+ if ( 0 != Result )
+ TRACE(_T("Bind failed\n"));
+ return Result;
+ }
+
+ inline int CSocket::Connect(LPCTSTR addr, LPCTSTR port)
+ // The Connect function establishes a connection to the socket.
+ {
+ int RetVal = 0;
+
+ if (IsIPV6Supported())
+ {
+
+#ifdef GetAddrInfo // Skip the following code block for older development environments
+
+ ADDRINFO Hints= {0};
+ Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+ ADDRINFO *AddrInfo;
+
+ RetVal = GetAddrInfo(addr, port, &Hints, &AddrInfo);
+ if (RetVal != 0)
+ {
+ TRACE( _T("getaddrinfo failed\n"));
+ return SOCKET_ERROR;
+ }
+
+ // Bind the IP address to the listening socket
+ RetVal = Connect( AddrInfo->ai_addr, (int)AddrInfo->ai_addrlen );
+ if ( RetVal == SOCKET_ERROR )
+ {
+ TRACE(_T("Connect failed\n"));
+ return RetVal;
+ }
+
+ // Free the address information allocatied by GetAddrInfo
+ FreeAddrInfo(AddrInfo);
+
+#endif
+
+ }
+ else
+ {
+ sockaddr_in clientService;
+ clientService.sin_family = AF_INET;
+ clientService.sin_addr.s_addr = inet_addr( T2A(addr) );
+ int nPort = -1;
+ nPort = atoi( T2A(port) );
+ if (-1 == nPort)
+ {
+ TRACE(_T("Invalid port number\n"));
+ return SOCKET_ERROR;
+ }
+ clientService.sin_port = htons( (u_short)nPort );
+
+ RetVal = ::connect( m_Socket, (SOCKADDR*) &clientService, sizeof(clientService) );
+ if ( 0 != RetVal )
+ TRACE(_T("Connect failed\n"));
+ }
+
+ return RetVal;
+ }
+
+ inline int CSocket::Connect(const struct sockaddr* name, int namelen)
+ {
+ // The Connect function establishes a connection to the socket.
+
+ int Result = ::connect( m_Socket, name, namelen );
+ if ( 0 != Result )
+ TRACE(_T("Connect failed\n"));
+
+ return Result;
+ }
+
+ inline BOOL CSocket::Create( int family, int type, int protocol /*= IPPROTO_IP*/)
+ {
+ // Creates the socket
+
+ // Valid values:
+ // family: AF_INET or AF_INET6
+ // type: SOCK_DGRAM, SOCK_SEQPACKET, SOCK_STREAM, SOCK_RAW
+ // protocol: IPPROTO_IP, IPPROTO_TCP, IPPROTO_UDP, IPPROTO_RAW, IPPROTO_ICMP, IPPROTO_ICMPV6
+
+ m_Socket = socket(family, type, protocol);
+ if(m_Socket == INVALID_SOCKET)
+ {
+ TRACE(_T("Failed to create socket\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ inline void CSocket::Disconnect()
+ {
+ ::shutdown(m_Socket, SD_BOTH);
+ StopEvents();
+ ::closesocket(m_Socket);
+ m_Socket = INVALID_SOCKET;
+ }
+
+ inline UINT WINAPI CSocket::EventThread(LPVOID thread_data)
+ {
+ // These are the possible network event notifications:
+ // FD_READ Notification of readiness for reading.
+ // FD_WRITE Motification of readiness for writing.
+ // FD_OOB Notification of the arrival of Out Of Band data.
+ // FD_ACCEPT Notification of incoming connections.
+ // FD_CONNECT Notification of completed connection or multipoint join operation.
+ // FD_CLOSE Notification of socket closure.
+ // FD_QOS Notification of socket Quality Of Service changes
+ // FD_ROUTING_INTERFACE_CHANGE Notification of routing interface changes for the specified destination.
+ // FD_ADDRESS_LIST_CHANGE Notification of local address list changes for the address family of the socket.
+
+ WSANETWORKEVENTS NetworkEvents;
+ CSocket* pSocket = (CSocket*)thread_data;
+ SOCKET sClient = pSocket->m_Socket;
+
+ WSAEVENT AllEvents[2];
+ AllEvents[0] = ::WSACreateEvent();
+ AllEvents[1] = (WSAEVENT)pSocket->m_StopRequest;
+ long Events = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE |
+ FD_QOS | FD_ROUTING_INTERFACE_CHANGE | FD_ADDRESS_LIST_CHANGE;
+
+ // Associate the network event object (hNetworkEvents) with the
+ // specified network events (Events) on socket sClient.
+ if( SOCKET_ERROR == WSAEventSelect(sClient, AllEvents[0], Events))
+ {
+ TRACE(_T("Error in Event Select\n"));
+ ::SetEvent(pSocket->m_Stopped);
+ ::WSACloseEvent(AllEvents[0]);
+ return 0;
+ }
+
+ // loop until the stop event is set
+ for (;;) // infinite loop
+ {
+ // Wait 100 ms for a network event
+ DWORD dwResult = ::WSAWaitForMultipleEvents(2, AllEvents, FALSE, THREAD_TIMEOUT, FALSE);
+
+ // Check event for stop thread
+ if(::WaitForSingleObject(pSocket->m_StopRequest, 0) == WAIT_OBJECT_0)
+ {
+ ::WSACloseEvent(AllEvents[0]);
+ ::SetEvent(pSocket->m_Stopped);
+ return 0;
+ }
+
+ if (WSA_WAIT_FAILED == dwResult)
+ {
+ TRACE(_T("WSAWaitForMultipleEvents failed\n"));
+ ::WSACloseEvent(AllEvents[0]);
+ ::SetEvent(pSocket->m_Stopped);
+ return 0;
+ }
+
+ // Proceed if a network event occurred
+ if (WSA_WAIT_TIMEOUT != dwResult)
+ {
+
+ if ( SOCKET_ERROR == ::WSAEnumNetworkEvents(sClient, AllEvents[0], &NetworkEvents) )
+ {
+ TRACE(_T("WSAEnumNetworkEvents failed\n"));
+ ::WSACloseEvent(AllEvents[0]);
+ ::SetEvent(pSocket->m_Stopped);
+ return 0;
+ }
+
+ if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
+ pSocket->OnAccept();
+
+ if (NetworkEvents.lNetworkEvents & FD_READ)
+ pSocket->OnReceive();
+
+ if (NetworkEvents.lNetworkEvents & FD_WRITE)
+ pSocket->OnSend();
+
+ if (NetworkEvents.lNetworkEvents & FD_OOB)
+ pSocket->OnOutOfBand();
+
+ if (NetworkEvents.lNetworkEvents & FD_QOS)
+ pSocket->OnQualityOfService();
+
+ if (NetworkEvents.lNetworkEvents & FD_CONNECT)
+ pSocket->OnConnect();
+
+ if (NetworkEvents.lNetworkEvents & FD_ROUTING_INTERFACE_CHANGE)
+ pSocket->OnRoutingChange();
+
+ if (NetworkEvents.lNetworkEvents & FD_ADDRESS_LIST_CHANGE)
+ pSocket->OnAddresListChange();
+
+ if (NetworkEvents.lNetworkEvents & FD_CLOSE)
+ {
+ ::shutdown(sClient, SD_BOTH);
+ ::closesocket(sClient);
+ pSocket->OnDisconnect();
+ ::WSACloseEvent(AllEvents[0]);
+ ::SetEvent(pSocket->m_Stopped);
+ return 0;
+ }
+ }
+ }
+ }
+
+ inline int CSocket::GetAddrInfo( LPCTSTR nodename, LPCTSTR servname, const struct addrinfo* hints, struct addrinfo** res)
+ {
+
+#ifdef GetAddrInfo
+
+ std::string sNodeName = T2A(nodename);
+ std::string sServName = T2A(servname);
+ return (*m_pfnGetAddrInfo)(sNodeName.c_str(), sServName.c_str(), hints, res);
+
+#else
+
+ UNREFERENCED_PARAMETER(nodename);
+ UNREFERENCED_PARAMETER(servname);
+ UNREFERENCED_PARAMETER(hints);
+ UNREFERENCED_PARAMETER(res);
+
+ throw CWinException(_T("getaddrinfo is not supported"));
+
+#endif
+
+ }
+
+ inline LPCTSTR CSocket::GetLastError()
+ {
+ // Retrieves the most recent network error.
+
+ int ErrorCode = WSAGetLastError();
+ LPTSTR Message = NULL;
+ m_tsErrorMessage = _T("");
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&Message, 1024, NULL);
+
+ if (Message)
+ {
+ m_tsErrorMessage = Message;
+ ::LocalFree(Message);
+ }
+
+ return m_tsErrorMessage.c_str();
+ }
+
+ inline int CSocket::GetPeerName(struct sockaddr* name, int* namelen)
+ {
+ int Result = ::getpeername(m_Socket, name, namelen);
+ if (0 != Result)
+ TRACE(_T("GetPeerName failed\n"));
+
+ return Result;
+ }
+
+ inline int CSocket::GetSockName(struct sockaddr* name, int* namelen)
+ {
+ int Result = ::getsockname(m_Socket, name, namelen);
+ if (0 != Result)
+ TRACE(_T("GetSockName Failed\n"));
+
+ return Result;
+ }
+
+ inline int CSocket::GetSockOpt(int level, int optname, char* optval, int* optlen)
+ {
+ int Result = ::getsockopt(m_Socket, level, optname, optval, optlen);
+ if (0 != Result)
+ TRACE(_T("GetSockOpt Failed\n"));
+
+ return Result;
+ }
+
+ inline void CSocket::FreeAddrInfo( struct addrinfo* ai )
+ {
+
+#ifdef GetAddrInfo
+
+ (*m_pfnFreeAddrInfo)(ai);
+
+#else
+
+ UNREFERENCED_PARAMETER(ai);
+
+ throw CWinException(_T("getaddrinfo is not supported"));
+
+#endif
+
+ }
+
+ inline int CSocket::ioCtlSocket(long cmd, u_long* argp)
+ {
+ int Result = ::ioctlsocket(m_Socket, cmd, argp);
+ if (0 != Result)
+ TRACE(_T("ioCtlSocket Failed\n"));
+
+ return Result;
+ }
+
+ inline BOOL CSocket::IsIPV6Supported()
+ {
+ BOOL IsIPV6Supported = FALSE;
+
+#ifdef GetAddrInfo
+
+ if (m_pfnGetAddrInfo != 0 && m_pfnFreeAddrInfo != 0)
+ IsIPV6Supported = TRUE;
+
+#endif
+
+ return IsIPV6Supported;
+ }
+
+ inline int CSocket::Listen(int backlog /*= SOMAXCONN*/)
+ {
+ int Result = ::listen(m_Socket, backlog);
+ if (0 != Result)
+ TRACE(_T("Listen Failed\n"));
+
+ return Result;
+ }
+
+ inline int CSocket::Receive(TCHAR* buf, int len, int flags)
+ {
+ std::vector<char> vChar(len+1, '\0');
+ char* pCharArray = &vChar.front();
+ int Result = ::recv(m_Socket, pCharArray, len, flags);
+ if (SOCKET_ERROR == Result)
+ TRACE(_T("Receive failed\n"));
+
+ lstrcpyn(buf, A2T(pCharArray), len);
+
+ return Result;
+ }
+
+ inline int CSocket::ReceiveFrom(TCHAR* buf, int len, int flags, struct sockaddr* from, int* fromlen)
+ //The ReceiveFrom function receives a datagram and stores the source address.
+ {
+ std::vector<char> vChar(len+1, '\0');
+ char* pCharArray = &vChar.front();
+ int Result = ::recvfrom(m_Socket, pCharArray, len, flags, from, fromlen);
+ if (SOCKET_ERROR == Result)
+ TRACE(_T("ReceiveFrom failed\n"));
+
+ lstrcpyn(buf, A2T(pCharArray), len);
+
+ return Result;
+ }
+
+ inline int CSocket::Send(LPCTSTR buf, int len, int flags)
+ {
+ int Result = ::send(m_Socket, T2A(buf), len, flags);
+ if (SOCKET_ERROR == Result)
+ TRACE(_T("Send failed\n"));
+
+ return Result;
+ }
+
+ inline int CSocket::SendTo(LPCTSTR send, int len, int flags, LPCTSTR addr, LPCTSTR port)
+ // The sendto function sends data to a specific destination.
+ {
+ int RetVal = 0;
+
+ if (IsIPV6Supported())
+ {
+
+#ifdef GetAddrInfo // Skip the following code block for older development environments
+
+ ADDRINFO Hints= {0};
+ Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+ ADDRINFO *AddrInfo;
+
+ RetVal = GetAddrInfo(addr, port, &Hints, &AddrInfo);
+ if (RetVal != 0)
+ {
+ TRACE( _T("GetAddrInfo failed\n"));
+ return SOCKET_ERROR;
+ }
+
+ RetVal = ::sendto(m_Socket, T2A(send), len, flags, AddrInfo->ai_addr, (int)AddrInfo->ai_addrlen );
+ if ( RetVal == SOCKET_ERROR )
+ {
+ TRACE(_T("SendTo failed\n"));
+ return RetVal;
+ }
+
+ // Free the address information allocatied by GetAddrInfo
+ FreeAddrInfo(AddrInfo);
+
+#endif
+
+ }
+ else
+ {
+ sockaddr_in clientService;
+ clientService.sin_family = AF_INET;
+ clientService.sin_addr.s_addr = inet_addr( T2A(addr) );
+ int nPort = -1;
+ nPort = atoi( T2A(port));
+ if (-1 == nPort)
+ {
+ TRACE(_T("Invalid port number\n"));
+ return SOCKET_ERROR;
+ }
+ clientService.sin_port = htons( (u_short)nPort );
+
+ RetVal = ::sendto( m_Socket, T2A(send), len, flags, (SOCKADDR*) &clientService, sizeof(clientService) );
+ if ( SOCKET_ERROR != RetVal )
+ TRACE(_T("SendTo failed\n"));
+ }
+
+ return RetVal;
+ }
+
+ inline int CSocket::SendTo(LPCTSTR buf, int len, int flags, const struct sockaddr* to, int tolen)
+ // The sendto function sends data to a specific destination.
+ {
+ int Result = ::sendto(m_Socket, T2A(buf), len, flags, to, tolen);
+ if (SOCKET_ERROR == Result)
+ TRACE(_T("SendTo failed\n"));
+
+ return Result;
+ }
+
+ inline int CSocket::SetSockOpt(int level, int optname, const char* optval, int optlen)
+ {
+ int Result = ::setsockopt(m_Socket, level, optname, optval, optlen);
+ if (0 != Result)
+ TRACE(_T("SetSockOpt failed\n"));
+
+ return Result;
+ }
+
+ inline void CSocket::StartEvents()
+ {
+ // This function starts the thread which monitors the socket for events.
+ StopEvents(); // Ensure the thread isn't already running
+ UINT ThreadID; // a return variable required for Win95, Win98, WinME
+ m_hEventThread = (HANDLE)::_beginthreadex(NULL, 0, CSocket::EventThread, (LPVOID) this, 0, &ThreadID);
+ }
+
+ inline void CSocket::StopEvents()
+ {
+ // Terminates the event thread gracefully (if possible)
+ if (m_hEventThread)
+ {
+ ::SetThreadPriority(m_hEventThread, THREAD_PRIORITY_HIGHEST);
+ ::SetEvent(m_StopRequest);
+
+ for (;;) // infinite loop
+ {
+ // wait for the Thread stopping event to be set
+ if ( WAIT_TIMEOUT == ::WaitForSingleObject(m_Stopped, THREAD_TIMEOUT * 10) )
+ {
+ // Note: An excessive delay in processing any of the notification functions
+ // can cause us to get here. (Yes one second is an excessive delay. Its a bug!)
+ TRACE(_T("*** Error: Event Thread won't die ***\n") );
+ }
+ else break;
+ }
+
+ ::CloseHandle(m_hEventThread);
+ m_hEventThread = 0;
+ }
+
+ ::ResetEvent(m_StopRequest);
+ ::ResetEvent(m_Stopped);
+ }
+}
+
+
+#endif // #ifndef _WIN32XX_SOCKET_H_
+
diff --git a/mmc_updater/depends/win32cpp/statusbar.h b/mmc_updater/depends/win32cpp/statusbar.h
new file mode 100644
index 00000000..ad9a007b
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/statusbar.h
@@ -0,0 +1,226 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+#ifndef _WIN32XX_STATUSBAR_H_
+#define _WIN32XX_STATUSBAR_H_
+
+#include "wincore.h"
+
+namespace Win32xx
+{
+
+ //////////////////////////////////////
+ // Declaration of the CStatusBar class
+ //
+ class CStatusBar : public CWnd
+ {
+ public:
+ CStatusBar();
+ virtual ~CStatusBar() {}
+
+ // Overridables
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+
+ // Attributes
+ int GetParts();
+ HICON GetPartIcon(int iPart);
+ CRect GetPartRect(int iPart);
+ tString GetPartText(int iPart) const;
+ BOOL IsSimple();
+ BOOL SetPartIcon(int iPart, HICON hIcon);
+ BOOL SetPartText(int iPart, LPCTSTR szText, UINT Style = 0) const;
+ BOOL SetPartWidth(int iPart, int iWidth) const;
+
+ // Operations
+ CStatusBar(const CStatusBar&); // Disable copy construction
+ CStatusBar& operator = (const CStatusBar&); // Disable assignment operator
+
+ BOOL CreateParts(int iParts, const int iPaneWidths[]) const;
+ void SetSimple(BOOL fSimple = TRUE);
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ //////////////////////////////////////
+ // Definitions for the CStatusBar class
+ //
+ inline CStatusBar::CStatusBar()
+ {
+ }
+
+ inline BOOL CStatusBar::CreateParts(int iParts, const int iPaneWidths[]) const
+ // Sets the number of parts in a status window and the coordinate of the right edge of each part.
+ // If an element of iPaneWidths is -1, the right edge of the corresponding part extends
+ // to the border of the window
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(iParts <= 256);
+
+ return (BOOL)SendMessage(SB_SETPARTS, iParts, (LPARAM)iPaneWidths);
+ }
+
+ inline int CStatusBar::GetParts()
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(SB_GETPARTS, 0L, 0L);
+ }
+
+ inline HICON CStatusBar::GetPartIcon(int iPart)
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(SB_GETICON, (WPARAM)iPart, 0L);
+ }
+
+ inline CRect CStatusBar::GetPartRect(int iPart)
+ {
+ assert(::IsWindow(m_hWnd));
+
+ CRect rc;
+ SendMessage(SB_GETRECT, (WPARAM)iPart, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline tString CStatusBar::GetPartText(int iPart) const
+ {
+ assert(::IsWindow(m_hWnd));
+ tString PaneText;
+
+ // Get size of Text array
+ int iChars = LOWORD (SendMessage(SB_GETTEXTLENGTH, iPart, 0L));
+
+ std::vector<TCHAR> Text( iChars +1, _T('\0') );
+ TCHAR* pTextArray = &Text[0];
+
+ SendMessage(SB_GETTEXT, iPart, (LPARAM)pTextArray);
+ PaneText = pTextArray;
+ return PaneText;
+ }
+
+ inline BOOL CStatusBar::IsSimple()
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(SB_ISSIMPLE, 0L, 0L);
+ }
+
+ inline void CStatusBar::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | CCS_BOTTOM | SBARS_SIZEGRIP;
+ }
+
+ inline void CStatusBar::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = STATUSCLASSNAME;
+ }
+
+ inline BOOL CStatusBar::SetPartText(int iPart, LPCTSTR szText, UINT Style) const
+ // Available Styles: Combinations of ...
+ //0 The text is drawn with a border to appear lower than the plane of the window.
+ //SBT_NOBORDERS The text is drawn without borders.
+ //SBT_OWNERDRAW The text is drawn by the parent window.
+ //SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
+ //SBT_RTLREADING The text will be displayed in the opposite direction to the text in the parent window.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ BOOL bResult = FALSE;
+ if (SendMessage(SB_GETPARTS, 0L, 0L) >= iPart)
+ bResult = (BOOL)SendMessage(SB_SETTEXT, iPart | Style, (LPARAM)szText);
+
+ return bResult;
+ }
+
+ inline BOOL CStatusBar::SetPartIcon(int iPart, HICON hIcon)
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(SB_SETICON, (WPARAM)iPart, (LPARAM) hIcon);
+ }
+
+ inline BOOL CStatusBar::SetPartWidth(int iPart, int iWidth) const
+ {
+ // This changes the width of an existing pane, or creates a new pane
+ // with the specified width.
+ // A width of -1 for the last part sets the width to the border of the window.
+
+ assert(::IsWindow(m_hWnd));
+ assert(iPart >= 0 && iPart <= 255);
+
+ // Fill the PartWidths vector with the current width of the statusbar parts
+ int PartsCount = (int)SendMessage(SB_GETPARTS, 0L, 0L);
+ std::vector<int> PartWidths(PartsCount, 0);
+ int* pPartWidthArray = &PartWidths[0];
+ SendMessage(SB_GETPARTS, PartsCount, (LPARAM)pPartWidthArray);
+
+ // Fill the NewPartWidths vector with the new width of the statusbar parts
+ int NewPartsCount = MAX(iPart+1, PartsCount);
+ std::vector<int> NewPartWidths(NewPartsCount, 0);;
+ NewPartWidths = PartWidths;
+ int* pNewPartWidthArray = &NewPartWidths[0];
+
+ if (0 == iPart)
+ pNewPartWidthArray[iPart] = iWidth;
+ else
+ {
+ if (iWidth >= 0)
+ pNewPartWidthArray[iPart] = pNewPartWidthArray[iPart -1] + iWidth;
+ else
+ pNewPartWidthArray[iPart] = -1;
+ }
+
+ // Set the statusbar parts with our new parts count and part widths
+ BOOL bResult = (BOOL)SendMessage(SB_SETPARTS, NewPartsCount, (LPARAM)pNewPartWidthArray);
+
+ return bResult;
+ }
+
+ inline void CStatusBar::SetSimple(BOOL fSimple /* = TRUE*/)
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(SB_SIMPLE, (WPARAM)fSimple, 0L);
+ }
+
+} // namespace Win32xx
+
+#endif // #ifndef _WIN32XX_STATUSBAR_H_
diff --git a/mmc_updater/depends/win32cpp/stdcontrols.h b/mmc_updater/depends/win32cpp/stdcontrols.h
new file mode 100644
index 00000000..b362f07b
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/stdcontrols.h
@@ -0,0 +1,1000 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// stdcontrols.h
+// Declaration of the CButton, CEdit, CListBox and CStatic classes
+
+// The Button, Edit, ListBox and Static controls are often referred to
+// as "standard controls". These set of older controls were originally
+// developed for Win16 operating systems (Windows 3.1 and 3.11). They use an
+// older form of notification, and send their notifications via a WM_COMMAND
+// message. Newer controls send their notifications via a WM_NOTIFY message.
+
+
+#ifndef _WIN32XX_STDCONTROLS_H_
+#define _WIN32XX_STDCONTROLS_H_
+
+#include "wincore.h"
+
+
+namespace Win32xx
+{
+ class CButton : public CWnd
+ {
+ public:
+ CButton() {}
+ virtual ~CButton() {}
+
+ // Attributes
+ HBITMAP GetBitmap() const;
+ UINT GetButtonStyle() const;
+ int GetCheck() const;
+ HCURSOR GetCursor() const;
+ HICON GetIcon() const;
+ UINT GetState() const;
+ HBITMAP SetBitmap(HBITMAP hBitmap) const;
+ void SetButtonStyle(DWORD dwStyle, BOOL bRedraw) const;
+ void SetCheck(int nCheckState) const;
+ HCURSOR SetCursor(HCURSOR hCursor) const;
+ HICON SetIcon(HICON hIcon) const;
+ void SetState(BOOL bHighlight) const;
+
+ protected:
+ // Overridables
+ virtual void PreCreate(CREATESTRUCT& cs);
+ };
+
+ class CEdit : public CWnd
+ {
+ public:
+ // Construction
+ CEdit() {}
+ virtual ~CEdit() {}
+
+ // Attributes
+ BOOL CanUndo() const;
+ int CharFromPos(CPoint pt) const;
+ int GetFirstVisibleLine() const;
+ HLOCAL GetHandle() const;
+ UINT GetLimitText() const;
+ int GetLine(int nIndex, LPTSTR lpszBuffer) const;
+ int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const;
+ int GetLineCount() const;
+ DWORD GetMargins() const;
+ BOOL GetModify() const;
+ TCHAR GetPasswordChar() const;
+ void GetRect(LPRECT lpRect) const;
+ void GetSel(int& nStartChar, int& nEndChar) const;
+ DWORD GetSel() const;
+ CPoint PosFromChar(UINT nChar) const;
+ void SetHandle(HLOCAL hBuffer) const;
+ void SetLimitText(UINT nMax) const;
+ void SetMargins(UINT nLeft, UINT nRight) const;
+ void SetModify(BOOL bModified = TRUE) const;
+
+ // Operations
+ void EmptyUndoBuffer() const;
+ BOOL FmtLines(BOOL bAddEOL) const;
+ void LimitText(int nChars = 0) const;
+ int LineFromChar(int nIndex = -1) const;
+ int LineIndex(int nLine = -1) const;
+ int LineLength(int nLine = -1) const;
+ void LineScroll(int nLines, int nChars = 0) const;
+ void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo) const;
+ void SetPasswordChar(TCHAR ch) const;
+ BOOL SetReadOnly(BOOL bReadOnly = TRUE) const;
+ void SetRect(LPCRECT lpRect) const;
+ void SetRectNP(LPCRECT lpRect) const;
+ void SetSel(DWORD dwSelection, BOOL bNoScroll) const;
+ void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll) const;
+ BOOL SetTabStops(int nTabStops, LPINT rgTabStops) const;
+ BOOL SetTabStops() const;
+ BOOL SetTabStops(const int& cxEachStop) const;
+
+ //Clipboard Operations
+ void Clear() const;
+ void Copy() const;
+ void Cut() const;
+ void Paste() const;
+ void Undo() const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ };
+
+ class CListBox : public CWnd
+ {
+ public:
+ CListBox() {}
+ virtual ~CListBox() {}
+
+ // General Operations
+ int GetCount() const;
+ int GetHorizontalExtent() const;
+ DWORD GetItemData(int nIndex) const;
+ void* GetItemDataPtr(int nIndex) const;
+ int GetItemHeight(int nIndex) const;
+ int GetItemRect(int nIndex, LPRECT lpRect) const;
+ LCID GetLocale() const;
+ int GetSel(int nIndex) const;
+ int GetText(int nIndex, LPTSTR lpszBuffer) const;
+ int GetTextLen(int nIndex) const;
+ int GetTopIndex() const;
+ UINT ItemFromPoint(CPoint pt, BOOL& bOutside ) const;
+ void SetColumnWidth(int cxWidth) const;
+ void SetHorizontalExtent(int cxExtent) const;
+ int SetItemData(int nIndex, DWORD dwItemData) const;
+ int SetItemDataPtr(int nIndex, void* pData) const;
+ int SetItemHeight(int nIndex, UINT cyItemHeight) const;
+ LCID SetLocale(LCID nNewLocale) const;
+ BOOL SetTabStops(int nTabStops, LPINT rgTabStops) const;
+ void SetTabStops() const;
+ BOOL SetTabStops(const int& cxEachStop) const;
+ int SetTopIndex(int nIndex) const;
+
+ // Single-Selection Operations
+ int GetCurSel() const;
+ int SetCurSel(int nSelect) const;
+
+ // Multiple-Selection Operations
+ int GetAnchorIndex() const;
+ int GetCaretIndex() const;
+ int GetSelCount() const;
+ int GetSelItems(int nMaxItems, LPINT rgIndex) const;
+ int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem) const;
+ void SetAnchorIndex(int nIndex) const;
+ int SetCaretIndex(int nIndex, BOOL bScroll) const;
+ int SetSel(int nIndex, BOOL bSelect) const;
+
+ // String Operations
+ int AddString(LPCTSTR lpszItem) const;
+ int DeleteString(UINT nIndex) const;
+ int Dir(UINT attr, LPCTSTR lpszWildCard) const;
+ int FindString(int nStartAfter, LPCTSTR lpszItem) const;
+ int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const;
+ int InsertString(int nIndex, LPCTSTR lpszItem) const;
+ void ResetContent() const;
+ int SelectString(int nStartAfter, LPCTSTR lpszItem) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ };
+
+ class CStatic : public CWnd
+ {
+ public:
+ CStatic() {}
+ virtual ~CStatic() {}
+
+ // Operations
+ HBITMAP GetBitmap() const;
+ HCURSOR GetCursor() const;
+ HENHMETAFILE GetEnhMetaFile() const;
+ HICON GetIcon() const;
+ HBITMAP SetBitmap(HBITMAP hBitmap) const;
+ HCURSOR SetCursor(HCURSOR hCursor) const;
+ HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile) const;
+ HICON SetIcon(HICON hIcon) const;
+
+ protected:
+ // Overridables
+ virtual void PreRegisterClass(WNDCLASS &wc);
+
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////////
+ // Definitions for the CButton class
+ //
+ inline HBITMAP CButton::GetBitmap() const
+ // returns the handle to the bitmap associated with the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HBITMAP)SendMessage(BM_GETIMAGE, IMAGE_BITMAP, 0);
+ }
+
+ inline UINT CButton::GetButtonStyle() const
+ // returns the style of the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)GetWindowLongPtr(GWL_STYLE) & 0xff;
+ }
+
+ inline int CButton::GetCheck() const
+ // returns the check state of the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(BM_GETCHECK, 0, 0);
+ }
+
+ inline HCURSOR CButton::GetCursor() const
+ // returns the handle to the cursor associated withe the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HCURSOR)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_CURSOR, 0L);
+ }
+
+ inline HICON CButton::GetIcon() const
+ // returns the handle to the icon associated withe the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(BM_GETIMAGE, IMAGE_ICON, 0);
+ }
+
+ inline UINT CButton::GetState() const
+ // returns the state of the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)SendMessage(BM_GETSTATE, 0, 0);
+ }
+
+ inline HBITMAP CButton::SetBitmap(HBITMAP hBitmap) const
+ // sets the bitmap associated with the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HBITMAP)SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
+ }
+
+ inline void CButton::SetButtonStyle(DWORD dwStyle, BOOL bRedraw) const
+ // sets the button style
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(BM_SETSTYLE, dwStyle, bRedraw);
+ }
+
+ inline void CButton::SetCheck(int nCheckState) const
+ // sets the button check state
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(BM_SETCHECK, nCheckState, 0);
+ }
+
+ inline HCURSOR CButton::SetCursor(HCURSOR hCursor) const
+ // sets the cursor associated with the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HCURSOR)SendMessage(STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor);
+ }
+
+ inline HICON CButton::SetIcon(HICON hIcon) const
+ // sets the icon associated with the button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage( BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ }
+
+ inline void CButton::SetState(BOOL bHighlight) const
+ // sets the button state
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(BM_SETSTATE, bHighlight, 0);
+ }
+
+ inline void CButton::PreCreate(CREATESTRUCT& cs)
+ {
+ cs.lpszClass = _T("Button");
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CEdit class
+ //
+ inline BOOL CEdit::CanUndo() const
+ // Returns TRUE if the edit control operation can be undone.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(EM_CANUNDO, 0, 0);
+ }
+
+ inline int CEdit::CharFromPos(CPoint pt) const
+ // Returns the character index and line index of the character nearest the specified point.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
+ }
+
+ inline int CEdit::GetFirstVisibleLine() const
+ // Returns the zero-based index of the first visible character in a single-line edit control
+ // or the zero-based index of the uppermost visible line in a multiline edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_GETFIRSTVISIBLELINE, 0, 0);
+ }
+
+ inline HLOCAL CEdit::GetHandle() const
+ // Returns a handle identifying the buffer containing the multiline edit control's text.
+ // It is not processed by single-line edit controls.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HLOCAL)SendMessage(EM_GETHANDLE, 0, 0);
+ }
+
+ inline UINT CEdit::GetLimitText() const
+ // Returns the current text limit, in characters.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)SendMessage(EM_GETLIMITTEXT, 0, 0);
+ }
+
+ inline int CEdit::GetLine(int nIndex, LPTSTR lpszBuffer) const
+ // Copies characters to a buffer and returns the number of characters copied.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
+ }
+
+ inline int CEdit::GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const
+ // Copies characters to a buffer and returns the number of characters copied.
+ {
+ assert(::IsWindow(m_hWnd));
+ *(LPWORD)lpszBuffer = (WORD)nMaxLength;
+ return (int)SendMessage(EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
+ }
+
+ inline int CEdit::GetLineCount() const
+ // Returns the number of lines in the edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_GETLINECOUNT, 0, 0);
+ }
+
+ inline DWORD CEdit::GetMargins() const
+ // Returns the widths of the left and right margins.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(EM_GETMARGINS, 0, 0);
+ }
+
+ inline BOOL CEdit::GetModify() const
+ // Returns a flag indicating whether the content of an edit control has been modified.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(EM_GETMODIFY, 0, 0);
+ }
+
+ inline TCHAR CEdit::GetPasswordChar() const
+ // Returns the character that edit controls use in conjunction with the ES_PASSWORD style.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (TCHAR)SendMessage(EM_GETPASSWORDCHAR, 0, 0);
+ }
+
+ inline void CEdit::GetRect(LPRECT lpRect) const
+ // Returns the coordinates of the formatting rectangle in an edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_GETRECT, 0, (LPARAM)lpRect);
+ }
+
+ inline void CEdit::GetSel(int& nStartChar, int& nEndChar) const
+ // Returns the starting and ending character positions of the current selection in the edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_GETSEL, (WPARAM)&nStartChar,(LPARAM)&nEndChar);
+ }
+
+ inline DWORD CEdit::GetSel() const
+ // Returns the starting and ending character positions of the current selection in the edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(EM_GETSEL, 0, 0);
+ }
+
+ inline CPoint CEdit::PosFromChar(UINT nChar) const
+ // Returns the client coordinates of the specified character.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CPoint( (DWORD)SendMessage(EM_POSFROMCHAR, nChar, 0));
+ }
+
+ inline void CEdit::SetHandle(HLOCAL hBuffer) const
+ // Sets a handle to the memory used as a text buffer, empties the undo buffer,
+ // resets the scroll positions to zero, and redraws the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETHANDLE, (WPARAM)hBuffer, 0);
+ }
+
+ inline void CEdit::SetLimitText(UINT nMax) const
+ // Sets the maximum number of characters the user may enter in the edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETLIMITTEXT, (WPARAM)nMax, 0);
+ }
+
+ inline void CEdit::SetMargins(UINT nLeft, UINT nRight) const
+ // Sets the widths of the left and right margins, and redraws the edit control to reflect the new margins.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(nLeft, nRight));
+ }
+
+ inline void CEdit::SetModify(BOOL bModified) const
+ // Sets or clears the modification flag to indicate whether the edit control has been modified.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETMODIFY, bModified, 0);
+ }
+
+ inline void CEdit::EmptyUndoBuffer() const
+ // Empties the undo buffer and sets the undo flag retrieved by the EM_CANUNDO message to FALSE.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_EMPTYUNDOBUFFER, 0, 0);
+ }
+
+ inline BOOL CEdit::FmtLines(BOOL bAddEOL) const
+ // Adds or removes soft line-break characters (two carriage returns and a line feed) to the ends of wrapped lines
+ // in a multiline edit control. It is not processed by single-line edit controls.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(EM_FMTLINES, bAddEOL, 0);
+ }
+
+ inline void CEdit::LimitText(int nChars) const
+ // Sets the text limit of an edit control. The text limit is the maximum amount of text, in TCHARs,
+ // that the user can type into the edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_LIMITTEXT, nChars, 0);
+ }
+
+ inline int CEdit::LineFromChar(int nIndex) const
+ // Returns the zero-based number of the line in a multiline edit control that contains a specified character index.
+ // This message is the reverse of the EM_LINEINDEX message.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_LINEFROMCHAR, (WPARAM)nIndex, 0);
+ }
+
+ inline int CEdit::LineIndex(int nLine) const
+ // Returns the character of a line in a multiline edit control.
+ // This message is the reverse of the EM_LINEFROMCHAR message
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_LINEINDEX, (WPARAM)nLine, 0);
+ }
+
+ inline int CEdit::LineLength(int nLine) const
+ // Returns the length, in characters, of a single-line edit control. In a multiline edit control,
+ // returns the length, in characters, of a specified line.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(EM_LINELENGTH, (WPARAM)nLine, 0);
+ }
+
+ inline void CEdit::LineScroll(int nLines, int nChars) const
+ // Scrolls the text vertically in a single-line edit control or horizontally in a multiline edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_LINESCROLL, (WPARAM)nChars, (LPARAM)nLines);
+ }
+
+ inline void CEdit::ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo) const
+ // Replaces the current selection with the text in an application-supplied buffer, sends the parent window
+ // EN_UPDATE and EN_CHANGE messages, and updates the undo buffer.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText);
+ }
+
+ inline void CEdit::SetPasswordChar(TCHAR ch) const
+ // Defines the character that edit controls use in conjunction with the ES_PASSWORD style.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETPASSWORDCHAR, ch, 0);
+ }
+
+ inline BOOL CEdit::SetReadOnly(BOOL bReadOnly) const
+ // Sets or removes the read-only style (ES_READONLY) in an edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(EM_SETREADONLY, bReadOnly, 0);
+ }
+
+ inline void CEdit::SetRect(LPCRECT lpRect) const
+ // Sets the formatting rectangle for the multiline edit control and redraws the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETRECT, 0, (LPARAM)lpRect);
+ }
+
+ inline void CEdit::SetRectNP(LPCRECT lpRect) const
+ // Sets the formatting rectangle for the multiline edit control but does not redraw the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETRECTNP, 0, (LPARAM)lpRect);
+ }
+
+ inline void CEdit::SetSel(DWORD dwSelection, BOOL bNoScroll) const
+ // Selects a range of characters in the edit control by setting the starting and ending positions to be selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection));
+ if (!bNoScroll)
+ SendMessage(EM_SCROLLCARET, 0, 0);
+ }
+
+ inline void CEdit::SetSel(int nStartChar, int nEndChar, BOOL bNoScroll) const
+ // Selects a range of characters in the edit control by setting the starting and ending positions to be selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar);
+ if (!bNoScroll)
+ SendMessage(EM_SCROLLCARET, 0, 0);
+ }
+
+ inline BOOL CEdit::SetTabStops(int nTabStops, LPINT rgTabStops) const
+ // Sets tab-stop positions in the multiline edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
+ }
+
+ inline BOOL CEdit::SetTabStops() const
+ // Sets tab-stop positions in the multiline edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage( EM_SETTABSTOPS, 0, 0);
+ }
+
+ inline BOOL CEdit::SetTabStops(const int& cxEachStop) const
+ // Sets tab-stop positions in the multiline edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
+ }
+
+ inline void CEdit::Clear() const
+ // Clears the current selection, if any, in an edit control.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(WM_CLEAR, 0, 0);
+ }
+
+ inline void CEdit::Copy() const
+ // Copies text to the clipboard unless the style is ES_PASSWORD, in which case the message returns zero.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(WM_COPY, 0, 0);
+ }
+
+ inline void CEdit::Cut() const
+ // Cuts the selection to the clipboard, or deletes the character to the left of the cursor if there is no selection.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(WM_CUT, 0, 0);
+ }
+
+ inline void CEdit::Paste() const
+ // Pastes text from the clipboard into the edit control window at the caret position.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(WM_PASTE, 0, 0);
+ }
+
+ inline void CEdit::Undo() const
+ // Removes any text that was just inserted or inserts any deleted characters and sets the selection to the inserted text.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(EM_UNDO, 0, 0);
+ }
+
+ inline void CEdit::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = _T("Edit");
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CListbox class
+ //
+ inline int CListBox::GetCount() const
+ // Returns the number of items in the list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETCOUNT, 0, 0);
+ }
+
+ inline int CListBox::GetHorizontalExtent() const
+ // Returns the scrollable width, in pixels, of a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETHORIZONTALEXTENT, 0, 0);
+ }
+
+ inline DWORD CListBox::GetItemData(int nIndex) const
+ // Returns the value associated with the specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(LB_GETITEMDATA, nIndex, 0);
+ }
+
+ inline void* CListBox::GetItemDataPtr(int nIndex) const
+ // Returns the value associated with the specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (LPVOID)SendMessage(LB_GETITEMDATA, nIndex, 0);
+ }
+
+ inline int CListBox::GetItemHeight(int nIndex) const
+ // Returns the height, in pixels, of an item in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETITEMHEIGHT, nIndex, 0L);
+ }
+
+ inline int CListBox::GetItemRect(int nIndex, LPRECT lpRect) const
+ // Retrieves the client coordinates of the specified list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETITEMRECT, nIndex, (LPARAM)lpRect);
+ }
+
+ inline LCID CListBox::GetLocale() const
+ // Retrieves the locale of the list box. The high-order word contains the country/region code
+ // and the low-order word contains the language identifier.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0);
+ }
+
+ inline int CListBox::GetSel(int nIndex) const
+ // Returns the selection state of a list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETSEL, nIndex, 0);
+ }
+
+ inline int CListBox::GetText(int nIndex, LPTSTR lpszBuffer) const
+ // Retrieves the string associated with a specified item and the length of the string.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer);
+ }
+
+ inline int CListBox::GetTextLen(int nIndex) const
+ // Returns the length, in characters, of the string associated with a specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage( LB_GETTEXTLEN, nIndex, 0);
+ }
+
+ inline int CListBox::GetTopIndex() const
+ // Returns the index of the first visible item in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETTOPINDEX, 0, 0);
+ }
+
+ inline UINT CListBox::ItemFromPoint(CPoint pt, BOOL& bOutside) const
+ // Retrieves the zero-based index of the item nearest the specified point in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
+ bOutside = !!HIWORD(dw);
+ return LOWORD(dw);
+ }
+
+ inline void CListBox::SetColumnWidth(int cxWidth) const
+ // Sets the width, in pixels, of all columns in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(LB_SETCOLUMNWIDTH, cxWidth, 0);
+ }
+
+ inline void CListBox::SetHorizontalExtent(int cxExtent) const
+ // Sets the scrollable width, in pixels, of a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(LB_SETHORIZONTALEXTENT, cxExtent, 0);
+ }
+
+ inline int CListBox::SetItemData(int nIndex, DWORD dwItemData) const
+ // Associates a value with a list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETITEMDATA, nIndex, (LPARAM)dwItemData);
+ }
+
+ inline int CListBox::SetItemDataPtr(int nIndex, void* pData) const
+ // Associates a value with a list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return SetItemData(nIndex, (DWORD)(DWORD_PTR)pData);
+ }
+
+ inline int CListBox::SetItemHeight(int nIndex, UINT cyItemHeight) const
+ // Sets the height, in pixels, of an item or items in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0));
+ }
+
+ inline LCID CListBox::SetLocale(LCID nNewLocale) const
+ // Sets the locale of a list box and returns the previous locale identifier.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0);
+ }
+
+ inline BOOL CListBox::SetTabStops(int nTabStops, LPINT rgTabStops) const
+ // Sets the tab stops to those specified in a specified array.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops);
+ }
+
+ inline void CListBox::SetTabStops() const
+ // Sets the tab stops to those specified in a specified array.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(LB_SETTABSTOPS, 0, 0);
+ }
+
+ inline BOOL CListBox::SetTabStops(const int& cxEachStop) const
+ // Sets the tab stops to those specified in a specified array.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop);
+ }
+
+ inline int CListBox::SetTopIndex(int nIndex) const
+ // Scrolls the list box so the specified item is at the top of the visible range.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETTOPINDEX, nIndex, 0);
+ }
+
+ inline int CListBox::GetCurSel() const
+ // Returns the index of the currently selected item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETCURSEL, 0, 0);
+ }
+
+ inline int CListBox::SetCurSel(int nSelect) const
+ // Selects a specified list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETCURSEL, nSelect, 0);
+ }
+
+ inline int CListBox::GetAnchorIndex() const
+ // Returns the index of the item that the mouse last selected.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETANCHORINDEX, 0, 0);
+ }
+
+ inline int CListBox::GetCaretIndex() const
+ // Returns the index of the item that has the focus rectangle.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETCARETINDEX, 0, 0L);
+ }
+
+ inline int CListBox::GetSelCount() const
+ // Returns the number of selected items in a multiple-selection list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETSELCOUNT, 0, 0);
+ }
+
+ inline int CListBox::GetSelItems(int nMaxItems, LPINT rgIndex) const
+ // Creates an array of the indexes of all selected items in a multiple-selection list box
+ // and returns the total number of selected items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex);
+ }
+
+ inline int CListBox::SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem) const
+ // Selects a specified range of items in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ if (bSelect)
+ return (int)SendMessage(LB_SELITEMRANGEEX, nFirstItem, nLastItem);
+ else
+ return (int)SendMessage(LB_SELITEMRANGEEX, nLastItem, nFirstItem);
+ }
+
+ inline void CListBox::SetAnchorIndex(int nIndex) const
+ // Sets the item that the mouse last selected to a specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(LB_SETANCHORINDEX, nIndex, 0);
+ }
+
+ inline int CListBox::SetCaretIndex(int nIndex, BOOL bScroll) const
+ // Sets the focus rectangle to a specified list box item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0));
+ }
+
+ inline int CListBox::SetSel(int nIndex, BOOL bSelect) const
+ // Selects an item in a multiple-selection list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_SETSEL, bSelect, nIndex);
+ }
+
+ inline int CListBox::AddString(LPCTSTR lpszItem) const
+ // Adds a string to a list box and returns its index.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_ADDSTRING, 0, (LPARAM)lpszItem);
+ }
+
+ inline int CListBox::DeleteString(UINT nIndex) const
+ // Removes a string from a list box and returns the number of strings remaining in the list.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_DELETESTRING, nIndex, 0);
+ }
+
+ inline int CListBox::Dir(UINT attr, LPCTSTR lpszWildCard) const
+ // Adds a list of filenames to a list box and returns the index of the last filename added.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_DIR, attr, (LPARAM)lpszWildCard);
+ }
+
+ inline int CListBox::FindString(int nStartAfter, LPCTSTR lpszItem) const
+ // Returns the index of the first string in the list box that begins with a specified string.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem);
+ }
+
+ inline int CListBox::FindStringExact(int nIndexStart, LPCTSTR lpszFind) const
+ // Returns the index of the string in the list box that is equal to a specified string.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind);
+ }
+
+ inline int CListBox::InsertString(int nIndex, LPCTSTR lpszItem) const
+ // Inserts a string at a specified index in a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(LB_INSERTSTRING, nIndex, (LPARAM)lpszItem);
+ }
+
+ inline void CListBox::ResetContent() const
+ // Removes all items from a list box.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(LB_RESETCONTENT, 0, 0);
+ }
+
+ inline int CListBox::SelectString(int nStartAfter, LPCTSTR lpszItem) const
+ // Selects the first string it finds that matches a specified prefix.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem);
+ }
+
+ inline void CListBox::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = _T("ListBox");
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CStatic class
+ //
+ inline HBITMAP CStatic::GetBitmap() const
+ // Returns the handle to the bitmap for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HBITMAP)SendMessage(STM_GETIMAGE, IMAGE_BITMAP, 0);
+ }
+
+ inline HCURSOR CStatic::GetCursor() const
+ // Returns the handle to the icon for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HCURSOR)SendMessage(STM_GETIMAGE, IMAGE_CURSOR, 0);
+ }
+
+ inline HENHMETAFILE CStatic::GetEnhMetaFile() const
+ // Returns the handle to the enhanced metafile for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HENHMETAFILE)SendMessage(STM_GETIMAGE, IMAGE_ENHMETAFILE, 0);
+ }
+
+ inline HICON CStatic::GetIcon() const
+ // Returns the handle to the icon for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(STM_GETIMAGE, IMAGE_ICON, 0);
+ }
+
+ inline HBITMAP CStatic::SetBitmap(HBITMAP hBitmap) const
+ // Sets the handle to the bitmap for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HBITMAP)SendMessage(STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
+ }
+
+ inline HCURSOR CStatic::SetCursor(HCURSOR hCursor) const
+ // Sets the handle to the cursor for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HCURSOR)SendMessage(STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor);
+ }
+
+ inline HENHMETAFILE CStatic::SetEnhMetaFile(HENHMETAFILE hMetaFile) const
+ // Sets the handle to the enhanced metafile for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HENHMETAFILE)SendMessage(STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile);
+ }
+
+ inline HICON CStatic::SetIcon(HICON hIcon) const
+ // Sets the handle to the icon for the static control
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ }
+
+ inline void CStatic::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = _T("Static");
+ }
+
+}
+
+#endif // _WIN32XX_STDCONTROLS_H_
+
diff --git a/mmc_updater/depends/win32cpp/tab.h b/mmc_updater/depends/win32cpp/tab.h
new file mode 100644
index 00000000..15699144
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/tab.h
@@ -0,0 +1,1658 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////
+// tab.h
+// Declaration of the CTab and CMDITab classes
+
+#ifndef _WIN32XX_TAB_H_
+#define _WIN32XX_TAB_H_
+
+#include "wincore.h"
+#include "dialog.h"
+#include "gdi.h"
+#include "default_resource.h"
+
+namespace Win32xx
+{
+
+ struct TabPageInfo
+ {
+ TCHAR szTabText[MAX_MENU_STRING];
+ int iImage; // index of this tab's image
+ int idTab; // identifier for this tab (optional)
+ CWnd* pView; // pointer to the view window
+ };
+
+ class CTab : public CWnd
+ {
+ protected:
+ // Declaration of the CSelectDialog class, a nested class of CTab
+ // It creates the dialog to choose which tab to activate
+ class CSelectDialog : public CDialog
+ {
+ public:
+ CSelectDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent = NULL);
+ virtual ~CSelectDialog() {}
+ virtual void AddItem(LPCTSTR szString);
+ virtual BOOL IsTab() const { return FALSE; }
+
+ protected:
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ virtual void OnCancel() { EndDialog(-2); }
+
+ private:
+ CSelectDialog(const CSelectDialog&); // Disable copy construction
+ CSelectDialog& operator = (const CSelectDialog&); // Disable assignment operator
+
+ std::vector<tString> m_vItems;
+ int IDC_LIST;
+
+ };
+ public:
+ CTab();
+ virtual ~CTab();
+ virtual int AddTabPage(WndPtr pView, LPCTSTR szTabText, HICON hIcon, UINT idTab);
+ virtual int AddTabPage(WndPtr pView, LPCTSTR szTabText, int nID_Icon, UINT idTab = 0);
+ virtual int AddTabPage(WndPtr pView, LPCTSTR szTabText);
+ virtual CRect GetCloseRect() const;
+ virtual CRect GetListRect() const;
+ virtual HMENU GetListMenu();
+ virtual BOOL GetTabsAtTop() const;
+ virtual int GetTabIndex(CWnd* pWnd) const;
+ virtual TabPageInfo GetTabPageInfo(UINT nTab) const;
+ virtual int GetTextHeight() const;
+ virtual void RecalcLayout();
+ virtual void RemoveTabPage(int nPage);
+ virtual void SelectPage(int nPage);
+ virtual void SetFixedWidth(BOOL bEnabled);
+ virtual void SetOwnerDraw(BOOL bEnabled);
+ virtual void SetShowButtons(BOOL bShow);
+ virtual void SetTabIcon(int i, HICON hIcon);
+ virtual void SetTabsAtTop(BOOL bTop);
+ virtual void SetTabText(UINT nTab, LPCTSTR szText);
+ virtual void SwapTabs(UINT nTab1, UINT nTab2);
+
+ // Attributes
+ std::vector <TabPageInfo>& GetAllTabs() const { return (std::vector <TabPageInfo>&) m_vTabPageInfo; }
+ HIMAGELIST GetImageList() const { return m_himlTab; }
+ BOOL GetShowButtons() const { return m_bShowButtons; }
+ int GetTabHeight() const { return m_nTabHeight; }
+ CWnd* GetActiveView() const { return m_pActiveView; }
+ void SetTabHeight(int nTabHeight) { m_nTabHeight = nTabHeight; NotifyChanged();}
+
+ // Wrappers for Win32 Macros
+ void AdjustRect(BOOL fLarger, RECT *prc) const;
+ int GetCurFocus() const;
+ int GetCurSel() const;
+ BOOL GetItem(int iItem, LPTCITEM pitem) const;
+ int GetItemCount() const;
+ int HitTest(TCHITTESTINFO& info) const;
+ void SetCurFocus(int iItem) const;
+ int SetCurSel(int iItem) const;
+ DWORD SetItemSize(int cx, int cy) const;
+ int SetMinTabWidth(int cx) const;
+ void SetPadding(int cx, int cy) const;
+
+ protected:
+ virtual void DrawCloseButton(CDC& DrawDC);
+ virtual void DrawListButton(CDC& DrawDC);
+ virtual void DrawTabs(CDC& dcMem);
+ virtual void DrawTabBorders(CDC& dcMem, CRect& rcTab);
+ virtual void OnCreate();
+ virtual void OnLButtonDown(WPARAM wParam, LPARAM lParam);
+ virtual void OnLButtonUp(WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseLeave(WPARAM wParam, LPARAM lParam);
+ virtual void OnMouseMove(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNCHitTest(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam);
+ virtual void NotifyChanged();
+ virtual void Paint();
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual void SetTabSize();
+ virtual void ShowListDialog();
+ virtual void ShowListMenu();
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CTab(const CTab&); // Disable copy construction
+ CTab& operator = (const CTab&); // Disable assignment operator
+
+ SIZE GetMaxTabSize() const;
+ void ShowActiveView(CWnd* pView);
+
+ std::vector<TabPageInfo> m_vTabPageInfo;
+ std::vector<WndPtr> m_vTabViews;
+ CFont m_Font;
+ HIMAGELIST m_himlTab;
+ HMENU m_hListMenu;
+ CWnd* m_pActiveView;
+ BOOL m_bShowButtons; // Show or hide the close and list button
+ BOOL m_IsTracking;
+ BOOL m_IsClosePressed;
+ BOOL m_IsListPressed;
+ BOOL m_IsListMenuActive;
+ int m_nTabHeight;
+ };
+
+ ////////////////////////////////////////
+ // Declaration of the CTabbedMDI class
+ class CTabbedMDI : public CWnd
+ {
+ public:
+ CTabbedMDI();
+ virtual ~CTabbedMDI();
+ virtual CWnd* AddMDIChild(CWnd* pView, LPCTSTR szTabText, int idMDIChild = 0);
+ virtual void CloseActiveMDI();
+ virtual void CloseAllMDIChildren();
+ virtual void CloseMDIChild(int nTab);
+ virtual CWnd* GetActiveMDIChild() const;
+ virtual int GetActiveMDITab() const;
+ virtual CWnd* GetMDIChild(int nTab) const;
+ virtual int GetMDIChildCount() const;
+ virtual int GetMDIChildID(int nTab) const;
+ virtual LPCTSTR GetMDIChildTitle(int nTab) const;
+ virtual HMENU GetListMenu() const { return GetTab().GetListMenu(); }
+ virtual CTab& GetTab() const {return (CTab&)m_Tab;}
+ virtual BOOL LoadRegistrySettings(tString tsRegistryKeyName);
+ virtual void RecalcLayout();
+ virtual BOOL SaveRegistrySettings(tString tsRegistryKeyName);
+ virtual void SetActiveMDIChild(CWnd* pWnd);
+ virtual void SetActiveMDITab(int nTab);
+
+ protected:
+ virtual HWND Create(CWnd* pParent);
+ virtual CWnd* NewMDIChildFromID(int idMDIChild);
+ virtual void OnCreate();
+ virtual void OnDestroy(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual void OnWindowPosChanged(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CTabbedMDI(const CTabbedMDI&); // Disable copy construction
+ CTabbedMDI& operator = (const CTabbedMDI&); // Disable assignment operator
+
+ CTab m_Tab;
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ /////////////////////////////////////////////////////////////
+ // Definitions for the CSelectDialog class nested within CTab
+ //
+ inline CTab::CSelectDialog::CSelectDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent) :
+ CDialog(lpTemplate, pParent), IDC_LIST(121)
+ {
+ }
+
+ inline BOOL CTab::CSelectDialog::OnInitDialog()
+ {
+ for (UINT u = 0; u < m_vItems.size(); ++u)
+ {
+ SendDlgItemMessage(IDC_LIST, LB_ADDSTRING, 0, (LPARAM) m_vItems[u].c_str());
+ }
+
+ return true;
+ }
+
+ inline void CTab::CSelectDialog::AddItem(LPCTSTR szString)
+ {
+ m_vItems.push_back(szString);
+ }
+
+ inline void CTab::CSelectDialog::OnOK()
+ {
+ int iSelect = (int)SendDlgItemMessage(IDC_LIST, LB_GETCURSEL, 0, 0);
+ if (iSelect != LB_ERR)
+ EndDialog(iSelect);
+ else
+ EndDialog(-2);
+ }
+
+
+ //////////////////////////////////////////////////////////
+ // Definitions for the CTab class
+ //
+ inline CTab::CTab() : m_hListMenu(NULL), m_pActiveView(NULL), m_bShowButtons(FALSE), m_IsTracking(FALSE), m_IsClosePressed(FALSE),
+ m_IsListPressed(FALSE), m_IsListMenuActive(FALSE), m_nTabHeight(0)
+ {
+ // Create and assign the image list
+ m_himlTab = ImageList_Create(16, 16, ILC_MASK|ILC_COLOR32, 0, 0);
+
+ // Set the tab control's font
+ NONCLIENTMETRICS info = {0};
+ info.cbSize = GetSizeofNonClientMetrics();
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
+ m_Font.CreateFontIndirect(&info.lfStatusFont);
+ }
+
+ inline CTab::~CTab()
+ {
+ ImageList_Destroy(m_himlTab);
+
+ if (IsMenu(m_hListMenu)) ::DestroyMenu(m_hListMenu);
+ }
+
+ inline int CTab::AddTabPage(WndPtr pView, LPCTSTR szTabText, HICON hIcon, UINT idTab)
+ {
+ assert(pView.get());
+ assert(lstrlen(szTabText) < MAX_MENU_STRING);
+
+ m_vTabViews.push_back(pView);
+
+ TabPageInfo tpi = {0};
+ tpi.pView = pView.get();
+ tpi.idTab = idTab;
+ lstrcpyn(tpi.szTabText, szTabText, MAX_MENU_STRING);
+ if (hIcon)
+ tpi.iImage = ImageList_AddIcon(GetImageList(), hIcon);
+ else
+ tpi.iImage = -1;
+
+ int iNewPage = (int)m_vTabPageInfo.size();
+ m_vTabPageInfo.push_back(tpi);
+
+ if (m_hWnd)
+ {
+ TCITEM tie = {0};
+ tie.mask = TCIF_TEXT | TCIF_IMAGE;
+ tie.iImage = tpi.iImage;
+ tie.pszText = tpi.szTabText;
+ TabCtrl_InsertItem(m_hWnd, iNewPage, &tie);
+
+ SetTabSize();
+ SelectPage(iNewPage);
+ NotifyChanged();
+ }
+
+ return iNewPage;
+ }
+
+ inline int CTab::AddTabPage(WndPtr pView, LPCTSTR szTabText, int idIcon, UINT idTab /* = 0*/)
+ {
+ HICON hIcon = (HICON)LoadImage(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(idIcon), IMAGE_ICON, 0, 0, LR_SHARED);
+ return AddTabPage(pView, szTabText, hIcon, idTab);
+ }
+
+ inline int CTab::AddTabPage(WndPtr pView, LPCTSTR szTabText)
+ {
+ return AddTabPage(pView, szTabText, (HICON)0, 0);
+ }
+
+ inline void CTab::DrawCloseButton(CDC& DrawDC)
+ {
+ // The close button isn't displayed on Win95
+ if (GetWinVersion() == 1400) return;
+
+ if (!m_bShowButtons) return;
+ if (!GetActiveView()) return;
+ if (!(GetWindowLongPtr(GWL_STYLE) & TCS_FIXEDWIDTH)) return;
+ if (!(GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED)) return;
+
+ // Determine the close button's drawing position relative to the window
+ CRect rcClose = GetCloseRect();
+
+ CPoint pt = GetCursorPos();
+ ScreenToClient(pt);
+ UINT uState = rcClose.PtInRect(pt)? m_IsClosePressed? 2: 1: 0;
+
+ // Draw the outer highlight for the close button
+ if (!IsRectEmpty(&rcClose))
+ {
+ switch (uState)
+ {
+ case 0:
+ {
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(232, 228, 220));
+
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ break;
+ }
+
+ case 1:
+ {
+ // Draw outline, white at top, black on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ }
+
+ break;
+ case 2:
+ {
+ // Draw outline, black on top, white on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.MoveTo(rcClose.left, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.bottom);
+ DrawDC.LineTo(rcClose.right, rcClose.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.LineTo(rcClose.left, rcClose.top);
+ DrawDC.LineTo(rcClose.left, rcClose.bottom);
+ }
+ break;
+ }
+
+ // Manually draw close button
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(64, 64, 64));
+
+ DrawDC.MoveTo(rcClose.left + 3, rcClose.top +3);
+ DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.left + 4, rcClose.top +3);
+ DrawDC.LineTo(rcClose.right - 2, rcClose.bottom -3);
+
+ DrawDC.MoveTo(rcClose.left + 3, rcClose.top +4);
+ DrawDC.LineTo(rcClose.right - 3, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -3, rcClose.top +3);
+ DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -3, rcClose.top +4);
+ DrawDC.LineTo(rcClose.left + 3, rcClose.bottom -2);
+
+ DrawDC.MoveTo(rcClose.right -4, rcClose.top +3);
+ DrawDC.LineTo(rcClose.left + 2, rcClose.bottom -3);
+ }
+ }
+
+ inline void CTab::DrawListButton(CDC& DrawDC)
+ {
+ // The list button isn't displayed on Win95
+ if (GetWinVersion() == 1400) return;
+
+ if (!m_bShowButtons) return;
+ if (!GetActiveView()) return;
+ if (!(GetWindowLongPtr(GWL_STYLE) & TCS_FIXEDWIDTH)) return;
+ if (!(GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED)) return;
+
+ // Determine the list button's drawing position relative to the window
+ CRect rcList = GetListRect();
+
+ CPoint pt = GetCursorPos();
+ ScreenToClient(pt);
+ UINT uState = rcList.PtInRect(pt)? 1: 0;
+ if (m_IsListMenuActive) uState = 2;
+
+ // Draw the outer highlight for the list button
+ if (!IsRectEmpty(&rcList))
+ {
+ switch (uState)
+ {
+ case 0:
+ {
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(232, 228, 220));
+
+ DrawDC.MoveTo(rcList.left, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.top);
+ DrawDC.LineTo(rcList.left, rcList.top);
+ DrawDC.LineTo(rcList.left, rcList.bottom);
+ break;
+ }
+
+ case 1:
+ {
+ // Draw outline, white at top, black on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.MoveTo(rcList.left, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.LineTo(rcList.left, rcList.top);
+ DrawDC.LineTo(rcList.left, rcList.bottom);
+ }
+
+ break;
+ case 2:
+ {
+ // Draw outline, black on top, white on bottom
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
+ DrawDC.MoveTo(rcList.left, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.bottom);
+ DrawDC.LineTo(rcList.right, rcList.top);
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
+ DrawDC.LineTo(rcList.left, rcList.top);
+ DrawDC.LineTo(rcList.left, rcList.bottom);
+ }
+ break;
+ }
+
+ // Manually draw list button
+ DrawDC.CreatePen(PS_SOLID, 1, RGB(64, 64, 64));
+
+ int MaxLength = (int)(0.65 * rcList.Width());
+ int topGap = 1 + rcList.Height()/3;
+ for (int i = 0; i <= MaxLength/2; i++)
+ {
+ int Length = MaxLength - 2*i;
+ DrawDC.MoveTo(rcList.left +1 + (rcList.Width() - Length)/2, rcList.top +topGap +i);
+ DrawDC.LineTo(rcList.left +1 + (rcList.Width() - Length)/2 + Length, rcList.top +topGap +i);
+ }
+ }
+ }
+
+ inline void CTab::DrawTabs(CDC& dcMem)
+ {
+ // Draw the tab buttons:
+ for (int i = 0; i < TabCtrl_GetItemCount(m_hWnd); ++i)
+ {
+ CRect rcItem;
+ TabCtrl_GetItemRect(m_hWnd, i, &rcItem);
+ if (!rcItem.IsRectEmpty())
+ {
+ if (i == TabCtrl_GetCurSel(m_hWnd))
+ {
+ dcMem.CreateSolidBrush(RGB(248,248,248));
+ dcMem.SetBkColor(RGB(248,248,248));
+ }
+ else
+ {
+ dcMem.CreateSolidBrush(RGB(200,200,200));
+ dcMem.SetBkColor(RGB(200,200,200));
+ }
+
+ dcMem.CreatePen(PS_SOLID, 1, RGB(160, 160, 160));
+ dcMem.RoundRect(rcItem.left+1, rcItem.top, rcItem.right+2, rcItem.bottom, 6, 6);
+
+ if (rcItem.Width() >= 24)
+ {
+ TCHAR szText[30];
+ TCITEM tcItem = {0};
+ tcItem.mask = TCIF_TEXT | TCIF_IMAGE;
+ tcItem.cchTextMax = 30;
+ tcItem.pszText = szText;
+ TabCtrl_GetItem(m_hWnd, i, &tcItem);
+ int xImage;
+ int yImage;
+ int yOffset = 0;
+ if (ImageList_GetIconSize(m_himlTab, &xImage, &yImage))
+ yOffset = (rcItem.Height() - yImage)/2;
+
+ // Draw the icon
+ ImageList_Draw(m_himlTab, tcItem.iImage, dcMem, rcItem.left+5, rcItem.top+yOffset, ILD_NORMAL);
+
+ // Draw the text
+ dcMem.SelectObject(&m_Font);
+
+ // Calculate the size of the text
+ CRect rcText = rcItem;
+
+ int iImageSize = 20;
+ int iPadding = 4;
+ if (tcItem.iImage >= 0)
+ rcText.left += iImageSize;
+
+ rcText.left += iPadding;
+ dcMem.DrawText(szText, -1, rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
+ }
+ }
+ }
+ }
+
+ inline void CTab::DrawTabBorders(CDC& dcMem, CRect& rcTab)
+ {
+ BOOL IsBottomTab = (BOOL)GetWindowLongPtr(GWL_STYLE) & TCS_BOTTOM;
+
+ // Draw a lighter rectangle touching the tab buttons
+ CRect rcItem;
+ TabCtrl_GetItemRect(m_hWnd, 0, &rcItem);
+ int left = rcItem.left +1;
+ int right = rcTab.right;
+ int top = rcTab.bottom;
+ int bottom = top + 3;
+
+ if (!IsBottomTab)
+ {
+ bottom = MAX(rcTab.top, m_nTabHeight +4);
+ top = bottom -3;
+ }
+
+ dcMem.CreateSolidBrush(RGB(248,248,248));
+ dcMem.CreatePen(PS_SOLID, 1, RGB(248,248,248));
+ if (!rcItem.IsRectEmpty())
+ {
+ dcMem.Rectangle(left, top, right, bottom);
+
+ // Draw a darker line below the rectangle
+ dcMem.CreatePen(PS_SOLID, 1, RGB(160, 160, 160));
+ if (IsBottomTab)
+ {
+ dcMem.MoveTo(left-1, bottom);
+ dcMem.LineTo(right, bottom);
+ }
+ else
+ {
+ dcMem.MoveTo(left-1, top-1);
+ dcMem.LineTo(right, top-1);
+ }
+
+ // Draw a lighter line over the darker line for the selected tab
+ dcMem.CreatePen(PS_SOLID, 1, RGB(248,248,248));
+ TabCtrl_GetItemRect(m_hWnd, TabCtrl_GetCurSel(m_hWnd), &rcItem);
+ OffsetRect(&rcItem, 1, 1);
+
+ if (IsBottomTab)
+ {
+ dcMem.MoveTo(rcItem.left, bottom);
+ dcMem.LineTo(rcItem.right, bottom);
+ }
+ else
+ {
+ dcMem.MoveTo(rcItem.left, top-1);
+ dcMem.LineTo(rcItem.right, top-1);
+ }
+ }
+ }
+
+ inline CRect CTab::GetCloseRect() const
+ {
+ CRect rcClose;
+ if (GetShowButtons())
+ {
+ rcClose= GetClientRect();
+ int Gap = 2;
+ int cx = GetSystemMetrics(SM_CXSMICON) -1;
+ int cy = GetSystemMetrics(SM_CYSMICON) -1;
+ rcClose.right -= Gap;
+ rcClose.left = rcClose.right - cx;
+
+ if (GetTabsAtTop())
+ rcClose.top = Gap;
+ else
+ rcClose.top = MAX(Gap, rcClose.bottom - m_nTabHeight);
+
+ rcClose.bottom = rcClose.top + cy;
+ }
+ return rcClose;
+ }
+
+ inline HMENU CTab::GetListMenu()
+ {
+ if (IsMenu(m_hListMenu))
+ ::DestroyMenu(m_hListMenu);
+
+ m_hListMenu = CreatePopupMenu();
+
+ // Add the menu items
+ for(UINT u = 0; u < MIN(GetAllTabs().size(), 9); ++u)
+ {
+ TCHAR szMenuString[MAX_MENU_STRING+1];
+ TCHAR szTabText[MAX_MENU_STRING];
+ lstrcpyn(szTabText, GetAllTabs()[u].szTabText, MAX_MENU_STRING -4);
+ wsprintf(szMenuString, _T("&%d %s"), u+1, szTabText);
+ AppendMenu(m_hListMenu, MF_STRING, IDW_FIRSTCHILD +u, szMenuString);
+ }
+ if (GetAllTabs().size() >= 10)
+ AppendMenu(m_hListMenu, MF_STRING, IDW_FIRSTCHILD +9, _T("More Windows"));
+
+ // Add a checkmark to the menu
+ int iSelected = GetCurSel();
+ if (iSelected < 9)
+ CheckMenuItem(m_hListMenu, iSelected, MF_BYPOSITION|MF_CHECKED);
+
+ return m_hListMenu;
+ }
+
+ inline CRect CTab::GetListRect() const
+ {
+ CRect rcList;
+ if (GetShowButtons())
+ {
+ CRect rcClose = GetCloseRect();
+ rcList = rcClose;
+ rcList.OffsetRect( -(rcClose.Width() + 2), 0);
+ rcList.InflateRect(-1, 0);
+ }
+ return rcList;
+ }
+
+ inline SIZE CTab::GetMaxTabSize() const
+ {
+ CSize Size;
+
+ for (int i = 0; i < TabCtrl_GetItemCount(m_hWnd); i++)
+ {
+ CClientDC dcClient(this);
+ dcClient.SelectObject(&m_Font);
+ std::vector<TCHAR> vTitle(MAX_MENU_STRING, _T('\0'));
+ TCHAR* pszTitle = &vTitle.front();
+ TCITEM tcItem = {0};
+ tcItem.mask = TCIF_TEXT |TCIF_IMAGE;
+ tcItem.cchTextMax = MAX_MENU_STRING;
+ tcItem.pszText = pszTitle;
+ TabCtrl_GetItem(m_hWnd, i, &tcItem);
+ CSize TempSize = dcClient.GetTextExtentPoint32(pszTitle, lstrlen(pszTitle));
+
+ int iImageSize = 0;
+ int iPadding = 6;
+ if (tcItem.iImage >= 0)
+ iImageSize = 20;
+ TempSize.cx += iImageSize + iPadding;
+
+ if (TempSize.cx > Size.cx)
+ Size = TempSize;
+ }
+
+ return Size;
+ }
+
+ inline BOOL CTab::GetTabsAtTop() const
+ // Returns TRUE if the contol's tabs are placed at the top
+ {
+ DWORD dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
+ return (!(dwStyle & TCS_BOTTOM));
+ }
+
+ inline int CTab::GetTextHeight() const
+ {
+ CClientDC dcClient(this);
+ dcClient.SelectObject(&m_Font);
+ CSize szText = dcClient.GetTextExtentPoint32(_T("Text"), lstrlen(_T("Text")));
+ return szText.cy;
+ }
+
+ inline int CTab::GetTabIndex(CWnd* pWnd) const
+ {
+ assert(pWnd);
+
+ for (int i = 0; i < (int)m_vTabPageInfo.size(); ++i)
+ {
+ if (m_vTabPageInfo[i].pView == pWnd)
+ return i;
+ }
+
+ return -1;
+ }
+
+ inline TabPageInfo CTab::GetTabPageInfo(UINT nTab) const
+ {
+ assert (nTab < m_vTabPageInfo.size());
+
+ return m_vTabPageInfo[nTab];
+ }
+
+ inline void CTab::NotifyChanged()
+ {
+ NMHDR nmhdr = {0};
+ nmhdr.hwndFrom = m_hWnd;
+ nmhdr.code = UWM_TAB_CHANGED;
+ GetParent()->SendMessage(WM_NOTIFY, 0L, (LPARAM)&nmhdr);
+ }
+
+ inline void CTab::OnCreate()
+ {
+ SetFont(&m_Font, TRUE);
+
+ // Assign ImageList unless we are owner drawn
+ if (!(GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED))
+ TabCtrl_SetImageList(m_hWnd, m_himlTab);
+
+ for (int i = 0; i < (int)m_vTabPageInfo.size(); ++i)
+ {
+ // Add tabs for each view.
+ TCITEM tie = {0};
+ tie.mask = TCIF_TEXT | TCIF_IMAGE;
+ tie.iImage = m_vTabPageInfo[i].iImage;
+ tie.pszText = m_vTabPageInfo[i].szTabText;
+ TabCtrl_InsertItem(m_hWnd, i, &tie);
+ }
+
+ int HeightGap = 5;
+ SetTabHeight(MAX(20, (GetTextHeight() + HeightGap)));
+ SelectPage(0);
+ }
+
+ inline void CTab::OnLButtonDown(WPARAM /*wParam*/, LPARAM lParam)
+ {
+ CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+
+ if (GetCloseRect().PtInRect(pt))
+ {
+ m_IsClosePressed = TRUE;
+ SetCapture();
+ CClientDC dc(this);
+ DrawCloseButton(dc);
+ }
+ else
+ m_IsClosePressed = FALSE;
+
+ if (GetListRect().PtInRect(pt))
+ {
+ ShowListMenu();
+ }
+ }
+
+ inline void CTab::OnLButtonUp(WPARAM /*wParam*/, LPARAM lParam)
+ {
+ ReleaseCapture();
+ CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ if (m_IsClosePressed && GetCloseRect().PtInRect(pt))
+ {
+ RemoveTabPage(GetCurSel());
+ if (GetActiveView())
+ GetActiveView()->RedrawWindow();
+ }
+
+ m_IsClosePressed = FALSE;
+ }
+
+ inline void CTab::OnMouseLeave(WPARAM /*wParam*/, LPARAM /*lParam*/)
+ {
+ CClientDC dc(this);
+ DrawCloseButton(dc);
+ DrawListButton(dc);
+
+ m_IsTracking = FALSE;
+ }
+
+ inline void CTab::OnMouseMove(WPARAM /*wParam*/, LPARAM /*lParam*/)
+ {
+ if (!m_IsListMenuActive && m_IsListPressed)
+ {
+ m_IsListPressed = FALSE;
+ }
+
+ if (!m_IsTracking)
+ {
+ TRACKMOUSEEVENT TrackMouseEventStruct = {0};
+ TrackMouseEventStruct.cbSize = sizeof(TrackMouseEventStruct);
+ TrackMouseEventStruct.dwFlags = TME_LEAVE;
+ TrackMouseEventStruct.hwndTrack = m_hWnd;
+ _TrackMouseEvent(&TrackMouseEventStruct);
+ m_IsTracking = TRUE;
+ }
+
+ CClientDC dc(this);
+ DrawCloseButton(dc);
+ DrawListButton(dc);
+ }
+
+ inline LRESULT CTab::OnNCHitTest(WPARAM wParam, LPARAM lParam)
+ {
+ // Ensure we have an arrow cursor when the tab has no view window
+ if (0 == GetAllTabs().size())
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ // Cause WM_LBUTTONUP and WM_LBUTTONDOWN messages to be sent for buttons
+ CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ ScreenToClient(pt);
+ if (GetCloseRect().PtInRect(pt)) return HTCLIENT;
+ if (GetListRect().PtInRect(pt)) return HTCLIENT;
+
+ return CWnd::WndProcDefault(WM_NCHITTEST, wParam, lParam);
+ }
+
+ inline LRESULT CTab::OnNotifyReflect(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGE:
+ {
+ // Display the newly selected tab page
+ int nPage = GetCurSel();
+ ShowActiveView(m_vTabPageInfo[nPage].pView);
+ }
+ break;
+ }
+
+ return 0L;
+ }
+
+ inline void CTab::Paint()
+ {
+ // Microsoft's drawing for a tab control is rubbish, so we do our own.
+ // We use double buffering and regions to eliminate flicker
+
+ // Create the memory DC and bitmap
+ CClientDC dcView(this);
+ CMemDC dcMem(&dcView);
+ CRect rcClient = GetClientRect();
+ dcMem.CreateCompatibleBitmap(&dcView, rcClient.Width(), rcClient.Height());
+
+ if (0 == GetItemCount())
+ {
+ // No tabs, so simply display a grey background and exit
+ COLORREF rgbDialog = GetSysColor(COLOR_BTNFACE);
+ dcView.SolidFill(rgbDialog, rcClient);
+ return;
+ }
+
+ // Create a clipping region. Its the overall tab window's region,
+ // less the region belonging to the individual tab view's client area
+ CRgn rgnSrc1 = ::CreateRectRgn(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+ CRect rcTab = GetClientRect();
+ TabCtrl_AdjustRect(m_hWnd, FALSE, &rcTab);
+ if (rcTab.Height() < 0)
+ rcTab.top = rcTab.bottom;
+ if (rcTab.Width() < 0)
+ rcTab.left = rcTab.right;
+
+ CRgn rgnSrc2 = ::CreateRectRgn(rcTab.left, rcTab.top, rcTab.right, rcTab.bottom);
+ CRgn rgnClip = ::CreateRectRgn(0, 0, 0, 0);
+ ::CombineRgn(rgnClip, rgnSrc1, rgnSrc2, RGN_DIFF);
+
+ // Use the region in the memory DC to paint the grey background
+ dcMem.SelectClipRgn(&rgnClip);
+ HWND hWndParent = ::GetParent(m_hWnd);
+ CDC dcParent = ::GetDC(hWndParent);
+ HBRUSH hBrush = (HBRUSH) SendMessage(hWndParent, WM_CTLCOLORDLG, (WPARAM)dcParent.GetHDC(), (LPARAM)hWndParent);
+ dcMem.SelectObject(FromHandle(hBrush));
+ dcMem.PaintRgn(&rgnClip);
+
+ // Draw the tab buttons on the memory DC:
+ DrawTabs(dcMem);
+
+ // Draw buttons and tab borders
+ DrawCloseButton(dcMem);
+ DrawListButton(dcMem);
+ DrawTabBorders(dcMem, rcTab);
+
+ // Now copy our from our memory DC to the window DC
+ dcView.SelectClipRgn(&rgnClip);
+ dcView.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);
+ }
+
+ inline void CTab::PreCreate(CREATESTRUCT &cs)
+ {
+ // For Tabs on the bottom, add the TCS_BOTTOM style
+ cs.style = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
+ }
+
+ inline void CTab::PreRegisterClass(WNDCLASS &wc)
+ {
+ wc.lpszClassName = WC_TABCONTROL;
+ }
+
+ inline void CTab::RecalcLayout()
+ {
+ if (IsWindow())
+ {
+ if (GetActiveView())
+ {
+ // Set the tab sizes
+ SetTabSize();
+
+ // Position the View over the tab control's display area
+ CRect rc = GetClientRect();
+ TabCtrl_AdjustRect(m_hWnd, FALSE, &rc);
+ GetActiveView()->SetWindowPos(NULL, rc, SWP_SHOWWINDOW);
+ }
+ else
+ RedrawWindow();
+ }
+ }
+
+ inline void CTab::RemoveTabPage(int nPage)
+ {
+ if ((nPage < 0) || (nPage > (int)m_vTabPageInfo.size() -1))
+ return;
+
+ // Remove the tab
+ TabCtrl_DeleteItem(m_hWnd, nPage);
+
+ // Remove the TapPageInfo entry
+ std::vector<TabPageInfo>::iterator itTPI = m_vTabPageInfo.begin() + nPage;
+ CWnd* pView = (*itTPI).pView;
+ int iImage = (*itTPI).iImage;
+ if (iImage >= 0)
+ TabCtrl_RemoveImage(m_hWnd, iImage);
+
+ if (pView == m_pActiveView)
+ m_pActiveView = 0;
+
+ (*itTPI).pView->Destroy();
+ m_vTabPageInfo.erase(itTPI);
+
+ std::vector<WndPtr>::iterator itView;
+ for (itView = m_vTabViews.begin(); itView < m_vTabViews.end(); ++itView)
+ {
+ if ((*itView).get() == pView)
+ {
+ m_vTabViews.erase(itView);
+ break;
+ }
+ }
+
+ if (IsWindow())
+ {
+ if (m_vTabPageInfo.size() > 0)
+ {
+ SetTabSize();
+ SelectPage(0);
+ }
+ else
+ ShowActiveView(NULL);
+
+ NotifyChanged();
+ }
+ }
+
+ inline void CTab::SelectPage(int nPage)
+ {
+ if ((nPage >= 0) && (nPage < GetItemCount()))
+ {
+ if (nPage != GetCurSel())
+ SetCurSel(nPage);
+
+ ShowActiveView(m_vTabPageInfo[nPage].pView);
+ }
+ }
+
+ inline void CTab::SetFixedWidth(BOOL bEnabled)
+ {
+ DWORD dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
+ if (bEnabled)
+ SetWindowLongPtr(GWL_STYLE, dwStyle | TCS_FIXEDWIDTH);
+ else
+ SetWindowLongPtr(GWL_STYLE, dwStyle & ~TCS_FIXEDWIDTH);
+
+ RecalcLayout();
+ }
+
+ inline void CTab::SetOwnerDraw(BOOL bEnabled)
+ // Enable or disable owner draw
+ {
+ DWORD dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
+ if (bEnabled)
+ {
+ SetWindowLongPtr(GWL_STYLE, dwStyle | TCS_OWNERDRAWFIXED);
+ TabCtrl_SetImageList(m_hWnd, NULL);
+ }
+ else
+ {
+ SetWindowLongPtr(GWL_STYLE, dwStyle & ~TCS_OWNERDRAWFIXED);
+ TabCtrl_SetImageList(m_hWnd, m_himlTab);
+ }
+
+ RecalcLayout();
+ }
+
+ inline void CTab::SetShowButtons(BOOL bShow)
+ {
+ m_bShowButtons = bShow;
+ RecalcLayout();
+ }
+
+ inline void CTab::SetTabIcon(int i, HICON hIcon)
+ // Changes or sets the tab's icon
+ {
+ assert (GetItemCount() > i);
+ TCITEM tci = {0};
+ tci.mask = TCIF_IMAGE;
+ GetItem(i, &tci);
+ if (tci.iImage >= 0)
+ {
+ ImageList_ReplaceIcon(GetImageList(), i, hIcon);
+ }
+ else
+ {
+ int iImage = ImageList_AddIcon(GetImageList(), hIcon);
+ tci.iImage = iImage;
+ TabCtrl_SetItem(m_hWnd, i, &tci);
+ m_vTabPageInfo[i].iImage = iImage;
+ }
+ }
+
+ inline void CTab::SetTabsAtTop(BOOL bTop)
+ // Positions the tabs at the top or botttom of the control
+ {
+ DWORD dwStyle = (DWORD)GetWindowLongPtr(GWL_STYLE);
+
+ if (bTop)
+ dwStyle &= ~TCS_BOTTOM;
+ else
+ dwStyle |= TCS_BOTTOM;
+
+ SetWindowLongPtr(GWL_STYLE, dwStyle);
+ RecalcLayout();
+ }
+
+ inline void CTab::SetTabSize()
+ {
+ if (GetItemCount() > 0)
+ {
+ CRect rc = GetClientRect();
+ TabCtrl_AdjustRect(m_hWnd, FALSE, &rc);
+
+ int xGap = 2;
+ if (m_bShowButtons) xGap += GetCloseRect().Width() + GetListRect().Width() +2;
+
+ int nItemWidth = MIN( GetMaxTabSize().cx, (rc.Width() - xGap)/GetItemCount() );
+ nItemWidth = MAX(nItemWidth, 0);
+ SendMessage(TCM_SETITEMSIZE, 0L, MAKELPARAM(nItemWidth, m_nTabHeight));
+ NotifyChanged();
+ }
+ }
+
+ inline void CTab::SetTabText(UINT nTab, LPCTSTR szText)
+ {
+ // Allows the text to be changed on an existing tab
+ if (nTab < GetAllTabs().size())
+ {
+ TCITEM Item = {0};
+ std::vector<TCHAR> vTChar(MAX_MENU_STRING+1, _T('\0'));
+ TCHAR* pTChar = &vTChar.front();
+ lstrcpyn(pTChar, szText, MAX_MENU_STRING);
+ Item.mask = TCIF_TEXT;
+ Item.pszText = pTChar;
+
+ if (TabCtrl_SetItem(m_hWnd, nTab, &Item))
+ lstrcpyn(m_vTabPageInfo[nTab].szTabText, pTChar, MAX_MENU_STRING);
+ }
+ }
+
+ inline void CTab::ShowActiveView(CWnd* pView)
+ // Sets or changes the View window displayed within the tab page
+ {
+ // Hide the old view
+ if (GetActiveView() && (GetActiveView()->IsWindow()))
+ GetActiveView()->ShowWindow(SW_HIDE);
+
+ // Assign the view window
+ m_pActiveView = pView;
+
+ if (m_pActiveView && m_hWnd)
+ {
+ if (!m_pActiveView->IsWindow())
+ {
+ // The tab control is already created, so create the new view too
+ GetActiveView()->Create(this);
+ }
+
+ // Position the View over the tab control's display area
+ CRect rc = GetClientRect();
+ TabCtrl_AdjustRect(m_hWnd, FALSE, &rc);
+ GetActiveView()->SetWindowPos(HWND_TOP, rc, SWP_SHOWWINDOW);
+ GetActiveView()->SetFocus();
+ }
+ }
+
+ inline void CTab::ShowListMenu()
+ // Displays the list of windows in a popup menu
+ {
+ if (!m_IsListPressed)
+ {
+ m_IsListPressed = TRUE;
+ HMENU hMenu = GetListMenu();
+
+ CPoint pt(GetListRect().left, GetListRect().top + GetTabHeight());
+ ClientToScreen(pt);
+
+ // Choosing the frame's hwnd for the menu's messages will automatically theme the popup menu
+ HWND MenuHwnd = GetAncestor()->GetHwnd();
+ int nPage = 0;
+ m_IsListMenuActive = TRUE;
+ nPage = TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, pt.x, pt.y, MenuHwnd, NULL) - IDW_FIRSTCHILD;
+ if ((nPage >= 0) && (nPage < 9)) SelectPage(nPage);
+ if (nPage == 9) ShowListDialog();
+ m_IsListMenuActive = FALSE;
+ }
+
+ CClientDC dc(this);
+ DrawListButton(dc);
+ }
+
+ inline void CTab::ShowListDialog()
+ {
+ // Definition of a dialog template which displays a List Box
+ unsigned char dlg_Template[] =
+ {
+ 0x01,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xc8,0x00,0xc8,0x90,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0xdc,0x00,0x8e,0x00,0x00,0x00,0x00,0x00,0x53,0x00,0x65,
+ 0x00,0x6c,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x20,0x00,0x57,0x00,0x69,0x00,0x6e,
+ 0x00,0x64,0x00,0x6f,0x00,0x77,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x4d,
+ 0x00,0x53,0x00,0x20,0x00,0x53,0x00,0x68,0x00,0x65,0x00,0x6c,0x00,0x6c,0x00,0x20,
+ 0x00,0x44,0x00,0x6c,0x00,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x01,0x50,0x40,0x00,0x7a,0x00,0x25,0x00,0x0f,0x00,0x01,
+ 0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x4f,0x00,0x4b,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x50,0x7a,0x00,0x7a,0x00,0x25,
+ 0x00,0x0f,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x43,0x00,0x61,0x00,0x6e,
+ 0x00,0x63,0x00,0x65,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x02,0x00,0x01,0x01,0x21,0x50,0x06,0x00,0x06,0x00,0xcf,0x00,0x6d,0x00,0x79,
+ 0x00,0x00,0x00,0xff,0xff,0x83,0x00,0x00,0x00,0x00,0x00
+ };
+
+ // Display the modal dialog. The dialog is defined in the dialog template rather
+ // than in the resource script (rc) file.
+ CSelectDialog MyDialog((LPCDLGTEMPLATE) dlg_Template);
+ for(UINT u = 0; u < GetAllTabs().size(); ++u)
+ {
+ MyDialog.AddItem(GetAllTabs()[u].szTabText);
+ }
+
+ int iSelected = (int)MyDialog.DoModal();
+ if (iSelected >= 0) SelectPage(iSelected);
+ }
+
+ inline void CTab::SwapTabs(UINT nTab1, UINT nTab2)
+ {
+ if ((nTab1 < GetAllTabs().size()) && (nTab2 < GetAllTabs().size()) && (nTab1 != nTab2))
+ {
+ int nPage = GetCurSel();
+ TabPageInfo T1 = GetTabPageInfo(nTab1);
+ TabPageInfo T2 = GetTabPageInfo(nTab2);
+
+ TCITEM Item1 = {0};
+ Item1.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_RTLREADING | TCIF_STATE | TCIF_TEXT;
+ GetItem(nTab1, &Item1);
+ TCITEM Item2 = {0};
+ Item2.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_RTLREADING | TCIF_STATE | TCIF_TEXT;
+ GetItem(nTab2, &Item2);
+ TabCtrl_SetItem(m_hWnd, nTab1, &Item2);
+ TabCtrl_SetItem(m_hWnd, nTab2, &Item1);
+
+ m_vTabPageInfo[nTab1] = T2;
+ m_vTabPageInfo[nTab2] = T1;
+ SelectPage(nPage);
+ }
+ }
+
+ inline LRESULT CTab::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch(uMsg)
+ {
+ case WM_PAINT:
+ if (GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED)
+ {
+ // Remove all pending paint requests
+ PAINTSTRUCT ps;
+ BeginPaint(ps);
+ EndPaint(ps);
+
+ // Now call our local Paint
+ Paint();
+ return 0;
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ if (GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED)
+ return 0;
+ break;
+ case WM_KILLFOCUS:
+ m_IsClosePressed = FALSE;
+ break;
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ OnLButtonDown(wParam, lParam);
+ break;
+ case WM_LBUTTONUP:
+ OnLButtonUp(wParam, lParam);
+ break;
+ case WM_MOUSEMOVE:
+ OnMouseMove(wParam, lParam);
+ break;
+ case WM_MOUSELEAVE:
+ OnMouseLeave(wParam, lParam);
+ break;
+ case WM_NCHITTEST:
+ return OnNCHitTest(wParam, lParam);
+
+ case WM_WINDOWPOSCHANGING:
+ // A little hack to reduce tab flicker
+ if (IsWindowVisible() && (GetWindowLongPtr(GWL_STYLE) & TCS_OWNERDRAWFIXED))
+ {
+ LPWINDOWPOS pWinPos = (LPWINDOWPOS)lParam;
+ pWinPos->flags |= SWP_NOREDRAW;
+
+ Paint();
+ }
+
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ RecalcLayout();
+ break;
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+ // Wrappers for Win32 Macros
+ inline void CTab::AdjustRect(BOOL fLarger, RECT *prc) const
+ {
+ assert(::IsWindow(m_hWnd));
+ TabCtrl_AdjustRect(m_hWnd, fLarger, prc);
+ }
+
+ inline int CTab::GetCurFocus() const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_GetCurFocus(m_hWnd);
+ }
+
+ inline int CTab::GetCurSel() const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_GetCurSel(m_hWnd);
+ }
+
+ inline BOOL CTab::GetItem(int iItem, LPTCITEM pitem) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_GetItem(m_hWnd, iItem, pitem);
+ }
+
+ inline int CTab::GetItemCount() const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_GetItemCount(m_hWnd);
+ }
+
+ inline int CTab::HitTest(TCHITTESTINFO& info) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_HitTest(m_hWnd, &info);
+ }
+
+ inline void CTab::SetCurFocus(int iItem) const
+ {
+ assert(::IsWindow(m_hWnd));
+ TabCtrl_SetCurFocus(m_hWnd, iItem);
+ }
+
+ inline int CTab::SetCurSel(int iItem) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_SetCurSel(m_hWnd, iItem);
+ }
+
+ inline DWORD CTab::SetItemSize(int cx, int cy) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_SetItemSize(m_hWnd, cx, cy);
+ }
+
+ inline int CTab::SetMinTabWidth(int cx) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return TabCtrl_SetMinTabWidth(m_hWnd, cx);
+ }
+
+ inline void CTab::SetPadding(int cx, int cy) const
+ {
+ assert(::IsWindow(m_hWnd));
+ TabCtrl_SetPadding(m_hWnd, cx, cy);
+ }
+
+ ////////////////////////////////////////
+ // Definitions for the CTabbedMDI class
+ inline CTabbedMDI::CTabbedMDI()
+ {
+ GetTab().SetShowButtons(TRUE);
+ }
+
+ inline CTabbedMDI::~CTabbedMDI()
+ {
+ }
+
+ inline CWnd* CTabbedMDI::AddMDIChild(CWnd* pView, LPCTSTR szTabText, int idMDIChild /*= 0*/)
+ {
+ assert(pView);
+ assert(lstrlen(szTabText) < MAX_MENU_STRING);
+
+ GetTab().AddTabPage(WndPtr(pView), szTabText, 0, idMDIChild);
+
+ // Fake a WM_MOUSEACTIVATE to propogate focus change to dockers
+ if (IsWindow())
+ GetParent()->SendMessage(WM_MOUSEACTIVATE, (WPARAM)GetAncestor(), MAKELPARAM(HTCLIENT,WM_LBUTTONDOWN));
+
+ return pView;
+ }
+
+ inline void CTabbedMDI::CloseActiveMDI()
+ {
+ int nTab = GetTab().GetCurSel();
+ if (nTab >= 0)
+ GetTab().RemoveTabPage(nTab);
+
+ RecalcLayout();
+ }
+
+ inline void CTabbedMDI::CloseAllMDIChildren()
+ {
+ while (GetMDIChildCount() > 0)
+ {
+ GetTab().RemoveTabPage(0);
+ }
+ }
+
+ inline void CTabbedMDI::CloseMDIChild(int nTab)
+ {
+ GetTab().RemoveTabPage(nTab);
+
+ if (GetActiveMDIChild())
+ GetActiveMDIChild()->RedrawWindow();
+ }
+
+ inline HWND CTabbedMDI::Create(CWnd* pParent /* = NULL*/)
+ {
+ CLIENTCREATESTRUCT clientcreate ;
+ clientcreate.hWindowMenu = m_hWnd;
+ clientcreate.idFirstChild = IDW_FIRSTCHILD ;
+ DWORD dwStyle = WS_CHILD | WS_VISIBLE | MDIS_ALLCHILDSTYLES;
+
+ // Create the MDICLIENT view window
+ if (!CreateEx(0, _T("MDICLIENT"), _T(""),
+ dwStyle, 0, 0, 0, 0, pParent, NULL, (PSTR) &clientcreate))
+ throw CWinException(_T("CMDIClient::Create ... CreateEx failed"));
+
+ return m_hWnd;
+ }
+
+ inline CWnd* CTabbedMDI::GetActiveMDIChild() const
+ {
+ CWnd* pView = NULL;
+ int nTab = GetTab().GetCurSel();
+ if (nTab >= 0)
+ {
+ TabPageInfo tbi = GetTab().GetTabPageInfo(nTab);
+ pView = tbi.pView;
+ }
+
+ return pView;
+ }
+
+ inline int CTabbedMDI::GetActiveMDITab() const
+ {
+ return GetTab().GetCurSel();
+ }
+
+ inline CWnd* CTabbedMDI::GetMDIChild(int nTab) const
+ {
+ assert(nTab >= 0);
+ assert(nTab < GetMDIChildCount());
+ return GetTab().GetTabPageInfo(nTab).pView;
+ }
+
+ inline int CTabbedMDI::GetMDIChildCount() const
+ {
+ return (int) GetTab().GetAllTabs().size();
+ }
+
+ inline int CTabbedMDI::GetMDIChildID(int nTab) const
+ {
+ assert(nTab >= 0);
+ assert(nTab < GetMDIChildCount());
+ return GetTab().GetTabPageInfo(nTab).idTab;
+ }
+
+ inline LPCTSTR CTabbedMDI::GetMDIChildTitle(int nTab) const
+ {
+ assert(nTab >= 0);
+ assert(nTab < GetMDIChildCount());
+ return GetTab().GetTabPageInfo(nTab).szTabText;
+ }
+
+ inline BOOL CTabbedMDI::LoadRegistrySettings(tString tsRegistryKeyName)
+ {
+ BOOL bResult = FALSE;
+
+ if (0 != tsRegistryKeyName.size())
+ {
+ tString tsKey = _T("Software\\") + tsRegistryKeyName + _T("\\MDI Children");
+ HKEY hKey = 0;
+ RegOpenKeyEx(HKEY_CURRENT_USER, tsKey.c_str(), 0, KEY_READ, &hKey);
+ if (hKey)
+ {
+ DWORD dwType = REG_BINARY;
+ DWORD BufferSize = sizeof(TabPageInfo);
+ TabPageInfo tbi = {0};
+ int i = 0;
+ TCHAR szNumber[16];
+ tString tsSubKey = _T("MDI Child ");
+ tsSubKey += _itot(i, szNumber, 10);
+
+ // Fill the DockList vector from the registry
+ while (0 == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&tbi, &BufferSize))
+ {
+ CWnd* pWnd = NewMDIChildFromID(tbi.idTab);
+ if (pWnd)
+ {
+ AddMDIChild(pWnd, tbi.szTabText, tbi.idTab);
+ i++;
+ tsSubKey = _T("MDI Child ");
+ tsSubKey += _itot(i, szNumber, 10);
+ bResult = TRUE;
+ }
+ else
+ {
+ TRACE(_T("Failed to get TabbedMDI info from registry"));
+ bResult = FALSE;
+ break;
+ }
+ }
+
+ // Load Active MDI Tab from the registry
+ tsSubKey = _T("Active MDI Tab");
+ int nTab;
+ dwType = REG_DWORD;
+ BufferSize = sizeof(int);
+ if(ERROR_SUCCESS == RegQueryValueEx(hKey, tsSubKey.c_str(), NULL, &dwType, (LPBYTE)&nTab, &BufferSize))
+ SetActiveMDITab(nTab);
+ else
+ SetActiveMDITab(0);
+
+ RegCloseKey(hKey);
+ }
+ }
+
+ if (!bResult)
+ CloseAllMDIChildren();
+
+ return bResult;
+ }
+
+ inline CWnd* CTabbedMDI::NewMDIChildFromID(int /*idMDIChild*/)
+ {
+ // Override this function to create new MDI children from IDs as shown below
+ CWnd* pView = NULL;
+ /* switch(idTab)
+ {
+ case ID_SIMPLE:
+ pView = new CViewSimple;
+ break;
+ case ID_RECT:
+ pView = new CViewRect;
+ break;
+ default:
+ TRACE(_T("Unknown MDI child ID\n"));
+ break;
+ } */
+
+ return pView;
+ }
+
+ inline void CTabbedMDI::OnCreate()
+ {
+ GetTab().Create(this);
+ GetTab().SetFixedWidth(TRUE);
+ GetTab().SetOwnerDraw(TRUE);
+ }
+
+ inline void CTabbedMDI::OnDestroy(WPARAM /*wParam*/, LPARAM /*lParam*/ )
+ {
+ CloseAllMDIChildren();
+ }
+
+ inline LRESULT CTabbedMDI::OnNotify(WPARAM /*wParam*/, LPARAM lParam)
+ {
+ LPNMHDR pnmhdr = (LPNMHDR)lParam;
+ if (pnmhdr->code == UWM_TAB_CHANGED)
+ RecalcLayout();
+
+ return 0L;
+ }
+
+ inline void CTabbedMDI::OnWindowPosChanged(WPARAM /*wParam*/, LPARAM /*lParam*/)
+ {
+ RecalcLayout();
+ }
+
+ inline void CTabbedMDI::RecalcLayout()
+ {
+ if (GetTab().IsWindow())
+ {
+ if (GetTab().GetItemCount() >0)
+ {
+ CRect rcClient = GetClientRect();
+ GetTab().SetWindowPos(NULL, rcClient, SWP_SHOWWINDOW);
+ GetTab().UpdateWindow();
+ }
+ else
+ {
+ CRect rcClient = GetClientRect();
+ GetTab().SetWindowPos(NULL, rcClient, SWP_HIDEWINDOW);
+ Invalidate();
+ }
+ }
+ }
+
+ inline BOOL CTabbedMDI::SaveRegistrySettings(tString tsRegistryKeyName)
+ {
+ if (0 != tsRegistryKeyName.size())
+ {
+ tString tsKeyName = _T("Software\\") + tsRegistryKeyName;
+ HKEY hKey = NULL;
+ HKEY hKeyMDIChild = NULL;
+
+ try
+ {
+ if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, tsKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
+ throw (CWinException(_T("RegCreateKeyEx Failed")));
+
+ RegDeleteKey(hKey, _T("MDI Children"));
+ if (ERROR_SUCCESS != RegCreateKeyEx(hKey, _T("MDI Children"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyMDIChild, NULL))
+ throw (CWinException(_T("RegCreateKeyEx Failed")));
+
+ for (int i = 0; i < GetMDIChildCount(); ++i)
+ {
+ TCHAR szNumber[16];
+ tString tsSubKey = _T("MDI Child ");
+ tsSubKey += _itot(i, szNumber, 10);
+ TabPageInfo pdi = GetTab().GetTabPageInfo(i);
+ if (ERROR_SUCCESS != RegSetValueEx(hKeyMDIChild, tsSubKey.c_str(), 0, REG_BINARY, (LPBYTE)&pdi, sizeof(TabPageInfo)))
+ throw (CWinException(_T("RegSetValueEx Failed")));
+ }
+
+ // Add Active Tab to the registry
+ tString tsSubKey = _T("Active MDI Tab");
+ int nTab = GetActiveMDITab();
+ if(ERROR_SUCCESS != RegSetValueEx(hKeyMDIChild, tsSubKey.c_str(), 0, REG_DWORD, (LPBYTE)&nTab, sizeof(int)))
+ throw (CWinException(_T("RegSetValueEx failed")));
+
+ RegCloseKey(hKeyMDIChild);
+ RegCloseKey(hKey);
+ }
+ catch (const CWinException& e)
+ {
+ // Roll back the registry changes by deleting the subkeys
+ if (hKey)
+ {
+ if (hKeyMDIChild)
+ {
+ RegDeleteKey(hKeyMDIChild, _T("MDI Children"));
+ RegCloseKey(hKeyMDIChild);
+ }
+
+ RegDeleteKey(HKEY_CURRENT_USER ,tsKeyName.c_str());
+ RegCloseKey(hKey);
+ }
+
+ e.what();
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ inline void CTabbedMDI::SetActiveMDIChild(CWnd* pWnd)
+ {
+ assert(pWnd);
+ int nPage = GetTab().GetTabIndex(pWnd);
+ if (nPage >= 0)
+ GetTab().SelectPage(nPage);
+ }
+
+ inline void CTabbedMDI::SetActiveMDITab(int iTab)
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(GetTab().IsWindow());
+ GetTab().SelectPage(iTab);
+ }
+
+ inline LRESULT CTabbedMDI::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch(uMsg)
+ {
+ case WM_DESTROY:
+ OnDestroy(wParam, lParam);
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ OnWindowPosChanged(wParam, lParam);
+ break;
+ }
+
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_TAB_H_
diff --git a/mmc_updater/depends/win32cpp/taskdialog.h b/mmc_updater/depends/win32cpp/taskdialog.h
new file mode 100644
index 00000000..2285d1e1
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/taskdialog.h
@@ -0,0 +1,811 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////
+// taskdialog.h
+// Declaration of the CTaskDialog class
+
+// A task dialog is a dialog box that can be used to display information
+// and receive simple input from the user. Like a message box, it is
+// formatted by the operating system according to parameters you set.
+// However, a task dialog has many more features than a message box.
+
+// NOTES:
+// Task Dialogs are only supported on Windows Vista and above.
+// Task Dialogs require XP themes enabled (use version 6 of Common Controls)
+// Task Dialogs are always modal.
+
+
+#ifndef _WIN32XX_TASKDIALOG_H_
+#define _WIN32XX_TASKDIALOG_H_
+
+#include "wincore.h"
+
+namespace Win32xx
+{
+
+ class CTaskDialog : public CWnd
+ {
+ public:
+ CTaskDialog();
+ virtual ~CTaskDialog() {}
+
+ void AddCommandControl(int nButtonID, LPCTSTR pszCaption);
+ void AddRadioButton(int nRadioButtonID, LPCTSTR pszCaption);
+ void AddRadioButtonGroup(int nIDRadioButtonsFirst, int nIDRadioButtonsLast);
+ void ClickButton(int nButtonID) const;
+ void ClickRadioButton(int nRadioButtonID) const;
+ LRESULT DoModal(CWnd* pParent = NULL);
+ void ElevateButton(int nButtonID, BOOL bElevated);
+ void EnableButton(int nButtonID, BOOL bEnabled);
+ void EnableRadioButton(int nButtonID, BOOL bEnabled);
+ TASKDIALOGCONFIG GetConfig() const;
+ TASKDIALOG_FLAGS GetOptions() const;
+ int GetSelectedButtonID() const;
+ int GetSelectedRadioButtonID() const;
+ BOOL GetVerificationCheckboxState() const;
+ static BOOL IsSupported();
+ void NavigateTo(CTaskDialog& TaskDialog) const;
+ void RemoveAllButtons();
+ void RemoveAllRadioButtons();
+ void Reset();
+ void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons);
+ void SetContent(LPCTSTR pszContent);
+ void SetDefaultButton(int nButtonID);
+ void SetDefaultRadioButton(int nRadioButtonID);
+ void SetDialogWidth(UINT nWidth = 0);
+ void SetExpansionArea(LPCTSTR pszExpandedInfo, LPCTSTR pszExpandedLabel = _T(""), LPCTSTR pszCollapsedLabel = _T(""));
+ void SetFooterIcon(HICON hFooterIcon);
+ void SetFooterIcon(LPCTSTR lpszFooterIcon);
+ void SetFooterText(LPCTSTR pszFooter);
+ void SetMainIcon(HICON hMainIcon);
+ void SetMainIcon(LPCTSTR lpszMainIcon);
+ void SetMainInstruction(LPCTSTR pszMainInstruction);
+ void SetOptions(TASKDIALOG_FLAGS dwFlags);
+ void SetProgressBarMarquee(BOOL bEnabled = TRUE, int nMarqueeSpeed = 0);
+ void SetProgressBarPosition(int nProgressPos);
+ void SetProgressBarRange(int nMinRange, int nMaxRange);
+ void SetProgressBarState(int nNewState = PBST_NORMAL);
+ void SetVerificationCheckbox(BOOL bChecked);
+ void SetVerificationCheckboxText(LPCTSTR pszVerificationText);
+ void SetWindowTitle(LPCTSTR pszWindowTitle);
+ static HRESULT CALLBACK StaticTaskDialogProc(HWND hWnd, UINT uNotification, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData);
+ void StoreText(std::vector<WCHAR>& vWChar, LPCTSTR pFromTChar);
+ void UpdateElementText(TASKDIALOG_ELEMENTS eElement, LPCTSTR pszNewText);
+
+
+ protected:
+ // Override these functions as required
+ virtual BOOL OnTDButtonClicked(int nButtonID);
+ virtual void OnTDConstructed();
+ virtual void OnTDCreated();
+ virtual void OnTDDestroyed();
+ virtual void OnTDExpandButtonClicked(BOOL bExpanded);
+ virtual void OnTDHelp();
+ virtual void OnTDHyperlinkClicked(LPCTSTR pszHref);
+ virtual void OnTDNavigatePage();
+ virtual BOOL OnTDRadioButtonClicked(int nRadioButtonID);
+ virtual BOOL OnTDTimer(DWORD dwTickCount);
+ virtual void OnTDVerificationCheckboxClicked(BOOL bChecked);
+ virtual LRESULT TaskDialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual LRESULT TaskDialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CTaskDialog(const CTaskDialog&); // Disable copy construction
+ CTaskDialog& operator = (const CTaskDialog&); // Disable assignment operator
+
+ std::vector<TASKDIALOG_BUTTON> m_vButtons;
+ std::vector<TASKDIALOG_BUTTON> m_vRadioButtons;
+
+ std::vector< std::vector<WCHAR> > m_vButtonsText; // A vector of WCHAR vectors
+ std::vector< std::vector<WCHAR> > m_vRadioButtonsText; // A vector of WCHAR vectors
+
+ std::vector<WCHAR> m_vWindowTitle;
+ std::vector<WCHAR> m_vMainInstruction;
+ std::vector<WCHAR> m_vContent;
+ std::vector<WCHAR> m_vVerificationText;
+ std::vector<WCHAR> m_vExpandedInformation;
+ std::vector<WCHAR> m_vExpandedControlText;
+ std::vector<WCHAR> m_vCollapsedControlText;
+ std::vector<WCHAR> m_vFooter;
+
+ TASKDIALOGCONFIG m_tc;
+ int m_SelectedButtonID;
+ int m_SelectedRadioButtonID;
+ BOOL m_VerificationCheckboxState;
+ };
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ inline CTaskDialog::CTaskDialog() : m_SelectedButtonID(0), m_SelectedRadioButtonID(0), m_VerificationCheckboxState(FALSE)
+ {
+ ZeroMemory(&m_tc, sizeof(m_tc));
+ m_tc.cbSize = sizeof(m_tc);
+ m_tc.pfCallback = CTaskDialog::StaticTaskDialogProc;
+ }
+
+ inline void CTaskDialog::AddCommandControl(int nButtonID, LPCTSTR pszCaption)
+ // Adds a command control or push button to the Task Dialog.
+ {
+ assert (m_hWnd == NULL);
+
+ std::vector<WCHAR> vButtonText;
+ StoreText(vButtonText, pszCaption);
+ m_vButtonsText.push_back(vButtonText); // m_vButtonsText is a vector of vector<WCHAR>'s
+
+ TASKDIALOG_BUTTON tdb;
+ tdb.nButtonID = nButtonID;
+ tdb.pszButtonText = &m_vButtonsText.back().front();
+
+ m_vButtons.push_back(tdb);
+ }
+
+ inline void CTaskDialog::AddRadioButton(int nRadioButtonID, LPCTSTR pszCaption)
+ // Adds a radio button to the Task Dialog.
+ {
+ assert (m_hWnd == NULL);
+
+ std::vector<WCHAR> vRadioButtonText;
+ StoreText(vRadioButtonText, pszCaption);
+ m_vRadioButtonsText.push_back(vRadioButtonText); // m_vRadioButtonsText is a vector of vector<WCHAR>'s
+
+ TASKDIALOG_BUTTON tdb;
+ tdb.nButtonID = nRadioButtonID;
+ tdb.pszButtonText = &m_vRadioButtonsText.back().front();
+
+ m_vRadioButtons.push_back(tdb);
+ }
+
+ inline void CTaskDialog::AddRadioButtonGroup(int nIDRadioButtonsFirst, int nIDRadioButtonsLast)
+ // Adds a range of radio buttons to the Task Dialog.
+ // Assumes the resource ID of the button and it's string match
+ {
+ assert (m_hWnd == NULL);
+ assert(nIDRadioButtonsFirst > 0);
+ assert(nIDRadioButtonsLast > nIDRadioButtonsFirst);
+
+ TASKDIALOG_BUTTON tdb;
+ for (int nID = nIDRadioButtonsFirst; nID <= nIDRadioButtonsLast; ++nID)
+ {
+ tdb.nButtonID = nID;
+ tdb.pszButtonText = MAKEINTRESOURCEW(nID);
+ m_vRadioButtons.push_back(tdb);
+ }
+ }
+
+ inline void CTaskDialog::ClickButton(int nButtonID) const
+ // Simulates the action of a button click in the Task Dialog.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_CLICK_BUTTON, (WPARAM)nButtonID, 0);
+ }
+
+ inline void CTaskDialog::ClickRadioButton(int nRadioButtonID) const
+ // Simulates the action of a radio button click in the TaskDialog.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_CLICK_RADIO_BUTTON, (WPARAM)nRadioButtonID, 0);
+ }
+
+ inline LRESULT CTaskDialog::DoModal(CWnd* pParent /* = NULL */)
+ // Creates and displays the Task Dialog.
+ {
+ assert (m_hWnd == NULL);
+
+ m_tc.cbSize = sizeof(m_tc);
+ m_tc.pButtons = m_vButtons.empty()? NULL : &m_vButtons.front();
+ m_tc.cButtons = m_vButtons.size();
+ m_tc.pRadioButtons = m_vRadioButtons.empty()? NULL : &m_vRadioButtons.front();
+ m_tc.cRadioButtons = m_vRadioButtons.size();
+ m_tc.hwndParent = pParent? pParent->GetHwnd() : NULL;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+
+ // Store the CWnd pointer in thread local storage
+ pTLSData->pCWnd = this;
+
+ // Declare a pointer to the TaskDialogIndirect function
+ HMODULE hComCtl = ::LoadLibrary(_T("COMCTL32.DLL"));
+ assert(hComCtl);
+ typedef HRESULT WINAPI TASKDIALOGINDIRECT(const TASKDIALOGCONFIG*, int*, int*, BOOL*);
+ TASKDIALOGINDIRECT* pTaskDialogIndirect = (TASKDIALOGINDIRECT*)::GetProcAddress(hComCtl, "TaskDialogIndirect");
+
+ // Call TaskDialogIndirect through our function pointer
+ LRESULT lr = (*pTaskDialogIndirect)(&m_tc, &m_SelectedButtonID, &m_SelectedRadioButtonID, &m_VerificationCheckboxState);
+
+ FreeLibrary(hComCtl);
+ return lr;
+ }
+
+ inline void CTaskDialog::ElevateButton(int nButtonID, BOOL bElevated)
+ // Adds a shield icon to indicate that the button's action requires elevated privilages.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, (WPARAM)nButtonID, (LPARAM)bElevated);
+ }
+
+ inline void CTaskDialog::EnableButton(int nButtonID, BOOL bEnabled)
+ // Enables or disables a push button in the TaskDialog.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_ENABLE_BUTTON, (WPARAM)nButtonID, (LPARAM)bEnabled);
+ }
+ inline void CTaskDialog::EnableRadioButton(int nRadioButtonID, BOOL bEnabled)
+ // Enables or disables a radio button in the TaskDialog.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_ENABLE_RADIO_BUTTON, (WPARAM)nRadioButtonID, (LPARAM)bEnabled);
+ }
+
+ inline TASKDIALOGCONFIG CTaskDialog::GetConfig() const
+ // Returns the TASKDIALOGCONFIG structure for the Task Dialog.
+ {
+ return m_tc;
+ }
+
+ inline TASKDIALOG_FLAGS CTaskDialog::GetOptions() const
+ // Returns the Task Dialog's options. These are a combination of:
+ // TDF_ENABLE_HYPERLINKS
+ // TDF_USE_HICON_MAIN
+ // TDF_USE_HICON_FOOTER
+ // TDF_ALLOW_DIALOG_CANCELLATION
+ // TDF_USE_COMMAND_LINKS
+ // TDF_USE_COMMAND_LINKS_NO_ICON
+ // TDF_EXPAND_FOOTER_AREA
+ // TDF_EXPANDED_BY_DEFAULT
+ // TDF_VERIFICATION_FLAG_CHECKED
+ // TDF_SHOW_PROGRESS_BAR
+ // TDF_SHOW_MARQUEE_PROGRESS_BAR
+ // TDF_CALLBACK_TIMER
+ // TDF_POSITION_RELATIVE_TO_WINDOW
+ // TDF_RTL_LAYOUT
+ // TDF_NO_DEFAULT_RADIO_BUTTON
+ // TDF_CAN_BE_MINIMIZED
+ {
+ return m_tc.dwFlags;
+ }
+
+ inline int CTaskDialog::GetSelectedButtonID() const
+ // Returns the ID of the selected button.
+ {
+ assert (m_hWnd == NULL);
+ return m_SelectedButtonID;
+ }
+
+ inline int CTaskDialog::GetSelectedRadioButtonID() const
+ // Returns the ID of the selected radio button.
+ {
+ assert (m_hWnd == NULL);
+ return m_SelectedRadioButtonID;
+ }
+
+ inline BOOL CTaskDialog::GetVerificationCheckboxState() const
+ // Returns the state of the verification check box.
+ {
+ assert (m_hWnd == NULL);
+ return m_VerificationCheckboxState;
+ }
+
+ inline BOOL CTaskDialog::IsSupported()
+ // Returns true if TaskDialogs are supported on this system.
+ {
+ HMODULE hModule = ::LoadLibrary(_T("COMCTL32.DLL"));
+ assert(hModule);
+
+ BOOL bResult = (BOOL)::GetProcAddress(hModule, "TaskDialogIndirect");
+
+ ::FreeLibrary(hModule);
+ return bResult;
+ }
+
+ inline void CTaskDialog::NavigateTo(CTaskDialog& TaskDialog) const
+ // Replaces the information displayed by the task dialog.
+ {
+ assert(m_hWnd);
+ TASKDIALOGCONFIG tc = TaskDialog.GetConfig();
+ SendMessage(TDM_NAVIGATE_PAGE, 0, (LPARAM)&tc);
+ }
+
+ inline BOOL CTaskDialog::OnTDButtonClicked(int nButtonID)
+ // Called when the user selects a button or command link.
+ {
+ UNREFERENCED_PARAMETER(nButtonID);
+
+ // return TRUE to prevent the task dialog from closing
+ return FALSE;
+ }
+
+ inline void CTaskDialog::OnTDConstructed()
+ // Called when the task dialog is constructed, before it is displayed.
+ {}
+
+ inline void CTaskDialog::OnTDCreated()
+ // Called when the task dialog is displayed.
+ {}
+
+ inline void CTaskDialog::OnTDDestroyed()
+ // Called when the task dialog is destroyed.
+ {
+ }
+
+ inline void CTaskDialog::OnTDExpandButtonClicked(BOOL bExpanded)
+ // Called when the expand button is clicked.
+ {
+ UNREFERENCED_PARAMETER(bExpanded);
+ }
+
+ inline void CTaskDialog::OnTDHelp()
+ // Called when the user presses F1 on the keyboard.
+ {}
+
+ inline void CTaskDialog::OnTDHyperlinkClicked(LPCTSTR pszHref)
+ // Called when the user clicks on a hyperlink.
+ {
+ UNREFERENCED_PARAMETER(pszHref);
+ }
+
+ inline void CTaskDialog::OnTDNavigatePage()
+ // Called when a navigation has occurred.
+ {}
+
+ inline BOOL CTaskDialog::OnTDRadioButtonClicked(int nRadioButtonID)
+ // Called when the user selects a radio button.
+ {
+ UNREFERENCED_PARAMETER(nRadioButtonID);
+ return TRUE;
+ }
+
+ inline BOOL CTaskDialog::OnTDTimer(DWORD dwTickCount)
+ // Called every 200 milliseconds (aproximately) when the TDF_CALLBACK_TIMER flag is set.
+ {
+ UNREFERENCED_PARAMETER(dwTickCount);
+
+ // return TRUE to reset the tick count
+ return FALSE;
+ }
+
+ inline void CTaskDialog::OnTDVerificationCheckboxClicked(BOOL bChecked)
+ // Called when the user clicks the Task Dialog verification check box.
+ {
+ UNREFERENCED_PARAMETER(bChecked);
+ }
+
+ inline void CTaskDialog::RemoveAllButtons()
+ // Removes all push buttons from the task dialog.
+ {
+ assert (m_hWnd == NULL);
+ m_vButtons.clear();
+ m_vButtonsText.clear();
+ }
+
+ inline void CTaskDialog::RemoveAllRadioButtons()
+ // Removes all radio buttons from the task dialog.
+ {
+ assert (m_hWnd == NULL);
+ m_vRadioButtons.clear();
+ m_vRadioButtonsText.clear();
+ }
+
+ inline void CTaskDialog::Reset()
+ // Returns the dialog to its default state.
+ {
+ assert (m_hWnd == NULL);
+
+ RemoveAllButtons();
+ RemoveAllRadioButtons();
+ ZeroMemory(&m_tc, sizeof(m_tc));
+ m_tc.cbSize = sizeof(m_tc);
+ m_tc.pfCallback = CTaskDialog::StaticTaskDialogProc;
+
+ m_SelectedButtonID = 0;
+ m_SelectedRadioButtonID = 0;
+ m_VerificationCheckboxState = FALSE;
+
+ m_vWindowTitle.clear();
+ m_vMainInstruction.clear();
+ m_vContent.clear();
+ m_vVerificationText.clear();
+ m_vExpandedInformation.clear();
+ m_vExpandedControlText.clear();
+ m_vCollapsedControlText.clear();
+ m_vFooter.clear();
+ }
+
+ inline void CTaskDialog::SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons)
+ // The dwCommonButtons parameter can be a combination of:
+ // TDCBF_OK_BUTTON OK button
+ // TDCBF_YES_BUTTON Yes button
+ // TDCBF_NO_BUTTON No button
+ // TDCBF_CANCEL_BUTTON Cancel button
+ // TDCBF_RETRY_BUTTON Retry button
+ // TDCBF_CLOSE_BUTTON Close button
+ {
+ assert (m_hWnd == NULL);
+ m_tc.dwCommonButtons = dwCommonButtons;
+ }
+
+ inline void CTaskDialog::SetContent(LPCTSTR pszContent)
+ // Sets the task dialog's primary content.
+ {
+ StoreText(m_vContent, pszContent);
+ m_tc.pszContent = &m_vContent.front();
+
+ if (IsWindow())
+ SendMessage(TDM_SET_ELEMENT_TEXT, (WPARAM)TDE_CONTENT, (LPARAM)(LPCWSTR)T2W(pszContent));
+ }
+
+ inline void CTaskDialog::SetDefaultButton(int nButtonID)
+ // Sets the task dialog's default button.
+ // Can be either a button ID or one of the common buttons
+ {
+ assert (m_hWnd == NULL);
+ m_tc.nDefaultButton = nButtonID;
+ }
+
+ inline void CTaskDialog::SetDefaultRadioButton(int nRadioButtonID)
+ // Sets the default radio button.
+ {
+ assert (m_hWnd == NULL);
+ m_tc.nDefaultRadioButton = nRadioButtonID;
+ }
+
+ inline void CTaskDialog::SetDialogWidth(UINT nWidth /*= 0*/)
+ // The width of the task dialog's client area. If 0, the
+ // task dialog manager will calculate the ideal width.
+ {
+ assert (m_hWnd == NULL);
+ m_tc.cxWidth = nWidth;
+ }
+
+ inline void CTaskDialog::SetExpansionArea(LPCTSTR pszExpandedInfo, LPCTSTR pszExpandedLabel /* = _T("")*/, LPCTSTR pszCollapsedLabel /* = _T("")*/)
+ // Sets the text in the expandable area of the Task Dialog.
+ {
+ StoreText(m_vExpandedInformation, pszExpandedInfo);
+ m_tc.pszExpandedInformation = &m_vExpandedInformation.front();
+
+ StoreText(m_vExpandedControlText, pszExpandedLabel);
+ m_tc.pszExpandedControlText = &m_vExpandedControlText.front();
+
+ StoreText(m_vCollapsedControlText, pszCollapsedLabel);
+ m_tc.pszCollapsedControlText = &m_vCollapsedControlText.front();
+
+ if (IsWindow())
+ SendMessage(TDM_SET_ELEMENT_TEXT, (WPARAM)TDE_EXPANDED_INFORMATION, (LPARAM)(LPCWSTR)T2W(pszExpandedInfo));
+ }
+
+ inline void CTaskDialog::SetFooterIcon(HICON hFooterIcon)
+ // Sets the icon that will be displayed in the Task Dialog's footer.
+ {
+ m_tc.hFooterIcon = hFooterIcon;
+
+ if (IsWindow())
+ SendMessage(TDM_UPDATE_ICON, (WPARAM)TDIE_ICON_FOOTER, (LPARAM)hFooterIcon);
+ }
+
+ inline void CTaskDialog::SetFooterIcon(LPCTSTR lpszFooterIcon)
+ // Sets the icon that will be displayed in the Task Dialog's footer.
+ // Possible icons:
+ // TD_ERROR_ICON A stop-sign icon appears in the task dialog.
+ // TD_WARNING_ICON An exclamation-point icon appears in the task dialog.
+ // TD_INFORMATION_ICON An icon consisting of a lowercase letter i in a circle appears in the task dialog.
+ // TD_SHIELD_ICON A shield icon appears in the task dialog.
+ // or a value passed via MAKEINTRESOURCE
+ {
+ m_tc.pszFooterIcon = (LPCWSTR)lpszFooterIcon;
+
+ if (IsWindow())
+ SendMessage(TDM_UPDATE_ICON, (WPARAM)TDIE_ICON_FOOTER, (LPARAM)lpszFooterIcon);
+ }
+
+ inline void CTaskDialog::SetFooterText(LPCTSTR pszFooter)
+ // Sets the text that will be displayed in the Task Dialog's footer.
+ {
+ StoreText(m_vFooter, pszFooter);
+ m_tc.pszFooter = &m_vFooter.front();
+
+ if (IsWindow())
+ SendMessage(TDM_SET_ELEMENT_TEXT, (WPARAM)TDE_FOOTER, (LPARAM)(LPCWSTR)T2W(pszFooter));
+ }
+
+ inline void CTaskDialog::SetMainIcon(HICON hMainIcon)
+ // Sets Task Dialog's main icon.
+ {
+ m_tc.hMainIcon = hMainIcon;
+
+ if (IsWindow())
+ SendMessage(TDM_UPDATE_ICON, (WPARAM)TDIE_ICON_MAIN, (LPARAM)hMainIcon);
+ }
+
+ inline void CTaskDialog::SetMainIcon(LPCTSTR lpszMainIcon)
+ // Sets Task Dialog's main icon.
+ // Possible icons:
+ // TD_ERROR_ICON A stop-sign icon appears in the task dialog.
+ // TD_WARNING_ICON An exclamation-point icon appears in the task dialog.
+ // TD_INFORMATION_ICON An icon consisting of a lowercase letter i in a circle appears in the task dialog.
+ // TD_SHIELD_ICON A shield icon appears in the task dialog.
+ // or a value passed via MAKEINTRESOURCE
+ //
+ // Note: Some values of main icon will also generate a MessageBeep when the TaskDialog is created.
+ {
+ m_tc.pszMainIcon = (LPCWSTR)lpszMainIcon;
+
+ if (IsWindow())
+ SendMessage(TDM_UPDATE_ICON, (WPARAM)TDIE_ICON_MAIN, (LPARAM)lpszMainIcon);
+ }
+
+ inline void CTaskDialog::SetMainInstruction(LPCTSTR pszMainInstruction)
+ // Sets the Task Dialog's main instruction text.
+ {
+ StoreText(m_vMainInstruction, pszMainInstruction);
+ m_tc.pszMainInstruction = &m_vMainInstruction.front();
+
+ if (IsWindow())
+ SendMessage(TDM_SET_ELEMENT_TEXT, (WPARAM)TDE_FOOTER, (LPARAM)(LPCWSTR)T2W(pszMainInstruction));
+ }
+
+ inline void CTaskDialog::SetOptions(TASKDIALOG_FLAGS dwFlags)
+ // Sets the Task Dialog's options. These are a combination of:
+ // TDF_ENABLE_HYPERLINKS
+ // TDF_USE_HICON_MAIN
+ // TDF_USE_HICON_FOOTER
+ // TDF_ALLOW_DIALOG_CANCELLATION
+ // TDF_USE_COMMAND_LINKS
+ // TDF_USE_COMMAND_LINKS_NO_ICON
+ // TDF_EXPAND_FOOTER_AREA
+ // TDF_EXPANDED_BY_DEFAULT
+ // TDF_VERIFICATION_FLAG_CHECKED
+ // TDF_SHOW_PROGRESS_BAR
+ // TDF_SHOW_MARQUEE_PROGRESS_BAR
+ // TDF_CALLBACK_TIMER
+ // TDF_POSITION_RELATIVE_TO_WINDOW
+ // TDF_RTL_LAYOUT
+ // TDF_NO_DEFAULT_RADIO_BUTTON
+ // TDF_CAN_BE_MINIMIZED
+ {
+ assert (m_hWnd == NULL);
+ m_tc.dwFlags = dwFlags;
+ }
+
+ inline void CTaskDialog::SetProgressBarMarquee(BOOL bEnabled /* = TRUE*/, int nMarqueeSpeed /* = 0*/)
+ // Starts and stops the marquee display of the progress bar, and sets the speed of the marquee.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_SET_PROGRESS_BAR_MARQUEE, (WPARAM)bEnabled, (LPARAM)nMarqueeSpeed);
+ }
+
+ inline void CTaskDialog::SetProgressBarPosition(int nProgressPos)
+ // Sets the current position for a progress bar.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_SET_PROGRESS_BAR_POS, (WPARAM)nProgressPos, 0);
+ }
+
+ inline void CTaskDialog::SetProgressBarRange(int nMinRange, int nMaxRange)
+ // Sets the minimum and maximum values for the hosted progress bar.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(nMinRange, nMaxRange));
+ }
+
+ inline void CTaskDialog::SetProgressBarState(int nNewState /* = PBST_NORMAL*/)
+ // Sets the current state of the progress bar. Possible states are:
+ // PBST_NORMAL
+ // PBST_PAUSE
+ // PBST_ERROR
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_SET_PROGRESS_BAR_STATE, (WPARAM)nNewState, 0);
+ }
+
+ inline void CTaskDialog::SetVerificationCheckbox(BOOL bChecked)
+ // Simulates a click on the verification checkbox of the Task Dialog, if it exists.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_CLICK_VERIFICATION, (WPARAM)bChecked, (LPARAM)bChecked);
+ }
+
+ inline void CTaskDialog::SetVerificationCheckboxText(LPCTSTR pszVerificationText)
+ // Sets the text for the verification check box.
+ {
+ assert (m_hWnd == NULL);
+ StoreText(m_vVerificationText, pszVerificationText);
+ m_tc.pszVerificationText = &m_vVerificationText.front();
+ }
+
+ inline void CTaskDialog::SetWindowTitle(LPCTSTR pszWindowTitle)
+ // Sets the Task Dialog's window title.
+ {
+ assert (m_hWnd == NULL);
+ StoreText(m_vWindowTitle, pszWindowTitle);
+ m_tc.pszWindowTitle = &m_vWindowTitle.front();
+ }
+
+ inline HRESULT CALLBACK CTaskDialog::StaticTaskDialogProc(HWND hWnd, UINT uNotification, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData)
+ // TaskDialogs direct their messages here.
+ {
+ UNREFERENCED_PARAMETER(dwRefData);
+
+ assert( GetApp() );
+
+ try
+ {
+ CTaskDialog* t = (CTaskDialog*)GetApp()->GetCWndFromMap(hWnd);
+ if (0 == t)
+ {
+ // The CTaskDialog pointer wasn't found in the map, so add it now
+
+ // Retrieve the pointer to the TLS Data
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ if (NULL == pTLSData)
+ throw CWinException(_T("Unable to get TLS"));
+
+ // Retrieve pointer to CTaskDialog object from Thread Local Storage TLS
+ t = (CTaskDialog*)(pTLSData->pCWnd);
+ if (NULL == t)
+ throw CWinException(_T("Failed to route message"));
+
+ pTLSData->pCWnd = NULL;
+
+ // Store the CTaskDialog pointer in the HWND map
+ t->m_hWnd = hWnd;
+ t->AddToMap();
+ }
+
+ return t->TaskDialogProc(uNotification, wParam, lParam);
+ }
+
+ catch (const CWinException &e)
+ {
+ // Most CWinExceptions will end up here unless caught earlier.
+ e.what();
+ }
+
+ return 0L;
+
+ } // LRESULT CALLBACK StaticTaskDialogProc(...)
+
+ inline void CTaskDialog::StoreText(std::vector<WCHAR>& vWChar, LPCTSTR pFromTChar)
+ {
+ // Stores a TChar string in a WCHAR vector
+
+ std::vector<TCHAR> vTChar;
+
+ if (IS_INTRESOURCE(pFromTChar)) // support MAKEINTRESOURCE
+ {
+ tString ts = LoadString((UINT)pFromTChar);
+ int len = pFromTChar? ts.length() + 1 : 1;
+ vTChar.assign(len, _T('\0'));
+ vWChar.assign(len, _T('\0'));
+ if (pFromTChar)
+ lstrcpy( &vTChar.front(), ts.c_str());
+
+ }
+ else
+ {
+ int len = lstrlen(pFromTChar) +1;
+ vTChar.assign(len, _T('\0'));
+ vWChar.assign(len, _T('\0'));
+ lstrcpy( &vTChar.front(), pFromTChar);
+ }
+
+ lstrcpyW(&vWChar.front(), T2W(&vTChar.front()) );
+ }
+
+ inline LRESULT CTaskDialog::TaskDialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // Handles the Task Dialog's notificaions.
+ {
+ switch(uMsg)
+ {
+ case TDN_BUTTON_CLICKED:
+ return OnTDButtonClicked((int)wParam);
+
+ case TDN_CREATED:
+ OnTDCreated();
+ break;
+ case TDN_DESTROYED:
+ Cleanup(); // Prepare this CWnd to be reused.
+ OnTDDestroyed();
+ break;
+ case TDN_DIALOG_CONSTRUCTED:
+ OnTDConstructed();
+ break;
+ case TDN_EXPANDO_BUTTON_CLICKED:
+ OnTDExpandButtonClicked((BOOL)wParam);
+ break;
+ case TDN_HELP:
+ OnTDHelp();
+ break;
+ case TDN_HYPERLINK_CLICKED:
+ OnTDHyperlinkClicked(W2T((LPCWSTR)lParam));
+ break;
+ case TDN_NAVIGATED:
+ OnTDNavigatePage();
+ break;
+ case TDN_RADIO_BUTTON_CLICKED:
+ OnTDRadioButtonClicked((int)wParam);
+ break;
+ case TDN_TIMER:
+ return OnTDTimer((DWORD)wParam);
+
+ case TDN_VERIFICATION_CLICKED:
+ OnTDVerificationCheckboxClicked((BOOL)wParam);
+ break;
+ }
+
+ return S_OK;
+ }
+
+ inline LRESULT CTaskDialog::TaskDialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // Override this function in your class derrived from CDialog if you wish to handle messages
+ // A typical function might look like this:
+
+ // switch (uMsg)
+ // {
+ // case MESSAGE1: // Some Windows API message
+ // OnMessage1(); // A user defined function
+ // break; // Also do default processing
+ // case MESSAGE2:
+ // OnMessage2();
+ // return x; // Don't do default processing, but instead return
+ // // a value recommended by the Windows API documentation
+ // }
+
+ // Always pass unhandled messages on to TaskDialogProcDefault
+ return TaskDialogProcDefault(uMsg, wParam, lParam);
+ }
+
+ inline void CTaskDialog::UpdateElementText(TASKDIALOG_ELEMENTS eElement, LPCTSTR pszNewText)
+ // Updates a text element on the Task Dialog.
+ {
+ assert(m_hWnd);
+ SendMessage(TDM_UPDATE_ELEMENT_TEXT, (WPARAM)eElement, (LPARAM)(LPCWSTR)T2W(pszNewText));
+ }
+
+}
+
+
+
+#endif // _WIN32XX_TASKDIALOG_H_ \ No newline at end of file
diff --git a/mmc_updater/depends/win32cpp/thread.h b/mmc_updater/depends/win32cpp/thread.h
new file mode 100644
index 00000000..5564d888
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/thread.h
@@ -0,0 +1,241 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+// The CThread class simplifies the use of threads with Win32++.
+// To use threads in your Win32++ application, inherit a class from
+// CThread, and override InitInstance. When your class is instanciated,
+// a new thread is started, and the InitInstance function is called to
+// run in the new thread.
+
+// If your thread is used to run one or more windows, InitInstance should
+// return TRUE, causing the MessageLoop function to be called. If your
+// thread doesn't require a MessageLoop, it should return FALSE. Threads
+// which don't run a message loop as sometimes referred to as "worker" threads.
+
+// Note: It is your job to end the thread before CThread ends!
+// To end a thread with a message loop, use PostQuitMessage on the thread.
+// To end a thread without a message loop, set an event, and end the thread
+// when the event is received.
+
+// Hint: It is never a good idea to use things like TerminateThread or ExitThread to
+// end your thread. These represent poor programming techniques, and are likely
+// to leak memory and resources.
+
+// More Hints for thread programming:
+// 1) Avoid using SendMessage between threads, as this will cause one thread to wait for
+// the other to respond. Use PostMessage between threads to avoid this problem.
+// 2) Access to variables and resources shared between threads need to be made thread safe.
+// Having one thread modify a resouce or variable while another thread is accessing it is
+// a recipe for disaster.
+// 3) Thread Local Storage (TLS) can be used to replace global variables to make them thread
+// safe. With TLS, each thread gets its own copy of the variable.
+// 4) Critical Sections can be used to make shared resources thread safe.
+// 5) Window messages (including user defined messages) can be posted between GUI threads to
+// communicate information between them.
+// 6) Events (created by CreateEvent) can be used to comunicate information between threads
+// (both GUI and worker threads).
+// 7) Avoid using sleep to synchronise threads. Generally speaking, the various wait
+// functions (e.g. WaitForSingleObject) will be better for this.
+
+// About Threads:
+// Each program that executes has a "process" allocated to it. A process has one or more
+// threads. Threads run independantly of each other. It is the job of the operating system
+// to manage the running of the threads, and do the task switching between threads as required.
+// Systems with multiple CPUs will be able to run as many threads simultaneously as there are
+// CPUs.
+
+// Threads behave like a program within a program. When the main thread starts, the application
+// runs the WinMain function and ends when WinMain ends. When another thread starts, it too
+// will run the function provided to it, and end when that function ends.
+
+
+#ifndef _WIN32XX_WINTHREAD_H_
+#define _WIN32XX_WINTHREAD_H_
+
+
+#include <process.h>
+
+
+namespace Win32xx
+{
+
+ //////////////////////////////////////
+ // Declaration of the CThread class
+ //
+ class CThread
+ {
+ public:
+ CThread();
+ CThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag);
+ virtual ~CThread();
+
+ // Overridables
+ virtual BOOL InitInstance();
+ virtual int MessageLoop();
+
+ // Operations
+ HANDLE GetThread() const;
+ int GetThreadID() const;
+ int GetThreadPriority() const;
+ DWORD ResumeThread() const;
+ BOOL SetThreadPriority(int nPriority) const;
+ DWORD SuspendThread() const;
+
+ private:
+ CThread(const CThread&); // Disable copy construction
+ CThread& operator = (const CThread&); // Disable assignment operator
+ void CreateThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag);
+ static UINT WINAPI StaticThreadCallback(LPVOID pCThread);
+
+ HANDLE m_hThread; // Handle of this thread
+ UINT m_nThreadID; // ID of this thread
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ ///////////////////////////////////////
+ // Definitions for the CThread class
+ //
+ inline CThread::CThread() : m_hThread(0), m_nThreadID(0)
+ {
+ CreateThread(0, 0, CREATE_SUSPENDED);
+ }
+
+ inline CThread::CThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag)
+ : m_hThread(0), m_nThreadID(0)
+
+ {
+ // Valid argument values:
+ // pSecurityAttributes Either a pointer to SECURITY_ATTRIBUTES or 0
+ // stack_size Either the stack size or 0
+ // initflag Either CREATE_SUSPENDED or 0
+
+ CreateThread(pSecurityAttributes, stack_size, initflag);
+ }
+
+ inline CThread::~CThread()
+ {
+ // A thread's state is set to signalled when the thread terminates.
+ // If your thread is still running at this point, you have a bug.
+ if (0 != WaitForSingleObject(m_hThread, 0))
+ TRACE(_T("*** Error *** Ending CThread before ending its thread\n"));
+
+ // Close the thread's handle
+ ::CloseHandle(m_hThread);
+ }
+
+ inline void CThread::CreateThread(LPSECURITY_ATTRIBUTES pSecurityAttributes, unsigned stack_size, unsigned initflag)
+ {
+ // NOTE: By default, the thread is created in the default state.
+ m_hThread = (HANDLE)_beginthreadex(pSecurityAttributes, stack_size, CThread::StaticThreadCallback, (LPVOID) this, initflag, &m_nThreadID);
+
+ if (0 == m_hThread)
+ throw CWinException(_T("Failed to create thread"));
+ }
+
+ inline HANDLE CThread::GetThread() const
+ {
+ assert(m_hThread);
+ return m_hThread;
+ }
+
+ inline int CThread::GetThreadID() const
+ {
+ assert(m_hThread);
+ return m_nThreadID;
+ }
+
+ inline int CThread::GetThreadPriority() const
+ {
+ assert(m_hThread);
+ return ::GetThreadPriority(m_hThread);
+ }
+
+ inline BOOL CThread::InitInstance()
+ {
+ // Override this function to perform tasks when the thread starts.
+
+ // return TRUE to run a message loop, otherwise return FALSE.
+ // A thread with a window must run a message loop.
+ return FALSE;
+ }
+
+ inline int CThread::MessageLoop()
+ {
+ // Override this function if your thread needs a different message loop
+ return GetApp()->MessageLoop();
+ }
+
+ inline DWORD CThread::ResumeThread() const
+ {
+ assert(m_hThread);
+ return ::ResumeThread(m_hThread);
+ }
+
+ inline DWORD CThread::SuspendThread() const
+ {
+ assert(m_hThread);
+ return ::SuspendThread(m_hThread);
+ }
+
+ inline BOOL CThread::SetThreadPriority(int nPriority) const
+ {
+ assert(m_hThread);
+ return ::SetThreadPriority(m_hThread, nPriority);
+ }
+
+ inline UINT WINAPI CThread::StaticThreadCallback(LPVOID pCThread)
+ // When the thread starts, it runs this function.
+ {
+ // Get the pointer for this CMyThread object
+ CThread* pThread = (CThread*)pCThread;
+
+ if (pThread->InitInstance())
+ return pThread->MessageLoop();
+
+ return 0;
+ }
+
+}
+
+#endif // #define _WIN32XX_WINTHREAD_H_
+
diff --git a/mmc_updater/depends/win32cpp/toolbar.h b/mmc_updater/depends/win32cpp/toolbar.h
new file mode 100644
index 00000000..1ed005a0
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/toolbar.h
@@ -0,0 +1,1361 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+#ifndef _WIN32XX_TOOLBAR_H_
+#define _WIN32XX_TOOLBAR_H_
+
+#include "wincore.h"
+#include "gdi.h"
+#include "rebar.h"
+
+
+namespace Win32xx
+{
+
+ struct ToolBarTheme
+ {
+ BOOL UseThemes; // TRUE if themes are used
+ COLORREF clrHot1; // Colour 1 for hot button
+ COLORREF clrHot2; // Colour 2 for hot button
+ COLORREF clrPressed1; // Colour 1 for pressed button
+ COLORREF clrPressed2; // Colour 2 for pressed button
+ COLORREF clrOutline; // Colour for border outline
+ };
+
+
+ ////////////////////////////////////
+ // Declaration of the CToolBar class
+ //
+ class CToolBar : public CWnd
+ {
+ public:
+ CToolBar();
+ virtual ~CToolBar();
+
+ // Operations
+ virtual int AddBitmap(UINT ToolBarID);
+ virtual BOOL AddButton(UINT nID, BOOL bEnabled = TRUE);
+ virtual void Destroy();
+ virtual BOOL ReplaceBitmap(UINT NewToolBarID);
+ virtual BOOL SetBitmap(UINT nID);
+ virtual int SetButtons(const std::vector<UINT>& vToolBarData) const;
+ virtual BOOL SetButtonText(int idButton, LPCTSTR szText);
+ virtual BOOL SetImages(COLORREF crMask, UINT ToolBarID, UINT ToolBarHotID, UINT ToolBarDisabledID);
+
+ // Wrappers for Win32 API functions
+ BOOL AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons) const;
+ int AddString(UINT nStringID) const;
+ int AddStrings(LPCTSTR lpszStrings) const;
+ void Autosize() const;
+ void CheckButton(int idButton, BOOL fCheck) const;
+ int CommandToIndex(int idButton) const;
+ BOOL DeleteButton(int iButton) const;
+ BOOL DisableButton(int idButton) const;
+ BOOL EnableButton(int idButton) const;
+ BOOL GetButton(int iButton, LPTBBUTTON lpButton) const;
+ int GetButtonCount() const;
+ DWORD GetButtonSize() const;
+ UINT GetButtonState(int idButton) const;
+ BYTE GetButtonStyle(int idButton) const;
+ CString GetButtonText(int idButton) const;
+ int GetCommandID(int iIndex) const;
+ HIMAGELIST GetDisabledImageList() const;
+ int GetHotItem() const;
+ HIMAGELIST GetHotImageList() const;
+ HIMAGELIST GetImageList() const;
+ CRect GetItemRect(int iIndex) const;
+ CSize GetMaxSize() const;
+ DWORD GetPadding() const;
+ CRect GetRect(int idButton) const;
+ int GetRows() const;
+ int GetTextRows() const;
+ HWND GetToolTips() const;
+ BOOL HasText() const;
+ BOOL HideButton(int idButton, BOOL fShow) const;
+ int HitTest() const;
+ BOOL Indeterminate(int idButton, BOOL fIndeterminate) const;
+ BOOL InsertButton(int iButton, LPTBBUTTON lpButton) const;
+ BOOL IsButtonHidden(int idButton) const;
+ BOOL IsButtonHighlighted(int idButton) const;
+ BOOL IsButtonIndeterminate(int idButton) const;
+ BOOL IsButtonPressed(int idButton) const;
+ int MapAccelerator(TCHAR chAccel) const;
+ BOOL MarkButton(int idButton) const;
+ BOOL MoveButton(UINT uOldPos, UINT uNewPos) const;
+ BOOL PressButton(int idButton, BOOL fPress) const;
+ void SaveRestore(BOOL fSave, TBSAVEPARAMS* ptbsp) const;
+ BOOL SetBitmapSize(int cx, int cy) const;
+ BOOL SetButtonSize(int cx, int cy) const;
+ BOOL SetButtonState(int idButton, UINT State) const;
+ BOOL SetButtonStyle(int idButton, BYTE Style) const;
+ BOOL SetButtonWidth(int idButton, int nWidth) const;
+ BOOL SetCommandID(int iIndex, int idButton) const;
+ HIMAGELIST SetDisableImageList(HIMAGELIST himlNewDisabled) const;
+ DWORD SetDrawTextFlags(DWORD dwMask, DWORD dwDTFlags) const;
+ DWORD SetExtendedStyle(DWORD dwExStyle) const;
+ HIMAGELIST SetHotImageList(HIMAGELIST himlNewHot) const;
+ int SetHotItem(int iHot) const;
+ HIMAGELIST SetImageList(HIMAGELIST himlNew) const;
+ BOOL SetIndent(int iIndent) const;
+ BOOL SetMaxTextRows(int iMaxRows) const;
+ BOOL SetPadding(int cx, int cy) const;
+ void SetToolTips(HWND hwndToolTip) const;
+
+ // Attributes
+ std::vector<UINT>& GetToolBarData() const {return (std::vector <UINT> &)m_vToolBarData;}
+ ToolBarTheme& GetToolBarTheme() {return m_Theme;}
+ void SetToolBarTheme(ToolBarTheme& Theme);
+
+ protected:
+ // Overridables
+ virtual void OnCreate();
+ virtual void OnDestroy();
+ virtual void OnWindowPosChanging(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnCustomDraw(NMHDR* pNMHDR);
+ virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam);
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void PreRegisterClass(WNDCLASS &wc);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CToolBar(const CToolBar&); // Disable copy construction
+ CToolBar& operator = (const CToolBar&); // Disable assignment operator
+
+ std::vector<UINT> m_vToolBarData; // vector of resource IDs for toolbar buttons
+ std::map<tString, int> m_StringMap; // a map of strings used in SetButtonText
+ UINT m_OldToolBarID; // Bitmap Resource ID, used in AddBitmap/ReplaceBitmap
+ ToolBarTheme m_Theme; // The theme structure
+ BOOL m_bDrawArrowBkgrnd; // True if a seperate arrow background is to be drawn
+
+ }; // class CToolBar
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////
+ // Definitions for the CToolBar class
+ //
+ inline CToolBar::CToolBar() : m_OldToolBarID(0), m_bDrawArrowBkgrnd(FALSE)
+ {
+ ZeroMemory(&m_Theme, sizeof(ToolBarTheme));
+ }
+
+ inline CToolBar::~CToolBar()
+ {
+ }
+
+ inline int CToolBar::AddBitmap(UINT ToolBarID)
+ // Adds one or more images to the list of button images available for a toolbar.
+
+ // Note: AddBitmap supports a maximum colour depth of 8 bits (256 colours)
+ // For more colours, use an ImageList instead
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int iNumButtons = 0;
+ std::vector<UINT>::iterator iter;
+ for (iter = GetToolBarData().begin(); iter < GetToolBarData().end(); ++iter)
+ if ((*iter) != 0) ++iNumButtons;
+
+ TBADDBITMAP tbab = {0};
+ tbab.hInst = GetApp()->GetResourceHandle();
+ tbab.nID = ToolBarID;
+ int iResult = (int)SendMessage(TB_ADDBITMAP, iNumButtons, (LPARAM)&tbab);
+
+ if (-1 != iResult)
+ m_OldToolBarID = ToolBarID;
+
+ return iResult;
+ }
+
+ inline BOOL CToolBar::AddButton(UINT nID, BOOL bEnabled /* = TRUE */)
+ // Adds Resource IDs to toolbar buttons.
+ // A resource ID of 0 is a separator
+ {
+ assert(::IsWindow(m_hWnd));
+
+ m_vToolBarData.push_back(nID);
+
+ // TBBUTTON structure for each button in the toolbar
+ TBBUTTON tbb = {0};
+
+ std::vector<UINT>::iterator iter;
+ int iImages = 0;
+ for(iter = m_vToolBarData.begin(); iter < m_vToolBarData.end(); ++iter)
+ if (0 != *iter) iImages++;
+
+ ZeroMemory(&tbb, sizeof(TBBUTTON));
+
+ if (0 == nID)
+ {
+ tbb.fsStyle = TBSTYLE_SEP;
+ }
+ else
+ {
+ tbb.dwData = iImages -1;
+ tbb.iBitmap = iImages -1;
+ tbb.idCommand = nID;
+ tbb.fsState = bEnabled? TBSTATE_ENABLED : 0;
+ tbb.fsStyle = TBSTYLE_BUTTON;
+ }
+
+ // Add the button to the toolbar
+ return (BOOL)SendMessage(TB_ADDBUTTONS, 1L, (LPARAM)&tbb);
+ }
+
+ inline BOOL CToolBar::AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons) const
+ // Adds one or more buttons to a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ADDBUTTONS, (LPARAM)uNumButtons, (WPARAM)lpButtons);
+ }
+
+ inline int CToolBar::AddString(UINT nStringID) const
+ // Adds a new string, passed as a resource ID, to the toolbar's internal list of strings.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_ADDSTRING, (LPARAM)GetApp()->GetResourceHandle(), (WPARAM)nStringID);
+ }
+
+ inline int CToolBar::AddStrings(LPCTSTR lpszStrings) const
+ // Adds a new string or strings to the list of strings available for a toolbar control.
+ // Strings in the buffer must be separated by a null character. You must ensure that the last string has two null terminators.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_ADDSTRING, 0L, (WPARAM)lpszStrings);
+ }
+
+ inline void CToolBar::Autosize() const
+ // Causes a toolbar to be resized.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(TB_AUTOSIZE, 0L, 0L);
+ }
+
+ inline void CToolBar::CheckButton(int idButton, BOOL fCheck) const
+ // Checks or unchecks a given button in a toolbar.
+ // When a button is checked, it is displayed in the pressed state.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(TB_CHECKBUTTON, (WPARAM)idButton, (LPARAM)MAKELONG(fCheck, 0));
+ }
+
+ inline int CToolBar::CommandToIndex(int idButton) const
+ // Retrieves the zero-based index for the button associated with the specified command identifier
+ {
+ assert(::IsWindow(m_hWnd));
+
+ // returns -1 on fail
+ return (int)SendMessage(TB_COMMANDTOINDEX, (WPARAM)idButton, 0L);
+ }
+
+ inline BOOL CToolBar::DeleteButton(int iButton) const
+ // Deletes a button from the toolbar.
+ // iButton is the Zero-based index of the button to delete.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_DELETEBUTTON, (WPARAM)iButton, 0L);
+ }
+
+ inline void CToolBar::Destroy()
+ // Allows CToolBar to be reused after the window is destroyed
+ {
+ CWnd::Destroy();
+ m_StringMap.clear();
+ }
+
+ inline BOOL CToolBar::DisableButton(int idButton) const
+ // Disables the specified button in a toolbar
+ // An example of idButton would be IDM_FILE_OPEN
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ENABLEBUTTON, (WPARAM)idButton, (LPARAM) MAKELONG(FALSE, 0));
+ }
+
+ inline BOOL CToolBar::EnableButton(int idButton) const
+ // Enables the specified button in a toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ENABLEBUTTON, (WPARAM)idButton, (LPARAM) MAKELONG(TRUE,0 ));
+ }
+
+ inline BOOL CToolBar::GetButton(int iButton, LPTBBUTTON lpButton) const
+ // Recieves the TBBUTTON structure information from the specified button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_GETBUTTON, (LPARAM)iButton, (WPARAM)lpButton);
+ }
+
+ inline int CToolBar::GetButtonCount() const
+ // Retrieves a count of the buttons currently in the toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_BUTTONCOUNT, 0L, 0L);
+ }
+
+ inline DWORD CToolBar::GetButtonSize() const
+ // Retrieves the current width and height of toolbar buttons, in pixels.
+ // Returns a DWORD value that contains the width and height values in the low word and high word, respectively.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(TB_GETBUTTONSIZE, 0L, 0L);
+ }
+
+ inline UINT CToolBar::GetButtonState(int idButton) const
+ // Get the state of an individual button
+ // TBSTATE_CHECKED The button has the TBSTYLE_CHECK style and is being clicked.
+ // TBSTATE_ELLIPSES The button's text is cut off and an ellipsis is displayed.
+ // TBSTATE_ENABLED The button accepts user input. A button that doesn't have this state is grayed.
+ // TBSTATE_HIDDEN The button is not visible and cannot receive user input.
+ // TBSTATE_INDETERMINATE The button is grayed.
+ // TBSTATE_MARKED The button is marked. The interpretation of a marked item is dependent upon the application.
+ // TBSTATE_PRESSED The button is being clicked.
+ // TBSTATE_WRAP The button is followed by a line break.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (UINT)SendMessage(TB_GETSTATE, (WPARAM) idButton, 0L);
+ }
+
+ inline BYTE CToolBar::GetButtonStyle(int idButton) const
+ // Get the the style of the toolbar control. The following button styles are supported:
+ // TBSTYLE_BUTTON Standard pushbutton (default)
+ // TBSTYLE_SEP Separator
+ // TBSTYLE_CHECK Auto check-box button
+ // TBSTYLE_GROUP Marks the start of a group of buttons
+ // TBSTYLE_CHECKGROUP Marks the start of a group of check-box buttons
+ // TBSTYLE_DROPDOWN Creates a drop-down list button
+ // TBSTYLE_AUTOSIZE The button's width will be calculated based on the text of the button, not on the size of the image
+ // TBSTYLE_NOPREFIX The button text will not have an accelerator prefix associated with it
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int iIndex = CommandToIndex(idButton);
+ TBBUTTON tbb = {0};
+ SendMessage(TB_GETBUTTON, iIndex, (LPARAM) &tbb);
+
+ return tbb.fsStyle;
+ }
+
+ inline CString CToolBar::GetButtonText(int idButton) const
+ // Retrieves the display text of a button on a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int Length = (int)SendMessage(TB_GETBUTTONTEXT, idButton, 0);
+ CString str;
+ LPTSTR szStr = str.GetBuffer(Length +1);
+ SendMessage(TB_GETBUTTONTEXT, (LPARAM)idButton, (WPARAM)szStr);
+ str.ReleaseBuffer();
+ return str;
+ }
+
+ inline int CToolBar::GetCommandID(int iIndex) const
+ // Retrieves information about the specified button in a toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ TBBUTTON tbb = {0};
+ SendMessage(TB_GETBUTTON, iIndex, (WPARAM) &tbb);
+
+ // returns zero if failed
+ return tbb.idCommand;
+ }
+
+ inline HIMAGELIST CToolBar::GetDisabledImageList() const
+ // Retrieves the image list that a toolbar control uses to display inactive buttons.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_GETDISABLEDIMAGELIST, 0L, 0L);
+ }
+
+ inline HIMAGELIST CToolBar::GetHotImageList() const
+ // Retrieves the image list that a toolbar control uses to display hot buttons.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_GETHOTIMAGELIST, 0L, 0L);
+ }
+
+ inline int CToolBar::GetHotItem() const
+ // Retrieves the index of the hot item in a toolbar, or -1 if no hot item is set.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_GETHOTITEM, 0L, 0L);
+ }
+
+ inline HIMAGELIST CToolBar::GetImageList() const
+ // Retrieves the image list that a toolbar control uses to display buttons in their default state.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_GETIMAGELIST, 0L, 0L);
+ }
+
+ inline CRect CToolBar::GetItemRect(int iIndex) const
+ // Retrieves the bounding rectangle of a button in a toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ int iCount = (int)SendMessage(TB_BUTTONCOUNT, 0L, 0L);
+
+ if (iCount >= iIndex)
+ SendMessage(TB_GETITEMRECT, (WPARAM)iIndex, (LPARAM)&rc);
+
+ return rc;
+ }
+
+ inline CSize CToolBar::GetMaxSize() const
+ // Retrieves the total size of all of the visible buttons and separators in the toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ CSize sz;
+ SendMessage(TB_GETMAXSIZE, 0L, (LPARAM)&sz);
+
+ // This fixes a Windows bug calculating the size when TBSTYLE_DROPDOWN is used.
+ int xMaxSize = 0;
+ for (int i= 0 ; i < GetButtonCount(); ++i)
+ {
+ xMaxSize += GetItemRect(i).Width();
+ }
+
+ sz.cx = xMaxSize;
+ return sz;
+ }
+
+ inline DWORD CToolBar::GetPadding() const
+ // Returns a DWORD value that contains the horizontal padding in the low word and the vertical padding in the high word, in pixels.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(TB_GETPADDING, 0L, 0L);
+ }
+
+ inline CRect CToolBar::GetRect(int idButton) const
+ // Retrieves the bounding rectangle for a specified toolbar button.
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ SendMessage(TB_GETRECT, (WPARAM)idButton, (LPARAM)&rc);
+ return rc;
+ }
+
+ inline int CToolBar::GetRows() const
+ // Retrieves the number of rows of buttons in a toolbar with the TBSTYLE_WRAPABLE style.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_GETROWS, 0L, 0L);
+ }
+
+ inline int CToolBar::GetTextRows() const
+ // Retrieves the maximum number of text rows that can be displayed on a toolbar button.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_GETTEXTROWS, 0L, 0L);
+ }
+
+ inline HWND CToolBar::GetToolTips() const
+ // Retrieves the handle to the ToolTip control, if any, associated with the toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HWND)SendMessage(TB_GETTOOLTIPS, 0L, 0L);
+ }
+
+ inline BOOL CToolBar::HasText() const
+ {
+ assert(::IsWindow(m_hWnd));
+ BOOL bReturn = FALSE;
+
+ for (int i = 0 ; i < GetButtonCount(); ++i)
+ {
+ if (SendMessage(TB_GETBUTTONTEXT, GetCommandID(i), 0L) != -1)
+ bReturn = TRUE;
+ }
+
+ // return TRUE if any button has text
+ return bReturn;
+ }
+
+ inline BOOL CToolBar::HideButton(int idButton, BOOL fShow) const
+ //Hides or shows the specified button in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_HIDEBUTTON, (WPARAM)idButton, (LPARAM)MAKELONG (fShow, 0));
+ }
+
+ inline int CToolBar::HitTest() const
+ // Determines where a point lies in a toolbar control.
+
+ // We do our own hit test since TB_HITTEST is a bit buggy,
+ // and also doesn't work at all on earliest versions of Win95
+ {
+ assert(::IsWindow(m_hWnd));
+ CPoint pt = GetCursorPos();
+ ScreenToClient(pt);
+
+ int nButtons = (int)SendMessage(TB_BUTTONCOUNT, 0L, 0L);
+ int iButton = -1;
+
+ for (int i = 0 ; i < nButtons; ++i)
+ {
+ CRect rc = GetItemRect(i);
+ if (rc.PtInRect(pt))
+ iButton = i;
+ }
+
+ return iButton;
+ }
+
+ inline BOOL CToolBar::Indeterminate(int idButton, BOOL fIndeterminate) const
+ //Hides or shows the specified button in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_INDETERMINATE, (WPARAM)idButton, (LPARAM)MAKELONG (fIndeterminate, 0));
+ }
+
+ inline BOOL CToolBar::InsertButton(int iButton, LPTBBUTTON lpButton) const
+ // Inserts a button in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_INSERTBUTTON, (WPARAM)iButton, (LPARAM)lpButton);
+ }
+
+ inline BOOL CToolBar::IsButtonHidden(int idButton) const
+ // Determines whether the specified button in a toolbar is hidden.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ISBUTTONHIDDEN, (WPARAM)idButton, 0L);
+ }
+
+ inline BOOL CToolBar::IsButtonHighlighted(int idButton) const
+ // Checks the highlight state of a toolbar button.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ISBUTTONHIGHLIGHTED, (WPARAM)idButton, 0L);
+ }
+
+ inline BOOL CToolBar::IsButtonIndeterminate(int idButton) const
+ // Determines whether the specified button in a toolbar is indeterminate.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ISBUTTONINDETERMINATE, (WPARAM)idButton, 0L);
+ }
+
+ inline BOOL CToolBar::IsButtonPressed(int idButton) const
+ // Determines whether the specified button in a toolbar is pressed.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_ISBUTTONPRESSED, (WPARAM)idButton, 0L);
+ }
+
+ inline int CToolBar::MapAccelerator(TCHAR chAccel) const
+ // Determines whether the specified button in a toolbar is pressed.
+ {
+ assert(::IsWindow(m_hWnd));
+ int uButtonID;
+ int idButton;
+ if (SendMessage(TB_MAPACCELERATOR, (WPARAM)chAccel, (LPARAM)&uButtonID))
+ idButton = uButtonID;
+ else
+ idButton = -1;
+
+ return idButton;
+ }
+
+ inline BOOL CToolBar::MarkButton(int idButton) const
+ // Sets the highlight state of a given button in a toolbar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_MARKBUTTON, (WPARAM)idButton, 0L);
+ }
+
+ inline BOOL CToolBar::MoveButton(UINT uOldPos, UINT uNewPos) const
+ // Moves a button from one index to another.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_MOVEBUTTON, (WPARAM)uOldPos, (LPARAM)uNewPos);
+ }
+
+
+ inline void CToolBar::OnCreate()
+ {
+ // We must send this message before sending the TB_ADDBITMAP or TB_ADDBUTTONS message
+ SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0L);
+
+ // allows buttons to have a separate dropdown arrow
+ // Note: TBN_DROPDOWN notification is sent by a toolbar control when the user clicks a dropdown button
+ SendMessage(TB_SETEXTENDEDSTYLE, 0L, TBSTYLE_EX_DRAWDDARROWS);
+
+ // Turn of Double click processing (i.e. treat a double click as two single clicks)
+ DWORD dwStyle = (DWORD)GetClassLongPtr(GCL_STYLE);
+ dwStyle &= ~CS_DBLCLKS;
+ SetClassLongPtr(GCL_STYLE, dwStyle);
+
+ // Add extra styles for toolbars inside a rebar
+ if (lstrcmp(GetParent()->GetClassName(), _T("ReBarWindow32")) == 0)
+ {
+ DWORD style = (DWORD)GetWindowLongPtr(GWL_STYLE);
+ style |= CCS_NODIVIDER | CCS_NORESIZE;
+ SetWindowLongPtr(GWL_STYLE, style);
+ }
+
+ SetButtons(m_vToolBarData);
+
+ // Set rows of text to zero
+ SendMessage(TB_SETMAXTEXTROWS, 0L, 0L);
+ }
+
+ inline LRESULT CToolBar::OnCustomDraw(NMHDR* pNMHDR)
+ // With CustomDraw we manually control the drawing of each toolbar button
+ {
+ 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;
+ DWORD dwTBStyle = (DWORD)SendMessage(TB_GETSTYLE, 0L, 0L);
+ int nStyle = GetButtonStyle(dwItem);
+
+ int nButton = (int)SendMessage(TB_COMMANDTOINDEX, (WPARAM) dwItem, 0L);
+ TBBUTTON tbb = {0};
+ SendMessage(TB_GETBUTTON, nButton, (LPARAM)&tbb);
+ int iImage = (int)tbb.dwData;
+
+ // Calculate text size
+ std::vector<TCHAR> vText(MAX_MENU_STRING, _T('\0'));
+ TCHAR* pszText = &vText[0];
+ CSize TextSize;
+ if (HasText()) // Does any button have text?
+ {
+ pDrawDC->SelectObject(GetFont());
+ if (SendMessage(TB_GETBUTTONTEXT, dwItem, (LPARAM)pszText)> 0)
+ {
+ TextSize = pDrawDC->GetTextExtentPoint32(pszText, lstrlen(pszText));
+ }
+ }
+
+ // Draw outline rectangle
+ if (nState & (CDIS_HOT | CDIS_SELECTED | CDIS_CHECKED))
+ {
+ pDrawDC->CreatePen(PS_SOLID, 1, m_Theme.clrOutline);
+ pDrawDC->MoveTo(rcRect.left, rcRect.top);
+ pDrawDC->LineTo(rcRect.left, rcRect.bottom-1);
+ pDrawDC->LineTo(rcRect.right-1, rcRect.bottom-1);
+ pDrawDC->LineTo(rcRect.right-1, rcRect.top);
+ pDrawDC->LineTo(rcRect.left, rcRect.top);
+ }
+
+ // Draw filled gradient background
+ rcRect.InflateRect(-1, -1);
+ if ((nState & (CDIS_SELECTED|CDIS_CHECKED)) || (GetButtonState(dwItem) & TBSTATE_PRESSED))
+ {
+ pDrawDC->GradientFill(m_Theme.clrPressed1, m_Theme.clrPressed2, rcRect, FALSE);
+ }
+ else if (nState & CDIS_HOT)
+ {
+ pDrawDC->GradientFill(m_Theme.clrHot1, m_Theme.clrHot2, rcRect, FALSE);
+ }
+
+ // Get the appropriate image list depending on the button state
+ HIMAGELIST himlToolBar;
+ if (nState & CDIS_DISABLED)
+ {
+ himlToolBar = (HIMAGELIST)SendMessage(TB_GETDISABLEDIMAGELIST, 0L, 0L);
+ }
+ else if (nState & (CDIS_HOT | CDIS_SELECTED | CDIS_CHECKED))
+ {
+ himlToolBar = (HIMAGELIST)SendMessage(TB_GETHOTIMAGELIST, 0L, 0L);
+ if (0 == himlToolBar)
+ himlToolBar = (HIMAGELIST)SendMessage(TB_GETIMAGELIST, 0L, 0L);
+ }
+ else
+ {
+ himlToolBar = (HIMAGELIST)SendMessage(TB_GETIMAGELIST, 0L, 0L);
+ }
+
+ BOOL IsWin95 = (1400 == (GetWinVersion()) || (2400 == GetWinVersion()));
+
+ // Calculate image position
+ int cxImage = 0;
+ int cyImage = 0;
+ ImageList_GetIconSize(himlToolBar, &cxImage, &cyImage);
+
+ int yImage = (rcRect.bottom - rcRect.top - cyImage - TextSize.cy +2)/2;
+ int xImage = (rcRect.right + rcRect.left - cxImage)/2 + ((nState & (CDIS_SELECTED|CDIS_CHECKED))? 1:0);
+ if (dwTBStyle & TBSTYLE_LIST)
+ {
+ xImage = rcRect.left + (IsXPThemed()?2:4) + ((nState & CDIS_SELECTED)? 1:0);
+ yImage = (rcRect.bottom -rcRect.top - cyImage +2)/2 + ((nState & (CDIS_SELECTED|CDIS_CHECKED))? 1:0);
+ }
+
+ // Handle the TBSTYLE_DROPDOWN and BTNS_WHOLEDROPDOWN styles
+ if ((nStyle & TBSTYLE_DROPDOWN) || ((nStyle & 0x0080) && (!IsWin95)))
+ {
+ // Calculate the dropdown arrow position
+ int xAPos = (nStyle & TBSTYLE_DROPDOWN)? rcRect.right -6 : (rcRect.right + rcRect.left + cxImage + 4)/2;
+ int yAPos = (nStyle & TBSTYLE_DROPDOWN)? (rcRect.bottom - rcRect.top +1)/2 : (cyImage)/2;
+ if (dwTBStyle & TBSTYLE_LIST)
+ {
+ xAPos = (nStyle & TBSTYLE_DROPDOWN)?rcRect.right -6:rcRect.right -5;
+ yAPos = (rcRect.bottom - rcRect.top +1)/2 + ((nStyle & TBSTYLE_DROPDOWN)?0:1);
+ }
+
+ xImage -= (nStyle & TBSTYLE_DROPDOWN)?((dwTBStyle & TBSTYLE_LIST)? (IsXPThemed()?-4:0):6):((dwTBStyle & TBSTYLE_LIST)? 0:4);
+
+ // Draw separate background for dropdown arrow
+ if ((m_bDrawArrowBkgrnd) && (nState & CDIS_HOT))
+ {
+ CRect rcArrowBkgnd = rcRect;
+ rcArrowBkgnd.left = rcArrowBkgnd.right - 13;
+ pDrawDC->GradientFill(m_Theme.clrPressed1, m_Theme.clrPressed2, rcArrowBkgnd, FALSE);
+ }
+
+ m_bDrawArrowBkgrnd = FALSE;
+
+ // Manually draw the dropdown arrow
+ pDrawDC->CreatePen(PS_SOLID, 1, RGB(0,0,0));
+ for (int i = 2; i >= 0; --i)
+ {
+ pDrawDC->MoveTo(xAPos -i-1, yAPos - i+1);
+ pDrawDC->LineTo(xAPos +i, yAPos - i+1);
+ }
+
+ // Draw line between icon and dropdown arrow
+ if ((nStyle & TBSTYLE_DROPDOWN) && ((nState & CDIS_SELECTED) || nState & CDIS_HOT))
+ {
+ pDrawDC->CreatePen(PS_SOLID, 1, m_Theme.clrOutline);
+ pDrawDC->MoveTo(rcRect.right - 13, rcRect.top);
+ pDrawDC->LineTo(rcRect.right - 13, rcRect.bottom);
+ }
+ }
+
+ // Draw the button image
+ if (xImage > 0)
+ {
+ ImageList_Draw(himlToolBar, iImage, *pDrawDC, xImage, yImage, ILD_TRANSPARENT);
+ }
+
+ //Draw Text
+ if (lstrlen(pszText) > 0)
+ {
+ int iWidth = rcRect.right - rcRect.left - ((nStyle & TBSTYLE_DROPDOWN)?13:0);
+ CRect rcText(0, 0, MIN(TextSize.cx, iWidth), TextSize.cy);
+
+ int xOffset = (rcRect.right + rcRect.left - rcText.right + rcText.left - ((nStyle & TBSTYLE_DROPDOWN)? 11 : 1))/2;
+ int yOffset = yImage + cyImage +1;
+
+ if (dwTBStyle & TBSTYLE_LIST)
+ {
+ xOffset = rcRect.left + cxImage + ((nStyle & TBSTYLE_DROPDOWN)?(IsXPThemed()?10:6): 6) + ((nState & CDIS_SELECTED)? 1:0);
+ yOffset = (2+rcRect.bottom - rcRect.top - rcText.bottom + rcText.top)/2 + ((nState & CDIS_SELECTED)? 1:0);
+ rcText.right = MIN(rcText.right, rcRect.right - xOffset);
+ }
+
+ OffsetRect(&rcText, xOffset, yOffset);
+
+ int iMode = pDrawDC->SetBkMode(TRANSPARENT);
+ pDrawDC->SelectObject(GetFont());
+
+ if (nState & (CDIS_DISABLED))
+ {
+ // Draw text twice for embossed look
+ rcText.OffsetRect(1, 1);
+ pDrawDC->SetTextColor(RGB(255,255,255));
+ pDrawDC->DrawText(pszText, lstrlen(pszText), rcText, DT_LEFT);
+ rcText.OffsetRect(-1, -1);
+ pDrawDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
+ pDrawDC->DrawText(pszText, lstrlen(pszText), rcText, DT_LEFT);
+ }
+ else
+ {
+ pDrawDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
+ pDrawDC->DrawText(pszText, lstrlen(pszText), rcText, DT_LEFT | DT_END_ELLIPSIS);
+ }
+ pDrawDC->SetBkMode(iMode);
+ }
+ }
+ return CDRF_SKIPDEFAULT; // No further drawing
+ }
+ return 0L;
+ }
+
+ inline void CToolBar::OnDestroy()
+ {
+ HIMAGELIST himlToolBar = (HIMAGELIST)SendMessage(TB_GETIMAGELIST, 0L, 0L);
+ HIMAGELIST himlToolBarHot = (HIMAGELIST)SendMessage(TB_GETHOTIMAGELIST, 0L, 0L);
+ HIMAGELIST himlToolBarDis = (HIMAGELIST)SendMessage(TB_GETDISABLEDIMAGELIST, 0L, 0L);
+ ImageList_Destroy(himlToolBar);
+ ImageList_Destroy(himlToolBarHot);
+ ImageList_Destroy(himlToolBarDis);
+ }
+
+ inline LRESULT CToolBar::OnNotifyReflect(WPARAM wParam, LPARAM lParam)
+ // Notifications sent to the parent window are reflected back here
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_CUSTOMDRAW:
+ {
+ if (m_Theme.UseThemes)
+ return OnCustomDraw((LPNMHDR) lParam);
+ }
+ break;
+
+ case TBN_DROPDOWN:
+ {
+ int iItem = ((LPNMTOOLBAR) lParam)->iItem;
+
+ // a boolean expression
+ m_bDrawArrowBkgrnd = (GetButtonStyle(iItem) & TBSTYLE_DROPDOWN);
+ }
+ break;
+ }
+ return 0L;
+ }
+
+ inline void CToolBar::OnWindowPosChanging(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+
+ // Adjust size for toolbars inside a rebar
+ CWnd* pParent = GetParent();
+ if (lstrcmp(pParent->GetClassName(), _T("ReBarWindow32")) == 0)
+ {
+ ReBarTheme* pTheme = (ReBarTheme*)pParent->SendMessage(UWM_GETREBARTHEME, 0, 0);
+
+ if (pTheme && pTheme->UseThemes && pTheme->ShortBands)
+ {
+ LPWINDOWPOS pWinPos = (LPWINDOWPOS)lParam;
+ pWinPos->cx = GetMaxSize().cx+2;
+ }
+ }
+ }
+
+ inline void CToolBar::PreCreate(CREATESTRUCT &cs)
+ {
+ // Sets the CREATESTRUCT parameters prior to window creation
+ cs.style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT;
+ }
+
+ inline void CToolBar::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = TOOLBARCLASSNAME;
+ }
+
+ inline BOOL CToolBar::PressButton(int idButton, BOOL fPress) const
+ // Presses or releases the specified button in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_PRESSBUTTON, (WPARAM)idButton, (LPARAM)MAKELONG(fPress, 0));
+ }
+
+ inline BOOL CToolBar::ReplaceBitmap(UINT NewToolBarID)
+ // Replaces an existing bitmap with a new bitmap.
+
+ // Note: ReplaceBitmap supports a maximum colour depth of 8 bits (256 colours)
+ // For more colours, use an ImageList instead
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int iNumButtons = 0;
+ std::vector<UINT>::iterator iter;
+ for (iter = GetToolBarData().begin(); iter < GetToolBarData().end(); ++iter)
+ if ((*iter) != 0) ++iNumButtons;
+
+ TBREPLACEBITMAP tbrb = {0};
+ tbrb.hInstNew = GetApp()->GetResourceHandle();
+ tbrb.hInstOld = GetApp()->GetResourceHandle();
+ tbrb.nIDNew = NewToolBarID;
+ tbrb.nIDOld = m_OldToolBarID;
+ tbrb.nButtons = iNumButtons;
+
+ BOOL bResult = (BOOL)SendMessage(TB_REPLACEBITMAP, iNumButtons, (LPARAM)&tbrb);
+ if (bResult)
+ m_OldToolBarID = NewToolBarID;
+
+ return bResult;
+ }
+
+ inline void CToolBar::SaveRestore(BOOL fSave, TBSAVEPARAMS* ptbsp) const
+ // Presses or releases the specified button in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(TB_PRESSBUTTON, (WPARAM)fSave, (LPARAM)ptbsp);
+ }
+
+ inline BOOL CToolBar::SetBitmap(UINT nID)
+ // Set the button images
+ {
+ assert(::IsWindow(m_hWnd));
+
+ CBitmap Bitmap(nID);
+ assert (Bitmap.GetHandle());
+ BITMAP bm = Bitmap.GetBitmapData();
+
+ int iNumButtons = 0;
+ std::vector<UINT>::iterator iter;
+ for (iter = GetToolBarData().begin(); iter < GetToolBarData().end(); ++iter)
+ if ((*iter) != 0) ++iNumButtons;
+
+ int iImageWidth = bm.bmWidth / iNumButtons;
+ int iImageHeight = bm.bmHeight;
+
+ // Set the bitmap size first
+ SetBitmapSize(iImageWidth, iImageHeight);
+
+ BOOL bResult = FALSE;
+ if (m_OldToolBarID)
+ bResult = ReplaceBitmap(nID);
+ else
+ bResult = (BOOL)AddBitmap(nID);
+
+ return bResult;
+ }
+
+ inline BOOL CToolBar::SetBitmapSize(int cx, int cy) const
+ // Sets the size of the bitmapped images to be added to a toolbar.
+
+ // Needs to be used when the image size is not the default 16 x 15
+ // Call this function before using AddBitmap or ReplaceBitmap
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETBITMAPSIZE, 0L, MAKELONG(cx, cy));
+ }
+
+ inline int CToolBar::SetButtons(const std::vector<UINT>& vToolBarData) const
+ // Assigns a resource ID to each toolbar button
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int iImages = 0;
+ UINT iNumButtons = (UINT)vToolBarData.size();
+
+ // Remove any existing buttons
+ while (SendMessage(TB_BUTTONCOUNT, 0L, 0L) > 0)
+ {
+ if(!SendMessage(TB_DELETEBUTTON, 0L, 0L))
+ break;
+ }
+
+ if (iNumButtons > 0)
+ {
+ // TBBUTTON structure for each button in the toolbar
+ TBBUTTON tbb = {0};
+
+ for (UINT j = 0 ; j < iNumButtons; ++j)
+ {
+ ZeroMemory(&tbb, sizeof(TBBUTTON));
+
+ if (0 == vToolBarData[j])
+ {
+ tbb.fsStyle = TBSTYLE_SEP;
+ }
+ else
+ {
+ tbb.dwData = iImages;
+ tbb.iBitmap = iImages;
+ tbb.idCommand = vToolBarData[j];
+ tbb.fsState = TBSTATE_ENABLED;
+ tbb.fsStyle = TBSTYLE_BUTTON;
+ }
+
+ // Add the button to the toolbar
+ if (SendMessage(TB_ADDBUTTONS, 1L, (LPARAM)&tbb))
+ iImages++;
+ else
+ break;
+ }
+ }
+
+ return iImages;
+ }
+
+ inline BOOL CToolBar::SetButtonSize(int cx, int cy) const
+ // Sets the size of the buttons to be added to a toolbar
+ // The size can be set only before adding any buttons to the toolbar
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETBUTTONSIZE, 0L, MAKELONG(cx, cy));
+ }
+
+ inline BOOL CToolBar::SetButtonState(int idButton, UINT State) const
+ {
+ // Set the state of an individual button
+ // TBSTATE_CHECKED The button has the TBSTYLE_CHECK style and is being clicked.
+ // TBSTATE_ELLIPSES The button's text is cut off and an ellipsis is displayed.
+ // TBSTATE_ENABLED The button accepts user input. A button that doesn't have this state is grayed.
+ // TBSTATE_HIDDEN The button is not visible and cannot receive user input.
+ // TBSTATE_INDETERMINATE The button is grayed.
+ // TBSTATE_MARKED The button is marked. The interpretation of a marked item is dependent upon the application.
+ // TBSTATE_PRESSED The button is being clicked.
+ // TBSTATE_WRAP The button is followed by a line break.
+
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETSTATE, (WPARAM) idButton, (LPARAM)MAKELONG (State, 0));
+ }
+
+ inline BOOL CToolBar::SetButtonStyle(int idButton, BYTE Style) const
+ // The the style of the toolbar control. The following button styles are supported:
+ // TBSTYLE_BUTTON Standard pushbutton (default)
+ // TBSTYLE_SEP Separator
+ // TBSTYLE_CHECK Auto check-box button
+ // TBSTYLE_GROUP Marks the start of a group of buttons
+ // TBSTYLE_CHECKGROUP Marks the start of a group of check-box buttons
+ // TBSTYLE_DROPDOWN Creates a drop-down list button
+ // TBSTYLE_AUTOSIZE The button's width will be calculated based on the text of the button, not on the size of the image
+ // TBSTYLE_NOPREFIX The button text will not have an accelerator prefix associated with it
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TBBUTTONINFO tbbi = {0};
+ tbbi.cbSize = sizeof(TBBUTTONINFO);
+ tbbi.dwMask = TBIF_STYLE;
+ tbbi.fsStyle = Style;
+
+ // Note: TB_SETBUTTONINFO requires comctl32.dll version 4.71 or later
+ // i.e. Win95 with IE4 / NT with IE4 or later
+ return (BOOL)SendMessage(TB_SETBUTTONINFO, idButton, (LPARAM) &tbbi);
+ }
+
+ inline BOOL CToolBar::SetButtonText(int idButton, LPCTSTR szText)
+ // This rather convoluted approach to setting toolbar button text supports
+ // all versions of Windows, including Win95 with COMCTL32.DLL version 4.0
+ {
+ assert(::IsWindow(m_hWnd));
+ int iIndex = CommandToIndex(idButton);
+ assert(-1 != iIndex);
+
+ BOOL Succeeded = TRUE;
+ tString sString = szText;
+ std::map<tString, int>::iterator m;
+ int iString;
+
+ // Check to see if the string is already added
+ m = m_StringMap.find(sString);
+ if (m_StringMap.end() == m)
+ {
+ if (0 == m_StringMap.size())
+ {
+ // Place a blank string first in the string table, in case some
+ // buttons don't have text
+ TCHAR szString[3] = _T(" ");
+ szString[2] = _T('\0'); // Double-null terminate
+ SendMessage(TB_ADDSTRING, 0L, (LPARAM)szString);
+ }
+
+ // No index for this string exists, so create it now
+ TCHAR szBuf[80] = _T("");
+ lstrcpyn(szBuf, szText, 79);
+ szBuf[lstrlen(szBuf)+1] = _T('\0'); // Double-null terminate
+
+ iString = (int)SendMessage(TB_ADDSTRING, 0L, (LPARAM)szBuf);
+ if (-1 == iString )
+ Succeeded = FALSE;
+
+ // Save the string its index in our map
+ m_StringMap.insert(std::make_pair(sString, iString));
+ }
+ else
+ {
+ // String found, use the index from our map
+ iString = m->second;
+ }
+
+ if (Succeeded)
+ {
+ TBBUTTON tbb = {0};
+ Succeeded = (BOOL)SendMessage(TB_GETBUTTON, iIndex, (LPARAM)&tbb);
+
+ tbb.iString = iString;
+
+ // Turn off ToolBar drawing
+ SendMessage(WM_SETREDRAW, FALSE, 0L);
+
+ if (Succeeded)
+ Succeeded = (BOOL)SendMessage(TB_DELETEBUTTON, iIndex, 0L);
+
+ if (Succeeded)
+ Succeeded = (BOOL)SendMessage(TB_INSERTBUTTON, iIndex, (LPARAM)&tbb);
+
+ // Ensure the button now includes some text rows
+ if (0 == SendMessage(TB_GETTEXTROWS, 0L, 0L))
+ SendMessage(TB_SETMAXTEXTROWS, 1L, 0L);
+
+ // Turn on ToolBar drawing
+ SendMessage(WM_SETREDRAW, TRUE, 0L);
+ }
+ // Redraw button
+ CRect r = GetItemRect(iIndex);
+ InvalidateRect(&r, TRUE);
+
+ return Succeeded;
+ }
+
+ inline BOOL CToolBar::SetButtonWidth(int idButton, int nWidth) const
+ // The set button width can adjust the width of the button after it is created.
+ // This is useful when replacing a button with a ComboBox or other control.
+ // Note: TB_SETBUTTONINFO requires comctl32.dll version 4.71 or later
+ // i.e. Win95 with IE4 / NT with IE4 or later
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TBBUTTONINFO tbbi = {0};
+ tbbi.cbSize = sizeof(TBBUTTONINFO);
+ tbbi.dwMask = TBIF_SIZE;
+ tbbi.cx = (WORD)nWidth;
+ BOOL bResult = (BOOL)SendMessage(TB_SETBUTTONINFO, (WPARAM)idButton, (LPARAM)&tbbi);
+
+ // Send a changed message to the parent (used by the rebar)
+ SIZE MaxSize = GetMaxSize();
+ GetParent()->SendMessage(UWM_TOOLBAR_RESIZE, (WPARAM)m_hWnd, (LPARAM)&MaxSize);
+
+ return bResult;
+ }
+
+ inline BOOL CToolBar::SetCommandID(int iIndex, int idButton) const
+ // Sets the command identifier of a toolbar button
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETCMDID, iIndex, idButton);
+ }
+
+ inline HIMAGELIST CToolBar::SetDisableImageList(HIMAGELIST himlNewDisabled) const
+ // Sets the image list that the toolbar control will use to display disabled buttons.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_SETDISABLEDIMAGELIST, 0L, (LPARAM)himlNewDisabled);
+ }
+
+ inline DWORD CToolBar::SetDrawTextFlags(DWORD dwMask, DWORD dwDTFlags) const
+ // Sets the text drawing flags for the toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(TB_SETDRAWTEXTFLAGS, (WPARAM)dwMask, (LPARAM)dwDTFlags);
+ }
+
+ inline DWORD CToolBar::SetExtendedStyle(DWORD dwExStyle) const
+ // Sets the text drawing flags for the toolbar.
+ // Extended styles include: TBSTYLE_EX_DRAWDDARROWS, TBSTYLE_EX_HIDECLIPPEDBUTTONS, TBSTYLE_EX_DOUBLEBUFFER and TBSTYLE_EX_MIXEDBUTTONS
+ {
+ assert(::IsWindow(m_hWnd));
+ return (DWORD)SendMessage(TB_SETEXTENDEDSTYLE, 0L, (LPARAM)dwExStyle);
+ }
+
+ inline HIMAGELIST CToolBar::SetHotImageList(HIMAGELIST himlNewHot) const
+ // Sets the image list that the toolbar control will use to display hot buttons.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_SETHOTIMAGELIST, 0L, (LPARAM)himlNewHot);
+ }
+
+ inline int CToolBar::SetHotItem(int iHot) const
+ // Sets the hot item in a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (int)SendMessage(TB_SETHOTITEM, (WPARAM)iHot, 0L);
+ }
+
+ inline HIMAGELIST CToolBar::SetImageList(HIMAGELIST himlNew) const
+ // Sets the image list that the toolbar will use to display buttons that are in their default state.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HIMAGELIST)SendMessage(TB_SETIMAGELIST, 0L, (LPARAM)himlNew);
+ }
+
+ inline BOOL CToolBar::SetImages(COLORREF crMask, UINT ToolBarID, UINT ToolBarHotID, UINT ToolBarDisabledID)
+ // Either sets the imagelist or adds/replaces bitmap depending on ComCtl32.dll version
+ // Assumes the width of the button image = bitmap_size / buttons
+ // Assumes buttons have been already been added via AdddToolBarButton
+ // The colour mask is often grey RGB(192,192,192) or magenta (255,0,255);
+ // The color mask is ignored for 32bit bitmap resources
+ // The Hot and disiabled bitmap resources can be 0
+ {
+ assert(::IsWindow(m_hWnd));
+
+ // ToolBar ImageLists require Comctl32.dll version 4.7 or later
+ if (400 == GetComCtlVersion())
+ {
+ // We are using COMCTL32.DLL version 4.0, so we can't use an imagelist.
+ // Instead we simply set the bitmap.
+ return SetBitmap(ToolBarID);
+ }
+
+ int iNumButtons = 0;
+ std::vector<UINT>::iterator iter;
+ for (iter = GetToolBarData().begin(); iter < GetToolBarData().end(); ++iter)
+ if ((*iter) != 0) ++iNumButtons;
+
+ if (iNumButtons > 0)
+ {
+ // Set the button images
+ CBitmap Bitmap(ToolBarID);
+ assert(Bitmap.GetHandle());
+
+ BITMAP bm = Bitmap.GetBitmapData();
+ int iImageWidth = bm.bmWidth / iNumButtons;
+ int iImageHeight = bm.bmHeight;
+
+ HIMAGELIST himlToolBar = (HIMAGELIST)SendMessage(TB_GETIMAGELIST, 0L, 0L);
+ HIMAGELIST himlToolBarHot = (HIMAGELIST)SendMessage(TB_GETHOTIMAGELIST, 0L, 0L);
+ HIMAGELIST himlToolBarDis = (HIMAGELIST)SendMessage(TB_GETDISABLEDIMAGELIST, 0L, 0L);
+ ImageList_Destroy(himlToolBar);
+ ImageList_Destroy(himlToolBarHot);
+ ImageList_Destroy(himlToolBarDis);
+
+ himlToolBar = ImageList_Create(iImageWidth, iImageHeight, ILC_COLOR32 | ILC_MASK, iNumButtons, 0);
+ assert(himlToolBar);
+
+ ImageList_AddMasked(himlToolBar, Bitmap, crMask);
+ SendMessage(TB_SETIMAGELIST, 0L, (LPARAM)himlToolBar);
+
+ if (ToolBarHotID)
+ {
+ CBitmap BitmapHot(ToolBarHotID);
+ assert(BitmapHot);
+
+ himlToolBarHot = ImageList_Create(iImageWidth, iImageHeight, ILC_COLOR32 | ILC_MASK, iNumButtons, 0);
+ assert(himlToolBarHot);
+
+ ImageList_AddMasked(himlToolBarHot, BitmapHot, crMask);
+ SendMessage(TB_SETHOTIMAGELIST, 0L, (LPARAM)himlToolBarHot);
+ }
+
+ if (ToolBarDisabledID)
+ {
+ CBitmap BitmapDisabled(ToolBarDisabledID);
+ assert(BitmapDisabled);
+
+ himlToolBarDis = ImageList_Create(iImageWidth, iImageHeight, ILC_COLOR32 | ILC_MASK, iNumButtons, 0);
+ assert(himlToolBarDis);
+
+ ImageList_AddMasked(himlToolBarDis, BitmapDisabled, crMask);
+ SendMessage(TB_SETDISABLEDIMAGELIST, 0L, (LPARAM)himlToolBarDis);
+ }
+ else
+ {
+ himlToolBarDis = CreateDisabledImageList(himlToolBar);
+ SendMessage(TB_SETDISABLEDIMAGELIST, 0L, (LPARAM)himlToolBarDis);
+ }
+
+ // Inform the parent of the change (rebar needs this)
+ SIZE MaxSize = GetMaxSize();
+ GetParent()->SendMessage(UWM_TOOLBAR_RESIZE, (WPARAM)m_hWnd, (LPARAM)&MaxSize);
+ }
+
+ return TRUE;
+ }
+
+ inline BOOL CToolBar::SetIndent(int iIndent) const
+ // Sets the indentation for the first button in a toolbar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETINDENT, (WPARAM)iIndent, 0L);
+ }
+
+ inline BOOL CToolBar::SetMaxTextRows(int iMaxRows) const
+ // Sets the maximum number of text rows displayed on a toolbar button.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETMAXTEXTROWS, (WPARAM)iMaxRows, 0L);
+ }
+
+ inline BOOL CToolBar::SetPadding(int cx, int cy) const
+ // Sets the padding for a toolbar control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)SendMessage(TB_SETPADDING, 0L, (WPARAM)MAKELONG(cx, cy));
+ }
+
+ inline void CToolBar::SetToolBarTheme(ToolBarTheme& Theme)
+ {
+ m_Theme.UseThemes = Theme.UseThemes;
+ m_Theme.clrHot1 = Theme.clrHot1;
+ m_Theme.clrHot2 = Theme.clrHot2;
+ m_Theme.clrPressed1 = Theme.clrPressed1;
+ m_Theme.clrPressed2 = Theme.clrPressed2;
+ m_Theme.clrOutline = Theme.clrOutline;
+
+ if (IsWindow())
+ Invalidate();
+ }
+
+ inline void CToolBar::SetToolTips(HWND hwndToolTip) const
+ // Associates a ToolTip control with a toolbar.
+ {
+ assert(::IsWindow(m_hWnd));
+ SendMessage(TB_SETTOOLTIPS, (WPARAM)hwndToolTip, 0L);
+ }
+
+ inline LRESULT CToolBar::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_DESTROY:
+ OnDestroy();
+ break;
+ case UWM_GETTOOLBARTHEME:
+ {
+ ToolBarTheme& tt = GetToolBarTheme();
+ return (LRESULT)&tt;
+ }
+ case WM_WINDOWPOSCHANGING:
+ OnWindowPosChanging(wParam, lParam);
+ break;
+ }
+
+ // pass unhandled messages on for default processing
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+} // namespace Win32xx
+
+#endif // #ifndef _WIN32XX_TOOLBAR_H_
diff --git a/mmc_updater/depends/win32cpp/treeview.h b/mmc_updater/depends/win32cpp/treeview.h
new file mode 100644
index 00000000..4186e9ce
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/treeview.h
@@ -0,0 +1,624 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+
+
+#ifndef _WIN32XX_TREEVIEW_H_
+#define _WIN32XX_TREEVIEW_H_
+
+#include "wincore.h"
+#include "commctrl.h"
+
+// Disable macros from Windowsx.h
+#undef GetNextSibling
+#undef GetPrevSibling
+
+namespace Win32xx
+{
+
+ class CTreeView : public CWnd
+ {
+ public:
+ CTreeView() {}
+ virtual ~CTreeView() {}
+ virtual void PreRegisterClass(WNDCLASS &wc);
+
+// Attributes
+ COLORREF GetBkColor() const;
+ HTREEITEM GetChild(HTREEITEM hItem) const;
+ UINT GetCount() const;
+ HTREEITEM GetDropHiLightItem() const;
+ HWND GetEditControl() const;
+ HTREEITEM GetFirstVisible() const;
+ HIMAGELIST GetImageList(int iImageType) const;
+ UINT GetIndent() const;
+ COLORREF GetInsertMarkColor() const;
+ BOOL GetItem(TVITEM& Item) const;
+ DWORD_PTR GetItemData(HTREEITEM hItem) const;
+ int GetItemHeight() const;
+ BOOL GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage ) const;
+ BOOL GetItemRect(HTREEITEM hItem, CRect& rc, BOOL bTextOnly) const;
+ tString GetItemText(HTREEITEM hItem, UINT nTextMax /* = 260 */) const;
+ HTREEITEM GetLastVisible() const;
+ HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) const;
+ HTREEITEM GetNextSibling(HTREEITEM hItem) const;
+ HTREEITEM GetNextVisible(HTREEITEM hItem) const;
+ HTREEITEM GetParentItem(HTREEITEM hItem) const;
+ HTREEITEM GetPrevSibling(HTREEITEM hItem) const;
+ HTREEITEM GetPrevVisible(HTREEITEM hItem) const;
+ HTREEITEM GetRootItem() const;
+ int GetScrollTime() const;
+ HTREEITEM GetSelection() const;
+ COLORREF GetTextColor() const;
+ HWND GetToolTips() const;
+ UINT GetVisibleCount() const;
+ BOOL ItemHasChildren(HTREEITEM hItem) const;
+ COLORREF SetBkColor(COLORREF clrBk) const;
+ HIMAGELIST SetImageList(HIMAGELIST himl, int nType) const;
+ void SetIndent(int indent) const;
+ BOOL SetInsertMark(HTREEITEM hItem, BOOL fAfter = TRUE) const;
+ COLORREF SetInsertMarkColor(COLORREF clrInsertMark) const;
+ BOOL SetItem(TVITEM& Item) const;
+ BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR szText, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) const;
+ BOOL SetItemData(HTREEITEM hItem, DWORD_PTR dwData) const;
+ int SetItemHeight(SHORT cyItem) const;
+ BOOL SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage) const;
+ BOOL SetItemText(HTREEITEM hItem, LPCTSTR szText) const;
+ UINT SetScrollTime(UINT uScrollTime) const;
+ COLORREF SetTextColor(COLORREF clrText) const;
+ HWND SetToolTips(HWND hwndTooltip) const;
+
+// Operations
+ HIMAGELIST CreateDragImage(HTREEITEM hItem) const;
+ BOOL DeleteAllItems() const;
+ BOOL DeleteItem(HTREEITEM hItem) const;
+ HWND EditLabel(HTREEITEM hItem) const;
+ BOOL EndEditLabelNow(BOOL fCancel) const;
+ BOOL EnsureVisible(HTREEITEM hItem) const;
+ BOOL Expand(HTREEITEM hItem, UINT nCode) const;
+ HTREEITEM HitTest(TVHITTESTINFO& ht) const;
+ HTREEITEM InsertItem(TVINSERTSTRUCT& tvIS) const;
+ BOOL Select(HTREEITEM hitem, UINT flag) const;
+ BOOL SelectDropTarget(HTREEITEM hItem) const;
+ BOOL SelectItem(HTREEITEM hItem) const;
+ BOOL SelectSetFirstVisible(HTREEITEM hItem) const;
+ BOOL SortChildren(HTREEITEM hItem, BOOL fRecurse) const;
+ BOOL SortChildrenCB(TVSORTCB& sort, BOOL fRecurse) const;
+
+ private:
+ CTreeView(const CTreeView&); // Disable copy construction
+ CTreeView& operator = (const CTreeView&); // Disable assignment operator
+
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+
+ inline void CTreeView::PreRegisterClass(WNDCLASS &wc)
+ {
+ // Set the Window Class
+ wc.lpszClassName = WC_TREEVIEW;
+ }
+
+// Attributes
+ inline COLORREF CTreeView::GetBkColor() const
+ // Retrieves the current background color of the control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetBkColor( m_hWnd );
+ }
+
+ inline HTREEITEM CTreeView::GetChild(HTREEITEM hItem) const
+ // Retrieves the first child item of the specified tree-view item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetChild(m_hWnd, hItem);
+ }
+
+ inline UINT CTreeView::GetCount() const
+ // Retrieves a count of the items in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetCount( m_hWnd );
+ }
+
+ inline HTREEITEM CTreeView::GetDropHiLightItem() const
+ // Retrieves the tree-view item that is the target of a drag-and-drop operation.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetDropHilight(m_hWnd);
+ }
+
+ inline HWND CTreeView::GetEditControl() const
+ // Retrieves the handle to the edit control being used to edit a tree-view item's text.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetEditControl( m_hWnd );
+ }
+
+ inline HTREEITEM CTreeView::GetFirstVisible() const
+ // Retrieves the first visible item in a tree-view control window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetFirstVisible(m_hWnd);
+ }
+
+ inline HIMAGELIST CTreeView::GetImageList(int iImageType) const
+ // Retrieves the handle to the normal or state image list associated with a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetImageList( m_hWnd, iImageType );
+ }
+
+ inline UINT CTreeView::GetIndent() const
+ // Retrieves the amount, in pixels, that child items are indented relative to their parent items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetIndent( m_hWnd );
+ }
+
+ inline COLORREF CTreeView::GetInsertMarkColor() const
+ // Retrieves the color used to draw the insertion mark for the tree view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetInsertMarkColor( m_hWnd );
+ }
+
+ inline BOOL CTreeView::GetItem(TVITEM& Item) const
+ // Retrieves some or all of a tree-view item's attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetItem( m_hWnd, &Item );
+ }
+
+ inline DWORD_PTR CTreeView::GetItemData(HTREEITEM hItem) const
+ // Retrieves a tree-view item's application data.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.mask = TVIF_PARAM;
+ tvi.hItem = hItem;
+ TreeView_GetItem( m_hWnd, &tvi );
+ return tvi.lParam;
+ }
+
+ inline int CTreeView::GetItemHeight() const
+ // Retrieves the current height of the tree-view item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetItemHeight( m_hWnd );
+ }
+
+ inline BOOL CTreeView::GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage ) const
+ // Retrieves the index of the tree-view item's image and selected image.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hItem;
+ BOOL bResult = TreeView_GetItem( m_hWnd, &tvi );
+ nImage = tvi.iImage;
+ nSelectedImage = tvi.iSelectedImage;
+ return bResult;
+ }
+
+ inline BOOL CTreeView::GetItemRect(HTREEITEM hItem, CRect& rc, BOOL bTextOnly) const
+ // Retrieves the bounding rectangle for a tree-view item and indicates whether the item is visible.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetItemRect( m_hWnd, hItem, &rc, bTextOnly );
+ }
+
+ inline tString CTreeView::GetItemText(HTREEITEM hItem, UINT nTextMax /* = 260 */) const
+ // Retrieves the text for a tree-view item.
+ // Note: Although the tree-view control allows any length string to be stored
+ // as item text, only the first 260 characters are displayed.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ tString t;
+ if (nTextMax > 0)
+ {
+ TVITEM tvi = {0};
+ tvi.hItem = hItem;
+ tvi.mask = TVIF_TEXT;
+ tvi.cchTextMax = nTextMax;
+ std::vector<TCHAR> vTChar(nTextMax +1, _T('\0'));
+ TCHAR* pTCharArray = &vTChar.front();
+ tvi.pszText = pTCharArray;
+ ::SendMessage(m_hWnd, TVM_GETITEM, 0L, (LPARAM)&tvi);
+ t = tvi.pszText;
+ }
+ return t;
+ }
+
+ inline HTREEITEM CTreeView::GetLastVisible() const
+ // Retrieves the last expanded item in a tree-view control.
+ // This does not retrieve the last item visible in the tree-view window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetLastVisible(m_hWnd);
+ }
+
+ inline HTREEITEM CTreeView::GetNextItem(HTREEITEM hItem, UINT nCode) const
+ // Retrieves the tree-view item that bears the specified relationship to a specified item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetNextItem( m_hWnd, hItem, nCode);
+ }
+
+ inline HTREEITEM CTreeView::GetNextSibling(HTREEITEM hItem) const
+ // Retrieves the next sibling item of a specified item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetNextSibling(m_hWnd, hItem);
+ }
+
+ inline HTREEITEM CTreeView::GetNextVisible(HTREEITEM hItem) const
+ // Retrieves the next visible item that follows a specified item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetNextVisible(m_hWnd, hItem);
+ }
+
+ inline HTREEITEM CTreeView::GetParentItem(HTREEITEM hItem) const
+ // Retrieves the parent item of the specified tree-view item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetParent(m_hWnd, hItem);
+ }
+
+ inline HTREEITEM CTreeView::GetPrevSibling(HTREEITEM hItem) const
+ // Retrieves the previous sibling item of a specified item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetPrevSibling(m_hWnd, hItem);
+ }
+
+ inline HTREEITEM CTreeView::GetPrevVisible(HTREEITEM hItem) const
+ // Retrieves the first visible item that precedes a specified item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetPrevSibling(m_hWnd, hItem);
+ }
+
+ inline HTREEITEM CTreeView::GetRootItem() const
+ // Retrieves the topmost or very first item of the tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetRoot(m_hWnd);
+ }
+
+ inline int CTreeView::GetScrollTime() const
+ // Retrieves the maximum scroll time for the tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetScrollTime( m_hWnd );
+ }
+
+ inline HTREEITEM CTreeView::GetSelection() const
+ // Retrieves the currently selected item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetSelection(m_hWnd);
+ }
+
+ inline COLORREF CTreeView::GetTextColor() const
+ // Retrieves the current text color of the control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetTextColor( m_hWnd );
+ }
+
+ inline HWND CTreeView::GetToolTips() const
+ // Retrieves the handle to the child ToolTip control used by a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetToolTips( m_hWnd );
+ }
+
+ inline UINT CTreeView::GetVisibleCount() const
+ // Obtains the number of items that can be fully visible in the client window of a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_GetVisibleCount( m_hWnd );
+ }
+
+ inline BOOL CTreeView::ItemHasChildren(HTREEITEM hItem) const
+ // Returns true of the tree-view item has one or more children
+ {
+ assert(::IsWindow(m_hWnd));
+
+ if (TreeView_GetChild( m_hWnd, hItem ))
+ return TRUE;
+
+ return FALSE;
+ }
+
+ inline COLORREF CTreeView::SetBkColor(COLORREF clrBk) const
+ // Sets the background color of the control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetBkColor( m_hWnd, clrBk );
+ }
+
+ inline HIMAGELIST CTreeView::SetImageList(HIMAGELIST himl, int nType) const
+ // Sets the normal or state image list for a tree-view control
+ // and redraws the control using the new images.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetImageList( m_hWnd, himl, nType );
+ }
+
+ inline void CTreeView::SetIndent(int indent) const
+ // Sets the width of indentation for a tree-view control
+ // and redraws the control to reflect the new width.
+ {
+ assert(::IsWindow(m_hWnd));
+ TreeView_SetIndent( m_hWnd, indent );
+ }
+
+ inline BOOL CTreeView::SetInsertMark(HTREEITEM hItem, BOOL fAfter/* = TRUE*/) const
+ // Sets the insertion mark in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetInsertMark( m_hWnd, hItem, fAfter );
+ }
+
+ inline COLORREF CTreeView::SetInsertMarkColor(COLORREF clrInsertMark) const
+ // Sets the color used to draw the insertion mark for the tree view.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetInsertMarkColor( m_hWnd, clrInsertMark );
+ }
+
+ inline BOOL CTreeView::SetItem(TVITEM& Item) const
+ // Sets some or all of a tree-view item's attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetItem( m_hWnd, &Item );
+ }
+
+ inline BOOL CTreeView::SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR szText, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) const
+ // Sets some or all of a tree-view item's attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.hItem = hItem;
+ tvi.mask = nMask;
+ tvi.pszText = (LPTSTR)szText;
+ tvi.iImage = nImage;
+ tvi.iSelectedImage = nSelectedImage;
+ tvi.state = nState;
+ tvi.stateMask = nStateMask;
+ tvi.lParam = lParam;
+ return TreeView_SetItem( m_hWnd, &tvi );
+ }
+
+ inline BOOL CTreeView::SetItemData(HTREEITEM hItem, DWORD_PTR dwData) const
+ // Sets the tree-view item's application data.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.hItem = hItem;
+ tvi.mask = TVIF_PARAM;
+ tvi.lParam = dwData;
+ return TreeView_SetItem( m_hWnd, &tvi );
+ }
+
+ inline int CTreeView::SetItemHeight(SHORT cyItem) const
+ // Sets the height of the tree-view items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetItemHeight( m_hWnd, cyItem );
+ }
+
+ inline BOOL CTreeView::SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage) const
+ // Sets the tree-view item's application image.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.hItem = hItem;
+ tvi.iImage = nImage;
+ tvi.iSelectedImage = nSelectedImage;
+ tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ return TreeView_SetItem(m_hWnd, &tvi );
+ }
+
+ inline BOOL CTreeView::SetItemText(HTREEITEM hItem, LPCTSTR szText) const
+ // Sets the tree-view item's application text.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ TVITEM tvi = {0};
+ tvi.hItem = hItem;
+ tvi.pszText = (LPTSTR)szText;
+ tvi.mask = TVIF_TEXT;
+ return TreeView_SetItem(m_hWnd, &tvi );
+ }
+
+ inline UINT CTreeView::SetScrollTime(UINT uScrollTime) const
+ // Sets the maximum scroll time for the tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetScrollTime( m_hWnd, uScrollTime );
+ }
+
+ inline COLORREF CTreeView::SetTextColor(COLORREF clrText) const
+ // Sets the text color of the control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetTextColor( m_hWnd, clrText );
+ }
+
+ inline HWND CTreeView::SetToolTips(HWND hwndTooltip) const
+ // Sets a tree-view control's child ToolTip control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SetToolTips( m_hWnd, hwndTooltip );
+ }
+
+ // Operations
+
+ inline HIMAGELIST CTreeView::CreateDragImage(HTREEITEM hItem) const
+ // Creates a dragging bitmap for the specified item in a tree-view control.
+ // It also creates an image list for the bitmap and adds the bitmap to the image list.
+ // An application can display the image when dragging the item by using the image list functions.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_CreateDragImage( m_hWnd, hItem );
+ }
+
+ inline BOOL CTreeView::DeleteAllItems() const
+ // Deletes all items from a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_DeleteAllItems( m_hWnd );
+ }
+
+ inline BOOL CTreeView::DeleteItem(HTREEITEM hItem) const
+ // Removes an item and all its children from a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_DeleteItem( m_hWnd, hItem );
+ }
+
+ inline HWND CTreeView::EditLabel(HTREEITEM hItem) const
+ // Begins in-place editing of the specified item's text, replacing the text of the item
+ // with a single-line edit control containing the text.
+ // The specified item is implicitly selected and focused.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_EditLabel( m_hWnd, hItem );
+ }
+
+ inline BOOL CTreeView::EndEditLabelNow(BOOL fCancel) const
+ // Ends the editing of a tree-view item's label.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_EndEditLabelNow(m_hWnd, fCancel);
+ }
+
+ inline BOOL CTreeView::EnsureVisible(HTREEITEM hItem) const
+ // Ensures that a tree-view item is visible, expanding the parent item or
+ // scrolling the tree-view control, if necessary.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_EnsureVisible( m_hWnd, hItem );
+ }
+
+ inline BOOL CTreeView::Expand(HTREEITEM hItem, UINT nCode) const
+ // The TreeView_Expand macro expands or collapses the list of child items associated
+ // with the specified parent item, if any.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_Expand( m_hWnd, hItem, nCode );
+ }
+
+ inline HTREEITEM CTreeView::HitTest(TVHITTESTINFO& ht) const
+ // Determines the location of the specified point relative to the client area of a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_HitTest( m_hWnd, &ht );
+ }
+
+ inline HTREEITEM CTreeView::InsertItem(TVINSERTSTRUCT& tvIS) const
+ // Inserts a new item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_InsertItem( m_hWnd, &tvIS );
+ }
+
+ inline BOOL CTreeView::Select(HTREEITEM hitem, UINT flag) const
+ // Selects the specified tree-view item, scrolls the item into view, or redraws
+ // the item in the style used to indicate the target of a drag-and-drop operation.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_Select(m_hWnd, hitem, flag );
+ }
+
+ inline BOOL CTreeView::SelectDropTarget(HTREEITEM hItem) const
+ // Redraws a specified tree-view control item in the style used to indicate the
+ // target of a drag-and-drop operation.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SelectDropTarget(m_hWnd, hItem);
+ }
+
+ inline BOOL CTreeView::SelectItem(HTREEITEM hItem) const
+ // Selects the specified tree-view item.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SelectItem(m_hWnd, hItem);
+ }
+
+ inline BOOL CTreeView::SelectSetFirstVisible(HTREEITEM hItem) const
+ // Scrolls the tree-view control vertically to ensure that the specified item is visible.
+ // If possible, the specified item becomes the first visible item at the top of the control's window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SelectSetFirstVisible(m_hWnd, hItem);
+ }
+
+ inline BOOL CTreeView::SortChildren(HTREEITEM hItem, BOOL fRecurse) const
+ // Sorts the child items of the specified parent item in a tree-view control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SortChildren( m_hWnd, hItem, fRecurse );
+ }
+
+ inline BOOL CTreeView::SortChildrenCB(TVSORTCB& sort, BOOL fRecurse) const
+ // Sorts tree-view items using an application-defined callback function that compares the items.
+ {
+ assert(::IsWindow(m_hWnd));
+ return TreeView_SortChildrenCB( m_hWnd, &sort, fRecurse );
+ }
+
+
+} // namespace Win32xx
+
+#endif // #ifndef _WIN32XX_TREEVIEW_H_
+
diff --git a/mmc_updater/depends/win32cpp/wceframe.h b/mmc_updater/depends/win32cpp/wceframe.h
new file mode 100644
index 00000000..f3aa67ef
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/wceframe.h
@@ -0,0 +1,420 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////
+// WceFrame.h
+// Definitions for the CCmdBar and CWceFrame
+
+// These classes are provide a frame window for use on Window CE devices such
+// as Pocket PCs. The frame uses CommandBar (a control unique to the Windows CE
+// operating systems) to display the menu and toolbar.
+//
+// Use the PocketPCWceFrame generic application as the starting point for your own
+// frame based applications on the Pocket PC.
+//
+// Refer to the Scribble demo application for an example of how these classes
+// can be used.
+
+
+#ifndef _WIN32XX_WCEFRAME_H_
+#define _WIN32XX_WCEFRAME_H_
+
+
+#include "wincore.h"
+#include <commctrl.h>
+#include <vector>
+#include "default_resource.h"
+
+#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
+ #define SHELL_AYGSHELL
+#endif
+
+#ifdef SHELL_AYGSHELL
+ #include <aygshell.h>
+ #pragma comment(lib, "aygshell.lib")
+#endif // SHELL_AYGSHELL
+
+#if (_WIN32_WCE < 0x500 && defined(SHELL_AYGSHELL)) || _WIN32_WCE == 420
+ #pragma comment(lib, "ccrtrtti.lib")
+#endif
+
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////
+ // Declaration of the CCmdBar class
+ //
+ class CCmdBar : public CWnd
+ {
+ public:
+ CCmdBar();
+ virtual ~CCmdBar();
+ virtual BOOL AddAdornments(DWORD dwFlags);
+ virtual int AddBitmap(int idBitmap, int iNumImages, int iImageWidth, int iImageHeight);
+ virtual BOOL AddButtons(int nButtons, TBBUTTON* pTBButton);
+ virtual HWND Create(HWND hwndParent);
+ virtual int GetHeight() const;
+ virtual HWND InsertComboBox(int iWidth, UINT dwStyle, WORD idComboBox, WORD iButton);
+ virtual BOOL IsVisible();
+ virtual BOOL Show(BOOL fShow);
+
+ private:
+
+#ifdef SHELL_AYGSHELL
+ SHMENUBARINFO m_mbi;
+#endif
+
+ };
+
+
+ //////////////////////////////////////
+ // Declaration of the CWceFrame class
+ // A mini frame based on CCmdBar
+ class CWceFrame : public CWnd
+ {
+ public:
+ CWceFrame();
+ virtual ~CWceFrame();
+ virtual void AddToolBarButton(UINT nID);
+ CRect GetViewRect() const;
+ CCmdBar& GetMenuBar() const {return (CCmdBar&)m_MenuBar;}
+ virtual void OnActivate(WPARAM wParam, LPARAM lParam);
+ virtual void OnCreate();
+ virtual void PreCreate(CREATESTRUCT &cs);
+ virtual void RecalcLayout();
+ virtual void SetButtons(const std::vector<UINT> ToolBarData);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ protected:
+ std::vector<UINT> m_ToolBarData;
+
+ private:
+ CCmdBar m_MenuBar;
+ tString m_tsAppName;
+
+#ifdef SHELL_AYGSHELL
+ SHACTIVATEINFO m_sai;
+#endif
+
+ };
+
+ //////////////////////////////////////////
+ // Definitions for the CCmdBar class
+ // This class wraps CommandBar_Create which
+ // creates a CommandBar at the top of the window
+ inline CCmdBar::CCmdBar()
+ {
+ }
+
+ inline CCmdBar::~CCmdBar()
+ {
+ if (IsWindow())
+ ::CommandBar_Destroy(m_hWnd);
+ }
+
+
+ inline BOOL CCmdBar::AddAdornments(DWORD dwFlags)
+ {
+ BOOL bReturn = CommandBar_AddAdornments(m_hWnd, dwFlags, 0);
+
+ if (!bReturn)
+ throw CWinException(_T("AddAdornments failed"));
+
+ return bReturn;
+ }
+
+ inline int CCmdBar::AddBitmap(int idBitmap, int iNumImages, int iImageWidth, int iImageHeight)
+ {
+ HINSTANCE hInst = GetApp()->GetInstanceHandle();
+ return CommandBar_AddBitmap(m_hWnd, hInst, idBitmap, iNumImages, iImageWidth, iImageHeight);
+ }
+
+ inline BOOL CCmdBar::AddButtons(int nButtons, TBBUTTON* pTBButton)
+ {
+ BOOL bReturn = CommandBar_AddButtons(m_hWnd, nButtons, pTBButton);
+ if (!bReturn)
+ throw CWinException(_T("Failed to add buttons to commandbar"));
+
+ return bReturn;
+ }
+
+ inline HWND CCmdBar::Create(HWND hParent)
+ {
+#ifdef SHELL_AYGSHELL
+ SHMENUBARINFO mbi;
+
+ memset(&mbi, 0, sizeof(SHMENUBARINFO));
+ mbi.cbSize = sizeof(SHMENUBARINFO);
+ mbi.hwndParent = hParent;
+ mbi.nToolBarId = IDW_MAIN;
+ mbi.hInstRes = GetApp()->GetInstanceHandle();
+ mbi.nBmpId = 0;
+ mbi.cBmpImages = 0;
+
+ if (SHCreateMenuBar(&mbi))
+ {
+ m_hWnd = mbi.hwndMB;
+ }
+ else
+ throw CWinException(_T("Failed to create MenuBar"));
+
+#else
+ m_hWnd = CommandBar_Create(GetApp()->GetInstanceHandle(), hParent, IDW_MENUBAR);
+
+ if (m_hWnd == NULL)
+ throw CWinException(_T("Failed to create CommandBar"));
+
+ CommandBar_InsertMenubar(m_hWnd, GetApp()->GetInstanceHandle(), IDW_MAIN, 0);
+#endif
+ return m_hWnd;
+ }
+
+ inline int CCmdBar::GetHeight() const
+ {
+ return CommandBar_Height(m_hWnd);
+ }
+
+ inline HWND CCmdBar::InsertComboBox(int iWidth, UINT dwStyle, WORD idComboBox, WORD iButton)
+ {
+ HINSTANCE hInst = GetApp()->GetInstanceHandle();
+ HWND hWnd = CommandBar_InsertComboBox(m_hWnd, hInst, iWidth, dwStyle, idComboBox, iButton);
+
+ if (!hWnd)
+ throw CWinException(_T("InsertComboBox failed"));
+
+ return hWnd;
+ }
+
+ inline BOOL CCmdBar::IsVisible()
+ {
+ return ::CommandBar_IsVisible(m_hWnd);
+ }
+
+ inline BOOL CCmdBar::Show(BOOL fShow)
+ {
+ return ::CommandBar_Show(m_hWnd, fShow);
+ }
+
+
+ /////////////////////////////////////////
+ // Definitions for the CWceFrame class
+ // This class creates a simple frame using CCmdBar
+ inline CWceFrame::CWceFrame()
+ {
+#ifdef SHELL_AYGSHELL
+ // Initialize the shell activate info structure
+ memset (&m_sai, 0, sizeof (m_sai));
+ m_sai.cbSize = sizeof (m_sai);
+#endif
+ }
+
+ inline CWceFrame::~CWceFrame()
+ {
+ }
+
+ inline void CWceFrame::AddToolBarButton(UINT nID)
+ // Adds Resource IDs to toolbar buttons.
+ // A resource ID of 0 is a separator
+ {
+ m_ToolBarData.push_back(nID);
+ }
+
+ inline CRect CWceFrame::GetViewRect() const
+ {
+ CRect r;
+ ::GetClientRect(m_hWnd, &r);
+
+#ifndef SHELL_AYGSHELL
+ // Reduce the size of the client rectange, by the commandbar height
+ r.top += m_MenuBar.GetHeight();
+#endif
+
+ return r;
+ }
+
+ inline void CWceFrame::OnCreate()
+ {
+ // Create the Commandbar
+ m_MenuBar.Create(m_hWnd);
+
+ // Set the keyboard accelerators
+ HACCEL hAccel = LoadAccelerators(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_MAIN));
+ GetApp()->SetAccelerators(hAccel, this);
+
+ // Add the toolbar buttons
+ if (m_ToolBarData.size() > 0)
+ SetButtons(m_ToolBarData);
+
+#ifndef SHELL_AYGSHELL
+ // Add close button
+ m_MenuBar.AddAdornments(0);
+#endif
+
+ }
+
+ inline void CWceFrame::OnActivate(WPARAM wParam, LPARAM lParam)
+ {
+#ifdef SHELL_AYGSHELL
+ // Notify shell of our activate message
+ SHHandleWMActivate(m_hWnd, wParam, lParam, &m_sai, FALSE);
+
+ UINT fActive = LOWORD(wParam);
+ if ((fActive == WA_ACTIVE) || (fActive == WA_CLICKACTIVE))
+ {
+ // Reposition the window when it's activated
+ RecalcLayout();
+ }
+#endif
+ }
+
+ inline void CWceFrame::PreCreate(CREATESTRUCT &cs)
+ {
+ cs.style = WS_VISIBLE;
+ m_tsAppName = _T("Win32++ Application");
+
+ // Choose a unique class name for this app
+ if (LoadString(IDW_MAIN) != _T(""))
+ {
+ m_tsAppName = LoadString(IDW_MAIN);
+ }
+
+ cs.lpszClass = m_tsAppName.c_str();
+ }
+
+/* inline BOOL CWceFrame::PreTranslateMessage(MSG* pMsg)
+ {
+ HACCEL hAccelTable = ::LoadAccelerators(GetApp()->GetResourceHandle(), MAKEINTRESOURCE(IDW_MAIN));
+ if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
+ {
+ if (TranslateAccelerator(m_hWnd, hAccelTable, pMsg))
+ return TRUE;
+ }
+ return CWnd::PreTranslateMessage(pMsg);
+ } */
+
+ inline void CWceFrame::RecalcLayout()
+ {
+ HWND hwndCB = m_MenuBar.GetHwnd();
+ if (hwndCB)
+ {
+ CRect rc; // Desktop window size
+ CRect rcMenuBar; // MenuBar window size
+
+ ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
+ ::GetWindowRect(hwndCB, &rcMenuBar);
+ rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
+
+ MoveWindow(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
+ }
+
+ ShowWindow(TRUE);
+ UpdateWindow();
+ }
+
+ inline void CWceFrame::SetButtons(const std::vector<UINT> ToolBarData)
+ // Define the resource IDs for the toolbar like this in the Frame's constructor
+ // m_ToolBarData.push_back ( 0 ); // Separator
+ // m_ToolBarData.clear();
+ // m_ToolBarData.push_back ( IDM_FILE_NEW );
+ // m_ToolBarData.push_back ( IDM_FILE_OPEN );
+ // m_ToolBarData.push_back ( IDM_FILE_SAVE );
+
+ {
+ int iImages = 0;
+ int iNumButtons = (int)ToolBarData.size();
+
+
+ if (iNumButtons > 0)
+ {
+ // Create the TBBUTTON array for each button
+ std::vector<TBBUTTON> vTBB(iNumButtons);
+ TBBUTTON* tbbArray = &vTBB.front();
+
+ for (int j = 0 ; j < iNumButtons; j++)
+ {
+ ZeroMemory(&tbbArray[j], sizeof(TBBUTTON));
+
+ if (ToolBarData[j] == 0)
+ {
+ tbbArray[j].fsStyle = TBSTYLE_SEP;
+ }
+ else
+ {
+ tbbArray[j].iBitmap = iImages++;
+ tbbArray[j].idCommand = ToolBarData[j];
+ tbbArray[j].fsState = TBSTATE_ENABLED;
+ tbbArray[j].fsStyle = TBSTYLE_BUTTON;
+ tbbArray[j].iString = -1;
+ }
+ }
+
+ // Add the bitmap
+ GetMenuBar().AddBitmap(IDW_MAIN, iImages , 16, 16);
+
+ // Add the buttons
+ GetMenuBar().AddButtons(iNumButtons, tbbArray);
+ }
+ }
+
+ inline LRESULT CWceFrame::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch (uMsg)
+ {
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ case WM_ACTIVATE:
+ OnActivate(wParam, lParam);
+ break;
+
+#ifdef SHELL_AYGSHELL
+
+ case WM_SETTINGCHANGE:
+ SHHandleWMSettingChange(m_hWnd, wParam, lParam, &m_sai);
+ break;
+#endif
+
+ }
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+
+} // namespace Win32xx
+
+#endif // _WIN32XX_WCEFRAME_H_
+
diff --git a/mmc_updater/depends/win32cpp/wcestddef.h b/mmc_updater/depends/win32cpp/wcestddef.h
new file mode 100644
index 00000000..f7b22833
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/wcestddef.h
@@ -0,0 +1,58 @@
+
+#pragma once
+
+#pragma comment(linker, "/nodefaultlib:libc.lib")
+#pragma comment(linker, "/nodefaultlib:libcd.lib")
+
+
+#include <ceconfig.h>
+#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
+ #define SHELL_AYGSHELL
+#endif
+
+#ifdef _CE_DCOM
+ #define _ATL_APARTMENT_THREADED
+#endif
+
+#if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
+ #ifndef _DEVICE_RESOLUTION_AWARE
+ #define _DEVICE_RESOLUTION_AWARE
+ #endif
+#endif
+
+
+#if _WIN32_WCE == 420 || _WIN32_WCE == 0x420
+ // For Pocket PC 2003
+ #pragma comment(lib, "ccrtrtti.lib")
+#endif
+
+#if _MSC_VER >= 1300
+
+ // NOTE - this value is not strongly correlated to the Windows CE OS version being targeted
+ #undef WINVER
+ #define WINVER _WIN32_WCE
+
+ #ifdef _DEVICE_RESOLUTION_AWARE
+ #include "DeviceResolutionAware.h"
+ #endif
+
+ #if _WIN32_WCE < 0x500 && ( defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP) )
+ #ifdef _X86_
+ #if defined(_DEBUG)
+ #pragma comment(lib, "libcmtx86d.lib")
+ #else
+ #pragma comment(lib, "libcmtx86.lib")
+ #endif
+ #endif
+ #endif
+
+ #include <altcecrt.h>
+
+#endif// _MSC_VER >= 1300
+
+#ifdef SHELL_AYGSHELL
+ #include <aygshell.h>
+ #pragma comment(lib, "aygshell.lib")
+#endif // SHELL_AYGSHELL
+
+// TODO: reference additional headers your program requires here
diff --git a/mmc_updater/depends/win32cpp/webbrowser.h b/mmc_updater/depends/win32cpp/webbrowser.h
new file mode 100644
index 00000000..5a5b5f41
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/webbrowser.h
@@ -0,0 +1,760 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+#ifndef _WIN32XX_WEBBROWSER_H_
+#define _WIN32XX_WEBBROWSER_H_
+
+#include <exdisp.h>
+#include <ocidl.h>
+
+
+namespace Win32xx
+{
+ ///////////////////////////////////////////////////
+ // Declaration of the CAXWindow class
+ // This class implements an ActiveX control container
+ class CAXWindow : public IOleClientSite, public IOleInPlaceSite, public IOleInPlaceFrame,
+ public IOleControlSite, public IDispatch
+ {
+ public:
+ CAXWindow();
+ virtual ~CAXWindow();
+ virtual void Activate(BOOL fFocus);
+ virtual void CreateControl(BSTR bstrClsid);
+ virtual void CreateControl(CLSID clsid);
+ virtual void Remove();
+ virtual void SetParent(HWND hWndParent);
+ virtual void SetLocation(int x, int y, int width, int height);
+ virtual void SetVisible(BOOL fVisible);
+ virtual void SetStatusWindow(HWND hWndStatus);
+ virtual void TranslateKey(MSG msg);
+ IDispatch* GetDispatch();
+ IUnknown* GetUnknown();
+
+ // IUnknown Methods
+ STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject);
+ STDMETHODIMP_(ULONG) AddRef();
+ STDMETHODIMP_(ULONG) Release();
+
+ // IOleClientSite Methods
+ STDMETHODIMP SaveObject();
+ STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMk);
+ STDMETHODIMP GetContainer(LPOLECONTAINER* ppContainer);
+ STDMETHODIMP ShowObject();
+ STDMETHODIMP OnShowWindow(BOOL fShow);
+ STDMETHODIMP RequestNewObjectLayout();
+
+ // IOleWindow Methods
+ STDMETHODIMP GetWindow(HWND* phwnd);
+ STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
+
+ // IOleInPlaceSite Methods
+ STDMETHODIMP CanInPlaceActivate();
+ STDMETHODIMP OnInPlaceActivate();
+ STDMETHODIMP OnUIActivate();
+ STDMETHODIMP GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo);
+ STDMETHODIMP Scroll(SIZE scrollExtent);
+ STDMETHODIMP OnUIDeactivate(BOOL fUndoable);
+ STDMETHODIMP OnInPlaceDeactivate();
+ STDMETHODIMP DiscardUndoState();
+ STDMETHODIMP DeactivateAndUndo();
+ STDMETHODIMP OnPosRectChange(LPCRECT lprcPosRect);
+
+ // IOleInPlaceUIWindow Methods
+ STDMETHODIMP GetBorder(LPRECT lprectBorder);
+ STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS lpborderwidths);
+ STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS lpborderwidths);
+ STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR lpszObjName);
+
+ // IOleInPlaceFrame Methods
+ STDMETHODIMP InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
+ STDMETHODIMP SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject);
+ STDMETHODIMP RemoveMenus(HMENU hmenuShared);
+ STDMETHODIMP SetStatusText(LPCOLESTR pszStatusText);
+ STDMETHODIMP EnableModeless(BOOL fEnable);
+ STDMETHODIMP TranslateAccelerator(LPMSG lpmsg, WORD wID);
+
+ // IOleControlSite Methods
+ STDMETHODIMP OnControlInfoChanged();
+ STDMETHODIMP LockInPlaceActive(BOOL fLock);
+ STDMETHODIMP GetExtendedControl(IDispatch** ppDisp);
+ STDMETHODIMP TransformCoords(POINTL* pptlHimetric, POINTF* pptfContainer, DWORD dwFlags);
+ STDMETHODIMP TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers);
+ STDMETHODIMP OnFocus(BOOL fGotFocus);
+ STDMETHODIMP ShowPropertyFrame();
+
+ // IDispatch Methods
+ STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, unsigned int cNames, LCID lcid, DISPID* rgdispid);
+ STDMETHODIMP GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo** pptinfo);
+ STDMETHODIMP GetTypeInfoCount(unsigned int* pctinfo);
+ STDMETHODIMP Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexecinfo, unsigned int* puArgErr);
+
+ private:
+ ULONG m_cRefs; // ref count
+ HWND m_hWnd; // window handle of the container
+ HWND m_hWndStatus; // status window handle
+ IUnknown* m_pUnk; // IUnknown of contained object
+ CRect m_rcControl; // size of control
+ };
+
+
+ ///////////////////////////////////////////////
+ // Declaration of the CWebBrowser class
+ // This class uses an AciveX Container provided by
+ // CAXWindow to host the IWebBrower2 interface.
+ class CWebBrowser : public CWnd
+ {
+ public:
+ CWebBrowser();
+ virtual ~CWebBrowser();
+ virtual void AddWebBrowserControl(void);
+ virtual CAXWindow& GetAXWindow() const { return (CAXWindow&)m_AXContainer; }
+ virtual IWebBrowser2* GetIWebBrowser2() const { return m_pIWebBrowser2; }
+ virtual void Navigate(LPCTSTR str);
+
+ protected:
+ virtual void OnCreate();
+ virtual void OnSize(int width, int height);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ private:
+ CAXWindow m_AXContainer; // The ActiveX Container
+ IWebBrowser2* m_pIWebBrowser2;// Interface to the ActiveX web browser control
+ };
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+namespace Win32xx
+{
+ /////////////////////////////////////////
+ // Definitions for the CAXWindow class
+ //
+ inline CAXWindow::CAXWindow() : m_cRefs(1), m_hWnd(NULL), m_pUnk(NULL)
+ {
+ }
+
+ inline CAXWindow::~CAXWindow()
+ {
+ }
+
+ inline void CAXWindow::CreateControl(BSTR bstrClsid)
+ {
+ CLSID clsid;
+ CLSIDFromString(bstrClsid, &clsid);
+ CreateControl(clsid);
+ }
+
+ inline void CAXWindow::Activate(BOOL fFocus)
+ {
+ if (!m_pUnk)
+ return;
+
+ if (fFocus)
+ {
+ IOleObject* pioo;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleObject, (void**)&pioo);
+ if (FAILED(hr))
+ return;
+
+ pioo->DoVerb(OLEIVERB_UIACTIVATE, NULL, this, 0, m_hWnd, &m_rcControl);
+ pioo->Release();
+ }
+ }
+
+ inline void CAXWindow::CreateControl(CLSID clsid)
+ {
+ CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&m_pUnk);
+
+ if (!m_pUnk)
+ return;
+
+ IOleObject* pioo;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleObject, (void**)&pioo);
+ if (FAILED(hr))
+ return;
+
+ pioo->SetClientSite(this);
+ pioo->Release();
+
+ IPersistStreamInit* ppsi;
+ hr = m_pUnk->QueryInterface(IID_IPersistStreamInit, (void**)&ppsi);
+ if (SUCCEEDED(hr))
+ {
+ ppsi->InitNew();
+ ppsi->Release();
+ }
+ }
+
+ inline STDMETHODIMP_(ULONG) CAXWindow::AddRef()
+ {
+ return ++m_cRefs;
+ }
+
+ inline STDMETHODIMP CAXWindow::CanInPlaceActivate()
+ {
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::ContextSensitiveHelp(BOOL fEnterMode)
+ {
+ UNREFERENCED_PARAMETER(fEnterMode);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::DeactivateAndUndo()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::DiscardUndoState()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::EnableModeless(BOOL fEnable)
+ {
+ UNREFERENCED_PARAMETER(fEnable);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetBorder(LPRECT lprectBorder)
+ {
+ UNREFERENCED_PARAMETER(lprectBorder);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetContainer(LPOLECONTAINER* ppContainer)
+ {
+ UNREFERENCED_PARAMETER(ppContainer);
+ return E_NOINTERFACE;
+ }
+
+ inline IDispatch* CAXWindow::GetDispatch()
+ {
+ if (!m_pUnk)
+ return NULL;
+
+ HRESULT hr;
+ IDispatch* pdisp;
+
+ hr = m_pUnk->QueryInterface(IID_IDispatch, (void**)&pdisp);
+ return pdisp;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetExtendedControl(IDispatch** ppDisp)
+ {
+ if (ppDisp == NULL)
+ return E_INVALIDARG;
+
+ *ppDisp = (IDispatch*)this;
+ (*ppDisp)->AddRef();
+
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, unsigned int cNames, LCID lcid, DISPID* rgdispid)
+ {
+ UNREFERENCED_PARAMETER((IID)riid); // IID cast required for the MinGW compiler
+ UNREFERENCED_PARAMETER(rgszNames);
+ UNREFERENCED_PARAMETER(cNames);
+ UNREFERENCED_PARAMETER(lcid);
+
+ *rgdispid = DISPID_UNKNOWN;
+ return DISP_E_UNKNOWNNAME;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMk)
+ {
+ UNREFERENCED_PARAMETER(dwAssign);
+ UNREFERENCED_PARAMETER(dwWhichMoniker);
+ UNREFERENCED_PARAMETER(ppMk);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo** pptinfo)
+ {
+ UNREFERENCED_PARAMETER(itinfo);
+ UNREFERENCED_PARAMETER(lcid);
+ UNREFERENCED_PARAMETER(pptinfo);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetTypeInfoCount(unsigned int* pctinfo)
+ {
+ UNREFERENCED_PARAMETER(pctinfo);
+ return E_NOTIMPL;
+ }
+
+ inline IUnknown* CAXWindow::GetUnknown()
+ {
+ if (!m_pUnk)
+ return NULL;
+
+ m_pUnk->AddRef();
+ return m_pUnk;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetWindow(HWND* lphwnd)
+ {
+ if (!IsWindow(m_hWnd))
+ return S_FALSE;
+
+ *lphwnd = m_hWnd;
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::GetWindowContext (IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppIIPUIWin,
+ LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+ {
+ *ppFrame = (IOleInPlaceFrame*)this;
+ *ppIIPUIWin = NULL;
+
+ RECT rect;
+ GetClientRect(m_hWnd, &rect);
+ lprcPosRect->left = 0;
+ lprcPosRect->top = 0;
+ lprcPosRect->right = rect.right;
+ lprcPosRect->bottom = rect.bottom;
+
+ CopyRect(lprcClipRect, lprcPosRect);
+
+ lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
+ lpFrameInfo->fMDIApp = FALSE;
+ lpFrameInfo->hwndFrame = m_hWnd;
+ lpFrameInfo->haccel = 0;
+ lpFrameInfo->cAccelEntries = 0;
+
+ (*ppFrame)->AddRef();
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
+ {
+ UNREFERENCED_PARAMETER(hmenuShared);
+ UNREFERENCED_PARAMETER(lpMenuWidths);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexecinfo, unsigned int* puArgErr)
+ {
+ UNREFERENCED_PARAMETER(dispid);
+ UNREFERENCED_PARAMETER((IID)riid); // IID cast required for the MinGW compiler
+ UNREFERENCED_PARAMETER(lcid);
+ UNREFERENCED_PARAMETER(wFlags);
+ UNREFERENCED_PARAMETER(pdispparams);
+ UNREFERENCED_PARAMETER(pvarResult);
+ UNREFERENCED_PARAMETER(pexecinfo);
+ UNREFERENCED_PARAMETER(puArgErr);
+ return DISP_E_MEMBERNOTFOUND;
+ }
+
+ inline STDMETHODIMP CAXWindow::LockInPlaceActive(BOOL fLock)
+ {
+ UNREFERENCED_PARAMETER(fLock);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnControlInfoChanged()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnFocus(BOOL fGotFocus)
+ {
+ UNREFERENCED_PARAMETER(fGotFocus);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnInPlaceActivate()
+ {
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnInPlaceDeactivate()
+ {
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnPosRectChange(LPCRECT lprcPosRect)
+ {
+ UNREFERENCED_PARAMETER(lprcPosRect);
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnShowWindow(BOOL fShow)
+ {
+ UNREFERENCED_PARAMETER(fShow);
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnUIActivate()
+ {
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::OnUIDeactivate(BOOL fUndoable)
+ {
+ UNREFERENCED_PARAMETER(fUndoable);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::QueryInterface(REFIID riid, void** ppvObject)
+ {
+ if (!ppvObject)
+ return E_POINTER;
+
+ if (IsEqualIID(riid, IID_IOleClientSite))
+ *ppvObject = (IOleClientSite*)this;
+ else if (IsEqualIID(riid, IID_IOleInPlaceSite))
+ *ppvObject = (IOleInPlaceSite*)this;
+ else if (IsEqualIID(riid, IID_IOleInPlaceFrame))
+ *ppvObject = (IOleInPlaceFrame*)this;
+ else if (IsEqualIID(riid, IID_IOleInPlaceUIWindow))
+ *ppvObject = (IOleInPlaceUIWindow*)this;
+ else if (IsEqualIID(riid, IID_IOleControlSite))
+ *ppvObject = (IOleControlSite*)this;
+ else if (IsEqualIID(riid, IID_IOleWindow))
+ *ppvObject = this;
+ else if (IsEqualIID(riid, IID_IDispatch))
+ *ppvObject = (IDispatch*)this;
+ else if (IsEqualIID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+ inline STDMETHODIMP_(ULONG) CAXWindow::Release()
+ {
+ return --m_cRefs;
+ }
+
+ inline void CAXWindow::Remove()
+ {
+ if (!m_pUnk)
+ return;
+
+ IOleObject* pioo;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleObject, (void**)&pioo);
+ if (SUCCEEDED(hr))
+ {
+ pioo->Close(OLECLOSE_NOSAVE);
+ pioo->SetClientSite(NULL);
+ pioo->Release();
+ }
+
+ IOleInPlaceObject* pipo;
+ hr = m_pUnk->QueryInterface(IID_IOleInPlaceObject, (void**)&pipo);
+ if (SUCCEEDED(hr))
+ {
+ pipo->UIDeactivate();
+ pipo->InPlaceDeactivate();
+ pipo->Release();
+ }
+
+ m_pUnk->Release();
+ m_pUnk = NULL;
+ }
+
+ inline STDMETHODIMP CAXWindow::RemoveMenus(HMENU hmenuShared)
+ {
+ UNREFERENCED_PARAMETER(hmenuShared);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::RequestBorderSpace(LPCBORDERWIDTHS lpborderwidths)
+ {
+ UNREFERENCED_PARAMETER(lpborderwidths);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::RequestNewObjectLayout()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::SaveObject()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::Scroll(SIZE scrollExtent)
+ {
+ UNREFERENCED_PARAMETER(scrollExtent);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::SetActiveObject(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR lpszObjName)
+ {
+ UNREFERENCED_PARAMETER(pActiveObject);
+ UNREFERENCED_PARAMETER(lpszObjName);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::SetBorderSpace(LPCBORDERWIDTHS lpborderwidths)
+ {
+ UNREFERENCED_PARAMETER(lpborderwidths);
+ return E_NOTIMPL;
+ }
+
+ inline void CAXWindow::SetLocation(int x, int y, int width, int height)
+ {
+ m_rcControl.SetRect(x, y, x + width, y + height);
+
+ if (!m_pUnk)
+ return;
+
+ IOleInPlaceObject* pipo;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleInPlaceObject, (void**)&pipo);
+ if (FAILED(hr))
+ return;
+
+ pipo->SetObjectRects(&m_rcControl, &m_rcControl);
+ pipo->Release();
+ }
+
+ inline STDMETHODIMP CAXWindow::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
+ {
+ UNREFERENCED_PARAMETER(hmenuShared);
+ UNREFERENCED_PARAMETER(holemenu);
+ UNREFERENCED_PARAMETER(hwndActiveObject);
+ return E_NOTIMPL;
+ }
+
+ inline void CAXWindow::SetParent(HWND hWndParent)
+ {
+ m_hWnd = hWndParent;
+ }
+
+ inline STDMETHODIMP CAXWindow::SetStatusText(LPCOLESTR pszStatusText)
+ {
+ if (NULL == pszStatusText)
+ return E_POINTER;
+
+ #ifndef _UNICODE
+ char status[MAX_PATH];
+ // Convert the Wide string to char
+ WideCharToMultiByte(CP_ACP, 0, pszStatusText, -1, status, MAX_PATH, NULL, NULL);
+
+ if (IsWindow(m_hWndStatus))
+ SendMessage(m_hWndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)status);
+ #else
+ if (IsWindow(m_hWndStatus))
+ SendMessage(m_hWndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)pszStatusText);
+ #endif
+
+ return (S_OK);
+ }
+
+ inline void CAXWindow::SetStatusWindow(HWND hWndStatus)
+ {
+ m_hWndStatus = hWndStatus;
+ }
+
+ inline void CAXWindow::SetVisible(BOOL fVisible)
+ {
+ if (!m_pUnk)
+ return;
+
+ IOleObject* pioo;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleObject, (void**)&pioo);
+ if (FAILED(hr))
+ return;
+
+ if (fVisible)
+ {
+ pioo->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, m_hWnd, &m_rcControl);
+ pioo->DoVerb(OLEIVERB_SHOW, NULL, this, 0, m_hWnd, &m_rcControl);
+ }
+ else
+ pioo->DoVerb(OLEIVERB_HIDE, NULL, this, 0, m_hWnd, NULL);
+
+ pioo->Release();
+ }
+
+ inline STDMETHODIMP CAXWindow::ShowObject()
+ {
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::ShowPropertyFrame()
+ {
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::TransformCoords(POINTL* pptlHimetric, POINTF* pptfContainer, DWORD dwFlags)
+ {
+ UNREFERENCED_PARAMETER(pptlHimetric);
+ UNREFERENCED_PARAMETER(pptfContainer);
+ UNREFERENCED_PARAMETER(dwFlags);
+ return E_NOTIMPL;
+ }
+
+ inline STDMETHODIMP CAXWindow::TranslateAccelerator(LPMSG lpmsg, WORD wID)
+ {
+ UNREFERENCED_PARAMETER(lpmsg);
+ UNREFERENCED_PARAMETER(wID);
+ return S_OK;
+ }
+
+ inline STDMETHODIMP CAXWindow::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
+ {
+ UNREFERENCED_PARAMETER(pMsg);
+ UNREFERENCED_PARAMETER(grfModifiers);
+ return S_FALSE;
+ }
+
+ inline void CAXWindow::TranslateKey(MSG msg)
+ {
+ if (!m_pUnk)
+ return;
+
+ IOleInPlaceActiveObject* pao;
+ HRESULT hr = m_pUnk->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&pao);
+ if (FAILED(hr))
+ return;
+
+ pao->TranslateAccelerator(&msg);
+ pao->Release();
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CWebBrowser class
+ //
+ inline CWebBrowser::CWebBrowser() : m_pIWebBrowser2(0)
+ {
+ OleInitialize(NULL);
+ }
+
+ inline CWebBrowser::~CWebBrowser()
+ {
+ if (m_pIWebBrowser2)
+ {
+ m_pIWebBrowser2->Stop();
+ m_pIWebBrowser2->Release();
+ }
+
+ OleUninitialize();
+ }
+
+ inline void CWebBrowser::AddWebBrowserControl()
+ {
+ GetAXWindow().CreateControl(CLSID_WebBrowser);
+ GetAXWindow().SetParent(m_hWnd);
+ GetAXWindow().SetVisible(TRUE);
+ GetAXWindow().Activate(TRUE);
+
+ IUnknown* pUnk = GetAXWindow().GetUnknown();
+ if(pUnk)
+ {
+ // Store the pointer to the WebBrowser control
+ HRESULT hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&m_pIWebBrowser2);
+ pUnk->Release();
+
+ // Navigate to an empty page
+ if (SUCCEEDED(hr))
+ {
+ VARIANT vURL;
+ vURL.vt = VT_BSTR;
+ vURL.bstrVal = SysAllocString(L"about:blank");
+ VARIANT ve1, ve2, ve3, ve4;
+ ve1.vt = VT_EMPTY;
+ ve2.vt = VT_EMPTY;
+ ve3.vt = VT_EMPTY;
+ ve4.vt = VT_EMPTY;
+
+ m_pIWebBrowser2->Navigate2(&vURL, &ve1, &ve2, &ve3, &ve4);
+
+ VariantClear(&vURL);
+ }
+ }
+ }
+
+ inline void CWebBrowser::Navigate(LPCTSTR pTChar)
+ {
+ // Navigate to our web page
+ VARIANT vURL;
+ vURL.vt = VT_BSTR;
+ vURL.bstrVal = SysAllocString(T2W(pTChar));
+ VARIANT ve1, ve2, ve3, ve4;
+ ve1.vt = VT_EMPTY;
+ ve2.vt = VT_EMPTY;
+ ve3.vt = VT_EMPTY;
+ ve4.vt = VT_EMPTY;
+
+ GetIWebBrowser2()->Navigate2(&vURL, &ve1, &ve2, &ve3, &ve4);
+
+ VariantClear(&vURL); // Also frees memory allocated by SysAllocateString
+ }
+
+ inline void CWebBrowser::OnCreate()
+ {
+ AddWebBrowserControl();
+ }
+
+ inline void CWebBrowser::OnSize(int width, int height)
+ {
+ // position the container
+ GetAXWindow().SetLocation(0, 0, width, height);
+ }
+
+ inline LRESULT CWebBrowser::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ switch(uMsg)
+ {
+ case WM_SIZE:
+ OnSize(LOWORD(lParam), HIWORD(lParam));
+ break;
+ case WM_DESTROY:
+ GetAXWindow().Remove();
+ break;
+ }
+
+ return CWnd::WndProcDefault(uMsg, wParam, lParam);
+ }
+
+}
+
+#endif // _WIN32XX_WEBBROWSER_H_
+
diff --git a/mmc_updater/depends/win32cpp/wincore.h b/mmc_updater/depends/win32cpp/wincore.h
new file mode 100644
index 00000000..d6b1f9b6
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/wincore.h
@@ -0,0 +1,2977 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////
+// wincore.h
+// Declaration of the following classes:
+// CWinApp, CWnd, CWinException, CCriticalSection,
+// CPoint, CRect, and CSize
+//
+// This file contains the declarations for the core set of classes required to
+// create simple windows using Win32++.
+//
+// 1) CCriticalSection: This class is used internally to manage thread access
+// to shared resources. You can also use this class to lock and
+// release your own critical sections.
+//
+// 2) CWinException: This class is used internally by Win32++ to handle
+// exceptions. You can also use it to throw and catch exceptions.
+//
+// 3) WinApp: This class is used start Win32++ and run the message loop. You
+// should inherit from this class to start Win32++ in your own
+// application.
+//
+// 4) CWnd: This class is used to represent a window. It provides a means
+// of creating the window, and handling its messages. Inherit
+// from this class to define and control windows.
+//
+//
+// Note: This header file (or another Win32++ header file which includes it)
+// should be included before all other header files. It sets some
+// important macros which need to be set before including Windows.h
+// Including this file first also allows it to disable some pointless
+// warning messages (see below).
+
+
+
+#ifndef _WIN32XX_WINCORE_H_
+#define _WIN32XX_WINCORE_H_
+
+
+// Remove pointless warning messages
+#ifdef _MSC_VER
+ #pragma warning (disable : 4996) // function or variable may be unsafe (deprecated)
+ #ifndef _CRT_SECURE_NO_WARNINGS
+ #define _CRT_SECURE_NO_WARNINGS // eliminate deprecation warnings for VS2005/VS2010
+ #endif
+ #if _MSC_VER < 1500
+ #pragma warning (disable : 4511) // copy operator could not be generated
+ #pragma warning (disable : 4512) // assignment operator could not be generated
+ #pragma warning (disable : 4702) // unreachable code (bugs in Microsoft's STL)
+ #pragma warning (disable : 4786) // identifier was truncated
+ #endif
+#endif
+
+#ifdef __BORLANDC__
+ #pragma option -w-8019 // code has no effect
+ #pragma option -w-8026 // functions with exception specifiations are not expanded inline
+ #pragma option -w-8027 // function not expanded inline
+ #define STRICT 1
+#endif
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic ignored "-Wmissing-braces"
+ #pragma GCC diagnostic ignored "-Wunused-value"
+#endif
+
+#ifdef _WIN32_WCE
+ #include "wcestddef.h"
+#endif
+
+#define _WINSOCKAPI_ // Prevent winsock.h #include's.
+
+#include <assert.h>
+#include <vector>
+#include <algorithm>
+#include <string>
+#include <map>
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <shlwapi.h>
+#include "shared_ptr.h"
+//#include "winutils.h" // included later in this file
+//#include "cstring.h" // included later in this file
+//#include "gdi.h" // included later in this file
+//#include "menu.h" // included later in this file
+
+// For compilers lacking Win64 support
+#ifndef GetWindowLongPtr
+ #define GetWindowLongPtr GetWindowLong
+ #define SetWindowLongPtr SetWindowLong
+ #define GWLP_WNDPROC GWL_WNDPROC
+ #define GWLP_HINSTANCE GWL_HINSTANCE
+ #define GWLP_ID GWL_ID
+ #define GWLP_USERDATA GWL_USERDATA
+ #define DWLP_DLGPROC DWL_DLGPROC
+ #define DWLP_MSGRESULT DWL_MSGRESULT
+ #define DWLP_USER DWL_USER
+ #define DWORD_PTR DWORD
+ #define LONG_PTR LONG
+ #define ULONG_PTR LONG
+#endif
+#ifndef GetClassLongPtr
+ #define GetClassLongPtr GetClassLong
+ #define SetClassLongPtr SetClassLong
+ #define GCLP_HBRBACKGROUND GCL_HBRBACKGROUND
+ #define GCLP_HCURSOR GCL_HCURSOR
+ #define GCLP_HICON GCL_HICON
+ #define GCLP_HICONSM GCL_HICONSM
+ #define GCLP_HMODULE GCL_HMODULE
+ #define GCLP_MENUNAME GCL_MENUNAME
+ #define GCLP_WNDPROC GCL_WNDPROC
+#endif
+
+
+// Messages defined by Win32++
+#define UWM_POPUPMENU (WM_APP + 1) // Message - creates the menubar popup menu
+#define UWM_DOCK_START (WM_APP + 2) // Notification - about to start undocking
+#define UWM_DOCK_MOVE (WM_APP + 3) // Notification - undocked docker is being moved
+#define UWM_DOCK_END (WM_APP + 4) // Notification - docker has been docked
+#define UWM_BAR_START (WM_APP + 5) // Notification - docker bar selected for move
+#define UWM_BAR_MOVE (WM_APP + 6) // Notification - docker bar moved
+#define UWM_BAR_END (WM_APP + 7) // Notification - end of docker bar move
+#define UWM_UNDOCKED (WM_APP + 8) // Notification - sent by docker when undocked
+#define UWM_FRAMELOSTFOCUS (WM_APP + 9) // Notification - sent by frame to view window when focus lost
+#define UWM_FRAMEGOTFOCUS (WM_APP + 10) // Notification - sent by frame to view window when focus acquired
+#define UWM_DOCK_DESTROYED (WM_APP + 11) // Message - posted when docker is destroyed
+#define UWM_TAB_CHANGED (WM_APP + 12) // Notification - tab layout changed
+#define UWM_TOOLBAR_RESIZE (WM_APP + 13) // Message - sent by toolbar to parent. Used by the rebar
+#define UWM_UPDATE_COMMAND (WM_APP + 14) // Message - sent before a menu is displayed. Used by OnUpdate
+#define UWM_DOCK_ACTIVATED (WM_APP + 15) // Message - sent to dock ancestor when a docker is activated or deactivated.
+#define UWM_GETMENUTHEME (WM_APP + 16) // Message - returns a pointer to MenuTheme
+#define UWM_GETREBARTHEME (WM_APP + 17) // Message - returns a pointer to CToolBar
+#define UWM_GETTOOLBARTHEME (WM_APP + 18) // Message - returns a pointer to ToolBarTheme
+#define UWM_CLEANUPTEMPS (WM_APP + 19) // Message - posted to cleanup temporary CDCs
+
+
+// Automatically include the Win32xx namespace
+// define NO_USING_NAMESPACE to skip this step
+namespace Win32xx {}
+#ifndef NO_USING_NAMESPACE
+ using namespace Win32xx;
+#endif
+
+// Required for WinCE
+#ifndef TLS_OUT_OF_INDEXES
+ #define TLS_OUT_OF_INDEXES ((DWORD_PTR) -1)
+#endif
+#ifndef WM_PARENTNOTIFY
+ #define WM_PARENTNOTIFY 0x0210
+#endif
+
+
+namespace Win32xx
+{
+
+ ////////////////////////////////////////////////
+ // Forward declarations.
+ // These classes are defined later or elsewhere
+ class CDC;
+ class CGDIObject;
+ class CMenu;
+ class CWinApp;
+ class CWnd;
+ class CBitmap;
+ class CBrush;
+ class CFont;
+ class CPalette;
+ class CPen;
+ class CRgn;
+
+ // tString is a TCHAR std::string
+ typedef std::basic_string<TCHAR> tString;
+
+ // tStringStream is a TCHAR std::stringstream
+ typedef std::basic_stringstream<TCHAR> tStringStream;
+
+ // Some useful smart pointers
+ typedef Shared_Ptr<CDC> DCPtr;
+ typedef Shared_Ptr<CGDIObject> GDIPtr;
+ typedef Shared_Ptr<CMenu> MenuPtr;
+ typedef Shared_Ptr<CWnd> WndPtr;
+ typedef Shared_Ptr<CBitmap> BitmapPtr;
+ typedef Shared_Ptr<CBrush> BrushPtr;
+ typedef Shared_Ptr<CFont> FontPtr;
+ typedef Shared_Ptr<CPalette> PalettePtr;
+ typedef Shared_Ptr<CPen> PenPtr;
+ typedef Shared_Ptr<CRgn> RgnPtr;
+
+ enum Constants // Defines the maximum size for TCHAR strings
+ {
+ MAX_MENU_STRING = 80,
+ MAX_STRING_SIZE = 255,
+ };
+
+ struct CompareHDC // The comparison function object used by CWinApp::m_mapHDC
+ {
+ bool operator()(HDC const a, const HDC b) const
+ {return ((DWORD_PTR)a < (DWORD_PTR)b);}
+ };
+
+ struct CompareGDI // The comparison function object used by CWinApp::m_mapGDI
+ {
+ bool operator()(HGDIOBJ const a, const HGDIOBJ b) const
+ {return ((DWORD_PTR)a < (DWORD_PTR)b);}
+ };
+
+ struct CompareHMENU // The comparison function object used by CWinApp::m_mapHMENU
+ {
+ bool operator()(HMENU const a, const HMENU b) const
+ {return ((DWORD_PTR)a < (DWORD_PTR)b);}
+ };
+
+ struct CompareHWND // The comparison function object used by CWinApp::m_mapHWND
+ {
+ bool operator()(HWND const a, const HWND b) const
+ {return ((DWORD_PTR)a < (DWORD_PTR)b);}
+ };
+
+ struct TLSData // Used for Thread Local Storage (TLS)
+ {
+ CWnd* pCWnd; // pointer to CWnd object for Window creation
+ CWnd* pMenuBar; // pointer to CMenuBar object used for the WH_MSGFILTER hook
+ HHOOK hHook; // WH_MSGFILTER hook for CMenuBar and Modeless Dialogs
+
+ std::vector<DCPtr> vTmpDCs; // A vector of temporary CDC pointers
+ std::vector<GDIPtr> vTmpGDIs; // A vector of temporary CGDIObject pointers
+ std::vector<WndPtr> vTmpWnds; // A vector of temporary CWnd pointers
+ TLSData() : pCWnd(0), pMenuBar(0), hHook(0) {}
+
+#ifndef _WIN32_WCE
+ std::vector<MenuPtr> vTmpMenus; // A vector of temporary CMenu pointers
+#endif
+ };
+
+
+ /////////////////////////////////////////
+ // Declarations for the CCriticalSection class
+ // This class is used for thread synchronisation
+ class CCriticalSection
+ {
+ public:
+ CCriticalSection() { ::InitializeCriticalSection(&m_cs); }
+ ~CCriticalSection() { ::DeleteCriticalSection(&m_cs); }
+
+ void Lock() { ::EnterCriticalSection(&m_cs); }
+ void Release() { ::LeaveCriticalSection(&m_cs); }
+
+ private:
+ CCriticalSection ( const CCriticalSection& );
+ CCriticalSection& operator = ( const CCriticalSection& );
+
+ CRITICAL_SECTION m_cs;
+ };
+
+
+ ////////////////////////////////////////
+ // Declaration of the CWinException class
+ //
+ // Note: Each function guarantees not to throw an exception
+
+ class CWinException : public std::exception
+ {
+ public:
+ CWinException(LPCTSTR pszText) throw ();
+ ~CWinException() throw() {}
+ DWORD GetError() const throw ();
+ LPCTSTR GetErrorString() const throw ();
+ const char * what () const throw ();
+
+ private:
+ DWORD m_Error;
+ LPCTSTR m_pszText;
+ TCHAR m_szErrorString[MAX_STRING_SIZE];
+ };
+
+
+ ///////////////////////////////////
+ // Declaration of the CWinApp class
+ //
+ class CWinApp
+ {
+ // Provide these access to CWinApp's private members:
+ friend class CDC;
+ friend class CDialog;
+ friend class CGDIObject;
+ friend class CMenu;
+ friend class CMenuBar;
+ friend class CPropertyPage;
+ friend class CPropertySheet;
+ friend class CTaskDialog;
+ friend class CWnd;
+ friend CWinApp* GetApp();
+ friend CGDIObject* FromHandle(HGDIOBJ hObject);
+ friend CBitmap* FromHandle(HBITMAP hBitmap);
+ friend CBrush* FromHandle(HBRUSH hBrush);
+ friend CFont* FromHandle(HFONT hFont);
+ friend CPalette* FromHandle(HPALETTE hPalette);
+ friend CPen* FromHandle(HPEN hPen);
+ friend CRgn* FromHandle(HRGN hRgn);
+ friend CDC* FromHandle(HDC hDC);
+ friend CWnd* FromHandle(HWND hWnd);
+#ifndef _WIN32_WCE
+ friend CMenu* FromHandle(HMENU hMenu);
+#endif
+
+ typedef Shared_Ptr<TLSData> TLSDataPtr;
+
+ public:
+ CWinApp();
+ virtual ~CWinApp();
+
+ HACCEL GetAccelerators() const { return m_hAccel; }
+ HINSTANCE GetInstanceHandle() const { return m_hInstance; }
+ HINSTANCE GetResourceHandle() const { return (m_hResource ? m_hResource : m_hInstance); }
+ void SetAccelerators(HACCEL hAccel, CWnd* pWndAccel);
+ void SetResourceHandle(HINSTANCE hResource);
+
+ // These are the functions you might wish to override
+ virtual BOOL InitInstance();
+ virtual int MessageLoop();
+ virtual int Run();
+
+ protected:
+ virtual BOOL OnIdle(LONG lCount);
+ virtual BOOL PreTranslateMessage(MSG Msg);
+
+ private:
+ CWinApp(const CWinApp&); // Disable copy construction
+ CWinApp& operator = (const CWinApp&); // Disable assignment operator
+ CDC* GetCDCFromMap(HDC hDC);
+ CGDIObject* GetCGDIObjectFromMap(HGDIOBJ hObject);
+ CMenu* GetCMenuFromMap(HMENU hMenu);
+ CWnd* GetCWndFromMap(HWND hWnd);
+
+ void AddTmpDC(CDC* pDC);
+ void AddTmpGDI(CGDIObject* pObject);
+ CMenu* AddTmpMenu(HMENU hMenu);
+ CWnd* AddTmpWnd(HWND hWnd);
+ void CleanupTemps();
+ DWORD GetTlsIndex() const {return m_dwTlsIndex;}
+ void SetCallback();
+ TLSData* SetTlsIndex();
+ static CWinApp* SetnGetThis(CWinApp* pThis = 0);
+
+ std::map<HDC, CDC*, CompareHDC> m_mapHDC; // maps device context handles to CDC objects
+ std::map<HGDIOBJ, CGDIObject*, CompareGDI> m_mapGDI; // maps GDI handles to CGDIObjects.
+ std::map<HMENU, CMenu*, CompareHMENU> m_mapHMENU; // maps menu handles to CMenu objects
+ std::map<HWND, CWnd*, CompareHWND> m_mapHWND; // maps window handles to CWnd objects
+ std::vector<TLSDataPtr> m_vTLSData; // vector of TLSData smart pointers, one for each thread
+ CCriticalSection m_csMapLock; // thread synchronisation for m_mapHWND
+ CCriticalSection m_csTLSLock; // thread synchronisation for m_vTLSData
+ CCriticalSection m_csAppStart; // thread synchronisation for application startup
+ HINSTANCE m_hInstance; // handle to the applications instance
+ HINSTANCE m_hResource; // handle to the applications resources
+ DWORD m_dwTlsIndex; // Thread Local Storage index
+ WNDPROC m_Callback; // callback address of CWnd::StaticWndowProc
+ HACCEL m_hAccel; // handle to the accelerator table
+ CWnd* m_pWndAccel; // handle to the window for accelerator keys
+
+ };
+
+}
+
+#include "winutils.h"
+#include "cstring.h"
+
+
+namespace Win32xx
+{
+ ////////////////////////////////
+ // Declaration of the CWnd class
+ //
+ class CWnd
+ {
+ friend class CMDIChild;
+ friend class CDialog;
+ friend class CPropertyPage;
+ friend class CTaskDialog;
+ friend class CWinApp;
+
+ public:
+ CWnd(); // Constructor
+ virtual ~CWnd(); // Destructor
+
+ // These virtual functions can be overridden
+ virtual BOOL Attach(HWND hWnd);
+ virtual BOOL AttachDlgItem(UINT nID, CWnd* pParent);
+ virtual void CenterWindow() const;
+ virtual HWND Create(CWnd* pParent = NULL);
+ virtual HWND CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, CWnd* pParent, CMenu* pMenu, LPVOID lpParam = NULL);
+ virtual HWND CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rc, CWnd* pParent, CMenu* pMenu, LPVOID lpParam = NULL);
+ virtual void Destroy();
+ virtual HWND Detach();
+ virtual HICON SetIconLarge(int nIcon);
+ virtual HICON SetIconSmall(int nIcon);
+
+ // Attributes
+ HWND GetHwnd() const { return m_hWnd; }
+ WNDPROC GetPrevWindowProc() const { return m_PrevWindowProc; }
+
+ // Wrappers for Win32 API functions
+ // These functions aren't virtual, and shouldn't be overridden
+ CDC* BeginPaint(PAINTSTRUCT& ps) const;
+ BOOL BringWindowToTop() const;
+ LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, UINT Msg, WPARAM wParam, LPARAM lParam) const;
+ BOOL CheckDlgButton(int nIDButton, UINT uCheck) const;
+ BOOL CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton) const;
+ CWnd* ChildWindowFromPoint(POINT pt) const;
+ BOOL ClientToScreen(POINT& pt) const;
+ BOOL ClientToScreen(RECT& rc) const;
+ LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) const;
+ HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags) const;
+ HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, const RECT& rc, UINT uFlags) const;
+ BOOL DrawMenuBar() const;
+ BOOL EnableWindow(BOOL bEnable = TRUE) const;
+ BOOL EndPaint(PAINTSTRUCT& ps) const;
+ CWnd* GetActiveWindow() const;
+ CWnd* GetAncestor(UINT gaFlag = 3 /*= GA_ROOTOWNER*/) const;
+ CWnd* GetCapture() const;
+ ULONG_PTR GetClassLongPtr(int nIndex) const;
+ CString GetClassName() const;
+ CRect GetClientRect() const;
+ CDC* GetDC() const;
+ CDC* GetDCEx(HRGN hrgnClip, DWORD flags) const;
+ CWnd* GetDesktopWindow() const;
+ CWnd* GetDlgItem(int nIDDlgItem) const;
+ UINT GetDlgItemInt(int nIDDlgItem, BOOL* lpTranslated, BOOL bSigned) const;
+ CString GetDlgItemText(int nIDDlgItem) const;
+ CWnd* GetFocus() const;
+ CFont* GetFont() const;
+ HICON GetIcon(BOOL bBigIcon) const;
+ CWnd* GetNextDlgGroupItem(CWnd* pCtl, BOOL bPrevious) const;
+ CWnd* GetNextDlgTabItem(CWnd* pCtl, BOOL bPrevious) const;
+ CWnd* GetParent() const;
+ BOOL GetScrollInfo(int fnBar, SCROLLINFO& si) const;
+ CRect GetUpdateRect(BOOL bErase) const;
+ int GetUpdateRgn(CRgn* pRgn, BOOL bErase) const;
+ CWnd* GetWindow(UINT uCmd) const;
+ CDC* GetWindowDC() const;
+ LONG_PTR GetWindowLongPtr(int nIndex) const;
+ CRect GetWindowRect() const;
+ CString GetWindowText() const;
+ int GetWindowTextLength() const;
+ void Invalidate(BOOL bErase = TRUE) const;
+ BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE) const;
+ BOOL InvalidateRgn(CRgn* pRgn, BOOL bErase = TRUE) const;
+ BOOL IsChild(CWnd* pChild) const;
+ BOOL IsDialogMessage(LPMSG lpMsg) const;
+ UINT IsDlgButtonChecked(int nIDButton) const;
+ BOOL IsWindow() const;
+ BOOL IsWindowEnabled() const;
+ BOOL IsWindowVisible() const;
+ BOOL KillTimer(UINT_PTR uIDEvent) const;
+ int MessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) const;
+ void MapWindowPoints(CWnd* pWndTo, POINT& pt) const;
+ void MapWindowPoints(CWnd* pWndTo, RECT& rc) const;
+ void MapWindowPoints(CWnd* pWndTo, LPPOINT ptArray, UINT nCount) const;
+ BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE) const;
+ BOOL MoveWindow(const RECT& rc, BOOL bRepaint = TRUE) const;
+ BOOL PostMessage(UINT uMsg, WPARAM wParam = 0L, LPARAM lParam = 0L) const;
+ BOOL PostMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) const;
+ BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, CRgn* pRgn = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN) const;
+ int ReleaseDC(CDC* pDC) const;
+ BOOL ScreenToClient(POINT& Point) const;
+ BOOL ScreenToClient(RECT& rc) const;
+ LRESULT SendDlgItemMessage(int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam) const;
+ LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0L, LPARAM lParam = 0L) const;
+ LRESULT SendMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) const;
+ BOOL SendNotifyMessage(UINT Msg, WPARAM wParam, LPARAM lParam) const;
+ CWnd* SetActiveWindow() const;
+ CWnd* SetCapture() const;
+ ULONG_PTR SetClassLongPtr(int nIndex, LONG_PTR dwNewLong) const;
+ BOOL SetDlgItemInt(int nIDDlgItem, UINT uValue, BOOL bSigned) const;
+ BOOL SetDlgItemText(int nIDDlgItem, LPCTSTR lpString) const;
+ CWnd* SetFocus() const;
+ void SetFont(CFont* pFont, BOOL bRedraw = TRUE) const;
+ BOOL SetForegroundWindow() const;
+ HICON SetIcon(HICON hIcon, BOOL bBigIcon) const;
+ CWnd* SetParent(CWnd* pWndParent) const;
+ BOOL SetRedraw(BOOL bRedraw = TRUE) const;
+ int SetScrollInfo(int fnBar, const SCROLLINFO& si, BOOL fRedraw) const;
+ UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) const;
+ LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong) const;
+ BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags) const;
+ BOOL SetWindowPos(HWND hWndInsertAfter, const RECT& rc, UINT uFlags) const;
+ int SetWindowRgn(CRgn* pRgn, BOOL bRedraw = TRUE) const;
+ BOOL SetWindowText(LPCTSTR lpString) const;
+ HRESULT SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) const;
+ BOOL ShowWindow(int nCmdShow = SW_SHOWNORMAL) const;
+ BOOL UpdateWindow() const;
+ BOOL ValidateRect(LPCRECT prc) const;
+ BOOL ValidateRgn(CRgn* pRgn) const;
+ static CWnd* WindowFromPoint(POINT pt);
+
+ #ifndef _WIN32_WCE
+ BOOL CloseWindow() const;
+ int DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT uFileType) const;
+ int DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT uFiletype) const;
+ BOOL DlgDirSelectEx(LPTSTR lpString, int nCount, int nIDListBox) const;
+ BOOL DlgDirSelectComboBoxEx(LPTSTR lpString, int nCount, int nIDComboBox) const;
+ BOOL DrawAnimatedRects(int idAni, RECT& rcFrom, RECT& rcTo) const;
+ BOOL DrawCaption(CDC* pDC, RECT& rc, UINT uFlags) const;
+ BOOL EnableScrollBar(UINT uSBflags, UINT uArrows) const;
+ CWnd* GetLastActivePopup() const;
+ CMenu* GetMenu() const;
+ int GetScrollPos(int nBar) const;
+ BOOL GetScrollRange(int nBar, int& MinPos, int& MaxPos) const;
+ CMenu* GetSystemMenu(BOOL bRevert) const;
+ CWnd* GetTopWindow() const;
+ BOOL GetWindowPlacement(WINDOWPLACEMENT& pWndpl) const;
+ BOOL HiliteMenuItem(CMenu* pMenu, UINT uItemHilite, UINT uHilite) const;
+ BOOL IsIconic() const;
+ BOOL IsZoomed() const;
+ BOOL LockWindowUpdate() const;
+ BOOL OpenIcon() const;
+ void Print(CDC* pDC, DWORD dwFlags) const;
+ BOOL SetMenu(CMenu* pMenu) const;
+ BOOL ScrollWindow(int XAmount, int YAmount, LPCRECT lprcScroll, LPCRECT lprcClip) const;
+ int ScrollWindowEx(int dx, int dy, LPCRECT lprcScroll, LPCRECT lprcClip, CRgn* prgnUpdate, LPRECT lprcUpdate, UINT flags) const;
+ int SetScrollPos(int nBar, int nPos, BOOL bRedraw) const;
+ BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw) const;
+ BOOL SetWindowPlacement(const WINDOWPLACEMENT& wndpl) const;
+ BOOL ShowOwnedPopups(BOOL fShow) const;
+ BOOL ShowScrollBar(int nBar, BOOL bShow) const;
+ BOOL ShowWindowAsync(int nCmdShow) const;
+ BOOL UnLockWindowUpdate() const;
+ CWnd* WindowFromDC(CDC* pDC) const;
+
+ #ifndef WIN32_LEAN_AND_MEAN
+ void DragAcceptFiles(BOOL fAccept) const;
+ #endif
+ #endif
+
+ static LRESULT CALLBACK StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ operator HWND() const { return m_hWnd; }
+
+ protected:
+ // Override these functions as required
+ virtual LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual void OnCreate();
+ virtual void OnDraw(CDC* pDC);
+ virtual BOOL OnEraseBkgnd(CDC* pDC);
+ virtual void OnInitialUpdate();
+ virtual void OnMenuUpdate(UINT nID);
+ virtual LRESULT OnMessageReflect(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);
+ virtual LRESULT OnNotifyReflect(WPARAM wParam, LPARAM lParam);
+ virtual void PreCreate(CREATESTRUCT& cs);
+ virtual void PreRegisterClass(WNDCLASS& wc);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ HWND m_hWnd; // handle to this object's window
+
+ private:
+ CWnd(const CWnd&); // Disable copy construction
+ CWnd& operator = (const CWnd&); // Disable assignment operator
+ void AddToMap();
+ void Cleanup();
+ LRESULT MessageReflect(HWND hwndParent, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ BOOL RegisterClass(WNDCLASS& wc);
+ BOOL RemoveFromMap();
+ void Subclass(HWND hWnd);
+
+ Shared_Ptr<WNDCLASS> m_pwc; // defines initialisation parameters for PreRegisterClass
+ Shared_Ptr<CREATESTRUCT> m_pcs; // defines initialisation parameters for PreCreate and Create
+ WNDPROC m_PrevWindowProc; // pre-subclassed Window Procedure
+ BOOL m_IsTmpWnd; // True if this CWnd is a TmpWnd
+
+ }; // class CWnd
+
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#include "gdi.h"
+#include "menu.h"
+
+namespace Win32xx
+{
+
+ //////////////////////////////////////////
+ // Definitions for the CWinException class
+ //
+ inline CWinException::CWinException(LPCTSTR pszText) throw () : m_Error(::GetLastError()), m_pszText(pszText)
+ {
+ memset(m_szErrorString, 0, MAX_STRING_SIZE * sizeof(TCHAR));
+
+ if (m_Error != 0)
+ {
+ DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
+ ::FormatMessage(dwFlags, NULL, m_Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), m_szErrorString, MAX_STRING_SIZE-1, NULL);
+ }
+ }
+
+ inline DWORD CWinException::GetError() const throw ()
+ {
+ return m_Error;
+ }
+
+ inline LPCTSTR CWinException::GetErrorString() const throw ()
+ {
+ return m_szErrorString;
+ }
+
+ inline const char * CWinException::what() const throw ()
+ {
+ // Sends the last error string to the debugger (typically displayed in the IDE's output window).
+ ::OutputDebugString(m_szErrorString);
+ return "CWinException thrown";
+ }
+
+
+ ////////////////////////////////////
+ // Definitions for the CWinApp class
+ //
+
+ // To begin Win32++, inherit your application class from this one.
+ // You must run only one instance of the class inherited from this.
+ inline CWinApp::CWinApp() : m_Callback(NULL), m_hAccel(0), m_pWndAccel(0)
+ {
+ try
+ {
+ m_csAppStart.Lock();
+ assert( 0 == SetnGetThis() ); // Test if this is the first instance of CWinApp
+
+ m_dwTlsIndex = ::TlsAlloc();
+ if (m_dwTlsIndex == TLS_OUT_OF_INDEXES)
+ {
+ // We only get here in the unlikely event that all TLS indexes are already allocated by this app
+ // At least 64 TLS indexes per process are allowed. Win32++ requires only one TLS index.
+ m_csAppStart.Release();
+ throw CWinException(_T("CWinApp::CWinApp Failed to allocate TLS Index"));
+ }
+
+ SetnGetThis(this);
+ m_csAppStart.Release();
+
+ // Set the instance handle
+ #ifdef _WIN32_WCE
+ m_hInstance = (HINSTANCE)GetModuleHandle(0);
+ #else
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ VirtualQuery( (LPCVOID)SetnGetThis, &mbi, sizeof(mbi) );
+ assert(mbi.AllocationBase);
+ m_hInstance = (HINSTANCE)mbi.AllocationBase;
+ #endif
+
+ m_hResource = m_hInstance;
+ SetCallback();
+ }
+
+ catch (const CWinException &e)
+ {
+ e.what();
+ throw;
+ }
+ }
+
+ inline CWinApp::~CWinApp()
+ {
+ std::vector<TLSDataPtr>::iterator iter;
+ for (iter = m_vTLSData.begin(); iter < m_vTLSData.end(); ++iter)
+ {
+ (*iter)->vTmpDCs.clear();
+#ifndef _WIN32_WCE
+ (*iter)->vTmpMenus.clear();
+#endif
+ (*iter)->vTmpWnds.clear();
+ }
+
+ // Check that all CWnd windows are destroyed
+ std::map<HWND, CWnd*, CompareHWND>::iterator m;
+ for (m = m_mapHWND.begin(); m != m_mapHWND.end(); ++m)
+ {
+ HWND hWnd = (*m).first;
+ if (::IsWindow(hWnd))
+ ::DestroyWindow(hWnd);
+ }
+ m_mapHWND.clear();
+ m_mapGDI.clear();
+ m_mapHDC.clear();
+ m_mapHMENU.clear();
+
+ // Do remaining tidy up
+ if (m_dwTlsIndex != TLS_OUT_OF_INDEXES)
+ {
+ ::TlsSetValue(GetTlsIndex(), NULL);
+ ::TlsFree(m_dwTlsIndex);
+ }
+
+ SetnGetThis((CWinApp*)-1);
+ }
+
+ inline void CWinApp::AddTmpDC(CDC* pDC)
+ {
+ // The TmpMenus are created by GetSybMenu.
+ // They are removed by CleanupTemps
+ assert(pDC);
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+ pTLSData->vTmpDCs.push_back(pDC); // save pDC as a smart pointer
+ }
+
+ inline void CWinApp::AddTmpGDI(CGDIObject* pObject)
+ {
+ // The temporary CGDIObjects are removed by CleanupTemps
+ assert(pObject);
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+ pTLSData->vTmpGDIs.push_back(pObject); // save pObject as a smart pointer
+ }
+
+#ifndef _WIN32_WCE
+ inline CMenu* CWinApp::AddTmpMenu(HMENU hMenu)
+ {
+ // The TmpMenus are created by GetSybMenu.
+ // They are removed by CleanupTemps
+ assert(::IsMenu(hMenu));
+ assert(!GetCMenuFromMap(hMenu));
+
+ CMenu* pMenu = new CMenu;
+ pMenu->m_hMenu = hMenu;
+ m_csMapLock.Lock();
+ m_mapHMENU.insert(std::make_pair(hMenu, pMenu));
+ m_csMapLock.Release();
+ pMenu->m_IsTmpMenu = TRUE;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+ pTLSData->vTmpMenus.push_back(pMenu); // save pMenu as a smart pointer
+ return pMenu;
+ }
+#endif
+
+ inline CWnd* CWinApp::AddTmpWnd(HWND hWnd)
+ {
+ // TmpWnds are created if required to support functions like CWnd::GetParent.
+ // They are removed by CleanupTemps
+ assert(::IsWindow(hWnd));
+ assert(!GetCWndFromMap(hWnd));
+
+ CWnd* pWnd = new CWnd;
+ pWnd->m_hWnd = hWnd;
+ pWnd->AddToMap();
+ pWnd->m_IsTmpWnd = TRUE;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+ pTLSData->vTmpWnds.push_back(pWnd); // save pWnd as a smart pointer
+ return pWnd;
+ }
+
+ inline void CWinApp::CleanupTemps()
+ // Removes all Temporary CWnds and CMenus belonging to this thread
+ {
+ // Retrieve the pointer to the TLS Data
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+
+ pTLSData->vTmpDCs.clear();
+ pTLSData->vTmpGDIs.clear();
+ pTLSData->vTmpWnds.clear();
+
+
+ #ifndef _WIN32_WCE
+ pTLSData->vTmpMenus.clear();
+ #endif
+ }
+
+ inline CDC* CWinApp::GetCDCFromMap(HDC hDC)
+ {
+ // Allocate an iterator for our HWND map
+ std::map<HDC, CDC*, CompareHDC>::iterator m;
+
+ // Find the CDC pointer mapped to this HDC
+ CDC* pDC = 0;
+ m_csMapLock.Lock();
+ m = m_mapHDC.find(hDC);
+
+ if (m != m_mapHDC.end())
+ pDC = m->second;
+
+ m_csMapLock.Release();
+ return pDC;
+ }
+
+ inline CGDIObject* CWinApp::GetCGDIObjectFromMap(HGDIOBJ hObject)
+ {
+ // Allocate an iterator for our HWND map
+ std::map<HGDIOBJ, CGDIObject*, CompareGDI>::iterator m;
+
+ // Find the CGDIObject pointer mapped to this HGDIOBJ
+ CGDIObject* pObject = 0;
+ m_csMapLock.Lock();
+ m = m_mapGDI.find(hObject);
+
+ if (m != m_mapGDI.end())
+ pObject = m->second;
+
+ m_csMapLock.Release();
+ return pObject;
+ }
+
+ inline CMenu* CWinApp::GetCMenuFromMap(HMENU hMenu)
+ {
+ std::map<HMENU, CMenu*, CompareHMENU>::iterator m;
+
+ // Find the CMenu pointer mapped to this HMENU
+ CMenu* pMenu = 0;
+ m_csMapLock.Lock();
+ m = m_mapHMENU.find(hMenu);
+
+ if (m != m_mapHMENU.end())
+ pMenu = m->second;
+
+ m_csMapLock.Release();
+ return pMenu;
+ }
+
+ inline CWnd* CWinApp::GetCWndFromMap(HWND hWnd)
+ {
+ // Allocate an iterator for our HWND map
+ std::map<HWND, CWnd*, CompareHWND>::iterator m;
+
+ // Find the CWnd pointer mapped to this HWND
+ CWnd* pWnd = 0;
+ m_csMapLock.Lock();
+ m = m_mapHWND.find(hWnd);
+
+ if (m != m_mapHWND.end())
+ pWnd = m->second;
+
+ m_csMapLock.Release();
+ return pWnd;
+ }
+
+ inline BOOL CWinApp::InitInstance()
+ {
+ // InitInstance contains the initialization code for your application
+ // You should override this function with the code to run when the application starts.
+
+ // return TRUE to indicate success. FALSE will end the application
+ return TRUE;
+ }
+
+ inline int CWinApp::MessageLoop()
+ {
+ // This gets any messages queued for the application, and dispatches them.
+ MSG Msg = {0};
+ int status = 1;
+ LONG lCount = 0;
+
+ while (status != 0)
+ {
+ // While idle, perform idle processing until OnIdle returns FALSE
+ while (!::PeekMessage(&Msg, 0, 0, 0, PM_NOREMOVE) && OnIdle(lCount) == TRUE)
+ {
+ ++lCount;
+ }
+
+ lCount = 0;
+
+ // Now wait until we get a message
+ if ((status = ::GetMessage(&Msg, NULL, 0, 0)) == -1)
+ return -1;
+
+ if (!PreTranslateMessage(Msg))
+ {
+ ::TranslateMessage(&Msg);
+ ::DispatchMessage(&Msg);
+ }
+ }
+
+ return LOWORD(Msg.wParam);
+ }
+
+ inline BOOL CWinApp::OnIdle(LONG lCount)
+ {
+ if (lCount == 0)
+ CleanupTemps();
+
+ return FALSE;
+ }
+
+ inline BOOL CWinApp::PreTranslateMessage(MSG Msg)
+ {
+ // This functions is called by the MessageLoop. It processes the
+ // keyboard accelerator keys and calls CWnd::PreTranslateMessage for
+ // keyboard and mouse events.
+
+ BOOL Processed = FALSE;
+
+ // only pre-translate mouse and keyboard input events
+ if ((Msg.message >= WM_KEYFIRST && Msg.message <= WM_KEYLAST) ||
+ (Msg.message >= WM_MOUSEFIRST && Msg.message <= WM_MOUSELAST))
+ {
+ // Process keyboard accelerators
+ if (m_pWndAccel && ::TranslateAccelerator(*m_pWndAccel, m_hAccel, &Msg))
+ Processed = TRUE;
+ else
+ {
+ // Search the chain of parents for pretranslated messages.
+ for (HWND hWnd = Msg.hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
+ {
+ CWnd* pWnd = GetCWndFromMap(hWnd);
+ if (pWnd)
+ {
+ Processed = pWnd->PreTranslateMessage(&Msg);
+ if(Processed)
+ break;
+ }
+ }
+ }
+ }
+
+ return Processed;
+ }
+
+ inline int CWinApp::Run()
+ {
+ // InitInstance runs the App's initialization code
+ if (InitInstance())
+ {
+ // Dispatch the window messages
+ return MessageLoop();
+ }
+ else
+ {
+ TRACE(_T("InitInstance failed! Terminating program\n"));
+ ::PostQuitMessage(-1);
+ return -1;
+ }
+ }
+
+ inline void CWinApp::SetAccelerators(HACCEL hAccel, CWnd* pWndAccel)
+ // nID is the resource ID of the accelerator table
+ // pWndAccel is the window pointer for translated messages
+ {
+ assert (hAccel);
+ assert (pWndAccel);
+
+ m_pWndAccel = pWndAccel;
+ m_hAccel = hAccel;
+ }
+
+ inline void CWinApp::SetCallback()
+ {
+ // Registers a temporary window class so we can get the callback
+ // address of CWnd::StaticWindowProc.
+ // This technique works for all Window versions, including WinCE.
+
+ WNDCLASS wcDefault = {0};
+
+ LPCTSTR szClassName = _T("Win32++ Temporary Window Class");
+ wcDefault.hInstance = GetInstanceHandle();
+ wcDefault.lpfnWndProc = CWnd::StaticWindowProc;
+ wcDefault.lpszClassName = szClassName;
+
+ ::RegisterClass(&wcDefault);
+
+ // Retrieve the class information
+ ZeroMemory(&wcDefault, sizeof(wcDefault));
+ ::GetClassInfo(GetInstanceHandle(), szClassName, &wcDefault);
+
+ // Save the callback address of CWnd::StaticWindowProc
+ assert(wcDefault.lpfnWndProc); // Assert fails when running UNICODE build on ANSI OS.
+ m_Callback = wcDefault.lpfnWndProc;
+ ::UnregisterClass(szClassName, GetInstanceHandle());
+ }
+
+ inline CWinApp* CWinApp::SetnGetThis(CWinApp* pThis /*= 0*/)
+ {
+ // This function stores the 'this' pointer in a static variable.
+ // Once stored, it can be used later to return the 'this' pointer.
+ // CWinApp's Destructor calls this function with a value of -1.
+
+ static CWinApp* pWinApp = 0;
+
+ if ((CWinApp*)-1 == pThis)
+ pWinApp = 0;
+ else if (0 == pWinApp)
+ pWinApp = pThis;
+
+ return pWinApp;
+ }
+
+ inline void CWinApp::SetResourceHandle(HINSTANCE hResource)
+ {
+ // This function can be used to load a resource dll.
+ // A resource dll can be used to define resources in different languages.
+ // To use this function, place code like this in InitInstance
+ //
+ // HINSTANCE hResource = LoadLibrary(_T("MyResourceDLL.dll"));
+ // SetResourceHandle(hResource);
+
+ m_hResource = hResource;
+ }
+
+ inline TLSData* CWinApp::SetTlsIndex()
+ {
+ TLSData* pTLSData = (TLSData*)::TlsGetValue(GetTlsIndex());
+ if (NULL == pTLSData)
+ {
+ pTLSData = new TLSData;
+
+ m_csTLSLock.Lock();
+ m_vTLSData.push_back(pTLSData); // store as a Shared_Ptr
+ m_csTLSLock.Release();
+
+ ::TlsSetValue(GetTlsIndex(), pTLSData);
+ }
+
+ return pTLSData;
+ }
+
+
+ ////////////////////////////////////////
+ // Definitions for the CWnd class
+ //
+ inline CWnd::CWnd() : m_hWnd(NULL), m_PrevWindowProc(NULL), m_IsTmpWnd(FALSE)
+ {
+ // Note: m_hWnd is set in CWnd::CreateEx(...)
+ m_pcs = new CREATESTRUCT; // store the CREATESTRICT in a smart pointer
+ m_pwc = new WNDCLASS; // store the WNDCLASS in a smart pointer
+ ::ZeroMemory(m_pcs.get(), sizeof(CREATESTRUCT));
+ ::ZeroMemory(m_pwc.get(), sizeof(WNDCLASS));
+ }
+
+ inline CWnd::~CWnd()
+ {
+ // Destroys the window for this object and cleans up resources.
+ Destroy();
+ }
+
+ inline void CWnd::AddToMap()
+ // Store the window handle and CWnd pointer in the HWND map
+ {
+ assert( GetApp() );
+ GetApp()->m_csMapLock.Lock();
+
+ assert(::IsWindow(m_hWnd));
+ assert(!GetApp()->GetCWndFromMap(m_hWnd));
+
+ GetApp()->m_mapHWND.insert(std::make_pair(m_hWnd, this));
+ GetApp()->m_csMapLock.Release();
+ }
+
+ inline BOOL CWnd::Attach(HWND hWnd)
+ // Subclass an existing window and attach it to a CWnd
+ {
+ assert( GetApp() );
+ assert(::IsWindow(hWnd));
+
+ // Ensure this thread has the TLS index set
+ // Note: Perform the attach from the same thread as the window's message loop
+ GetApp()->SetTlsIndex();
+
+ if (m_PrevWindowProc)
+ Detach();
+
+ Subclass(hWnd);
+
+ // Store the CWnd pointer in the HWND map
+ AddToMap();
+ OnCreate();
+ OnInitialUpdate();
+
+ return TRUE;
+ }
+
+ inline BOOL CWnd::AttachDlgItem(UINT nID, CWnd* pParent)
+ // Converts a dialog item to a CWnd object
+ {
+ assert(pParent->IsWindow());
+
+ HWND hWnd = ::GetDlgItem(pParent->GetHwnd(), nID);
+ return Attach(hWnd);
+ }
+
+ inline void CWnd::CenterWindow() const
+ // Centers this window over it's parent
+ {
+
+ // required for multi-monitor support with Dev-C++ and VC6
+ #ifndef _WIN32_WCE
+ #ifndef MONITOR_DEFAULTTONEAREST
+ #define MONITOR_DEFAULTTONEAREST 0x00000002
+ #endif
+ #ifndef HMONITOR
+ DECLARE_HANDLE(HMONITOR);
+ #endif
+ #ifndef MONITORINFO
+ typedef struct tagMONITORINFO
+ {
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+ } MONITORINFO, *LPMONITORINFO;
+ #endif // MONITOR_DEFAULTTONEAREST
+ #endif // _WIN32_WCE
+
+ assert(::IsWindow(m_hWnd));
+
+ CRect rc = GetWindowRect();
+ CRect rcParent;
+ CRect rcDesktop;
+
+ // Get screen dimensions excluding task bar
+ ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0);
+
+ // Get the parent window dimensions (parent could be the desktop)
+ if (GetParent() != NULL) rcParent = GetParent()->GetWindowRect();
+ else rcParent = rcDesktop;
+
+ #ifndef _WIN32_WCE
+ // Import the GetMonitorInfo and MonitorFromWindow functions
+ HMODULE hUser32 = LoadLibrary(_T("USER32.DLL"));
+ typedef BOOL (WINAPI* LPGMI)(HMONITOR hMonitor, LPMONITORINFO lpmi);
+ typedef HMONITOR (WINAPI* LPMFW)(HWND hwnd, DWORD dwFlags);
+ LPMFW pfnMonitorFromWindow = (LPMFW)::GetProcAddress(hUser32, "MonitorFromWindow");
+ #ifdef _UNICODE
+ LPGMI pfnGetMonitorInfo = (LPGMI)::GetProcAddress(hUser32, "GetMonitorInfoW");
+ #else
+ LPGMI pfnGetMonitorInfo = (LPGMI)::GetProcAddress(hUser32, "GetMonitorInfoA");
+ #endif
+
+ // Take multi-monitor systems into account
+ if (pfnGetMonitorInfo && pfnMonitorFromWindow)
+ {
+ HMONITOR hActiveMonitor = pfnMonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
+ MONITORINFO mi = { sizeof(mi), 0};
+
+ if(pfnGetMonitorInfo(hActiveMonitor, &mi))
+ {
+ rcDesktop = mi.rcWork;
+ if (GetParent() == NULL) rcParent = mi.rcWork;
+ }
+ }
+ FreeLibrary(hUser32);
+ #endif
+
+ // Calculate point to center the dialog over the portion of parent window on this monitor
+ rcParent.IntersectRect(rcParent, rcDesktop);
+ int x = rcParent.left + (rcParent.Width() - rc.Width())/2;
+ int y = rcParent.top + (rcParent.Height() - rc.Height())/2;
+
+ // Keep the dialog wholly on the monitor display
+ x = (x < rcDesktop.left)? rcDesktop.left : x;
+ x = (x > rcDesktop.right - rc.Width())? rcDesktop.right - rc.Width() : x;
+ y = (y < rcDesktop.top) ? rcDesktop.top: y;
+ y = (y > rcDesktop.bottom - rc.Height())? rcDesktop.bottom - rc.Height() : y;
+
+ SetWindowPos(HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
+ }
+
+ inline void CWnd::Cleanup()
+ // Returns the CWnd to its default state
+ {
+ if ( GetApp() ) RemoveFromMap();
+ m_hWnd = NULL;
+ m_PrevWindowProc = NULL;
+ m_IsTmpWnd = FALSE;
+ }
+
+ inline HWND CWnd::Create(CWnd* pParent /* = NULL */)
+ // Creates the window. This is the default method of window creation.
+ {
+
+ // Test if Win32++ has been started
+ assert( GetApp() );
+
+ // Set the WNDCLASS parameters
+ PreRegisterClass(*m_pwc);
+ if (m_pwc->lpszClassName)
+ {
+ RegisterClass(*m_pwc);
+ m_pcs->lpszClass = m_pwc->lpszClassName;
+ }
+
+ // Set the CREATESTRUCT parameters
+ PreCreate(*m_pcs);
+
+ // Set the Window Class Name
+ if (!m_pcs->lpszClass)
+ m_pcs->lpszClass = _T("Win32++ Window");
+
+ // Set Parent
+ HWND hWndParent = pParent? pParent->GetHwnd() : 0;
+ if (!hWndParent && m_pcs->hwndParent)
+ hWndParent = m_pcs->hwndParent;
+
+ // Set the window style
+ DWORD dwStyle;
+ DWORD dwOverlappedStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
+ if (m_pcs->style)
+ dwStyle = m_pcs->style;
+ else
+ dwStyle = WS_VISIBLE | ((hWndParent)? WS_CHILD : dwOverlappedStyle);
+
+ // Set window size and position
+ int x = (m_pcs->cx || m_pcs->cy)? m_pcs->x : CW_USEDEFAULT;
+ int cx = (m_pcs->cx || m_pcs->cy)? m_pcs->cx : CW_USEDEFAULT;
+ int y = (m_pcs->cx || m_pcs->cy)? m_pcs->y : CW_USEDEFAULT;
+ int cy = (m_pcs->cx || m_pcs->cy)? m_pcs->cy : CW_USEDEFAULT;
+
+ // Create the window
+#ifndef _WIN32_WCE
+ CreateEx(m_pcs->dwExStyle, m_pcs->lpszClass, m_pcs->lpszName, dwStyle, x, y,
+ cx, cy, pParent, FromHandle(m_pcs->hMenu), m_pcs->lpCreateParams);
+#else
+ CreateEx(m_pcs->dwExStyle, m_pcs->lpszClass, m_pcs->lpszName, dwStyle, x, y,
+ cx, cy, pParent, 0, m_pcs->lpCreateParams);
+#endif
+
+ return m_hWnd;
+ }
+
+ inline HWND CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rc, CWnd* pParent, CMenu* pMenu, LPVOID lpParam /*= NULL*/)
+ // Creates the window by specifying all the window creation parameters
+ {
+ int x = rc.left;
+ int y = rc.top;
+ int cx = rc.right - rc.left;
+ int cy = rc.bottom - rc.top;
+ return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, x, y, cx, cy, pParent, pMenu, lpParam);
+ }
+
+ inline HWND CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, CWnd* pParent, CMenu* pMenu, LPVOID lpParam /*= NULL*/)
+ // Creates the window by specifying all the window creation parameters
+ {
+
+ assert( GetApp() ); // Test if Win32++ has been started
+ assert(!::IsWindow(m_hWnd)); // Only one window per CWnd instance allowed
+
+ try
+ {
+ // Prepare the CWnd if it has been reused
+ Destroy();
+
+ // Ensure a window class is registered
+ std::vector<TCHAR> vTChar( MAX_STRING_SIZE+1, _T('\0') );
+ TCHAR* ClassName = &vTChar[0];
+ if (0 == lpszClassName || 0 == lstrlen(lpszClassName) )
+ lstrcpyn (ClassName, _T("Win32++ Window"), MAX_STRING_SIZE);
+ else
+ // Create our own local copy of szClassName.
+ lstrcpyn(ClassName, lpszClassName, MAX_STRING_SIZE);
+
+ WNDCLASS wc = {0};
+ wc.lpszClassName = ClassName;
+ wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
+ wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+
+ // Register the window class (if not already registered)
+ if (!RegisterClass(wc))
+ throw CWinException(_T("Failed to register window class"));
+
+ HWND hWndParent = pParent? pParent->GetHwnd() : 0;
+
+ // Ensure this thread has the TLS index set
+ TLSData* pTLSData = GetApp()->SetTlsIndex();
+
+ // Store the CWnd pointer in thread local storage
+ pTLSData->pCWnd = this;
+
+ // Create window
+#ifdef _WIN32_WCE
+ m_hWnd = ::CreateWindowEx(dwExStyle, ClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight,
+ hWndParent, 0, GetApp()->GetInstanceHandle(), lpParam);
+#else
+ HMENU hMenu = pMenu? pMenu->GetHandle() : NULL;
+ m_hWnd = ::CreateWindowEx(dwExStyle, ClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight,
+ hWndParent, hMenu, GetApp()->GetInstanceHandle(), lpParam);
+#endif
+
+ // Now handle window creation failure
+ if (!m_hWnd)
+ throw CWinException(_T("Failed to Create Window"));
+
+ // Automatically subclass predefined window class types
+ ::GetClassInfo(GetApp()->GetInstanceHandle(), lpszClassName, &wc);
+ if (wc.lpfnWndProc != GetApp()->m_Callback)
+ {
+ Subclass(m_hWnd);
+
+ // Send a message to force the HWND to be added to the map
+ SendMessage(WM_NULL, 0L, 0L);
+
+ OnCreate(); // We missed the WM_CREATE message, so call OnCreate now
+ }
+
+ // Clear the CWnd pointer from TLS
+ pTLSData->pCWnd = NULL;
+ }
+
+ catch (const CWinException &e)
+ {
+ TRACE(_T("\n*** Failed to create window ***\n"));
+ e.what(); // Display the last error message.
+
+ // eat the exception (don't rethrow)
+ }
+
+ // Window creation is complete. Now call OnInitialUpdate
+ OnInitialUpdate();
+
+ return m_hWnd;
+ }
+
+ inline void CWnd::Destroy()
+ // Destroys the window and returns the CWnd back to its default state, ready for reuse.
+ {
+ if (m_IsTmpWnd)
+ m_hWnd = NULL;
+
+ if (IsWindow())
+ ::DestroyWindow(m_hWnd);
+
+ // Return the CWnd to its default state
+ Cleanup();
+ }
+
+ inline HWND CWnd::Detach()
+ // Reverse an Attach
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(0 != m_PrevWindowProc); // Only a subclassed window can be detached
+
+ SetWindowLongPtr(GWLP_WNDPROC, (LONG_PTR)m_PrevWindowProc);
+ HWND hWnd = m_hWnd;
+ Cleanup();
+
+ return hWnd;
+ }
+
+ inline LRESULT CWnd::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // Pass messages on to the appropriate default window procedure
+ // CMDIChild and CMDIFrame override this function
+ {
+ return ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
+ }
+
+ inline CWnd* CWnd::GetAncestor(UINT gaFlags /*= GA_ROOTOWNER*/) const
+ // The GetAncestor function retrieves a pointer to the ancestor (root parent)
+ // of the window. Supports Win95.
+ {
+ assert(::IsWindow(m_hWnd));
+ HWND hWnd;
+
+#if (WINVER < 0x0500) // Win2000 and above
+ UNREFERENCED_PARAMETER(gaFlags);
+ hWnd = m_hWnd;
+ HWND hWndParent = ::GetParent(hWnd);
+ while (::IsChild(hWndParent, hWnd))
+ {
+ hWnd = hWndParent;
+ hWndParent = ::GetParent(hWnd);
+ }
+#else
+ hWnd = ::GetAncestor(m_hWnd, gaFlags);
+#endif
+
+ return FromHandle(hWnd);
+
+ }
+
+ inline CString CWnd::GetClassName() const
+ // Retrieves the name of the class to which the specified window belongs.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ CString str;
+ LPTSTR szStr = str.GetBuffer(MAX_STRING_SIZE+1);
+ ::GetClassName(m_hWnd, szStr, MAX_STRING_SIZE+1);
+ str.ReleaseBuffer();
+ return str;
+ }
+
+ inline CString CWnd::GetDlgItemText(int nIDDlgItem) const
+ // Retrieves the title or text associated with a control in a dialog box.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int nLength = ::GetWindowTextLength(::GetDlgItem(m_hWnd, nIDDlgItem));
+ CString str;
+ LPTSTR szStr = str.GetBuffer(nLength+1);
+ ::GetDlgItemText(m_hWnd, nIDDlgItem, szStr, nLength+1);
+ str.ReleaseBuffer();
+ return str;
+ }
+
+ inline CString CWnd::GetWindowText() const
+ // Retrieves the text of the window's title bar.
+ {
+ assert(::IsWindow(m_hWnd));
+
+ int nLength = ::GetWindowTextLength(m_hWnd);
+ CString str;
+ LPTSTR szStr = str.GetBuffer(nLength+1);
+ ::GetWindowText(m_hWnd, szStr, nLength+1);
+ str.ReleaseBuffer();
+ return str;
+ }
+
+ inline BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Override this to handle WM_COMMAND messages, for example
+
+ // switch (LOWORD(wParam))
+ // {
+ // case IDM_FILE_NEW:
+ // OnFileNew();
+ // TRUE; // return TRUE for handled commands
+ // }
+
+ // return FALSE for unhandled commands
+ return FALSE;
+ }
+
+ inline void CWnd::OnCreate()
+ {
+ // This function is called when a WM_CREATE message is recieved
+ // Override it in your derived class to automatically perform tasks
+ // during window creation.
+ }
+
+ inline void CWnd::OnDraw(CDC* pDC)
+ // Called when part of the client area of the window needs to be drawn
+ {
+ UNREFERENCED_PARAMETER(pDC);
+
+ // Override this function in your derived class to perform drawing tasks.
+ }
+
+ inline BOOL CWnd::OnEraseBkgnd(CDC* pDC)
+ // Called when the background of the window's client area needs to be erased.
+ {
+ UNREFERENCED_PARAMETER(pDC);
+
+ // Override this function in your derived class to perform drawing tasks.
+
+ // Return Value: Return FALSE to also permit default erasure of the background
+ // Return TRUE to prevent default erasure of the background
+
+ return FALSE;
+ }
+
+
+ inline void CWnd::OnInitialUpdate()
+ {
+ // This function is called automatically once the window is created
+ // Override it in your derived class to automatically perform tasks
+ // after window creation.
+ }
+
+ inline LRESULT CWnd::MessageReflect(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // A function used to call OnMessageReflect. You shouldn't need to call or
+ // override this function.
+
+ HWND hWnd = NULL;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORSCROLLBAR:
+ case WM_CTLCOLORSTATIC:
+ case WM_CHARTOITEM:
+ case WM_VKEYTOITEM:
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ hWnd = (HWND)lParam;
+ break;
+
+ case WM_DRAWITEM:
+ case WM_MEASUREITEM:
+ case WM_DELETEITEM:
+ case WM_COMPAREITEM:
+ hWnd = ::GetDlgItem(hWndParent, (int)wParam);
+ break;
+
+ case WM_PARENTNOTIFY:
+ switch(LOWORD(wParam))
+ {
+ case WM_CREATE:
+ case WM_DESTROY:
+ hWnd = (HWND)lParam;
+ break;
+ }
+ }
+
+ CWnd* Wnd = GetApp()->GetCWndFromMap(hWnd);
+
+ if (Wnd != NULL)
+ return Wnd->OnMessageReflect(uMsg, wParam, lParam);
+
+ return 0L;
+ }
+
+ inline LRESULT CWnd::OnMessageReflect(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(uMsg);
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+ // This function processes those special messages (see above) sent
+ // by some older controls, and reflects them back to the originating CWnd object.
+ // Override this function in your derrived class to handle these special messages.
+
+ // Your overriding function should look like this ...
+
+ // switch (uMsg)
+ // {
+ // Handle your reflected messages here
+ // }
+
+ // return 0L for unhandled messages
+ return 0L;
+ }
+
+ inline LRESULT CWnd::OnNotify(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // You can use either OnNotifyReflect or OnNotify to handle notifications
+ // Override OnNotifyReflect to handle notifications in the CWnd class that
+ // generated the notification. OR
+ // Override OnNotify to handle notifications in the PARENT of the CWnd class
+ // that generated the notification.
+
+ // Your overriding function should look like this ...
+
+ // switch (((LPNMHDR)lParam)->code)
+ // {
+ // Handle your notifications from the CHILD window here
+ // Return the value recommended by the Windows API documentation.
+ // For many notifications, the return value doesn't matter, but for some it does.
+ // }
+
+ // return 0L for unhandled notifications
+ return 0L;
+ }
+
+ inline LRESULT CWnd::OnNotifyReflect(WPARAM wParam, LPARAM lParam)
+ {
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+
+ // Override OnNotifyReflect to handle notifications in the CWnd class that
+ // generated the notification.
+
+ // Your overriding function should look like this ...
+
+ // switch (((LPNMHDR)lParam)->code)
+ // {
+ // Handle your notifications from this window here
+ // Return the value recommended by the Windows API documentation.
+ // }
+
+ // return 0L for unhandled notifications
+ return 0L;
+ }
+
+ inline void CWnd::OnMenuUpdate(UINT nID)
+ // Called when menu items are about to be displayed
+ {
+ UNREFERENCED_PARAMETER(nID);
+
+ // Override this function to modify the behaviour of menu items,
+ // such as adding or removing checkmarks
+ }
+
+ inline void CWnd::PreCreate(CREATESTRUCT& cs)
+ // Called by CWnd::Create to set some window parameters
+ {
+ // Test if Win32++ has been started
+ assert(GetApp()); // Test if Win32++ has been started
+
+ m_pcs->cx = cs.cx;
+ m_pcs->cy = cs.cy;
+ m_pcs->dwExStyle = cs.dwExStyle;
+ m_pcs->hInstance = GetApp()->GetInstanceHandle();
+ m_pcs->hMenu = cs.hMenu;
+ m_pcs->hwndParent = cs.hwndParent;
+ m_pcs->lpCreateParams = cs.lpCreateParams;
+ m_pcs->lpszClass = cs.lpszClass;
+ m_pcs->lpszName = cs.lpszName;
+ m_pcs->style = cs.style;
+ m_pcs->x = cs.x;
+ m_pcs->y = cs.y;
+
+ // Overide this function in your derived class to set the
+ // CREATESTRUCT values prior to window creation.
+ // The cs.lpszClass parameter should NOT be specified if the
+ // PreRegisterClass function is used to create a window class.
+ }
+
+ inline void CWnd::PreRegisterClass(WNDCLASS& wc)
+ // Called by CWnd::Create to set some window parameters
+ // Useful for setting the background brush and cursor
+ {
+ // Test if Win32++ has been started
+ assert( GetApp() );
+
+ m_pwc->style = wc.style;
+ m_pwc->lpfnWndProc = CWnd::StaticWindowProc;
+ m_pwc->cbClsExtra = wc.cbClsExtra;
+ m_pwc->cbWndExtra = wc.cbWndExtra;
+ m_pwc->hInstance = GetApp()->GetInstanceHandle();
+ m_pwc->hIcon = wc.hIcon;
+ m_pwc->hCursor = wc.hCursor;
+ m_pwc->hbrBackground = wc.hbrBackground;
+ m_pwc->lpszMenuName = wc.lpszMenuName;
+ m_pwc->lpszClassName = wc.lpszClassName;
+
+ // Overide this function in your derived class to set the
+ // WNDCLASS values prior to window creation.
+
+ // ADDITIONAL NOTES:
+ // 1) The lpszClassName must be set for this function to take effect.
+ // 2) The lpfnWndProc is always CWnd::StaticWindowProc.
+ // 3) No other defaults are set, so the following settings might prove useful
+ // wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+ // wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
+ // wc.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
+ // 4) The styles that can be set here are WNDCLASS styles. These are a different
+ // set of styles to those set by CREATESTRUCT (used in PreCreate).
+ // 5) RegisterClassEx is not used because its not supported on WinCE.
+ // To set a small icon for the window, use SetIconSmall.
+ }
+
+ inline BOOL CWnd::PreTranslateMessage(MSG* pMsg)
+ {
+ UNREFERENCED_PARAMETER(pMsg);
+
+ // Override this function if your class requires input messages to be
+ // translated before normal processing. Function which translate messages
+ // include TranslateAccelerator, TranslateMDISysAccel and IsDialogMessage.
+ // Return TRUE if the message is translated.
+
+ return FALSE;
+ }
+
+ inline BOOL CWnd::RegisterClass(WNDCLASS& wc)
+ // A private function used by the PreRegisterClass function to register a
+ // window class prior to window creation
+ {
+ assert( GetApp() );
+ assert( (0 != lstrlen(wc.lpszClassName) && ( lstrlen(wc.lpszClassName) <= MAX_STRING_SIZE) ) );
+
+ // Check to see if this classname is already registered
+ WNDCLASS wcTest = {0};
+ BOOL Done = FALSE;
+
+ if (::GetClassInfo(GetApp()->GetInstanceHandle(), wc.lpszClassName, &wcTest))
+ {
+ wc = wcTest;
+ Done = TRUE;
+ }
+
+ if (!Done)
+ {
+ // Set defaults
+ wc.hInstance = GetApp()->GetInstanceHandle();
+ wc.lpfnWndProc = CWnd::StaticWindowProc;
+
+ // Register the WNDCLASS structure
+ if ( !::RegisterClass(&wc) )
+ throw CWinException(_T("Failed to register window class"));
+
+ Done = TRUE;
+ }
+
+ return Done;
+ }
+
+ inline BOOL CWnd::RemoveFromMap()
+ {
+ BOOL Success = FALSE;
+
+ if (GetApp())
+ {
+
+ // Allocate an iterator for our HWND map
+ std::map<HWND, CWnd*, CompareHWND>::iterator m;
+
+ CWinApp* pApp = GetApp();
+ if (pApp)
+ {
+ // Erase the CWnd pointer entry from the map
+ pApp->m_csMapLock.Lock();
+ for (m = pApp->m_mapHWND.begin(); m != pApp->m_mapHWND.end(); ++m)
+ {
+ if (this == m->second)
+ {
+ pApp->m_mapHWND.erase(m);
+ Success = TRUE;
+ break;
+ }
+ }
+
+ pApp->m_csMapLock.Release();
+ }
+ }
+
+ return Success;
+ }
+
+ inline HICON CWnd::SetIconLarge(int nIcon)
+ // Sets the large icon associated with the window
+ {
+ assert( GetApp() );
+ assert(::IsWindow(m_hWnd));
+
+ HICON hIconLarge = (HICON) (::LoadImage (GetApp()->GetResourceHandle(), MAKEINTRESOURCE (nIcon), IMAGE_ICON,
+ ::GetSystemMetrics (SM_CXICON), ::GetSystemMetrics (SM_CYICON), 0));
+
+ if (hIconLarge)
+ SendMessage (WM_SETICON, WPARAM (ICON_BIG), LPARAM (hIconLarge));
+ else
+ TRACE(_T("**WARNING** SetIconLarge Failed\n"));
+
+ return hIconLarge;
+ }
+
+ inline HICON CWnd::SetIconSmall(int nIcon)
+ // Sets the small icon associated with the window
+ {
+ assert( GetApp() );
+ assert(::IsWindow(m_hWnd));
+
+ HICON hIconSmall = (HICON) (::LoadImage (GetApp()->GetResourceHandle(), MAKEINTRESOURCE (nIcon), IMAGE_ICON,
+ ::GetSystemMetrics (SM_CXSMICON), ::GetSystemMetrics (SM_CYSMICON), 0));
+
+ if (hIconSmall)
+ SendMessage (WM_SETICON, WPARAM (ICON_SMALL), LPARAM (hIconSmall));
+ else
+ TRACE(_T("**WARNING** SetIconSmall Failed\n"));
+
+ return hIconSmall;
+ }
+
+ inline LRESULT CALLBACK CWnd::StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // All CWnd windows direct their messages here. This function redirects the message
+ // to the CWnd's WndProc function.
+ {
+ assert( GetApp() );
+
+ CWnd* w = GetApp()->GetCWndFromMap(hWnd);
+ if (0 == w)
+ {
+ // The CWnd pointer wasn't found in the map, so add it now
+
+ // Retrieve the pointer to the TLS Data
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ assert(pTLSData);
+
+ // Retrieve pointer to CWnd object from Thread Local Storage TLS
+ w = pTLSData->pCWnd;
+ assert(w); // pTLSData->pCWnd is assigned in CreateEx
+ pTLSData->pCWnd = NULL;
+
+ // Store the CWnd pointer in the HWND map
+ w->m_hWnd = hWnd;
+ w->AddToMap();
+ }
+
+ return w->WndProc(uMsg, wParam, lParam);
+
+ } // LRESULT CALLBACK StaticWindowProc(...)
+
+ inline void CWnd::Subclass(HWND hWnd)
+ // A private function used by CreateEx, Attach and AttachDlgItem
+ {
+ assert(::IsWindow(hWnd));
+
+ m_PrevWindowProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)CWnd::StaticWindowProc);
+ m_hWnd = hWnd;
+ }
+
+ inline LRESULT CWnd::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ // Override this function in your class derrived from CWnd to handle
+ // window messages. A typical function might look like this:
+
+ // switch (uMsg)
+ // {
+ // case MESSAGE1: // Some Windows API message
+ // OnMessage1(); // A user defined function
+ // break; // Also do default processing
+ // case MESSAGE2:
+ // OnMessage2();
+ // return x; // Don't do default processing, but instead return
+ // // a value recommended by the Windows API documentation
+ // }
+
+ // Always pass unhandled messages on to WndProcDefault
+ return WndProcDefault(uMsg, wParam, lParam);
+ }
+
+ inline LRESULT CWnd::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
+ // All WndProc functions should pass unhandled window messages to this function
+ {
+ LRESULT lr = 0L;
+
+ switch (uMsg)
+ {
+ case UWM_CLEANUPTEMPS:
+ {
+ TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());
+ pTLSData->vTmpWnds.clear();
+ }
+ break;
+ case WM_COMMAND:
+ {
+ // Refelect this message if it's from a control
+ CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam);
+ if (pWnd != NULL)
+ lr = pWnd->OnCommand(wParam, lParam);
+
+ // Handle user commands
+ if (!lr)
+ lr = OnCommand(wParam, lParam);
+
+ if (lr) return 0L;
+ }
+ break; // Note: Some MDI commands require default processing
+ case WM_CREATE:
+ OnCreate();
+ break;
+ // An example of how to end the application when the window closes
+ // If needed, put this in the class you inherit from CWnd
+ // case WM_DESTROY:
+ // ::PostQuitMessage(0);
+ // return 0L;
+ case WM_NOTIFY:
+ {
+ // Do Notification reflection if it came from a CWnd object
+ HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom;
+ CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom);
+
+ if (lstrcmp(GetClassName(), _T("ReBarWindow32")) != 0) // Skip notification reflection for rebars to avoid double handling
+ {
+ if (pWndFrom != NULL)
+ lr = pWndFrom->OnNotifyReflect(wParam, lParam);
+ else
+ {
+ // Some controls (eg ListView) have child windows.
+ // Reflect those notifications too.
+ CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom));
+ if (pWndFromParent != NULL)
+ lr = pWndFromParent->OnNotifyReflect(wParam, lParam);
+ }
+ }
+
+ // Handle user notifications
+ if (!lr) lr = OnNotify(wParam, lParam);
+ if (lr) return lr;
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ // Subclassed controls expect to do their own painting.
+ // CustomDraw or OwnerDraw are normally used to modify the drawing of controls.
+ if (m_PrevWindowProc) break;
+
+ if (::GetUpdateRect(m_hWnd, NULL, FALSE))
+ {
+ CPaintDC dc(this);
+ OnDraw(&dc);
+ }
+ else
+ // RedrawWindow can require repainting without an update rect
+ {
+ CClientDC dc(this);
+ OnDraw(&dc);
+ }
+ }
+ return 0L;
+
+ case WM_ERASEBKGND:
+ {
+ CDC dc((HDC)wParam);
+ BOOL bResult = OnEraseBkgnd(&dc);
+ dc.Detach();
+ if (bResult) return TRUE;
+ }
+ break;
+
+ // A set of messages to be reflected back to the control that generated them
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORSCROLLBAR:
+ case WM_CTLCOLORSTATIC:
+ case WM_DRAWITEM:
+ case WM_MEASUREITEM:
+ case WM_DELETEITEM:
+ case WM_COMPAREITEM:
+ case WM_CHARTOITEM:
+ case WM_VKEYTOITEM:
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ case WM_PARENTNOTIFY:
+ {
+ // if (m_PrevWindowProc) break; // Suppress for subclassed windows
+
+ LRESULT lr = MessageReflect(m_hWnd, uMsg, wParam, lParam);
+ if (lr) return lr; // Message processed so return
+ }
+ break; // Do default processing when message not already processed
+
+ case UWM_UPDATE_COMMAND:
+ OnMenuUpdate((UINT)wParam); // Perform menu updates
+ break;
+
+ } // switch (uMsg)
+
+ // Now hand all messages to the default procedure
+ if (m_PrevWindowProc)
+ return ::CallWindowProc(m_PrevWindowProc, m_hWnd, uMsg, wParam, lParam);
+ else
+ return FinalWindowProc(uMsg, wParam, lParam);
+
+ } // LRESULT CWnd::WindowProc(...)
+
+
+ //
+ // Wrappers for Win32 API functions
+ //
+
+ inline CDC* CWnd::BeginPaint(PAINTSTRUCT& ps) const
+ // The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with
+ // information about the painting.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle(::BeginPaint(m_hWnd, &ps));
+ }
+
+ inline BOOL CWnd::BringWindowToTop() const
+ // The BringWindowToTop function brings the specified window to the top
+ // of the Z order. If the window is a top-level window, it is activated.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::BringWindowToTop(m_hWnd);
+ }
+
+ inline LRESULT CWnd::CallWindowProc(WNDPROC lpPrevWndFunc, UINT Msg, WPARAM wParam, LPARAM lParam) const
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::CallWindowProc(lpPrevWndFunc, m_hWnd, Msg, wParam, lParam);
+ }
+
+ inline BOOL CWnd::CheckDlgButton(int nIDButton, UINT uCheck) const
+ // The CheckDlgButton function changes the check state of a button control.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::CheckDlgButton(m_hWnd, nIDButton, uCheck);
+ }
+
+ inline BOOL CWnd::CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton) const
+ // The CheckRadioButton function adds a check mark to (checks) a specified radio button in a group
+ // and removes a check mark from (clears) all other radio buttons in the group.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::CheckRadioButton(m_hWnd, nIDFirstButton, nIDLastButton, nIDCheckButton);
+ }
+
+ inline CWnd* CWnd::ChildWindowFromPoint(POINT pt) const
+ // determines which, if any, of the child windows belonging to a parent window contains
+ // the specified point. The search is restricted to immediate child windows.
+ // Grandchildren, and deeper descendant windows are not searched.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle(::ChildWindowFromPoint(m_hWnd, pt));
+ }
+
+ inline BOOL CWnd::ClientToScreen(POINT& pt) const
+ // The ClientToScreen function converts the client-area coordinates of a specified point to screen coordinates.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ClientToScreen(m_hWnd, &pt);
+ }
+
+ inline BOOL CWnd::ClientToScreen(RECT& rc) const
+ // The ClientToScreen function converts the client-area coordinates of a specified RECT to screen coordinates.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)::MapWindowPoints(m_hWnd, NULL, (LPPOINT)&rc, 2);
+ }
+
+ inline HDWP CWnd::DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags) const
+ // The DeferWindowPos function updates the specified multiple-window – position structure for the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DeferWindowPos(hWinPosInfo, m_hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
+ }
+
+ inline HDWP CWnd::DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, const RECT& rc, UINT uFlags) const
+ // The DeferWindowPos function updates the specified multiple-window – position structure for the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DeferWindowPos(hWinPosInfo, m_hWnd, hWndInsertAfter, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, uFlags);
+ }
+
+ inline LRESULT CWnd::DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) const
+ // This function provides default processing for any window messages that an application does not process.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
+ }
+
+ inline BOOL CWnd::DrawMenuBar() const
+ // The DrawMenuBar function redraws the menu bar of the specified window. If the menu bar changes after
+ // the system has created the window, this function must be called to draw the changed menu bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DrawMenuBar(m_hWnd);
+ }
+
+ inline BOOL CWnd::EnableWindow(BOOL bEnable /*= TRUE*/) const
+ // The EnableWindow function enables or disables mouse and
+ // keyboard input to the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::EnableWindow(m_hWnd, bEnable);
+ }
+
+ inline BOOL CWnd::EndPaint(PAINTSTRUCT& ps) const
+ // The EndPaint function marks the end of painting in the specified window. This function is required for
+ // each call to the BeginPaint function, but only after painting is complete.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::EndPaint(m_hWnd, &ps);
+ }
+
+ inline CWnd* CWnd::GetActiveWindow() const
+ // The GetActiveWindow function retrieves a pointer to the active window attached to the calling
+ // thread's message queue.
+ {
+ return FromHandle( ::GetActiveWindow() );
+ }
+
+ inline CWnd* CWnd::GetCapture() const
+ // The GetCapture function retrieves a pointer to the window (if any) that has captured the mouse.
+ {
+ return FromHandle( ::GetCapture() );
+ }
+
+ inline ULONG_PTR CWnd::GetClassLongPtr(int nIndex) const
+ // The GetClassLongPtr function retrieves the specified value from the
+ // WNDCLASSEX structure associated with the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetClassLongPtr(m_hWnd, nIndex);
+ }
+
+ inline CRect CWnd::GetClientRect() const
+ // The GetClientRect function retrieves the coordinates of a window's client area.
+ // The client coordinates specify the upper-left and lower-right corners of the
+ // client area. Because client coordinates are relative to the upper-left corner
+ // of a window's client area, the coordinates of the upper-left corner are (0,0).
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ ::GetClientRect(m_hWnd, &rc);
+ return rc;
+ }
+
+ inline CDC* CWnd::GetDC() const
+ // The GetDC function retrieves a handle to a display device context (DC) for the
+ // client area of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CDC::AddTempHDC(::GetDC(m_hWnd), m_hWnd);
+ }
+
+ inline CDC* CWnd::GetDCEx(HRGN hrgnClip, DWORD flags) const
+ // The GetDCEx function retrieves a handle to a display device context (DC) for the
+ // client area or entire area of a window
+ {
+ assert(::IsWindow(m_hWnd));
+ return CDC::AddTempHDC(::GetDCEx(m_hWnd, hrgnClip, flags), m_hWnd);
+ }
+
+ inline CWnd* CWnd::GetDesktopWindow() const
+ // The GetDesktopWindow function retrieves a pointer to the desktop window.
+ {
+ return FromHandle( ::GetDesktopWindow() );
+ }
+
+ inline CWnd* CWnd::GetDlgItem(int nIDDlgItem) const
+ // The GetDlgItem function retrieves a handle to a control in the dialog box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::GetDlgItem(m_hWnd, nIDDlgItem) );
+ }
+
+ inline UINT CWnd::GetDlgItemInt(int nIDDlgItem, BOOL* lpTranslated, BOOL bSigned) const
+ // The GetDlgItemInt function translates the text of a specified control in a dialog box into an integer value.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetDlgItemInt(m_hWnd, nIDDlgItem, lpTranslated, bSigned);
+ }
+
+ inline CWnd* CWnd::GetFocus() const
+ // The GetFocus function retrieves a pointer to the window that has the keyboard focus, if the window
+ // is attached to the calling thread's message queue.
+ {
+ return FromHandle( ::GetFocus() );
+ }
+
+ inline CFont* CWnd::GetFont() const
+ // Retrieves the font with which the window is currently drawing its text.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle((HFONT)SendMessage(WM_GETFONT, 0, 0));
+ }
+
+ inline HICON CWnd::GetIcon(BOOL bBigIcon) const
+ // Retrieves a handle to the large or small icon associated with a window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(WM_GETICON, (WPARAM)bBigIcon, 0);
+ }
+
+ inline CWnd* CWnd::GetNextDlgGroupItem(CWnd* pCtl, BOOL bPrevious) const
+ // The GetNextDlgGroupItem function retrieves a pointer to the first control in a group of controls that
+ // precedes (or follows) the specified control in a dialog box.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pCtl);
+ return FromHandle(::GetNextDlgGroupItem(m_hWnd, pCtl->GetHwnd(), bPrevious));
+ }
+
+ inline CWnd* CWnd::GetNextDlgTabItem(CWnd* pCtl, BOOL bPrevious) const
+ // The GetNextDlgTabItem function retrieves a pointer to the first control that has the WS_TABSTOP style
+ // that precedes (or follows) the specified control.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pCtl);
+ return FromHandle(::GetNextDlgTabItem(m_hWnd, pCtl->GetHwnd(), bPrevious));
+ }
+
+ inline CWnd* CWnd::GetParent() const
+ // The GetParent function retrieves a pointer to the specified window's parent or owner.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::GetParent(m_hWnd) );
+ }
+
+ inline LONG_PTR CWnd::GetWindowLongPtr(int nIndex) const
+ // The GetWindowLongPtr function retrieves information about the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetWindowLongPtr(m_hWnd, nIndex);
+ }
+
+ inline BOOL CWnd::GetScrollInfo(int fnBar, SCROLLINFO& si) const
+ // The GetScrollInfo function retrieves the parameters of a scroll bar, including
+ // the minimum and maximum scrolling positions, the page size, and the position
+ // of the scroll box (thumb).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetScrollInfo(m_hWnd, fnBar, &si);
+ }
+
+ inline CRect CWnd::GetUpdateRect(BOOL bErase) const
+ // The GetUpdateRect function retrieves the coordinates of the smallest rectangle that completely
+ // encloses the update region of the specified window.
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ ::GetUpdateRect(m_hWnd, &rc, bErase);
+ return rc;
+ }
+
+ inline int CWnd::GetUpdateRgn(CRgn* pRgn, BOOL bErase) const
+ // The GetUpdateRgn function retrieves the update region of a window by copying it into the specified region.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pRgn);
+ HRGN hRgn = (HRGN)pRgn->GetHandle();
+ return ::GetUpdateRgn(m_hWnd, hRgn, bErase);
+ }
+
+ inline CWnd* CWnd::GetWindow(UINT uCmd) const
+ // The GetWindow function retrieves a pointer to a window that has the specified
+ // relationship (Z-Order or owner) to the specified window.
+ // Possible uCmd values: GW_CHILD, GW_ENABLEDPOPUP, GW_HWNDFIRST, GW_HWNDLAST,
+ // GW_HWNDNEXT, GW_HWNDPREV, GW_OWNER
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::GetWindow(m_hWnd, uCmd) );
+ }
+
+ inline CDC* CWnd::GetWindowDC() const
+ // The GetWindowDC function retrieves the device context (DC) for the entire
+ // window, including title bar, menus, and scroll bars.
+ {
+ assert(::IsWindow(m_hWnd));
+ return CDC::AddTempHDC(::GetWindowDC(m_hWnd), m_hWnd);
+ }
+
+ inline CRect CWnd::GetWindowRect() const
+ // retrieves the dimensions of the bounding rectangle of the window.
+ // The dimensions are given in screen coordinates that are relative to the
+ // upper-left corner of the screen.
+ {
+ assert(::IsWindow(m_hWnd));
+ CRect rc;
+ ::GetWindowRect(m_hWnd, &rc);
+ return rc;
+ }
+
+ inline int CWnd::GetWindowTextLength() const
+ // The GetWindowTextLength function retrieves the length, in characters, of the specified window's
+ // title bar text (if the window has a title bar).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetWindowTextLength(m_hWnd);
+ }
+
+ inline void CWnd::Invalidate(BOOL bErase /*= TRUE*/) const
+ // The Invalidate function adds the entire client area the window's update region.
+ // The update region represents the portion of the window's client area that must be redrawn.
+ {
+ assert(::IsWindow(m_hWnd));
+ ::InvalidateRect(m_hWnd, NULL, bErase);
+ }
+
+ inline BOOL CWnd::InvalidateRect(LPCRECT lpRect, BOOL bErase /*= TRUE*/) const
+ // The InvalidateRect function adds a rectangle to the window's update region.
+ // The update region represents the portion of the window's client area that must be redrawn.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::InvalidateRect(m_hWnd, lpRect, bErase);
+ }
+
+ inline BOOL CWnd::InvalidateRgn(CRgn* pRgn, BOOL bErase /*= TRUE*/) const
+ // The InvalidateRgn function invalidates the client area within the specified region
+ // by adding it to the current update region of a window. The invalidated region,
+ // along with all other areas in the update region, is marked for painting when the
+ // next WM_PAINT message occurs.
+ {
+ assert(::IsWindow(m_hWnd));
+ HRGN hRgn = pRgn? (HRGN)pRgn->GetHandle() : NULL;
+ return ::InvalidateRgn(m_hWnd, hRgn, bErase);
+ }
+
+ inline BOOL CWnd::IsChild(CWnd* pChild) const
+ // The IsChild function tests whether a window is a child window or descendant window
+ // of a parent window's CWnd.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsChild(m_hWnd, pChild->GetHwnd());
+ }
+
+ inline BOOL CWnd::IsDialogMessage(LPMSG lpMsg) const
+ // The IsDialogMessage function determines whether a message is intended for the specified dialog box and,
+ // if it is, processes the message.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsDialogMessage(m_hWnd, lpMsg);
+ }
+
+ inline UINT CWnd::IsDlgButtonChecked(int nIDButton) const
+ // The IsDlgButtonChecked function determines whether a button control has a check mark next to it
+ // or whether a three-state button control is grayed, checked, or neither.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsDlgButtonChecked(m_hWnd, nIDButton);
+ }
+
+ inline BOOL CWnd::IsWindowEnabled() const
+ // The IsWindowEnabled function determines whether the window is enabled
+ // for mouse and keyboard input.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsWindowEnabled(m_hWnd);
+ }
+
+ inline BOOL CWnd::IsWindowVisible() const
+ // The IsWindowVisible function retrieves the visibility state of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsWindowVisible(m_hWnd);
+ }
+
+ inline BOOL CWnd::IsWindow() const
+ // The IsWindow function determines whether the window exists.
+ {
+ return ::IsWindow(m_hWnd);
+ }
+
+ inline void CWnd::MapWindowPoints(CWnd* pWndTo, POINT& pt) const
+ // The MapWindowPoints function converts (maps) a set of points from a coordinate space relative to one
+ // window to a coordinate space relative to another window.
+ {
+ assert (m_hWnd);
+ if(pWndTo)
+ {
+ assert (pWndTo->GetHwnd());
+ ::MapWindowPoints(m_hWnd, pWndTo->GetHwnd(), &pt, 1);
+ }
+ else
+ ::MapWindowPoints(m_hWnd, NULL, &pt, 1);
+ }
+
+ inline void CWnd::MapWindowPoints(CWnd* pWndTo, RECT& rc) const
+ // The MapWindowPoints function converts (maps) a set of points from a coordinate space relative to one
+ // window to a coordinate space relative to another window.
+ {
+ assert (m_hWnd);
+ if(pWndTo)
+ {
+ assert (pWndTo->GetHwnd());
+ ::MapWindowPoints(m_hWnd, pWndTo->GetHwnd(), (LPPOINT)&rc, 2);
+ }
+ else
+ ::MapWindowPoints(m_hWnd, NULL, (LPPOINT)&rc, 2);
+ }
+
+ inline void CWnd::MapWindowPoints(CWnd* pWndTo, LPPOINT ptArray, UINT nCount) const
+ // The MapWindowPoints function converts (maps) a set of points from a coordinate space relative to one
+ // window to a coordinate space relative to another window.
+ {
+ assert (m_hWnd);
+ if (pWndTo)
+ {
+ assert (pWndTo->GetHwnd());
+ ::MapWindowPoints(m_hWnd, pWndTo->GetHwnd(), (LPPOINT)ptArray, nCount);
+ }
+ else
+ ::MapWindowPoints(m_hWnd, NULL, (LPPOINT)ptArray, nCount);
+ }
+
+ inline int CWnd::MessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) const
+ // The MessageBox function creates, displays, and operates a message box.
+ // Possible combinations of uType values include: MB_OK, MB_HELP, MB_OKCANCEL, MB_RETRYCANCEL,
+ // MB_YESNO, MB_YESNOCANCEL, MB_ICONEXCLAMATION, MB_ICONWARNING, MB_ICONERROR (+ many others).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::MessageBox(m_hWnd, lpText, lpCaption, uType);
+ }
+
+ inline BOOL CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint /* = TRUE*/) const
+ // The MoveWindow function changes the position and dimensions of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint = TRUE);
+ }
+
+ inline BOOL CWnd::MoveWindow(const RECT& rc, BOOL bRepaint /* = TRUE*/) const
+ // The MoveWindow function changes the position and dimensions of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, bRepaint);
+ }
+
+ inline BOOL CWnd::PostMessage(UINT uMsg, WPARAM wParam /*= 0L*/, LPARAM lParam /*= 0L*/) const
+ // The PostMessage function places (posts) a message in the message queue
+ // associated with the thread that created the window and returns without
+ // waiting for the thread to process the message.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::PostMessage(m_hWnd, uMsg, wParam, lParam);
+ }
+
+ inline BOOL CWnd::PostMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) const
+ // Required by by some macros
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::PostMessage(hWnd, uMsg, wParam, lParam);
+ }
+
+ inline BOOL CWnd::RedrawWindow(LPCRECT lpRectUpdate, CRgn* pRgn, UINT flags) const
+ // The RedrawWindow function updates the specified rectangle or region in a window's client area.
+ {
+ assert(::IsWindow(m_hWnd));
+ HRGN hRgn = pRgn? (HRGN)pRgn->GetHandle() : NULL;
+ return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgn, flags);
+ }
+
+ inline int CWnd::ReleaseDC(CDC* pDC) const
+ // The ReleaseDC function releases a device context (DC), freeing it for use
+ // by other applications.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pDC);
+ return ::ReleaseDC(m_hWnd, pDC->GetHDC());
+ }
+
+ inline BOOL CWnd::ScreenToClient(POINT& Point) const
+ // The ScreenToClient function converts the screen coordinates of a specified point on the screen to client-area coordinates.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ScreenToClient(m_hWnd, &Point);
+ }
+
+ inline BOOL CWnd::ScreenToClient(RECT& rc) const
+ // The ScreenToClient function converts the screen coordinates of a specified RECT on the screen to client-area coordinates.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rc, 2);
+ }
+
+ inline LRESULT CWnd::SendDlgItemMessage(int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam) const
+ // The SendDlgItemMessage function sends a message to the specified control in a dialog box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SendDlgItemMessage(m_hWnd, nIDDlgItem, Msg, wParam, lParam);
+ }
+
+ inline LRESULT CWnd::SendMessage(UINT uMsg, WPARAM wParam /*= 0L*/, LPARAM lParam /*= 0L*/) const
+ // The SendMessage function sends the specified message to a window or windows.
+ // It calls the window procedure for the window and does not return until the
+ // window procedure has processed the message.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SendMessage(m_hWnd, uMsg, wParam, lParam);
+ }
+
+ inline LRESULT CWnd::SendMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) const
+ // Required by by some macros
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SendMessage(hWnd, uMsg, wParam, lParam);
+ }
+
+ inline BOOL CWnd::SendNotifyMessage(UINT Msg, WPARAM wParam, LPARAM lParam) const
+ // The SendNotifyMessage function sends the specified message to a window or windows. If the window was created by the
+ // calling thread, SendNotifyMessage calls the window procedure for the window and does not return until the window procedure
+ // has processed the message. If the window was created by a different thread, SendNotifyMessage passes the message to the
+ // window procedure and returns immediately; it does not wait for the window procedure to finish processing the message.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SendNotifyMessage(m_hWnd, Msg, wParam, lParam);
+ }
+
+ inline CWnd* CWnd::SetActiveWindow() const
+ // The SetActiveWindow function activates the window, but
+ // not if the application is in the background.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::SetActiveWindow(m_hWnd) );
+ }
+
+ inline CWnd* CWnd::SetCapture() const
+ // The SetCapture function sets the mouse capture to the window.
+ // SetCapture captures mouse input either when the mouse is over the capturing
+ // window, or when the mouse button was pressed while the mouse was over the
+ // capturing window and the button is still down.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::SetCapture(m_hWnd) );
+ }
+
+ inline ULONG_PTR CWnd::SetClassLongPtr(int nIndex, LONG_PTR dwNewLong) const
+ // The SetClassLongPtr function replaces the specified value at the specified offset in the
+ // extra class memory or the WNDCLASSEX structure for the class to which the window belongs.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetClassLongPtr(m_hWnd, nIndex, dwNewLong);
+ }
+
+ inline CWnd* CWnd::SetFocus() const
+ // The SetFocus function sets the keyboard focus to the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::SetFocus(m_hWnd) );
+ }
+
+ inline void CWnd::SetFont(CFont* pFont, BOOL bRedraw /* = TRUE*/) const
+ // Specifies the font that the window will use when drawing text.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pFont);
+ SendMessage(WM_SETFONT, (WPARAM)pFont->GetHandle(), (LPARAM)bRedraw);
+ }
+
+ inline HICON CWnd::SetIcon(HICON hIcon, BOOL bBigIcon) const
+ // Associates a new large or small icon with a window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (HICON)SendMessage(WM_SETICON, (WPARAM)bBigIcon, (LPARAM)hIcon);
+ }
+
+ inline BOOL CWnd::SetForegroundWindow() const
+ // The SetForegroundWindow function puts the thread that created the window into the
+ // foreground and activates the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetForegroundWindow(m_hWnd);
+ }
+
+ inline CWnd* CWnd::SetParent(CWnd* pWndParent) const
+ // The SetParent function changes the parent window of the child window.
+ {
+ assert(::IsWindow(m_hWnd));
+ if (pWndParent)
+ {
+ HWND hParent = pWndParent->GetHwnd();
+ return FromHandle(::SetParent(m_hWnd, hParent));
+ }
+ else
+ return FromHandle(::SetParent(m_hWnd, 0));
+ }
+
+ inline BOOL CWnd::SetRedraw(BOOL bRedraw /*= TRUE*/) const
+ // This function allows changes in that window to be redrawn or prevents changes
+ // in that window from being redrawn.
+ {
+ assert(::IsWindow(m_hWnd));
+ return (BOOL)::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0L);
+ }
+
+ inline LONG_PTR CWnd::SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong) const
+ // The SetWindowLongPtr function changes an attribute of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetWindowLongPtr(m_hWnd, nIndex, dwNewLong);
+ }
+
+ inline BOOL CWnd::SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags) const
+ // The SetWindowPos function changes the size, position, and Z order of a child, pop-up,
+ // or top-level window. The hWndInsertAfter can be a HWND or one of:
+ // HWND_BOTTOM, HWND_NOTOPMOST, HWND_TOP, HWND_TOPMOST
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
+ }
+
+ inline BOOL CWnd::SetWindowPos(HWND hWndInsertAfter, const RECT& rc, UINT uFlags) const
+ // The SetWindowPos function changes the size, position, and Z order of a child, pop-up,
+ // or top-level window. The hWndInsertAfter can be a HWND or one of:
+ // HWND_BOTTOM, HWND_NOTOPMOST, HWND_TOP, HWND_TOPMOST
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetWindowPos(m_hWnd, hWndInsertAfter, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, uFlags);
+ }
+
+ inline int CWnd::SetWindowRgn(CRgn* pRgn, BOOL bRedraw /*= TRUE*/) const
+ // The SetWindowRgn function sets the window region of the window.
+ // The window region determines the area within the window where the system permits drawing.
+ {
+ assert(::IsWindow(m_hWnd));
+ HRGN hRgn = pRgn? (HRGN)pRgn->GetHandle() : NULL;
+ int iResult = ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
+ if (iResult && pRgn)
+ pRgn->Detach(); // The system owns the region now
+ return iResult;
+ }
+
+ inline BOOL CWnd::SetDlgItemInt(int nIDDlgItem, UINT uValue, BOOL bSigned) const
+ // The SetDlgItemInt function sets the text of a control in a dialog box to the string representation of a specified integer value.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetDlgItemInt(m_hWnd, nIDDlgItem, uValue, bSigned);
+ }
+
+ inline BOOL CWnd::SetDlgItemText(int nIDDlgItem, LPCTSTR lpString) const
+ // The SetDlgItemText function sets the title or text of a control in a dialog box.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetDlgItemText(m_hWnd, nIDDlgItem, lpString);
+ }
+
+ inline UINT_PTR CWnd::SetTimer(UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) const
+ // Creates a timer with the specified time-out value.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetTimer(m_hWnd, nIDEvent, uElapse, lpTimerFunc);
+ }
+
+ inline BOOL CWnd::SetWindowText(LPCTSTR lpString) const
+ // The SetWindowText function changes the text of the window's title bar (if it has one).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetWindowText(m_hWnd, lpString);
+ }
+
+ inline HRESULT CWnd::SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) const
+ // Set the XP Theme for a window.
+ // Exampes:
+ // SetWindowTheme(NULL, NULL); // Reverts the window's XP theme back to default
+ // SetWindowTheme(L" ", L" "); // Disables XP theme for the window
+ {
+ HRESULT hr = E_NOTIMPL;
+
+#ifndef _WIN32_WCE
+
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));
+ if(hMod)
+ {
+ typedef HRESULT (__stdcall *PFNSETWINDOWTHEME)(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+ PFNSETWINDOWTHEME pfn = (PFNSETWINDOWTHEME)GetProcAddress(hMod, "SetWindowTheme");
+
+ hr = (*pfn)(m_hWnd, pszSubAppName, pszSubIdList);
+
+ ::FreeLibrary(hMod);
+ }
+
+#endif
+
+ return hr;
+ }
+
+ inline BOOL CWnd::ShowWindow(int nCmdShow /*= SW_SHOWNORMAL*/) const
+ // The ShowWindow function sets the window's show state.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ShowWindow(m_hWnd, nCmdShow);
+ }
+
+ inline BOOL CWnd::UpdateWindow() const
+ // The UpdateWindow function updates the client area of the window by sending a
+ // WM_PAINT message to the window if the window's update region is not empty.
+ // If the update region is empty, no message is sent.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::UpdateWindow(m_hWnd);
+ }
+
+ inline BOOL CWnd::ValidateRect(LPCRECT prc) const
+ // The ValidateRect function validates the client area within a rectangle by
+ // removing the rectangle from the update region of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ValidateRect(m_hWnd, prc);
+ }
+
+ inline BOOL CWnd::ValidateRgn(CRgn* pRgn) const
+ // The ValidateRgn function validates the client area within a region by
+ // removing the region from the current update region of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ HRGN hRgn = pRgn? (HRGN)pRgn->GetHandle() : NULL;
+ return ::ValidateRgn(m_hWnd, hRgn);
+ }
+
+ inline CWnd* CWnd::WindowFromPoint(POINT pt)
+ // Retrieves the window that contains the specified point (in screen coodinates).
+ {
+ return FromHandle(::WindowFromPoint(pt));
+ }
+
+ //
+ // These functions aren't supported on WinCE
+ //
+ #ifndef _WIN32_WCE
+ inline BOOL CWnd::CloseWindow() const
+ // The CloseWindow function minimizes (but does not destroy) the window.
+ // To destroy a window, an application can use the Destroy function.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::CloseWindow(m_hWnd);
+ }
+
+ inline int CWnd::DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT uFileType) const
+ // The DlgDirList function replaces the contents of a list box with the names of the subdirectories and files
+ // in a specified directory. You can filter the list of names by specifying a set of file attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DlgDirList(m_hWnd, lpPathSpec, nIDListBox, nIDStaticPath, uFileType);
+ }
+
+ inline int CWnd::DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT uFiletype) const
+ // The DlgDirListComboBox function replaces the contents of a combo box with the names of the subdirectories
+ // and files in a specified directory. You can filter the list of names by specifying a set of file attributes.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DlgDirListComboBox(m_hWnd, lpPathSpec, nIDComboBox, nIDStaticPath, uFiletype);
+ }
+
+ inline BOOL CWnd::DlgDirSelectEx(LPTSTR lpString, int nCount, int nIDListBox) const
+ // The DlgDirSelectEx function retrieves the current selection from a single-selection list box. It assumes that the list box
+ // has been filled by the DlgDirList function and that the selection is a drive letter, filename, or directory name.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DlgDirSelectEx(m_hWnd, lpString, nCount, nIDListBox);
+ }
+
+ inline BOOL CWnd::DlgDirSelectComboBoxEx(LPTSTR lpString, int nCount, int nIDComboBox) const
+ // The DlgDirSelectComboBoxEx function retrieves the current selection from a combo box filled by using the
+ // DlgDirListComboBox function. The selection is interpreted as a drive letter, a file, or a directory name.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DlgDirSelectComboBoxEx(m_hWnd, lpString, nCount, nIDComboBox);
+ }
+
+ #ifndef WIN32_LEAN_AND_MEAN
+ inline void CWnd::DragAcceptFiles(BOOL fAccept) const
+ // Registers whether a window accepts dropped files.
+ {
+ assert(::IsWindow(m_hWnd));
+ ::DragAcceptFiles(m_hWnd, fAccept);
+ }
+ #endif
+
+ inline BOOL CWnd::DrawAnimatedRects(int idAni, RECT& rcFrom, RECT& rcTo) const
+ // The DrawAnimatedRects function draws a wire-frame rectangle and animates it to indicate the opening of
+ // an icon or the minimizing or maximizing of a window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::DrawAnimatedRects(m_hWnd, idAni, &rcFrom, &rcTo);
+ }
+
+ inline BOOL CWnd::DrawCaption(CDC* pDC, RECT& rc, UINT uFlags) const
+ // The DrawCaption function draws a window caption.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pDC);
+ return ::DrawCaption(m_hWnd, pDC->GetHDC(), &rc, uFlags);
+ }
+
+ inline BOOL CWnd::EnableScrollBar(UINT uSBflags, UINT uArrows) const
+ // The EnableScrollBar function enables or disables one or both scroll bar arrows.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::EnableScrollBar(m_hWnd, uSBflags, uArrows);
+ }
+
+ inline CWnd* CWnd::GetLastActivePopup() const
+ // The GetLastActivePopup function determines which pop-up window owned by the specified window was most recently active.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::GetLastActivePopup(m_hWnd) );
+ }
+
+ inline CMenu* CWnd::GetMenu() const
+ // The GetMenu function retrieves a handle to the menu assigned to the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle(::GetMenu(m_hWnd));
+ }
+
+ inline int CWnd::GetScrollPos(int nBar) const
+ // The GetScrollPos function retrieves the current position of the scroll box
+ // (thumb) in the specified scroll bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetScrollPos(m_hWnd, nBar);
+ }
+
+ inline BOOL CWnd::GetScrollRange(int nBar, int& MinPos, int& MaxPos) const
+ // The GetScrollRange function retrieves the current minimum and maximum scroll box
+ // (thumb) positions for the specified scroll bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetScrollRange(m_hWnd, nBar, &MinPos, &MaxPos );
+ }
+
+ inline CMenu* CWnd::GetSystemMenu(BOOL bRevert) const
+ // The GetSystemMenu function allows the application to access the window menu (also known as the system menu
+ // or the control menu) for copying and modifying.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle(::GetSystemMenu(m_hWnd, bRevert));
+ }
+
+ inline CWnd* CWnd::GetTopWindow() const
+ // The GetTopWindow function examines the Z order of the child windows associated with the parent window and
+ // retrieves a handle to the child window at the top of the Z order.
+ {
+ assert(::IsWindow(m_hWnd));
+ return FromHandle( ::GetTopWindow(m_hWnd) );
+ }
+
+ inline BOOL CWnd::GetWindowPlacement(WINDOWPLACEMENT& wndpl) const
+ // The GetWindowPlacement function retrieves the show state and the restored,
+ // minimized, and maximized positions of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::GetWindowPlacement(m_hWnd, &wndpl);
+ }
+
+ inline BOOL CWnd::HiliteMenuItem(CMenu* pMenu, UINT uItemHilite, UINT uHilite) const
+ // The HiliteMenuItem function highlights or removes the highlighting from an item in a menu bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pMenu);
+ return ::HiliteMenuItem(m_hWnd, pMenu->GetHandle(), uItemHilite, uHilite);
+ }
+
+ inline BOOL CWnd::IsIconic() const
+ // The IsIconic function determines whether the window is minimized (iconic).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsIconic(m_hWnd);
+ }
+
+ inline BOOL CWnd::IsZoomed() const
+ // The IsZoomed function determines whether the window is maximized.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::IsZoomed(m_hWnd);
+ }
+
+ inline BOOL CWnd::KillTimer(UINT_PTR uIDEvent) const
+ // Destroys the specified timer.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::KillTimer(m_hWnd, uIDEvent);
+ }
+
+ inline BOOL CWnd::LockWindowUpdate() const
+ // Disables drawing in the window. Only one window can be locked at a time.
+ // Use UnLockWindowUpdate to re-enable drawing in the window
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::LockWindowUpdate(m_hWnd);
+ }
+
+ inline BOOL CWnd::OpenIcon() const
+ // The OpenIcon function restores a minimized (iconic) window to its previous size and position.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::OpenIcon(m_hWnd);
+ }
+
+ inline void CWnd::Print(CDC* pDC, DWORD dwFlags) const
+ // Requests that the window draw itself in the specified device context, most commonly in a printer device context.
+ {
+ assert(::IsWindow(m_hWnd));
+ assert(pDC);
+ SendMessage(m_hWnd, WM_PRINT, (WPARAM)pDC, (LPARAM)dwFlags);
+ }
+
+ inline BOOL CWnd::ScrollWindow(int XAmount, int YAmount, LPCRECT lprcScroll, LPCRECT lprcClip) const
+ // The ScrollWindow function scrolls the contents of the specified window's client area.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ScrollWindow(m_hWnd, XAmount, YAmount, lprcScroll, lprcClip);
+ }
+
+ inline int CWnd::ScrollWindowEx(int dx, int dy, LPCRECT lprcScroll, LPCRECT lprcClip, CRgn* prgnUpdate, LPRECT lprcUpdate, UINT flags) const
+ // The ScrollWindow function scrolls the contents of the window's client area.
+ {
+ assert(::IsWindow(m_hWnd));
+ HRGN hrgnUpdate = prgnUpdate? (HRGN)prgnUpdate->GetHandle() : NULL;
+ return ::ScrollWindowEx(m_hWnd, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate, flags);
+ }
+
+ inline BOOL CWnd::SetMenu(CMenu* pMenu) const
+ // The SetMenu function assigns a menu to the specified window.
+ // A hMenu of NULL removes the menu.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetMenu(m_hWnd, pMenu? pMenu->GetHandle() : NULL);
+ }
+
+ inline int CWnd::SetScrollInfo(int fnBar, const SCROLLINFO& si, BOOL fRedraw) const
+ // The SetScrollInfo function sets the parameters of a scroll bar, including
+ // the minimum and maximum scrolling positions, the page size, and the
+ // position of the scroll box (thumb).
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetScrollInfo(m_hWnd, fnBar, &si, fRedraw);
+ }
+
+ inline int CWnd::SetScrollPos(int nBar, int nPos, BOOL bRedraw) const
+ // The SetScrollPos function sets the position of the scroll box (thumb) in
+ // the specified scroll bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
+ }
+
+ inline BOOL CWnd::SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw) const
+ // The SetScrollRange function sets the minimum and maximum scroll box positions for the scroll bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
+ }
+
+ inline BOOL CWnd::SetWindowPlacement(const WINDOWPLACEMENT& wndpl) const
+ // The SetWindowPlacement function sets the show state and the restored, minimized,
+ // and maximized positions of the window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::SetWindowPlacement(m_hWnd, &wndpl);
+ }
+
+ inline BOOL CWnd::ShowOwnedPopups(BOOL fShow) const
+ // The ShowOwnedPopups function shows or hides all pop-up windows owned by the specified window.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ShowOwnedPopups(m_hWnd, fShow);
+ }
+
+ inline BOOL CWnd::ShowScrollBar(int nBar, BOOL bShow) const
+ // The ShowScrollBar function shows or hides the specified scroll bar.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ShowScrollBar(m_hWnd, nBar, bShow);
+ }
+
+ inline BOOL CWnd::ShowWindowAsync(int nCmdShow) const
+ // The ShowWindowAsync function sets the show state of a window created by a different thread.
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::ShowWindowAsync(m_hWnd, nCmdShow);
+ }
+
+ inline BOOL CWnd::UnLockWindowUpdate() const
+ // Enables drawing in the window. Only one window can be locked at a time.
+ // Use LockWindowUpdate to disable drawing in the window
+ {
+ assert(::IsWindow(m_hWnd));
+ return ::LockWindowUpdate(0);
+ }
+
+ inline CWnd* CWnd::WindowFromDC(CDC* pDC) const
+ // The WindowFromDC function returns a handle to the window associated with the specified display device context (DC).
+ {
+ assert(pDC);
+ return FromHandle( ::WindowFromDC(pDC->GetHDC()) );
+ }
+
+ #endif
+
+}; // namespace Win32xx
+
+
+#endif // _WIN32XX_WINCORE_H_
+
diff --git a/mmc_updater/depends/win32cpp/winutils.h b/mmc_updater/depends/win32cpp/winutils.h
new file mode 100644
index 00000000..94ba2d80
--- /dev/null
+++ b/mmc_updater/depends/win32cpp/winutils.h
@@ -0,0 +1,649 @@
+// 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.
+//
+////////////////////////////////////////////////////////
+
+#ifndef _WIN32XX_WINUTILS_H_
+#define _WIN32XX_WINUTILS_H_
+
+
+// define useful macros from WindowsX.h
+#ifndef GET_X_LPARAM
+ #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#endif
+#ifndef GET_Y_LPARAM
+ #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+#endif
+
+// Define our own MIN and MAX macros
+// this avoids inconsistencies with Dev-C++ and other compilers, and
+// avoids conflicts between typical min/max macros and std::min/std::max
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+
+namespace Win32xx
+{
+ // Forward declarations
+ class CPoint;
+ class CRect;
+ CWinApp* GetApp();
+ void TRACE(LPCTSTR str);
+
+
+ /////////////////////////////////////////
+ // Definition of the CSize class
+ // This class can be used to replace the SIZE structure
+ class CSize : public SIZE
+ {
+ public:
+ CSize() { cx = 0; cy = 0; }
+ CSize(int CX, int CY) { cx = CX; cy = CY; }
+ CSize(SIZE sz) { cx = sz.cx; cy = sz.cy; }
+ CSize(POINT pt) { cx = pt.x; cy = pt.y; }
+ CSize(DWORD dw) { cx = (short)LOWORD(dw); cy = (short)HIWORD(dw); }
+ void SetSize(int CX, int CY) { cx = CX; cy = CY; }
+
+ // Operators
+ operator LPSIZE() { return this; }
+ BOOL operator == (SIZE sz) const { return (cx == sz.cx && cy == sz.cy); }
+ BOOL operator != (SIZE sz) const { return (cx != sz.cx || cy != sz.cy); }
+ void operator += (SIZE sz) { cx += sz.cx; cy += sz.cy; }
+ void operator -= (SIZE sz) { cx -= sz.cx; cy -= sz.cy; }
+
+ // Operators returning CSize
+ CSize operator - () const { return CSize (-cx, -cy); }
+ CSize operator + (SIZE sz) const { return CSize (cx + sz.cx, cy + sz.cy); }
+ CSize operator - (SIZE sz) const { return CSize (cx - sz.cx, cy - sz.cy); }
+
+ // Operators returning CPoint
+ CPoint operator + (POINT point) const;
+ CPoint operator - (POINT point) const;
+
+ // Operators returning CRect
+ CRect operator + (RECT rc) const;
+ CRect operator - (RECT rc) const;
+ };
+
+
+ /////////////////////////////////////////
+ // Definition of the CPoint class
+ // This class can be used to replace the POINT structure
+ class CPoint : public POINT
+ {
+ public:
+ CPoint() { x = 0; y = 0; }
+ CPoint(int X, int Y) { x = X; y = Y; }
+ CPoint(POINT pt) { x = pt.x ; y = pt.y; }
+ CPoint(POINTS pts) { x = pts.x; y = pts.y; }
+ CPoint(SIZE sz) { x = sz.cx; y = sz.cy; }
+ CPoint(DWORD dw) { x = (short) LOWORD(dw); y = (short) HIWORD(dw); }
+
+ void Offset(int dx, int dy) { x += dx; y += dy; }
+ void Offset(POINT pt) { x += pt.x; y += pt.y; }
+ void Offset(SIZE sz) { x += sz.cx; y += sz.cy; }
+ void SetPoint(int X, int Y) { x = X; y = Y; }
+
+ // Operators
+ operator LPPOINT() { return this; }
+ BOOL operator == (POINT pt) const { return ((x == pt.x) && (y == pt.y)); }
+ BOOL operator != (POINT pt) const { return ((x != pt.x) || (y != pt.y)); }
+ void operator += (SIZE sz) { x += sz.cx; y += sz.cy; }
+ void operator -= (SIZE sz) { x -= sz.cx; y -= sz.cy; }
+ void operator += (POINT pt) { x += pt.x; y += pt.y; }
+ void operator -= (POINT pt) { x -= pt.x; y -= pt.y; }
+
+ // Operators returning CPoint
+ CPoint operator - () const { return CPoint(-x, -y); }
+ CPoint operator + (SIZE sz) const { return CPoint(x + sz.cx, y + sz.cy); }
+ CPoint operator - (SIZE sz) const { return CPoint(x - sz.cx, y - sz.cy); }
+ CPoint operator + (POINT pt) const { return CPoint(x + pt.x, y + pt.y); }
+ CPoint operator - (POINT pt) const { return CPoint(x - pt.x, y - pt.y); }
+
+ // Operators returning CRect
+ CRect operator + (RECT rc) const;
+ CRect operator - (RECT rc) const;
+ };
+
+
+ /////////////////////////////////////////
+ // Definition of the CRect class
+ // This class can be used to replace the RECT structure.
+ class CRect : public RECT
+ {
+ public:
+ CRect() { left = top = right = bottom = 0; }
+ CRect(int l, int t, int r, int b) { left = l; top = t; right = r; bottom = b; }
+ CRect(RECT rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; }
+ CRect(POINT pt, SIZE sz) { right = (left = pt.x) + sz.cx; bottom = (top = pt.y) + sz.cy; }
+ CRect(POINT topLeft, POINT bottomRight) { left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; }
+
+ BOOL CopyRect(RECT rc) { return ::CopyRect(this, &rc); }
+ BOOL DeflateRect(int x, int y) { return ::InflateRect(this, -x, -y); }
+ BOOL DeflateRect(SIZE size) { return ::InflateRect(this, -size.cx, -size.cy); }
+ BOOL DeflateRect(RECT rc) { return ::InflateRect(this, rc.left - rc.right, rc.top - rc.bottom); }
+ BOOL DeflateRect(int l, int t, int r, int b){ return ::InflateRect(this, l - r, t - b); }
+ BOOL EqualRect(RECT rc) const { return ::EqualRect(&rc, this); }
+ BOOL InflateRect(int dx, int dy) { return ::InflateRect(this, dx, dy); }
+ BOOL InflateRect(SIZE sz) { return ::InflateRect(this, sz.cx, sz.cy); }
+ BOOL InflateRect(RECT rc) { return ::InflateRect(this, rc.right - rc.left, rc.bottom - rc.top); }
+ BOOL InflateRect(int l, int t, int r, int b){ return ::InflateRect(this, r - l, b - t); }
+ BOOL IntersectRect(RECT rc1, RECT rc2) { return ::IntersectRect(this, &rc1, &rc2); }
+ BOOL IsRectEmpty() const { return ::IsRectEmpty(this);}
+ BOOL IsRectNull() const { return (left == 0 && right == 0 && top == 0 && bottom == 0); }
+ CRect MulDiv(int nMult, int nDiv) const { return CRect ((left * nMult) / nDiv, (top * nMult) / nDiv,
+ (right * nMult) / nDiv, (bottom * nMult) / nDiv); }
+ void NormalizeRect() { int nTemp; if (left > right) { nTemp = left; left = right; right = nTemp; }
+ if (top > bottom) { nTemp = top; top = bottom; bottom = nTemp; } }
+ BOOL OffsetRect(int dx, int dy) { return ::OffsetRect(this, dx, dy); }
+ BOOL OffsetRect(POINT pt) { return ::OffsetRect(this, pt.x, pt.y); }
+ BOOL OffsetRect(SIZE size) { return ::OffsetRect(this, size.cx, size.cy); }
+ BOOL PtInRect(POINT pt) const { return ::PtInRect(this, pt); }
+ BOOL SetRect(int l, int t, int r, int b) { return ::SetRect(this, l, t, r, b); }
+ BOOL SetRect(POINT TopLeft, POINT BtmRight) { return ::SetRect(this, TopLeft.x, TopLeft.y, BtmRight.x, BtmRight.y); }
+ BOOL SetRectEmpty() { return ::SetRectEmpty(this); }
+ BOOL SubtractRect(RECT rc1, RECT rc2) { return ::SubtractRect(this, &rc1, &rc2); }
+ BOOL UnionRect(RECT rc1, RECT rc2) { return ::UnionRect(this, &rc1, &rc2); }
+
+ // Reposition rectangle
+ void MoveToX (int x) { right = Width() + x; left = x; }
+ void MoveToY (int y) { bottom = Height() + y; top = y; }
+ void MoveToXY (int x, int y) { MoveToX(x); MoveToY(y); }
+ void MoveToXY (POINT pt) { MoveToX (pt.x); MoveToY (pt.y); }
+
+ // Attributes
+ int Height() const { return bottom - top; }
+ int Width() const { return right - left; }
+ CSize Size() const { return CSize(Width(), Height()); }
+ CPoint CenterPoint() const { return CPoint((left + right) / 2, (top + bottom) / 2); }
+ CPoint TopLeft() const { return CPoint(left, top); }
+ CPoint BottomRight() const { return CPoint(right, bottom); }
+
+ // operators
+ operator LPRECT() { return this; }
+ BOOL operator == (RECT rc) const { return ::EqualRect(this, &rc); }
+ BOOL operator != (RECT rc) const { return !::EqualRect(this, &rc); }
+ void operator += (POINT pt) { ::OffsetRect(this, pt.x, pt.y); }
+ void operator += (SIZE size) { ::OffsetRect(this, size.cx, size.cy); }
+ void operator += (RECT rc) { ::InflateRect(this, rc.right - rc.left, rc.bottom - rc.top); }
+ void operator -= (RECT rc) { ::InflateRect(this, rc.left - rc.right, rc.top - rc.bottom); }
+ void operator -= (POINT pt) { ::OffsetRect(this, -pt.x, -pt.y); }
+ void operator -= (SIZE sz) { ::OffsetRect(this, -sz.cx, -sz.cy); }
+ void operator &= (RECT rc) { ::IntersectRect(this, this, &rc); }
+ void operator |= (RECT rc) { ::UnionRect(this, this, &rc); }
+
+ // Operators returning CRect
+ CRect operator + (POINT pt) const { CRect rc(*this); ::OffsetRect(&rc, pt.x, pt.y); return rc; }
+ CRect operator - (POINT pt) const { CRect rc(*this); ::OffsetRect(&rc, -pt.x, -pt.y); return rc; }
+ CRect operator + (SIZE sz) const { CRect rc(*this); ::OffsetRect(&rc, sz.cx, sz.cy); return rc; }
+ CRect operator - (SIZE sz) const { CRect rc(*this); ::OffsetRect(&rc, -sz.cx, -sz.cy); return rc; }
+ CRect operator + (RECT rc) const { CRect rc1(*this); rc1.InflateRect(rc); return rc1; }
+ CRect operator - (RECT rc) const { CRect rc1(*this); rc1.DeflateRect(rc); return rc1; }
+ CRect operator & (RECT rc) const { CRect rc1; ::IntersectRect(&rc1, this, &rc); return rc1; }
+ CRect operator | (RECT rc) const { CRect rc1; ::UnionRect(&rc1, this, &rc); return rc1; }
+ };
+
+ // CSize member function definitions
+ inline CPoint CSize::operator + (POINT pt) const { return CPoint(pt) + *this; }
+ inline CPoint CSize::operator - (POINT pt) const { return CPoint(pt) - *this; }
+ inline CRect CSize::operator + (RECT rc) const { return CRect(rc) + *this; }
+ inline CRect CSize::operator - (RECT rc) const { return CRect(rc) - *this; }
+
+ // CPoint member function definitions
+ inline CRect CPoint::operator + (RECT rc) const { return CRect(rc) + *this; }
+ inline CRect CPoint::operator - (RECT rc) const { return CRect(rc) - *this; }
+
+
+ ////////////////////////////////////////////////////////
+ // Classes and functions (typedefs) for text conversions
+ //
+ // This section defines the following text conversions:
+ // A2BSTR ANSI to BSTR
+ // A2OLE ANSI to OLE
+ // A2T ANSI to TCHAR
+ // A2W ANSI to WCHAR
+ // OLE2A OLE to ANSI
+ // OLE2T OLE to TCHAR
+ // OLE2W OLE to WCHAR
+ // T2A TCHAR to ANSI
+ // T2BSTR TCHAR to BSTR
+ // T2OLE TCHAR to OLE
+ // T2W TCHAR to WCHAR
+ // W2A WCHAR to ANSI
+ // W2BSTR WCHAR to BSTR
+ // W2OLE WCHAR to OLE
+ // W2T WCHAR to TCHAR
+
+ // About different character and string types:
+ // ------------------------------------------
+ // char (or CHAR) character types are ANSI (8 bits).
+ // wchar_t (or WCHAR) character types are Unicode (16 bits).
+ // TCHAR characters are Unicode if the _UNICODE macro is defined, otherwise they are ANSI.
+ // BSTR (Basic String) is a type of string used in Visual Basic and COM programming.
+ // OLE is the same as WCHAR. It is used in Visual Basic and COM programming.
+
+
+ // Forward declarations of our classes. They are defined later.
+ class CA2A;
+ class CA2W;
+ class CW2A;
+ class CW2W;
+ class CA2BSTR;
+ class CW2BSTR;
+
+ // typedefs for the well known text conversions
+ typedef CA2W A2W;
+ typedef CW2A W2A;
+ typedef CW2BSTR W2BSTR;
+ typedef CA2BSTR A2BSTR;
+ typedef CW2A BSTR2A;
+ typedef CW2W BSTR2W;
+
+#ifdef _UNICODE
+ typedef CA2W A2T;
+ typedef CW2A T2A;
+ typedef CW2W T2W;
+ typedef CW2W W2T;
+ typedef CW2BSTR T2BSTR;
+ typedef BSTR2W BSTR2T;
+#else
+ typedef CA2A A2T;
+ typedef CA2A T2A;
+ typedef CA2W T2W;
+ typedef CW2A W2T;
+ typedef CA2BSTR T2BSTR;
+ typedef BSTR2A BSTR2T;
+#endif
+
+ typedef A2W A2OLE;
+ typedef T2W T2OLE;
+ typedef CW2W W2OLE;
+ typedef W2A OLE2A;
+ typedef W2T OLE2T;
+ typedef CW2W OLE2W;
+
+ class CA2W
+ {
+ public:
+ CA2W(LPCSTR pStr) : m_pStr(pStr)
+ {
+ if (pStr)
+ {
+ // Resize the vector and assign null WCHAR to each element
+ int length = (int)strlen(pStr)+1;
+ m_vWideArray.assign(length, L'\0');
+
+ // Fill our vector with the converted WCHAR array
+ MultiByteToWideChar(CP_ACP, 0, pStr, -1, &m_vWideArray[0], length);
+ }
+ }
+ ~CA2W() {}
+ operator LPCWSTR() { return m_pStr? &m_vWideArray[0] : NULL; }
+ operator LPOLESTR() { return m_pStr? (LPOLESTR)&m_vWideArray[0] : (LPOLESTR)NULL; }
+ operator LPBSTR() { return m_pStr? (LPBSTR)&m_vWideArray[0] : (LPBSTR)NULL; }
+
+ private:
+ CA2W(const CA2W&);
+ CA2W& operator= (const CA2W&);
+ std::vector<wchar_t> m_vWideArray;
+ LPCSTR m_pStr;
+ };
+
+ class CW2A
+ {
+ public:
+ CW2A(LPCWSTR pWStr) : m_pWStr(pWStr)
+ {
+ // Resize the vector and assign null char to each element
+ int length = (int)wcslen(pWStr)+1;
+ m_vAnsiArray.assign(length, '\0');
+
+ // Fill our vector with the converted char array
+ WideCharToMultiByte(CP_ACP, 0, pWStr, -1, &m_vAnsiArray[0], length, NULL,NULL);
+ }
+
+ ~CW2A() {}
+ operator LPCSTR() { return m_pWStr? &m_vAnsiArray[0] : NULL; }
+
+ private:
+ CW2A(const CW2A&);
+ CW2A& operator= (const CW2A&);
+ std::vector<char> m_vAnsiArray;
+ LPCWSTR m_pWStr;
+ };
+
+ class CW2W
+ {
+ public:
+ CW2W(LPCWSTR pWStr) : m_pWStr(pWStr) {}
+ operator LPCWSTR() { return (LPWSTR)m_pWStr; }
+ operator LPOLESTR() { return (LPOLESTR)m_pWStr; }
+
+ private:
+ CW2W(const CW2W&);
+ CW2W& operator= (const CW2W&);
+
+ LPCWSTR m_pWStr;
+ };
+
+ class CA2A
+ {
+ public:
+ CA2A(LPCSTR pStr) : m_pStr(pStr) {}
+ operator LPCSTR() { return (LPSTR)m_pStr; }
+
+ private:
+ CA2A(const CA2A&);
+ CA2A& operator= (const CA2A&);
+
+ LPCSTR m_pStr;
+ };
+
+ class CW2BSTR
+ {
+ public:
+ CW2BSTR(LPCWSTR pWStr) { m_bstrString = ::SysAllocString(pWStr); }
+ ~CW2BSTR() { ::SysFreeString(m_bstrString); }
+ operator BSTR() { return m_bstrString;}
+
+ private:
+ CW2BSTR(const CW2BSTR&);
+ CW2BSTR& operator= (const CW2BSTR&);
+ BSTR m_bstrString;
+ };
+
+ class CA2BSTR
+ {
+ public:
+ CA2BSTR(LPCSTR pStr) { m_bstrString = ::SysAllocString(A2W(pStr)); }
+ ~CA2BSTR() { ::SysFreeString(m_bstrString); }
+ operator BSTR() { return m_bstrString;}
+
+ private:
+ CA2BSTR(const CA2BSTR&);
+ CA2BSTR& operator= (const CA2BSTR&);
+ BSTR m_bstrString;
+ };
+
+
+ ////////////////////////////////////////
+ // Global Functions
+ //
+
+ inline CWnd* FromHandle(HWND hWnd)
+ // Returns the CWnd object associated with the window handle
+ {
+ assert( GetApp() );
+ CWnd* pWnd = GetApp()->GetCWndFromMap(hWnd);
+ if (::IsWindow(hWnd) && pWnd == 0)
+ {
+ GetApp()->AddTmpWnd(hWnd);
+ pWnd = GetApp()->GetCWndFromMap(hWnd);
+ ::PostMessage(hWnd, UWM_CLEANUPTEMPS, 0, 0);
+ }
+
+ return pWnd;
+ }
+
+
+ inline CWinApp* GetApp()
+ // Returns a pointer to the CWinApp derrived class
+ {
+ return CWinApp::SetnGetThis();
+ }
+
+ inline CPoint GetCursorPos()
+ {
+ CPoint pt;
+ ::GetCursorPos(&pt);
+ return pt;
+ }
+
+ inline HBITMAP LoadBitmap (LPCTSTR lpszName)
+ {
+ assert(GetApp());
+
+ HBITMAP hBitmap = (HBITMAP)::LoadImage (GetApp()->GetResourceHandle(), lpszName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+ return hBitmap;
+ }
+
+ inline HBITMAP LoadBitmap (int nID)
+ {
+ return LoadBitmap(MAKEINTRESOURCE(nID));
+ }
+
+
+ inline void TRACE(LPCTSTR str)
+ // TRACE sends a string to the debug/output pane, or an external debugger
+ {
+ #ifdef _DEBUG
+ OutputDebugString(str);
+ #else
+ UNREFERENCED_PARAMETER(str); // no-op
+ #endif
+ }
+
+ #ifndef _WIN32_WCE // for Win32/64 operating systems, not WinCE
+
+ inline int GetWinVersion()
+ {
+ DWORD dwVersion = GetVersion();
+ int Platform = (dwVersion < 0x80000000)? 2:1;
+ int MajorVer = LOBYTE(LOWORD(dwVersion));
+ int MinorVer = HIBYTE(LOWORD(dwVersion));
+
+ int nVersion = 1000*Platform + 100*MajorVer + MinorVer;
+
+ // Return values and window versions:
+ // 1400 Windows 95
+ // 1410 Windows 98
+ // 1490 Windows ME
+ // 2400 Windows NT
+ // 2500 Windows 2000
+ // 2501 Windows XP
+ // 2502 Windows Server 2003
+ // 2600 Windows Vista and Windows Server 2008
+ // 2601 Windows 7
+
+ return nVersion;
+ }
+
+ inline int GetComCtlVersion()
+ {
+ // Load the Common Controls DLL
+ HMODULE hComCtl = ::LoadLibraryA("COMCTL32.DLL");
+ if (!hComCtl)
+ return 0;
+
+ int ComCtlVer = 400;
+
+ if (::GetProcAddress(hComCtl, "InitCommonControlsEx"))
+ {
+ // InitCommonControlsEx is unique to 4.7 and later
+ ComCtlVer = 470;
+
+ if (::GetProcAddress(hComCtl, "DllGetVersion"))
+ {
+ typedef HRESULT CALLBACK DLLGETVERSION(DLLVERSIONINFO*);
+ DLLGETVERSION* pfnDLLGetVersion = NULL;
+
+ pfnDLLGetVersion = (DLLGETVERSION*)::GetProcAddress(hComCtl, "DllGetVersion");
+ if(pfnDLLGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ dvi.cbSize = sizeof dvi;
+ if(NOERROR == pfnDLLGetVersion(&dvi))
+ {
+ DWORD dwVerMajor = dvi.dwMajorVersion;
+ DWORD dwVerMinor = dvi.dwMinorVersion;
+ ComCtlVer = 100 * dwVerMajor + dwVerMinor;
+ }
+ }
+ }
+ else if (::GetProcAddress(hComCtl, "InitializeFlatSB"))
+ ComCtlVer = 471; // InitializeFlatSB is unique to version 4.71
+ }
+
+ ::FreeLibrary(hComCtl);
+
+ // return values and DLL versions
+ // 400 dll ver 4.00 Windows 95/Windows NT 4.0
+ // 470 dll ver 4.70 Internet Explorer 3.x
+ // 471 dll ver 4.71 Internet Explorer 4.0
+ // 472 dll ver 4.72 Internet Explorer 4.01 and Windows 98
+ // 580 dll ver 5.80 Internet Explorer 5
+ // 581 dll ver 5.81 Windows 2000 and Windows ME
+ // 582 dll ver 5.82 Windows XP or Vista without XP themes
+ // 600 dll ver 6.00 Windows XP with XP themes
+ // 610 dll ver 6.10 Windows Vista with XP themes
+ // 616 dll ver 6.16 Windows Vista SP1 or Windows 7 with XP themes
+
+ return ComCtlVer;
+ }
+
+ inline UINT GetSizeofMenuItemInfo()
+ {
+ UINT uSize = sizeof(MENUITEMINFO);
+ // For Win95 and NT, cbSize needs to be 44
+ if (1400 == (GetWinVersion()) || (2400 == GetWinVersion()))
+ uSize = 44;
+
+ return uSize;
+ }
+
+ inline UINT GetSizeofNonClientMetrics()
+ {
+ // This function correctly determines the sizeof NONCLIENTMETRICS
+ UINT uSize = sizeof (NONCLIENTMETRICS);
+
+ #if (WINVER >= 0x0600)
+ if (GetWinVersion() < 2600 && (uSize > 500)) // Is OS version less than Vista
+ uSize -= sizeof(int); // Adjust size back to correct value
+ #endif
+
+ return uSize;
+ }
+
+
+
+ // A global function to report the state of the left mouse button
+ inline BOOL IsLeftButtonDown()
+ {
+ SHORT state;
+ if (GetSystemMetrics(SM_SWAPBUTTON))
+ // Mouse buttons are swapped
+ state = GetAsyncKeyState(VK_RBUTTON);
+ else
+ // Mouse buttons are not swapped
+ state = GetAsyncKeyState(VK_LBUTTON);
+
+ // returns true if the left mouse button is down
+ return (state & 0x8000);
+ }
+
+ inline BOOL IsAeroThemed()
+ {
+ BOOL bIsAeroThemed = FALSE;
+
+ // Test if Windows version is XP or greater
+ if (GetWinVersion() >= 2501)
+ {
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));
+ if(hMod)
+ {
+ // Declare pointers to IsCompositionActive function
+ FARPROC pIsCompositionActive = ::GetProcAddress(hMod, "IsCompositionActive");
+
+ if(pIsCompositionActive)
+ {
+ if(pIsCompositionActive())
+ {
+ bIsAeroThemed = TRUE;
+ }
+ }
+ ::FreeLibrary(hMod);
+ }
+ }
+
+ return bIsAeroThemed;
+ }
+
+ inline BOOL IsXPThemed()
+ {
+ BOOL bIsXPThemed = FALSE;
+
+ // Test if Windows version is XP or greater
+ if (GetWinVersion() >= 2501)
+ {
+ HMODULE hMod = ::LoadLibrary(_T("uxtheme.dll"));
+ if(hMod)
+ {
+ // Declare pointers to functions
+ FARPROC pIsAppThemed = ::GetProcAddress(hMod, "IsAppThemed");
+ FARPROC pIsThemeActive = ::GetProcAddress(hMod, "IsThemeActive");
+
+ if(pIsAppThemed && pIsThemeActive)
+ {
+ if(pIsAppThemed() && pIsThemeActive())
+ {
+ // Test if ComCtl32 dll used is version 6 or later
+ bIsXPThemed = (GetComCtlVersion() >= 600);
+ }
+ }
+ ::FreeLibrary(hMod);
+ }
+ }
+
+ return bIsXPThemed;
+ }
+
+ #endif // #ifndef _WIN32_WCE
+
+ // Required for WinCE
+ #ifndef lstrcpyn
+ inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength)
+ {
+ if(NULL == lpstrDest || NULL == lpstrSrc || nLength <= 0)
+ return NULL;
+ int nLen = MIN((int)lstrlen(lpstrSrc), nLength - 1);
+ LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR));
+ lpstrDest[nLen] = _T('\0');
+ return lpstrRet;
+ }
+ #endif // !lstrcpyn
+
+}
+
+
+#endif // _WIN32XX_WINUTILS_H_