• Welcome to PlanetSquires Forums.
 

Problem with CPrint.Chooseprinter and proposed solution

Started by philbar, September 08, 2021, 12:07:00 PM

Previous topic - Next topic

philbar

When you use ChoosePrinter to select a printer and then GetPrinterName to retrieve its name, the name is truncated to 30 characters. It prevents the user from selecting the right printer for a specific job and then saving the name in an INI file so it can be attached automatically the next time the program runs. Yes, we have printers with names like "Ricoh Aficio SP8200DN PCL6 (Accounting)".

I ran into the same problem a few years ago using a Fortran framework.

The DEVMODEW member of the printer dialog setup structure has a printer name that is a fixed string of 32 wide characters. Fortunately, the setup structure also points to a DEVNAMES structure that receives the printer name unrestricted. The following change to the ChoosePrinter function makes the problem go away, for me:


PRIVATE FUNCTION CPrint.ChoosePrinter (BYVAL hwndOwner AS HWND = NULL) AS BOOLEAN
   DIM pd AS PRINTDLGW
   pd.lStructSize = SIZEOF(pd)
   pd.hwndOwner = hwndOwner
   pd.flags = PD_RETURNDC OR PD_HIDEPRINTTOFILE OR PD_DISABLEPRINTTOFILE OR PD_NOSELECTION OR PD_NOPAGENUMS
   IF PrintDlgW(@pd) THEN
      IF pd.hDevMode THEN
         '*** Delete these lines ***
         ' DIM pdm AS DEVMODEW PTR = GlobalLock(pd.hDevMode)
         ' IF pdm THEN
            ' m_wszPrinterName = pdm->dmDeviceName
            ' GlobalUnlock(pd.hDevMode)
         ' END IF
         '****
         GlobalFree(pd.hDevMode)
      END IF
      IF pd.hDevNames THEN
         '*** Add these
         dim as wstring ptr pname                                             '*********
         dim as devnames ptr pdn                                             '*********

         pdn = globallock(pd.hdevnames)                                    '*********
         pname = cast(wstring ptr, pdn) +  pdn->wdeviceoffset      '*********
         m_wszprintername = *pname                                        '*********
         globalunlock(pd.hdevnames)                                         '*********
         '****
         GlobalFree(pd.hDevNames)
      end if
      IF m_hDC THEN DeleteDC m_hDC
      m_hDC = pd.hDC
      RETURN TRUE
   END IF
   RETURN FALSE
END FUNCTION


Maybe that will save somebody else some head-scratching.

José Roca