I use the followin function to change my default printer:
FUNCTION SetaImpDefa(imp,muda)
Declare long WriteProfileString in "kernel32" ;
string lpszSection, string lpszKeyName, string lpszString
Declare long SendMessage in "user32" ;
long hwnd, long wMSg, long wParam, String lParam
if muda
HWND_BROADCAST = -1
WM_WININICHANGE = 26
endif
printer_name = imp
printer_buffer = space(200)
*
len_ret = GetProfileString("PrinterPorts", printer_name, "", ;
@printer_buffer, Len(printer_buffer))
printer_buffer = left(printer_buffer,len_ret)
*
printer_driver = left(printer_buffer,at(',',printer_buffer)-1)
printer_buffer = substr(printer_buffer,at(',',printer_buffer)+1)
*
printer_port = left(printer_buffer,at(',',printer_buffer)-1)
*
new_printer_default = printer_name + "," + printer_driver + "," + printer_port
updated = WriteProfileString("Windows","device",new_printer_default)
*
if muda and updated = 1
SendMessage(HWND_BROADCAST,WM_WININICHANGE,0,"windows")
endif
return updated
endfunc
I call it twice on my code like this
setaImpDefa(text_only_printer,.t.)
PrintJob
Inicio
Items
Fim
EndPrintJob
setaImpDefa(laser_printer,.t.)
Where text_only_printer and laser_printer are strings containing printer names. (Inicio, Items and Fim are strings with printer comands and text to be printed).
Ok, the first time it works fine and the text goes to my text-only printer. Problem is, when I try to print a report afterwards, it also goes to the text-only printer, not to the laser printer. Wierdest thing is, it does change the default printer on Windows, only Fox doesn't seem to recognize it.
Anyone has any idea what I should be looking for
Thanks in advance.

Change default printer works only once
Donaghy
It's strange: It does chage the Windos Default printer, only my VFP program still tries to print to the text_only_printer
James Miles
Copy the Code to a PRG and then runnit:
Declare Integer OpenPrinter In WinSpool.DRV As OpenPRN String, Integer @, Integer
Declare Integer StartDocPrinter In WinSpool.DRV As StartDocPRN Integer, Integer, String @
Declare Integer StartPagePrinter In WinSpool.DRV As StartPagePRN Integer
Declare Integer WritePrinter In WinSpool.DRV As WritePRN Integer, String, Integer, Integer @
Declare Integer EndPagePrinter In WinSpool.DRV As EndPagePRN Integer
Declare Integer EndDocPrinter In WinSpool.DRV As EndDocPRN Integer
Declare Integer ClosePrinter In WinSpool.DRV As ClosePRN Integer
Declare Integer GlobalFree In Win32API Integer
Declare Integer GlobalAlloc In Win32API Integer, Integer
Declare RtlMoveMemory In Win32API As Str2Heap Integer, String @, Integer
hPrinter =OpenST("Generica / So Texto")
=LineST(hPrinter, "Isto e um Teste")
=CloseST(hPrinter)
Clear DLLs
*********************************************************************************
* Open The Printer via Windows API *
*********************************************************************************
Function OpenST (NomePRN)
Store 0 To hPrinter, nRetornoAPI
&& Start Printer...
nRetornoAPI =OpenPRN(NomePRN, @hPrinter, 0)
If Empty(nRetornoAPI) Then
=Messageb([Printer "] + Upper(AllTr(NomePRN)) + [" not found.], 48)
Return
EndIf
oDocName =CreateObj("PChar", "Documento")
sDocInf =oDocName.sMem + Replic(Chr(0), 8)
=StartDocPRN(hPrinter, 1, @sDocInf)
=StartPagePRN(hPrinter)
Release oDocName, nRetornoAPI
Return hPrinter
EndFunc
*********************************************************************************
* Send Data to Printer via Windows API
*********************************************************************************
Procedure LineST (phPrinter, pcString)
nGuarda =Len(pcString)
nGuarda =WritePRN(phPrinter, pcString, nGuarda, @nGuarda)
If Empty(nGuarda) Then
=Messageb("Cannot send Data to the Printer.", 48)
=CloseST(phPrinter)
EndIf
EndProc
******************************************************************************
* Close the Printer Job
******************************************************************************
Function CloseST (hnPRN)
=EndPagePRN(hnPRN)
=EndDocPRN(hnPRN)
=ClosePRN(hnPRN)
EndFunc
*********************************************************************************
* Transform a DWord (Integer - 32 bits) in a String
*********************************************************************************
Function DWord2Str (pInteiro)
Return Chr(Mod(pInteiro, 256)) + Chr(Mod(pInteiro, 65536)/256) + ;
Chr(Mod(pInteiro, 256^3)/65536) + Chr(Mod(pInteiro, 256^4)/256^3)
EndFunc
*********************************************************************************
* Pointer Class
*********************************************************************************
Define Class PChar As Custom
hMem =0
sMem =Replic(Chr(0), 4)
Procedure Destroy
=GlobalFree(This.hMem)
EndProc
Procedure Init (lcString)
lcString =lcString + Chr(0)
lnSize =Len(lcString)
This.hMem =GlobalAlloc(0, lnSize)
If !Empty(This.hMem) Then
=Str2Heap(This.hMem, @lcString, lnSize)
This.sMem =DWord2Str(This.hMem)
EndIf
EndProc
EndDefine
james_cline_
I don't know function GetProfileString but the returned value should be a integer.
I ran your code on my computer and it is working fine. I did not use GetProfileString and I am using Vfp 9 SP1.
Cammyr
>>It does chage the Windos Default printer, only my VFP program still tries to print to the text_only_printer
Sounds like you have the output printer saved in the report. You may need to clear out the fields that save the printer with the report definition (off the top of my head I think it is EXPR, TAG and TAG2 in the first record in the FRX file). When you create a report, ensure that you do not save the printer enviornment with it.
Swimmer84
I Have this code to change and restore the Default Printer Driver.
The code was written in VFP5 and tested in VFP6.
Procedure DefaultPrn (pOldPrn, pNewPrn)
&& If pOldPrn is empty (""), we want to restore the last default printer stored in a variable.
&& pNewPrn, should have the format: "<printer name>,WINSPOOL,<port>:"
&& if the format is not given, no printer is defined.
If !Empty(pOldPrn) Then
If Type(pOldPrn) ="U" Then
Public &pOldPrn
EndIf
EndIf
Local nAPIReturn, cBuffer
cBuffer =Replicate(Chr(0), 255)
&& Get the current default printer and store it in the public variavel &pOldPrn...
Declare Integer GetProfileString In Kernel32 String, String, String, String @, Integer
nAPIReturn =GetProfileString("Windows", "device", ",,,", @cBuffer, 255)
&pOldPrn =Left(cBuffer, nAPIReturn)
&& Setup the new printer...
If !Empty(AllTr(pNewPrn)) Then
Declare Integer WriteProfileString In Kernel32 String, String, String
nAPIReturn =WriteProfileString("Windows", "device", pNewPrn)
&& this will make the printer shows as default in Windows...
&& other programs must wait 1 second to get the new printer
Declare Integer SendMessageTimeout In User32 Integer, Integer, Integer, String, Integer, Integer, String
&& 0xFFFF = Inform all open Applications (HWnd_BroadCast)
&& 0x1A = Wait for the registry update (Wm_WinINIChange)
&& 0x0 = normal behavior (SMTo_Normal)
If At("NT", OS()) >0 Then && Windows NT
=SendMessageTimeout(0xFFFF, 0x1A, 0, "", 0x0, 1000, NULL) && 1000 = 1 Sec.
Else
=SendMessageTimeout(0xFFFF, 0x1A, 0, "windows", 0x0, 1000, NULL)
EndIf
EndIf
Clear DLLs
&& It should return 1 (OK).
Return nAPIReturn
EndProc
Hope this helps you.
Works for me in Win98/2000/XP using VFP6.
dpoon
I'm runing a VFP 6.0, maybe that's the problem...