使用 MFC 打印到打印机 DC [英] Printing to a Printer DC with MFC

查看:113
本文介绍了使用 MFC 打印到打印机 DC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了 Microsoft 创建设备上下文的教程,并尝试在 Internet 上寻找合适的来源(显然,MFC 是一个神秘的东西).下面成功打印出Hello, World!";除了它非常小.

I've followed Microsoft's tutorial on creating a Device Context, and I've tried looking around the internet for a decent source (apparently, MFC is a mystical thing). The following successfully prints out "Hello, World!"; except it's extremely tiny.

如何向打印机发送 CImage 而不是文本?我怎样才能使文本的大小大于几毫米?我已经搜索了 MSDN,但所有内容要么已经过时(如我使用的示例代码),要么只是没有很好的文档记录.

How can I send a CImage to the printer, rather than text? And how could I get the text's size to be bigger than a couple millimeters? I've scoured MSDN, but everything is either outdated (like the example code I am using), or just not well documented.

 // 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

问题是,默认情况下,字体的大小是以设备相关的单位指定的,而打印机的分辨率通常比屏幕高得多.因此,如果您尝试在打印机上使用该字体(每英寸可能有 300 或 600 个点)时,在屏幕上创建了一个 20 像素高的字体(每英寸可能有 96 像素),那么您的文本看起来会非常真实小.

Tiny Text Problem

The problem is that, by default, the size of a font is specified in device-dependent units and printers are generally much higher resolution that a screen. So if you've created a font that is 20 pixels high on the screen (which might have 96 pixels per inch) when you try to use that font on a printer, which maybe has 300 or 600 dots per inch, your text looks really small.

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

As another answer shows, one idea is to change the mapping mode so that the printer uses units that are closer to what is on the screen.

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

An alternative way is to create a new font with an appropriate size (the lfHeight field in the LOGFONT structure) based on the DPI of the printer, which you can determine with the GetDeviceCaps function. This can be handy if you want a particular font size, like 14 point text.

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);

发送 CImage

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

Sending a CImage

I don't use MFC, but it looks like you can just call CImage::StretchBlt with the printer DC. Once again, you'll probably have to take the printer's much higher resolution into account when you choose the target coordinates.

这篇关于使用 MFC 打印到打印机 DC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆