📄 cdxcdynamiccontrolsmanager.cpp
字号:
// 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_FILEstatic 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; // raise total counter ++rMaster.m_rMaster.m_iTotalCnt;}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; } // lower ASSERT( m_rMaster.m_rMaster.m_iTotalCnt > 0 ); ++m_rMaster.m_rMaster.m_iTotalCnt;}/////////////////////////////////////////////////////////////////////////////// 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; m_szMax.cy = 0; // // set up icon if wanted // if(bSizeIcon) { VERIFY( m_pWndSizeIcon = new cdxCSizeIconCtrl ); VERIFY( m_pWndSizeIcon->Create(m_pWnd,m_idSizeIcon) ); // creates my control; id is SIZE_CONTROL_ID AddSzControl(*m_pWndSizeIcon,mdRepos,mdRepos); m_pWndSizeIcon->ShowWindow(SW_SHOW); // finally - show it }}//////////////////////////////////////////////////////////////////////////////* * fill in MINMAXINFO as requested * Call your CWnd's OnGetMinMaxInfo first ! * * changed due to a but report by Michel Wassink <mww@mitutoyo.nl> */void cdxCDynamicControlsManager::DoOnGetMinMaxInfo(MINMAXINFO FAR* lpMMI){ if(IsReady() && !IsDisabled()) { lpMMI->ptMinTrackSize.x = m_szMin.cx; lpMMI->ptMinTrackSize.y = m_szMin.cy; if(m_Freedom & fdHoriz) { if(m_szMax.cx) lpMMI->ptMaxTrackSize.x = m_szMax.cx; } else lpMMI->ptMaxTrackSize.x = m_szMin.cx; if(m_Freedom & fdVert) { if(m_szMax.cy) lpMMI->ptMaxTrackSize.y = m_szMax.cy; } else lpMMI->ptMaxTrackSize.y = m_szMin.cy; }}/* * handle OnSize - we can't rely on cx,cy being client dimensions * as stated in the documentation ... */void cdxCDynamicControlsManager::DoOnSize(UINT nType, int cx, int cy){ if(IsReady() && (nType != SIZE_MINIMIZED) && !IsDisabled()) ReorganizeControls(true);}/* * free all memory * after having called this function, you can reuse the object * although I wouldn't recommend to do so :) */void cdxCDynamicControlsManager::DoDestroyWindow(){ while(m_pFirst) { OnDeleteControlPosition(*m_pFirst); delete m_pFirst; } if(m_pWndSizeIcon) { if(::IsWindow(m_pWndSizeIcon->m_hWnd)) m_pWndSizeIcon->DestroyWindow(); delete m_pWndSizeIcon; m_pWndSizeIcon = NULL; } m_pWnd = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -