// Win32++ Version 7.2 // Released: 5th AUgust 2011 // // David Nash // email: dnash@bigpond.net.au // url: https://sourceforge.net/projects/win32-framework // // // Copyright (c) 2005-2011 David Nash // // Permission is hereby granted, free of charge, to // any person obtaining a copy of this software and // associated documentation files (the "Software"), // to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, // merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom // the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice // shall be included in all copies or substantial portions // of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. // //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// // dialog.h // Declaration of the CDialog class // CDialog adds support for dialogs to Win32++. Dialogs are specialised // windows which are a parent window for common controls. Common controls // are special window types such as buttons, edit controls, tree views, // list views, static text etc. // The layout of a dialog is typically defined in a resource script file // (often Resource.rc). While this script file can be constructed manually, // it is often created using a resource editor. If your compiler doesn't // include a resource editor, you might find ResEdit useful. It is a free // resource editor available for download at: // http://www.resedit.net/ // CDialog supports modal and modeless dialogs. It also supports the creation // of dialogs defined in a resource script file, as well as those defined in // a dialog template. // Use the Dialog generic program as the starting point for your own dialog // applications. // The DlgSubclass sample demonstrates how to use subclassing to customise // the behaviour of common controls in a dialog. #ifndef _WIN32XX_DIALOG_H_ #define _WIN32XX_DIALOG_H_ #include "wincore.h" #ifndef SWP_NOCOPYBITS #define SWP_NOCOPYBITS 0x0100 #endif namespace Win32xx { class CDialog : public CWnd { public: CDialog(UINT nResID, CWnd* pParent = NULL); CDialog(LPCTSTR lpszResName, CWnd* pParent = NULL); CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent = NULL); virtual ~CDialog(); // You probably won't need to override these functions virtual void AttachItem(int nID, CWnd& Wnd); virtual HWND Create(CWnd* pParent = NULL); virtual INT_PTR DoModal(); virtual HWND DoModeless(); virtual void SetDlgParent(CWnd* pParent); BOOL IsModal() const { return m_IsModal; } BOOL IsIndirect() const { return (NULL != m_lpTemplate); } protected: // These are the functions you might wish to override virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam); virtual INT_PTR DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void EndDialog(INT_PTR nResult); virtual void OnCancel(); virtual BOOL OnInitDialog(); virtual void OnOK(); virtual BOOL PreTranslateMessage(MSG* pMsg); // Can't override these functions static INT_PTR CALLBACK StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #ifndef _WIN32_WCE static LRESULT CALLBACK StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam); #endif private: CDialog(const CDialog&); // Disable copy construction CDialog& operator = (const CDialog&); // Disable assignment operator BOOL m_IsModal; // a flag for modal dialogs LPCTSTR m_lpszResName; // the resource name for the dialog LPCDLGTEMPLATE m_lpTemplate; // the dialog template for indirect dialogs HWND m_hParent; // handle to the dialogs's parent window }; #ifndef _WIN32_WCE ////////////////////////////////////// // Declaration of the CResizer class // // The CResizer class can be used to rearrange a dialog's child // windows when the dialog is resized. // To use CResizer, follow the following steps: // 1) Use Initialize to specify the dialog's CWnd, and min and max size. // 3) Use AddChild for each child window // 4) Call HandleMessage from within DialogProc. // // Resize Dialog Styles #define RD_STRETCH_WIDTH 0x0001 // The item has a variable width #define RD_STRETCH_HEIGHT 0x0002 // The item has a variable height // Resize Dialog alignments enum Alignment { topleft, topright, bottomleft, bottomright }; class CResizer { public: CResizer() : m_pParent(0), m_xScrollPos(0), m_yScrollPos(0) {} virtual ~CResizer() {} virtual void AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle); virtual void AddChild(HWND hWnd, Alignment corner, DWORD dwStyle); virtual void HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void Initialize(CWnd* pParent, RECT rcMin, RECT rcMax = CRect(0,0,0,0)); virtual void OnHScroll(WPARAM wParam, LPARAM lParam); virtual void OnVScroll(WPARAM wParam, LPARAM lParam); virtual void RecalcLayout(); CRect GetMinRect() const { return m_rcMin; } CRect GetMaxRect() const { return m_rcMax; } struct ResizeData { CRect rcInit; CRect rcOld; Alignment corner; BOOL bFixedWidth; BOOL bFixedHeight; HWND hWnd; }; private: CWnd* m_pParent; std::vector m_vResizeData; CRect m_rcInit; CRect m_rcMin; CRect m_rcMax; int m_xScrollPos; int m_yScrollPos; }; #endif } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ namespace Win32xx { //////////////////////////////////// // Definitions for the CDialog class // inline CDialog::CDialog(LPCTSTR lpszResName, CWnd* pParent/* = NULL*/) : m_IsModal(TRUE), m_lpszResName(lpszResName), m_lpTemplate(NULL) { m_hParent = pParent? pParent->GetHwnd() : NULL; ::InitCommonControls(); } inline CDialog::CDialog(UINT nResID, CWnd* pParent/* = NULL*/) : m_IsModal(TRUE), m_lpszResName(MAKEINTRESOURCE (nResID)), m_lpTemplate(NULL) { m_hParent = pParent? pParent->GetHwnd() : NULL; ::InitCommonControls(); } //For indirect dialogs - created from a dialog box template in memory. inline CDialog::CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent/* = NULL*/) : m_IsModal(TRUE), m_lpszResName(NULL), m_lpTemplate(lpTemplate) { m_hParent = pParent? pParent->GetHwnd() : NULL; ::InitCommonControls(); } inline CDialog::~CDialog() { if (m_hWnd != NULL) { if (IsModal()) ::EndDialog(m_hWnd, 0); else Destroy(); } } inline void CDialog::AttachItem(int nID, CWnd& Wnd) // Attach a dialog item to a CWnd { Wnd.AttachDlgItem(nID, this); } inline HWND CDialog::Create(CWnd* pParent /* = NULL */) { // Allow a dialog to be used as a child window assert(GetApp()); SetDlgParent(pParent); return DoModeless(); } inline INT_PTR CDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { // Override this function in your class derrived from CDialog if you wish to handle messages // A typical function might look like this: // switch (uMsg) // { // case MESSAGE1: // Some Windows API message // OnMessage1(); // A user defined function // break; // Also do default processing // case MESSAGE2: // OnMessage2(); // return x; // Don't do default processing, but instead return // // a value recommended by the Windows API documentation // } // Always pass unhandled messages on to DialogProcDefault return DialogProcDefault(uMsg, wParam, lParam); } inline INT_PTR CDialog::DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) // All DialogProc functions should pass unhandled messages to this function { LRESULT lr = 0; switch (uMsg) { case UWM_CLEANUPTEMPS: { TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex()); pTLSData->vTmpWnds.clear(); } break; case WM_INITDIALOG: { // Center the dialog CenterWindow(); } return OnInitDialog(); case WM_COMMAND: switch (LOWORD (wParam)) { case IDOK: OnOK(); return TRUE; case IDCANCEL: OnCancel(); return TRUE; default: { // Refelect this message if it's from a control CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam); if (pWnd != NULL) lr = pWnd->OnCommand(wParam, lParam); // Handle user commands if (!lr) lr = OnCommand(wParam, lParam); if (lr) return 0L; } break; // Some commands require default processing } break; case WM_NOTIFY: { // Do Notification reflection if it came from a CWnd object HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom; CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom); if (pWndFrom != NULL) lr = pWndFrom->OnNotifyReflect(wParam, lParam); else { // Some controls (eg ListView) have child windows. // Reflect those notifications too. CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom)); if (pWndFromParent != NULL) lr = pWndFromParent->OnNotifyReflect(wParam, lParam); } // Handle user notifications if (!lr) lr = OnNotify(wParam, lParam); // Set the return code for notifications if (IsWindow()) SetWindowLongPtr(DWLP_MSGRESULT, (LONG_PTR)lr); return (BOOL)lr; } case WM_PAINT: { if (::GetUpdateRect(m_hWnd, NULL, FALSE)) { CPaintDC dc(this); OnDraw(&dc); } else // RedrawWindow can require repainting without an update rect { CClientDC dc(this); OnDraw(&dc); } break; } case WM_ERASEBKGND: { CDC dc((HDC)wParam); BOOL bResult = OnEraseBkgnd(&dc); dc.Detach(); if (bResult) return TRUE; } break; // A set of messages to be reflected back to the control that generated them case WM_CTLCOLORBTN: case WM_CTLCOLOREDIT: case WM_CTLCOLORDLG: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: case WM_DRAWITEM: case WM_MEASUREITEM: case WM_DELETEITEM: case WM_COMPAREITEM: case WM_CHARTOITEM: case WM_VKEYTOITEM: case WM_HSCROLL: case WM_VSCROLL: case WM_PARENTNOTIFY: return MessageReflect(m_hWnd, uMsg, wParam, lParam); } // switch(uMsg) return FALSE; } // INT_PTR CALLBACK CDialog::DialogProc(...) inline INT_PTR CDialog::DoModal() { // Create a modal dialog // A modal dialog box must be closed by the user before the application continues assert( GetApp() ); // Test if Win32++ has been started assert(!::IsWindow(m_hWnd)); // Only one window per CWnd instance allowed INT_PTR nResult = 0; try { m_IsModal=TRUE; // Ensure this thread has the TLS index set TLSData* pTLSData = GetApp()->SetTlsIndex(); #ifndef _WIN32_WCE BOOL IsHookedHere = FALSE; if (NULL == pTLSData->hHook ) { pTLSData->hHook = ::SetWindowsHookEx(WH_MSGFILTER, (HOOKPROC)StaticMsgHook, NULL, ::GetCurrentThreadId()); IsHookedHere = TRUE; } #endif HINSTANCE hInstance = GetApp()->GetInstanceHandle(); pTLSData->pCWnd = this; // Create a modal dialog if (IsIndirect()) nResult = ::DialogBoxIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc); else { if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG)) hInstance = GetApp()->GetResourceHandle(); nResult = ::DialogBox(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc); } // Tidy up m_hWnd = NULL; pTLSData->pCWnd = NULL; GetApp()->CleanupTemps(); #ifndef _WIN32_WCE if (IsHookedHere) { ::UnhookWindowsHookEx(pTLSData->hHook); pTLSData->hHook = NULL; } #endif if (nResult == -1) throw CWinException(_T("Failed to create modal dialog box")); } catch (const CWinException &e) { TRACE(_T("\n*** Failed to create dialog ***\n")); e.what(); // Display the last error message. // eat the exception (don't rethrow) } return nResult; } inline HWND CDialog::DoModeless() { assert( GetApp() ); // Test if Win32++ has been started assert(!::IsWindow(m_hWnd)); // Only one window per CWnd instance allowed try { m_IsModal=FALSE; // Ensure this thread has the TLS index set TLSData* pTLSData = GetApp()->SetTlsIndex(); // Store the CWnd pointer in Thread Local Storage pTLSData->pCWnd = this; HINSTANCE hInstance = GetApp()->GetInstanceHandle(); // Create a modeless dialog if (IsIndirect()) m_hWnd = ::CreateDialogIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc); else { if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG)) hInstance = GetApp()->GetResourceHandle(); m_hWnd = ::CreateDialog(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc); } // Tidy up pTLSData->pCWnd = NULL; // Now handle dialog creation failure if (!m_hWnd) throw CWinException(_T("Failed to create dialog")); } catch (const CWinException &e) { TRACE(_T("\n*** Failed to create dialog ***\n")); e.what(); // Display the last error message. // eat the exception (don't rethrow) } return m_hWnd; } inline void CDialog::EndDialog(INT_PTR nResult) { assert(::IsWindow(m_hWnd)); if (IsModal()) ::EndDialog(m_hWnd, nResult); else Destroy(); m_hWnd = NULL; } inline void CDialog::OnCancel() { // Override to customize OnCancel behaviour EndDialog(IDCANCEL); } inline BOOL CDialog::OnInitDialog() { // Called when the dialog is initialized // Override it in your derived class to automatically perform tasks // The return value is used by WM_INITDIALOG return TRUE; } inline void CDialog::OnOK() { // Override to customize OnOK behaviour EndDialog(IDOK); } inline BOOL CDialog::PreTranslateMessage(MSG* pMsg) { // allow the dialog to translate keyboard input if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST)) { // Process dialog keystrokes for modeless dialogs if (!IsModal()) { TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex()); if (NULL == pTLSData->hHook) { if (IsDialogMessage(pMsg)) return TRUE; } else { // A modal message loop is running so we can't do IsDialogMessage. // Avoid having modal dialogs create other windows, because those // windows will then use the modal dialog's special message loop. } } } return FALSE; } inline void CDialog::SetDlgParent(CWnd* pParent) // Allows the parent of the dialog to be set before the dialog is created { m_hParent = pParent? pParent->GetHwnd() : NULL; } inline INT_PTR CALLBACK CDialog::StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Find the CWnd pointer mapped to this HWND CDialog* w = (CDialog*)GetApp()->GetCWndFromMap(hWnd); if (0 == w) { // The HWND wasn't in the map, so add it now TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex()); assert(pTLSData); // Retrieve pointer to CWnd object from Thread Local Storage TLS w = (CDialog*)pTLSData->pCWnd; assert(w); pTLSData->pCWnd = NULL; // Store the Window pointer into the HWND map w->m_hWnd = hWnd; w->AddToMap(); } return w->DialogProc(uMsg, wParam, lParam); } // INT_PTR CALLBACK CDialog::StaticDialogProc(...) #ifndef _WIN32_WCE inline LRESULT CALLBACK CDialog::StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam) { // Used by Modal Dialogs to PreTranslate Messages TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex()); if (nCode == MSGF_DIALOGBOX) { MSG* lpMsg = (MSG*) lParam; // only pre-translate keyboard events if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST)) { for (HWND hWnd = lpMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd)) { CDialog* pDialog = (CDialog*)GetApp()->GetCWndFromMap(hWnd); if (pDialog && (lstrcmp(pDialog->GetClassName(), _T("#32770")) == 0)) // only for dialogs { pDialog->PreTranslateMessage(lpMsg); break; } } } } return ::CallNextHookEx(pTLSData->hHook, nCode, wParam, lParam); } #endif #ifndef _WIN32_WCE ///////////////////////////////////// // Definitions for the CResizer class // void inline CResizer::AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle) // Adds a child window (usually a dialog control) to the set of windows managed by // the Resizer. // // The alignment corner should be set to the closest corner of the dialog. Allowed // values are topleft, topright, bottomleft, and bottomright. // Set bFixedWidth to TRUE if the width should be fixed instead of variable. // Set bFixedHeight to TRUE if the height should be fixed instead of variable. { ResizeData rd; rd.corner = corner; rd.bFixedWidth = !(dwStyle & RD_STRETCH_WIDTH); rd.bFixedHeight = !(dwStyle & RD_STRETCH_HEIGHT); CRect rcInit = pWnd->GetWindowRect(); m_pParent->ScreenToClient(rcInit); rd.rcInit = rcInit; rd.hWnd = pWnd->GetHwnd(); m_vResizeData.insert(m_vResizeData.begin(), rd); } void inline CResizer::AddChild(HWND hWnd, Alignment corner, DWORD dwStyle) // Adds a child window (usually a dialog control) to the set of windows managed by // the Resizer. { AddChild(FromHandle(hWnd), corner, dwStyle); } inline void CResizer::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZE: RecalcLayout(); break; case WM_HSCROLL: if (0 == lParam) OnHScroll(wParam, lParam); break; case WM_VSCROLL: if (0 == lParam) OnVScroll(wParam, lParam); break; } } void inline CResizer::Initialize(CWnd* pParent, RECT rcMin, RECT rcMax) // Sets up the Resizer by specifying the parent window (usually a dialog), // and the minimum and maximum allowed rectangle sizes. { assert (NULL != pParent); m_pParent = pParent; m_rcInit = pParent->GetClientRect(); m_rcMin = rcMin; m_rcMax = rcMax; // Add scroll bar support to the parent window DWORD dwStyle = (DWORD)m_pParent->GetClassLongPtr(GCL_STYLE); dwStyle |= WS_HSCROLL | WS_VSCROLL; m_pParent->SetClassLongPtr(GCL_STYLE, dwStyle); } void inline CResizer::OnHScroll(WPARAM wParam, LPARAM /*lParam*/) { int xNewPos; switch (LOWORD(wParam)) { case SB_PAGEUP: // User clicked the scroll bar shaft left of the scroll box. xNewPos = m_xScrollPos - 50; break; case SB_PAGEDOWN: // User clicked the scroll bar shaft right of the scroll box. xNewPos = m_xScrollPos + 50; break; case SB_LINEUP: // User clicked the left arrow. xNewPos = m_xScrollPos - 5; break; case SB_LINEDOWN: // User clicked the right arrow. xNewPos = m_xScrollPos + 5; break; case SB_THUMBPOSITION: // User dragged the scroll box. xNewPos = HIWORD(wParam); break; case SB_THUMBTRACK: // User dragging the scroll box. xNewPos = HIWORD(wParam); break; default: xNewPos = m_xScrollPos; } // Scroll the window. xNewPos = MAX(0, xNewPos); xNewPos = MIN( xNewPos, GetMinRect().Width() - m_pParent->GetClientRect().Width() ); int xDelta = xNewPos - m_xScrollPos; m_xScrollPos = xNewPos; m_pParent->ScrollWindow(-xDelta, 0, NULL, NULL); // Reset the scroll bar. SCROLLINFO si = {0}; si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = m_xScrollPos; m_pParent->SetScrollInfo(SB_HORZ, si, TRUE); } void inline CResizer::OnVScroll(WPARAM wParam, LPARAM /*lParam*/) { int yNewPos; switch (LOWORD(wParam)) { case SB_PAGEUP: // User clicked the scroll bar shaft above the scroll box. yNewPos = m_yScrollPos - 50; break; case SB_PAGEDOWN: // User clicked the scroll bar shaft below the scroll box. yNewPos = m_yScrollPos + 50; break; case SB_LINEUP: // User clicked the top arrow. yNewPos = m_yScrollPos - 5; break; case SB_LINEDOWN: // User clicked the bottom arrow. yNewPos = m_yScrollPos + 5; break; case SB_THUMBPOSITION: // User dragged the scroll box. yNewPos = HIWORD(wParam); break; case SB_THUMBTRACK: // User dragging the scroll box. yNewPos = HIWORD(wParam); break; default: yNewPos = m_yScrollPos; } // Scroll the window. yNewPos = MAX(0, yNewPos); yNewPos = MIN( yNewPos, GetMinRect().Height() - m_pParent->GetClientRect().Height() ); int yDelta = yNewPos - m_yScrollPos; m_yScrollPos = yNewPos; m_pParent->ScrollWindow(0, -yDelta, NULL, NULL); // Reset the scroll bar. SCROLLINFO si = {0}; si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = m_yScrollPos; m_pParent->SetScrollInfo(SB_VERT, si, TRUE); } void inline CResizer::RecalcLayout() // Repositions the child windows. Call this function when handling // the WM_SIZE message in the parent window. { assert (m_rcInit.Width() > 0 && m_rcInit.Height() > 0); assert (NULL != m_pParent); CRect rcCurrent = m_pParent->GetClientRect(); // Adjust the scrolling if required m_xScrollPos = MIN(m_xScrollPos, MAX(0, m_rcMin.Width() - rcCurrent.Width() ) ); m_yScrollPos = MIN(m_yScrollPos, MAX(0, m_rcMin.Height() - rcCurrent.Height()) ); SCROLLINFO si = {0}; si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMax = m_rcMin.Width(); si.nPage = rcCurrent.Width(); si.nPos = m_xScrollPos; m_pParent->SetScrollInfo(SB_HORZ, si, TRUE); si.nMax = m_rcMin.Height(); si.nPage = rcCurrent.Height(); si.nPos = m_yScrollPos; m_pParent->SetScrollInfo(SB_VERT, si, TRUE); rcCurrent.right = MAX( rcCurrent.Width(), m_rcMin.Width() ); rcCurrent.bottom = MAX( rcCurrent.Height(), m_rcMin.Height() ); if (!m_rcMax.IsRectEmpty()) { rcCurrent.right = MIN( rcCurrent.Width(), m_rcMax.Width() ); rcCurrent.bottom = MIN( rcCurrent.Height(), m_rcMax.Height() ); } // Declare an iterator to step through the vector std::vector::iterator iter; for (iter = m_vResizeData.begin(); iter < m_vResizeData.end(); ++iter) { int left = 0; int top = 0; int width = 0; int height = 0; // Calculate the new size and position of the child window switch( (*iter).corner ) { case topleft: width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width(); height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height(); left = (*iter).rcInit.left; top = (*iter).rcInit.top; break; case topright: width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width(); height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height(); left = (*iter).rcInit.right - width - m_rcInit.Width() + rcCurrent.Width(); top = (*iter).rcInit.top; break; case bottomleft: width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width(); height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height(); left = (*iter).rcInit.left; top = (*iter).rcInit.bottom - height - m_rcInit.Height() + rcCurrent.Height(); break; case bottomright: width = (*iter).bFixedWidth? (*iter).rcInit.Width() : (*iter).rcInit.Width() - m_rcInit.Width() + rcCurrent.Width(); height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height(); left = (*iter).rcInit.right - width - m_rcInit.Width() + rcCurrent.Width(); top = (*iter).rcInit.bottom - height - m_rcInit.Height() + rcCurrent.Height(); break; } // Position the child window. CRect rc(left - m_xScrollPos, top - m_yScrollPos, left + width - m_xScrollPos, top + height - m_yScrollPos); if ( rc != (*iter).rcOld) { CWnd* pWnd = FromHandle((*iter).hWnd); CWnd *pWndPrev = pWnd->GetWindow(GW_HWNDPREV); // Trick to maintain the original tab order. HWND hWnd = pWndPrev ? pWndPrev->GetHwnd():NULL; pWnd->SetWindowPos(hWnd, rc, SWP_NOCOPYBITS); (*iter).rcOld = rc; } } } #endif // #ifndef _WIN32_WCE } // namespace Win32xx #endif // _WIN32XX_DIALOG_H_