www.pudn.com > LED.rar > cdxCDynamicWndEx.cpp


// cdxCDynamicWndEx.cpp: implementation of the cdxCDynamicWndEx class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "cdxCDynamicWndEx.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// Some static variables (taken from cdxCDynamicControlsManager) 
///////////////////////////////////////////////////////////////////////////// 
 
#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)"); 
 
LPCTSTR	cdxCDynamicWndEx::M_lpszAutoPosProfileSection	=	_T("WindowPositions"); 
 
///////////////////////////////////////////////////////////////////////////// 
// cdxCDynamicWndEx 
///////////////////////////////////////////////////////////////////////////// 
 
///////////////////////////////////////////////////////////////////////////// 
// cdxCDynamicWndEx stretches windows 
///////////////////////////////////////////////////////////////////////////// 
 
static inline CString _makeFullProfile(LPCTSTR lpszBase, const CString & str) 
{ 
	CString	s	=	lpszBase; 
 
	if(s.GetLength() && (s[s.GetLength()-1] != _T('\\'))) 
		s	+=	_T('\\'); 
 
	s	+=	str; 
	return s; 
} 
 
void cdxCDynamicWndEx::OnInitialized() 
{ 
	ASSERT(IsWindow()); 
 
	if(!m_strAutoPos.IsEmpty()) 
	{ 
		if(!RestoreWindowPosition(_makeFullProfile(M_lpszAutoPosProfileSection,m_strAutoPos),rflg_all)) 
		{ 
			Window()->CenterWindow(); 
			StretchWindow(10); 
		} 
	} 
} 
 
void cdxCDynamicWndEx::OnDestroying() 
{ 
	if(!m_strAutoPos.IsEmpty() && IsWindow()) 
		StoreWindowPosition(_makeFullProfile(M_lpszAutoPosProfileSection,m_strAutoPos)); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// cdxCDynamicWndEx stretches windows 
///////////////////////////////////////////////////////////////////////////// 
 
/* 
 * stretches the window by szDelta (i.e. if szDelta is 100, the window is enlarged by 100 pixels) 
 * stretching means that the center point of the window remains 
 * 
 * returns false if the window would be smaller than (1,1) 
 * 
 * NOTE: this function does NOT care of the min/max dimensions of a window 
 *			Use MoveWindow() if you need to take care of it. 
 * 
 * STATIC 
 */ 
 
bool cdxCDynamicWndEx::StretchWindow(const CSize & szDelta) 
{ 
	if(!IsWindow()) 
	{ 
		ASSERT(false); 
		return false; 
	} 
 
	CWnd	*pWnd	=	Window(); 
 
	WINDOWPLACEMENT	wpl; 
	pWnd->GetWindowPlacement(&wpl); 
 
	wpl.rcNormalPosition.left		-=	szDelta.cx / 2; 
	wpl.rcNormalPosition.right		+=	(szDelta.cx + 1) / 2; 
	wpl.rcNormalPosition.top		-=	szDelta.cy / 2; 
	wpl.rcNormalPosition.bottom	+=	(szDelta.cy + 1) / 2; 
//	wpl.flags	=	SW_SHOWNA|SW_SHOWNOACTIVATE; 
 
	if((wpl.rcNormalPosition.left >= wpl.rcNormalPosition.right) || 
		(wpl.rcNormalPosition.top >= wpl.rcNormalPosition.bottom)) 
		return false; 
 
	VERIFY( pWnd->SetWindowPos(NULL, 
										wpl.rcNormalPosition.left, 
										wpl.rcNormalPosition.top, 
										wpl.rcNormalPosition.right - wpl.rcNormalPosition.left, 
										wpl.rcNormalPosition.bottom - wpl.rcNormalPosition.top, 
										SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER) ); 
 
	return true; 
} 
 
/* 
 * stretch window by a percent value 
 * the algorithm calculates the new size for both dimensions by: 
 * 
 *  newWid = oldWid + (oldWid * iAddPcnt) / 100 
 * 
 * NOTE: iAddPcnt may even be nagtive, but it MUST be greater than -100. 
 * NOTE: this function does NOT care of the min/max dimensions of a window 
 * 
 * The function will return false if the new size would be empty. 
 */ 
 
bool cdxCDynamicWndEx::StretchWindow(int iAddPcnt) 
{ 
	if(!IsWindow()) 
	{ 
		ASSERT(false); 
		return false; 
	} 
 
	CSize	szDelta	=	GetCurrentClientSize() + GetBorderSize(); 
 
	szDelta.cx	=	(szDelta.cx * iAddPcnt) / 100; 
	szDelta.cy	=	(szDelta.cy * iAddPcnt) / 100; 
 
	return StretchWindow(szDelta); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// cdxCDynamicWndEx registry positioning 
///////////////////////////////////////////////////////////////////////////// 
 
/* 
 * stores a window's position and visiblity to the registry. 
 *	return false if any error occured 
 */ 
 
bool cdxCDynamicWndEx::StoreWindowPosition(LPCTSTR lpszProfile) 
{ 
	if(!IsWindow() || !lpszProfile || !*lpszProfile) 
	{ 
		ASSERT(false); 
		return false; 
	} 
 
	CWnd	*pWnd	=	Window(); 
 
	WINDOWPLACEMENT	wpl; 
	VERIFY( pWnd->GetWindowPlacement(&wpl) ); 
 
	BOOL	bVisible	=	pWnd->IsWindowVisible(); 
	int	iState	=	REGVAL_NOSTATE; 
 
	if(pWnd->IsIconic()) 
		iState	=	REGVAL_ICONIC; 
	else 
		if(pWnd->IsZoomed()) 
			iState	=	REGVAL_MAXIMIZED; 
 
	CWinApp	*app	=	AfxGetApp(); 
 
	if(!app->m_pszRegistryKey || !*app->m_pszRegistryKey) 
	{ 
		TRACE(_T("*** NOTE[cdxCDynamicWndEx::StoreWindowPosition()]: To properly store and restore a window's position, please call CWinApp::SetRegistryKey() in you app's InitInstance() !\n")); 
		return false; 
	} 
 
	return	app->WriteProfileInt(lpszProfile,	lpszRegVal_Valid,	REGVAL_INVALID) &&	// invalidate first 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Left,		wpl.rcNormalPosition.left) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Right,		wpl.rcNormalPosition.right) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Top,		wpl.rcNormalPosition.top) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Bottom,	wpl.rcNormalPosition.bottom) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Visible,	bVisible ? REGVAL_VISIBLE : REGVAL_HIDDEN) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_State,		iState) && 
				app->WriteProfileInt(lpszProfile,	lpszRegVal_Valid,	REGVAL_VALID);		// validate position 
} 
 
/* 
 * load the registry data stored by StoreWindowPosition() 
 * returns true if data have been found in the registry 
 */ 
 
bool cdxCDynamicWndEx::RestoreWindowPosition(LPCTSTR lpszProfile, UINT restoreFlags) 
{ 
	if(!IsWindow() || !lpszProfile || !*lpszProfile) 
	{ 
		ASSERT(false); 
		return false; 
	} 
 
	CWnd		*pWnd	=	Window(); 
	CWinApp	*app	=	AfxGetApp(); 
 
	if(!app->m_pszRegistryKey || !*app->m_pszRegistryKey) 
	{ 
		TRACE(_T("*** NOTE[cdxCDynamicWndEx::RestoreWindowPosition()]: To properly store and restore a window's position, please call CWinApp::SetRegistryKey() in you app's InitInstance() !\n")); 
		return false; 
	} 
 
	// 
	// first, we check whether the position had been saved successful any time before 
	// 
 
	if( app->GetProfileInt(lpszProfile,lpszRegVal_Valid,REGVAL_INVALID) != REGVAL_VALID ) 
		return false; 
 
	// 
	// get old position 
	// 
 
	WINDOWPLACEMENT	wpl; 
	VERIFY( pWnd->GetWindowPlacement(&wpl) ); 
 
	// 
	// read registry 
	// 
 
	int	iState	=	app->GetProfileInt(lpszProfile,	lpszRegVal_State, REGVAL_NOSTATE); 
 
	// 
	// get window's previous normal position 
	// 
 
	wpl.rcNormalPosition.left		=	app->GetProfileInt(lpszProfile,	lpszRegVal_Left,		wpl.rcNormalPosition.left); 
	wpl.rcNormalPosition.right		=	app->GetProfileInt(lpszProfile,	lpszRegVal_Right,		wpl.rcNormalPosition.right); 
	wpl.rcNormalPosition.top		=	app->GetProfileInt(lpszProfile,	lpszRegVal_Top,		wpl.rcNormalPosition.top); 
	wpl.rcNormalPosition.bottom	=	app->GetProfileInt(lpszProfile,	lpszRegVal_Bottom,	wpl.rcNormalPosition.bottom); 
 
	if(wpl.rcNormalPosition.left > wpl.rcNormalPosition.right) 
	{ 
		long	l	=	wpl.rcNormalPosition.right; 
		wpl.rcNormalPosition.right	=	wpl.rcNormalPosition.left; 
		wpl.rcNormalPosition.left	=	l; 
	} 
	if(wpl.rcNormalPosition.top > wpl.rcNormalPosition.bottom) 
	{ 
		long	l	=	wpl.rcNormalPosition.bottom; 
		wpl.rcNormalPosition.bottom	=	wpl.rcNormalPosition.top; 
		wpl.rcNormalPosition.top	=	l; 
	} 
 
	// 
	// get restore stuff 
	// 
 
	UINT	showCmd	=	SW_SHOWNA; 
	 
	if(restoreFlags & rflg_state) 
	{ 
		if(iState == REGVAL_MAXIMIZED) 
			showCmd	=	SW_MAXIMIZE; 
		else 
			if(iState == REGVAL_ICONIC) 
				showCmd	=	SW_MINIMIZE; 
	} 
 
	// 
	// use MoveWindow() which takes care of WM_GETMINMAXINFO 
	// 
 
	pWnd->MoveWindow(	wpl.rcNormalPosition.left,wpl.rcNormalPosition.top, 
							wpl.rcNormalPosition.right - wpl.rcNormalPosition.left, 
							wpl.rcNormalPosition.bottom - wpl.rcNormalPosition.top, 
							showCmd == SW_SHOWNA); 
 
	if(showCmd != SW_SHOWNA) 
	{ 
		// read updated position 
 
		VERIFY( pWnd->GetWindowPlacement(&wpl) ); 
		wpl.showCmd	=	showCmd; 
		pWnd->SetWindowPlacement(&wpl); 
	} 
	 
	// 
	// get visiblity 
	// 
 
	if(restoreFlags & rflg_visibility) 
	{ 
		int	i	=	app->GetProfileInt(lpszProfile,	lpszRegVal_Visible, REGVAL_NOSTATE); 
		if(i == REGVAL_VISIBLE) 
			pWnd->ShowWindow(SW_SHOW); 
		else 
			if(i == REGVAL_HIDDEN) 
				pWnd->ShowWindow(SW_HIDE); 
	} 
 
	return true; 
}