看到一段打印边距设置的代码,不太明白。运行后的数据
int GetDeviceCaps( HDC hdc, int nIndex); 其中,hdc用来指定设备环境句柄,nIndex用来指定要获取的参量索引,对于打印机而言,它常常需要下列的预定义值: LOGPIXELSX 打印机水平分辨率 LOGPIXELSY 打印机垂直分辨率 PHYSICALWIDTH 打印纸的实际宽度 PHYSICALHEIGHT 打印纸的实际高度 PHYSICALOFFSETX 实际可打印区域的物理左边距 PHYSICALOFFSETY 实际可打印区域的物理上边距
下面的函数代码就是用来设置页边距,并且还计算页面的物理边距: void CEx_Prn1View::SetPageMargin(CDC *pDC, CPrintInfo *pInfo, int l, int t, int r, int b)
// l, t, r, b分别表示左上右下边距, 单位为0.1mm
{
int nOldMode = pDC-> GetMapMode();
pDC-> SetMapMode(MM_LOMETRIC);
// 计算一个设备单位等于多少0.1mm
double scaleX = 254.0 / (double)GetDeviceCaps(
pDC-> m_hAttribDC, LOGPIXELSX);
double scaleY = 254.0 / (double)GetDeviceCaps(
pDC-> m_hAttribDC, LOGPIXELSY);
int x = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALOFFSETX);
int y = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALOFFSETY);
int w = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALWIDTH);
int h = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALHEIGHT);
int nPageWidth = (int)((double)w*scaleX + 0.5);
// 纸宽,单位0.1mm
int nPageHeight = (int)((double)h*scaleY + 0.5);
// 纸高,单位0.1mm
m_nPhyLeft = (int)((double)x*scaleX + 0.5);
// 物理左边距,单位0.1mm
m_nPhyTop = (int)((double)y*scaleY + 0.5);
// 物理上边距,单位0.1mm
pDC-> DPtoLP(&pInfo-> m_rectDraw);
CRect rcTemp = pInfo-> m_rectDraw;
rcTemp.NormalizeRect();
m_nPhyRight = nPageWidth - rcTemp.Width() -
m_nPhyLeft; // 物理右边距,单位0.1mm
m_nPhyBottom = nPageHeight - rcTemp.Height() -
m_nPhyTop; // 物理下边距,单位0.1mm
// 若边距小于物理边距,则调整它们
if (l < m_nPhyLeft) l = m_nPhyLeft;
if (t < m_nPhyTop) t = m_nPhyTop;
if (r < m_nPhyRight) r = m_nPhyRight;
if (b < m_nPhyBottom) b = m_nPhyBottom;
// 计算并调整pInfo-> m_rectDraw的大小
pInfo-> m_rectDraw.left = l - m_nPhyLeft;
pInfo-> m_rectDraw.top = - t + m_nPhyTop;
pInfo-> m_rectDraw.right -= r - m_nPhyRight;
pInfo-> m_rectDraw.bottom += b - m_nPhyBottom;
pDC-> LPtoDP(&pInfo-> m_rectDraw);
pDC-> SetMapMode(nOldMode);
// 恢复原来的映射模式
} 此函数原帖地址:http://topic.csdn.net/t/20040421/16/2992523.html调用此函数时,第二个参数这样设置可以吗?
取得的rectPrint的四个成员的值分别为left=0,top=0, right=4720,bottom=6776
CRect rectPrint(0, 0,
dc.GetDeviceCaps(HORZRES), // Get physical display width in millimeter of device
dc.GetDeviceCaps(VERTRES)); // Get physical display height in millimeter of device CPrintInfo info;
info.m_rectDraw = rectPrint; SetPageMargin(&dc, &info, ...);
执行SetPageMargin函数后,rectPrint的四个成员的值分别为left=249,top=-299, right=1749,bottom=-2619
为什么会这样呢?默认不是左上为x,y轴的原点吗?
int GetDeviceCaps( HDC hdc, int nIndex); 其中,hdc用来指定设备环境句柄,nIndex用来指定要获取的参量索引,对于打印机而言,它常常需要下列的预定义值: LOGPIXELSX 打印机水平分辨率 LOGPIXELSY 打印机垂直分辨率 PHYSICALWIDTH 打印纸的实际宽度 PHYSICALHEIGHT 打印纸的实际高度 PHYSICALOFFSETX 实际可打印区域的物理左边距 PHYSICALOFFSETY 实际可打印区域的物理上边距
下面的函数代码就是用来设置页边距,并且还计算页面的物理边距: void CEx_Prn1View::SetPageMargin(CDC *pDC, CPrintInfo *pInfo, int l, int t, int r, int b)
// l, t, r, b分别表示左上右下边距, 单位为0.1mm
{
int nOldMode = pDC-> GetMapMode();
pDC-> SetMapMode(MM_LOMETRIC);
// 计算一个设备单位等于多少0.1mm
double scaleX = 254.0 / (double)GetDeviceCaps(
pDC-> m_hAttribDC, LOGPIXELSX);
double scaleY = 254.0 / (double)GetDeviceCaps(
pDC-> m_hAttribDC, LOGPIXELSY);
int x = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALOFFSETX);
int y = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALOFFSETY);
int w = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALWIDTH);
int h = GetDeviceCaps(pDC-> m_hAttribDC,
PHYSICALHEIGHT);
int nPageWidth = (int)((double)w*scaleX + 0.5);
// 纸宽,单位0.1mm
int nPageHeight = (int)((double)h*scaleY + 0.5);
// 纸高,单位0.1mm
m_nPhyLeft = (int)((double)x*scaleX + 0.5);
// 物理左边距,单位0.1mm
m_nPhyTop = (int)((double)y*scaleY + 0.5);
// 物理上边距,单位0.1mm
pDC-> DPtoLP(&pInfo-> m_rectDraw);
CRect rcTemp = pInfo-> m_rectDraw;
rcTemp.NormalizeRect();
m_nPhyRight = nPageWidth - rcTemp.Width() -
m_nPhyLeft; // 物理右边距,单位0.1mm
m_nPhyBottom = nPageHeight - rcTemp.Height() -
m_nPhyTop; // 物理下边距,单位0.1mm
// 若边距小于物理边距,则调整它们
if (l < m_nPhyLeft) l = m_nPhyLeft;
if (t < m_nPhyTop) t = m_nPhyTop;
if (r < m_nPhyRight) r = m_nPhyRight;
if (b < m_nPhyBottom) b = m_nPhyBottom;
// 计算并调整pInfo-> m_rectDraw的大小
pInfo-> m_rectDraw.left = l - m_nPhyLeft;
pInfo-> m_rectDraw.top = - t + m_nPhyTop;
pInfo-> m_rectDraw.right -= r - m_nPhyRight;
pInfo-> m_rectDraw.bottom += b - m_nPhyBottom;
pDC-> LPtoDP(&pInfo-> m_rectDraw);
pDC-> SetMapMode(nOldMode);
// 恢复原来的映射模式
} 此函数原帖地址:http://topic.csdn.net/t/20040421/16/2992523.html调用此函数时,第二个参数这样设置可以吗?
取得的rectPrint的四个成员的值分别为left=0,top=0, right=4720,bottom=6776
CRect rectPrint(0, 0,
dc.GetDeviceCaps(HORZRES), // Get physical display width in millimeter of device
dc.GetDeviceCaps(VERTRES)); // Get physical display height in millimeter of device CPrintInfo info;
info.m_rectDraw = rectPrint; SetPageMargin(&dc, &info, ...);
执行SetPageMargin函数后,rectPrint的四个成员的值分别为left=249,top=-299, right=1749,bottom=-2619
为什么会这样呢?默认不是左上为x,y轴的原点吗?
pDC-> SetMapMode(MM_LOMETRIC);
MM_LOMETRIC 每一逻辑单位对换0.1毫米,X向右为正,Y向上为正。
是这样吗?
单步运行程序,一步步跟踪,看看值得变化,基本就清楚了.为何出现top=-299
正x的方向向右
正y的方向向上
该模式的原点没有特别指明,应该是(0,0)点,原点下方的区域为Y轴负半区
Res
--------------------------------------------------------------------------------The mapping mode defines the unit of measure used to convert logical units to device units; it also defines the orientation of the device's x- and y-axes
MM_LOMETRIC Each logical unit is mapped to 0.1 millimeter. Positive x is to the right; positive y is up.