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

穩(wěn)定盈利的期貨交易方法-量化趨勢交易

alantop -專業(yè)量化投資者

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

如何在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(?);
}


?

結(jié)論:

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?  回復(fù)  更多評論   

第二種方法打印出來的視圖就是空的,為什么我在上面畫的圖形都看不到呢?
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>
            午夜一区二区三视频在线观看| 久久精品亚洲精品国产欧美kt∨| 久久久综合精品| 在线不卡欧美| 欧美视频一区| 国产精品久久久久久妇女6080 | 美女图片一区二区| 久久久蜜桃一区二区人| 久久综合久久综合这里只有精品| 麻豆精品91| 欧美日韩视频在线一区二区观看视频| 欧美日韩国产系列| 国产精品久久久久久福利一牛影视| 国产麻豆视频精品| 伊人久久大香线蕉av超碰演员| 伊人蜜桃色噜噜激情综合| 99精品国产一区二区青青牛奶| 一区二区三区欧美成人| 欧美在线视频不卡| 亚洲人成在线播放网站岛国| 亚洲国产一区二区三区在线播 | 久久精品日产第一区二区| 久久婷婷国产综合国色天香| 亚洲高清在线| 性欧美18~19sex高清播放| 久久久久久网| 国产精品乱码人人做人人爱| 国内精品久久久久久久果冻传媒| 亚洲伦理一区| 久久天堂精品| 亚洲欧美日韩网| 欧美日韩xxxxx| 今天的高清视频免费播放成人| 亚洲精品中文字幕有码专区| 久久爱91午夜羞羞| 日韩一区二区精品| 欧美成人按摩| 韩国亚洲精品| 香蕉成人啪国产精品视频综合网| 亚洲二区视频| 久久国产精品久久精品国产| 欧美日韩亚洲国产一区| 亚洲激情视频在线| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲在线视频网站| 欧美日韩另类字幕中文| 亚洲黄网站黄| 欧美成人精精品一区二区频| 久久国内精品视频| 国产一区二区三区久久精品| 亚洲欧美在线播放| 99精品热视频| 国产亚洲午夜| 一本色道婷婷久久欧美| 久久国产精品色婷婷| 夜夜嗨av一区二区三区网页| 久久综合给合| 亚洲丰满少妇videoshd| 久久婷婷亚洲| 久久国产精品久久w女人spa| 国产欧美一区在线| 久久国产免费看| 性欧美video另类hd性玩具| 国产精品毛片大码女人| 香港成人在线视频| 亚洲欧美日韩精品久久| 国产精品人成在线观看免费| 亚洲女ⅴideoshd黑人| 亚洲一区二区三| 国产精品久久久久久久久| 欧美亚洲日本网站| 香港成人在线视频| 在线观看久久av| 亚洲第一页自拍| 欧美久久综合| 亚洲欧美一区二区三区久久| 亚洲欧美日产图| 影音先锋久久久| 亚洲激情在线| 国产精品日日摸夜夜添夜夜av| 久久国产精品72免费观看| 欧美在线免费观看| 亚洲精品日产精品乱码不卡| 亚洲作爱视频| 国一区二区在线观看| 亚洲国产精品成人久久综合一区| 欧美日韩国产bt| 久久av老司机精品网站导航| 久久aⅴ国产欧美74aaa| 日韩亚洲一区二区| 亚洲一级黄色av| 国产在线麻豆精品观看| 欧美激情第4页| 国产精品久久久久久久免费软件| 久久精品视频免费观看| 欧美a级片网站| 欧美在线观看视频一区二区三区| 久久亚洲电影| 午夜精品久久久久久久99黑人| 久久久99爱| 亚洲调教视频在线观看| 久久精品国产亚洲aⅴ| 亚洲私拍自拍| 蜜臀久久99精品久久久久久9| 亚洲午夜女主播在线直播| 久久精品二区| 亚洲欧美日韩区| 欧美高清视频一二三区| 久久精品国产精品亚洲| 欧美日韩伊人| 亚洲第一网站| 国产三级欧美三级| 99re66热这里只有精品3直播| 在线观看中文字幕亚洲| 一区二区三欧美| 一区二区欧美亚洲| 亚洲电影网站| 欧美成人自拍视频| 国产专区一区| 亚洲欧美日本伦理| 亚洲一区二区三区777| 欧美a级理论片| 欧美大片免费观看| 激情国产一区| 欧美一区二区免费| 亚洲欧洲av一区二区| 欧美日韩不卡在线| 亚洲黄色影院| 亚洲国产一区二区三区高清| 欧美一区免费视频| 欧美一级成年大片在线观看| 欧美三级午夜理伦三级中视频| 欧美电影在线观看| 亚洲黄色一区| 一区二区三区在线视频观看| 亚洲欧美激情精品一区二区| 亚洲在线播放电影| 国产精品国产三级国产普通话三级 | 久久av一区二区三区漫画| 亚洲摸下面视频| 国产精品久久久久久久久久妞妞| 亚洲乱码国产乱码精品精天堂 | 亚洲精品国精品久久99热一| 狠狠色综合网站久久久久久久| 欧美一级视频一区二区| 欧美一级午夜免费电影| 国产精品美女久久久久久久 | 91久久精品国产| 日韩午夜电影在线观看| 欧美丰满少妇xxxbbb| 亚洲韩国青草视频| 亚洲视频在线一区观看| 国产伦精品一区二区| 欧美一区日韩一区| 欧美va亚洲va日韩∨a综合色| 亚洲高清不卡在线观看| 欧美精品乱人伦久久久久久| 一本一本久久a久久精品综合妖精| 亚洲小说欧美另类婷婷| 国产一区欧美| 欧美激情麻豆| 99热在这里有精品免费| 午夜欧美大片免费观看| 永久久久久久| 欧美网站在线观看| 久久国产精品亚洲va麻豆| 欧美电影美腿模特1979在线看| 亚洲精品亚洲人成人网| 欧美午夜剧场| 久久精品亚洲乱码伦伦中文| 亚洲高清视频的网址| 亚洲欧美日韩一区二区三区在线观看| 国产一区二区三区四区老人| 免费欧美在线| 亚洲一区久久久| 亚洲第一精品夜夜躁人人爽| 亚洲视频大全| 久久精品人人做人人综合| 亚洲少妇自拍| 日韩一级在线| 国产精品视频一二三| 久久久国产精品亚洲一区| 亚洲人成在线观看网站高清| 午夜精品久久99蜜桃的功能介绍| 伊人狠狠色j香婷婷综合| 免费看亚洲片| 欧美一级理论片| 亚洲精品国产精品国自产观看浪潮 | 性欧美长视频| 最新亚洲一区| 免费成人av在线| 午夜宅男欧美| 一区二区三区精品国产| 亚洲第一页中文字幕| 国产欧美亚洲视频| 国产精品久久久久久久午夜 | 亚洲第一精品夜夜躁人人躁| 国产精品亚洲综合天堂夜夜 | 国产精品久久久久一区二区| 免费一区二区三区|