// WizView.h : interface of the CWizView resizable propertysheet class
//
// Contents:
//
// 1. CWizTabCtrl - subclass for the wizard propertysheet tab control
// 2. CWizView - resizable wizard-style property sheet usable as a view
//
// Copyright 2002 by SoftGee
//////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_WIZVIEW_H__A312271D_3926_11D6_B652_0048548B09C5__INCLUDED_)
#define AFX_WIZVIEW_H__A312271D_3926_11D6_B652_0048548B09C5__INCLUDED_
#pragma once
#include "WizPage.h"
#include "bmpbtn.h"
// forward declaration
class CWizView;
// wizard static controls
#define ATL_IDC_STATIC1 0x3026 // lower, WIZ and WIZ97
#define ATL_IDC_STATIC2 0x3027 // upper, WIZ97 only
/////////////////////////////////////////////////////////////////////////////
// CWizTabCtrlImpl - implements a wizard propertysheet tab control subclass
// user defined message sent when property page needs resizing
#define WM_RESIZEPAGE WM_USER + 111
template <class T, class TBase = CTabCtrl>
class ATL_NO_VTABLE CWizTabCtrlImpl : public CWindowImpl< T, TBase >
{
public:
BOOL SubclassWindow(HWND hWnd)
{
// subclass the propertysheet tab control window
return CWindowImpl< T, TBase >::SubclassWindow(hWnd);
}
BEGIN_MSG_MAP(CWizTabCtrlImpl)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
MESSAGE_HANDLER(TCM_SETCURSEL, OnSetCurSel)
MESSAGE_HANDLER(WM_RESIZEPAGE, OnResizePage)
END_MSG_MAP()
LRESULT OnWindowPosChanging(UINT, WPARAM, LPARAM lParam, BOOL&)
{
// get window position structure from lParam
LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
// limit maximum tab height to 0
if (lpWP->cy > 0) lpWP->cy = 0;
return 0;
}
LRESULT OnWindowPosChanged(UINT, WPARAM, LPARAM lParam, BOOL&)
{
// get window position structure from lParam
LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
// SEND resize message to ourselves with the new tab width
::SendMessage(m_hWnd, WM_RESIZEPAGE, 0, lpWP->cx);
return 0;
}
LRESULT OnSetCurSel(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
// get the tab control client rect
RECT rc;
GetClientRect(&rc);
// POST resize message to ourselves with the tab width
::PostMessage(m_hWnd, WM_RESIZEPAGE, 0, rc.right);
// further default processing is required to handle the tab
// change, so set bHandled to false
bHandled = false;
return 0;
}
LRESULT OnResizePage(UINT, WPARAM, LPARAM lParam, BOOL&)
{
// initialize a property sheet variable with the parent's handle
CWizView sheet;
sheet.m_hWnd = GetParent();
// create a lower bound for the property page just above
// the lower static control
RECT rc;
CStatic st = sheet.GetDlgItem(ATL_IDC_STATIC1);
st.GetWindowRect(&rc);
sheet.ScreenToClient(&rc);
int nBottom = rc.top - 15;
// adjust lower bound if WIZARD97 style
DWORD dwFlags = sheet.GetPshStyle();
dwFlags |= PSH_WIZARD97;
if (dwFlags == sheet.GetPshStyle())
nBottom -= 60;
// set the size of the active property page to the tab
// control's new client area width and slightly above
// the lower static control and wizard buttons
::SetWindowPos(sheet.GetActivePage(), NULL,
0, 0, lParam, nBottom,
SWP_NOMOVE | SWP_NOZORDER);
// release the property sheet handle since we don't own it
sheet.m_hWnd = NULL;
return 0;
}
};
class CWizTabCtrl : public CWizTabCtrlImpl<CWizTabCtrl>
{ };
/////////////////////////////////////////////////////////////////////////////
// CWizView - resizable wizard-style property sheet usable as a view
class CWizView : public CPropertySheetImpl<CWizView>,
public CDialogResize<CWizView>
{
public:
// property pages. Pass in dialog and control resource IDs
CWizPage<IDD_PAGE0, IDC_EDIT0> m_page0;
CWizPage<IDD_PAGE1, IDC_FRAME1> m_page1;
// tab control variable
CWizTabCtrl m_tab;
BOOL PreTranslateMessage(MSG* pMsg)
{
pMsg;
return FALSE;
}
// constructor. At least one page must be added before window is created
CWizView()
{
// disable Apply button, set Wizard style
m_psh.dwFlags |= PSH_NOAPPLYNOW | PSH_WIZARD97 | PSH_WIZARDHASFINISH;
// title must be set before page is added
m_page0.SetTitle("Zero");
AddPage(m_page0);
m_page1.SetTitle("One");
AddPage(m_page1);
SetActivePage(0);
}
// override the callback procedure and add a pre-creation message
// handler so that we can change the window style
static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
{
// dialog template is available and changeable pre-creation
if(uMsg == PSCB_PRECREATE)
{
LPDLGTEMPLATE lpDT = (LPDLGTEMPLATE)lParam;
// remove dialog border styles
lpDT->style -= DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU;
// add child window and clipping styles
lpDT->style |= WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
return 0;
}
else // call inherited method
return CPropertySheetImpl<CWizView>::PropSheetCallback(hWnd, uMsg, lParam);
}
// add button handlers and chain both inherited message maps
BEGIN_MSG_MAP(CWizView)
COMMAND_ID_HANDLER(ID_WIZBACK, OnBack)
COMMAND_ID_HANDLER(ID_WIZNEXT, OnNext)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
COMMAND_ID_HANDLER(ID_WIZFINISH, OnFinish)
CHAIN_MSG_MAP(CPropertySheetImpl<CWizView>)
CHAIN_MSG_MAP(CDialogResize<CWizView>)
END_MSG_MAP()
// add the tab control and buttons to the resize map. Tab must
// be last because it handles property page sizing and uses the
// lower static control's position as an input
BEGIN_DLGRESIZE_MAP(CWizView)
DLGRESIZE_CONTROL(ID_WIZBACK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ID_WIZNEXT, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ID_WIZFINISH, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ATL_IDC_STATIC1, DLSZ_SIZE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ATL_IDC_STATIC2, DLSZ_SIZE_X)
DLGRESIZE_CONTROL(ATL_IDC_TAB_CONTROL, DLSZ_SIZE_X | DLSZ_MOVE_Y)
END_DLGRESIZE_MAP()
// Since WTL's CPropertySheet does not receive a WM_INITDIALOG message,
// this needs to be called to handle the remaining initialization tasks
LRESULT _Init(HWND hwndParent)
{
SetParent(hwndParent);
// remove dialog modal frame, set client edge style
ModifyStyleEx(0, WS_EX_CLIENTEDGE);
// initialize the resize code
DlgResize_Init(false, false, 0);
// subclass the property sheet tab control
m_tab.SubclassWindow(GetTabControl());
return 0;
}
// button handlers
LRESULT OnBack(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
// TODO: add code for desired action on Back click
bHandled = false;
return 0;
}
LRESULT OnNext(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
// TODO: add code for desired action on Next click
SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT | PSWIZB_FINISH);
bHandled = false;
return 0;
}
LRESULT OnCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: add code for desired action on Cancel click
return 0;
}
LRESULT OnFinish(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: add code for desired action on Finish click
return 0;
}
// propertysheet style getter
DWORD GetPshStyle()
{
return m_psh.dwFlags;
}
};
#endif // !defined(AFX_PROPVIEW_H__A312271D_3926_11D6_B652_0048548B09C5__INCLUDED_)