以下是一个简单的示例,演示如何使用 VC++2012 在 A4 纸张上打印预览文件目录下所有照片,从上到下排列每页三张照片,每张照片下方显示照片文件名。
首先,在 DialogNameDlg.h 文件中添加以下 include 和宏定义:
cpp
Copy code
#pragma once
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#ifndef WINVER
#define WINVER 0x0501
#endif
然后,在 DialogNameDlg.cpp 文件中实现 OnPreview 函数和相关辅助函数:
cpp
Copy code
void CDialogNameDlg::OnPreview()
{
// 获取当前屏幕分辨率
int iScreenDPI = GetDeviceCaps(GetDC()->m_hDC, LOGPIXELSX);
// 创建打印预览对话框
CPrintPreviewDialog dlg(this);
if (dlg.DoModal() != IDOK)
return;
// 获取打印设备上下文和打印机 DC
CDC* pDC = dlg.GetPrinterCDC();
HDC hPrinterDC = pDC->GetSafeHdc();
// 获取打印区域矩形,并根据 A4 纸张大小调整比例
RECT rcPage;
GetPrintableRect(hPrinterDC, &rcPage);
double fScale = min((double)(rcPage.right - rcPage.left) / (3 * m_Size.cx), (double)(rcPage.bottom - rcPage.top - 50) / (6 * m_Size.cy));
int iWidth = (int)(m_Size.cx * fScale);
int iHeight = (int)(m_Size.cy * fScale);
int iMarginX = (int)((rcPage.right - rcPage.left - 3 * iWidth) / 2);
int iMarginY = (int)((rcPage.bottom - rcPage.top - 6 * iHeight - 50) / 2);
// 获取打印机分辨率
int iDPI = pDC->GetDeviceCaps(LOGPIXELSX);
// 设置打印字体
CFont font;
font.CreatePointFont((int)(8.0 * iDPI / 72), _T("Arial"));
pDC->SelectObject(&font);
// 打印照片和文件名
CString strFolder = _T("C:\\Photos");
CFileFind finder;
BOOL bWorking = finder.FindFile(strFolder + _T("\\*.jpg"));
int iPage = 1;
int iCount = 0;
while (bWorking)
{
bWorking = finder.FindNextFile();
if (!finder.IsDots() && !finder.IsDirectory())
{
CString strFileName = finder.GetFilePath();
CDC memDC;
CBitmap bmpMem;
memDC.CreateCompatibleDC(pDC);
bmpMem.CreateCompatibleBitmap(pDC, iWidth, iHeight);
memDC.SelectObject(&bmpMem);
CImage image;
image.Load(strFileName);
if (!image.IsNull())
{
StretchDIBits(memDC.m_hDC,
0, 0, iWidth, iHeight,
0, 0, m_Size.cx, m_Size.cy,
image.GetBits(), (BITMAPINFO*)image.GetHeader(), DIB_RGB_COLORS, SRCCOPY);
int iRow = iCount % 3;
int iCol = iCount / 3;
pDC->BitBlt(rcPage.left + iMarginX + iRow * iWidth, rcPage.top + iMarginY + iCol * iHeight, iWidth, iHeight, &memDC, 0, 0, SRCCOPY);
pDC->SetTextColor(RGB(0, 0, 0));
pDC->SetTextAlign(TA_CENTER);
RECT rcText = { rcPage.left + iMarginX + iRow * iWidth, rcPage.top + iMarginY + (iCol + 1) * iHeight, rcPage.left + iMarginX + (iRow + 1) * iWidth, rcPage.top + iMarginY + (iCol + 1) * iHeight + 50 };
pDC->DrawText(strFileName, &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
iCount++;
if (iCount == 18)
{
// 已经打印
续
满一页,开始打印下一页
pDC->EndPage();
pDC->StartPage();
iPage++;
iCount = 0;
}
}
}
}
scss
Copy code
// 打印完成,释放资源
finder.Close();
if (iCount > 0)
pDC->EndPage();
pDC->DeleteDC();
}
void CDialogNameDlg::GetPrintableRect(HDC hDC, LPRECT lpRect)
{
int iHorzRes = GetDeviceCaps(hDC, HORZRES);
int iVertRes = GetDeviceCaps(hDC, VERTRES);
int iLogPixelsX = GetDeviceCaps(hDC, LOGPIXELSX);
int iLogPixelsY = GetDeviceCaps(hDC, LOGPIXELSY);
scss
Copy code
lpRect->left = lpRect->top = 0;
lpRect->right = MulDiv(210, iLogPixelsX, 25.4);
lpRect->bottom = MulDiv(297, iLogPixelsY, 25.4);
int iHorzSize = MulDiv(lpRect->right - lpRect->left, 254, iLogPixelsX);
int iVertSize = MulDiv(lpRect->bottom - lpRect->top, 254, iLogPixelsY);
if (iHorzSize > iVertSize)
lpRect->right = MulDiv(iVertSize, iLogPixelsX, 254) + lpRect->left;
else
lpRect->bottom = MulDiv(iHorzSize, iLogPixelsY, 254) + lpRect->top;
}
kotlin
Copy code
最后,在 InitDialog 函数中添加以下代码,以便在对话框上添加打印和打印预览按钮:
BOOL CDialogNameDlg::OnInitDialog()
{
// ...
// 创建打印和打印预览按钮
m_btnPrint.Create(_T("打印"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(10, 10, 80, 30), this, ID_PRINT);
m_btnPreview.Create(_T("打印预览"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(100, 10, 200, 30), this, ID_PREVIEW);
// ...
return TRUE;
}
现在,您可以在 VC++2012 中编译并运行此应用程序。当您单击“打印”或“打印预览”按钮时,将弹出相应的对话框,并显示文件目录下所有照片,从上到下排列每页三张照片,每张照片下方显示照片文件名。