The following is a reply I received from Louse Simmons to my query regarding setting printers 
programmatically under FoxPro for Windows.  As a result of the procedures and functions that
Louise was kind enough to share with me, I developed the procedures and functions in this file.

All of the procedures and functions as Louise gave them to me remain as listed below, with the 
exception of the GETPRINT procedure which I modified as noted in the documentationn in the
PRNARRAY.PRG procedure.  All three of the program files in this project will run stand-alone, 
as the supporting procedures and functions are included in each.  Note that the project manager
will report errors on regfn and callfn as well as the reference to the array DEVICES() in GETPRINT
and PUTPRINT.  This is only because this was a quick-and-dirty demo, and I didn't take the time
to flag these references as EXTERNAL.

The DEMOWINP screen is an example of how to use the procedures in an interactive printer 
selection module that allows the developer greater control over the choices he gives to the user.
For a quick-and dirty approach, calling the Windows Control Panel:

RUN /N CONTROL PRINTERS 

is much easier, but many lengthy greenbar-style reports require special selections, and taking 
control of the available printers may be desirable.  Note too that the DEMOWINP screen can
be cleaned up or modified to be a little more neat in it's execution.

Hope you learn and enjoy!

Steve Sawyer - CIS I.D. 75730,455

#: 412064 S6/Win/Reports/Print
    14-Apr-93  21:47:54
Sb: #411840-coding to Select prn
Fm: Louise Simmons [MSF 71726,2652
To: Steve Sawyer (KarCal) 75730,455

 -Steve-

With the set of routines in GETPRINT.PRG you can change the
default Windows printer from FoxPro for Windows.

More Information:

LISTPRINT:

Displays all the printers in the win.ini, number of printers
and the default printer to the screen.

GETPRINT:

The procedure GETPRINT gets a list of available printers,
the number of printers in the win.ini file and the default
printer in the win.ini file. This is the list of the
parameters:

1) Printer list. Array
2) Number of printers in win.ini file.  Numeric.
3) Default printer in the win.ini file.  Character.

PUTPRINT:

The procedure PUTPRINT will set the default printer in the
win.ini file.  This procedure takes three or four
parameters.

1) Printer list.  Array (use param 1 from GETPRINT)
2) Number of printers. Numeric (use param 2 from GETPRINT)
3) The new default print string.  (put directly into the
win.ini.) or you can pass two numeric parameters (3 and 4) where:
3) Number of the printer in the printer array. Numeric.
4) The Port number.  If a printer has more than one port
(FILE:, LPT1:) the number will represent the number in the
list order (FILE: = 1, LPT1: = 2).  If you pass a third
parameter that is numeric and don't pass a fourth parameter
it will default to the first or only port.

These routines are below.

Louise [MSFT]


___________________________
!********
*!
*!     Procedure: GETPRINT
*!
*!*******
PROCEDURE getprint
* Query WIN.INI to get data on the installed and default printers.

PARAMETER DEVICE, NUMBER, dfltprnt
* Usage:
*    DIMENSION device[1]
*    numprinters = 0
*    defaultprnt = ""
*    DO GETPRINT WITH device, numprinters, defaultprnt
*
* The "device" array will be populated with the names
* and parameters for all installed print devices.
*
* The "device" array has this structure:
* Col 1:   Printer name
* Col 2:   Parameter for [device] section
* Col 3:   Parameter for [PrinterPort] section
* (includes timeout parameters)
*
* The contents of "device" might look like this after you call getprint:
*   Col 1                            Col 2                 Col 3
*   -----------------------   -------------   ---------------------
*   Apple LaserWriter II NTX         pscript,LPT2:         pscript,LPT2:,15,90
*   Generic / Text Only=TTY          fred.prn              fred.prn,15,45
*   HP LaserJet IIISi                hppcl5a,LPT1:         hppcl5a,LPT1:,15,45
*   HP LaserJet IIISi PostScript     pscript,LPT2:         pscript,LPT2:,15,90
*   HP LaserJets(Level 5)            HPPCL5MS,LPT1:        HPPCL5MS,LPT1:,15,45
*
* "numprinters" in this case would be 5
* "defaultprnt" might be this:
*    HP LaserJet IIISi PostScript,pscript,LPT2:


#DEFINE buflen 2048
PRIVATE m.in_talk, m.dcount, m.retbuf, m.bytes, m.thisdevice

IF PARAMETERS() < 3
   WAIT WINDOW "This procedure requires 3 parameters"
   RETURN
ENDIF

IF FILE(SYS(2004)+"FOXTOOLS.FLL")
   SET LIBRARY TO (SYS(2004)+"foxtools.fll") ADDITIVE
ELSE
   WAIT WINDOW "GETPRINT requires the FoxTools library."
   RETURN
ENDIF

IF SET("TALK") = "ON"
   SET TALK OFF
   m.in_talk = "ON"
ELSE
   m.in_talk = "OFF"
ENDIF

* Fill in the first column of the array with installed device names
m.retbuf = REPLICATE(CHR(0),buflen)
m.bytes = getprostrg("devices",0,CHR(0),@m.retbuf,buflen)
m.dcount = 0
m.retbuf = LEFT(m.retbuf,m.bytes)
DO WHILE CHR(0) $ m.retbuf
   m.thisdevice = LEFT(m.retbuf,AT(CHR(0),m.retbuf)-1)
   IF LEFT(m.thisdevice,1) <> CHR(0)
      m.dcount = m.dcount + 1
      DIMENSION DEVICE[m.dcount,3]
      DEVICE[m.dcount,1] = m.thisdevice
   ENDIF
   m.retbuf = SUBSTR(m.retbuf,AT(CHR(0),m.retbuf)+1)
ENDDO

* Fill in the second and third columns of the device array with the parameters
* of each installed device from the [devices] section (column 2) and the
* [PrinterPorts] section (column 3).
FOR m.j = 1 TO m.dcount
   retbuf = REPLICATE(CHR(0),256)
   m.bytes = getprostrg("devices",DEVICE[m.j,1],CHR(0),@m.retbuf,256)
   m.retbuf = LEFT(m.retbuf,m.bytes)
   DEVICE[m.j,2] = m.retbuf

   retbuf = REPLICATE(CHR(0),256)
   m.bytes = getprostrg("PrinterPorts",DEVICE[m.j,1],CHR(0),@m.retbuf,256)
   m.retbuf = LEFT(m.retbuf,m.bytes)
   DEVICE[m.j,3] = m.retbuf
ENDFOR

* Store the number of installed devices
m.number = m.dcount

* Now get the default printer
retbuf = REPLICATE(CHR(0),256)
m.bytes = getprostrg("windows","device",CHR(0),@m.retbuf,256)
m.retbuf = LEFT(m.retbuf,m.bytes)
m.dfltprnt = m.retbuf

SET TALK &in_talk


*!**********
*!
*!     Procedure: LISTPRINT
*!
*!**********
PROCEDURE listprint
PARAMETER DEVICE
#DEFINE buflen 2048
PRIVATE m.in_talk,m.i
IF FILE(SYS(2004)+"FOXTOOLS.FLL")
   SET LIBRARY TO (SYS(2004)+"foxtools.fll") ADDITIVE
ELSE
   WAIT WINDOW "LISTPRINT requires the FoxTools library."
   RETURN
ENDIF
IF SET("TALK") = "ON"
   SET TALK OFF
   m.in_talk = "ON"
ELSE
   m.in_talk = "OFF"
ENDIF

IF PARAMETERS() = 0
   RELEASE DEVICE
   IF TYPE("device[1]") = "U"
      PUBLIC DEVICE[1]
   ENDIF
ENDIF
NUMBER = 0
dflt = ""

DO getprint WITH DEVICE, NUMBER, dflt
CLEAR
? ALLTRIM(STR(m.number,3))+" installed printer devices in WIN.INI:"
FOR m.i = 1 TO NUMBER
   ? "  "+DEVICE[m.i,1]+"="+DEVICE[m.i,3]
ENDFOR
?
? "Default printer is "+dflt
SET TALK &in_talk

*!***********
*!
*!     Procedure: PUTPRINT
*!
*!***********
PROCEDURE putprint
PARAMETER DEVICE, NUMBER, dflt, portnum
* Take the printer device information in the device array and update WIN.INI
* with it.

* "Number" is the total number of printers listed in "device."
* "dflt" is the string to write to the [windows] device= statement to set the
* default printer, or if dflt is a number, the array row to construct this
* statement from.  Thus, if you wanted to make the default printer the
* third one listed in "device," you could either pass a 3 as dflt or you could
*pass the actual string (something like: HP LaserJets(Level 5),HPPCL5MS,LPT1:)
* If you pass the string, it must exactly match an entry in the
* [devices] section of your WIN.INI file.
*
* You'll probably want to use GETPRINT to construct the device array.
*
IF FILE(SYS(2004)+"FOXTOOLS.FLL")
   SET LIBRARY TO (SYS(2004)+"foxtools.fll") ADDITIVE
ELSE
   WAIT WINDOW "PUTPRINT requires the FoxTools library."
   RETURN
ENDIF

IF TYPE("dflt") = "N"
   IF PARAMETERS() < 4
      portnum = 1
   ENDIF
   m.strg = DEVICE[m.dflt,1]+","+getport(DEVICE[m.dflt,2],portnum)
ELSE
   m.strg = m.dflt
ENDIF

* Set the default printer
=putprostrg("windows","device",m.strg)

* Delete all existing device and PrinterPort entries.
=putprostrg("devices",0,CHR(0))
=putprostrg("PrinterPort",0,CHR(0))

FOR m.i = 1 TO NUMBER
   =putprostrg("devices",DEVICE[m.i,1],DEVICE[m.i,2])
   =putprostrg("PrinterPorts",DEVICE[m.i,1],DEVICE[m.i,3])
ENDFOR

*!**********
*!
*!     Function: PUTPROSTRG
*!
*!**********
FUNCTION putprostrg
PARAMETER SECTION, entry, string
fn = regfn("WRITEPROFILESTRING","CCC","I")
RETURN callfn(fn,SECTION,entry,string)

*!***********
*!
*!     Function: GETPROSTRG
*!
*!***********
FUNCTION getprostrg
PARAMETER SECTION, entry, dflt, buffer, blen
fn = regfn("GETPROFILESTRING","CCC@CI","I")
RETURN callfn(fn,SECTION,entry,dflt,@buffer,blen)

*!*******
*!
*!     Function: GETPORT
*!
*!*********
FUNCTION getport
PARAMETER m.pstrg, m.pnum
* Get the first "port" from a printer string

* First get the printer driver name (e.g., pscript) and the comma
m.retstrg = SUBSTR(m.pstrg,1,AT(',',m.pstrg))

* Now get the port designation (e.g., LPT1: or FILE:)

* Check if the port passed is greater than the ports avail.
IF OCCURS(',',m.pstrg) >= m.pnum
        m.portstrg = SUBSTR(m.pstrg,AT(',',m.pstrg,m.pnum)+1)
ELSE
        m.portstrg = SUBSTR(m.pstrg,AT(',',m.pstrg,1)+1)
ENDIF

IF AT(',',m.portstrg) > 0
   m.portstrg = LEFT(m.portstrg,AT(',',m.portstrg)-1)
ENDIF

RETURN m.retstrg + m.portstrg

______________________________________

