gusucode.com > VC++打印编程的实用例子源码程序 > VC++打印编程的实用例子源码程序/code/CustomPrinter.cpp

    // CustomPrinter.cpp : Implementation of CCustomPrinter
#include "stdafx.h"
#include "SetPrinter.h"
#include "CustomPrinter.h"
#include "winspool.h"



// Size of internal buffer used to hold "printername,drivername,portname"
// string. Increasing this may be necessary for huge strings.
#define MAXBUFFERSIZE 250

/*----------------------------------------------------------------*/ 
/* DPGetDefaultPrinter                                            */ 
/*                                                                */ 
/* Parameters:                                                    */ 
/*   pPrinterName: Buffer alloc'd by caller to hold printer name. */ 
/*   pdwBufferSize: On input, ptr to size of pPrinterName.        */ 
/*          On output, min required size of pPrinterName.         */ 
/*                                                                */ 
/* NOTE: You must include enough space for the NULL terminator!   */ 
/*                                                                */ 
/* Returns: TRUE for success, FALSE for failure.                  */ 
/*----------------------------------------------------------------*/ 
STDMETHODIMP CCustomPrinter::DPGetDefaultPrinter(BSTR *pPrinterName, long *pdwBufferSize, int *Result)
{

USES_CONVERSION;

char* pPrinterNameLocal = (char*)OLE2CA(*pPrinterName);

  BOOL bFlag;
  OSVERSIONINFO osv;
  TCHAR cBuffer[MAXBUFFERSIZE];
  PRINTER_INFO_2 *ppi2 = NULL;
  DWORD dwNeeded = 0;
  DWORD dwReturned = 0;
  
  // What version of Windows are you running?
  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx(&osv);
  
  // If Windows 95 or 98, use EnumPrinters...
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  {
    // The first EnumPrinters() tells you how big our buffer should
    // be in order to hold ALL of PRINTER_INFO_2. Note that this will
    // usually return FALSE. This only means that the buffer (the 4th
    // parameter) was not filled in. You don't want it filled in here...
    EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0, &dwNeeded, &dwReturned);
    if (dwNeeded == 0) 
      *Result = 0;
	  return S_FALSE;
	
		
    
    // Allocate enough space for PRINTER_INFO_2...
    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
    if (!ppi2)
      *Result = 0;
	  return S_FALSE;
    
    // The second EnumPrinters() will fill in all the current information...
    bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded, &dwReturned);
    if (!bFlag)
    {
      GlobalFree(ppi2);
      *Result = 0;
	  return S_FALSE;
    }
    
    // If given buffer too small, set required size and fail...
    if ((DWORD)lstrlen(ppi2->pPrinterName) >= *pdwBufferSize)
    {
      *pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;
      GlobalFree(ppi2);
      *Result = 0;
	  return S_FALSE;
    }
    
    // Copy printer name into passed-in buffer...
    //lstrcpy(pPrinterName, ppi2->pPrinterName);
    *pPrinterName = A2W(ppi2->pPrinterName);

    // Set buffer size parameter to min required buffer size...
    *pdwBufferSize = (long)lstrlen(ppi2->pPrinterName) + 1;
  }
  
  // If Windows NT, use the GetDefaultPrinter API for Windows 2000,
  // or GetProfileString for version 4.0 and earlier...
  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
  {
#if(WINVER >= 0x0500)
    if (osv.dwMajorVersion >= 5) // Windows 2000 or later
    {
      bFlag = GetDefaultPrinter(pPrinterName, pdwBufferSize);
      if (!bFlag)
        *Result = 0;
		return S_FALSE;
    }
    
    else // NT4.0 or earlier
#endif
    {
      // Retrieve the default string from Win.ini (the registry).
      // String will be in form "printername,drivername,portname".
      if (GetProfileString("windows", "device", ",,,", cBuffer, MAXBUFFERSIZE) <= 0)
        *Result = 0;
		return S_FALSE;
      
      // Printer name precedes first "," character...
      strtok(cBuffer, ",");
      
      // If given buffer too small, set required size and fail...
      if ((DWORD)lstrlen(cBuffer) >= *pdwBufferSize)
      {
        *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
        *Result = 0;
		return S_FALSE;
      }
      
      // Copy printer name into passed-in buffer...
      //lstrcpy(pPrinterName, cBuffer);
      *pPrinterName = A2W(cBuffer);


      // Set buffer size parameter to min required buffer size...
      *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
    }
  }
  
  // Cleanup...
  if (ppi2)
    GlobalFree(ppi2);
  
*Result = 1;
return S_OK;
}


#undef MAXBUFFERSIZE


/*-----------------------------------------------------------------*/ 
/* DPSetDefaultPrinter                                             */ 
/*                                                                 */ 
/* Parameters:                                                     */ 
/*   pPrinterName: Valid name of existing printer to make default. */ 
/*                                                                 */ 
/* Returns: TRUE for success, FALSE for failure.                   */ 
/*-----------------------------------------------------------------*/ 
STDMETHODIMP CCustomPrinter::DPSetDefaultPrinter(BSTR pPrinterName, int *Result)
{

USES_CONVERSION;

  BOOL bFlag;
  OSVERSIONINFO osv;
  DWORD dwNeeded = 0;
  HANDLE hPrinter = NULL;
  PRINTER_INFO_2 *ppi2 = NULL;
  LPTSTR pBuffer = NULL;
  LONG lResult;
  
  // What version of Windows are you running?
  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx(&osv);
  
  if (!pPrinterName)
	*Result = 0;
	return S_FALSE;  
  // If Windows 95 or 98, use SetPrinter...
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  {
    // Open this printer so you can get information about it...
    bFlag = OpenPrinter((char*)OLE2CA(pPrinterName), &hPrinter, NULL);
    if (!bFlag || !hPrinter)
		*Result = 0;
		return S_FALSE;    
    // The first GetPrinter() tells you how big our buffer should
    // be in order to hold ALL of PRINTER_INFO_2. Note that this will
    // usually return FALSE. This only means that the buffer (the 3rd
    // parameter) was not filled in. You don't want it filled in here...
    GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
    if (dwNeeded == 0)
    {
      ClosePrinter(hPrinter);
      *Result = 0;
	  return S_FALSE;
    }
    
    // Allocate enough space for PRINTER_INFO_2...
    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
    if (!ppi2)
    {
      ClosePrinter(hPrinter);
      *Result = 0;
	  return S_FALSE;
    }
    
    // The second GetPrinter() will fill in all the current information
    // so that all you need to do is modify what you're interested in...
    bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
    if (!bFlag)
    {
      ClosePrinter(hPrinter);
      GlobalFree(ppi2);
      *Result = 0;
	  return S_FALSE;
    }
    
    // Set default printer attribute for this printer...
    ppi2->Attributes |= PRINTER_ATTRIBUTE_DEFAULT;
    bFlag = SetPrinter(hPrinter, 2, (LPBYTE)ppi2, 0);
    if (!bFlag)
    {
      ClosePrinter(hPrinter);
      GlobalFree(ppi2);
      *Result = 0;
	  return S_FALSE;
    }
    
    // Tell all open applications that this change occurred. 
    // Allow each application 1 second to handle this message.
    lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L,
      (LPARAM)(LPCTSTR)"windows", SMTO_NORMAL, 1000, NULL);
  }
  
  // If Windows NT, use the SetDefaultPrinter API for Windows 2000,
  // or WriteProfileString for version 4.0 and earlier...
  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
  {
#if(WINVER >= 0x0500)
    if (osv.dwMajorVersion >= 5) // Windows 2000 or later...
    {
      bFlag = SetDefaultPrinter(pPrinterName);
      if (!bFlag)
        *Result = 0;
		return S_FALSE;
    }
    
    else // NT4.0 or earlier...
#endif
    {
      // Open this printer so you can get information about it...
      bFlag = OpenPrinter((char*)OLE2CA(pPrinterName), &hPrinter, NULL);
      if (!bFlag || !hPrinter)
        *Result = 0;
		return S_FALSE;
      
      // The first GetPrinter() tells you how big our buffer should
      // be in order to hold ALL of PRINTER_INFO_2. Note that this will
      // usually return FALSE. This only means that the buffer (the 3rd
      // parameter) was not filled in. You don't want it filled in here...
      GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
      if (dwNeeded == 0)
      {
        ClosePrinter(hPrinter);
        *Result = 0;
		return S_FALSE;
      }
      
      // Allocate enough space for PRINTER_INFO_2...
      ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
      if (!ppi2)
      {
        ClosePrinter(hPrinter);
        *Result = 0;
		return S_FALSE;
      }
      
      // The second GetPrinter() fills in all the current<BR/>
      // information...
      bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
      if ((!bFlag) || (!ppi2->pDriverName) || (!ppi2->pPortName))
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
        *Result = 0;
		return S_FALSE;
      }
      
      // Allocate buffer big enough for concatenated string.
      // String will be in form "printername,drivername,portname"...
      pBuffer = (LPTSTR)GlobalAlloc(GPTR,
        lstrlen((char*)OLE2CA(pPrinterName)) +
        lstrlen(ppi2->pDriverName) +
        lstrlen(ppi2->pPortName) + 3);
      if (!pBuffer)
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
		*Result = 0;
		return S_FALSE;
      }
      
      // Build string in form "printername,drivername,portname"...
      lstrcpy(pBuffer, (char*)OLE2CA(pPrinterName));  lstrcat(pBuffer, ",");
      lstrcat(pBuffer, ppi2->pDriverName);  lstrcat(pBuffer, ",");
      lstrcat(pBuffer, ppi2->pPortName);
      
      // Set the default printer in Win.ini and registry...
      bFlag = WriteProfileString("windows", "device", pBuffer);
      if (!bFlag)
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
        GlobalFree(pBuffer);
        *Result = 0;
		return S_FALSE;
      }
    }
    
    // Tell all open applications that this change occurred. 
    // Allow each app 1 second to handle this message.
    lResult = SendMessageTimeout(HWND_BROADCAST, 
								 WM_SETTINGCHANGE, 
								 0L, 0L,
								 SMTO_NORMAL, 
								 1000, 
								 NULL);
  }
  
  // Cleanup...
  if (hPrinter)
    ClosePrinter(hPrinter);
  if (ppi2)
    GlobalFree(ppi2);
  if (pBuffer)
    GlobalFree(pBuffer);
  
*Result = 1;
return S_OK;

}