重温 Win32 API ----- 截屏指定窗口并打印

来源:互联网 发布:樱井知香2010年番号 编辑:程序博客网 时间:2024/06/10 20:06

朋友说在一个VC++6.0开发的项目中要加入打印窗口的功能,让帮忙写个代码供其调用。这么老的IDE当然不想碰了,而且也不喜欢MFC笨拙不清晰的封装,所以决定采用纯Win32 API,然后用C++类简单封装一下。

1 基本思路

窗口DC和打印机DC是两类不兼容的DC,所以它们之间传送位图只能通过DIB。首先,通过BitBlt()把要打印窗口的客户区拷贝到DDB内存位图中,然后通过GetDIBits()把DDB转换为DIB,最后通过StretchDIBits()向打印机DC输出。

2 代码实现

头文件 WinowPrinter.h

#pragma once/********************************************************************************                         WindowPrinter 打印窗口类功能描述:提供截屏窗口并通过默认打印机,自动进行居中缩放打印使用说明:样例代码如下。 HWND hwnd = this->GetSafeWnd();WindowPrinter::PrintWindowClientArea(hwnd);********************************************************************************/class WindowPrinter{public:WindowPrinter();~WindowPrinter();public:/*功能:获取当前默认打印机的DC返回:成功返回打印机的DC,失败返回NULL*/static HDC GetPrinterDC();/*功能:打印窗口客户区内容到打印机,自动缩放居中打印参数: hWnd-被打印窗口的句柄*/static void PrintWindowClientArea(HWND hwnd);};


 

实现文件 WindowPrinter.cpp

#include "stdafx.h"#include "WindowPrinter.h"#include <Winspool.h>WindowPrinter::WindowPrinter(){}WindowPrinter::~WindowPrinter(){}/*功能:获取当前默认打印机的DC返回:成功返回打印机的DC,失败返回NULL*/HDC WindowPrinter::GetPrinterDC(){DWORD dwNeeded, dwReturned;HDC hdc;::EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned);PRINTER_INFO_4* pinfo4 = (PRINTER_INFO_4*)malloc(dwNeeded);::EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (BYTE*)pinfo4, dwNeeded, &dwNeeded, &dwReturned);hdc = ::CreateDC(NULL, pinfo4->pPrinterName, NULL, NULL);free(pinfo4);return hdc;}/*功能:打印窗口客户区内容到打印机,自动缩放居中打印参数: hWnd-被打印窗口的句柄*/void WindowPrinter::PrintWindowClientArea(HWND hWnd){if (hWnd == NULL) return;RECT rectClient;::GetClientRect(hWnd, &rectClient);int width = rectClient.right - rectClient.left;int height = rectClient.bottom - rectClient.top;// 通过内存DC复制客户区到DDB位图HDC hdcWnd = ::GetDC(hWnd);HBITMAP hbmWnd = ::CreateCompatibleBitmap(hdcWnd, width, height);HDC hdcMem = ::CreateCompatibleDC(hdcWnd);::SelectObject(hdcMem, hbmWnd);::BitBlt(hdcMem, 0, 0, width, height, hdcWnd, 0, 0, SRCCOPY);// 把窗口DDB转为DIBBITMAP bmpWnd;::GetObject(hbmWnd, sizeof(BITMAP), &bmpWnd);BITMAPINFOHEADER bi; // 信息头bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = bmpWnd.bmWidth;bi.biHeight = bmpWnd.bmHeight;bi.biPlanes = 1;bi.biBitCount = 32; // 按照每个像素用32bits表示转换bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrUsed = 0;bi.biClrImportant = 0;DWORD dwBmpSize = ((bmpWnd.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpWnd.bmHeight; // 每一行像素位32对齐char *lpbitmap = (char*)malloc(dwBmpSize); // 像素位指针::GetDIBits(hdcMem, hbmWnd, 0, (UINT)bmpWnd.bmHeight,lpbitmap,(BITMAPINFO*)&bi,DIB_RGB_COLORS);::DeleteDC(hdcMem);::DeleteObject(hbmWnd);::ReleaseDC(hWnd, hdcWnd);// 存为文件(可选)BITMAPFILEHEADER bmfHeader; // 文件头DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);bmfHeader.bfSize = dwSizeofDIB;bmfHeader.bfType = 0x4D42;FILE* fp = NULL;::_wfopen_s(&fp, L"capture.bmp", L"w");::fwrite(&bmfHeader, sizeof(BITMAPFILEHEADER), 1, fp); // 写入文件头::fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, fp);        // 写入信息头::fwrite(lpbitmap, dwBmpSize, 1, fp);                  // 写入像素位::fclose(fp);fp = NULL;// StretchDIBits()缩放打印DIBHDC hdcPrinter = WindowPrinter::GetPrinterDC();if (hdcPrinter == NULL)return;int pageWidth = ::GetDeviceCaps(hdcPrinter, HORZRES);int pageHeight = ::GetDeviceCaps(hdcPrinter, VERTRES);float scaleX = (float)pageWidth / (float)bmpWnd.bmWidth;float scaleY = (float)pageHeight / (float)bmpWnd.bmHeight;float scale = scaleX < scaleY ? scaleX : scaleY;int xDst, yDst, cxDst, cyDst;cxDst = (int)((float)bmpWnd.bmWidth * scale);cyDst = (int)((float)bmpWnd.bmHeight * scale);xDst = (int)((pageWidth - cxDst) / 2);yDst = (int)((pageHeight - cyDst) / 2);static DOCINFO di = { sizeof(DOCINFO), L"PRINTJOBNAME" };if (::StartDoc(hdcPrinter, &di) > 0){if (::StartPage(hdcPrinter) > 0){::StretchDIBits(hdcPrinter,xDst, yDst, cxDst, cyDst,0, 0, bmpWnd.bmWidth, bmpWnd.bmHeight,lpbitmap,(BITMAPINFO*)&bi,DIB_RGB_COLORS,SRCCOPY);::EndPage(hdcPrinter);}::EndDoc(hdcPrinter);}::DeleteDC(hdcPrinter);::free(lpbitmap);}


 

 

 

0 0
原创粉丝点击