// 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;
}
}