/* * Copyright 1997, 1999 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ // WinPos.cpp : implementation file // #include "stdafx.h" #include "p4win.h" #include "WinPos.h" #include "RegKeyEx.h" #include "MainFrm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static LPCTSTR sRegKey = _T("Software\\Perforce\\P4Win\\Layout\\"); static LPCTSTR sRegValue_WindowPosition = _T("WindowPosition"); ///////////////////////////////////////////////////////////////////////////// // CWinPos CWinPos::CWinPos(bool noSize) : m_noSize(noSize) { m_pWnd = NULL; m_MinSize= CSize(0,0); m_DefPos = CRect(0,0,0,0); } void CWinPos::SetWindow( CWnd *pWnd, LPCTSTR windowName ) { m_pWnd= pWnd; m_WindowName= windowName; } bool CWinPos::RestoreWindowPosition() { ASSERT( m_pWnd != NULL ); ASSERT( !m_WindowName.IsEmpty() ); ///////////////// // Restore window size and context from registry CRect rect; m_pWnd->GetWindowRect(&rect); // If we don't get a registry value, // make sure we have enough height // so as to not trigger a vertical scrollbar rect.InflateRect( 0, 0, 0, 50 ); bool rc = ReadRegistry(&rect); rect.NormalizeRect(); if(rect.Width() < m_MinSize.cx) rect.right= rect.left + m_MinSize.cx; if(rect.Height() <= m_MinSize.cy) rect.bottom= rect.top + m_MinSize.cy + GetSystemMetrics(SM_CYHSCROLL) * 2; if(rect.Width() < 50 || rect.Height() < 50) { // Might have a bad reg value, so set a reasonable default rect= CRect(GetSystemMetrics(SM_CXSCREEN) /10, GetSystemMetrics(SM_CYSCREEN) /10, GetSystemMetrics(SM_CXSCREEN) * 9/10, GetSystemMetrics(SM_CYSCREEN) * 9/10); } else { // If rectangle bigger than screen, shrink/shift as required // (some 8-ball may have changed video res since we last ran) int reduceX= 0; if (MainFrame()->m_NbrDisplays < 2) reduceX= max( rect.Width() - GetSystemMetrics(SM_CXSCREEN), 0 ); int reduceY= max( rect.Height() - GetSystemMetrics(SM_CYSCREEN), 0 ); rect.DeflateRect(reduceX/2, reduceY/2); int shiftX= 0; if (MainFrame()->m_NbrDisplays < 2) shiftX= max( rect.right - GetSystemMetrics(SM_CXSCREEN), 0); int shiftY= max( rect.bottom - GetSystemMetrics(SM_CYSCREEN), 0); rect.OffsetRect(-shiftX, -shiftY); } ///////////////// // Set the size of the window WINDOWPLACEMENT place; place.showCmd=SW_NORMAL; place.flags=WPF_SETMINPOSITION; place.length= sizeof(WINDOWPLACEMENT); place.ptMinPosition=CPoint(0,0); place.ptMaxPosition=CPoint(-::GetSystemMetrics(SM_CXBORDER), -::GetSystemMetrics(SM_CYBORDER)); place.rcNormalPosition= rect; m_pWnd->SetWindowPlacement(&place); return rc; } void CWinPos::SaveWindowPosition() { ASSERT( m_pWnd != NULL ); ASSERT( !m_WindowName.IsEmpty() ); WINDOWPLACEMENT place; if(m_pWnd->GetWindowPlacement(&place)) { WriteRegistry(&place.rcNormalPosition); } } void CWinPos::WriteRegistry( RECT *rect ) { // Save values to registry. Fail silently if unable to write. CString keyName= sRegKey + m_WindowName; CRegKeyEx regKey; if(regKey.Create(HKEY_CURRENT_USER, keyName) == ERROR_SUCCESS) { CString str; if(m_noSize) str.Format(_T("%d,%d"), rect->top, rect->left); else str.Format(_T("%d,%d,%d,%d"), rect->top, rect->left, rect->right- rect->left, rect->bottom-rect->top); regKey.SetValueString(str, sRegValue_WindowPosition); } } bool CWinPos::ReadRegistry( RECT *rect ) { CString keyName= sRegKey + m_WindowName; // Look in the registry for the window rect, and assign it if it is // a valid rect CRegKeyEx regKey; if(regKey.Open(HKEY_CURRENT_USER, keyName, KEY_READ) == ERROR_SUCCESS) { CString result = regKey.QueryValueString(sRegValue_WindowPosition); if(!result.IsEmpty()) { int top= GetPositiveNumber(result); int left= GetPositiveNumber(result); int width,height; if(m_noSize) { width = rect->right - rect->left; height = rect->bottom - rect->top; } else { width= GetPositiveNumber(result); height= GetPositiveNumber(result); } if(left >=0 && top >= 0 && width > 0 && height > 0) { width= min( width, GetSystemMetrics(SM_CXSCREEN)); height= min( height, GetSystemMetrics(SM_CYSCREEN)); if (MainFrame()->m_NbrDisplays > 1) rect->left= left; else rect->left= min(left, GetSystemMetrics(SM_CXSCREEN)-width); rect->top= min(top, GetSystemMetrics(SM_CYSCREEN)-height); rect->right= rect->left+width; rect->bottom= rect->top+height; } return true; } } // failed to get something from the registry, // so see if there is a default position if (m_DefPos.Width() && m_DefPos.Height()) { rect->top = m_DefPos.top; rect->bottom= m_DefPos.bottom; rect->left = m_DefPos.left; rect->right = m_DefPos.right; } return false; }