Paradox Community
Search:

 Welcome |  What is Paradox |  Paradox Folk |  Paradox Solutions |
 Interactive Paradox |  Paradox Programming |  Internet/Intranet Development |
 Support Options |  Classified Ads |  Wish List |  Submissions 


Paradox Programming Articles  |  Beyond Help Articles  |  Tips & Tricks Articles  


Win32 API and Printers
Setting Default Windows Printer
© 2002 Rick Kelly
www.crooit.com

Preface

Libraries and forms (Paradox 9) presented are available as a download here. Paradox 8 is not supported although Paradox 7-32 surprisingly works. After downloading into the folder of your choice, make that folder :WORK: and run the included form for a demonstration.


Introduction

The first article in our series showed how the Win32 API could be used to retrieve the default Windows printer as well as some basic properties for any properly installed Windows printer. In this article we'll cover how to set the default Windows printer based on the version of Windows running.


Commonly Referenced Win32 Methods

The following Win32 methods are frequently called as part of other methods and/or procedures.
Uses "user32"
  SendMessageTimeout(
    hWnd cLong,
    msg cLong,
    wParam cLong,
    lParam cLong,
    fuFlags cLong,
    uTimeout cLong,
    lpdwResult cPtr) cLong [stdcall "SendMessageTimeoutA"]
endUses
hWnd = Window Handle; always -1 to broadcast to all
msg = Type of message; always 26 for a setting change
wParam = always 0 for our use
lParam = always 0 for our use
fuFlags = Timeout options; always 0 for our use
uTimeout = Number of milliseconds to wait for response; always 500 (.5 second)
lpdwResult = Not used

Referenced constants for the above are:
cnBroadcast  = -1
cnSettingChange = 26
The following Paradox procedure encapsulates the Win32 method "SendMessageTimeout".
Proc cmSettingChangeAlert(liTimer LongInt)
var
  liResult  LongInt
endVar
  liResult = 0
;
; Send out alert to all running applications
; that a system value has been updated
;
  SendMessageTimeout(
    cnBroadcast,
    cnSettingChange,
    0,
    0,
    cnTimeOutNormal,
    liTimer,
    liResult)
endProc

Set Default Windows Printer

Our approach to setting the default printer is based on the version of the operating system and is derived from article Q246772 at:

http://support.microsoft.com/support/kb/articles/q246/7/72.asp

Win95/Win98/WinME

The following Win32 API method is used with Win9x versions to set the default printer name.
Uses "winspool.drv"
  SetPrinter(
    hPrn cLong,
    cLevel cLong,
    pPrinter cLong,
    command cLong) cLong [stdcall "SetPrinterA"]
endUses
hPrn - Handle to the printer
cLevel = Level or type of printer information structure to return - we will use 2
pPrinter = pointer to address of printer structure
command = always 0 for our use

See the introductory article for an overview of other referenced Win32 API calls.

Example:

Assume that "cnPrinterDefault" is a constant with value = 4 and that "stPrinter" contains the name of the printer we want to make the default Windows printer.
var
  loRetur           Logical
  liPrinterHandle   LongInt
  liReturn          LongInt
  liSizeNeeded      LongInt
  liSizeUsed        LongInt
  liMemoryStructure LongInt
  liAttributes      LongInt
endVar
loReturn = False
liAttributes = 0
;
; Get a handle to the printer
;
liPrinterHandle = 0
liReturn = OpenPrinter(stPrinter,liPrinterHandle,0)
;
; Check if stPrinter contained a valid printer name
;
switch
  case liReturn <> 1 :
  otherwise :
;
; First call is to get buffer size needed
;
    liSizeNeeded = 0
    liSizeUsed = 0
    liReturn = GetPrinter(liPrinterHandle,2,0,0,liSizeNeeded)
;
; Allocate memory for Printer Info Structure Level 2
;
    liMemoryStructure = GlobalAlloc(fromHex("0x40"),liSizeNeeded)
;
; Get Printer Info Structure
;
    liReturn = GetPrinter(liPrinterHandle,2,liMemoryStructure,liSizeNeeded,liSizeUsed)
    switch
      case liReturn = 1 :
;
; Retrieve attributes
;
        MoveFromMemory(liAttributes,liMemoryStructure + 52,4)
;
; Turn on default bit flag
;
        liAttributes = liAttributes.bitOR(cnPrinterDefault)
;
; Update attributes
;
        MoveToMemory(liMemoryStructure + 52,liAttributes,4)
        liReturn = SetPrinter(liPrinterHandle,2,liMemoryStructure,0)
        switch
          case liReturn = 1 :
;
; Notify other applications that a system value has been changed
;
            cmSettingChangeAlert(500)
            loReturn = True
        endSwitch
        liReturn = ClosePrinter(liPrinterHandle)
    endSwitch
endSwitch
The variable "loReturn" will contain True if the switch was successful.

WinNT

For WinNT, the default printer is set in WIN.INI in the "windows" section with the keyword "device=" and we can use normal OPAL to set it.

Assume that "stPrinter" contains the name of the printer we want to make the default Windows printer.

Example:
var
  stPort        String
  arAny         Array[] String
  loReturn      Logical
  stProfileFile String
endVar
loReturn = False
stProfileFile = windowsDir() + "\\win.ini"
;
; Retrieve driver and port information
;
stPort = readProfileString(
           stProfileFile,
           "PrinterPorts",
           stPrinter)
switch
  case stPort.isEmpty() :
  otherwise :
    stPort.breakApart(arAny,",")
    switch
      case arAny.size() > 1 :
        writeProfileString(
          stProfileFile,
          "windows",
          "device",
          stPrinter  +
          "," +
          arAny[1] +
          "," +
          arAny[2])
;
; Notify other applications that a system value has been changed
;
        cmSettingChangeAlert(500)
        loReturn = True
    endSwitch
endSwitch
The variable "loReturn" will contain True if the switch was successful.

W2K and XP

For W2K and XP, the following Win32 API (only present in those OS versions) is used.
Uses "winspool.drv"
  SetDefaultPrinter(stPrinter cptr) cLong [stdcall "SetDefaultPrinterA"]
endUses
stPrinter = Paradox String Type of default printer name to set.

Assume that "stPrinter" contains the name of the printer we want to make the default Windows printer.

Example:
var
  loReturn Logical
endVar
switch
  case SetDefaultPrinter(stPrinter) = 1 :
    loReturn = True
  otherwise :
    loReturn = False
endSwitch
The variable "loReturn" will contain True if the switch was successful.


Conclusion

We now have methods that provide access to the Win32 API for setting the default Windows printer.


Next: Access and Control of the Print Spooler


Discussion of this article


 Feedback |  Paradox Day |  Who Uses Paradox |  I Use Paradox |  Downloads 


 The information provided on this Web site is not in any way sponsored or endorsed by Corel Corporation.
 Paradox is a registered trademark of Corel Corporation.


 Modified: 15 May 2003
 Terms of Use / Legal Disclaimer


 Copyright © 2001- 2003 Paradox Community. All rights reserved. 
 Company and product names are trademarks or registered trademarks of their respective companies. 
 Authors hold the copyrights to their own works. Please contact the author of any article for details.