青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

穩定盈利的期貨交易方法-量化趨勢交易

alantop -專業量化投資者

愛好:量化投資,逆向工程,滲透
隨筆 - 595, 文章 - 0, 評論 - 921, 引用 - 0
數據加載中……

如何在MFC中打印CFormView?

MFC的打印是如何工作的?

Before we go further, we need to learn how OnPrintPreview and OnPrint work in MFC. Here is the scratch of the code.

  1. Calls OnPreparePrint to prompt dialog to setup actual printer and number of pages. Usually we will let MFC do the work for us here. But if you want to skip the dialog and setup printer DC directly, you’d better do it here or totally rewrite OnPrint/OnPrintPreview.
  2. Calls OnBeginPrint. If we can decide how many page we need to print, it is better to set the number of pages here if possible.
  3. Print each page in a loop.
    • In the loop, Calls OnPrepareDC. If you need to setup map mode and conversion ratio between logical pixel and physical pixel, such as like one inch in screen equals one inch in printer, you'd better do it here. One important thing to bear in mind is that if you can’t decide how many pages you need to print on step 2, you can still use CPrintInfo::m_bContinuePrinting member variable to terminate printing.
    • Calls OnPrint to do actually printing

打印CFormView有兩種方法:
1.Capturing screen image of CFormView.

Like injecting any code into a framework, first you need to know where to add your code. Such type of question is always the toughest one when programming in MFC. In this case, the question is when to grab the image. How about doing it in OnBeginPrint? Not bad idea at first glance. Well, it turns out there is catch here. As MFC prompts a window to emulate Printer DC in preview mode, you could end up capturing wrong image in this mode. It is better to do it in OnFilePrint and OnFilePrintPreview. The actual code looks like this:

void?CFormViewPrintView::_grapImage(?)?
{
????
//Grap?Image
????CPoint?oldPoint?=?GetScrollPosition(?);
????
//scroll?to?top?left?corner?as?CFormView?is?a?Scroll?view
????CPoint?pt(?0,?0?);
????
this->ScrollToPosition(?pt?);

????CClientDC?dc(
this);
????CRect?rect;
????
this->GetClientRect(?rect?);
????m_dib.Attach(?GDIUtil::GrabDIB(?
&dc,?rect?)?);

????ScrollToPosition(?oldPoint?);
}

void?CFormViewPrintView::OnFilePrintPreview()?
{
????
//?TODO:?Add?your?command?handler?code?here
????_grapImage(?);
????CFormView::OnFilePrintPreview()?;
}

void?CFormViewPrintView::OnFilePrint()?
{
????_grapImage(?);
????CFormView::OnFilePrint()?;
}

Hmm, what does the GDIUtil::GradDIB do? It grabs Bitmap from the screen and converts it to DIB. Why DIB, not Bitmap directly? A bitmap always depends on DC and screen DC is different than Printer DC. Without such conversion, we are under the mercy of Printer Driver. It may work fine in some printer, but badly on the other. Seen Roger Allen’s article on this.

Next, we need to deal with how to preserve something the same size as displayed on screen. Ever wondered why something turns terribly small when printing? Here is the reason, let’s say the resolution in printer is 600 pixel per inch, while we usually have 96 or 120 pixel per inch in the screen. If you simply print something “the same size” in pixel, it is not hard to imagine what will happen. That is also the reason why you should change font size when printing text. What we really want, is to print something the same size in inch, not pixel. “Point taken, but where to put the code of such conversion?” You ask yourself and realize this is the same old “where” question again. This can be done by overriding the method OnPrepareDC. What Microsoft really means by the name is “Setup map mode here if needed”. This is also the place to decide whether to terminate printing or not, if you haven’t figured out the number of printing pages previously. Our OnPrepareDC looks like this.

void?CFormViewPrintView::OnPrepareDC(CDC*?pDC,?
??????????????????????CPrintInfo
*?pInfo?/*?=?NULL?*/)
{
????
//?TODO:?Add?your?specialized?code?here?and/or?call?the?base?class
????if(?pInfo?)
????{
????????CClientDC?dc(?
this?);
????????pDC
->SetMapMode(MM_ANISOTROPIC);

????????CSize?sz(?dc.GetDeviceCaps(LOGPIXELSX),?
????????????????????dc.GetDeviceCaps(LOGPIXELSY)?);
????????pDC
->SetWindowExt(?sz?);
????????sz?
=?CSize(?pDC->GetDeviceCaps(LOGPIXELSX),
????????????????????????pDC
->GetDeviceCaps(LOGPIXELSY)?);
????????pDC
->SetViewportExt(?sz?);
????}
}

What does this code mean? It means one inch in screen, dc in this case, equals one inch in printer (could be pseudo one) and we don’t care about actual pixel size varies, say 120 ppi in screen vs 600 ppi in printer.

Last, the actual printing.

void?CFormViewPrintView::OnPrint(CDC*?pDC,?CPrintInfo*?pInfo)
{
????
//?TODO:?add?customized?printing?code?here
????if(?pInfo?==?NULL?)
????????
return;

????
if(?m_dib.GetHandle(?)?==?NULL?)
????????
return;
????{
????????
//Call?GlobalLock?in?constructor,?call?Unlock?when?exists?the?block
????????GLock?lock(?m_dib?);
????????BITMAPINFOHEADER?
*pBMI?=?(BITMAPINFOHEADER*)(LPVOID)lock;

????????
int?nColors?=?0;
????????
if(?pBMI->biBitCount?<=?8?)
????????????nColors?
=?(?1<<?pBMI->biBitCount?);

????????::StretchDIBits(?pDC
->GetSafeHdc(?),
????????pInfo
->m_rectDraw.left,?
????????pInfo
->m_rectDraw.top,
????????pBMI
->biWidth,
????????pBMI
->biHeight,
????????????????
0,?
????????????????
0,?
????????????????pBMI
->biWidth,
????????????????pBMI
->biHeight,
????????????????(LPBYTE)pBMI?
+?(pBMI->biSize?+?nColors?*?sizeof(RGBQUAD)),
????????????????(BITMAPINFO
*)pBMI,
????????????????DIB_RGB_COLORS,?
????????????????SRCCOPY);
????}
}

One thing to mention is that GLock in GUtil follows the same idea as AutoPtr in STD. I have no idea why Microsoft does right thing in CClientDC and CPaintDC, while turning blind when dealing something like GlobalLock/Unlock or the notorious SelectObject. How many times have we scratched our head to detect GDI object resource leak, only finding out that we select something in, but forget to select it out.

2.Another way WM_PRINT message
Ever heard of WM_PRINT message? It is not even in Visual C++ class wizard, but it seems promising everything we need for printing CFormView. Here is another way to print CFormView:

void?CFormViewPrint2View::_print(?)
{
????CRect?rect;
????
this->GetClientRect(?rect?);
????CDC?memDC;

????CClientDC?dc(?
this?);
????memDC.CreateCompatibleDC(?
&dc?);

????CBitmap?bitmap;
????bitmap.CreateCompatibleBitmap(?
&dc,?rect.Width(),?rect.Height()?);
????{
????????
//This?will?force?bitmap?selected?out?of?DC?when?exit?this?block
????????LocalGDI?local(?&memDC,?&bitmap?);
????????
this->Print(?&memDC,?PRF_ERASEBKGND|PRF_CLIENT|PRF_CHILDREN?);
????}
????m_dib.Attach(?GDIUtil::DDBToDIB(?bitmap?)?);
}

void?CFormViewPrint2View::OnFilePrintPreview()?
{
????
//?TODO:?Add?your?command?handler?code?here
????_print(?);
????CFormView::OnFilePrintPreview(?);
}

void?CFormViewPrint2View::OnFilePrint()?
{
????
//?TODO:?Add?your?command?handler?code?here
????_print(?);
????CFormView::OnFilePrint(?);
}


?

結論:

So, what is the strength and weakness of each method? The first one doesn’t care about how many individual child controls you have and how to print each of them on Printer, but it can only print visual part of the screen. While second one seems much better and cleaner than the first one, it even allows you to print all client area without displaying them on the screen. Unfortunately, there is a catch for it too. Some sub-classed Windows controls and user custom controls may forget to process WM_PRINT message at all, which is amazingly easy to implement if you can process WM_PAINT message.

posted on 2006-05-23 15:11 AlanTop 閱讀(1399) 評論(1)  編輯 收藏 引用 所屬分類: C++

評論

# re: 如何在MFC中打印CFormView?  回復  更多評論   

第二種方法打印出來的視圖就是空的,為什么我在上面畫的圖形都看不到呢?
2006-05-23 16:45 | byli
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久免费观看| 国产精品成人在线| 亚洲欧洲视频在线| 欧美r片在线| 亚洲国产成人不卡| 亚洲国产欧美一区二区三区同亚洲| 亚洲电影第三页| 亚洲精品专区| 亚洲欧美日韩一区二区| 欧美一级免费视频| 麻豆久久久9性大片| 欧美激情一区二区三区在线视频| 欧美日本二区| 国产亚洲va综合人人澡精品| 伊人久久大香线| 亚洲精品免费一二三区| 亚洲永久在线观看| 免费观看久久久4p| 亚洲图片你懂的| 久久亚洲综合| 国产精品久久久久毛片大屁完整版 | 亚洲午夜精品久久久久久app| 亚洲永久免费| 久久综合导航| 国产精品jizz在线观看美国| 韩日成人在线| 亚洲永久免费| 亚洲成色精品| 午夜精品一区二区三区在线播放| 蜜臀99久久精品久久久久久软件| 国产精品成人一区二区三区吃奶| 激情欧美一区二区三区| 中文久久精品| 亚洲第一黄色网| 性8sex亚洲区入口| 国产精品超碰97尤物18| 亚洲欧洲一区二区天堂久久| 久久成人亚洲| 亚洲在线成人精品| 欧美日韩精品不卡| 亚洲国产第一页| 欧美在线短视频| 99国产精品久久久久久久久久| 久久国产日韩| 国产亚洲综合精品| 久久av红桃一区二区小说| 日韩亚洲不卡在线| 欧美理论在线播放| 日韩视频一区| 亚洲激情综合| 欧美成人在线网站| 亚洲国产成人av在线| 久久男人资源视频| 欧美一区精品| 国产一区亚洲| 久久精品一本久久99精品| 亚洲一区久久| 国产一区二区三区观看| 久久精品视频在线看| 午夜视频在线观看一区二区三区| 国产精品露脸自拍| 欧美在线视频一区| 久久国产精品一区二区三区四区| 国产一区二区福利| 久久艳片www.17c.com| 久久精品中文字幕一区| 在线观看亚洲精品| 亚洲电影免费观看高清| 欧美精品啪啪| 亚洲自拍16p| 性欧美xxxx视频在线观看| 国产一区二区精品久久| 老牛嫩草一区二区三区日本| 久久免费99精品久久久久久| 亚洲国产精品成人久久综合一区| 欧美成人中文字幕| 欧美激情一区二区| 亚洲一级网站| 91久久精品美女高潮| 欧美一区二区精品久久911| 欧美精品一区在线发布| 一本色道精品久久一区二区三区| 99视频有精品| 国产一区视频在线看| 欧美国产日韩精品| 国产精品久久福利| 女人色偷偷aa久久天堂| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲免费黄色| 亚洲欧美日本国产专区一区| 在线播放日韩| 国产精品99久久久久久宅男 | 影院欧美亚洲| 亚洲经典自拍| 国产视频一区在线| 亚洲国产精品久久精品怡红院| 欧美日韩视频一区二区| 久久久久综合一区二区三区| 欧美精品1区2区3区| 欧美在线观看天堂一区二区三区| 欧美va亚洲va日韩∨a综合色| 亚洲午夜精品在线| 美国三级日本三级久久99| 午夜精品久久久久久久男人的天堂 | 狠狠色丁香婷综合久久| 亚洲激情电影中文字幕| 国产三级精品三级| 夜夜嗨av一区二区三区 | 久久精品国产69国产精品亚洲 | 91久久亚洲| 狠狠色香婷婷久久亚洲精品| 日韩亚洲视频| 亚洲国产高清aⅴ视频| 亚洲欧美电影院| 艳妇臀荡乳欲伦亚洲一区| 久久国产免费| 久久精品首页| 国产精品自在线| 亚洲视频国产视频| 一区二区三区高清不卡| 麻豆成人综合网| 久久久夜精品| 好吊成人免视频| 欧美一二区视频| 久久精品一区二区国产| 国产精品伊人日日| 亚洲一级黄色片| 亚洲四色影视在线观看| 欧美人与性动交cc0o| 亚洲精品久久久久| 在线亚洲一区观看| 欧美涩涩网站| 亚洲永久字幕| 久久99在线观看| 久久香蕉精品| 亚洲欧美综合精品久久成人| 亚洲视频视频在线| 欧美欧美全黄| 日韩午夜视频在线观看| 一区二区三区欧美| 欧美色网在线| 亚洲已满18点击进入久久 | 美女网站久久| 亚洲国产99精品国自产| 欧美va亚洲va国产综合| 亚洲人体大胆视频| 亚洲伦理在线| 国产精品v日韩精品| 亚洲综合色网站| 久久综合久久综合久久综合| 亚洲福利视频免费观看| 久热精品在线视频| 亚洲精品久久7777| 性欧美大战久久久久久久免费观看| 国产精品日韩二区| 欧美在线观看你懂的| 免费在线国产精品| 亚洲国产精品99久久久久久久久| 欧美激情欧美激情在线五月| 99精品国产高清一区二区| 午夜精品在线看| 一区二区三区在线视频免费观看 | 欧美精品1区2区3区| 一区二区三区高清不卡| 久久本道综合色狠狠五月| 亚洲电影自拍| 国产精品伦理| 久久综合久久综合这里只有精品| 亚洲国产欧美一区二区三区久久| 亚洲一区二区在| 伊人精品视频| 国产精品一区二区黑丝| 麻豆精品在线视频| 午夜精品美女自拍福到在线| 欧美成人亚洲成人| 先锋影音久久久| 日韩亚洲精品电影| 精品二区视频| 国产农村妇女毛片精品久久麻豆 | 伊人男人综合视频网| 欧美日韩不卡视频| 久久国内精品自在自线400部| 亚洲欧洲一区二区天堂久久| 久久精品视频在线| 亚洲综合精品自拍| 亚洲精品一区二区三区福利| 国产色爱av资源综合区| 欧美激情一区二区三区全黄 | 久久成人国产| 一级日韩一区在线观看| 亚洲第一页中文字幕| 国产日韩欧美视频在线| 欧美色图首页| 欧美欧美在线| 免费成人激情视频| 久久综合中文| 欧美在线视频一区二区| 亚洲一区二区三区三| 99国产麻豆精品| 日韩午夜在线视频|