// EasySize.h
/* * 说明:一个用于在MFC对话框程序改变大小时自动保持各控件相对位置的功能类。 * 用法:1、定义一个成员变量 CEasySize m_cEasySize; * 2、在对话框程序的OnInitDialog方法中加入 m_cEasySize.OnInitDialog(this); * 3、在对话框程序的OnSize方法中加入 m_cEasySize.OnSize(cx, cy); */ #pragma once #include <afxtempl.h> struct ControlPos { int nID; float fT; float fB; float fL; float fR; }; class CEasySize { public: CEasySize(); public: void OnInitDialog(CDialog* pDlg); void OnInitDialog(HWND hWnd); void OnSize(int cx, int cy); private: void RecordControlPos(int nID, CRect cClientRect); void AdjustControlPos(int nID, int cx, int cy); private: BOOL m_Init; HWND m_hDlg; CList<ControlPos> m_listControlPos; };
// EasySize.cpp
#include "stdafx.h" #include "EasySize.h" CEasySize::CEasySize() { m_Init = FALSE; m_hDlg = NULL; } void CEasySize::OnInitDialog(CDialog* pDlg) { OnInitDialog(pDlg->GetSafeHwnd()); } void CEasySize::OnInitDialog(HWND hWnd) { m_Init = TRUE; m_hDlg = hWnd; CRect cClientRect; GetClientRect(m_hDlg, &cClientRect); HWND hWndChild = GetWindow(m_hDlg, GW_CHILD); while ( hWndChild ) { CWnd *pCWnd = CWnd::FromHandle(hWndChild); LONG nID = GetWindowLong(pCWnd->m_hWnd, GWL_ID); RecordControlPos(nID, cClientRect); hWndChild = GetWindow(hWndChild, GW_HWNDNEXT); } } void CEasySize::OnSize(int cx, int cy) { if ( !m_Init ) { return ; } HWND hWndChild = GetWindow(m_hDlg, GW_CHILD); while ( hWndChild ) { CWnd* pCWnd = CWnd::FromHandle(hWndChild); LONG nID = GetWindowLong(pCWnd->m_hWnd, GWL_ID); AdjustControlPos(nID, cx, cy); hWndChild = GetWindow(hWndChild, GW_HWNDNEXT); } } void CEasySize::RecordControlPos(int nID, CRect cClientRect) { CRect rect; GetWindowRect(GetDlgItem(m_hDlg, nID), &rect); ScreenToClient(m_hDlg, (LPPOINT)&rect); ScreenToClient(m_hDlg, ((LPPOINT)&rect)+1); ControlPos cControlPos; cControlPos.nID = nID; cControlPos.fT = float(rect.top) / float(cClientRect.Height()); cControlPos.fB = float(rect.bottom) / float(cClientRect.Height()); cControlPos.fL = float(rect.left) / float(cClientRect.Width()); cControlPos.fR = float(rect.right) / float(cClientRect.Width()); int nCount = (int)m_listControlPos.GetCount(); if ( 0 == nCount ) { m_listControlPos.AddTail(cControlPos); return ; } else { POSITION pos = m_listControlPos.GetHeadPosition(); while ( nCount ) { ControlPos cControlPosTmp = m_listControlPos.GetAt(pos); if ( cControlPosTmp.nID == nID ) { return ; } m_listControlPos.GetNext(pos); --nCount; } m_listControlPos.AddTail(cControlPos); } } void CEasySize::AdjustControlPos(int nID, int cx, int cy) { int nCount = (int)m_listControlPos.GetCount(); POSITION pos = m_listControlPos.GetHeadPosition(); while ( nCount ) { ControlPos cControlPos; cControlPos = m_listControlPos.GetAt(pos); if ( cControlPos.nID == nID ) { CRect rect; rect.top = LONG(cControlPos.fT * cy); rect.bottom = LONG(cControlPos.fB * cy); rect.left = LONG(cControlPos.fL * cx); rect.right = LONG(cControlPos.fR * cx); MoveWindow( GetDlgItem(m_hDlg, nID), rect.left, rect.top, rect.Width(), rect.Height(), TRUE); return ; } m_listControlPos.GetNext(pos); --nCount; } }