1 // ResizableSheet.cpp : implementation file
3 /////////////////////////////////////////////////////////////////////////////
5 // Modified 14/09/2000 by David Fleury
6 // get rid if the "resizable" stuff, just kept the auto arrange of controls
8 // Copyright (C) 2000 by Paolo Messina
9 // (ppescher@yahoo.com)
11 // Free for non-commercial use.
12 // You may change the code to your needs,
13 // provided that credits to the original
14 // author is given in the modified files.
16 /////////////////////////////////////////////////////////////////////////////
19 #include "ResizableSheet.h"
24 static char THIS_FILE
[] = __FILE__
;
27 /////////////////////////////////////////////////////////////////////////////
30 IMPLEMENT_DYNAMIC(CResizableSheet
, CPropertySheet
)
32 inline void CResizableSheet::Construct()
36 m_bEnableSaveRestore
= FALSE
;
41 CResizableSheet::CResizableSheet()
46 CResizableSheet::CResizableSheet(UINT nIDCaption
, CWnd
*pParentWnd
, UINT iSelectPage
)
47 : CPropertySheet(nIDCaption
, pParentWnd
, iSelectPage
)
52 CResizableSheet::CResizableSheet(LPCTSTR pszCaption
, CWnd
*pParentWnd
, UINT iSelectPage
)
53 : CPropertySheet(pszCaption
, pParentWnd
, iSelectPage
)
58 CResizableSheet::~CResizableSheet()
62 BEGIN_MESSAGE_MAP(CResizableSheet
, CPropertySheet
)
63 //{{AFX_MSG_MAP(CResizableSheet)
68 ON_BN_CLICKED(ID_WIZBACK
, OnPageChanged
)
69 ON_BN_CLICKED(ID_WIZNEXT
, OnPageChanged
)
72 /////////////////////////////////////////////////////////////////////////////
73 // CResizableSheet message handlers
75 int CResizableSheet::OnCreate(LPCREATESTRUCT lpCreateStruct
)
77 if (CPropertySheet::OnCreate(lpCreateStruct
) == -1)
80 /*********************************/
81 // MODIFIED 14/09/2000 Fleury David, I don't want the user to be able to resize the sheet
82 // // change window style to be resizable
83 // ModifyStyle(0,/* WS_THICKFRAME |*/ WS_CLIPCHILDREN);
84 /*********************************/
88 BOOL
CResizableSheet::OnInitDialog()
90 BOOL bResult
= CPropertySheet::OnInitDialog();
93 GetTabControl()->ModifyStyle(0, WS_CLIPSIBLINGS
);
100 void CResizableSheet::OnDestroy()
102 CPropertySheet::OnDestroy();
104 if (m_bEnableSaveRestore
)
109 CPropertySheet::OnDestroy();
112 // maps an index to a button ID and vice-versa
113 static UINT _propButtons
[] =
115 IDOK
, IDCANCEL
, ID_APPLY_NOW
, IDHELP
,
116 ID_WIZBACK
, ID_WIZNEXT
, ID_WIZFINISH
119 // horizontal line in wizard mode
120 #define ID_WIZLINE ID_WIZFINISH+1
122 void CResizableSheet::PresetLayout()
124 CWnd
* pWnd
; // points to various children
126 GetClientRect(&wndrc
);
128 // tab control or wizard line position
129 if (m_psh
.dwFlags
& PSH_WIZARD
) // wizard mode
131 // get wizard line's bottom-right corner
132 pWnd
= GetDlgItem(ID_WIZLINE
);
135 GetTabControl()->ShowWindow(SW_HIDE
);
139 // get tab control's bottom-right corner
140 pWnd
= GetTabControl();
142 // whatever it is, take the right margin
143 pWnd
->GetWindowRect(&objrc
);
144 ScreenToClient(&objrc
);
146 m_szLayoutTabLine
.cx
= objrc
.right
- wndrc
.right
;
147 m_szLayoutTabLine
.cy
= objrc
.bottom
- wndrc
.bottom
;
149 // get child dialog's bottom-right corner
150 pWnd
= GetActivePage();
152 pWnd
->GetWindowRect(&objrc
);
153 ScreenToClient(&objrc
);
155 m_szLayoutPage
.cx
= objrc
.right
- wndrc
.right
;
156 m_szLayoutPage
.cy
= objrc
.bottom
- wndrc
.bottom
;
158 // store buttons position
159 for (int i
= 0; i
< 7; i
++)
161 pWnd
= GetDlgItem(_propButtons
[i
]);
165 // invalid position, button does not exist
166 // (just to initialize, any button you may activate
167 // in the future is present, but hidden)
168 m_szLayoutButton
[i
].cx
= 0;
169 m_szLayoutButton
[i
].cy
= 0;
173 pWnd
->GetWindowRect(&objrc
);
174 ScreenToClient(&objrc
);
176 m_szLayoutButton
[i
].cx
= objrc
.left
- wndrc
.right
;
177 m_szLayoutButton
[i
].cy
= objrc
.top
- wndrc
.bottom
;
181 void CResizableSheet::ArrangeLayout()
186 GetClientRect(&wndrc
);
188 // usually no more than
190 // 1 tab control or wizard line +
192 HDWP hdwp
= BeginDeferWindowPos(6);
194 if (m_psh
.dwFlags
& PSH_WIZARD
) // wizard mode
196 // get wizard line's bottom-right corner
197 pWnd
= GetDlgItem(ID_WIZLINE
);
199 pWnd
->GetWindowRect(&objrc
);
200 ScreenToClient(&objrc
);
202 int oldHeight
= objrc
.Height();
203 objrc
.right
= m_szLayoutTabLine
.cx
+ wndrc
.right
;
204 objrc
.bottom
= m_szLayoutTabLine
.cy
+ wndrc
.bottom
;
205 objrc
.top
= objrc
.bottom
- oldHeight
;
208 DeferWindowPos(hdwp
, *pWnd
, NULL
, objrc
.left
, objrc
.top
,
209 objrc
.Width(), objrc
.Height(), SWP_NOZORDER
| SWP_NOACTIVATE
);
213 // get tab control's bottom-right corner
214 pWnd
= GetTabControl();
216 pWnd
->GetWindowRect(&objrc
);
217 ScreenToClient(&objrc
);
219 objrc
.right
= m_szLayoutTabLine
.cx
+ wndrc
.right
;
220 objrc
.bottom
= m_szLayoutTabLine
.cy
+ wndrc
.bottom
;
222 // add the control, only resize
223 DeferWindowPos(hdwp
, *pWnd
, NULL
, 0, 0, objrc
.Width(),
224 objrc
.Height(), SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
227 // get child dialog's bottom-right corner
228 pWnd
= GetActivePage();
230 pWnd
->GetWindowRect(&objrc
);
231 ScreenToClient(&objrc
);
233 objrc
.right
= m_szLayoutPage
.cx
+ wndrc
.right
;
234 objrc
.bottom
= m_szLayoutPage
.cy
+ wndrc
.bottom
;
236 // add the control, only resize
237 DeferWindowPos(hdwp
, *pWnd
, NULL
, 0, 0, objrc
.Width(),
238 objrc
.Height(), SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
240 // arrange buttons position
241 for (int i
= 0; i
< 7; i
++)
243 pWnd
= GetDlgItem(_propButtons
[i
]);
246 continue; // ignores deleted buttons
248 // this should never happen, because all the buttons you
249 // may activate already exist at time PresetLayout is called
250 ASSERT(m_szLayoutButton
[i
].cx
!= 0 || m_szLayoutButton
[i
].cy
!= 0);
252 pWnd
->GetWindowRect(&objrc
);
253 ScreenToClient(&objrc
);
255 objrc
.left
= m_szLayoutButton
[i
].cx
+ wndrc
.right
;
256 objrc
.top
= m_szLayoutButton
[i
].cy
+ wndrc
.bottom
;
258 // add the control, only move
259 DeferWindowPos(hdwp
, *pWnd
, NULL
, objrc
.left
, objrc
.top
,
260 0, 0, SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
263 // go re-arrange child windows
264 EndDeferWindowPos(hdwp
);
267 void CResizableSheet::OnSize(UINT nType
, int cx
, int cy
)
269 CWnd::OnSize(nType
, cx
, cy
);
271 if (nType
== SIZE_MAXHIDE
|| nType
== SIZE_MAXSHOW
)
272 return; // arrangement not needed
278 // only gets called in wizard mode
279 // (when back or next button pressed)
280 void CResizableSheet::OnPageChanged()
282 // call default handler to allow page change
285 // update new wizard page
293 // NOTE: this must be called after all the other settings
294 // to have the dialog and its controls displayed properly
295 void CResizableSheet::EnableSaveRestore(LPCTSTR pszSection
, LPCTSTR pszEntry
, BOOL bWithPage
)
297 m_sSection
= pszSection
;
299 m_bSavePage
= bWithPage
;
301 m_bEnableSaveRestore
= TRUE
;
308 // used to save/restore window's size and position
309 // either in the registry or a private .INI file
310 // depending on your application settings
312 #define PROFILE_FMT _T("%d,%d,%d,%d,%d,%d [%d]")
314 void CResizableSheet::SaveWindowRect()
319 ZeroMemory(&wp
, sizeof(WINDOWPLACEMENT
));
320 wp
.length
= sizeof(WINDOWPLACEMENT
);
321 GetWindowPlacement(&wp
);
323 RECT
& rc
= wp
.rcNormalPosition
; // alias
325 // also saves active page index, zero (the first) if problems
326 // cannot use GetActivePage, because it always fails
327 CTabCtrl
*pTab
= GetTabControl();
331 page
= pTab
->GetCurSel();
336 data
.Format(PROFILE_FMT
, rc
.left
, rc
.top
,
337 rc
.right
, rc
.bottom
, wp
.showCmd
, wp
.flags
, page
);
339 AfxGetApp()->WriteProfileString(m_sSection
, m_sEntry
, data
);
342 void CResizableSheet::LoadWindowRect()
348 data
= AfxGetApp()->GetProfileString(m_sSection
, m_sEntry
);
350 if (data
.IsEmpty()) // never saved before
353 ZeroMemory(&wp
, sizeof(WINDOWPLACEMENT
));
354 wp
.length
= sizeof(WINDOWPLACEMENT
);
356 RECT
& rc
= wp
.rcNormalPosition
; // alias
358 if (_stscanf_s(data
, PROFILE_FMT
, &rc
.left
, &rc
.top
,
359 &rc
.right
, &rc
.bottom
, &wp
.showCmd
, &wp
.flags
, &page
) == 7)
361 SetWindowPlacement(&wp
);
365 ArrangeLayout(); // needs refresh
370 int CResizableSheet::GetMinWidth()
374 // search for leftmost button
375 for (int i = 0; i < 7; i++)
377 // left position is relative to the right border
378 // of the parent window (negative value)
379 if (m_szLayoutButton[i].cx < min)
380 min = m_szLayoutButton[i].cx;
383 // sizing border width
384 int border = GetSystemMetrics(SM_CXSIZEFRAME);
386 // get tab control or wizard line left position
390 if (m_psh.dwFlags & PSH_WIZARD)
391 pWnd = GetDlgItem(ID_WIZLINE);
393 pWnd = GetTabControl();
395 pWnd->GetWindowRect(&objrc);
396 ScreenToClient(&objrc);
398 // add the left margin and window's border
399 return -min + objrc.left + border*2;