我正在尝试打印我在屏幕上看到的画笔图案,但根据打印机DC,我会得到不同的结果。我使用Microsoft PDF或打印机。两者都使用600 DPI进行打印。当我通过调整CreatePatternBrush使用的位图大小来打印时,我试图获得相同的模式。这似乎适用于Microsoft PDF,但不适用于打印机。使用打印机的图案太大了。有什么线索的原因?
OnBnClickedButtonprint是我尝试打印在模式位图上完成ScaleBitmap的地方。这是代码:
#include "stdafx.h"
#include "Printing.h"
#include "PrintingDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
RECT rcSmall = { 25, 25, 75, 75 };
RECT rcBig = { 55, 55, 255, 255 };
RECT rcWholeArea = { 0, 0, 300, 300 };
COLORREF crRed = RGB(255, 0, 0);
COLORREF crGreen = RGB(0, 255, 0);
COLORREF crBlue = RGB(0, 0, 255);
COLORREF crWhite = RGB(255, 255, 255);
COLORREF crBlack = RGB(0, 0, 0);
CPrintingDlg::CPrintingDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_PRINTING_DIALOG, pParent)
{
WORD HatchBits[8] = { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe };
m_hBitmap = ::CreateBitmap(8, 8, 1, 1, HatchBits);
}
void CPrintingDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPrintingDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTONPRINT, &CPrintingDlg::OnBnClickedButtonprint)
END_MESSAGE_MAP()
// CPrintingDlg message handlers
BOOL CPrintingDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
return TRUE; // return TRUE unless you set the focus to a control
}
HBITMAP CPrintingDlg::ScaleBitmap(HDC hdc, HBITMAP hBitmapSrc)
{
double gDPIScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
double gDPIScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f;
if (gDPIScaleX == 1.0 && gDPIScaleY == 1.0)
return hBitmapSrc;
// Get logical coordinates
BITMAP bm;
::GetObject(hBitmapSrc, sizeof(bm), &bm);
int iWidth = (int)(bm.bmWidth * gDPIScaleX);
int iHeight = (int)(bm.bmHeight * gDPIScaleY);
// Select the source DC
HDC hdcSrc = ::CreateCompatibleDC(hdc);
HBITMAP hBitmapOldSrc = (HBITMAP)::SelectObject(hdcSrc, hBitmapSrc);
// Create the bitmap and select the destination DC
HDC hdcDst = ::CreateCompatibleDC(hdc);
HBITMAP hBitmapDst = ::CreateCompatibleBitmap(hdcDst, iWidth, iHeight);
HBITMAP hBitmapOldDst = (HBITMAP)::SelectObject(hdcDst, hBitmapDst);
// Resize
::StretchBlt(hdcDst, 0, 0, iWidth, iHeight, hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
// Reselect the old bitmaps
::SelectObject(hdcSrc, hBitmapOldSrc);
::SelectObject(hdcDst, hBitmapOldDst);
// Delete the resources
DeleteDC(hdcSrc);
DeleteDC(hdcDst);
return hBitmapDst;
}
RECT CPrintingDlg::ScaleRect(HDC hdc, RECT rcOriginal)
{
double gDPIScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
double gDPIScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f;
if (gDPIScaleX == 1.0 && gDPIScaleY == 1.0)
return rcOriginal;
RECT rcScaled;
rcScaled.left = (long)(rcOriginal.left * gDPIScaleX);
rcScaled.right = (long)(rcOriginal.right * gDPIScaleX);
rcScaled.top = (long)(rcOriginal.top * gDPIScaleY);
rcScaled.bottom = (long)(rcOriginal.bottom * gDPIScaleY);
return rcScaled;
}
void CPrintingDlg::DrawRectangle(HDC hdc, RECT rect, COLORREF cr)
{
HPEN hPen = ::CreatePen(PS_SOLID, 1, cr);
::SelectObject(hdc, hPen);
HBRUSH hBrush = ::CreateSolidBrush(cr);
::SelectObject(hdc, hBrush);
::Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void CPrintingDlg::DrawPatternRectangle(HDC hdc, HBITMAP hBitmap, RECT rect, COLORREF cr)
{
int oldROP2 = 0;
HPEN hPen = ::CreatePen(PS_SOLID, 1, crBlack);
::SelectObject(hdc, hPen);
HBRUSH hPatternBrush = ::CreatePatternBrush(hBitmap);
::SelectObject(hdc, hPatternBrush);
::SetTextColor(hdc, crBlack);
if (::GetROP2(hdc) == R2_COPYPEN)
{
::SetBkColor(hdc, crWhite);
oldROP2 = ::SetROP2(hdc, R2_MASKNOTPEN);
::Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
::SetBkColor(hdc, cr);
::SetROP2(hdc, R2_MERGEPEN);
::Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
::SetROP2(hdc, oldROP2);
}
else
{
::SetBkColor(hdc, cr);
::Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
}
}
void CPrintingDlg::OnPaint()
{
CPaintDC hdc(this);
DrawRectangle(hdc, rcWholeArea, crWhite);
DrawRectangle(hdc, rcSmall, crGreen);
DrawPatternRectangle(hdc, m_hBitmap, rcBig, crRed);
}
void CPrintingDlg::OnBnClickedButtonprint()
{
CPrintDialog dlgPrint(FALSE, PD_NOSELECTION);
dlgPrint.GetDefaults();
dlgPrint.m_pd.Flags &= ~PD_RETURNDEFAULT;
DEVMODE* dm = (DEVMODE*)GlobalLock(dlgPrint.m_pd.hDevMode);
dm->dmFields |= DM_ORIENTATION;
dm->dmOrientation = DMORIENT_LANDSCAPE;
GlobalUnlock(dlgPrint.m_pd.hDevMode);
dlgPrint.DoModal();
HDC hdc = dlgPrint.GetPrinterDC();
DOCINFO docInfo;
ZeroMemory(&docInfo, sizeof(docInfo));
docInfo.cbSize = sizeof(docInfo);
docInfo.lpszDocName = _T("PrintTest");
StartDoc(hdc, &docInfo);
StartPage(hdc);
DrawRectangle(hdc, ScaleRect(hdc, rcWholeArea), crWhite);
DrawRectangle(hdc, ScaleRect(hdc, rcSmall), crGreen);
DrawPatternRectangle(hdc, ScaleBitmap(hdc, m_hBitmap), ScaleRect(hdc, rcBig), crRed);
EndPage(hdc);
EndDoc(hdc);
DeleteDC(hdc);
}
以下是我试图打印的内容: