comparison foosdk/sdk/libPPUI/CDialogResizeHelper.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 #include "stdafx.h"
2 #include "CDialogResizeHelper.h"
3
4 #include "win32_op.h"
5
6 static BOOL GetChildWindowRect2(HWND wnd, HWND wndChild, RECT* child) {
7 RECT temp;
8 if (wndChild == NULL) return FALSE;
9 if (!GetWindowRect(wndChild, &temp)) return FALSE;
10 if (!MapWindowPoints(NULL, wnd, (POINT*)&temp, 2)) return FALSE;
11 *child = temp;
12 return TRUE;
13 }
14
15 static BOOL GetChildWindowRect(HWND wnd, UINT id, RECT* child) {
16 return GetChildWindowRect2(wnd, GetDlgItem(wnd, id), child);
17 }
18
19
20 bool CDialogResizeHelper::EvalRect(UINT id, CRect & out) const {
21 for( auto iter = m_runtime.begin(); iter != m_runtime.end(); ++ iter ) {
22 if ( iter->initData.id == id ) {
23 out = _EvalRect(*iter, this->CurrentSize() );
24 return true;
25 }
26 }
27 return false;
28 }
29
30 CRect CDialogResizeHelper::_EvalRect(runtime_t const & rt, CSize wndSize) const {
31 CRect rc = rt.origRect;
32 int delta_x = wndSize.cx - rt.origWindowSize.cx,
33 delta_y = wndSize.cy - rt.origWindowSize.cy;
34
35 const Param & e = rt.initData;
36 rc.left += pfc::rint32(e.snapLeft * delta_x);
37 rc.right += pfc::rint32(e.snapRight * delta_x);
38 rc.top += pfc::rint32(e.snapTop * delta_y);
39 rc.bottom += pfc::rint32(e.snapBottom * delta_y);
40
41 return rc;
42 }
43
44 CWindow CDialogResizeHelper::ResolveWnd(runtime_t const & rt) const {
45 if ( rt.userHWND != NULL ) return rt.userHWND;
46 return m_thisWnd.GetDlgItem( rt.initData.id );
47 }
48
49 CSize CDialogResizeHelper::CurrentSize() const {
50 CRect rc;
51 WIN32_OP_D( m_thisWnd.GetClientRect(rc) );
52 return rc.Size();
53 }
54
55 void CDialogResizeHelper::OnSize(UINT, CSize newSize)
56 {
57 if (m_thisWnd != NULL) {
58 HDWP hWinPosInfo = BeginDeferWindowPos((int)(m_runtime.size() + (m_sizeGrip != NULL ? 1 : 0)));
59 for (auto iter = m_runtime.begin(); iter != m_runtime.end(); ++ iter) {
60 CRect rc = _EvalRect(*iter, newSize);
61 hWinPosInfo = DeferWindowPos(hWinPosInfo, ResolveWnd(*iter), 0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
62 }
63 if (m_sizeGrip != NULL)
64 {
65 RECT rc, rc_grip;
66 if (m_thisWnd.GetClientRect(&rc) && m_sizeGrip.GetWindowRect(&rc_grip)) {
67 DWORD flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS;
68 if (IsZoomed(m_thisWnd)) flags |= SWP_HIDEWINDOW;
69 else flags |= SWP_SHOWWINDOW;
70 hWinPosInfo = DeferWindowPos(hWinPosInfo, m_sizeGrip, NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, flags);
71 }
72 }
73 EndDeferWindowPos(hWinPosInfo);
74 //RedrawWindow(m_thisWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
75 }
76 SetMsgHandled(FALSE);
77 }
78
79 void CDialogResizeHelper::OnGetMinMaxInfo(LPMINMAXINFO info) const {
80 CRect r;
81 const DWORD dwStyle = m_thisWnd.GetWindowLong(GWL_STYLE);
82 const DWORD dwExStyle = m_thisWnd.GetWindowLong(GWL_EXSTYLE);
83 if (max_x && max_y)
84 {
85 r.left = 0; r.right = max_x;
86 r.top = 0; r.bottom = max_y;
87 MapDialogRect(m_thisWnd, &r);
88 AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
89 info->ptMaxTrackSize.x = r.right - r.left;
90 info->ptMaxTrackSize.y = r.bottom - r.top;
91 }
92 if (min_x && min_y)
93 {
94 r.left = 0; r.right = min_x;
95 r.top = 0; r.bottom = min_y;
96 MapDialogRect(m_thisWnd, &r);
97 AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
98 info->ptMinTrackSize.x = r.right - r.left;
99 info->ptMinTrackSize.y = r.bottom - r.top;
100 }
101 }
102
103 void CDialogResizeHelper::OnInitDialog(CWindow thisWnd) {
104
105 m_thisWnd = thisWnd;
106 const auto origSize = CurrentSize();
107 for( auto initIter = m_initData.begin(); initIter != m_initData.end(); ++ initIter ) {
108 CRect rc;
109 if (GetChildWindowRect(m_thisWnd, initIter->id, &rc)) {
110 runtime_t rt;
111 rt.origRect = rc;
112 rt.initData = * initIter;
113 rt.origWindowSize = origSize;
114 m_runtime.push_back( std::move(rt) );
115 }
116 }
117 AddSizeGrip();
118 SetMsgHandled(FALSE);
119 }
120 void CDialogResizeHelper::OnDestroy() {
121 m_runtime.clear();
122 m_sizeGrip = NULL; m_thisWnd = NULL;
123 SetMsgHandled(FALSE);
124 }
125
126 void CDialogResizeHelper::AddSizeGrip()
127 {
128 if ( m_autoSizeGrip && m_thisWnd != NULL && m_sizeGrip == NULL)
129 {
130 if (m_thisWnd.GetWindowLong(GWL_STYLE) & WS_POPUP) {
131 m_sizeGrip = CreateWindowEx(0, WC_SCROLLBAR, _T(""), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN,
132 0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
133 m_thisWnd, (HMENU)0, NULL, NULL);
134 if (m_sizeGrip != NULL)
135 {
136 RECT rc, rc_grip;
137 if (m_thisWnd.GetClientRect(&rc) && m_sizeGrip.GetWindowRect(&rc_grip)) {
138 m_sizeGrip.SetWindowPos(NULL, rc.right - (rc_grip.right - rc_grip.left), rc.bottom - (rc_grip.bottom - rc_grip.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
139 }
140 }
141 }
142 }
143 }
144
145
146 void CDialogResizeHelper::InitTable(const Param* table, size_t tableSize) {
147 m_initData.assign( table, table+tableSize );
148 }
149 void CDialogResizeHelper::InitTable(const ParamOld * table, size_t tableSize) {
150 m_initData.resize(tableSize);
151 for (size_t walk = 0; walk < tableSize; ++walk) {
152 const ParamOld in = table[walk];
153 Param entry = {};
154 entry.id = table[walk].id;
155 if (in.flags & CDialogResizeHelperCompat::X_MOVE) entry.snapLeft = entry.snapRight = 1;
156 else if (in.flags & CDialogResizeHelperCompat::X_SIZE) entry.snapRight = 1;
157 if (in.flags & CDialogResizeHelperCompat::Y_MOVE) entry.snapTop = entry.snapBottom = 1;
158 else if (in.flags & CDialogResizeHelperCompat::Y_SIZE) entry.snapBottom = 1;
159 m_initData[walk] = entry;
160 }
161 }
162 void CDialogResizeHelper::InitMinMax(const CRect & range) {
163 min_x = range.left; min_y = range.top; max_x = range.right; max_y = range.bottom;
164 }
165
166 void CDialogResizeHelper::AddControl(Param const & initData, CWindow wnd) {
167 CRect rc;
168 if ( wnd == NULL ) {
169 PFC_ASSERT( initData.id != 0 );
170 WIN32_OP_D(GetChildWindowRect(m_thisWnd, initData.id, rc));
171 } else {
172 WIN32_OP_D(GetChildWindowRect2(m_thisWnd, wnd, rc));
173 }
174
175 runtime_t rt;
176 rt.initData = initData;
177 rt.userHWND = wnd;
178 rt.origRect = rc;
179 rt.origWindowSize = this->CurrentSize();
180 m_runtime.push_back( std::move(rt) );
181 }
182
183 bool CDialogResizeHelper::RemoveControl(CWindow wnd) {
184 return pfc::remove_if_t( m_runtime, [wnd] (runtime_t const & rt) {
185 return rt.userHWND == wnd;
186 } ) > 0;
187 }
188
189 bool CDialogResizeHelper::HaveControl(CWindow wnd) const {
190 for( auto i = m_runtime.begin(); i != m_runtime.end(); ++ i ) {
191 if ( i->userHWND == wnd ) return true;
192 }
193 return false;
194 }