MFC中当改变对话框大小时怎么让控件自动调整大小
MFC中当改变对话框大小时怎么让控件自动调整大小?让控件随对话框的改变而调整大小
有代码的可以发给我,我邮箱是3624240213@163.com
[解决办法]
响应WM_SIZE消息,然后MoveWindow等调整各个控件成比例
class CWndAutoPos
{
struct ITEM_DATA
{
CRect Rect;
int nID;
int nPersentX;
int nPersentY;
int nPersentWidth;
int nPersentHeigh;
BOOL bReDraw;
};
public:
CWndAutoPos();
~CWndAutoPos();
BOOL Clear();
BOOL AddItem(int nID, BOOL bReDraw = FALSE, int nPersentX = 0, int nPersentY = 0, int nPersentWidth = 0, int nPersentHeigh = 0);
BOOL InitOrgSize(CWnd *pParent);
BOOL InflateItemRect(int nID, CRect &IftRect, BOOL bRePaint = TRUE);
BOOL DeflateItemRect(int nID, CRect &DftRect, BOOL bRePaint = TRUE);
BOOL FindItem(int nID, ITEM_DATA **ppItemData);
virtual void OnParentSize(int nWidth, int nHeigh, BOOL bRepaint = FALSE);
//
CWnd * m_pParent;
int m_nWidth;
int m_nHeigh;
CList<ITEM_DATA> m_ItemList;
};
////////////////////////////////////////////////////////////////////////////////
// CwndAutoPos
BOOL NMfc::GetDlgBkRgn(CWnd *pWnd, CRgn *pBkRgn)
{
CWnd * pChildWnd;
DWORD dwStyle;
CRect MainRect;
CRect OneRect;
CRgn MainRgn;
CRgn AllRgn;
CRgn OneRgn;
pWnd->GetWindowRect(MainRect);
pWnd->ScreenToClient(MainRect);
MainRgn.CreateRectRgnIndirect(MainRect);
AllRgn.CreateRectRgn(0, 0, 0, 0);
for(pChildWnd = pWnd->GetTopWindow();
pChildWnd;
pChildWnd = pChildWnd->GetNextWindow(GW_HWNDNEXT))
{
dwStyle = pChildWnd->GetStyle();
if((dwStyle & WS_VISIBLE) == 0)
continue;
pChildWnd->GetWindowRect(OneRect);
pWnd->ScreenToClient(OneRect);
OneRgn.CreateRectRgnIndirect(OneRect);
AllRgn.CombineRgn(&AllRgn, &OneRgn, RGN_OR);
OneRgn.DeleteObject();
}
pBkRgn->CreateRectRgn(0, 0, 0, 0);
pBkRgn->CombineRgn(&MainRgn, &AllRgn, RGN_XOR);
MainRgn.DeleteObject();
AllRgn.DeleteObject();
return TRUE;
}
CWndAutoPos::CWndAutoPos()
{
m_nWidth = 0;
m_nHeigh = 0;
m_pParent = NULL;
}
CWndAutoPos::~CWndAutoPos()
{
}
BOOL CWndAutoPos::Clear()
{
return FALSE;
}
BOOL CWndAutoPos::AddItem(int nID, BOOL bReDraw, int nPersentX, int nPersentY, int nPersentWidth, int nPersentHeigh)
{
ITEM_DATA OneItem;
CWnd * pItem;
CRect WindowRect;
pItem = m_pParent->GetDlgItem(nID);
pItem->GetWindowRect(WindowRect);
m_pParent->ScreenToClient(WindowRect);
OneItem.Rect = WindowRect;
OneItem.nID = nID;
OneItem.nPersentX = nPersentX;
OneItem.nPersentY = nPersentY;
OneItem.nPersentWidth = nPersentWidth;
OneItem.nPersentHeigh = nPersentHeigh;
OneItem.bReDraw = bReDraw;
m_ItemList.AddTail(OneItem);
return TRUE;
}
BOOL CWndAutoPos::InitOrgSize(CWnd *pParent)
{
CRect CltRect;
m_pParent = pParent;
pParent->GetClientRect(CltRect);
m_nWidth = CltRect.Width();
m_nHeigh = CltRect.Height();
return TRUE;
}
BOOL CWndAutoPos::FindItem(int nID, ITEM_DATA **ppItemData)
{
POSITION pos;
ITEM_DATA * pItem;
int nCount;
*ppItemData = NULL;
nCount = (int)m_ItemList.GetSize();
if(nCount == 0)
return FALSE;
for(pos = m_ItemList.GetHeadPosition();
pos;
)
{
pItem = &(m_ItemList.GetNext(pos));
if(pItem->nID == nID)
{
*ppItemData = pItem;
return TRUE;
}
}
return FALSE;
}
BOOL CWndAutoPos::InflateItemRect(int nID, CRect &IftRect, BOOL bRePaint)
{
CWnd * pItemWnd;
ITEM_DATA * pItemData;
CRect ItemRect;
pItemWnd = m_pParent->GetDlgItem(nID);
FindItem(nID, &pItemData);
if(pItemData == NULL)
return FALSE;
pItemWnd->GetWindowRect(ItemRect);
m_pParent->ScreenToClient(ItemRect);
ItemRect.InflateRect(IftRect);
pItemWnd->MoveWindow(ItemRect, bRePaint);
pItemData->Rect.InflateRect(IftRect);
return TRUE;
}
BOOL CWndAutoPos::DeflateItemRect(int nID, CRect &DftRect, BOOL bRePaint)
{
CWnd * pItemWnd;
ITEM_DATA * pItemData;
CRect ItemRect;
pItemWnd = m_pParent->GetDlgItem(nID);
FindItem(nID, &pItemData);
if(pItemData == NULL)
return FALSE;
pItemWnd->GetWindowRect(ItemRect);
m_pParent->ScreenToClient(ItemRect);
ItemRect.DeflateRect(DftRect);
pItemWnd->MoveWindow(ItemRect, bRePaint);
pItemData->Rect.DeflateRect(DftRect);
return TRUE;
}
void CWndAutoPos::OnParentSize(int nWidth, int nHeigh, BOOL bRepaint)
{
POSITION pos;
ITEM_DATA * pItem;
CRect FinRect;
int x, y;
int w, h;
CWnd * pItemWnd;
int nCount;
HDWP hWinPosInfo;
CRgn BkRgn;
nCount = (int)m_ItemList.GetSize();
if(nCount == 0)
return;
// m_pParent->RedrawWindow();
hWinPosInfo = BeginDeferWindowPos(nCount);
for(pos = m_ItemList.GetHeadPosition();
pos;
)
{
pItem = &(m_ItemList.GetNext(pos));
pItemWnd = m_pParent->GetDlgItem(pItem->nID);
FinRect = pItem->Rect;
x = pItem->Rect.left;
y = pItem->Rect.top;
w = pItem->Rect.Width();
h = pItem->Rect.Height();
x += (nWidth - m_nWidth) * pItem->nPersentX / 100;
y += (nHeigh - m_nHeigh) * pItem->nPersentY / 100;
w += (nWidth - m_nWidth) * pItem->nPersentWidth / 100;
h += (nHeigh - m_nHeigh) * pItem->nPersentHeigh / 100;
if(bRepaint || pItem->bReDraw)
DeferWindowPos(hWinPosInfo, pItemWnd->GetSafeHwnd(), HWND_TOP, x, y, w, h, SWP_NOZORDER);
else
DeferWindowPos(hWinPosInfo, pItemWnd->GetSafeHwnd(), HWND_TOP, x, y, w, h, SWP_NOZORDER | SWP_NOREDRAW);
}
EndDeferWindowPos(hWinPosInfo);
NMfc::GetDlgBkRgn(m_pParent, &BkRgn);
m_pParent->InvalidateRgn(&BkRgn, TRUE);
return;
}
// CWndAutoPos
////////////////////////////////////////////////////////////////////////////////
用法: (如 CTinyIeDlg )
1. 初始化
BOOL CTinyIeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
…
m_AutoPos.InitOrgSize(this);
m_AutoPos.AddItem(IDC_COMBOBOXEX1, TRUE, 0, 0, 100, 0);
m_AutoPos.AddItem(IDOK, TRUE, 100, 0, 0, 0);
…
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
2. OnSize
void CTinyIeDlg::OnSize(UINT nType, int cx, int cy)
{
m_AutoPos.OnParentSize(cx, cy);
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
}