bitmap的打印机打印问题

我现在的思路是用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); 
    }
}


图片说明