// cdxCDynamicControlsManager.cpp: implementation of the cdxCDynamicControlsManager class.
//
//////////////////////////////////////////////////////////////////////
/*
* you should define OEMRESOURCE
* in your project settings (C/C++, General) !
*/
#include "stdafx.h"
#include "cdxCDynamicControlsManager.h"
#include <winuser.h>
#include <afxmt.h>
#ifndef OBM_SIZE
#define OBM_SIZE 32766
#pragma message("*** NOTE: cdxCDynamicControlsManager.cpp: Please define OEMRESOURCE in your project settings !")
// taken from WinresRc.h
// if not used for any reason
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Some static variables
/////////////////////////////////////////////////////////////////////////////
#define REGVAL_NOSTATE -1
#define REGVAL_VISIBLE 1
#define REGVAL_HIDDEN 0
#define REGVAL_MAXIMIZED 1
#define REGVAL_ICONIC 0
#define REGVAL_INVALID 0
#define REGVAL_VALID 1
/*
* registry value names
* (for StoreWindowPosition()/RestoreWindowPosition())
*/
static LPCTSTR lpszRegVal_Left = _T("Left"),
lpszRegVal_Right = _T("Right"),
lpszRegVal_Top = _T("Top"),
lpszRegVal_Bottom = _T("Bottom"),
lpszRegVal_Visible = _T("Visibility"),
lpszRegVal_State = _T("State"),
lpszRegVal_Valid = _T("(valid)");
/////////////////////////////////////////////////////////////////////////////
// cdxCDynamicControlsManager::ControlData::ControlEntry
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// construction/destruction
/////////////////////////////////////////////////////////////////////////////
cdxCDynamicControlsManager::ControlData::ControlEntry::ControlEntry(CWnd & ctrl, ControlData & rMaster)
: m_rMaster(rMaster), m_rCtrl(ctrl)
{
if(m_pNext = rMaster.m_pCtrl)
m_pNext->m_pPrev = this;
rMaster.m_pCtrl = this;
m_pPrev = NULL;
}
cdxCDynamicControlsManager::ControlData::ControlEntry::~ControlEntry()
{
if(m_pPrev)
{
if(m_pPrev->m_pNext = m_pNext)
m_pNext->m_pPrev = m_pPrev;
}
else
{
ASSERT( m_rMaster.m_pCtrl == this );
if(m_rMaster.m_pCtrl = m_pNext)
m_pNext->m_pPrev = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// cdxCDynamicControlsManager::ControlData
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// construction/destruction
/////////////////////////////////////////////////////////////////////////////
/*
* constructor
* copies all paramaters and gets the controls initial position using
* GetWindowPos().
*
* NOTE that the constructor need ctrl.m_hWnd to exist (in contrast to
* Add()
*/
cdxCDynamicControlsManager::ControlData::ControlData(cdxCDynamicControlsManager & rMaster, CWnd & ctrl, const PositionSetup & rPosSetup)
: m_rMaster(rMaster), m_pCtrl(NULL),
m_pNext(NULL), m_pPrev(NULL),
m_posSetup(rPosSetup)
{
ASSERT(::IsWindow(ctrl.m_hWnd)); // control must have already been created !
ASSERT(rPosSetup.IsValid());
//
// get initial values
//
WINDOWPLACEMENT wpl;
VERIFY( ctrl.GetWindowPlacement(&wpl) );
m_rectOriginal = wpl.rcNormalPosition;
//
// remember control
//
new ControlEntry(ctrl,*this);
ASSERT(m_pCtrl != NULL);
//
// link us to the cdxCDynamicControlsManager's list
//
if(m_pNext = m_rMaster.m_pFirst)
m_pNext->m_pPrev = this;
m_pPrev = NULL;
m_rMaster.m_pFirst = this;
}
/*
* detach from list
* The m_Ctrl deletes all children by itself
*/
cdxCDynamicControlsManager::ControlData::~ControlData()
{
//
// delete all control references
//
while(m_pCtrl)
delete m_pCtrl;
//
// unlink from list
//
if(m_pPrev)
{
if(m_pPrev->m_pNext = m_pNext)
m_pNext->m_pPrev = m_pPrev;
}
else
{
ASSERT(m_rMaster.m_pFirst == this);
if(m_rMaster.m_pFirst = m_pNext)
m_pNext->m_pPrev = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// cdxCDynamicControlsManager::ControlData virtuals
/////////////////////////////////////////////////////////////////////////////
/*
* checks whether the CWnd is part of this control data
*/
bool cdxCDynamicControlsManager::ControlData::IsMember(CWnd & ctrl) const
{
for(const ControlEntry *pEntry = m_pCtrl; pEntry; pEntry = pEntry->GetNext())
if(*pEntry == ctrl)
return true;
return false;
}
/*
* removes a CWnd from this chain
*/
bool cdxCDynamicControlsManager::ControlData::Rem(CWnd & ctrl)
{
for(ControlEntry *pEntry = m_pCtrl; pEntry; pEntry = pEntry->GetNext())
if(*pEntry == ctrl)
{
delete pEntry;
return true;
}
return false;
}
/*
* Get current position
*/
CRect cdxCDynamicControlsManager::ControlData::GetCurrentPosition() const
{
if(!IsUsed())
{
ASSERT(false); // all sub-controls have been deleted
return CRect(0,0,0,0);
}
WINDOWPLACEMENT wpl;
VERIFY( m_pCtrl->GetCWnd().GetWindowPlacement(&wpl) );
return CRect(wpl.rcNormalPosition);
}
/*
* modify initial setup
* NOTE: this function does not move the controls.
* You habe to call cdxCDynamicControlsManager::ReorganizeControls past
* using this function
*/
bool cdxCDynamicControlsManager::ControlData::Modify(const CRect & rectOriginal, const PositionSetup & rSetup)
{
if((rectOriginal.left > rectOriginal.right) ||
(rectOriginal.top > rectOriginal.bottom) ||
!rSetup.IsValid())
{
ASSERT(false); // bad function call
return false;
}
m_rectOriginal = rectOriginal;
m_posSetup = rSetup;
return true;
}
/////////////////////////////////////////////////////////////////////////////
// cdxCDynamicControlsManager
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// handling events from CWnd
/////////////////////////////////////////////////////////////////////////////
/*
* this function initializes the following members:
* m_pWnd - the window handle
* m_szCurrent - the current window's size
* m_szMin - the minimum window's size (taken from current size)
* m_szMax - the maximum window's size (set to (0,0) <=> don't change maximum)
* m_wndSizeIcon - the icon (if wanted)
*
* parameters:
* rWnd - the window to supervise
* fd - in which directions can we size the window (does only apply to user-sizing)
* bSizeIcon - do you want a sizable icon ?
* pBaseClientSize- if non-zero, this defines the real (normal) size of the
* window relative to all furher calculations will be made.
* if zero, the current window's size will be taken.
*/
void cdxCDynamicControlsManager::DoInitWindow(CWnd & rWnd, Freedom fd, bool bSizeIcon, const CSize * pBaseClientSize)
{
ASSERT(m_pWnd == NULL); // you MUST NOT call this function twice !
ASSERT(::IsWindow(rWnd.m_hWnd)); // rWnd MUST already exist !!
m_pWnd = &rWnd;
m_Freedom = fd;
//
// get current's window size
//
CRect rect;
m_pWnd->GetWindowRect(&rect);
CRect rectClient;
m_pWnd->GetClientRect(&rectClient);
if(!pBaseClientSize)
{
m_szClientRelative.cx = rectClient.Width();
m_szClientRelative.cy = rectClient.Height();
m_szMin.cx = rect.Width();
m_szMin.cy = rect.Height();
}
else
{
ASSERT((pBaseClientSize->cx > 0) && (pBaseClientSize->cy > 0));
m_szClientRelative = *pBaseClientSize;
m_szMin.cx = m_szClientRelative.cx + (rect.Width() - rectClient.Width());
m_szMin.cy = m_szClientRelative.cy + (rect.Height() - rectClient.Height());
}
m_szMax.cx = 0
- 1
- 2
前往页