Renew the updater branch
Now with some actual consensus on what the updater will do!
This commit is contained in:
876
mmc_updater/depends/win32cpp/dialog.h
Normal file
876
mmc_updater/depends/win32cpp/dialog.h
Normal file
@ -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_
|
||||
|
Reference in New Issue
Block a user