Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

sys(1037) or other function/procedure

Status
Not open for further replies.

jefftoaster

Programmer
Feb 6, 2003
19
US
VFP 6.0 running on Win98.

I have setup a custom printer selection using sys(1037). After it returns, I use set("PRINTER",3) to get the printer name and PRTINFO to pick out the 2 or 3 printer settings I want. I store all this in a memo field for use later to plug into the expr field in the report table.

1. Is there any way I can tell if they've clicked cancel?

2. I can preset the printer name prior to the SYS(1037) with set printer to name xxxxx (where xxxxx is the name I pulled earlier with set("PRINTER",3)). Is there any way to preset the other settings? That way they'll know what settings they selected last time. (I'm only doing orientation, paper size, and paper source)





 
jefftoaster

. Is there any way I can tell if they've clicked cancel?

Sys(1037) does not return any values, you would have a better chance with either GETPRINTER()


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Well, GETPRINTER() would work if I didn't need any custom settings, such as Orientation, Paper Size, and Source.

This app has about a dozen different reports in VFP Report format. Then I have a table with hundreds of different queries, filters, comments, and report printer settings - which gets used in conjunction with the reports within a batch printing system.

It really irritates me that there's no way to detect the cancel on SYS(1037).

Well, for now I'll just present the printer name and settings in a messagebox after calling sys(1037) and ask if they're ok. The users will whine about having to hit cancel twice - but what else can I do?

Thanks anyway!
Jeff Owens
 
jefftoaster

You can be a little more creative then that! Create your own dialog. Or use the commondialogs, you sound defeatist. Just because I said the sys(1037) does not return a value, it does not mean you need to give up. I'm just saying that the road your are taking will not yield very much, take another route.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Jeff,

I agree with Mike. CommonDialog has a better interface for that purposed. You can also detect Cancel button.

-- AirCon --
 
jefftoaster

If you were to create your own custom print dialog (that would handle all of your users needs), here a few hints to help you:
[ol][li]Create a blank form.[/li]
[li]Add an array property to it (call it aprintarray)[/li]
[li]Add a combobox to it to create a list of available printers , set the rowsource to thisform.aprintarray and the rowsourcetype to 5 and in the init of the combo put :
Code:
Local lnI
For lnI = 1 To Aprinters(Thisform.aprintarray)
	Thisform.aprintarray[lnI,1] = Space(1) + ;
		THISFORM.aprintarray[lnI,1] && to fix the network printer issue with the backslash
Endfor
This.Requery()
If '5.0' $ Version() && At version 5.0 they were not sorted by default printer first
	For Each a_element In Thisform.aprintarray
		If Upper(Set('PRINTER',2))$Upper(a_element)
			This.Value = a_element
		Endif
	Endfor
Else
	This.Value = Thisform.aprintarray[1] && With 6.0 and up they were.
Endif
Endproc
[/li]
[li] Put two command buttons (Pront report and cancel). Now you can trap the cancel.[/li]
[li]Put a spinner on the form and set the value to 1, the spinnerLowvalue to 1 and the high value to 9999 (or whatever). That will handle the number of copies. To handle this, when you print you either hack the report on the fly and insert to number of copies in the Expr field of the report, or you use:
for i = 1 to thisform.spinner1.value
report form ... to printer
endform[/li]
[li] Add a Optiongroup with 2 options (Portrait and Landscape). That one you will have to handle with hacking the report and setting the Orientation in the Expr field.[/li][/lo]

That should help you get started. As for the papersource and trays available that is handled with a series of API calls that would retrieve the information from the printer drivers themselves.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
jefftoaster

After a little digging, I will retract myself, and tell you that ?sys(1037) does return a value to determine if the user hit the cancel button or the OK button (Sorry for my misleading comment above). But you have to use the API calls that make up the ? sys(1037) to determine that, here is the code that makes up that sys function (I have added a messagebox to help you find the value). Copy the following in a program and run it. (This code came from a Japanese website although I have a feeling to original author is Anatoliy Mogylevets except for the messagebox I added)
Code:
*| typedef struct tagPD {
*| DWORD lStructSize; 4
*| HWND hwndOwner; 4
*| HGLOBAL hDevMode; 4
*| HGLOBAL hDevNames; 4
*| HDC hDC; 4
*| DWORD Flags; 4
*| WORD nFromPage; 2
*| WORD nToPage; 2
*| WORD nMinPage; 2
*| WORD nMaxPage; 2
*| WORD nCopies; 2
*| HINSTANCE hInstance; 4
*| LPARAM lCustData; 4
*| LPPRINTHOOKPROC lpfnPrintHook; 4
*| LPSETUPHOOKPROC lpfnSetupHook; 4
*| LPCTSTR lpPrintTemplateName; 4
*| LPCTSTR lpSetupTemplateName; 4
*| HGLOBAL hPrintTemplate; 4
*| HGLOBAL hSetupTemplate; 4
*| } PRINTDLG, *LPPRINTDLG; 66 Bytes

Do Decl
#Define PD_ALLPAGES 0
#Define PD_RETURNDC 256
#Define PD_USEDEVMODECOPIESANDCOLLATE 262144 && 0x40000
#Define PD_RETURNDEFAULT 1024 && 0x400

Local lcStruct, hDc, lnFlags

* for this value of flags no Device Context returned
*    lnFlags = PD_ALLPAGES

lnFlags = PD_USEDEVMODECOPIESANDCOLLATE + PD_RETURNDC

* fill PRINTDLG structure
lcStruct = num2dword(66) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(lnFlags) +;
	num2word(65535) +;
	num2word(65535) +;
	num2word(1) +;
	num2word(65535) +;
	num2word(1) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0) +;
	num2dword(0)

If PrintDlg (@lcStruct) <> 0
	hDc = buf2dword (Substr (lcStruct, 17, 4))
	If !Empty(hDc)
		Messagebox(&quot;User hit the OK button&quot;)
	Endif
* release system resources
	= DeleteDC (hDc)
Else
	Messagebox(&quot;User hit the Cancel button&quot;)
Endif

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)

Function num2word (lnValue)
Return Chr(Mod(m.lnValue,256)) + Chr(Int(m.lnValue/256))

Function buf2dword (lcBuffer)
Return Asc(Substr(lcBuffer, 1,1)) + ;
	Asc(Substr(lcBuffer, 2,1)) * 256 +;
	Asc(Substr(lcBuffer, 3,1)) * 65536 +;
	Asc(Substr(lcBuffer, 4,1)) * 16777216

Procedure Decl
Declare Integer DeleteDC In gdi32 Integer hdc
Declare Integer PrintDlg In comdlg32;
	STRING @ lppd




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike,

sys(1037) does return a value to determine if the user hit the cancel button or the OK button (Sorry for my misleading comment above)

You were not wrong for that.
sys(1037) is a VFP wrapper to &quot;PrintDlg&quot; API. VFP supress the returned value.

CommonDialog ActiveX is the same, but it can return whatever PrintDlg return.


-- AirCon --
 
Thanks Guys! I really do appreciate your efforts and time.

Well, here's the basic idea of what I ended up with:

sys(1037)
if messagebox(Ok? ...)
create report tmpxxx from yyy
then store the objtype=1 and objcode=53 line out of the tmpxxx.frx table to a separate table
later on copy the required line to the desired report frx table

Reasoning: It seems like only calling sys(1037) affects foxpro internally - so that the &quot;create report tmpxxx from yyy&quot; command does what I need it to (store all the selected printer settings). Neither the ActiveX CommonDialog nor the PrintDlg affects Foxpro internally (why should they?).

Foxpro stores A LOT of printer/page setup information to the report table - which allows me to have granular control over printing. Saving this information into a separate file to be recalled later gives me on the fly printer setup and switching during batch printing.

Again - thanks for everyone's input!

Jeff Owens
PS - I take absolutely NO credit for any of this solution. I saw part or all of this posted elsewhere (sorry I can't remember where, I've looked in a LOT of places!) - perhaps on Tek-Tips.

 
Mike,

Your answer to jefftoaster regarding the Windows default printer you says that VFP 6 and higher APRINTERS will show the default printer as the first element in the array.

I am useing VFP 7 (SP1). I have a local printer installed. I changed my default printer to a network printer in windows. APRINTERS is returning the local printer as the first element in the array.

Any suggestion.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top