我现在的思路是用loadimage读取一个bmp文件,然后用stretchblt的函数把图片复制到打印机的句柄上,现在的问题是我本地的图片是一个纵向的图片,但是打印机打出来的是个横向的图片
// Q695292.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "resource.h"
HBITMAP CaptureImage(HWND hwnd)
{
HANDLE hDIB;
DWORD dwBmpSize;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
BITMAPINFOHEADER bi;
CHAR *lpbitmap;
INT width = GetSystemMetrics(SM_CXSCREEN); // ÆÁÄ»¿í
INT height = GetSystemMetrics(SM_CYSCREEN); // ÆÁÄ»¸ß
HDC hdcScreen = GetDC(NULL); // È«ÆÁÄ»DC
HDC hdcMemDC = CreateCompatibleDC(hdcScreen); // ´´½¨¼æÈÝÄÚ´æDC
if (!hdcMemDC)
{
//echo(TEXT("CreateCompatibleDC has failed"));
goto done;
}
// ͨ¹ý´°¿ÚDC ´´½¨Ò»¸ö¼æÈÝλͼ
hbmScreen = CreateCompatibleBitmap(hdcScreen, width, height);
if (!hbmScreen)
{
//echo(TEXT("CreateCompatibleBitmap Failed"));
goto done;
}
// ½«Î»Í¼¿é´«Ë͵½ÎÒÃǼæÈݵÄÄÚ´æDCÖÐ
SelectObject(hdcMemDC, hbmScreen);
if (!BitBlt(
hdcMemDC, // Ä¿µÄDC
0, 0, // Ä¿µÄDCµÄ x,y ×ø±ê
width, height, // Ä¿µÄ DC µÄ¿í¸ß
hdcScreen, // À´Ô´DC
0, 0, // À´Ô´DCµÄ x,y ×ø±ê
SRCCOPY)) // Õ³Ìù·½Ê½
{
//echo(TEXT("BitBlt has failed"));
goto done;
}
// »ñȡλͼÐÅÏ¢²¢´æ·ÅÔÚ bmpScreen ÖÐ
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
// ÔÚ 32-bit Windows ϵͳÉÏ, GlobalAlloc ºÍ LocalAlloc ÊÇÓÉ HeapAlloc ·â×°À´µÄ
// handle Ö¸Ïò½ø³ÌĬÈϵĶÑ. ËùÒÔ¿ªÏú±È HeapAlloc Òª´ó
hDIB = GlobalAlloc(GHND, dwBmpSize);
lpbitmap = (char *)GlobalLock(hDIB);
// »ñÈ¡¼æÈÝλͼµÄλ²¢ÇÒ¿½±´½á¹ûµ½Ò»¸ö lpbitmap ÖÐ.
GetDIBits(
hdcScreen, // É豸»·¾³¾ä±ú
hbmScreen, // λͼ¾ä±ú
0, // Ö¸¶¨¼ìË÷µÄµÚÒ»¸öɨÃèÏß
(UINT)bmpScreen.bmHeight, // Ö¸¶¨¼ìË÷µÄɨÃèÏßÊý
lpbitmap, // Ö¸ÏòÓÃÀ´¼ìË÷λͼÊý¾ÝµÄ»º³åÇøµÄÖ¸Õë
(BITMAPINFO *)&bi, // ¸Ã½á¹¹Ìå±£´æÎ»Í¼µÄÊý¾Ý¸ñʽ
DIB_RGB_COLORS // ÑÕÉ«±íÓɺ졢ÂÌ¡¢À¶£¨RGB£©Èý¸öÖ±½ÓÖµ¹¹³É
);
// ½âËø¶ÑÄÚ´æ²¢ÊÍ·Å
GlobalUnlock(hDIB);
GlobalFree(hDIB);
// ÇåÀí×ÊÔ´
done:
//DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL, hdcScreen);
return hbmScreen;
}
LPDEVMODE GetLandscapeDevMode(HWND hWnd, LPWSTR pDevice)
{
HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;
/* Start by opening the printer */
if (!OpenPrinter(pDevice, &hPrinter, NULL))
return NULL;
/*
* Step 1:
* Allocate a buffer of the correct size.
*/
dwNeeded = DocumentProperties(hWnd,
hPrinter, /* Handle to our printer. */
pDevice, /* Name of the printer. */
NULL, /* Asking for size, so */
NULL, /* these are not used. */
0); /* Zero returns buffer size. */
pDevMode = (LPDEVMODE)malloc(dwNeeded);
/*
* Step 2:
* Get the default DevMode for the printer and
* modify it for your needs.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* The address of the buffer to fill. */
NULL, /* Not using the input buffer. */
DM_OUT_BUFFER); /* Have the output buffer filled. */
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
ClosePrinter(hPrinter);
return NULL;
}
/*
* Make changes to the DevMode which are supported.
*/
if (pDevMode->dmFields & DM_ORIENTATION)
{
/* If the printer supports paper orientation, set it.*/
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
if (pDevMode->dmFields & DM_DUPLEX)
{
/* If it supports duplex printing, use it. */
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
}
/*
* Step 3:
* Merge the new settings with the old.
* This gives the driver an opportunity to update any private
* portions of the DevMode structure.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* Reuse our buffer for output. */
pDevMode, /* Pass the driver our changes. */
DM_IN_BUFFER | /* Commands to Merge our changes and */
DM_OUT_BUFFER); /* write the result. */
/* Finished with the printer */
ClosePrinter(hPrinter);
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
return NULL;
}
/* Return the modified DevMode structure. */
return pDevMode;
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szDriver[16] = _T("WINSPOOL");
TCHAR szPrinter[256];
DWORD cchBuffer = 255;
HDC hdcPrint = NULL;
HANDLE hPrinter = NULL;
PRINTER_INFO_2 *pPrinterData;
BYTE pdBuffer[16384];
BOOL bReturn = FALSE;
DWORD cbBuf = sizeof (pdBuffer);
DWORD cbNeeded = 0;
pPrinterData = (PRINTER_INFO_2 *)&pdBuffer[0];
// get the default printer name
bReturn = GetDefaultPrinter(
szPrinter,
&cchBuffer);
if (bReturn) {
// open the default printer
bReturn = OpenPrinter(
szPrinter,
&hPrinter,
NULL);
}
if (bReturn) {
// get the printer port name
bReturn = GetPrinter(
hPrinter,
2,
&pdBuffer[0],
cbBuf,
&cbNeeded);
// this handle is no longer needed
ClosePrinter(hPrinter);
}
if (bReturn) {
// create the Print DC
DEVMODE * devmode = GetLandscapeDevMode(0, szPrinter);
devmode->dmOrientation = 2;
hdcPrint = CreateDC(szDriver, szPrinter,
pPrinterData->pPortName, devmode);
}
if (hdcPrint) {
Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL);
HBITMAP hBitmap = CaptureImage(GetDesktopWindow()); //LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1));
HDC hMemDC = CreateCompatibleDC(hdcPrint);
SelectObject(hMemDC, hBitmap);
//BitBlt(hdcPrint, 0, 0, 3650 * 15, 2710 * 15, hMemDC, 0, 0, SRCCOPY);
StretchBlt(hdcPrint, 300, 400, 1680 * 15 / 4, 1050 * 15 / 4, hMemDC, 0, 0, 1680, 1050, SRCCOPY);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
Escape(hdcPrint, NEWFRAME, 0, NULL, NULL);
Escape(hdcPrint, ENDDOC, 0, NULL, NULL);
// Delete the printer DC.
DeleteDC(hdcPrint);
}
}