기본 콘텐츠로 건너뛰기

프린터 속성 설정하기

아래는 프린터 속성을 설정하는 함수입니다.
원문보기
#include <WinSpool.h>
/**
 @brief set printer property
 @author humkyung
 @date 2013.11.06
 @param pPrinterName 
 @param dmType
 @param dmValue
**/
STDMETHODIMP CISODwgLib4IDCS::SetPrinterProperty(BSTR pPrinterName , SHORT dmType, SHORT dmValue, VARIANT_BOOL* ret)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 CString sPrinterName(pPrinterName);
 
 (*ret) = VARIANT_TRUE;
 //////////////////////////////////////////////////////////////////////////
 
 HANDLE hPrinter = NULL;
 DWORD dwNeeded = 0;
 PRINTER_INFO_2 *pi2 = NULL;
 DEVMODE *pDevMode = NULL;
 PRINTER_DEFAULTS pd;
 BOOL bFlag;
 LONG lFlag;

 // Open printer handle (on Windows NT, you need full-access because you
 // will eventually use SetPrinter)...
 ZeroMemory(&pd, sizeof(pd));
 pd.DesiredAccess = PRINTER_ALL_ACCESS;
 bFlag = OpenPrinter(LPSTR(sPrinterName.operator LPCSTR()) , &hPrinter, &pd);
 if (!bFlag || (hPrinter == NULL))
  return FALSE;

 // The first GetPrinter tells you how big the buffer should be in 
 // order to hold all of PRINTER_INFO_2. Note that this should fail with 
 // ERROR_INSUFFICIENT_BUFFER.  If GetPrinter fails for any other reason 
 // or dwNeeded isn't set for some reason, then there is a problem...
 SetLastError(0);
 bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
         if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || 
         (dwNeeded == 0))
 {
  ClosePrinter(hPrinter);
  return FALSE;
 }

 // Allocate enough space for PRINTER_INFO_2...
 pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
 if (pi2 == NULL)
 {
  ClosePrinter(hPrinter);
  return FALSE;
 }

 // The second GetPrinter fills in all the current settings, so all you
 // need to do is modify what you're interested in...
 bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
 if (!bFlag)
 {
  GlobalFree(pi2);
  ClosePrinter(hPrinter);
  return FALSE;
 }

 // If GetPrinter didn't fill in the DEVMODE, try to get it by calling
 // DocumentProperties...
 if (pi2->pDevMode == NULL)
 {
  dwNeeded = DocumentProperties(NULL, hPrinter,
      LPSTR(sPrinterName.operator LPCSTR()),
      NULL, NULL, 0);
  if (dwNeeded <= 0)
  {
   GlobalFree(pi2);
   ClosePrinter(hPrinter);
   return FALSE;
  }

  pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
  if (pDevMode == NULL)
  {
   GlobalFree(pi2);
   ClosePrinter(hPrinter);
   return FALSE;
  }

  lFlag = DocumentProperties(NULL, hPrinter,
      LPSTR(sPrinterName.operator LPCSTR()),
      pDevMode, NULL,
      DM_OUT_BUFFER);
  if (lFlag != IDOK || pDevMode == NULL)
  {
   GlobalFree(pDevMode);
   GlobalFree(pi2);
   ClosePrinter(hPrinter);
   return FALSE;
  }

  pi2->pDevMode = pDevMode;
 }

 // Driver is reporting that it doesn't support this change...
 if (!(pi2->pDevMode->dmFields & DM_ORIENTATION))
 {
  GlobalFree(pi2);
  ClosePrinter(hPrinter);
  if (pDevMode)
   GlobalFree(pDevMode);
  return FALSE;
 }

 // Specify exactly what we are attempting to change...
 switch(dmType)
 {
  case DM_ORIENTATION:
   pi2->pDevMode->dmFields = DM_ORIENTATION;
   pi2->pDevMode->dmOrientation = dmValue;
   break;
  case DM_PAPERSIZE:
   pi2->pDevMode->dmFields = DM_PAPERSIZE;
   pi2->pDevMode->dmPaperSize = dmValue;
   break;
 }

 // Do not attempt to set security descriptor...
 pi2->pSecurityDescriptor = NULL;

 // Make sure the driver-dependent part of devmode is updated...
 lFlag = DocumentProperties(NULL, hPrinter,
    LPSTR(sPrinterName.operator LPCSTR()),
    pi2->pDevMode, pi2->pDevMode,
    DM_IN_BUFFER | DM_OUT_BUFFER);
 if (lFlag != IDOK)
 {
  GlobalFree(pi2);
  ClosePrinter(hPrinter);
  if (pDevMode)
   GlobalFree(pDevMode);
  return FALSE;
 }

 // Update printer information...
 bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
 if (!bFlag)
 // The driver doesn't support, or it is unable to make the change...
 {
  GlobalFree(pi2);
  ClosePrinter(hPrinter);
  if (pDevMode)
   GlobalFree(pDevMode);
  return FALSE;
 }

 // Tell other apps that there was a change...
 SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
     (LPARAM)(LPCSTR)pPrinterName,
     SMTO_NORMAL, 1000, NULL);

 // Clean up...
 if (pi2)
  GlobalFree(pi2);
 if (hPrinter)
  ClosePrinter(hPrinter);
 if (pDevMode)
  GlobalFree(pDevMode);
 
 return S_OK;
}

댓글