使用MFC打印到打印机DC

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用MFC打印到打印机DC相关的知识,希望对你有一定的参考价值。

我已经按照微软关于创建设备上下文的教程,我已经尝试在互联网上寻找一个合适的来源(显然,MFC是一个神秘的东西)。以下成功打印出“Hello,World!”;除了它非常小。

如何将CImage发送到打印机而不是文本?我怎么能让文本的大小超过几毫米?我已经搜索过MSDN,但是一切都已过时(比如我正在使用的示例代码),或者只是没有很好的文档记录。

 // get the default printer
  CPrintDialog dlg(FALSE);
  dlg.GetDefaults();

  // is a default printer set up?
  HDC hdcPrinter = dlg.GetPrinterDC();
  if (hdcPrinter == NULL)
  {
    //MessageBox(_T("Buy a printer!"));
  }
  else
  {
    // create a CDC and attach it to the default printer
    CDC dcPrinter;
    dcPrinter.Attach(hdcPrinter);

    // call StartDoc() to begin printing
    DOCINFO docinfo;
    memset(&docinfo, 0, sizeof(docinfo));
    docinfo.cbSize = sizeof(docinfo);
    docinfo.lpszDocName = _T("CDC::StartDoc() Code Fragment");

    // if it fails, complain and exit gracefully
    if (dcPrinter.StartDoc(&docinfo) < 0)
    {
      //MessageBox(_T("Printer wouldn't initalize"));
    }
    else
    {
      // start a page
      if (dcPrinter.StartPage() < 0)
      {
        //MessageBox(_T("Could not start page"));
        dcPrinter.AbortDoc();
      }
      else
      {
        // actually do some printing
        //CGdiObject* pOldFont = dcPrinter.SelectStockObject(SYSTEM_FONT);

        dcPrinter.SetMapMode(MM_HIENGLISH);
      auto font = CreateFont(
      3'000,                        // nHeight
      1'500,                         // nWidth
      0,                         // nEscapement
      0,                         // nOrientation
      FW_NORMAL,                 // nWeight
      FALSE,                     // bItalic
      FALSE,                     // bUnderline
      0,                         // cStrikeOut
      ANSI_CHARSET,              // nCharSet
      OUT_DEFAULT_PRECIS,        // nOutPrecision
      CLIP_DEFAULT_PRECIS,       // nClipPrecision
      DEFAULT_QUALITY,           // nQuality
      DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
      _T("Arial"));                 // lpszFacename
      dcPrinter.SelectObject(&font);
        dcPrinter.TextOut(450, 450, _T("Hello World!"), 12);
        dcPrinter.EndPage();
        dcPrinter.EndDoc();
        //dcPrinter.SelectObject(pOldFont);
      }
    }
  }
答案

Tiny Text Problem

问题在于,默认情况下,字体的大小是在依赖于设备的单元中指定的,并且打印机的分辨率通常比屏幕高得多。因此,当您尝试在打印机上使用该字体时,如果您在屏幕上创建了一个20像素高的字体(可能每英寸有96个像素),那么每英寸可能有300或600个点,那么您的文字看起来真的很棒小。

另一个答案显示,一个想法是更改映射模式,以便打印机使用更接近屏幕上的单位。

另一种方法是根据打印机的DPI创建具有适当大小的新字体(LOGFONT结构中的lfHeight字段),您可以使用GetDeviceCaps函数确定该字体。如果您想要特定的字体大小(如14磅文本),这可能很方便。

LOGFONT lf = {0};
lf.lfHeight = -MulDiv(point_size, ::GetDeviceCaps(dcPrinter, LOGPIXELSY), 72);
// init other field of lf as you like
HFONT hfontPrinter = ::CreateFontIndirect(&lf);
HFONT hfontOld = ::SelectObject(hdcPrinter, hfontPrinter);

// now draw to the hdcPrinter

::SelectObject(hdcPrinter, hfontOld);
::DeleteObject(hfontPrinter);

Sending a CImage

我不使用MFC,但看起来你可以用打印机DC调用CImage::StretchBlt。再次,当您选择目标坐标时,您可能必须考虑打印机的更高分辨率。

另一答案

这是问题所在:

dcPrinter.SetMapMode(MM_TEXT);

MM_TEXT将一个逻辑点映射到一个设备点;考虑到打印机的典型分辨率为600 DPI,您的东西将比屏幕上的小几倍。

使用MM_HIENGLISH或其他一些与设备无关的模式;这是MSDN link

另一答案

使用CFont :: CreatePointFont()或CFont :: CreatePointFontIndirect()来创建合理的字体。大多数打印机都是600 DPI。大多数屏幕都是96 DPI。屏幕上的12磅字体基本上是2磅字体,在打印机上难以辨认。

创建字体并将其选择到DC中。在使用它之后和销毁DC(CDC类)之前,不要忘记从DC中选择它。 (CDC析构函数自动删除HDC)。

另一答案

我用以下内容成功打印了“Hello World!”祝你有愉快的一天!”位于打印机页面原点的200x200单色位图(MyLogo.bmp)右侧(我使用的是黑白热敏打印机):

CDC printDC( GetMyPrintDC() );    // e.g. as per original code
DOCINFO di( GetMyDocInfo() );     // e.g. as per original code
printDC.StartDoc( &di );
  ATL::CImage logo;
  logo.Load( "MyLogo.bmp" );
  const BOOL result( logo.Draw( printDC.GetSafeHdc(), CPoint( 0, 0 ) ) );
CFont myFont, *old;
myFont.CreatePointFont(100, "Courier New", &printDC);
old = printDC.SelectObject(&myFont);
printDC.TextOut( 250, 50, "   Hello World!" );
printDC.TextOut( 250, 150, "Have a nice Day!" );
printDC.SelectObject( old );
myFont.DeleteObject();
printDC.EndPage();
printDC.EndDoc();
printDC.DeleteDC();

三条缩进线突出显示在我的打印机上渲染CImage所需的全部内容。改变CreatePointFont()中的参数来调整(否则很小的)文本以适应。

以上是关于使用MFC打印到打印机DC的主要内容,如果未能解决你的问题,请参考以下文章

MFC - 打印 rtf 文档

如何将 MFC DC 与 QPrinter 关联?

如何使用直接 2d 在打印机 DC 中绘制文本?

如何用MFC打印指定excel

VC6 和 MFC 中的 HTML 打印和打印预览

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情