YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET

 


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


MFC VC++ Topics: Getting the location of a printer device
By Dan Pilat. 
Getting the locate of a printer device.

 

Introduction

If you want to get the location ('Printer room, second floor') of a printer device, you won't find it in the DEVMODE or DEVNAMES structure - you must use the Windows printer API. To make it easier to get, I've wrapped the printer API in a class called GPrinter:

 Collapse

///////////////////////////////////////////////////////////////////////////
// wrapper class for the printer API...

class GPrinter 
{
public:
   GPrinter();

   // open a printer with the name 'lpszPrinterName'
   BOOL Open(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS *lpDefaults=NULL);
   // get various types of printer info    
   // pInfo is good for the lifetime of the class,
   // or until the next call to Get(),
   // whichever comes first
   BOOL Get(PRINTER_INFO_1 *pInfo);
   BOOL Get(PRINTER_INFO_2 *pInfo);
   BOOL Get(PRINTER_INFO_3 *pInfo);
   BOOL Get(PRINTER_INFO_4 *pInfo);
   BOOL Get(PRINTER_INFO_5 *pInfo);
   BOOL Get(PRINTER_INFO_7 *pInfo);
   // set to TRUE to turn off message box reporting of errors
   void SetSilent(BOOL bSilent=TRUE);
   // handy operator to return printer object handle
   operator HANDLE() const {return m_hPrinter;}

protected:
   BOOL Get(int nLevel, LPBYTE lpBuf, int nBufSize);

   HANDLE m_hPrinter;      // handle to the printer object
   LPBYTE m_lpGetInfoBuf;  // temporary buffer
   BOOL m_bSilent;         // silent mode flag

public:
   // closes the open printer object
   void Close();

   virtual ~GPrinter();
};

In order to use this class, you must first get the name of the printer from the DEVNAMES structure. In the image above, the name would be 'HP LaserJet 5P'. Use that name to call the GPrinter::Open() function. From there, you can use any of the API wrapper functions. Currently, it wraps only one function, ::GetPrinter(), with a series of overloaded Get() functions, each taking a specific type of PRINTER_INFO_* struct. There is some information overlap between the seven different types of structs - I use PRINTER_INFO_2 to get the printer location:

// Given a DEVNAMES handle, this function will display the device location
void DisplayLocation(HANDLE hDevNames)
{
   LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(hDevNames);
   LPCTSTR lpszDevice = (LPCTSTR)lpDev + lpDev->wDriverOffset;

   GPrinter prn;
   prn.SetSilent();

   if(prn.Open(lpszDevice))
   {
      PRINTER_INFO_2 prnInfo;
      if(prn.Get(&prnInfo) && prnInfo.pLocation)
      {
         // display the location
         AfxMessageBox(prnInfo.pLocation);
      }

      // you can call Close() here, but the destructor will do that for you
   }

   ::GlobalUnlock(hDevNames);
}

Use the GPrinter::SetSilent() function to turn off the display of error messages. There are more printer API functions which can be added to this class that I never got around to wrapping - feel free to add them. Here is the implementation for this class:

Collapse

///////////////////////////////////////////////////////////////////////////
// first define helper function to display error messages

BOOL ReportLastError()
{
   LPVOID lpMsgBuf = NULL;

   BOOL bFormat = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
               FORMAT_MESSAGE_FROM_SYSTEM,
               NULL, GetLastError(), 
               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
               (LPTSTR) &lpMsgBuf, 0, NULL);

   if(bFormat && lpMsgBuf)
   {
      AfxMessageBox((LPCTSTR)lpMsgBuf);
      LocalFree(lpMsgBuf);
   }

   return bFormat;
}

///////////////////////////////////////////////////////////////////////////
// GPrinter Implementation

GPrinter::GPrinter()
{
   m_hPrinter = NULL;
   m_lpGetInfoBuf = NULL;
   m_bSilent = FALSE;
}


GPrinter::~GPrinter()
{
   Close();
}


void GPrinter::SetSilent(BOOL bSilent)
{
   m_bSilent = bSilent;
}


BOOL GPrinter::Open(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS *lpDefaults)
{
   // it should be closed!
   ASSERT(!m_hPrinter);
   BOOL bOpen = ::OpenPrinter((char *)lpszPrinterName, 
                    &m_hPrinter, lpDefaults);  // i18nOk
   if(!bOpen && !m_bSilent)
      ReportLastError();

   return bOpen;
}


void GPrinter::Close()
{
   if(m_hPrinter)
   {
      ::ClosePrinter(m_hPrinter);
      m_hPrinter = NULL;
   }

   if(m_lpGetInfoBuf)
   {
      ::GlobalFree(m_lpGetInfoBuf);
      m_lpGetInfoBuf = NULL;
   }
}


BOOL GPrinter::Get(PRINTER_INFO_1 *pInfo)
{
   return Get(1, (LPBYTE)pInfo, sizeof(*pInfo));
}

BOOL GPrinter::Get(PRINTER_INFO_2 *pInfo)
{
   return Get(2, (LPBYTE)pInfo, sizeof(*pInfo));
}

BOOL GPrinter::Get(PRINTER_INFO_3 *pInfo)
{
   return Get(3, (LPBYTE)pInfo, sizeof(*pInfo));
}

BOOL GPrinter::Get(PRINTER_INFO_4 *pInfo)
{
   return Get(4, (LPBYTE)pInfo, sizeof(*pInfo));
}

BOOL GPrinter::Get(PRINTER_INFO_5 *pInfo)
{
   return Get(5, (LPBYTE)pInfo, sizeof(*pInfo));
}

BOOL GPrinter::Get(PRINTER_INFO_7 *pInfo)
{
   return Get(7, (LPBYTE)pInfo, sizeof(*pInfo));
}


BOOL GPrinter::Get(int nLevel, LPBYTE lpBuf, int nBufSize)
{
   if(m_lpGetInfoBuf)
   {
      ::GlobalFree(m_lpGetInfoBuf);
      m_lpGetInfoBuf = NULL;
   }

   DWORD dwBytesReturned;
   DWORD dwBytesNeeded;

   ::GetPrinter(m_hPrinter, nLevel, NULL, 0, &dwBytesNeeded);
   m_lpGetInfoBuf = (LPBYTE)GlobalAlloc(GPTR, dwBytesNeeded);
   
   BOOL bGet = ::GetPrinter(m_hPrinter, nLevel, 
       m_lpGetInfoBuf, dwBytesNeeded, &dwBytesReturned);
   if(bGet)
      memcpy(lpBuf, m_lpGetInfoBuf, nBufSize); // i18nOk
   else
   if(!m_bSilent)
      ReportLastError();

   return bGet;
}

 

 

Copyright ?1998-2022 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net