IonicWind Software

IWBasic => General Questions => Topic started by: Andy on May 23, 2017, 11:56:26 PM

Title: Printing
Post by: Andy on May 23, 2017, 11:56:26 PM
I'm sure this has been raised before, but this is the first time I have tried printing from IWB!

My printer is an HP Desktop 2130, and it is set to default printer, and yet I cannot use the
WRITEPRINTER command.

I open the printer like this:

   prtname = GETDEFAULTPRINTER
   hPrinter = OPENPRINTER(prtname, "Job 1", "TEXT")

   IF hPrinter

It's reading a simple text file, which I can confirm on screen, and yet nothing is printed, hPrinter returns 0 (zero) which means it failed to open the printer - does that mean my printer is not supported?

Thanks,
Andy.
Title: Re: Printing
Post by: Egil on May 24, 2017, 04:05:41 AM
Hi Andy

Struggling with a similar problem here. The only difference is that I am using a HP1210 printer.
I finally  managed to print out plain text with the code below, but still have to find a way to set the margins.
The sub is coded with CB (a modified version of an example found in the old IB Std Archive). Just put an ENDSUB at  the end, and it will work with IWB.

Maybe this can help you a little step further?


Egil


'
SUB PrintItem(wnd:window,ID:int)
'-------------------------------------------------------------------------------------
' Print selected Item
' ID = The Edit Control containing the text to print
'-------------------------------------------------------------------------------------
DEF buffer2[32766]:ISTRING
DEF printer:STRING
DEF startpg,endpg,copies,collate,hprinter:INT
startpg = 1 : endpg = 1 : copies = 1 : collate = 1

printer = PRTDIALOG(wnd,startpg,endpg,copies,collate)
hprinter = OPENPRINTER(printer,"Document","TEXT")

if(hprinter)
buffer2 = getcontroltext(wnd,ID)
WRITEPRINTER hprinter, buffer2
CLOSEPRINTER hprinter
endif

RETURN




Title: Re: Printing
Post by: LarryMc on May 24, 2017, 09:45:23 PM
Quote from: Andy on May 23, 2017, 11:56:26 PM
yet nothing is printed, hPrinter returns 0 (zero) which means it failed to open the printer - does that mean my printer is not supported?


It could mean your printer is configured for printing directly to the printer.  That will cause the same thing.   I duplicated that on my printer.
When I set it up to use the printers buffer then it returned the printers name and the printer command worked.
Title: Re: Printing
Post by: Andy on May 24, 2017, 09:48:57 PM
Larry,

Thanks for that, so is it a windows / printer setting somewhere? how do I change this?

Thanks
Title: Re: Printing
Post by: LarryMc on May 24, 2017, 09:56:10 PM
It COULD be a printer SETTING - in win7 it would be found START/Devices and Printers then select your printer.  On my HP is was under the Advanced tab.
If it is not a SETTING it COULD be the DESIGN of your printer and you are just out of luck as for as I know.
Title: Re: Printing
Post by: Andy on May 24, 2017, 10:02:56 PM
Thanks Larry,

I will have a look now.
Title: Re: Printing
Post by: LarryMc on May 24, 2017, 10:06:33 PM
@Egil
When I was working on the module to to allow the IWBasic IDE user to printout code and preview it first and set the font, color, and margins I had to jump through all kinds of hoops to get it to work.  I had to print it to hidden windows and use Listviews and such and it took around 1300 lines of code in one module(multiple subroutines) and there's probably some support routines scattered around outside that module.
It was so complicated and I haven't looked at it in so long I don't even know if I could figure out how it works right now. LOL.
Title: Re: Printing
Post by: Andy on May 24, 2017, 10:21:47 PM
Larry,

I found some of your code from this thread:
http://www.ionicwind.com/forums/index.php?topic=3044.msg25070#msg25070

It does indeed see my printer but there are 2 differences:

1. Does not return the printer's status.
2. On the output screen I get PrintProcessor as winprint not a hp one.

 
Title: Re: Printing
Post by: Egil on May 25, 2017, 02:12:01 AM
Quote from: LarryMc on May 24, 2017, 10:06:33 PM
@Egil
When I was working on the module to to allow the IWBasic IDE user to printout code and preview it first and set the font, color, and margins I had to jump through all kinds of hoops to get it to work.  I had to print it to hidden windows and use Listviews and such and it took around 1300 lines of code in one module(multiple subroutines) and there's probably some support routines scattered around outside that module.
It was so complicated and I haven't looked at it in so long I don't even know if I could figure out how it works right now. LOL.

LarryMc,
That really sounds complicated. But at least the CB code I posted, prints to my rather cheap printer. The only thing I miss is being able to specify margins. But that is something I'll try to figure out.



Title: Re: Printing
Post by: Andy on May 25, 2017, 06:40:01 AM
On my machine the printer driver is winprint not HP's.

Done the usual things such as trying to change the driver to HP Deskjet 2130 - no joy.
Downloaded the HP driver for it (which is an exe file by the way), but when I browse to what I think is the USB driver for it, it says it's not for 32 bit machines - although you do not get an option for 32 bit machines.

Help / suggestions anyone please!
Title: Re: Printing
Post by: Brian on May 25, 2017, 07:07:37 AM
Andy,

Have you read the WRITEPRINTER page in the help file? WRITEPRINTER doesn't work with GDI-only printers

Brian
Title: Re: Printing
Post by: Andy on May 25, 2017, 07:42:05 AM
Hi Brian,

Yes I read that, maybe this one is a GDI only printer?, just thought I would try as LarryMc's example on this post was also a HP.

Notepad prints, the example editor program sees the printer so you can select it - but no joy.

But I can print from the IWB IDE!
Title: Re: Printing
Post by: Brian on May 25, 2017, 08:13:28 AM
Andy,

This example from peterpuk works for me. I'm printing the output to a PDF printer, to save ink and paper

Brian
Title: Re: Printing
Post by: Andy on May 25, 2017, 11:14:34 PM
Brian,

Thanks for the code, it actually printed! - shows up in the printer job queue and of it goes!

I'm going to have to study this one, but thanks again.

Andy. :)


Title: Re: Printing
Post by: Brian on May 26, 2017, 02:27:24 AM
I agree with that - it DOES need a lot of studying! How practical the code is in the
real world is debatable, but it does prove your printer works, I guess

Brian
Title: Re: Printing
Post by: Egil on May 26, 2017, 04:27:44 AM
Quote from: Brian Pugh on May 26, 2017, 02:27:24 AM
How practical the code is in the real world is debatable, but it does prove your printer works, I guess

Brian,

That code is full of  good ideas, that ought to be be practical enough for most of us!
I have used most of my time this week trying to figure out how to set margins when printing text my own printer, and the code you posted showed me how. The API calls to GetDeviceCaps produce exactly what I want!

Thanks for sharing.


Egil
Title: Re: Printing
Post by: Andy on May 27, 2017, 04:58:27 AM
I've made a few changes to the program Brian shipped over.

1. I've put the printing section into a sub routine PrintTheDoc.
2. The MakeFont sub routine has an optional value for italics.

That is:

bigfont=MakeFont("Arial",30,1) - where the 1 specifies use italics, otherwise use
bigfont=MakeFont("Arial",30) - no italics.

This program reads a text file, and prints the data line by line.

I would suggest you print to pdf and then open it to check how it's come out.

Please let me know how it looks on your machine - if the lines of data are not correct, change the
myx value to something else - the bigger the number, the further across the page it goes.

Attached is the program and the text file it reads.

Andy.
Title: Re: Printing
Post by: Andy on May 28, 2017, 12:13:37 AM
I noticed when playing around with this printing program that sometimes (for no reason) the output
could be printed at an angle, sometimes underlined, even upside down!

Then I spotted this line:
def fnt:logfont

It was buried inside a sub routine, so I moved it to just after logfont is declared (at the top of the code).

As far as I can see (on my PC) the printing is now behaving itself.

Would someone please test it for me!
Send the output to PDF to save ink.
Attached are the files.

Thanks.


Title: Re: Printing
Post by: Egil on May 28, 2017, 01:52:08 AM
Hi Andy,

This is how it prints here.


Egil

Title: Re: Printing
Post by: Andy on May 28, 2017, 02:28:26 AM
Egil,

Thanks for trying it, it's okay on my pc, but it looks like there is some difference between yours and mine.

Wonder why printing to a pdf would show a difference?

Anyway, in the PrintTheDoc sub routine - line 195, if you change the value of myx i.e. increase the value to say 800 or 1000 it should move the lines across the page.

Also, you could change the number of data lines per page say from 27 to 20?

Thanks,
Andy.

Title: Re: Printing
Post by: Egil on May 28, 2017, 02:53:16 AM
Andy,

Been experimenting with the x and y values to see what happened with the positioning of the printed text. Also used another textfile for testing.
It then appeared that all printed text was senter aligned, regardless of what alignment the original text had. Also  printed to paper a couple of times, and the result was the same as with the PDF driver. (Bullzip PDF Printer).

I am also a little confused about the units used for the x and y values ( pixels or twips). I assume you mean pixels???

You posted while I was writing the above text. And your suggestions was exactly what I did for my experiments.
If I remember it right 1440 twips = 1 inch. So I'll experiment a little assuming the units should be i twips.



Egil
Title: Re: Printing
Post by: Egil on May 28, 2017, 03:11:54 AM
Copied my last post into NotePad to make a new test file.
Then I changed the x value and the font size before compiling and printing. The result is shown below.

Suggest that a variable specifying the maximum allowed length of any line, when considering the margins, and then fill the line with as many words there is room for, then print the line, and repeat this until the whole document is printed.

In MiniBasic the RichEdit controll class has a member doing just that. It is called with the margin value in twips. Very easy for the users.... ::)
Title: Re: Printing
Post by: Andy on May 28, 2017, 04:34:30 AM
Hi Egil,

Thanks again for testing!

I'd never heard of twips before, this printing business came about because the person who wanted the login program for the school wanted a print button on the screen so he could print off a log file.

In this instance, each line is short, but in view of the differences we are seeing, I've put in some fields so he can change the X offset, font sizes, and number of lines per page.

I will have to guide him with these values, and wait to see how he gets on with printing as I do not know what printers they have at the school.

Andy. :)
 
Title: Re: Printing
Post by: Egil on May 28, 2017, 04:56:49 AM
OK Andy,

Have you received the emails I sent you?

Egil
Title: Re: Printing
Post by: Andy on May 28, 2017, 05:16:42 AM
Hi Egil,

Partly my fault, forgot to tell you my new email address!

If you click on my name it shows the new one, however gone into the old ones and just reading them now.

Title: Re: Printing
Post by: Egil on May 28, 2017, 08:21:34 AM
Quote from: Andy on May 28, 2017, 04:34:30 AM
I'd never heard of twips before,

It's a typographical term, very often used when setting up printers. Maybe Brian know more about that.
Here is what Wikipedia says: https://en.wikipedia.org/wiki/Twip (https://en.wikipedia.org/wiki/Twip).


Egil
Title: Re: Printing
Post by: billhsln on May 28, 2017, 09:58:44 AM
Just a thought, you could set up your output in an RTF document and then print from Word.  Using CreateComObject, you should be able to adjust margins and other stuff and then print the RTF.

I have used the CreateComObject to read an Excel spread sheet and I know there is a way to work with Word files using this.

Of course, this brings up another question from me, can you put a picture in an RTF directly?

Bill
Title: Re: Printing
Post by: Andy on May 28, 2017, 12:15:15 PM
Bill,

Thanks for that, already had a button to open it in notepad but the person wanted it printing directly from the program I wrote for him.

Thanks,
Andy.
Title: Re: Printing
Post by: Egil on May 28, 2017, 01:32:29 PM
Andy,

Must be getting old here. Was out walking the dog, and all the fresh air usually clears my mind...

Many years ago I struggled when trying to make a print routine with EB, very similar to the printing job you are doing. Now I remember that it was solved by importing readings from an external sensor into a RichEdit Control, and  sending the resulting list to a printer using @RTPRINT.

Can't find that source code, but look up @RTPRINT in the IWB user manual and use the example shown there when your "Print" button is clicked.


Egil
Title: Re: Printing
Post by: LarryMc on May 28, 2017, 03:24:20 PM
Andy
There is a way to get they x,y offsets of a printer without knowing the type of printer in advance.
Here is the subroutine I wrote for the IWBasic IDE that gets the User's default (selected) printer's info  for setting of the print preview and printout  functions.  You might be able to study and use this.

TYPE SPRINTDLG,1
    DEF lStructSize as UINT
    DEF hwndOwner as UINT
    DEF hDevMode as UINT
    DEF hDevNames as UINT
    DEF hDC as UINT
    DEF Flags as UINT
    DEF nFromPage as WORD
    DEF nToPage as WORD
    DEF nMinPage as WORD
    DEF nMaxPage as WORD
    DEF nCopies as WORD
    DEF hInstance as UINT
    DEF lCustData as UINT
    DEF lpfnPrintHook as POINTER
    DEF lpfnSetupHook as POINTER
    DEF lpPrintTemplateName as POINTER
    DEF lpSetupTemplateName as POINTER
    DEF hPrintTemplate as UINT
    DEF hSetupTemplate as UINT
ENDTYPE


sub getprinterdefault()
DEF strPrinter[32] as ISTRING
strPrinter[0] = NULL
SPRINTDLG pd
ZeroMemory(pd,LEN(SPRINTDLG))
pd.lStructSize = LEN(SPRINTDLG)
pd.nCopies=1
pd.Flags = PD_RETURNDC|PD_RETURNDEFAULT
PrintDlg(pd)
_fpreset()
IF pd.hDevNames
ppDZL = GetDeviceCaps(pd.hdc,PHYSICALOFFSETX)     ' this is x offset - set to left margin
ppDZR = ppDZL                                                               ' set right margin to same as left
ppDZT = GetDeviceCaps(pd.hdc,PHYSICALOFFSETY)     ' this is y offset - top margin
ppDZB = ppDZT                                                               ' set bottom margin to same as top
ppPrnPPI_x = GetDeviceCaps(pd.hdc,LOGPIXELSX)       ' this is x pixels per inch
ppPrnPPI_y = GetDeviceCaps(pd.hdc,LOGPIXELSY)       ' this is y pixels per inch
/* you don't need this part
pointer pString = GlobalLock(pd.hDevNames)
pointer pTemp = pString
pString += #<DEVNAMES>pString.wOutputOffset
strPrinter = #<STRING>pString
if(strPrinter[0] <> "\\")
pTemp += #<DEVNAMES>pTemp.wDeviceOffset
strPrinter = #<STRING>pTemp
endif
setcontroltext ppwin,ppwin_eSelectedPrinter,strPrinter
GlobalFree(pd.hDevNames)
*/
ENDIF
ENDSUB
Title: Re: Printing
Post by: Andy on May 29, 2017, 06:49:01 AM
Larry,

Got my head around the code - thanks.

I'm now trying to work out how many printable lines on an A4 page.

That is, for each line the font could be say.... 12.

Given the printable width and height (in inches) and the font (in points), how do you calculate how many lines you could actually print?

Title: Re: Printing
Post by: Egil on May 29, 2017, 08:04:58 AM
Quote from: Andy on May 29, 2017, 06:49:01 AM
how do you calculate how many lines you could actually print?

The easiest way will be to use GETTEXTSIZE to get the height of the characters and divide available height with it.

Egil
Title: Re: Printing
Post by: LarryMc on May 29, 2017, 08:19:39 AM
Egil is right.
But you'll have to address word wrap.
Title: Re: Printing
Post by: Andy on May 29, 2017, 11:54:36 PM

I've used gettextsize and it returns a value of 22 pixels in height when using the same size font as printing.

The page height in inches is 11
In pixels the height is 6,600   
Printable lines 300? - I could go for 30 but not 300?  ???

Inches:
pphmm * 0.0393701   (where pphmm is height in millimeters)

Inches to pixels:
(pphmm * 0.0393701) * ydpi  (where ydpi = 600)

Printable lines:
((pphmm * 0.0393701) * ydpi) / tHeight  (where tHeight is 22)

I must be going wrong somewhere!



Title: Re: Printing
Post by: Brian on May 30, 2017, 02:43:10 AM
Andy,

Have a look at this code - it's from the  master, Sapero. It might help you, or just confuse you!

The resulting box is the right dimension on my screen

Brian
Title: Re: Printing
Post by: Andy on May 30, 2017, 04:51:44 AM
Biran,

Thanks for finding the code - he was indeed the master.

Actually, I find it rather easy to understand - for once!

I'll play around with it.

Thanks,
Andy.
Title: Re: Printing
Post by: Andy on June 03, 2017, 03:49:04 AM
Well, still working on some aspects of printing.

With the code Brian and Larry have posted, I've cobbled together a library file called:

PrinterDetails.

Copy the lib file to the IWBDev\Libs folder and compile the iwb code.

Does anyone think this could be useful?

It may take a second or so to return some details.

Andy.
Title: Re: Printing
Post by: Brian on June 03, 2017, 05:32:08 AM
Andy,

It's "Jobs in the Garden" day today, so I will look at your lib later, but a SepFile is a string that specifies the name of the file used to create the separator page. This page is used to separate print jobs sent to the printer

Brian
Title: Re: Printing
Post by: ckoehn on June 03, 2017, 06:19:02 AM
Andy,

I haven't looked at your library, but IWBasic needs a printer library.  Including a printer graphics library. All this could be included if there is a printer DC that is available, which it looks like there is.  I would work on it, but the chemo messed my nerve endings up and its hurts to type very much.  Can't tell when I'm pressing a key either so there is a lot of back spacing.

Later,
Clint
Title: Re: Printing
Post by: Andy on June 03, 2017, 07:04:04 AM
Brian,
Don't let those weeds grow too much.

Clint,
Glad to hear from you, take it easy!

I will look at adding more in tomorrow when l'll have more time including the DC.
Title: Re: Printing
Post by: Brian on June 03, 2017, 07:29:43 AM
Andy,

Here's a way of enumerating all printers, posted by Michael Hartlef about 10 years ago, I've tidied it up for use with IWB, and changed a few things

I've also added in the method of getting your Default Printer, as well, so you could ask for the default printer, and use the return string when setting up the printer DC

Brian

(Lawns cut, edges strimmed, weedkiller down, car vacuumed, tomato plants watered - Good boy!)
Title: Re: Printing
Post by: Andy on June 03, 2017, 08:14:39 AM
Brian,

All that and the gardening done, someone's going to get brownie points at home.

Enumerating printers begs the question - should we only be looking for physical printers?

In Devices and Printers (Control Panel) I have 4 printers listed, but only one is a physical printer, the HP, the others are:

Fax,
Microsoft print to PDF
Microsoft XPS document writer

Should we ignore these others?

Title: Re: Printing
Post by: Brian on June 03, 2017, 08:28:11 AM
I suppose the quick answer is: Depends where you want to print to!

I've been using the PDF driver lately

Brian
Title: Re: Printing
Post by: Andy on June 04, 2017, 04:14:35 AM
Well, I've got this far up to now....



OpenThePrinter("MyDocument") 'Also returns uint of printer DC

PrintLine(1000,800,"This is a line - Page 1","")
PrintLine(1000,900,"This is second line","")

   NewPage()

PrintLine(1000,800,"This is first line - Page 2","")
PrintLine(1000,900,"And this is second line","")

CloseThePrinter()


Working on the fonts and sizes next.
Title: Re: Printing
Post by: Andy on June 04, 2017, 06:20:29 AM
Here is the next part.

Copy the lib folder to the IWBDev\libs folder.

In the IWB source file, read from ***** Part 2 *********

This is giving some basic line printing, and able to set fonts, and sizes.

You may have to play around with the X and Y's:

PrintLine(1000,800,"This is a line - Page 1","")

Where PrintLine is (X across, Y down, Text to print,"")

Again, I would suggest you print to PDF to save ink.
Title: Re: Printing
Post by: ckoehn on June 04, 2017, 06:47:22 AM
Keep up the good work Andy.  The "lib" include and "External" lines could be put in an "inc" file.  Then all you would have to do is "#include "Printer.inc".

Later,
Clint
Title: Re: Printing
Post by: Andy on June 04, 2017, 07:22:10 AM
Thanks for that Clint.

Yes I forgot about an include file, so that will be next on the list.

Cheers.
Title: Re: Printing
Post by: Brian on June 04, 2017, 07:54:08 AM
Andy,

Just been messing with changing font names, and I can't get it to change at all, even to common fonts like Times New Roman or Arial

Going out for the afternoon now - sorry

Brian
Title: Re: Printing
Post by: Andy on June 04, 2017, 08:14:24 AM
Enjoy the afternoon!

I will look at the font issue tomorrow.

Thanks for having a look.

Andy.
:)
Title: Re: Printing
Post by: Andy on June 05, 2017, 12:48:01 AM
I found the font problem.

1. I needed to return a UINT value instead of an INT.

2. The LOGFONT define is wrong!

I looked at all the examples and they all say:
CHAR lfFaceName[LF_FACESIZE]

I changed it to a string:
STRING lfFaceName

Now the fonts work.

So LOGFONT should look like this (just in case you use it):

TYPE LOGFONT
INT lfHeight
INT lfWidth
INT lfEscapement
INT lfOrientation
INT lfWeight
CHAR lfItalic
CHAR lfUnderline
CHAR lfStrikeOut
CHAR lfCharSet
CHAR lfOutPrecision
CHAR lfClipPrecision
CHAR lfQuality
CHAR lfPitchAndFamily
string lfFaceName
ENDTYPE



Title: Re: Printing - fonts now working
Post by: Andy on June 05, 2017, 02:05:38 AM
Here is the corrected version with fonts working.

Title: Re: Printing
Post by: Brian on June 05, 2017, 02:16:00 AM
Andy,

According to my Win 32 API book (1,500 pages, and counting), lfFaceName is indeed a string, which specifies the name of the typeface. If it is NULL, the GDI attempts to select the default device typeface

Brian
Title: Re: Printing
Post by: Andy on June 05, 2017, 02:29:29 AM
Brian,

Thanks for confirming that, it drove me stupid all yesterday.

Cheers,
Andy.
Title: Re: Printing
Post by: Andy on June 05, 2017, 04:44:04 AM
I've sine changed it to:

istring lfFaceName[32]

As MS state the string must not be longer than 32 characters.

TYPE LOGFONT
INT lfHeight
INT lfWidth
INT lfEscapement
INT lfOrientation
INT lfWeight
CHAR lfItalic
CHAR lfUnderline
CHAR lfStrikeOut
CHAR lfCharSet
CHAR lfOutPrecision
CHAR lfClipPrecision
CHAR lfQuality
CHAR lfPitchAndFamily
istring lfFaceName[32]
ENDTYPE