Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Installing Printer Programatically
Message
From
20/05/2005 14:54:18
 
 
To
20/05/2005 10:53:07
Moacyr Zalcman
Independent Consultant
São Paulo, Brazil
General information
Forum:
Visual FoxPro
Category:
Installation, Setup and Configuration
Environment versions
Visual FoxPro:
VFP 7 SP1
OS:
Windows 2000 SP2
Network:
Windows NT
Database:
Visual FoxPro
Miscellaneous
Thread ID:
01016204
Message ID:
01016316
Views:
61
I don't remember where I got this originally:
*|typedef struct _PRINTER_INFO_2 {
*| LPTSTR pServerName; 0:4
*| LPTSTR pPrinterName; 4:4
*| LPTSTR pShareName; 8:4
*| LPTSTR pPortName; 12:4
*| LPTSTR pDriverName; 16:4
*| LPTSTR pComment; 20:4
*| LPTSTR pLocation; 24:4
*| LPDEVMODE pDevMode; 28:4
*| LPTSTR pSepFile; 32:4
*| LPTSTR pPrintProcessor; 36:4
*| LPTSTR pDatatype; 40:4
*| LPTSTR pParameters; 44:4
*| PSECURITY_DESCRIPTOR pSecDesc; 48:4
*| DWORD Attributes; 52:4
*| DWORD Priority; 56:4
*| DWORD DefaultPriority; 60:4
*| DWORD StartTime; 64:4
*| DWORD UntilTime; 68:4
*| DWORD Status; 72:4
*| DWORD cJobs; 76:4
*| DWORD AveragePPM; 80:4
*|} PRINTER_INFO_2, *PPRINTER_INFO_2; 84 bytes

* Here's the Win32 function we want to call:
DECLARE INTEGER AddPrinter IN winspool.drv;
        STRING pName, INTEGER Level, STRING @pPrinter

* Other needed Win32's
    DECLARE INTEGER GetLastError IN kernel32
    DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter

LOCAL lcInfoBuffer, hPrinter, lcSrvName, lcPrnName, lcDrvName
lcPrnName = "My Printer Name"
lcDrvName = "Generic / Text Only"

* empty server name means local computer
* or put existing server name like "\\MYSERV"
* Win9/Me: should be empty, can only install local printers
lcSrvName = ""

* MSDN: You must specify non-NULL values for the pPrinterName,
* pPortName, pDriverName, and pPrintProcessor members of
* this structure before calling AddPrinter.

LOCAL loSrvName, loPrnName, loPortName, loDrvName, loPrnProc
loSrvName = CreateObject("PChar", lcSrvName)
loPrnName = CreateObject("PChar", lcPrnName)
loPortName = CreateObject("PChar", "LPT1:")
loDrvName = CreateObject("PChar", lcDrvName)
loPrnProc = CreateObject("PChar", "WinPrint")

* filling PRINTER_INFO_2 structure
lcInfoBuffer = num2dword(loSrvName.GetAddr()) +;
    num2dword(loPrnName.GetAddr()) + num2dword(0) +;
    num2dword(loPortName.GetAddr()) +;
    num2dword(loDrvName.GetAddr()) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) +;
    num2dword(loPrnProc.GetAddr()) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0) + num2dword(0) +;
    num2dword(0)

hPrinter = AddPrinter(lcSrvName, 2, @lcInfoBuffer)
IF hPrinter = 0
* 1795 - ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
* 1796 - ERROR_UNKNOWN_PORT
* 1797 - ERROR_UNKNOWN_PRINTER_DRIVER
* 1798 - ERROR_UNKNOWN_PRINTPROCESSOR
* 1801 - ERROR_INVALID_PRINTER_NAME
* 1802 - ERROR_PRINTER_ALREADY_EXISTS
    ? "Error code:", GetLastError()
ELSE
    ? "Handle to a new printer object:", hPrinter
    = ClosePrinter(hPrinter)
ENDIF

***** end of main code ********

* Function & class follow that ease dealing with Win32 data types:

FUNCTION num2dword (lnValue)
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
    LOCAL b0, b1, b2, b3
    b3 = Int(lnValue/m2)
    b2 = Int((lnValue - b3*m2)/m1)
    b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
    b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)

* * * * * * * * * * * * * * * * * * * * * * * *
DEFINE CLASS PChar As Custom
    PROTECTED hMem

PROCEDURE Init (lcString)
    THIS.hMem = 0
    THIS.setValue (lcString)

PROCEDURE Destroy
    THIS.ReleaseString

FUNCTION getAddr && returns a pointer to the string
RETURN THIS.hMem

FUNCTION getValue && returns string value
    LOCAL lnSize, lcBuffer
    lnSize = THIS.getAllocSize()
    lcBuffer = SPACE(lnSize)

    IF THIS.hMem <> 0
        DECLARE RtlMoveMemory IN kernel32 As Heap2Str;
            STRING @, INTEGER, INTEGER
        = Heap2Str (@lcBuffer, THIS.hMem, lnSize)
    ENDIF
RETURN lcBuffer

FUNCTION getAllocSize && returns allocated memory size (string length)
    DECLARE INTEGER GlobalSize IN kernel32 INTEGER hMem
RETURN Iif(THIS.hMem=0, 0, GlobalSize(THIS.hMem))

PROCEDURE setValue (lcString) && assigns new string value
#DEFINE GMEM_FIXED 0
    THIS.ReleaseString

    DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER, INTEGER
    DECLARE RtlMoveMemory IN kernel32 As Str2Heap;
        INTEGER, STRING @, INTEGER

    LOCAL lnSize
    lcString = lcString + Chr(0)
    lnSize = Len(lcString)
    THIS.hMem = GlobalAlloc (GMEM_FIXED, lnSize)
    IF THIS.hMem <> 0
        = Str2Heap (THIS.hMem, @lcString, lnSize)
    ENDIF
         
PROCEDURE ReleaseString && releases allocated memory
    IF THIS.hMem <> 0
        DECLARE INTEGER GlobalFree IN kernel32 INTEGER
        = GlobalFree (THIS.hMem)
        THIS.hMem = 0
    ENDIF
ENDDEFINE
>Hi
>
>How to install a "Generic Only Text" printer driver programatically?
>I looked for this issue in UT threads, articles from George Tasker and Ed Raugh in Vfug and some other places, and I couldn´t find it. Someone could please help me?
>
>Best Regards
.·*´¨)
.·`TCH
(..·*

010000110101001101101000011000010111001001110000010011110111001001000010011101010111001101110100
"When the debate is lost, slander becomes the tool of the loser." - Socrates
Vita contingit, Vive cum eo. (Life Happens, Live With it.)
"Life is not measured by the number of breaths we take, but by the moments that take our breath away." -- author unknown
"De omnibus dubitandum"
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform