1 // ResizablePage.cpp : implementation file
3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2000 by Paolo Messina
6 // (ppescher@yahoo.com)
8 // Free for non-commercial use.
9 // You may change the code to your needs,
10 // provided that credits to the original
11 // author is given in the modified files.
13 /////////////////////////////////////////////////////////////////////////////
16 #include "ResizablePage.h"
21 static char THIS_FILE
[] = __FILE__
;
24 /////////////////////////////////////////////////////////////////////////////
27 IMPLEMENT_DYNCREATE(CResizablePage
, CPropertyPage
)
29 inline void CResizablePage::Construct()
34 CResizablePage::CResizablePage()
39 CResizablePage::CResizablePage(UINT nIDTemplate
, UINT nIDCaption
)
40 : CPropertyPage(nIDTemplate
, nIDCaption
)
45 CResizablePage::CResizablePage(LPCTSTR lpszTemplateName
, UINT nIDCaption
)
46 : CPropertyPage(lpszTemplateName
, nIDCaption
)
51 CResizablePage::~CResizablePage()
55 POSITION pos
= m_plLayoutList
.GetHeadPosition();
59 pl
= (Layout
*)m_plLayoutList
.GetNext(pos
);
65 BEGIN_MESSAGE_MAP(CResizablePage
, CPropertyPage
)
66 //{{AFX_MSG_MAP(CResizablePage)
72 /////////////////////////////////////////////////////////////////////////////
73 // CResizablePage message handlers
76 BOOL
CResizablePage::OnInitDialog()
78 CPropertyPage::OnInitDialog();
80 // gets the initial size as the min track size
86 return TRUE
; // return TRUE unless you set the focus to a control
87 // EXCEPTION: OCX Property Pages should return FALSE
90 void CResizablePage::AddAnchor(HWND wnd
, CSize tl_type
, CSize br_type
)
92 ASSERT(wnd
!= NULL
&& ::IsWindow(wnd
));
93 ASSERT(::IsChild(*this, wnd
));
94 ASSERT(tl_type
!= NOANCHOR
);
96 // get control's window class
99 GetClassName(wnd
, st
.GetBufferSetLength(MAX_PATH
), MAX_PATH
);
103 // add the style 'clipsiblings' to a GroupBox
104 // to avoid unnecessary repainting of controls inside
107 DWORD style
= GetWindowLong(wnd
, GWL_STYLE
);
108 if (style
& BS_GROUPBOX
)
109 SetWindowLong(wnd
, GWL_STYLE
, style
| WS_CLIPSIBLINGS
);
112 // wnd classes that don't redraw client area correctly
113 // when the hor scroll pos changes due to a resizing
114 BOOL hscroll
= FALSE
;
118 // wnd classes that need refresh when resized
119 BOOL refresh
= FALSE
;
122 DWORD style
= GetWindowLong(wnd
, GWL_STYLE
);
124 switch (style
& SS_TYPEMASK
)
129 // word-wrapped text needs refresh
133 // centered images or text need refresh
134 if (style
& SS_CENTERIMAGE
)
137 // simple text never needs refresh
138 if ((style
& SS_TYPEMASK
) == SS_SIMPLE
)
142 // get dialog's and control's rect
145 GetClientRect(&wndrc
);
146 ::GetWindowRect(wnd
, &objrc
);
147 ScreenToClient(&objrc
);
149 CSize tl_margin
, br_margin
;
151 if (br_type
== NOANCHOR
)
154 // calculate margin for the top-left corner
156 tl_margin
.cx
= objrc
.left
- wndrc
.Width() * tl_type
.cx
/ 100;
157 tl_margin
.cy
= objrc
.top
- wndrc
.Height() * tl_type
.cy
/ 100;
159 // calculate margin for the bottom-right corner
161 br_margin
.cx
= objrc
.right
- wndrc
.Width() * br_type
.cx
/ 100;
162 br_margin
.cy
= objrc
.bottom
- wndrc
.Height() * br_type
.cy
/ 100;
165 m_plLayoutList
.AddTail(new Layout(wnd
, tl_type
, tl_margin
,
166 br_type
, br_margin
, hscroll
, refresh
));
169 void CResizablePage::ArrangeLayout()
173 GetClientRect(&wndrc
);
176 POSITION pos
= m_plLayoutList
.GetHeadPosition();
178 HDWP hdwp
= BeginDeferWindowPos((int)m_plLayoutList
.GetCount());
182 pl
= (Layout
*)m_plLayoutList
.GetNext(pos
);
185 CWnd
* wnd
= CWnd::FromHandle(pl
->hwnd
); // temporary solution
187 wnd
->GetWindowRect(&objrc
);
188 ScreenToClient(&objrc
);
190 // calculate new top-left corner
192 newrc
.left
= pl
->tl_margin
.cx
+ wndrc
.Width() * pl
->tl_type
.cx
/ 100;
193 newrc
.top
= pl
->tl_margin
.cy
+ wndrc
.Height() * pl
->tl_type
.cy
/ 100;
195 // calculate new bottom-right corner
197 newrc
.right
= pl
->br_margin
.cx
+ wndrc
.Width() * pl
->br_type
.cx
/ 100;
198 newrc
.bottom
= pl
->br_margin
.cy
+ wndrc
.Height() * pl
->br_type
.cy
/ 100;
200 if (!newrc
.EqualRect(&objrc
))
206 // needs repainting, due to horiz scrolling
207 int diff
= newrc
.Width() - objrc
.Width();
208 int max
= wnd
->GetScrollLimit(SB_HORZ
);
210 if (max
> 0 && wnd
->GetScrollPos(SB_HORZ
) > max
- diff
)
212 wnd
->MoveWindow(&newrc
);
220 if (pl
->need_refresh
)
222 wnd
->MoveWindow(&newrc
);
230 DeferWindowPos(hdwp
, pl
->hwnd
, NULL
, newrc
.left
, newrc
.top
,
231 newrc
.Width(), newrc
.Height(), SWP_NOZORDER
| SWP_NOACTIVATE
);
235 // go re-arrange child windows
236 EndDeferWindowPos(hdwp
);
239 void CResizablePage::OnSize(UINT nType
, int cx
, int cy
)
241 CWnd::OnSize(nType
, cx
, cy
);