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

穩(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>
            亚洲二区视频| 美日韩丰满少妇在线观看| 久久永久免费| 欧美一区激情视频在线观看| 欧美激情久久久| 免费亚洲婷婷| 黄色小说综合网站| 午夜久久久久久| 欧美一区二区三区视频在线观看| 欧美系列亚洲系列| 99国内精品久久久久久久软件| 亚洲激情自拍| 久久精视频免费在线久久完整在线看| 亚洲欧美国产视频| 欧美日韩中文精品| 99re热这里只有精品免费视频| 亚洲人成艺术| 女女同性精品视频| 欧美高清视频一区二区三区在线观看 | 欧美成人在线免费观看| 精品不卡一区| 久久久精品日韩欧美| 久久艳片www.17c.com| 韩国av一区二区三区四区| 欧美伊久线香蕉线新在线| 久久久久综合一区二区三区| 国产亚洲欧美一区二区| 久久精品欧洲| 亚洲成人直播| 日韩天堂在线视频| 国产精品白丝jk黑袜喷水| 亚洲视频碰碰| 久久久久久日产精品| 尤物精品在线| 欧美激情久久久久| 亚洲午夜精品17c| 久久久综合激的五月天| 在线观看福利一区| 欧美xxx成人| 亚洲国产精品一区二区第一页 | 久久青青草综合| 国外成人性视频| 免费亚洲视频| 99精品国产高清一区二区| 性欧美暴力猛交69hd| 黄色日韩网站| 欧美日韩第一区| 亚洲男人的天堂在线观看| 可以看av的网站久久看| 一本久久青青| 国产一区二区日韩精品| 欧美69视频| 国产精品99久久不卡二区| 久久精品日韩| 亚洲人成在线播放| 国产精品久久久久影院色老大| 久久精品毛片| 日韩亚洲视频在线| 久久精品国产欧美激情| 亚洲全部视频| 国产一区 二区 三区一级| 欧美国产1区2区| 亚洲自拍偷拍色片视频| 欧美黄色aa电影| 一区二区三区久久久| 激情小说亚洲一区| 欧美性猛片xxxx免费看久爱| 久久青草久久| 西瓜成人精品人成网站| 亚洲国产精品一区二区第一页| 欧美淫片网站| 夜夜爽www精品| 狠狠综合久久av一区二区老牛| 欧美日韩一区成人| 久久精品国产亚洲高清剧情介绍| 亚洲国产美女| 久久人人97超碰国产公开结果| 在线亚洲一区| 最新成人av在线| 国产综合色产| 国产精品羞羞答答| 欧美日韩视频在线一区二区| 老司机午夜精品视频| 欧美伊人久久久久久午夜久久久久| 一区二区三区av| 日韩天堂av| 日韩午夜免费| 亚洲日本成人| 亚洲欧洲一级| 亚洲国产裸拍裸体视频在线观看乱了中文 | 国产精品国产自产拍高清av王其| 欧美成人免费网| 久久综合伊人77777| 久久久久久久久久看片| 欧美在线一二三| 久久国产毛片| 久久久午夜视频| 久久婷婷av| 嫩草影视亚洲| 欧美精品一区二区在线观看| 欧美va亚洲va国产综合| 欧美电影免费| 欧美人妖在线观看| 欧美日韩国产成人在线91| 欧美人与禽性xxxxx杂性| 欧美屁股在线| 国产精品第一页第二页第三页| 欧美婷婷久久| 国产精品日韩欧美一区| 国产精品免费久久久久久| 国产精品永久入口久久久| 国产视频在线观看一区二区| 国产一区二区三区av电影| 黑人巨大精品欧美一区二区小视频| 国内精品久久久久久久果冻传媒 | 巨乳诱惑日韩免费av| 欧美成人蜜桃| 99在线热播精品免费| 亚洲在线成人精品| 久久精品30| 欧美国产日韩精品| 国产精品久久久爽爽爽麻豆色哟哟| 国产精品日本一区二区| 狠狠色丁香久久综合频道| 亚洲人午夜精品免费| 一本在线高清不卡dvd| 午夜影院日韩| 免费成人你懂的| 亚洲毛片av在线| 性做久久久久久久久| 另类激情亚洲| 国产精品久久久久久福利一牛影视| 国产日产精品一区二区三区四区的观看方式 | 亚洲一区欧美二区| 久久免费99精品久久久久久| 亚洲风情亚aⅴ在线发布| 一区二区三区久久网| 久久精品国产2020观看福利| 欧美成人自拍视频| 国产精自产拍久久久久久| 亚洲国产高清在线观看视频| 亚洲一区二区三区在线视频| 久久亚洲一区二区| 这里只有精品视频在线| 久久综合久久久| 国产免费观看久久黄| 日韩一级在线| 久久视频免费观看| 在线视频精品| 免费在线欧美视频| 国产亚洲毛片| 亚洲免费视频网站| 亚洲国产精品电影在线观看| 亚洲欧美国产三级| 欧美日韩国产在线播放| 亚洲国产成人tv| 久久精品99久久香蕉国产色戒| 亚洲免费不卡| 欧美jizzhd精品欧美巨大免费| 国产日本欧洲亚洲| 亚洲天堂黄色| 亚洲人www| 噜噜噜噜噜久久久久久91| 国产又爽又黄的激情精品视频| 亚洲一区二区在线播放| 亚洲二区在线| 免费日韩av电影| 在线日韩日本国产亚洲| 久久久人成影片一区二区三区| 亚洲午夜一区| 欧美视频在线观看视频极品| 亚洲美女福利视频网站| 欧美韩日高清| 美女亚洲精品| 亚洲高清视频中文字幕| 麻豆成人小视频| 久久激情视频免费观看| 国产亚洲精品福利| 久久精品在线播放| 亚洲欧美自拍偷拍| 国产精品一区二区欧美| 午夜免费日韩视频| 亚洲视频在线看| 国产精品久久久久永久免费观看| 亚洲一级黄色av| 一区二区三区欧美在线观看| 欧美日韩午夜精品| 亚洲午夜一二三区视频| 一本色道久久综合亚洲精品高清 | 欧美人与禽猛交乱配| 在线一区二区日韩| 99re6这里只有精品| 欧美视频网站| 欧美主播一区二区三区| 欧美在线视频观看| 亚洲丶国产丶欧美一区二区三区| 欧美国产亚洲精品久久久8v| 欧美1区视频| 亚洲一区二区三区四区五区午夜| 亚洲视频在线观看|