vc打印机相关设置和pos打印机

我是用的MFC打印机制做的 然后重载了onprint函数 因为我是基于对话框的程序 然后在view类里面重载OnPrint()函数 并且把在这个里面把
如下:

C/C++ code


void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
CFont *pOldFont;
CFont DataFont;
DataFont.CreatePointFont(120,"宋体",pDC);

pOldFont=pDC->SelectObject(&DataFont);
pDC->Rectangle(......);

return TRUE;



这个我就是画了个巨型 Rectangle里面那些参数是我前面设置的 反正就是用pDC->Rectangle()画了个矩形;
问题是 我在打印预览的时候 看到我这个巨型占整个预览的很上面 下面茫茫多都是空白  
也就是说预览的时候 就是预览成一张纸上面画了个矩形,这个矩形在整个这张上面的最上面 占整个纸的很少一部分 然后我在整个过程当中“没有”设置纸张的大小(关键是我不晓得怎么设置) 以达到我有好多信息就打好多出来,因为毕竟是pos打印机 宽度是恒定的 但是长嘛就应该是有好多行信息就打好长的纸出来吧,不像一般的打印机 反正A4纸是固定的  

问题是 我没有任何设置 这个打印机怎么知道我这个矩形画完了 然后下面的空白部分它就不打印了 然后停住了 虽然这个正和我意 但是我翻遍了MFC的书都没有看到这个是怎么回事~~~


问题2:反过来我画一个很长很长的矩形 执行打印预览的时候 预览框上的一张纸都装不完 打印出来也和预览框上面的一样装不完 但是它怎么就不继续打印那装不下的一部分了呢?就是剩余没打完的矩形啊?


我继续重载了

void CPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)  
{
  pInfo->SetMaxPage (4);
}
设 置为4页 这样一来通过MFC的打印原理 会执行4次OnPrint()函数,然后在OnPrint()里面画一个短一点的矩形,也就是在打印预览里面一张纸能装下的那种 然后确实能打出4个矩形来 而且通过打印时候那个WINDOWS自带的对话框来看确实是打了一个再打第二个   

问 题3:按照打印预览里面看的 一个矩形打完后 那张纸还剩下面茫茫多的空白 然后再是第二张纸上面又是一个矩形 以此类推 按照我的理解应该是把那第一张纸下面的空白走完了再继续打第二张纸上面的矩形 但是事实是第一个矩形打完了 然后空点点空白马上就打第二个矩形了 然后直到把所有的矩形全部打完~~~ 这样貌似还给我节约了 本来我的要求也就是这样的 但是为什么??它怎么不把纸走完了再打第二个矩形???


问 题4:我想问题的关键是出在“打印预览”上面 书上说 打印预览是很完善的 都不需要我们去重载什么函数了 我也就没重载什么东西 但是我想知道 它是怎么来设置那张纸的?它怎么通过打印机来设置预览上面那张纸的宽度 高度? 是通过CDC::GetDeviceCaps()么?在我的程序里面从来没有设置过纸的高度宽度什么的.....

下面是我自己的看法 麻烦各位看看小弟我是否正确


最后我觉得 这个POS58打印机 是不是本身在硬件上就设定为没有要打印的东西的时候 它就自动停下来了   

我 感觉这个打印机也是要分页的 虽然这个纸装在里面有30米左右长度 但是从打印预览看出他还是要分页的 虽然宽度是固定 但是这一页很长~~通过前面的经验算下来 可能有半米左右吧 如果信息多了的话 半米都装不完的话 那么在OnPrient()里面还是要设置 第一页打什么 第二页打什么 至于有多少页 那么事先就要设个变量算好 int nPage; 然后在OnBeginPrinting()里面设置好最大页码数 并且在OnPrint() 里面做相应更改

C/C++ code

void CPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
pInfo->SetMaxPage (nPage);
}

void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
int nPageNumber = pInfo->m_nCurPage;

if(nPageNumber==1)
{
//第一页打印的类容
}

if(nPageNumber==2)
{
//第二页打印的类容
}
.........
}


这样来实现 不过在OnPrint() 里面只能靠if来判断该打印些什么 不能动态的弄~~~ 我曾今看过超市的员工就用这种打印机打报表 那个纸要多长有多长 不知道那个软件是怎么完成的 而且如果按照我们这种看法分页的话 那个页与页的衔接真的是天衣无缝的 不知道是怎么弄的



对于上面最后的东西 我觉得 如果我能够在VC里面 在程序开始时添加自定义纸张并设为默认纸张,程序结束前删除该自定义纸张并恢复原来的默认纸张类型。 那么我只要定义一个宽跟这个一样宽 长有很长很长的纸张 那么 所有问题不就解决了么?
以上都是自己的看法 麻烦各位给个意见~~~~


一般打印驱动都会针对常用的DC操作做优化的,所以在pDC指向一个打印机DC的时候,打印机执行的打印指令是Rectangle而不是画图
————————————————————————————————————————————————————

    
楼主发表于:2009-10-26 15:52:42
在做一个地图打印的程序,我想在View里画的地图边框大小和打印机纸张大小成比例
首先,我在OnDraw里面获取了打印机纸张的型号
  AfxGetApp()->GetPrinterDeviceDefaults(&pd)
  lpDevMode=(LPDEVMODE)GlobalLock(pd.hDevMode);  
用lpDevMode->dmPaperSize即可得到打印机纸张的型号了,默认为9(即A4)
然后我想用lpDevMode->dmPaperWidth和lpDevMode->dmPaperLength得到纸张的长宽,发现全部为0
请问,如何由纸张型号来得到它的长宽呢?假设纸张的型号为A4,那么怎么才能知道它的宽为210MM,高为297MM?

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

回复次数:25

    * feilinhe用户头像
    * feilinhe
    * (C/C++)
    *
    * 等 级:
    *

    
#1楼 得分:5回复于:2009-10-26 16:29:51
看看这个
http://gudianjun.spaces.live.com/Blog/cns!1F03C60E71DEB43D!234.entry

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

精华推荐:多线程同步的两个问题,可能需要高手,请关注!

    * scgjc用户头像
    * scgjc
    * (丑小鸭)
    *
    * 等 级:
    *

    
#2楼 得分:5回复于:2009-10-26 16:30:24
我想应该是打印机DC映射模式设置为MM_LOMETRIC或MM_HIMETRIC的前提下,调用GetDeviceCaps获取范围来得到。
如:
  m_prnDC.SetMapMode(MM_LOMETRIC);
  m_iPrnX = m_prnDC.GetDeviceCaps(HORZRES);
m_iPrnY = m_prnDC.GetDeviceCaps(VERTRES);
m_iPrnX为宽,m_iPrnY为高。

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

精华推荐:关于wince系统的内存碎片,收集贴

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#3楼 得分:0回复于:2009-10-26 16:32:13
引用 1 楼 feilinhe 的回复:
看看这个
http://gudianjun.spaces.live.com/Blog/cns!1F03C60E71DEB43D!234.entry

我也想过用GetDeviceCaps,可是GetDeviceCaps需要打印DC
在OnDraw里面没有打印DC,总不能再新建一个吧

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

精华推荐:算法与追MM,太强,不要错过~

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#4楼 得分:0回复于:2009-10-26 16:34:03
其实得到纸张型号时,如型号是A4,它的大小就一定了,210*297
我是问用什么样的方法通过A4来得到它的长宽?

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

精华推荐:超级玛丽制作揭秘文档发布,散分100

    * scgjc用户头像
    * scgjc
    * (丑小鸭)
    *
    * 等 级:
    *

    
#5楼 得分:5回复于:2009-10-26 16:41:25
打印DC和屏幕DC一样的,只是一个打印在纸上,一个画在屏幕上。MFC有固定的模式,可以用屏幕DC来打印,也可以创建和屏幕DC相同的一个打印DC来专门负责打印

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

精华推荐:《我的团长我的团》相关内容

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#6楼 得分:0回复于:2009-10-26 16:51:28
引用 5 楼 scgjc 的回复:
打印DC和屏幕DC一样的,只是一个打印在纸上,一个画在屏幕上。MFC有固定的模式,可以用屏幕DC来打印,也可以创建和屏幕DC相同的一个打印DC来专门负责打印

//获取打印机设备的横方向和纵方向的分辨率
//即每英寸像素点数
int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
如果pDC是打印机DC,那么xPixPerInch =yPixPerInch =600
如果pDC是屏幕DC,那么xPixPerInch =yPixPerInch =96
所以,这两个DC是不同的

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jeff_5388用户头像
    * jeff_5388
    * (披星戴月)
    *
    * 等 级:
    *

    
#7楼 得分:5回复于:2009-10-26 17:08:46
引用 3 楼 liumenghappy 的回复:
引用 1 楼 feilinhe 的回复:
看看这个
http://gudianjun.spaces.live.com/Blog/cns!1F03C60E71DEB43D!234.entry

我也想过用GetDeviceCaps,可是GetDeviceCaps需要打印DC
在OnDraw里面没有打印DC,总不能再新建一个吧


打印时参数pDC就指向打印机的DC了, 而不是屏幕的DC>

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * twins222用户头像
    * twins222
    * (twins222)
    *
    * 等 级:
    *

    
#8楼 得分:5回复于:2009-10-26 17:14:43
引用 6 楼 liumenghappy 的回复:
引用 5 楼 scgjc 的回复:
打印DC和屏幕DC一样的,只是一个打印在纸上,一个画在屏幕上。MFC有固定的模式,可以用屏幕DC来打印,也可以创建和屏幕DC相同的一个打印DC来专门负责打印

//获取打印机设备的横方向和纵方向的分辨率
//即每英寸像素点数
int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
如果pDC是打印机DC,那么xPixPerInch =yPixPerInch =600
如果pDC是屏幕DC,那么xPixPerInch =yPixPerInch =96
所以,这两个DC是不同的

这个是正确的,就使用GetDeviceCaps函数,然后让pDC是打印机DC 就行了

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * Jcily用户头像
    * Jcily
    * (Jcily)
    *
    * 等 级:
    *

    
#9楼 得分:5回复于:2009-10-26 17:25:02
打印时一样最终是调用OnDraw()做输出。

pDC->IsPrinting()可以判断当前是否是打印DC

可以像如下代码

C/C++ code

    if(pDC->IsPrinting()) { // 得到物理宽高(毫米单位) int nWidthMM = pDC->GetDeviceCaps(HORZSIZE); int nHeightMM = pDC->GetDeviceCaps(VERTSIZE); }

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#10楼 得分:0回复于:2009-10-26 17:57:54
引用 9 楼 jcily 的回复:
打印时一样最终是调用OnDraw()做输出。

pDC->IsPrinting()可以判断当前是否是打印DC

可以像如下代码
C/C++ codeif(pDC->IsPrinting())
{// 得到物理宽高(毫米单位)int nWidthMM= pDC->GetDeviceCaps(HORZSIZE);int nHeightMM= pDC->GetDeviceCaps(VERTSIZE);
}

这个我也知道,可是OnDraw里面的DC不是打印DC,后面的两个函数不会被调用

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#11楼 得分:0回复于:2009-10-27 08:31:59
不会没有人知道吧

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#12楼 得分:0回复于:2009-10-27 09:37:16
自己顶!

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * lmxphappy用户头像
    * lmxphappy
    * (lmxphappy)
    *
    * 等 级:
    *

    
#13楼 得分:5回复于:2009-10-27 14:34:47
帮你顶起!

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#14楼 得分:0回复于:2009-10-27 15:40:54
真没人会啊

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#15楼 得分:0回复于:2009-10-28 08:45:42
在线等高手

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * bobob用户头像
    * bobob
    * (静思)
    *
    * 等 级:
    *

    
#16楼 得分:0回复于:2009-10-28 09:16:39
获取纸张大小要么根据纸张类型自己计算,要么用GetDeviceCaps,方法上面都说了,无非就是调用时机的问题。你总不会永远不创建打印机DC吧?你创建打印dc的时候获取这些参数,保存,下次用的时候再拿不就行了吗?这么简单的问题不要在线等高手,真的没人会啊什么的,明眼人一看都知道这个问题的答案已经很清楚了,不屑再费口舌而已

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jennyvenus用户头像
    * jennyvenus
    * (智能卡 Snooper)
    *
    * 等 级:
    *

      3

      5
      更多勋章

    
#17楼 得分:60回复于:2009-10-28 09:28:09

C/C++ code

    声明并设置好一个PAGESETUPDLG结构 PAGESETUPDLG m_psd; PRINTDLG pd; memset(&pd, 0, sizeof(pd)); GetApp()->GetPrinterDeviceDefaults(&pd); m_pi = GetAppSettings()->PrintingGetInfo(); m_pOwner = pOwner; m_bPageSetup = (pOwner == NULL); m_psd.rtMargin = m_pi.m_rectMargin; m_psd.hDevMode = pd.hDevMode; m_psd.hDevNames = pd.hDevNames; m_psd.Flags &= ~(PSD_SHOWHELP | PSD_INTHOUSANDTHSOFINCHES); m_psd.Flags |= PSD_ENABLEPAGESETUPTEMPLATE | PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS | PSD_DEFAULTMINMARGINS; m_psd.hInstance = AfxGetResourceHandle(); m_psd.lpPageSetupTemplateName = MAKEINTRESOURCE(IDD_PRINT_INITIAL); 然后显示打印设置对话框 CPageSetupDialog::OnOK(); // 复制页边距和纸张尺寸。 m_pi.m_sizePaper.cx = m_psd.ptPaperSize.x; m_pi.m_sizePaper.cy = m_psd.ptPaperSize.y; A4纸得到的是21000与29700

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#18楼 得分:0回复于:2009-10-28 12:13:52
好,我试试,谢谢你

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#19楼 得分:0回复于:2009-10-28 12:41:39
引用 16 楼 bobob 的回复:
获取纸张大小要么根据纸张类型自己计算,要么用GetDeviceCaps,方法上面都说了,无非就是调用时机的问题。你总不会永远不创建打印机DC吧?你创建打印dc的时候获取这些参数,保存,下次用的时候再拿不就行了吗?这么简单的问题不要在线等高手,真的没人会啊什么的,明眼人一看都知道这个问题的答案已经很清楚了,不屑再费口舌而已

我现在是要按纸张的比例画地图边框,还没到打印那一步,怎么可能有打印DC呢?难道不用打印DC就不能得到纸张大小吗?我觉得真正的高手肯定知道的

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jyh_baoding用户头像
    * jyh_baoding
    *
    *
    * 等 级:
    *

    
#20楼 得分:5回复于:2009-10-28 12:51:56
帮顶

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#21楼 得分:0回复于:2009-10-28 14:31:37
引用 17 楼 jennyvenus 的回复:
C/C++ code声明并设置好一个PAGESETUPDLG结构
PAGESETUPDLG m_psd;

PRINTDLG pd;
memset(&pd,0,sizeof(pd));
GetApp()->GetPrinterDeviceDefaults(&pd);

m_pi= GetAppSettings()->PrintingGetInfo();
m_pOwner= pOwner;
m_bPageSetup= (pOwner== NULL);
m_psd.rtMargin= m_pi.m_rectMargin;
m_psd.hDevMode= pd.hDevMode;
m_psd.hDevNames= pd.hDevNames;
m_psd.Flags&=~(PSD_SHOWHELP| PSD_INTHOUSANDTHSOFINCHES);
m_psd.Flags|= PSD_ENABLEPAGESETUPTEMPLATE| PSD_INHUNDREDTHSOFMILLIMETERS|
PSD_MARGINS| PSD_DEFAULTMINMARGINS;
m_psd.hInstance= AfxGetResourceHandle();
m_psd.lpPageSetupTemplateName= MAKEINTRESOURCE(IDD_PRINT_INITIAL);


然后显示打印设置对话框
CPageSetupDialog::OnOK();// 复制页边距和纸张尺寸。 m_pi.m_sizePaper.cx= m_psd.ptPaperSize.x;
m_pi.m_sizePaper.cy= m_psd.ptPaperSize.y;

A4纸得到的是21000与29700
请问m_pi是什么数据类型?

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jennyvenus用户头像
    * jennyvenus
    * (智能卡 Snooper)
    *
    * 等 级:
    *

      3

      5
      更多勋章

    
#22楼 得分:0回复于:2009-10-28 17:57:34

C/C++ code

    #pragma once #include "MyEditMisc.h" / // CDlgPrint class CDlgPrint : public CPageSetupDialog { DECLARE_DYNAMIC(CDlgPrint) public: CDlgPrint(CMyEditView* pOwner); virtual ~CDlgPrint(); // 对话框数据 enum { IDD = IDD_PRINT_INITIAL }; public: CMyEditPrintInfo m_pi; CMyEditView* m_pOwner; BOOL m_bPageSetup; protected: void UpdateDataSet(); BOOL UpdateDataGet(); protected: virtual BOOL OnInitDialog(); virtual void OnOK(); virtual void OnCancel(); protected: afx_msg void OnSetHeaderFooterText(); DECLARE_MESSAGE_MAP() };



    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jennyvenus用户头像
    * jennyvenus
    * (智能卡 Snooper)
    *
    * 等 级:
    *

      3

      5
      更多勋章

    
#23楼 得分:0回复于:2009-10-28 17:58:29

C/C++ code

    // DlgPrint.cpp : 实现文件 // #include "stdafx.h" #include <winspool.h> #include <dlgs.h> #include "App.h" #include "AppGlobals.h" #include "AppSettings.h" #include "AppFrame.h" #include "DlgBase.h" #include "DlgPrint.h" / // 本来在RC资源文件中的打印对话框使用了<dlgs.h>中定义的控件标识,但VC的资源编 // 辑器把这些控件标识换成了常数。 #define IDC_PRINT_BTN_SET_PRINTER psh3 #define NUM_PRINTING_MIN_PRINT_PAGES_RANGE 1 #define NUM_PRINTING_MAX_PRINT_PAGES_RANGE USHRT_MAX / // CDlgPrint IMPLEMENT_DYNAMIC(CDlgPrint, CPageSetupDialog) BEGIN_MESSAGE_MAP(CDlgPrint, CPageSetupDialog) ON_BN_CLICKED(IDC_PRINT_BTN_SET_HEADER_TEXT, OnSetHeaderFooterText) ON_BN_CLICKED(IDC_PRINT_BTN_SET_FOOTER_TEXT, OnSetHeaderFooterText) END_MESSAGE_MAP() CDlgPrint::CDlgPrint(CMyEditView* pOwner) : CPageSetupDialog(0, pOwner) { PRINTDLG pd; memset(&pd, 0, sizeof(pd)); GetApp()->GetPrinterDeviceDefaults(&pd); m_pi = GetAppSettings()->PrintingGetInfo(); m_pOwner = pOwner; m_bPageSetup = (pOwner == NULL); m_psd.rtMargin = m_pi.m_rectMargin; m_psd.hDevMode = pd.hDevMode; m_psd.hDevNames = pd.hDevNames; m_psd.Flags &= ~(PSD_SHOWHELP | PSD_INTHOUSANDTHSOFINCHES); m_psd.Flags |= PSD_ENABLEPAGESETUPTEMPLATE | PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS | PSD_DEFAULTMINMARGINS; m_psd.hInstance = AfxGetResourceHandle(); m_psd.lpPageSetupTemplateName = MAKEINTRESOURCE(IDD_PRINT_INITIAL); } CDlgPrint::~CDlgPrint() { } / // CDlgPrint 消息处理程序 BOOL CDlgPrint::OnInitDialog() { CPageSetupDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 CDlgBase::DlgEnableItem(this, IDC_PRINT_EDT_SCALE, false); CDlgBase::DlgEnableItem(this, IDC_PRINT_SPN_SCALE, false); UpdateDataSet(); return true; // return true unless you set the focus to a control // 异常: OCX 属性页应返回 false } void CDlgPrint::OnOK() { // TODO: 在此添加专用代码和/或调用基类 if (!UpdateDataGet()) { return; } CPageSetupDialog::OnOK(); // 复制页边距和纸张尺寸。 m_pi.m_sizePaper.cx = m_psd.ptPaperSize.x; m_pi.m_sizePaper.cy = m_psd.ptPaperSize.y; m_pi.m_rectMargin.CopyRect(&m_psd.rtMargin); // 计算最小的页边距。 CDC dcPrint; if (dcPrint.Attach(CreatePrinterDC())) { CSize sizeLUsPI; // Logic Unit Per Inch sizeLUsPI.cx = dcPrint.GetDeviceCaps(LOGPIXELSX); sizeLUsPI.cy = dcPrint.GetDeviceCaps(LOGPIXELSY); CSize sizePaper; // 纸张尺寸。 sizePaper.cx = dcPrint.GetDeviceCaps(PHYSICALWIDTH); sizePaper.cy = dcPrint.GetDeviceCaps(PHYSICALHEIGHT); dcPrint.DPtoLP(&sizePaper); CSize sizePrint; // 可打印范围。 sizePrint.cx = dcPrint.GetDeviceCaps(HORZRES); sizePrint.cy = dcPrint.GetDeviceCaps(VERTRES); dcPrint.DPtoLP(&sizePrint); CSize sizeOfsLT; // 左边和上边,逻辑单位。 sizeOfsLT.cx = dcPrint.GetDeviceCaps(PHYSICALOFFSETX); sizeOfsLT.cy = dcPrint.GetDeviceCaps(PHYSICALOFFSETY); dcPrint.DPtoLP(&sizeOfsLT); CSize sizeOfsRB; // 右边和下边,逻辑单位。 sizeOfsRB.cx = sizePaper.cx - sizeOfsLT.cx - sizePrint.cx; sizeOfsRB.cy = sizePaper.cy - sizeOfsLT.cy - sizePrint.cy; CSize sizeLT_MM; // 转换成1/100MM单位。 sizeLT_MM.cx = (LONG)((FLOAT)sizeOfsLT.cx * 2540 / sizeLUsPI.cx); sizeLT_MM.cy = (LONG)((FLOAT)sizeOfsLT.cy * 2540 / sizeLUsPI.cy); CSize sizeRB_MM; // 转换成1/100MM单位。 sizeRB_MM.cx = (LONG)((FLOAT)sizeOfsRB.cx * 2540 / sizeLUsPI.cx); sizeRB_MM.cy = (LONG)((FLOAT)sizeOfsRB.cy * 2540 / sizeLUsPI.cy); CRect& rect = m_pi.m_rectMargin; rect.left = max(sizeLT_MM.cx, rect.left); rect.top = max(sizeLT_MM.cy, rect.top); rect.right = max(sizeRB_MM.cx, rect.right); rect.bottom = max(sizeRB_MM.cy, rect.bottom); dcPrint.DeleteDC(); } // 保存打印设置。 GetAppSettings()->PrintingSetInfo(m_pi); // 如果要求启动打印,现在就执行。 if ((m_pOwner != NULL) && (::IsWindow(m_pOwner->GetSafeHwnd()))) { m_pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(ID_FILE_PRINT, 0), 0); } }



都是网上的代码,多搜搜就搞定了。

    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * jennyvenus用户头像
    * jennyvenus
    * (智能卡 Snooper)
    *
    * 等 级:
    *

      3

      5
      更多勋章

    
#24楼 得分:0回复于:2009-10-28 17:58:46

C/C++ code

    void CDlgPrint::OnCancel() { // TODO: 在此添加专用代码和/或调用基类 CPageSetupDialog::OnCancel(); } / void CDlgPrint::OnSetHeaderFooterText() { // TODO: 在此添加控件通知处理程序代码 struct CMacroMap { UINT nID; LPCTSTR pszMacro; }; static const CMacroMap l_macro_map[] = { {ID_PRINT_MACRO_DATE, PFX_EC_PRINT_MACRO_DATE}, {ID_PRINT_MACRO_TIME, PFX_EC_PRINT_MACRO_TIME}, {ID_PRINT_MACRO_CURRENT_PAGE, PFX_EC_PRINT_MACRO_CURRENT_PAGE}, {ID_PRINT_MACRO_TOTAL_PAGES, PFX_EC_PRINT_MACRO_TOTAL_PAGES}, {ID_PRINT_MACRO_FILE_NAME, PFX_EC_PRINT_MACRO_FILE_NAME}, {ID_PRINT_MACRO_PATH_NAME, PFX_EC_PRINT_MACRO_PATH_NAME}, {ID_PRINT_MACRO_TAB, PFX_EC_PRINT_MACRO_TAB}, {ID_PRINT_MACRO_CRLF, PFX_EC_PRINT_MACRO_CRLF}, {ID_PRINT_MACRO_ALIGN_LEFT, PFX_EC_PRINT_MACRO_ALIGN_LEFT}, {ID_PRINT_MACRO_ALIGN_CENTER, PFX_EC_PRINT_MACRO_ALIGN_CENTER}, {ID_PRINT_MACRO_ALIGN_RIGHT, PFX_EC_PRINT_MACRO_ALIGN_RIGHT}, }; int nIDEdt; int nIDBtn; switch (GetAppFrame()->GetCurrentCommand()) { default: return; case IDC_PRINT_BTN_SET_HEADER_TEXT: nIDBtn = IDC_PRINT_BTN_SET_HEADER_TEXT; nIDEdt = IDC_PRINT_EDT_HEADER; break; case IDC_PRINT_BTN_SET_FOOTER_TEXT: nIDBtn = IDC_PRINT_BTN_SET_FOOTER_TEXT; nIDEdt = IDC_PRINT_EDT_FOOTER; break; } // 获取菜单的坐标。 CRect rect; GetDlgItem(nIDBtn)->GetWindowRect(&rect); CMenu Menu; VERIFY(Menu.LoadMenu(IDR_POPUP_PRINT_MACRO)); CPoint point(rect.left, rect.bottom); UINT nIDCmd = GetAppFrame()->CreateShortcutMenu(this, Menu.GetSubMenu(0), point); if (nIDCmd != 0) // nIDCmd等于零表示菜单被取消。 { LPCTSTR pszMacro = NULL; for (int i = 0; i < SIZEOF(l_macro_map); i++) { if (nIDCmd == l_macro_map[i].nID) { pszMacro = l_macro_map[i].pszMacro; break; } } if (pszMacro != NULL) { CWnd* pWndEdt = GetDlgItem(nIDEdt); ASSERT(pWndEdt != NULL); CEdit Edit; Edit.Attach(pWndEdt->GetSafeHwnd()); // 插入打印参数。 Edit.ReplaceSel(pszMacro, true); // 设置输入焦点。 Edit.SetFocus(); Edit.Detach(); } } } / void CDlgPrint::UpdateDataSet() { // 标题脚注。 SetDlgItemText(IDC_PRINT_EDT_HEADER, m_pi.m_strHeader); SetDlgItemText(IDC_PRINT_EDT_FOOTER, m_pi.m_strFooter); // 页码范围,开始页等于零,结束页留空表示全部打印。 if (!m_bPageSetup) { SetDlgItemInt(IDC_PRINT_EDT_PAGE_FROM, 1, false); SetDlgItemText(IDC_PRINT_EDT_PAGE_TO, _T("")); } else { CDlgBase::DlgEnableItem(this, IDC_PRINT_EDT_PAGE_FROM, false); CDlgBase::DlgEnableItem(this, IDC_PRINT_EDT_PAGE_TO, false); } } BOOL CDlgPrint::UpdateDataGet() { CMyEditPrintInfo pi; // 页码范围(从第几页到第几页)。 pi.m_nPageFrom = NUM_PRINTING_MIN_PRINT_PAGES_RANGE; pi.m_nPageTo = NUM_PRINTING_MAX_PRINT_PAGES_RANGE; if (!m_bPageSetup) // 页面设置不需要获取打印范围。 { if (!CDlgBase::DlgGetItemUINT(this, IDC_PRINT_EDT_PAGE_FROM, IDS_E_PRINT_INVALID_PAGES_RANGE, pi.m_nPageFrom, NUM_PRINTING_MIN_PRINT_PAGES_RANGE, NUM_PRINTING_MAX_PRINT_PAGES_RANGE)) { return false; } // 如果打印结束页的输入框留空或输入了空白字符,就表明用户想 // 从打印开始页打印到文档的最后一页。 CString strToPageText; GetDlgItemText(IDC_PRINT_EDT_PAGE_TO, strToPageText); strToPageText.TrimLeft(); strToPageText.TrimRight(); if (!strToPageText.IsEmpty() && !CDlgBase::DlgGetItemUINT(this, IDC_PRINT_EDT_PAGE_TO, IDS_E_PRINT_INVALID_PAGES_RANGE, pi.m_nPageTo, NUM_PRINTING_MIN_PRINT_PAGES_RANGE, NUM_PRINTING_MAX_PRINT_PAGES_RANGE)) { return false; } if (pi.m_nPageFrom > pi.m_nPageTo) { appAlert2(IDS_E_PRINT_INVALID_PAGES_SEQUENCE_NUMBER, MB_OK | MB_ICONEXCLAMATION, pi.m_nPageFrom, pi.m_nPageTo); return false; } } // 标题和脚注。 GetDlgItemText(IDC_PRINT_EDT_HEADER, pi.m_strHeader); GetDlgItemText(IDC_PRINT_EDT_FOOTER, pi.m_strFooter); m_pi = pi; // 复制所有正确的数据。 return true; }


    * 对我有用[0]
    * 丢个板砖[0]
    * 引用
    * 举报
    * 管理
    * TOP

    * liumenghappy用户头像
    * liumenghappy
    * (小胖)
    *
    * 等 级:
    *

    
#25楼 得分:0回复于:2009-10-29 10:30:00
引用 23 楼 jennyvenus 的回复:
C/C++ code// DlgPrint.cpp : 实现文件//
#include"stdafx.h"
#include<winspool.h>
#include<dlgs.h>
#include"App.h"
#include"AppGlobals.h"
#include"AppSettings.h"
#include"AppFrame.h"
#include"DlgBase.h"
#include"DlgPrint.h"/// 本来在RC资源文件中的打印对话框使用了<dlgs.h>中定义的控件标识,但VC的资源编// 辑器把这些控件标识换成了常数。#define IDC_PRINT_BTN_SET_PRINTER psh3#define NUM_PRINTING_MIN_PRINT_PAGES_RANGE 1#define NUM_PRINTING_MAX_PRINT_PAGES_RANGE USHRT_MAX/// CDlgPrintIMPLEMENT_DYNAMIC(CDlgPrint, CPageSetupDialog)
BEGIN_MESSAGE_MAP(CDlgPrint, CPageSetupDialog)
ON_BN_CLICKED(IDC_PRINT_BTN_SET_HEADER_TEXT, OnSetHeaderFooterText)
ON_BN_CLICKED(IDC_PRINT_BTN_SET_FOOTER_TEXT, OnSetHeaderFooterText)
END_MESSAGE_MAP()

CDlgPrint::CDlgPrint(CMyEditView* pOwner) : CPageSetupDialog(0, pOwner)
{
PRINTDLG pd;
memset(&pd,0,sizeof(pd));
GetApp()->GetPrinterDeviceDefaults(&pd);

m_pi= GetAppSettings()->PrintingGetInfo();
m_pOwner= pOwner;
m_bPageSetup= (pOwner== NULL);
m_psd.rtMargin= m_pi.m_rectMargin;
m_psd.hDevMode= pd.hDevMode;
m_psd.hDevNames= pd.hDevNames;
m_psd.Flags&=~(PSD_SHOWHELP| PSD_INTHOUSANDTHSOFINCHES);
m_psd.Flags|= PSD_ENABLEPAGESETUPTEMPLATE| PSD_INHUNDREDTHSOFMILLIMETERS|
PSD_MARGINS| PSD_DEFAULTMINMARGINS;
m_psd.hInstance= AfxGetResourceHandle();
m_psd.lpPageSetupTemplateName= MAKEINTRESOURCE(IDD_PRINT_INITIAL);
}

CDlgPrint::~CDlgPrint()
{
}/// CDlgPrint 消息处理程序BOOL CDlgPrint::OnInitDialog()
{
CPageSetupDialog::OnInitDialog();// TODO: 在此添加额外的初始化 CDlgBase::DlgEnableItem(this, IDC_PRINT_EDT_SCALE,false);
CDlgBase::DlgEnableItem(this, IDC_PRINT_SPN_SCALE,false);

UpdateDataSet();returntrue;// return true unless you set the focus to a control// 异常: OCX 属性页应返回 false}void CDlgPrint::OnOK()
{// TODO: 在此添加专用代码和/或调用基类if (!UpdateDataGet())
{return;
}

CPageSetupDialog::OnOK();// 复制页边距和纸张尺寸。 m_pi.m_sizePaper.cx= m_psd.ptPaperSize.x;
m_pi.m_sizePaper.cy= m_psd.ptPaperSize.y;
m_pi.m_rectMargin.CopyRect(&m_psd.rtMargin);// 计算最小的页边距。 CDC dcPrint;if (dcPrint.Attach(CreatePrinterDC()))
{
CSize sizeLUsPI;// Logic Unit Per Inch sizeLUsPI.cx= dcPrint.GetDeviceCaps(LOGPIXELSX);
sizeLUsPI.cy= dcPrint.GetDeviceCaps(LOGPIXELSY);

CSize sizePaper;// 纸张尺寸。 sizePaper.cx= dcPrint.GetDeviceCaps(PHYSICALWIDTH);
sizePaper.cy= dcPrint.GetDeviceCaps(PHYSICALHEIGHT);
dcPrint.DPtoLP(&sizePaper);

CSize sizePrint;// 可打印范围。 sizePrint.cx= dcPrint.GetDeviceCaps(HORZRES);
sizePrint.cy= dcPrint.GetDeviceCaps(VERTRES);
dcPrint.DPtoLP(&sizePrint);

CSize sizeOfsLT;// 左边和上边,逻辑单位。 sizeOfsLT.cx= dcPrint.GetDeviceCaps(PHYSICALOFFSETX);
sizeOfsLT.cy= dcPrint.GetDeviceCaps(PHYSICALOFFSETY);
dcPrint.DPtoLP(&sizeOfsLT);

CSize sizeOfsRB;// 右边和下边,逻辑单位。 sizeOfsRB.cx= sizePaper.cx- sizeOfsLT.cx- sizePrint.cx;
sizeOfsRB.cy= sizePaper.cy- sizeOfsLT.cy- sizePrint.cy;

CSize sizeLT_MM;// 转换成1/100MM单位。 sizeLT_MM.cx= (LONG)((FLOAT)sizeOfsLT.cx*2540/ sizeLUsPI.cx);
sizeLT_MM.cy= (LONG)((FLOAT)sizeOfsLT.cy*2540/ sizeLUsPI.cy);

CSize sizeRB_MM;// 转换成1/100MM单位。 sizeRB_MM.cx= (LONG)((FLOAT)sizeOfsRB.cx*2540/ sizeLUsPI.cx);
sizeRB_MM.cy= (LONG)((FLOAT)sizeOfsRB.cy*2540/ sizeLUsPI.cy);

CRect& rect= m_pi.m_rectMargin;
rect.left= max(sizeLT_MM.cx, rect.left);
rect.top= max(sizeLT_MM.cy, rect.top);
rect.right= max(sizeRB_MM.cx, rect.right);
rect.bottom= max(sizeRB_MM.cy, rect.bottom);

dcPrint.DeleteDC();
}// 保存打印设置。 GetAppSettings()->PrintingSetInfo(m_pi);// 如果要求启动打印,现在就执行。if ((m_pOwner!= NULL)&& (::IsWindow(m_pOwner->GetSafeHwnd())))
{
m_pOwner->SendMessage(WM_COMMAND,
MAKEWPARAM(ID_FILE_PRINT,0),0);
}
}

都是网上的代码,多搜搜就搞定了。

十分感谢

转载于:https://www.cnblogs.com/cwbo-win/articles/3380196.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值