自适应对话框 现在我用vs2008下的MFC做了一个对话框程序拿到客户那边用发现他是15寸的显示屏我的软件有点大了现在我想把我的软件做成自适应这个对话框如何更具屏幕的大小自己调整大小?请教各位大侠 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用MoveWindow函数OnSize中对你对话框中的控件进行调整 GetSystemMetrics来获取屏幕信息,然后用MoveWindow或SetWindowPos来调整 BOOL Zoom_Window(HWND hWnd, CRect TaregetEX_Pos, LPRECT mOrgRect=NULL, BOOL bZoomEx_Only=FALSE){ if(hWnd) { BOOL IsVisable = IsWindowVisible(hWnd); if(!bZoomEx_Only) { ::SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW); CRect SrcWndRect; if(mOrgRect) { SrcWndRect = mOrgRect; } else { GetWindowRect(hWnd,&SrcWndRect); } DWORD style = GetWindowLong(hWnd, GWL_STYLE); INT_PTR Board_dx = 0, Board_dy = 0; if( WS_CAPTION == (style & WS_CAPTION) ) { Board_dy += GetSystemMetrics(SM_CYCAPTION); } if( WS_DLGFRAME == (style & WS_DLGFRAME) ) { Board_dx += 2 * GetSystemMetrics(SM_CXBORDER); Board_dy += 2 * GetSystemMetrics(SM_CYBORDER); } else if( WS_BORDER == (style & WS_BORDER) ) { Board_dx += GetSystemMetrics(SM_CXBORDER); Board_dy += GetSystemMetrics(SM_CYBORDER); } else { } double dx = (double)(TaregetEX_Pos.Width() - Board_dx) / (double)(SrcWndRect.Width() - Board_dx); double dy = (double)(TaregetEX_Pos.Height() - Board_dy) / (double)(SrcWndRect.Height() - Board_dy); HWND hChild = ::GetWindow(hWnd, GW_CHILD); while(hChild != NULL) { CRect rect; GetWindowRect(hChild, &rect); CPoint pt_lt(rect.left, rect.top); ScreenToClient(hWnd, &pt_lt); MoveWindow(hChild, (INT)(pt_lt.x * dx), (INT)(pt_lt.y * dy), (INT)(rect.Width() * dx), (INT)(rect.Height() * dy), true); hChild = GetWindow(hChild, GW_HWNDNEXT); } } //MoveWindow(hWnd, TaregetEX_Pos.left, TaregetEX_Pos.top, TaregetEX_Pos.right, TaregetEX_Pos.bottom, true); UINT nFlage = SWP_NOZORDER|SWP_DRAWFRAME|SWP_DEFERERASE; if(IsVisable) nFlage |= SWP_SHOWWINDOW; ::SetWindowPos(hWnd, 0, TaregetEX_Pos.left, TaregetEX_Pos.top, TaregetEX_Pos.Width(), TaregetEX_Pos.Height(), nFlage); } return(false);}//应用CCCCDlg::OnInitDialog(){ CDialog::OnInitDialog(); Zoom_Window(GetSafeHwnd(), CRect(0,0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)) ); ……} 要让对话框中的控件随着对话框大小的变化进行自动调整,是一件很头疼的事情,需要在WM_SIZE的响应函数中对所有的控件用MoveWindow()或者SetWindowPos()设置其变化比例,极其繁琐。EasySize是一个很好解决方案,用一些宏封装了内部的实现机制,使用起来方便快捷。原文地址:http://www.codeproject.com/KB/dialog/easysize.aspx 使用方法如下:1.首先将EasySize.h拷贝到工程文件夹中,然后在stdafx.h中包含该头文件:#include "EasySize.h" 2.在对话框类声明中添加DECLARE_EASYSIZE宏:class CEasySizeDemoDlg : public CDialog{DECLARE_EASYSIZE... 3.在OnInitDialog()函数中添加INIT_EASYSIZE宏(注意有分号):BOOL CEasySizeDemoDlg::OnInitDialog(){ CDialog::OnInitDialog();... INIT_EASYSIZE; return TRUE; // return TRUE unless you set the focus to a control} 4.响应WM_SIZE消息,在响应函数中添加UPDATE_EASYSIZE宏(注意有分号):void CEasySizeDemoDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); UPDATE_EASYSIZE;} 5.如果需要限制对话框有一个最小尺寸,首先在资源视图中为对话框添加上最大化最小化按钮,然后Class Wizard中选择Class Info标签,在Message fileter下拉列表中选择Window,然后再点击Message Maps标签,就出现WM_SIZING消息了,添加该消息的响应函数:void CEasySizeDemoDlg::OnSizing(UINT fwSide, LPRECT pRect) { CDialog::OnSizing(fwSide, pRect); EASYSIZE_MINSIZE(280,250,fwSide,pRect);}这样就把对话框的最小尺寸限制在(280, 250)上了 6.添加控件布局映射,放到消息映射之后,基本格式如下:BEGIN_EASYSIZE_MAP(class_name) ... EASYSIZE(control,left,top,right,bottom,options) ...END_EASYSIZE_MAP class_name就是对话框类的类名control是要设置的控件的IDleft、top、right、bottom分别指的是该控件左、上、右、下方的控件的ID,也可以为以下特殊值: ES_BORDER:保持与边框距离不变 ES_KEEPSIZE:保持大小不变 所放位置: left -- 表示和right指定的控件右对齐 right -- 表示和left指定的控件左对齐 top -- 表示和bottom指定的控件上对齐 bottom -- 表示和top指定的控件下对齐options可指定为0,也可指定为以下值: ES_HCENTER:保持宽度不变,水平位置在left和right指定的控件正中间 ES_VCENTER:保持高度不变,垂直位置在left和right指定的控件正中间 用代码画界面就可以了,这样子开始画之前就GetDesktopWindow取得桌面句柄,再取得桌面RECT,就可以一个一个地画了 前几行输出比较乱,贴出来看 MFC支持winsock2.0吗? 重新提问!解决立刻给分!! 怎么取得CComboBox的当前值? VC中怎么获得键盘的输入阿? 关于在工具条上生成combobox的问题,高手请进,至少100分的高分相送! 请yousen大侠来领分! 关于时间的问题! 请问MFC的发展前途怎样 新人求助 如何在mfc中使用类似ckedit的富文本插件 还有如何获取其中的数据 IDispatch::GetIDsOfNames是什么意思呢? 坐等结贴。 垂直滚动条问题
BOOL Zoom_Window(HWND hWnd, CRect TaregetEX_Pos, LPRECT mOrgRect=NULL, BOOL bZoomEx_Only=FALSE)
{
if(hWnd)
{
BOOL IsVisable = IsWindowVisible(hWnd); if(!bZoomEx_Only)
{
::SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_HIDEWINDOW); CRect SrcWndRect;
if(mOrgRect)
{
SrcWndRect = mOrgRect;
}
else
{
GetWindowRect(hWnd,&SrcWndRect);
} DWORD style = GetWindowLong(hWnd, GWL_STYLE); INT_PTR Board_dx = 0, Board_dy = 0; if( WS_CAPTION == (style & WS_CAPTION) )
{
Board_dy += GetSystemMetrics(SM_CYCAPTION);
} if( WS_DLGFRAME == (style & WS_DLGFRAME) )
{
Board_dx += 2 * GetSystemMetrics(SM_CXBORDER);
Board_dy += 2 * GetSystemMetrics(SM_CYBORDER);
}
else if( WS_BORDER == (style & WS_BORDER) )
{
Board_dx += GetSystemMetrics(SM_CXBORDER);
Board_dy += GetSystemMetrics(SM_CYBORDER);
}
else
{
} double dx = (double)(TaregetEX_Pos.Width() - Board_dx) / (double)(SrcWndRect.Width() - Board_dx);
double dy = (double)(TaregetEX_Pos.Height() - Board_dy) / (double)(SrcWndRect.Height() - Board_dy); HWND hChild = ::GetWindow(hWnd, GW_CHILD);
while(hChild != NULL)
{
CRect rect;
GetWindowRect(hChild, &rect);
CPoint pt_lt(rect.left, rect.top);
ScreenToClient(hWnd, &pt_lt);
MoveWindow(hChild,
(INT)(pt_lt.x * dx),
(INT)(pt_lt.y * dy),
(INT)(rect.Width() * dx),
(INT)(rect.Height() * dy), true); hChild = GetWindow(hChild, GW_HWNDNEXT);
}
}
//MoveWindow(hWnd, TaregetEX_Pos.left, TaregetEX_Pos.top, TaregetEX_Pos.right, TaregetEX_Pos.bottom, true);
UINT nFlage = SWP_NOZORDER|SWP_DRAWFRAME|SWP_DEFERERASE;
if(IsVisable) nFlage |= SWP_SHOWWINDOW;
::SetWindowPos(hWnd, 0,
TaregetEX_Pos.left, TaregetEX_Pos.top, TaregetEX_Pos.Width(), TaregetEX_Pos.Height(),
nFlage);
}
return(false);
}//应用
CCCCDlg::OnInitDialog()
{
CDialog::OnInitDialog(); Zoom_Window(GetSafeHwnd(),
CRect(0,0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)) );
……
}
#include "EasySize.h" 2.在对话框类声明中添加DECLARE_EASYSIZE宏:
class CEasySizeDemoDlg : public CDialog
{
DECLARE_EASYSIZE
... 3.在OnInitDialog()函数中添加INIT_EASYSIZE宏(注意有分号):
BOOL CEasySizeDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
INIT_EASYSIZE;
return TRUE; // return TRUE unless you set the focus to a control
} 4.响应WM_SIZE消息,在响应函数中添加UPDATE_EASYSIZE宏(注意有分号):
void CEasySizeDemoDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
UPDATE_EASYSIZE;
} 5.如果需要限制对话框有一个最小尺寸,首先在资源视图中为对话框添加上最大化最小化按钮,然后Class Wizard中选择Class Info标签,在Message fileter下拉列表中选择Window,然后再点击Message Maps标签,就出现WM_SIZING消息了,添加该消息的响应函数:
void CEasySizeDemoDlg::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialog::OnSizing(fwSide, pRect);
EASYSIZE_MINSIZE(280,250,fwSide,pRect);
}
这样就把对话框的最小尺寸限制在(280, 250)上了 6.添加控件布局映射,放到消息映射之后,基本格式如下:
BEGIN_EASYSIZE_MAP(class_name)
...
EASYSIZE(control,left,top,right,bottom,options)
...
END_EASYSIZE_MAP class_name就是对话框类的类名control是要设置的控件的IDleft、top、right、bottom分别指的是该控件左、上、右、下方的控件的ID,也可以为以下特殊值:
ES_BORDER:保持与边框距离不变
ES_KEEPSIZE:保持大小不变
所放位置:
left -- 表示和right指定的控件右对齐
right -- 表示和left指定的控件左对齐
top -- 表示和bottom指定的控件上对齐
bottom -- 表示和top指定的控件下对齐options可指定为0,也可指定为以下值:
ES_HCENTER:保持宽度不变,水平位置在left和right指定的控件正中间
ES_VCENTER:保持高度不变,垂直位置在left和right指定的控件正中间