PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Problem with CPrint.Chooseprinter and proposed solution  (Read 515 times)

philbar

  • Little Newbie
  • *
  • Posts: 31
Problem with CPrint.Chooseprinter and proposed solution
« on: September 08, 2021, 12:07:00 PM »

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:

Code: [Select]
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.
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3341
Re: Problem with CPrint.Chooseprinter and proposed solution
« Reply #1 on: February 28, 2022, 03:57:54 PM »

Modified. Thanks very much for your code.