作者:刘树伟
QQ:1584793892
完整文章及示例代码请访问:www.iuishop.com
在*.rc中,对话框中及其中的控件的坐标单位叫“对话框坐标单位”,英文缩写为DLU。它们实际上依据一种特殊的坐标系统,该系统只用于对话框模板。数字依据对话框使用字体的大小而定:x坐标和宽度的单位是字符平均宽度的1/4;y坐标和高度的单位是字符高度的1/8。
公式如下:
pixelX = (dialogUnitX * baseUnitX) / 4
pixelY = (dialogUnitY * baseUnitY) / 8
其中:dialogUnitX为rc文件中,元素的坐标值。baseUnitX为对话框单位。
使用GetDialogBaseUnits()可以得到对话框单位,在计算时,它总是以系统字体为标准。如果你为对话框设置了与系统字体不同的字体。可以使用下面两种方法中的任意一种来计算对话框单位。
方法一:
对话框的垂直单位与设置为对话框的字体的字符高度相同。水平单位与字符平均宽度相同。平均宽度可以通过字母表中的52个字符(大小写各26个)的总宽度除以52得到。代码如下:
void CAboutDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CFont* pFont = GetFont();
CFont* oldFont = dc.SelectObject(pFont);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
int baseUnitY = tm.tmHeight;
CSize size;
size = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52);
int baseUnitX = (size.cx / 26 + 1) / 2;
TRACE("baseUnitX = %d\n", baseUnitX);
TRACE("baseUnitY = %d\n", baseUnitY);
dc.SelectObject(oldFont);
}
把计算得到的baseUnitX和baseUnitY代入上面的公司,就可以计算对应的像素值了。
方法二:
这种方法更简单,使用MapDialogRect()函数把CRect rc(0, 0, 4, 8);坐标转换后的right和bottom值,就是对话框单位。代码如下:
void CAboutDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rc(0, 0, 4, 8);
MapDialogRect(&rc);
int baseUnitY = rc.bottom;
int baseUnitX = rc.right;
TRACE("baseUnitX = %d\n", baseUnitX);
TRACE("baseUnitY = %d\n", baseUnitY);
}
例如:如果在rc中,某个对话框的宽度为320,高度为200。通过上面两种方法之一,计算得到baseUnitX为6,baseUnitY为13。那么对话框运行后,尺寸像素为:
width = 320 * 6 / 4 = 480;
height = 200 * 13 / 8 = 325。
但请注意的是:这里的宽度和高度对应的是客户区大小,不包含非客户区。