Mercurial > foo_out_sdl
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 } |
