khanat-opennel-code/code/nel/tools/logic/logic_editor_dll/ResizableSheet.cpp
2011-04-29 19:15:53 +02:00

402 lines
9.6 KiB
C++

// ResizableSheet.cpp : implementation file
//
/////////////////////////////////////////////////////////////////////////////
//
// Modified 14/09/2000 by David Fleury
// get rid if the "resizable" stuff, just kept the auto arrange of controls
//
// Copyright (C) 2000 by Paolo Messina
// (ppescher@yahoo.com)
//
// Free for non-commercial use.
// You may change the code to your needs,
// provided that credits to the original
// author is given in the modified files.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ResizableSheet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CResizableSheet
IMPLEMENT_DYNAMIC(CResizableSheet, CPropertySheet)
inline void CResizableSheet::Construct()
{
m_bInitDone = FALSE;
m_bEnableSaveRestore = FALSE;
m_bSavePage = FALSE;
}
CResizableSheet::CResizableSheet()
{
Construct();
}
CResizableSheet::CResizableSheet(UINT nIDCaption, CWnd *pParentWnd, UINT iSelectPage)
: CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
Construct();
}
CResizableSheet::CResizableSheet(LPCTSTR pszCaption, CWnd *pParentWnd, UINT iSelectPage)
: CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
Construct();
}
CResizableSheet::~CResizableSheet()
{
}
BEGIN_MESSAGE_MAP(CResizableSheet, CPropertySheet)
//{{AFX_MSG_MAP(CResizableSheet)
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_BN_CLICKED(ID_WIZBACK, OnPageChanged)
ON_BN_CLICKED(ID_WIZNEXT, OnPageChanged)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResizableSheet message handlers
int CResizableSheet::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CPropertySheet::OnCreate(lpCreateStruct) == -1)
return -1;
/*********************************/
// MODIFIED 14/09/2000 Fleury David, I don't want the user to be able to resize the sheet
// // change window style to be resizable
// ModifyStyle(0,/* WS_THICKFRAME |*/ WS_CLIPCHILDREN);
/*********************************/
return 0;
}
BOOL CResizableSheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
// prevent flickering
GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS);
m_bInitDone = TRUE;
return bResult;
}
void CResizableSheet::OnDestroy()
{
CPropertySheet::OnDestroy();
if (m_bEnableSaveRestore)
{
SaveWindowRect();
}
CPropertySheet::OnDestroy();
}
// maps an index to a button ID and vice-versa
static UINT _propButtons[] =
{
IDOK, IDCANCEL, ID_APPLY_NOW, IDHELP,
ID_WIZBACK, ID_WIZNEXT, ID_WIZFINISH
};
// horizontal line in wizard mode
#define ID_WIZLINE ID_WIZFINISH+1
void CResizableSheet::PresetLayout()
{
CWnd* pWnd; // points to various children
CRect wndrc, objrc;
GetClientRect(&wndrc);
// tab control or wizard line position
if (m_psh.dwFlags & PSH_WIZARD) // wizard mode
{
// get wizard line's bottom-right corner
pWnd = GetDlgItem(ID_WIZLINE);
// hide tab control
GetTabControl()->ShowWindow(SW_HIDE);
}
else // tabbed mode
{
// get tab control's bottom-right corner
pWnd = GetTabControl();
}
// whatever it is, take the right margin
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
m_szLayoutTabLine.cx = objrc.right - wndrc.right;
m_szLayoutTabLine.cy = objrc.bottom - wndrc.bottom;
// get child dialog's bottom-right corner
pWnd = GetActivePage();
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
m_szLayoutPage.cx = objrc.right - wndrc.right;
m_szLayoutPage.cy = objrc.bottom - wndrc.bottom;
// store buttons position
for (int i = 0; i < 7; i++)
{
pWnd = GetDlgItem(_propButtons[i]);
if (pWnd == NULL)
{
// invalid position, button does not exist
// (just to initialize, any button you may activate
// in the future is present, but hidden)
m_szLayoutButton[i].cx = 0;
m_szLayoutButton[i].cy = 0;
continue;
}
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
m_szLayoutButton[i].cx = objrc.left - wndrc.right;
m_szLayoutButton[i].cy = objrc.top - wndrc.bottom;
}
}
void CResizableSheet::ArrangeLayout()
{
// init some vars
CWnd* pWnd;
CRect wndrc, objrc;
GetClientRect(&wndrc);
// usually no more than
// 4 buttons +
// 1 tab control or wizard line +
// 1 active page
HDWP hdwp = BeginDeferWindowPos(6);
if (m_psh.dwFlags & PSH_WIZARD) // wizard mode
{
// get wizard line's bottom-right corner
pWnd = GetDlgItem(ID_WIZLINE);
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
int oldHeight = objrc.Height();
objrc.right = m_szLayoutTabLine.cx + wndrc.right;
objrc.bottom = m_szLayoutTabLine.cy + wndrc.bottom;
objrc.top = objrc.bottom - oldHeight;
// add the control
DeferWindowPos(hdwp, *pWnd, NULL, objrc.left, objrc.top,
objrc.Width(), objrc.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
}
else // tabbed mode
{
// get tab control's bottom-right corner
pWnd = GetTabControl();
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
objrc.right = m_szLayoutTabLine.cx + wndrc.right;
objrc.bottom = m_szLayoutTabLine.cy + wndrc.bottom;
// add the control, only resize
DeferWindowPos(hdwp, *pWnd, NULL, 0, 0, objrc.Width(),
objrc.Height(), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
// get child dialog's bottom-right corner
pWnd = GetActivePage();
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
objrc.right = m_szLayoutPage.cx + wndrc.right;
objrc.bottom = m_szLayoutPage.cy + wndrc.bottom;
// add the control, only resize
DeferWindowPos(hdwp, *pWnd, NULL, 0, 0, objrc.Width(),
objrc.Height(), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
// arrange buttons position
for (int i = 0; i < 7; i++)
{
pWnd = GetDlgItem(_propButtons[i]);
if (pWnd == NULL)
continue; // ignores deleted buttons
// this should never happen, because all the buttons you
// may activate already exist at time PresetLayout is called
ASSERT(m_szLayoutButton[i].cx != 0 || m_szLayoutButton[i].cy != 0);
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
objrc.left = m_szLayoutButton[i].cx + wndrc.right;
objrc.top = m_szLayoutButton[i].cy + wndrc.bottom;
// add the control, only move
DeferWindowPos(hdwp, *pWnd, NULL, objrc.left, objrc.top,
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
// go re-arrange child windows
EndDeferWindowPos(hdwp);
}
void CResizableSheet::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (nType == SIZE_MAXHIDE || nType == SIZE_MAXSHOW)
return; // arrangement not needed
if (m_bInitDone)
ArrangeLayout();
}
// only gets called in wizard mode
// (when back or next button pressed)
void CResizableSheet::OnPageChanged()
{
// call default handler to allow page change
Default();
// update new wizard page
ArrangeLayout();
}
// protected members
// NOTE: this must be called after all the other settings
// to have the dialog and its controls displayed properly
void CResizableSheet::EnableSaveRestore(LPCTSTR pszSection, LPCTSTR pszEntry, BOOL bWithPage)
{
m_sSection = pszSection;
m_sEntry = pszEntry;
m_bSavePage = bWithPage;
m_bEnableSaveRestore = TRUE;
LoadWindowRect();
}
// private memebers
// used to save/restore window's size and position
// either in the registry or a private .INI file
// depending on your application settings
#define PROFILE_FMT _T("%d,%d,%d,%d,%d,%d [%d]")
void CResizableSheet::SaveWindowRect()
{
CString data;
WINDOWPLACEMENT wp;
ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(&wp);
RECT& rc = wp.rcNormalPosition; // alias
// also saves active page index, zero (the first) if problems
// cannot use GetActivePage, because it always fails
CTabCtrl *pTab = GetTabControl();
int page = 0;
if (pTab != NULL)
page = pTab->GetCurSel();
if (page < 0)
page = 0;
// always save page
data.Format(PROFILE_FMT, rc.left, rc.top,
rc.right, rc.bottom, wp.showCmd, wp.flags, page);
AfxGetApp()->WriteProfileString(m_sSection, m_sEntry, data);
}
void CResizableSheet::LoadWindowRect()
{
CString data;
WINDOWPLACEMENT wp;
int page;
data = AfxGetApp()->GetProfileString(m_sSection, m_sEntry);
if (data.IsEmpty()) // never saved before
return;
ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
wp.length = sizeof(WINDOWPLACEMENT);
RECT& rc = wp.rcNormalPosition; // alias
if (_stscanf_s(data, PROFILE_FMT, &rc.left, &rc.top,
&rc.right, &rc.bottom, &wp.showCmd, &wp.flags, &page) == 7)
{
SetWindowPlacement(&wp);
if (m_bSavePage)
{
SetActivePage(page);
ArrangeLayout(); // needs refresh
}
}
}
int CResizableSheet::GetMinWidth()
{/*
int min = 0;
// search for leftmost button
for (int i = 0; i < 7; i++)
{
// left position is relative to the right border
// of the parent window (negative value)
if (m_szLayoutButton[i].cx < min)
min = m_szLayoutButton[i].cx;
}
// sizing border width
int border = GetSystemMetrics(SM_CXSIZEFRAME);
// get tab control or wizard line left position
CWnd* pWnd;
CRect objrc;
if (m_psh.dwFlags & PSH_WIZARD)
pWnd = GetDlgItem(ID_WIZLINE);
else
pWnd = GetTabControl();
pWnd->GetWindowRect(&objrc);
ScreenToClient(&objrc);
// add the left margin and window's border
return -min + objrc.left + border*2;
*/
return 1;
}