Introduction
Well.. it has been a long trip since I first found the excellent work “ReportGenrator” published by Johan Rosengren. Not only is it a very helpful set of tools, but I must use this opportunity to thank Johan for his ongoing support, feedback, and prompt response to many of my questions along the way.
Inspired by this project, and finding my own challenges, I had to resolve a few other issues along the way, two that are no doubt “Generic” type issues:
- Changing the printer orientation at run time – from Portrait to Landscape and back.
- Setting up the paper size / type programmatically.
The following two static functions are aimed exactly at doing that.
You can call SetDefaultPrinterOrientation()
like in the following example. The return value can be used to set the printer back to whatever it was set to, before making the call.
int OriginalOrientation = SetDefaultPrinterOrientation(DMORIENT_LANDSCAPE);
SetPaperType(DMPAPER_<st1:stockticker>ENV</st1:stockticker>_DL);
#define DMORIENT_PORTRAIT 1
#define DMORIENT_LANDSCAPE 2
Those are defined in WinGdi.h, as are the various paper selections that can be used by the SetPaperType()
function.
#include "winspool.h"
int SetDefaultPrinterOrientation(short dmOrientation)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
LPTSTR pPrinterName = NULL;
DWORD size;
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];
if(GetDefaultPrinter(buffer, &size))
pPrinterName = buffer;
else
{
if(buffer != NULL)
delete buffer;
return 0;
}
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
if(buffer != NULL)
delete buffer;
return 0;
}
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() !=
ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
if (pi2->pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,
pPrinterName,NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName, pDevMode, NULL,DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2->pDevMode = pDevMode;
}
if (!(pi2->pDevMode->dmFields & DM_ORIENTATION))
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2->pDevMode->dmFields = DM_ORIENTATION;
int OriginalOrientation = pi2->pDevMode->dmOrientation;
pi2->pDevMode->dmOrientation = dmOrientation;
pi2->pSecurityDescriptor = NULL;
lFlag = DocumentProperties(NULL, hPrinter, pPrinterName,
pi2->pDevMode, pi2->pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
(LPARAM)(LPCSTR)pPrinterName, SMTO_NORMAL, 1000, NULL);
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return OriginalOrientation;
}
BOOL SetPaperType(short dmPaperSize)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
LPTSTR pPrinterName = NULL;
DWORD size;
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];
if(GetDefaultPrinter(buffer, &size))
pPrinterName = buffer;
else
{
if(buffer != NULL)
delete buffer;
return FALSE;
}
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
if(buffer != NULL)
delete buffer;
return FALSE;
}
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() !=
ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
if (pi2->pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,
pPrinterName,NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName, pDevMode, NULL,DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pi2->pDevMode = pDevMode;
}
pi2->pDevMode->dmFields = DM_PAPERSIZE;
pi2->pDevMode->dmPaperSize = dmPaperSize;
pi2->pSecurityDescriptor = NULL;
lFlag = DocumentProperties(NULL, hPrinter, pPrinterName,
pi2->pDevMode, pi2->pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return FALSE;
}
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return FALSE;
}
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
(LPARAM)(LPCSTR)pPrinterName, SMTO_NORMAL, 1000, NULL);
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return TRUE;
}