1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
5 #include "layoutmanager.h"
\r
6 #include "windowstool.h"
\r
8 #include <windowsx.h>
\r
12 LayoutManager::LayoutManager(HWND i_hwnd)
\r
14 m_smallestRestriction(RESTRICT_NONE),
\r
15 m_largestRestriction(RESTRICT_NONE)
\r
19 // restrict the smallest size of the window to the current size of it or
\r
20 // specified by i_size
\r
21 void LayoutManager::restrictSmallestSize(Restrict i_restrict, SIZE *i_size)
\r
23 m_smallestRestriction = i_restrict;
\r
25 m_smallestSize = *i_size;
\r
28 GetWindowRect(m_hwnd, &rc);
\r
29 m_smallestSize.cx = rc.right - rc.left;
\r
30 m_smallestSize.cy = rc.bottom - rc.top;
\r
35 // restrict the largest size of the window to the current size of it or
\r
36 // specified by i_size
\r
37 void LayoutManager::restrictLargestSize(Restrict i_restrict, SIZE *i_size)
\r
39 m_largestRestriction = i_restrict;
\r
41 m_largestSize = *i_size;
\r
44 GetWindowRect(m_hwnd, &rc);
\r
45 m_largestSize.cx = rc.right - rc.left;
\r
46 m_largestSize.cy = rc.bottom - rc.top;
\r
51 bool LayoutManager::addItem(HWND i_hwnd, Origin i_originLeft,
\r
53 Origin i_originRight, Origin i_originBottom)
\r
58 item.m_hwnd = i_hwnd;
\r
60 if (!(GetWindowLongPtr(i_hwnd, GWL_STYLE) & WS_CHILD))
\r
62 if (!(GetWindowLong(i_hwnd, GWL_STYLE) & WS_CHILD))
\r
65 item.m_hwndParent = GetParent(i_hwnd);
\r
66 if (!item.m_hwndParent)
\r
68 getChildWindowRect(item.m_hwnd, &item.m_rc);
\r
69 GetWindowRect(item.m_hwndParent, &item.m_rcParent);
\r
70 item.m_origin[0] = i_originLeft;
\r
71 item.m_origin[1] = i_originTop;
\r
72 item.m_origin[2] = i_originRight;
\r
73 item.m_origin[3] = i_originBottom;
\r
75 m_items.push_back(item);
\r
80 void LayoutManager::adjust() const
\r
82 for (Items::const_iterator i = m_items.begin(); i != m_items.end(); ++ i) {
\r
84 GetWindowRect(i->m_hwndParent, &rc);
\r
92 { rcWidth(&i->m_rcParent), i->m_rc.left, rcWidth(&rc), &rc.left },
\r
93 { rcHeight(&i->m_rcParent), i->m_rc.top, rcHeight(&rc), &rc.top },
\r
94 { rcWidth(&i->m_rcParent), i->m_rc.right, rcWidth(&rc), &rc.right },
\r
95 { rcHeight(&i->m_rcParent), i->m_rc.bottom, rcHeight(&rc), &rc.bottom }
\r
97 for (int j = 0; j < 4; ++ j) {
\r
98 switch (i->m_origin[j]) {
\r
99 case ORIGIN_LEFT_EDGE:
\r
100 *pos[j].m_out = pos[j].m_pos;
\r
102 case ORIGIN_CENTER:
\r
103 *pos[j].m_out = pos[j].m_curWidth / 2
\r
104 - (pos[j].m_width / 2 - pos[j].m_pos);
\r
106 case ORIGIN_RIGHT_EDGE:
\r
107 *pos[j].m_out = pos[j].m_curWidth
\r
108 - (pos[j].m_width - pos[j].m_pos);
\r
112 MoveWindow(i->m_hwnd, rc.left, rc.top,
\r
113 rcWidth(&rc), rcHeight(&rc), FALSE);
\r
119 BOOL LayoutManager::wmPaint()
\r
122 HDC hdc = BeginPaint(m_hwnd, &ps);
\r
124 GetClientRect(m_hwnd, &rc);
\r
125 rc.left = rc.right - GetSystemMetrics(SM_CXHTHUMB);
\r
126 rc.top = rc.bottom - GetSystemMetrics(SM_CYVTHUMB);
\r
127 DrawFrameControl(hdc, &rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
\r
128 EndPaint(m_hwnd, &ps);
\r
133 // size restriction
\r
134 BOOL LayoutManager::wmSizing(int i_edge, RECT *io_rc)
\r
139 case WMSZ_BOTTOMLEFT:
\r
140 if (m_smallestRestriction & RESTRICT_HORIZONTALLY)
\r
141 if (io_rc->right - io_rc->left < m_smallestSize.cx)
\r
142 io_rc->left = io_rc->right - m_smallestSize.cx;
\r
143 if (m_largestRestriction & RESTRICT_HORIZONTALLY)
\r
144 if (m_largestSize.cx < io_rc->right - io_rc->left)
\r
145 io_rc->left = io_rc->right - m_largestSize.cx;
\r
149 case WMSZ_TOPRIGHT:
\r
151 case WMSZ_BOTTOMRIGHT:
\r
152 if (m_smallestRestriction & RESTRICT_HORIZONTALLY)
\r
153 if (io_rc->right - io_rc->left < m_smallestSize.cx)
\r
154 io_rc->right = io_rc->left + m_smallestSize.cx;
\r
155 if (m_largestRestriction & RESTRICT_HORIZONTALLY)
\r
156 if (m_largestSize.cx < io_rc->right - io_rc->left)
\r
157 io_rc->right = io_rc->left + m_largestSize.cx;
\r
163 case WMSZ_TOPRIGHT:
\r
164 if (m_smallestRestriction & RESTRICT_VERTICALLY)
\r
165 if (io_rc->bottom - io_rc->top < m_smallestSize.cy)
\r
166 io_rc->top = io_rc->bottom - m_smallestSize.cy;
\r
167 if (m_largestRestriction & RESTRICT_VERTICALLY)
\r
168 if (m_largestSize.cy < io_rc->bottom - io_rc->top)
\r
169 io_rc->top = io_rc->bottom - m_largestSize.cy;
\r
174 case WMSZ_BOTTOMLEFT:
\r
175 case WMSZ_BOTTOMRIGHT:
\r
176 if (m_smallestRestriction & RESTRICT_VERTICALLY)
\r
177 if (io_rc->bottom - io_rc->top < m_smallestSize.cy)
\r
178 io_rc->bottom = io_rc->top + m_smallestSize.cy;
\r
179 if (m_largestRestriction & RESTRICT_VERTICALLY)
\r
180 if (m_largestSize.cy < io_rc->bottom - io_rc->top)
\r
181 io_rc->bottom = io_rc->top + m_largestSize.cy;
\r
188 // hittest for size box
\r
189 BOOL LayoutManager::wmNcHitTest(int i_x, int i_y)
\r
191 POINT p = { i_x, i_y };
\r
192 ScreenToClient(m_hwnd, &p);
\r
194 GetClientRect(m_hwnd, &rc);
\r
195 if (rc.right - GetSystemMetrics(SM_CXHTHUMB) <= p.x &&
\r
196 rc.bottom - GetSystemMetrics(SM_CYVTHUMB) <= p.y) {
\r
198 SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, HTBOTTOMRIGHT);
\r
200 SetWindowLong(m_hwnd, DWL_MSGRESULT, HTBOTTOMRIGHT);
\r
209 BOOL LayoutManager::wmSize(DWORD /* i_fwSizeType */, short /* i_nWidth */,
\r
210 short /* i_nHeight */)
\r
213 RedrawWindow(m_hwnd, NULL, NULL,
\r
214 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
\r
220 BOOL LayoutManager::defaultWMHandler(UINT i_message,
\r
221 WPARAM i_wParam, LPARAM i_lParam)
\r
223 switch (i_message) {
\r
225 return wmSize(i_wParam, LOWORD(i_lParam), HIWORD(i_lParam));
\r
229 return wmSizing(i_wParam, reinterpret_cast<RECT *>(i_lParam));
\r
231 return wmNcHitTest(GET_X_LPARAM(i_lParam), GET_Y_LPARAM(i_lParam));
\r