// SizingDialog.h: interface for the CSizingDialog class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SIZINGDIALOG_H__5C154C94_9FEF_11D3_82D8_0020182B97FC__INCLUDED_) #define AFX_SIZINGDIALOG_H__5C154C94_9FEF_11D3_82D8_0020182B97FC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //#define SD_TOP 0x00000001 #define SD_HORZ 0x00000002 //#define SD_LEFT 0x00000010 #define SD_VERT 0x00000020 #define SD_MOVING 0x00010000 #define SD_SIZING 0x00020000 #define RECT_WIPE(rc) (rc.left = rc.top = rc.right = rc.bottom = 0) #define IS_RECT_EMPTY(rc) ((rc.left == 0) && (rc.top == 0) && (rc.right == 0) && (rc.bottom == 0)) #define POINT_WIPE(pt) (pt.x = pt.y = 0) #define IS_POINT_EMPTY(pt) ((pt.x == 0) && (pt.y == 0)) template class CSizingDialog { public: CSizingDialog() { POINT_WIPE(m_ptMin); } bool SetMin(UINT nID); bool SetMin(LPPOINT pt); bool SetControlSizing(UINT nID, DWORD dwLocation); BEGIN_MSG_MAP(CSizingDialog) MESSAGE_HANDLER(WM_SIZE, OnSize) MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) END_MSG_MAP() protected: // LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); struct POS_DATA { DWORD dwLocation; UINT nID; RECT rcOffsets; }; typedef vector pos_array; pos_array m_aPositions; POINT m_ptMin; }; template bool CSizingDialog::SetMin(LPPOINT pt) { m_ptMin.x = pt.x; m_ptMin.y = pt.y; return true; } template bool CSizingDialog::SetControlSizing(UINT nID, DWORD dwLocation) { T* pThis = (T*)this; ASSERT(dwLocation); ASSERT(pThis->GetDlgItem(nID)); POS_DATA ps; ps.dwLocation = dwLocation; ps.nID = nID; RECT rcDlg; if(!pThis->GetClientRect(&rcDlg)) return false; RECT rcCtl; if(!::GetWindowRect(pThis->GetDlgItem(nID), &rcCtl)) return false; if(!pThis->ScreenToClient(&rcCtl)) return false; ps.rcOffsets.left = rcCtl.left - rcDlg.left; ps.rcOffsets.top = rcCtl.top - rcDlg.top; ps.rcOffsets.right = rcDlg.right - rcCtl.right; ps.rcOffsets.bottom = rcDlg.bottom - rcCtl.bottom; m_aPositions.push_back(ps); return true; } template bool CSizingDialog::SetMin(UINT nID) { T* pThis = (T*)this; ASSERT(pThis->GetDlgItem(nID)); RECT rcCtl; if(!::GetWindowRect(pThis->GetDlgItem(nID), &rcCtl)) return false; RECT rcDlg; if(!pThis->GetWindowRect(&rcDlg)) return false; m_ptMin.x = rcCtl.right - rcDlg.left; m_ptMin.y = rcCtl.bottom - rcDlg.top; return true; } template LRESULT CSizingDialog::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if(IS_POINT_EMPTY(m_ptMin)) return 0; LPMINMAXINFO lpmmi = (LPMINMAXINFO) lParam; // address of structure lpmmi->ptMinTrackSize = m_ptMin; return 0; } template LRESULT CSizingDialog::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { T* pThis = (T*)this; UINT nWidth = LOWORD(lParam); // width of client area UINT nHeight = HIWORD(lParam); // height of client area for(pos_array::iterator iter = m_aPositions.begin(); iter != m_aPositions.end(); iter++) { RECT rc; if(!::GetWindowRect(pThis->GetDlgItem(iter->nID), &rc)) continue; if(!pThis->ScreenToClient(&rc)) continue; if(iter->dwLocation & SD_MOVING) { ::SetWindowPos(pThis->GetDlgItem(iter->nID), NULL, (iter->dwLocation & SD_HORZ) ? nWidth - iter->rcOffsets.right - rc.right + rc.left : rc.left, (iter->dwLocation & SD_VERT) ? nHeight - iter->rcOffsets.bottom - rc.bottom + rc.top : rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_DEFERERASE); } else if(iter->dwLocation & SD_SIZING) { ::SetWindowPos(pThis->GetDlgItem(iter->nID), NULL, 0, 0, (iter->dwLocation & SD_HORZ) ? nWidth - iter->rcOffsets.right - rc.left : rc.right - rc.left, (iter->dwLocation & SD_VERT) ? nHeight - iter->rcOffsets.bottom - rc.top : rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_DEFERERASE); } } return 0; } #endif // !defined(AFX_SIZINGDIALOG_H__5C154C94_9FEF_11D3_82D8_0020182B97FC__INCLUDED_)