Click here to Skip to main content
15,890,527 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: Summer & Winter time Pin
jan larsen10-Nov-04 23:55
jan larsen10-Nov-04 23:55 
GeneralRe: Summer & Winter time Pin
David Crow11-Nov-04 2:46
David Crow11-Nov-04 2:46 
GeneralRe: Summer & Winter time Pin
Michael Dunn11-Nov-04 11:54
sitebuilderMichael Dunn11-Nov-04 11:54 
Questionhow to compile this sample? Pin
includeh1010-Nov-04 21:26
includeh1010-Nov-04 21:26 
AnswerRe: how to compile this sample? Pin
David Crow11-Nov-04 3:31
David Crow11-Nov-04 3:31 
GeneralWindows Forms Help Pin
Member 213881410-Nov-04 21:03
Member 213881410-Nov-04 21:03 
GeneralRe: Windows Forms Help Pin
pubududilena10-Nov-04 23:25
pubududilena10-Nov-04 23:25 
Questionhow to set a custom paper size on a printer Pin
JP GOBLET10-Nov-04 21:01
JP GOBLET10-Nov-04 21:01 
I work on a cad application, in which users can plot plans on standard paper sizes but also on custom paper sizes.
To select the paper size the user can open a 'Print setup' dialogbox (a windows common dialogbox opened with
CPrintDialog::DoPrintDialog, see code), where he chooses the plotter, paper orientation & paper size.
The 'Print setup' dialogbox has a button 'Properties' that opens the properties dialogbox for the choosen plotter (this dialogbox comes
from the plotter driver). The properties dialogbox allows to define the sizes of the custom papers.

My 1st problem is that after closing the driver properties dialogbox, the 'Print setup' dialogbox does not show the new sizes
for the modified custom paper. So my application is not aware of the new sizes.
The only way i found to use the custom paper sizes is to define them outside of my application, via Start --> Parameters --> Printers.

My 2nd problem is that when one reopens a plan that had been recorded with a specific paper size (the paper ID & dimensions are saved in the plan), the printer must be reset to that paper size, even if the paper format ('custom 1' for example) was modified by another application. In others terms i need to redefine a custom paper size by programmation.

The driver is HP Designjet 750C, version 4.65. I'm using win XP.

The code : i got a lot of it from samples in msdn or others forums; i have poor understanding of it, it's seems to me like an awful garbage, but at least it works as long the user uses standard paper formats (ansi A0, ...). Sorry to insert so much code but there several functions specific to printer handling and i think i have to show it all.


// OnPrinterSetup : where user selects a printer & paper<br />
void CDlgPlan::OnPrinterSetup() <br />
{<br />
  CPrintDialog dlg(TRUE);<br />
  if (AfxGetApp()->DoPrintDialog(&dlg) == IDOK)<br />
  {<br />
    LPDEVMODE pDevMode = dlg.GetDevMode();<br />
    m_strPrinterName = dlg.GetDeviceName();<br />
    SetParamPrinter((const char *)m_strPrinterName, pDevMode->dmOrientation, <br />
                              pDevMode->dmPaperSize, pDevMode->dmPaperLength, pDevMode->dmPaperWidth);<br />
    GetPrinterInfo();<br />
    ::GlobalUnlock(pDevMode);<br />
  }<br />
}<br />
<br />
// SetParamPrinter : select the printer pPrinterName && defines the paper size & orientation<br />
BOOL CDlgPlan::SetParamPrinter(const char *pPrinterName, short dmOrientation, short IDPapier,                                    short paperLength, short paperWidth)<br />
{<br />
                BOOL res;<br />
     PRINTER_INFO_2 *pPrinterInfo;<br />
     DEVMODE *pDevModeTmp;<br />
     HANDLE hPrinter;<br />
     res = GetParamPrinter(pPrinterName, &pPrinterInfo, hPrinter, &pDevModeTmp);<br />
     if (! res)<br />
          goto cleanup;<br />
     // Specify exactly what we are attempting to change...<br />
     pPrinterInfo->pDevMode->dmFields = DM_ORIENTATION|DM_PAPERSIZE|DM_PAPERLENGTH|DM_PAPERWIDTH;<br />
     pPrinterInfo->pDevMode->dmOrientation = dmOrientation;<br />
     pPrinterInfo->pDevMode->dmPaperSize = IDPapier;<br />
     pPrinterInfo->pDevMode->dmPaperLength = paperLength;<br />
     pPrinterInfo->pDevMode->dmPaperWidth = paperWidth;<br />
     // Do not attempt to set security descriptor...<br />
     pPrinterInfo->pSecurityDescriptor = NULL;<br />
<br />
     // Make sure the driver-dependent part of devmode is updated...<br />
     res = ( DocumentProperties(NULL, hPrinter, (char *)pPrinterName, pPrinterInfo->pDevMode, <br />
                                                                      pPrinterInfo->pDevMode, DM_IN_BUFFER|DM_OUT_BUFFER) == IDOK );<br />
     if (! res)<br />
          goto cleanup;<br />
<br />
     // Update printer information...<br />
     res = SetPrinter(hPrinter, 2, (LPBYTE)pPrinterInfo, 0);<br />
     if (! res) // The driver doesn't support, or it is unable to make the change...<br />
         goto cleanup;<br />
<br />
cleanup:<br />
     if (pDevModeTmp)<br />
        GlobalFree(pDevModeTmp);<br />
     if (pPrinterInfo)<br />
       GlobalFree(pPrinterInfo);<br />
     if (hPrinter)<br />
       ClosePrinter(hPrinter);<br />
     return res;<br />
} <br />
<br />
// asks (& stores in the plan) the parameters for the printer m_strPrinterName<br />
void CDlgPlan::GetPrinterInfo()<br />
{<br />
 PRINTER_INFO_2 *pPrinterInfo;<br />
 DEVMODE *pDevModeTmp;<br />
 HANDLE hPrinter;<br />
 CDC DC;<br />
<br />
     if (! GetParamPrinter(m_pVplan->m_strPrinterName, &pPrinterInfo, hPrinter, &pDevModeTmp) )<br />
       goto cleanup;<br />
<br />
// GETTING HERE THE PAPER SIZE IN USE : <br />
     //Create a CDC object according to the current settings.<br />
     DC.CreateDC(pPrinterInfo->pDriverName, pPrinterInfo->pPrinterName, pPrinterInfo->pPortName, pPrinterInfo->pDevMode);<br />
     //Query this CDC object for the width and height of the current page.<br />
     m_lLongPapier = DC.GetDeviceCaps(HORZSIZE); <br />
     m_lHautPapier = DC.GetDeviceCaps(VERTSIZE) ;<br />
     m_pVplan->m_f.paperLength = m_lLongPapier * 10; // paperLength in .1 mm units<br />
     m_pVplan->m_f.paperWidth = m_lHautPapier * 10;<br />
     DC.DeleteDC();<br />
     m_pVplan->m_f.IDFormat = pPrinterInfo->pDevMode->dmPaperSize;<br />
     m_pVplan->m_f.Bits.bPaysage = (pPrinterInfo->pDevMode->dmOrientation == DMORIENT_LANDSCAPE);<br />
     m_pVplan->m_f.Bits.typePaper = m_typePaper;<br />
<br />
cleanup:<br />
               if (pDevModeTmp)<br />
          GlobalFree(pDevModeTmp);<br />
     if (pPrinterInfo)<br />
          GlobalFree(pPrinterInfo);<br />
     if (hPrinter)<br />
          ClosePrinter(hPrinter);<br />
}     <br />
<br />
// GetParamPrinter : creates  and fills struct PRINTER_INFO_2<br />
BOOL CDlgPlan::GetParamPrinter(const char *pPrinterName, PRINTER_INFO_2 **ppPrinterInfo,                                         HANDLE &hPrinter, DEVMODE **ppDevModeTmp)<br />
{<br />
     DWORD dwSizePrinterInfo = 0;<br />
     PRINTER_DEFAULTS pd;<br />
     BOOL bFlag;<br />
     LONG lFlag;<br />
<br />
     hPrinter = NULL;<br />
     *ppPrinterInfo = NULL;<br />
     *ppDevModeTmp = NULL;<br />
<br />
     // Open printer handle (on Windows NT, you need full-access because you will eventually use SetPrinter)...<br />
     ZeroMemory(&pd, sizeof(pd));<br />
     pd.DesiredAccess = PRINTER_ALL_ACCESS; //PRINTER_ACCESS_USE; <br />
     if (! OpenPrinter((char *)pPrinterName, &hPrinter, &pd) || hPrinter == NULL)<br />
          return FALSE;<br />
     // The first GetPrinter tells you how big the buffer should be in <br />
     // order to hold all of PRINTER_INFO_2. Note that this should fail with <br />
     // ERROR_INSUFFICIENT_BUFFER.  If GetPrinter fails for any other reason <br />
     // or dwNeeded isn't set for some reason, then there is a problem...<br />
     SetLastError(0);<br />
     bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwSizePrinterInfo);<br />
  if ( ! bFlag && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwSizePrinterInfo == 0))<br />
          return FALSE;<br />
<br />
     // Allocate enough space for PRINTER_INFO_2...<br />
     *ppPrinterInfo = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwSizePrinterInfo);<br />
     if (*ppPrinterInfo == NULL)<br />
          return FALSE;<br />
     // The second GetPrinter fills in all the current settings, so all you<br />
     // need to do is modify what you're interested in...<br />
     if (! GetPrinter(hPrinter, 2, (LPBYTE)*ppPrinterInfo, dwSizePrinterInfo, &dwSizePrinterInfo) )<br />
          return FALSE;<br />
     <br />
     // If GetPrinter didn't fill in the DEVMODE, try to get it by calling DocumentProperties...<br />
     if ((*ppPrinterInfo)->pDevMode == NULL)<br />
     {<br />
          long dwNeeded = DocumentProperties(NULL, hPrinter, (char *)pPrinterName,NULL, NULL, 0);<br />
          if (dwNeeded <= 0)<br />
               return FALSE;<br />
          *ppDevModeTmp = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);<br />
          if (*ppDevModeTmp == NULL)<br />
               return FALSE;<br />
          lFlag = DocumentProperties(NULL, hPrinter, (char *)pPrinterName, *ppDevModeTmp, NULL, DM_OUT_BUFFER);<br />
          if (lFlag != IDOK || *ppDevModeTmp == NULL)<br />
               return FALSE;<br />
          (*ppPrinterInfo)->pDevMode = *ppDevModeTmp;<br />
     }<br />
     return TRUE;<br />
}<br />
<br />
// returns a DEVMODE and DEVNAMES for the printer name specified<br />
BOOL CDlgPlan::GetPrinterDevice(const char * pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)<br />
{<br />
  // if NULL is passed, then assume we are setting app object's devmode and devnames<br />
     if (phDevMode == NULL || phDevNames == NULL)<br />
          return FALSE;<br />
<br />
     BOOL res;<br />
     PRINTER_INFO_2 *pPrinterInfo;<br />
     DEVMODE *pDevModeTmp;<br />
     HANDLE hPrinter;<br />
     long tcOffset, size, drvNameLen, ptrNameLen, porNameLen;<br />
     HGLOBAL hDevMode, hDevNames;<br />
     DEVNAMES* pDevNames;<br />
     DEVMODE* pDevMode;<br />
  <br />
     res = GetParamPrinter(pszPrinterName, &pPrinterInfo, hPrinter, &pDevModeTmp);<br />
     if (! res)<br />
          goto cleanup;<br />
<br />
   // Allocate a global handle for DEVMODE<br />
     size = sizeof(*pPrinterInfo->pDevMode) + pPrinterInfo->pDevMode->dmDriverExtra;<br />
     hDevMode = GlobalAlloc(GHND, size);<br />
     ASSERT(hDevMode);<br />
     pDevMode = (DEVMODE*)GlobalLock(hDevMode);<br />
     ASSERT(pDevMode);<br />
<br />
     // copy DEVMODE data from PRINTER_INFO_2::pDevMode<br />
     memcpy(pDevMode, pPrinterInfo->pDevMode, size);<br />
     GlobalUnlock(hDevMode);<br />
<br />
     // Compute size of DEVNAMES structure from PRINTER_INFO_2's data<br />
     drvNameLen = lstrlen(pPrinterInfo->pDriverName) + 1;  // driver name<br />
     ptrNameLen = lstrlen(pPrinterInfo->pPrinterName) + 1; // printer name<br />
     porNameLen = lstrlen(pPrinterInfo->pPortName) + 1;    // port name<br />
<br />
     // Allocate a global handle big enough to hold DEVNAMES.<br />
     hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) + (drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR));<br />
     ASSERT(hDevNames);<br />
     pDevNames = (DEVNAMES*)GlobalLock(hDevNames);<br />
     ASSERT(pDevNames);<br />
<br />
     // Copy the DEVNAMES information from PRINTER_INFO_2<br />
     // tcOffset = TCHAR Offset into structure<br />
     tcOffset = sizeof(DEVNAMES)/sizeof(TCHAR);<br />
     ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));<br />
<br />
     pDevNames->wDriverOffset = (int)tcOffset;<br />
     memcpy((LPTSTR)pDevNames + tcOffset, pPrinterInfo->pDriverName, drvNameLen*sizeof(TCHAR));<br />
     tcOffset += drvNameLen;<br />
<br />
     pDevNames->wDeviceOffset = (int)tcOffset;<br />
     memcpy((LPTSTR)pDevNames + tcOffset, pPrinterInfo->pPrinterName, ptrNameLen*sizeof(TCHAR));<br />
     tcOffset += ptrNameLen;<br />
<br />
     pDevNames->wOutputOffset = (int)tcOffset;<br />
     memcpy((LPTSTR)pDevNames + tcOffset, pPrinterInfo->pPortName, porNameLen*sizeof(TCHAR));<br />
     pDevNames->wDefault = 0;<br />
<br />
     GlobalUnlock(hDevNames);<br />
<br />
     // set the new hDevMode and hDevNames<br />
     *phDevMode = hDevMode;<br />
     *phDevNames = hDevNames;<br />
<br />
     cleanup:<br />
          if (pDevModeTmp)<br />
          GlobalFree(pDevModeTmp);<br />
     if (pPrinterInfo)<br />
          GlobalFree(pPrinterInfo);<br />
     if (hPrinter)<br />
          ClosePrinter(hPrinter);<br />
<br />
     return res;<br />
} <br />
<br />
// the code i use when a plan (m_pVplan) is reopened, for setting the printer and paper :<br />
<br />
HGLOBAL hDevMode = NULL;<br />
HGLOBAL hDevNames = NULL;<br />
GetPrinterDevice(m_strPrinterName, &hDevNames, &hDevMode);<br />
AfxGetApp()->SelectPrinter(hDevNames, hDevMode);<br />
SetParamPrinter(m_strPrinterName,                                                                 (short)m_pVplan->m_f.Bits.bPaysage ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT,                                  (short)m_pVplan->m_f.IDFormat,                                                          (short)m_pVplan->m_f.paperLength, (short)m_pVplan->m_f.paperWidth);

GeneralPlease Help-Device Driver Development in VC++ Pin
Mirza Faizan10-Nov-04 20:57
Mirza Faizan10-Nov-04 20:57 
GeneralRemote Desktop Access Pin
Anshul Mehra10-Nov-04 20:15
professionalAnshul Mehra10-Nov-04 20:15 
GeneralTiling jpeg as dialog backgroung Pin
Tariq87810-Nov-04 19:43
Tariq87810-Nov-04 19:43 
GeneralRe: Tiling jpeg as dialog backgroung Pin
ThatsAlok10-Nov-04 22:06
ThatsAlok10-Nov-04 22:06 
Generalpointer to function from its name Pin
fickdb10-Nov-04 18:16
fickdb10-Nov-04 18:16 
Generaltake alook Pin
Anonymous10-Nov-04 19:47
Anonymous10-Nov-04 19:47 
GeneralRe: take alook Pin
fickdb11-Nov-04 4:42
fickdb11-Nov-04 4:42 
GeneralRe: pointer to function from its name Pin
jan larsen10-Nov-04 23:47
jan larsen10-Nov-04 23:47 
GeneralRe: pointer to function from its name Pin
fickdb11-Nov-04 4:46
fickdb11-Nov-04 4:46 
GeneralRe: Templates? Pin
Budric B.11-Nov-04 5:45
Budric B.11-Nov-04 5:45 
GeneralRe: Templates? Pin
fickdb11-Nov-04 6:59
fickdb11-Nov-04 6:59 
GeneralRe: pointer to function from its name Pin
jan larsen12-Nov-04 0:21
jan larsen12-Nov-04 0:21 
GeneralSolution ? Seems to work ;) Pin
fickdb12-Nov-04 0:49
fickdb12-Nov-04 0:49 
GeneralRe: Solution ? Seems to work ;) Pin
Anonymous12-Nov-04 10:22
Anonymous12-Nov-04 10:22 
GeneralCreating Dialog Based Application which takes Paramters as input. Pin
Anonymous10-Nov-04 17:52
Anonymous10-Nov-04 17:52 
GeneralRe: Creating Dialog Based Application which takes Paramters as input. Pin
Kapoor Vikrant11-Nov-04 0:39
Kapoor Vikrant11-Nov-04 0:39 
QuestionHow to do Insert ,delete actions in SQL Database using C++? Pin
pubududilena10-Nov-04 17:18
pubududilena10-Nov-04 17:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.