Announcement

Collapse
No announcement yet.

Adding Printers and Drivers

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Adding Printers and Drivers

    Can anyone translate this to PB?
    Works great in C++ (Win9x), but can't get it working in PB.

    // AddPrinterDriver.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "windows.h"
    #include "winspool.h"

    int main(int argc, char* argv[])
    {

    PRINTER_INFO_2 pi2;
    DRIVER_INFO_2 di2;
    HANDLE hPrinter;

    ZeroMemory(&di2, sizeof(DRIVER_INFO_2));
    di2.cVersion = 1024;
    di2.pName = "Generic / Text Only";
    di2.pEnvironment = "Windows 4.0";
    di2.pDriverPath = "c:\\windows\\system\\tty.drv";
    di2.pDataFile = "c:\\windows\\system\\tty.drv";
    di2.pConfigFile = "c:\\windows\\system\\tty.drv";

    AddPrinterDriver(NULL, 2, (LPBYTE)&di2);

    ZeroMemory(&pi2, sizeof(PRINTER_INFO_2));
    pi2.pPrinterName = "Receipt";
    pi2.pPortName = "LPT1:";
    pi2.pDriverName = "Generic / Text Only";
    pi2.pPrintProcessor = "WinPrint";
    pi2.pDatatype = "RAW";

    hPrinter = AddPrinter(NULL, 2, (LPBYTE)&pi2);
    ClosePrinter(hPrinter);

    ZeroMemory(&pi2, sizeof(PRINTER_INFO_2));
    pi2.pPrinterName = "License";
    pi2.pPortName = "COM1:";
    pi2.pDriverName = "Generic / Text Only";
    pi2.pPrintProcessor = "WinPrint";
    pi2.pDatatype = "RAW";

    hPrinter = AddPrinter(NULL, 2, (LPBYTE)&pi2);
    ClosePrinter(hPrinter);


    return 0;
    }

  • #2
    This translates quite directly to PowerBASIC. Is there some specific part
    of the translation that is causing you problems?

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Comment


    • #3
      Originally posted by Tom Hanlin:
      This translates quite directly to PowerBASIC. Is there some specific part
      of the translation that is causing you problems?

      Probably the pointers, which are quite simple in C,
      are causing the problem. Is there a good reference somewhere
      on how to translate from C to PB? The Help file is not
      very helpful on this subject.

      Here's one of MANY variations I've tried, most simply do
      nothing, this one causes GPFs...

      #COMPILE EXE
      #INCLUDE "win32api.inc"

      '-- Program entry point
      FUNCTION PBMAIN() AS LONG

      DIM pi2 AS PRINTER_INFO_2
      DIM di2 AS DRIVER_INFO_2
      DIM hPrinter AS LONG
      DIM szNull AS ASCIIZ * 0

      di2.cVersion = 1024
      [email protected] = "Generic / Text Only"
      [email protected] = "Windows 4.0"
      [email protected] = "c:\windows\system\tty.drv"
      [email protected] = "c:\windows\system\tty.drv"
      [email protected] = "c:\windows\system\tty.drv"

      AddPrinterDriver szNull, 2, VARPTR(di2)

      [email protected] = "Receipt"
      [email protected] = "LPT1:"
      [email protected] = "Generic / Text Only"
      [email protected] = "WinPrint"
      [email protected] = "RAW"

      hPrinter = AddPrinter(szNull, 2, VARPTR(pi2))
      ClosePrinter hPrinter

      [email protected] = "License"
      [email protected] = "COM1:"
      [email protected] = "Generic / Text Only"
      [email protected] = "WinPrint"
      [email protected] = "RAW"

      hPrinter = AddPrinter(szNull, 2, VARPTR(pi2))
      ClosePrinter hPrinter

      EXIT FUNCTION

      END FUNCTION




      ------------------

      Comment


      • #4
        [email protected] = "Generic / Text Only" ??!

        Should be:
        Dim pName As Asciiz * 20
        pName = "Generic / Text Only"
        di2.pName = VarPtr(pName)

        and so on.

        szNull also enough funny. Should be ByVal 0& or simply ""

        ------------------
        E-MAIL: [email protected]

        Comment


        • #5
          Originally posted by Semen Matusovski:
          [email protected] = "Generic / Text Only" ??!

          Should be:
          Dim pName As Asciiz * 20
          pName = "Generic / Text Only"
          di2.pName = VarPtr(pName)

          and so on.

          szNull also enough funny. Should be ByVal 0& or simply ""

          Yup, tried all that too. This version doesn't GPF, but doesn't
          add the drivers either... Also, rather inelegant compared to
          the 'C' original, don't you think?

          #COMPILE EXE
          #INCLUDE "win32api.inc"

          '-- Program entry point
          FUNCTION PBMAIN() AS LONG

          DIM pi2 AS PRINTER_INFO_2
          DIM di2 AS DRIVER_INFO_2
          DIM hPrinter AS LONG
          DIM szName AS ASCIIZ * %MAX_PATH
          DIM szEnvironment AS ASCIIZ * %MAX_PATH
          DIM szDriverPath AS ASCIIZ * %MAX_PATH
          DIM szDataFile AS ASCIIZ * %MAX_PATH
          DIM szConfigFile AS ASCIIZ * %MAX_PATH
          DIM szPrinterName AS ASCIIZ * %MAX_PATH
          DIM szPortName AS ASCIIZ * %MAX_PATH
          DIM szDriverName AS ASCIIZ * %MAX_PATH
          DIM szPrintProcessor AS ASCIIZ * %MAX_PATH
          DIM szDataType AS ASCIIZ * %MAX_PATH

          szName = "Generic / Text Only"
          szEnvironment = "Windows 4.0"
          szDriverPath = "c:\windows\system\tty.drv"
          szDataFile = "c:\windows\system\tty.drv"
          szConfigFile = "c:\windows\system\tty.drv"

          di2.cVersion = 1024
          di2.pName = VARPTR(szName)
          di2.pEnvironment = VARPTR(szEnvironment)
          di2.pDriverPath = VARPTR(szDriverPath)
          di2.pDataFile = VARPTR(szDataFile)
          di2.pConfigFile = VARPTR(szConfigFile)

          AddPrinterDriver "", 2, VARPTR(di2)

          szPrinterName = "Receipt"
          szPortName = "LPT1:"
          szDriverName = "Generic / Text Only"
          szPrintProcessor = "WinPrint"
          szDataType = "RAW"

          pi2.pPrinterName = VARPTR(szPrinterName)
          pi2.pPortName = VARPTR(szPortName)
          pi2.pDriverName = VARPTR(szDriverName)
          pi2.pPrintProcessor = VARPTR(szPrintProcessor)
          pi2.pDatatype = VARPTR(szDataType)

          hPrinter = AddPrinter("", 2, VARPTR(pi2))
          ClosePrinter hPrinter

          szPrinterName = "License"

          pi2.pPrinterName = VARPTR(szPrinterName)
          pi2.pPortName = VARPTR(szPortName)
          pi2.pDriverName = VARPTR(szDriverName)
          pi2.pPrintProcessor = VARPTR(szPrintProcessor)
          pi2.pDatatype = VARPTR(szDataType)

          hPrinter = AddPrinter("", 2, VARPTR(pi2))
          ClosePrinter hPrinter

          EXIT FUNCTION

          END FUNCTION




          ------------------

          Comment


          • #6
            I see there's an error in the current AddPrinter and AddPrinterDriver declarations
            in Win32API.inc, which could well be the problem. If you add BYVAL before the
            VARPTR for your parameters, though, it should work properly.

            If that doesn't help, it would be well worth checking the results of the AddPrinter
            and AddPrinterDriver calls to find out where the error is occurring.

            Not as elegant as the C original? Well, the APIs were designed with C in mind, not
            PowerBASIC. Each language has its own strengths. There are many things you can do
            elegantly in PowerBASIC that would be a grim bit of coding in C.


            ------------------
            Tom Hanlin
            PowerBASIC Staff

            Comment


            • #7

              In the Win32Api.Inc AddPrinter is declared

              DECLARE FUNCTION AddPrinter LIB "WINSPOOL.DRV" ALIAS "AddPrinterA"
              (pName AS ASCIIZ, BYVAL Level AS LONG, pPrinter AS BYTE) AS LONG

              MSDN Shows

              HANDLE AddPrinter(
              LPTSTR pName, // server name
              DWORD Level, // printer information level
              LPBYTE pPrinter // printer information buffer
              );

              Note pPrinter is LPBYTE which is a pointer to a byte. A pointer
              is obviously 4 bytes. Change the declaration in your Win32Api.Inc
              to a LONG or DWORD from a BYTE. This may not solve all your
              problem but at least this will call the function correctly.


              ------------------
              Jim..
              [email protected]
              Jim..

              Comment


              • #8
                OK, added BYVAL before VARPTR(di2) and VARPTR(pi2).
                No go.

                Changed the prototype for pPrinter and pDriverInfor in
                Win32Api.inc to LONG.
                No go.

                Added BYVAL again, after change to LONG in Win32Api.inc.
                No go.

                AddPrinterDriver and AddPrinter return 0 in all cases. No GPFs
                in any of the above cases. Even tried changing di2 and pi2 to
                arrays, and using VARPTR(di2(0)), VARPTR(pi2(0)), same thing.

                I'm running out of ideas and patience...




                ------------------

                Comment


                • #9
                  Chuck --
                  1) "Works great in C++ (Win9x)" means that you can run C code on the same PC and it works ?
                  2) tty.drv. Sounds very familar, but for Windows 3.1. What is ir ?

                  ------------------
                  E-MAIL: [email protected]

                  Comment


                  • #10
                    Originally posted by Semen Matusovski:
                    Chuck --
                    1) "Works great in C++ (Win9x)" means that you can run C code on the same PC and it works ?
                    2) tty.drv. Sounds very familar, but for Windows 3.1. What is ir ?

                    1) Yes.
                    2) It's the "Generic / Text Only" printer driver, still there
                    in Win9x, and, so far as I know, Me, NT and 2000.



                    ------------------

                    Comment


                    • #11
                      Try this:
                      Code:
                      #compile exe
                      #register none
                      #dim all
                      #include "win32api.inc"  ' Comment AddPrinterDriver and AddPrinter out
                       
                      DECLARE FUNCTION AddPrinterDriver LIB "WINSPOOL.DRV" ALIAS "AddPrinterDriverA" (pName AS ASCIIZ, BYVAL Level AS LONG, pDriverInfor AS DRIVER_INFO_2) AS LONG
                      DECLARE FUNCTION AddPrinter LIB "WINSPOOL.DRV" ALIAS "AddPrinterA" (pName AS ASCIIZ, BYVAL Level AS LONG, pPrinter AS PRINTER_INFO_2) AS LONG
                       
                      global TEXTMemory() as string
                      function TEXT(byval s as string) as dword
                          static n as long : redim preserve TEXTMemory(n)
                          TEXTMemory(n) = s
                          function = strptr(TEXTMemory(n)) : incr n
                      end function
                       
                      function pbmain
                          
                          local pi2 as PRINTER_INFO_2
                          local di2 as DRIVER_INFO_2
                          local hPrinter as long
                       
                          di2.cVersion = 1024
                          di2.pName = TEXT("Generic / Text Only")
                          di2.pEnvironment = TEXT("Windows 4.0")
                          di2.pDriverPath = TEXT("c:\windows\system\tty.drv")
                          di2.pDataFile = TEXT("c:\windows\system\tty.drv")
                          di2.pConfigFile = TEXT("c:\windows\system\tty.drv")
                       
                          AddPrinterDriver byval %NULL,2, di2
                       
                          pi2.pPrinterName = TEXT("Receipt")
                          pi2.pPortName = TEXT("LPT1:")
                          pi2.pDriverName = TEXT("Generic / Text Only")
                          pi2.pPrintProcessor = TEXT("WinPrint")
                          pi2.pDatatype = TEXT("RAW")
                       
                          hPrinter = AddPrinter(byval %NULL, 2, pi2)
                          ClosePrinter hPrinter
                       
                          pi2.pPrinterName = TEXT("License")
                          pi2.pPortName = TEXT("COM1:")
                          pi2.pDriverName = TEXT("Generic / Text Only")
                          pi2.pPrintProcessor = TEXT("WinPrint")
                          pi2.pDatatype = TEXT("RAW")
                       
                          hPrinter = AddPrinter(byval %NULL, 2, pi2)
                          ClosePrinter hPrinter
                       
                      end function
                      '------------------------------------------
                      Regards
                      Peter


                      ------------------
                      [email protected]
                      www.dreammodel.dk

                      Comment


                      • #12
                        Chuck --
                        I was in Win2000 (BTW, here, unlike 98, I don't see tty even in distributive).

                        Just now I am under Win98 SE. I took your code and added ByVal only.
                        Ran and saw two printers. Ran again - failed.
                        After deleting in "Printers", ran again - works.

                        ------------------
                        E-MAIL: [email protected]

                        Comment


                        • #13
                          Originally posted by Semen Matusovski:
                          Chuck --
                          I was in Win2000 (BTW, here, unlike 98, I don't see tty even in distributive).

                          Just now I am under Win98 SE. I took your code and added ByVal only.
                          Ran and saw two printers. Ran again - failed.
                          After deleting in "Printers", ran again - works.

                          Semen,

                          Thanks, I think I was changing too many things at once. It
                          works now on '95 and '98.

                          Under 2000, MS has a rundll command line to do the same thing.
                          Not sure about NT yet, but will need to investigate.


                          ------------------

                          Comment


                          • #14
                            Semen,

                            Actually, it was my Win32api.inc. When I compiled on my '98,
                            your BYVAL change works fine. When I compile on my '95, it
                            didn't work. Both compiled to 7,168 bytes (C version is
                            24,566!), but there were several differences in the binary.

                            I copied the .inc from my '98 to my '95, and it now compiles
                            and runs fine on both. Don't know (and don't care, at this
                            point) what was wrong with Win32api.inc.

                            Thanks for your help.




                            ------------------

                            Comment


                            • #15
                              OK, here's how to add printer drivers and printers without
                              any user intervention. Tested so far on '95, '98 and NT 3.51,
                              should also work on other x86 platforms.

                              This will be used to install Generic / Text Only drivers on
                              about 3,000 PC's via an internet download, so receipts/journals
                              and labels can be printed from web pages (not HTML, using a
                              defined MIME type to download printer-specific data files).

                              Not asking users to install the drivers manually means no
                              support calls, right?

                              Thanks all for the help...

                              P.S., you will need the updated win32api.inc (dated yesterday).
                              --------------------------------------------------------------

                              #COMPILE EXE
                              #INCLUDE "win32api.inc"

                              '-- Get the application's path
                              FUNCTION AppPath() AS STRING

                              LOCAL TmpAsciiz AS ASCIIZ * %MAX_PATH

                              GetModuleFileName GetModuleHandle(BYVAL 0&), TmpAsciiz, %MAX_PATH

                              FUNCTION = LEFT$(TmpAsciiz, INSTR(-1, TmpAsciiz, "\"))

                              END FUNCTION

                              '-- Program entry point
                              FUNCTION PBMAIN() AS LONG

                              LOCAL osinfo AS OSVERSIONINFO
                              DIM pi2 AS PRINTER_INFO_2
                              DIM di2 AS DRIVER_INFO_2
                              DIM Ret AS LONG
                              DIM lCopied AS LONG
                              DIM hPrinter AS LONG
                              DIM lVersion AS LONG
                              DIM szDriverDirectory AS ASCIIZ * %MAX_PATH
                              DIM szName AS ASCIIZ * %MAX_PATH
                              DIM szEnvironment AS ASCIIZ * %MAX_PATH
                              DIM szDriverPath AS ASCIIZ * %MAX_PATH
                              DIM szDriverFile AS ASCIIZ * %MAX_PATH
                              DIM szHelpFile AS ASCIIZ * %MAX_PATH
                              DIM szDataFile AS ASCIIZ * %MAX_PATH
                              DIM szConfigFile AS ASCIIZ * %MAX_PATH
                              DIM szPrinterName AS ASCIIZ * %MAX_PATH
                              DIM szPortName AS ASCIIZ * %MAX_PATH
                              DIM szDriverName AS ASCIIZ * %MAX_PATH
                              DIM szPrintProcessor AS ASCIIZ * %MAX_PATH
                              DIM szDataType AS ASCIIZ * %MAX_PATH

                              '-- Set current directory to application path
                              CHDRIVE AppPath()
                              CHDIR AppPath()

                              '-- Get the system's Printer Driver Install Directory
                              Ret = GetPrinterDriverDirectory("", "", 1, BYVAL VARPTR(szDriverDirectory), SIZEOF(szDriverDirectory), lCopied)

                              IF Ret = 0 THEN
                              MSGBOX "Error Getting Printer Driver Directory"
                              EXIT FUNCTION
                              END IF

                              '-- Are we on Win32 or NT?
                              osinfo.dwOsVersionInfoSize = SIZEOF(osinfo)
                              Ret = GetVersionEx(osinfo)

                              IF Ret = 0 THEN
                              MSGBOX "Error Getting OS Info"
                              EXIT FUNCTION
                              END IF

                              '-- Set platform-dependent stuff
                              IF osinfo.dwPlatformId = %VER_PLATFORM_WIN32_NT THEN
                              szDriverFile = "rasdd.dll"
                              szHelpFile = "rasddui.hlp"
                              szDataFile = "txtonly.dll"
                              szConfigFile = "rasddui.dll"
                              szEnvironment = "Windows NT x86"
                              lVersion = 2
                              ELSEIF osinfo.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS THEN
                              szDriverFile = "tty.drv"
                              szHelpFile = "tty.hlp"
                              szDataFile = "tty.drv"
                              szConfigFile = "tty.drv"
                              szEnvironment = "Windows 4.0"
                              lVersion = 0
                              ELSE
                              MSGBOX "Unsupported Operating System"
                              EXIT FUNCTION
                              END IF

                              '-- Set driver name and files
                              szName = "Generic / Text Only"
                              szDriverPath = szDriverDirectory & "\" & szDriverFile
                              szDataFile = szDriverDirectory & "\" & szDataFile
                              szConfigFile = szDriverDirectory & "\" & szConfigFile

                              '-- Copy driver and help files from current directory
                              '-- to system's printer driver directory
                              IF DIR$(szDriverPath) = "" THEN
                              FILECOPY szDriverFile, szDriverDirectory & "\" & szDriverFile
                              FILECOPY szHelpFile, szDriverDirectory & "\" & szHelpFile
                              END IF

                              '-- Set DRIVER_INFO_2 values
                              di2.cVersion = lVersion
                              di2.pName = VARPTR(szName)
                              di2.pEnvironment = VARPTR(szEnvironment)
                              di2.pDriverPath = VARPTR(szDriverPath)
                              di2.pDataFile = VARPTR(szDataFile)
                              di2.pConfigFile = VARPTR(szConfigFile)

                              '-- Install the printer driver
                              Ret = AddPrinterDriver("", 2, di2)
                              IF Ret = 0 THEN
                              MSGBOX "Unable to Add Printer Driver"
                              EXIT FUNCTION
                              END IF

                              '-- Set the PRINTER_INFO_2 values
                              '-- for our Receipt printer
                              szPrinterName = "Receipt"
                              szPortName = "LPT1:"
                              szDriverName = "Generic / Text Only"
                              szPrintProcessor = "WinPrint"
                              szDataType = "RAW"

                              pi2.pPrinterName = VARPTR(szPrinterName)
                              pi2.pPortName = VARPTR(szPortName)
                              pi2.pDriverName = VARPTR(szDriverName)
                              pi2.pPrintProcessor = VARPTR(szPrintProcessor)
                              pi2.pDatatype = VARPTR(szDataType)

                              '-- Install the Receipt printer
                              hPrinter = AddPrinter("", 2, pi2)
                              ClosePrinter hPrinter

                              '-- Set the PRINTER_INFO_2 values
                              '-- for our License printer
                              szPrinterName = "License"
                              szPortName = "COM1:"

                              pi2.pPrinterName = VARPTR(szPrinterName)
                              pi2.pPortName = VARPTR(szPortName)
                              pi2.pDriverName = VARPTR(szDriverName)
                              pi2.pPrintProcessor = VARPTR(szPrintProcessor)
                              pi2.pDatatype = VARPTR(szDataType)

                              '-- Install the License printer
                              hPrinter = AddPrinter("", 2, pi2)
                              ClosePrinter hPrinter

                              EXIT FUNCTION

                              END FUNCTION




                              ------------------

                              Comment

                              Working...
                              X