summaryrefslogtreecommitdiffstats
path: root/mmc_updater/depends/win32cpp/dialog.h
diff options
context:
space:
mode:
authorAndrew <forkk@forkk.net>2013-12-09 12:04:05 -0600
committerAndrew <forkk@forkk.net>2013-12-09 12:04:05 -0600
commit7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c (patch)
tree52097b57dc7d18ec4e35ef3a8e554af2d91545e8 /mmc_updater/depends/win32cpp/dialog.h
parent9410dd042ea62224fa3e0eb3b525abbdf0c316ee (diff)
parent220e07aef4a34dca9f31ae0c5bb994e5c594125d (diff)
downloadMultiMC-7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c.tar
MultiMC-7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c.tar.gz
MultiMC-7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c.tar.lz
MultiMC-7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c.tar.xz
MultiMC-7f52bed9e3f559adcbcf3f3c1c7ac2251964db8c.zip
Merge branch 'feature_updater' into develop
Diffstat (limited to 'mmc_updater/depends/win32cpp/dialog.h')
-rw-r--r--mmc_updater/depends/win32cpp/dialog.h876
1 files changed, 876 insertions, 0 deletions
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_
+