页边距

  完整的打印和打印预览设计工作包括控制页边距和行距、设计页眉页脚、控制打印字体、选择打印模式、多页打印以及预览功能实现等。好在CEditView已经实现了多页打印和预览功能,因此,我们只要在此基础上添加页边距设置、页眉页脚以及控制打印字体等功能,就一定能满足绝大多数ASCII文档打印的需要。

  1.设置页边距

  页边距是指打印的文本区域与打印纸边界之间的距离,包括左、右、上和下边距。设置时可参考CPrintInfo的成员变量m_rectDraw的数值,但m_rectDraw的数值表示的是有效打印区域,它本身与打印纸边界有一定的边距,这个边距是打印机自身造成的,因此称之为物理边距,并且这些物理边距在不同大小的纸张中是不一样的,因此首先要获取这些数值。这时就需要调用全局函数GetDeviceCaps,它的原型如下:

int GetDeviceCaps( HDC hdc, int nIndex);

  其中,hdc用来指定设备环境句柄,nIndex用来指定要获取的参量索引,对于打印机而言,它常常需要下列的预定义值:

   LOGPIXELSX   打印机水平分辨率

   LOGPIXELSY   打印机垂直分辨率

   PHYSICALWIDTH  打印纸的实际宽度

   PHYSICALHEIGHT 打印纸的实际高度

   PHYSICALOFFSETX 实际可打印区域的物理左边距

   PHYSICALOFFSETY 实际可打印区域的物理上边距

  需要说明的是,若一张打印纸的大小为A4(210 x 297毫米),且打印机的分辨率为300 x300dpi,当指定函数的参数值为PHYSICALWIDTH时,则返回的值不是210毫米,而是2480。这个结果是这样计算来的:首先将毫米单位转换成英寸,即210毫米变成8.267英寸,然后乘以300dpi。

  下面的函数代码就是用来设置页边距,并且还计算页面的物理边距:

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);
// 恢复原来的映射模式
}

  需要说明的是,由于CEditView中的设置环境映射模式是MM_TEXT,即逻辑坐标和设备坐标相同,因此需要通过LPtoDP和DPtoLP函数在逻辑坐标(LP)和设备坐标(DP)之间进行转换。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值