The following demo was submitted by Robert McAllister ( - robmcal robmcal ). Use this code to incorporate a look alike printer dialog window in your program. It is setup to work with any DPI setting but that portion can be easily removed if desired. Also, since these functions only work on 2000/XP on up, it checks what platform the program is running on.

It has also been noted by Stefan Pendl ( - stpendl stpendl ) that there is no need to scale native LB controls in a dialog window, since dialog windows are automatically scaled to dpi by Liberty BASIC. API created controls must be scaled manually, even in a dialog window.

printer_window.jpeg


 DefaultPrinterName$=DefaultPrinterName$() 
gosub [SelectPrinter]
end

[SelectPrinter]
WinVersion=WinVersion()
if WinVersion>=5 then gosub [Find2000xpvistaprinters]'find installed printers
if WinVersion<=4 then notice "Incompatible OS"+chr$(13)+_
"This function will only work on Windows 2000,"+chr$(13)+_
"Windows XP or Windows Vista":wait
TEMPSelectedPrinter$=SelectedPrinter$

ScrnScl=GetScaleFactor()

WindowWidth=int(440/ScrnScl):WindowHeight=int(270/ScrnScl)
UpperLeftX=int(((DisplayWidth-WindowWidth)/2)/ScrnScl)
UpperLeftY=int(((DisplayHeight-WindowHeight)/2)/ScrnScl)
BackgroundColor$ = "buttonface"

groupbox #pselect.one, "Printer", int(13/ScrnScl), int(6/ScrnScl), int(410/ScrnScl), int(80/ScrnScl)
groupbox #pselect.two, "Print range", int(13/ScrnScl), int(92/ScrnScl), int(217/ScrnScl), int(105/ScrnScl)
groupbox #pselect.thr, "Copies", int(240/ScrnScl), int(92/ScrnScl), int(183/ScrnScl), int(105/ScrnScl)

statictext #pselect.1, "Name:", int(25/ScrnScl), int(33/ScrnScl), int(55/ScrnScl), int(26/ScrnScl)
statictext #pselect.6, "from:", int(89/ScrnScl), int(145/ScrnScl), int(26/ScrnScl), int(23/ScrnScl)
statictext #pselect.7, "to:", int(165/ScrnScl), int(145/ScrnScl), int(12/ScrnScl), int(23/ScrnScl)

statictext #pselect.8, "Number of copies:", int(251/ScrnScl), int(115/ScrnScl), int(112/ScrnScl), int(23/ScrnScl)

combobox #pselect.list1, prnt$(),[pSelected1], int(80/ScrnScl), int(29/ScrnScl), int(227/ScrnScl), 100

button #pselect.default,"OK",[pSelected2], UL, int(270/ScrnScl), int(207/ScrnScl), int(75/ScrnScl), int(24/ScrnScl)
button #pselect.Cancel,"Cancel",[quit.pselect], UL, int(351/ScrnScl), int(207/ScrnScl), int(75/ScrnScl), int(24/ScrnScl)
button #pselect.Cancel,"Properties...",[pProperties], UL,int(319/ScrnScl), int(26/ScrnScl), int(92/ScrnScl), int(24/ScrnScl)

checkbox #pselect.checkbox1, "Print to file", [pyes], [pno],int(319/ScrnScl), int(57/ScrnScl), int(80/ScrnScl), int(25/ScrnScl)

radiobutton #pselect.one, "All", [pyes], [pno], int(25/ScrnScl), int(115/ScrnScl), int(60/ScrnScl), int(20/ScrnScl)
radiobutton #pselect.two, "Pages", [pyes], [pno], int(25/ScrnScl), int(140/ScrnScl), int(60/ScrnScl), int(20/ScrnScl)
radiobutton #pselect.thr, "Selection", [pyes], [pno], int(25/ScrnScl), int(165/ScrnScl), int(85/ScrnScl), int(20/ScrnScl)
textbox #pselect.textbox1, int(116/ScrnScl), int(140/ScrnScl),int(38/ScrnScl),int(20/ScrnScl)
textbox #pselect.textbox2, int(180/ScrnScl), int(140/ScrnScl),int(38/ScrnScl),int(20/ScrnScl)

textbox #pselect.textbox3, int(363/ScrnScl), int(110/ScrnScl),int(48/ScrnScl),int(20/ScrnScl)

stylebits #pselect.g1, 0, _WS_BORDER, 0, 0
stylebits #pselect.g2, 0, _WS_BORDER, 0, 0
stylebits #pselect.g3, 0, _WS_BORDER, 0, 0
stylebits #pselect.g4, 0, _WS_BORDER, 0, 0
stylebits #pselect.g5, 0, _WS_BORDER, 0, 0
stylebits #pselect.g6, 0, _WS_BORDER, 0, 0
graphicbox #pselect.g4, int(252/ScrnScl),int(155/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)
graphicbox #pselect.g5, int(289/ScrnScl),int(155/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)
graphicbox #pselect.g6, int(326/ScrnScl),int(155/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)
graphicbox #pselect.g1, int(264/ScrnScl),int(148/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)
graphicbox #pselect.g2, int(302/ScrnScl),int(148/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)
graphicbox #pselect.g3, int(338/ScrnScl),int(148/ScrnScl) , int(20/ScrnScl), int(26/ScrnScl)

open "Select Printer" for dialog_modal as #pselect
#pselect "trapclose [quit.pselect]"
#pselect.list1 "select ";TEMPSelectedPrinter$

'create spinner control:http://libertybasic.conforums.com/index.cgi?board=LB3&action=display&num=1217524188
UpperLimit = 200
LowerLimit = 1
CurrentPosition = 1
hWnd = hWnd(#pselect)
hText = hWnd(#pselect.textbox3)
UDS.ARROWKEYS = hexdec("20")
UDS.WRAP = hexdec("1")
UDS.SETBUDDYINT = hexdec("2")
UDS.ALIGNRIGHT = hexdec("4")
dwStyle = _WS_CHILD or _WS_BORDER or _WS_VISIBLE or UDS.ARROWKEYS or UDS.WRAP or UDS.SETBUDDYINT or UDS.ALIGNRIGHT
hSpinner = CreateSpinner(hWnd, dwStyle, hText, UpperLimit, LowerLimit, CurrentPosition)

#pselect.checkbox1 "disable"
#pselect.two "disable"
#pselect.6 "!disable"
#pselect.7 "!disable"
#pselect.textbox1 "0"
#pselect.textbox2 "0"
#pselect.textbox1 "!disable"
#pselect.textbox2 "!disable"
#pselect.one "set"
#pselect.default "!setfocus"

for x=1 to NumberOfPrinters
if prnt$(x)=DefaultPrinterName$ then #pselect.list1, "selectindex ";x
next x

for x=1 to 6
c=c+1:var$ = "#pselect.g";x
#var$, "font Times_New_Roman 7"
#var$, "down;color darkgray"
#var$, "line 0 0 30 0"
#var$, "line 0 0 0 25"
#var$, "color black"
#var$, "line 19 0 19 25"
#var$, "line 0 24 20 24"
#var$, "place 10 21"
#var$, "\";c
#var$, "flush"
if c=3 then c=0
next x

wait

[pProperties]
notice "This feature is not available."
wait

[pyes]
wait

[pno]
wait

[quit.pselect]
SelectedPrinter$=TEMPSelectedPrinter$
calldll #user32, "DestroyWindow",_
hSpinner as ulong, ret as long
close #pselect
end

[pSelected1]
#pselect.list1 "selection? sel$"
SelectedPrinter$=sel$
wait

[pSelected2]
#pselect.list1 "selection? sel$"
SelectedPrinter$=sel$
if sel$="" then notice "Please select a printer"
calldll #user32, "DestroyWindow",_
hSpinner as ulong, ret as long
print "Selected printer...";SelectedPrinter$
#pselect.textbox3 "!contents? copies"
print "Number of copies...";copies
close #pselect
end

[setdefaultprinter]
open "winspool.drv" for dll as #winspool
calldll #winspool, "SetDefaultPrinterA",_
Printer$ as ptr,_
SetDefaultPrinter as long
close #winspool
if SetDefaultPrinter=0 then call DisplayError
return

[Find2000xpvistaprinters]
'find printers
PRINTER.ENUM.LOCAL = hexdec("2")
PRINTER.ENUM.CONNECTIONS = hexdec("4")
nLocalPrinters = EnumPrinters(PrinterInfo$, PRINTER.ENUM.LOCAL)
LocalPrintersInfo$ = PrinterInfo$
PrinterInfo$ = ""
nNetworkPrinters = EnumPrinters(PrinterInfo$, PRINTER.ENUM.CONNECTIONS)
NetworkPrintersInfo$ = PrinterInfo$
PrinterInfo$ = ""
NumberOfPrinters = nLocalPrinters + nNetworkPrinters
PrinterInfo$ = LocalPrintersInfo$;";";NetworkPrintersInfo$
dim prnt$(NumberOfPrinters)
if NumberOfPrinters then 'remove faxes from list
prnt=0
for x1=1 to NumberOfPrinters'remove "faxes", "Quicken pdf creator" and "Intuit pdf creator" from list
if instr(lower$(word$(PrinterInfo$,x1,";")),"fax")=0 _
and instr(lower$(word$(PrinterInfo$,x1,";")),"quick")=0 _
and instr(lower$(word$(PrinterInfo$,x1,";")),"intuit")=0 _
then prnt=prnt+1:prnt$(prnt)=word$(PrinterInfo$,x1,";")
next x1
end if
return

function EnumPrinters(byref PrinterInfo$, pLocale)
'returns the number of printers found
'fills the submitted variable with the printer names
'separated by semicolons (;)
open "winspool.drv" for dll as #winspool
struct pcbNeeded, value as ulong
struct pcReturned, value as ulong
struct PrinterInfo4,_
pPrinterName$ as ptr,_
pServerName$ as ptr,_
Attributes as ulong
PrinterInfo4Len = len(PrinterInfo4.struct)
nFlags = pLocale
Level = 4
cbBuf = PrinterInfo4Len
uFlags = _LMEM_MOVEABLE or _LMEM_ZEROINIT
calldll #kernel32, "LocalAlloc", _
uFlags as ulong, _
cbBuf as ulong, _
hMem as ulong
calldll #kernel32, "LocalLock", _
hMem as ulong, _
pBuffer as ulong

[retryEnumPrinters]
calldll #winspool, "EnumPrintersA",_
nFlags as ulong,_
PrinterName as ulong,_
Level as ulong,_
pBuffer as ulong,_
cbBuf as ulong,_
pcbNeeded as struct,_
pcReturned as struct,_
result as long
if result = 0 then
if GetLastError() = 122 then
cbBuf = pcbNeeded.value.struct
hOldMem = hMem
calldll #kernel32, "LocalReAlloc", _
hOldMem as ulong, _
cbBuf as ulong, _
uFlags as ulong, _
hMem as ulong
calldll #kernel32, "LocalLock", _
hMem as ulong, _
pBuffer as ulong
goto [retryEnumPrinters]
else
call DisplayError
end if
else
EnumPrinters = pcReturned.value.struct
EnumPrinters$(1)=str$(EnumPrinters)
BufferPointer = pBuffer
for count = 0 to EnumPrinters - 1
calldll #kernel32, "RtlMoveMemory", _
PrinterInfo4 as struct,_
BufferPointer as ulong, _
PrinterInfo4Len as ulong, _
result as void
BufferPointer = BufferPointer + PrinterInfo4Len
pointer = PrinterInfo4.pPrinterName$.struct
PrinterInfo$ = winstring(pointer); ";"; PrinterInfo$
next
PrinterInfo$ = left$(PrinterInfo$, len(PrinterInfo$)-1)
end if
calldll #kernel32, "LocalFree", _
hMem as ulong, _
result as ulong
close #winspool
end function

function GetLastError()
calldll #kernel32, "GetLastError", _
GetLastError as ulong
end function

sub DisplayError
dwFlags = _FORMAT_MESSAGE_FROM_SYSTEM
nSize = 1024
lpBuffer$ = space$(nSize); chr$(0)
dwMessageID = GetLastError()
calldll #kernel32, "FormatMessageA", _
dwFlags as ulong, _
lpSource as ulong, _
dwMessageID as ulong, _
dwLanguageID as ulong, _
lpBuffer$ as ptr, _
nSize as ulong, _
Arguments as ulong, _
result as ulong
if trim$(lpBuffer$)<> "The operation completed successfully." then notice "Error "; dwMessageID; chr$(13); left$(lpBuffer$, result)
end sub

function DefaultPrinterName$()
struct pcchBuffer, value as ulong
pszBuffer$ = space$(500)
pcchBuffer.value.struct = 500
open "winspool.drv" for dll as #winspool
calldll #winspool, "GetDefaultPrinterA",_
pszBuffer$ as ptr,_
pcchBuffer as struct, _
GetDefaultPrinter as long
close #winspool
DefaultPrinterName$ = left$(pszBuffer$, pcchBuffer.value.struct - 1)
end function

function WinVersion()
struct OSVERSIONINFO,_
dwOSVersionInfoSize as ulong,_
dwMajorVersion as ulong,_
dwMinorVersion as ulong,_
dwBuildNumber as ulong,_
dwPlatformId as ulong,_
szCSDVersion as char[128]

L=len(OSVERSIONINFO.struct)
OSVERSIONINFO.dwOSVersionInfoSize.struct=L
calldll #kernel32, "GetVersionExA",_
OSVERSIONINFO as struct,_
result as long
WinVersion=OSVERSIONINFO.dwMajorVersion.struct
'dwMajorVersion
'Identifies the major version number of the operating
'system as follows.
'Windows 95 4
'Windows 98 4
'Windows Me 4
'Windows NT 3.51 3
'Windows NT 4.0 4
'Windows 2000 5
'Windows XP 5
'Windows .NET Server 5
'Windows Vista 6
'Windows 7 6
end function

function GetScaleFactor()
LOGPIXELSX = 88
nIndex = LOGPIXELSX

calldll #user32, "GetDC",_
0 as ulong,_ ' entire screen
hDC as ulong

calldll #gdi32, "GetDeviceCaps",_
hDC as ulong,_
nIndex as ulong,_
dpi as ulong

calldll #user32, "ReleaseDC",_
0 as ulong,_ ' entire screen
hDC as ulong,_
result as long ' 1 = success

GetScaleFactor = dpi / 96
end function

Function CreateSpinner(hWnd, style, hTxt, upr, lwr, pos)
CallDLL #comctl32, "InitCommonControlsEx",_
re as void

CallDLL #user32, "GetWindowLongA",_
hWnd as ulong,_
_GWL_HINSTANCE as long,_
hInst as ulong

CallDLL #comctl32, "CreateUpDownControl",_
style as ulong,_
x as long,_
y as long,_
w as long,_
h as long,_
hWnd as ulong,_
id as long,_
hInst as ulong,_
hTxt as ulong,_
upr as long,_
lwr as long,_
pos as long,_
CreateSpinner as ulong
End Function