The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: allynm on October 29, 2009, 02:30:19 AM

Title: printing a file on my printer
Post by: allynm on October 29, 2009, 02:30:19 AM
Hello everyone:

I know the question I have has a very long history on the forum.  I have searched a number of previous posts on this subject.  Please don't tell me that I should seach the forum...I have.  I have looked at a lot of code you experts have contributed.  Still....

I have an ASCII file named "Mystuff.txt".  I would like to print this file with my trusty HP laserjet.  I'm not trying to do anything fancy, just print on the printer what I see on my screen.

BUT, I don't want to go thru Notepad to do it using the SHELL macro or its relatives. 

How do I INVOKE a Print dialog and have it print my little Mystuff file?  I spent a very rainy day in Pennsylvania messing around with Microsoft's suggestions on this, and have nothing to show for it but a sea of error messages....

Grateful, as always,

Mark Allyn, a pretty serious amateur professional newbie
Title: Re: printing a file on my printer
Post by: BlackVortex on October 29, 2009, 03:21:49 AM
I don't have a printer so I can't help with definitive code, but until someone with firsthand knowledge comes, do you really want/need to show a print dialog for the user to select options ?

Try this :
PrintDlgEx function
http://msdn.microsoft.com/en-us/library/ms646942%28VS.85%29.aspx
This seems to just get the information, not do the actual printing.

For simpler printing I would first try to access a printer and get a handle with
OpenPrinter function
http://msdn.microsoft.com/en-us/library/dd162751%28VS.85%29.aspx
Title: Re: printing a file on my printer
Post by: hutch-- on October 29, 2009, 03:52:12 AM
Mark,

This is not exactly what you were after but it does print to a default printer correctly, its the complete code for a printing DLL complete with preview window and font settings. You call the DLL from this procedure,


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

print_text proc lprTxt:DWORD,hParent:DWORD

    mrm prWnd,hParent                   ; copy parent address to global
    mrm prTxt,lprTxt                    ; copy text address to global

    invoke preview_win,prWnd

    ret

print_text endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤


This display of the DLL when it is called by an external app is in a richdit control set up for printing. You have cursor and page up and down navigation but no scroll bar. The guts of it are no joy but it does work OK on my HP Laser Jet and any of the PDF printer drivers I have installed.

I don't class it as a fully finished app but its close.
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 29, 2009, 01:01:54 PM
Mark,
            Do you want to print using TextOut ? If yes you need to get a PrinterDC to use TextOut.
            To get a PrinterDC you need to invoke CreateDC but you need  DriverName and PrinterName ok ? To get this 2 names use GetDefaultPrinter, OpenPrinter and GetPrinter. With GetPrinter you have DriverName and PrinterName and then CreateDC and so on
RuiLoureiro
Title: Re: printing a file on my printer
Post by: allynm on October 29, 2009, 02:01:49 PM
Hi Hutch, RuiLoureiro, and BlackVortex:

Thank you all for your help on this beginner problem.  I will try the Hutch DLL later today.  I bet it is pretty cool.  Hutch was right in thinking that I was trying to do more of the coding on my own--I'm trying bit by bit (literally!) to get the basics of the API's.  In Hutch's snippet there is this mrm instruction.  I have never seen it....what is it?  I can see what it does from the comments...

Coming on to RuiLoureiro, yes I wanted to do TextOut as you surmised.  I was recoding yesterday off a C program Microsoft posted on its developer site.  Got nowhere good.  I need to check, but I'm pretty sure that a couple of RuiLoureiro's API calls were not part of the MSFT program even though the model program used TextOut.

Thanks again,

Mark Allyn
Title: Re: printing a file on my printer
Post by: jj2007 on October 29, 2009, 02:09:04 PM
mrm is part of \masm32\macros\macros.asm

     mrm MACRO m1, m2
        mov eax, m2
        mov m1, eax
      ENDM

If it's not speed critical, m2m is usually shorter, and does not trash eax:

     m2m MACRO M1, M2
        push M2
        pop  M1
      ENDM
Title: Re: printing a file on my printer
Post by: allynm on October 29, 2009, 03:07:58 PM
Hi JJ-

I was afraid of that!  I looked for a Macro on MASM32 Help before I posted my query but I didn't see it.

Thanks,
Mark Allyn
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 29, 2009, 03:58:47 PM
Quote from: allynm on October 29, 2009, 02:01:49 PM
Coming on to RuiLoureiro, yes I wanted to do TextOut as you surmised.  I was recoding yesterday off a C program Microsoft posted on its developer site.  Got nowhere good.  I need to check, but I'm pretty sure that a couple of RuiLoureiro's API calls were not part of the MSFT program even though the model program used TextOut.
Hi Mark,
              AFAIK, all APIs are MSFT: GetDefaultPrinter, OpenPrinter, GetPrinter, CreateDC and TextOut.
             You need also: StartDoc, StartPage , ...TextOut...  ..., EndPage, EndDoc.

LATER: to get the printer device context you can use invoke PrintDlg. In this case you dont need to CreateDC etc
RuiLoureiro
Title: Re: printing a file on my printer
Post by: MichaelW on October 29, 2009, 04:06:11 PM
The attachment is a small console app that prints a file on a user-selected printer. The file can be specified on the command line or just dropped on the EXE. I did not attempt to implement any sort of WYSIWYG, and depending on the font selection the printed text may be too small to reasonably read. In my limited testing the app worked OK, but since I'm not sure about multiple details errors in the code are likely.
Title: Re: printing a file on my printer
Post by: dedndave on October 29, 2009, 04:34:53 PM
cool Michael - thanks

btw - am i the only one who is reminded of Ruy Lopez when i see the "RuiLoureiro" nic ? - lol

(http://www.worldchesslinks.net/lopez_01.jpg)
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 29, 2009, 06:57:35 PM
Quote from: dedndave on October 29, 2009, 04:34:53 PM
btw - am i the only one who is reminded of Ruy Lopez when i see the "RuiLoureiro" nic ? - lol
dedndave,
                 what about you ? Are you trying to play ? Iam not a kid dave. Yes you are the only one
RuiLoureiro
Title: Re: printing a file on my printer
Post by: dedndave on October 29, 2009, 07:31:57 PM
don't get all upset
Ruy Lopez was a great chess player from the 1500's
the most popular chess opening used today is called the "Ruy Lopez"
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 29, 2009, 07:41:14 PM
Ok dedndave,
                     now i understood the idea  :U
Rui

Title: Re: printing a file on my printer
Post by: hutch-- on October 30, 2009, 06:43:25 AM
For MArk,

There is an easy way to test the DLL I posted. Use QE and go to the directory that the DLL and code are in.

Select "Load Script" from the File menu.

Open the script "runprint.qse".

Open a file with QE.

Press F12.

The DLL should them display the text file ready to print.
Title: Re: printing a file on my printer
Post by: allynm on October 30, 2009, 12:57:52 PM
Hi Hutch -

Thanks for the tip.  I have a pretty open day today and I will give it a try.  I'm also going to try out MichaelW's code too. 

Mark Allyn
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 30, 2009, 03:44:36 PM
I wrote this Printer4 example to show how to use TextOut. Try it.
Procs:  GetPrinterDC is used to get the PrinterDC and set a Font for 50 lines by 120 columns
           PrintText uses TextPrint to print each string line
;-----------------------------------------------------------------------------------
PrintText           proc

                    cmp     _hpdc, 0
                    jne     short @F
                    ret
                   
@@:             mov    _di.cbSize, SIZEOF _di
                    mov    _di.lpszDocName, offset _DocTitle
                    mov    _di.lpszOutput, NULL
                    mov    _di.fwType, NULL
                    ;
                    invoke  StartDoc, _hpdc, addr _di
                    cmp     eax, 0
                    jg      short @F
                    ret
                   
@@:            invoke  StartPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc
                    ret

                    ; »»»»»»»»»»
                    ; Print Text
                    ; »»»»»»»»»»
@@:             invoke  TextPrint, offset _TxtToPrint0, 1, 1
                    invoke  TextPrint, offset _TxtToPrint1, 3, 10
                    invoke  TextPrint, offset _TxtToPrint2, 20, 40
                    invoke  TextPrint, offset _TxtToPrint3, 40, 1
                    invoke  TextPrint, offset _TxtToPrint4, 50, 80                   
                    ;   
                    ;
                    invoke  EndPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc                   
                    ret
                    ;
@@:             invoke  EndDoc, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ret
                   
@@:             invoke   DeleteObject, _hpFont
                    ;
                    invoke   DeleteDC, _hpdc   
                    mov      _hpdc, 0
                    ret
PrintText           endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
TextPrint           proc    pTxt:DWORD, Lin:DWORD, Col:DWORD

                    invoke  GetTextMetrics, _hpdc, addr _tm
                    ;
                    mov     ecx, _tm.tmHeight
                    mov     eax, Lin
                    sub     eax, 1
                    mul     ecx                 
                    mov     _PosPrnY, eax
                    ;
                    ;
                    ;
                    mov     ecx, _tm.tmAveCharWidth
                    mov     eax, Col
                    sub     eax, 1
                    mul     ecx
                    mov     _PosPrnX, eax

                    mov     ebx, pTxt
                    invoke  TextOut, _hpdc, _PosPrnX, _PosPrnY, ebx, [ebx - 4]
                   
                    ret
TextPrint           endp
;
Files below: Printer4.zip (exe & asm) ans rsrc.rc
Title: Re: printing a file on my printer
Post by: allynm on October 30, 2009, 06:40:25 PM
Hi RuiLoureiro-

Thank you so much for helping me the way you have.  I have been struggling with a couple of API books and just was not making any headway at all.  I will test drive your code for sure.  I tried the code MichaelW posted day before yesterday and it works nicely.  No surprise there of course.  He uses DrawText, not TextOut..and there are some other interesting differences such as how the device context is obtained that I can see.  So, the two solutions are very informative compared side by side.  For someone like me this is extremely helpful! 

I still haven't tried Hutch's DLL, but that is part of my agenda.   

Regards,

Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 30, 2009, 09:21:10 PM
Quote from: allynm on October 30, 2009, 06:40:25 PM
Hi RuiLoureiro
Thank you so much for helping me the way you have.   
Hi Mark,
           Nothing at all.
           If you have some problems about the code, please post it.
           As i said before, if you dont want to select de Printer, (you want to use the default one)
           you can use  GetDefaultPrinter, OpenPrinter, GetPrinter, CreateDC. They are in
           winspool.inc. If you are using Quick Editor (Hutch editor), type it there and press F1.
           I can post the example if you want.
RuiLoureiro
Title: Re: printing a file on my printer
Post by: allynm on October 31, 2009, 03:12:23 PM
Hi RuiLoureiro,

I downloaded and ran your Printer4 program.  Program runs fine.  If I wanted to modify Printer4 to print a file rather than the strings embedded in the .data section, what would you suggest I do to call your PrintText proc?

Michael W's code works fine too, but prints very tiny on my HP laser jet.  Even when I adjust the font size on the Properties box I still get tiny output.  I can't figure out how to adjust the dimensions of the rect and increase its size....still playing with it.

Thanks again, RuiLoureiro.  The quality of your code makes me realize how far I still have to go....

Mark
Title: Re: printing a file on my printer
Post by: hutch-- on October 31, 2009, 03:36:59 PM
Mark,

Give that DLL a blast and you will see why I do it that way. I used the basic guts of the printer code in QE and put it into a Window that displays the page in pretty much the way it looks when it prints. If I ever get in front time wise I will finish that app off and probably make a library module out of it as it saves messing around each time you write an app.
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 31, 2009, 05:57:36 PM
Quote from: allynm on October 31, 2009, 03:12:23 PM
If I wanted to modify Printer4 to print a file rather than the strings embedded in the .data section, what would you suggest I do to call your PrintText proc?
Hi Mark,
           Thats the idea. One way is to replace TextPrint by DrawTextEx used by MichaelW (i never used till now). The first DrawTextEx to format the text and the 2nd to draw like MichaelW did.

            Another way is 1.- Read the file to a Buffer1       2. - Format the text to a Buffer2
             3. If each sheet has 50 lines by 120 columns count how many pages to print and
             4.- write a proc to print pages of N strings. Is there another best way ... dont know.
             Give me time  and let me try a quick example i will post here ok ?
Rui
Title: Re: printing a file on my printer
Post by: allynm on October 31, 2009, 06:21:42 PM
Hi Hutch & RuiLoureiro-

I will give your DLL a try this afternoon.  I am gradually getting up the learning curve on this printer stuff.  Very slow.  RuiLoureiro has been quite helpful..as you can see.  Kudos also to MichaelW.  I'm still working on understanding what he did.

RuiLoureiro-- Your proposal sounds quite logical.  I couldn't figure out why MichaelW was using DrawTextEx twice.  Your comment on this was helpful. 

Regards
Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 31, 2009, 06:26:22 PM
Here is Printer6.zip (asm &exe) uses the same rsrc.rc.
Printer6 uses DrawTextEx. Try it and say something.
Now, PrintText is this:
PrintText           proc

                    cmp     _hpdc, 0
                    jne     short @F
                    ret
                   
@@:                 mov    _di.cbSize, SIZEOF _di
                    mov    _di.lpszDocName, offset _DocTitle
                    mov    _di.lpszOutput, NULL
                    mov    _di.fwType, NULL
                    ;
                    invoke  StartDoc, _hpdc, addr _di
                    cmp     eax, 0
                    jg      short @F
                    ret
                   
@@:                 invoke  StartPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc
                    ret

                    ; »»»»»»»»»»
                    ; Print Text
                    ; »»»»»»»»»»
@@:                 ;invoke  TextPrint, offset _TxtToPrint0, 1, 1
                    ;invoke  TextPrint, offset _TxtToPrint1, 3, 10
                    ;invoke  TextPrint, offset _TxtToPrint2, 20, 40
                    ;invoke  TextPrint, offset _TxtToPrint3, 40, 1
                    ;invoke  TextPrint, offset _TxtToPrint4, 50, 80                   

                    invoke  GetDeviceCaps, _hpdc, HORZRES
                    dec     eax
                    mov     _rc.right, eax

                    invoke  DrawTextEx, _hpdc, addr _Text, -1, addr _rc,
                                        DT_CALCRECT or DT_EDITCONTROL or \
                                        DT_EXPANDTABS or DT_WORDBREAK, 0

                    invoke  DrawTextEx, _hpdc, addr _Text, -1, addr _rc,
                                        DT_EDITCONTROL or DT_EXPANDTABS or DT_WORDBREAK,
                                        0
                    ;   
                    ;
                    ;
                    invoke  EndPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc                   
                    ret
                    ;
@@:                 invoke  EndDoc, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ret
                   
@@:                 invoke   DeleteObject, _hpFont
                    ;
                    invoke   DeleteDC, _hpdc   
                    mov      _hpdc, 0
                    ret
PrintText           endp
;-------------------------------------------------------
                  LATER:  now _Text is a null terminated string
Rui
Title: Re: printing a file on my printer
Post by: allynm on October 31, 2009, 07:04:11 PM
Hi Hutch & RuiLoureiro-

First Hutch:  I tried using QE the way you suggested.  I'm not very familiar with QE GUI so I know I'm not doing the right thing... problem is that when I hit F12 I get a message saying that it can't find your DLL.  The DLL is definitely in the folder, but I can't seem to link it.  I guess I could try the code you sent initially...but I'd like to try to use the GUI as a learning drill. 

Second RuiLoureiro:  WOW.  Very impressive. 

Regards,
Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on October 31, 2009, 10:01:07 PM
MichaelW,
                This is to you: can i use DrawTextEx to print more than one page. How ?
                 
                 Thanks MichaelW
RuiLoureiro
Title: Re: printing a file on my printer
Post by: jj2007 on November 01, 2009, 01:43:38 AM
I have implemented a print function for a RichEdit control, based on The Old New Thing (http://blogs.msdn.com/oldnewthing/archive/2007/01/12/1455972.aspx).

It works in principle, see the attached PDF, but:

1. I can't get ...
invoke SendMessage, hEdit, EM_SETTARGETDEVICE, 0, eax
... to generate any meaningful effect.

2. The rc.right and rc.bottom values don't work as expected, i.e. if I use the standard values returned from GetDeviceCaps, prtDlg.hDC, PHYSICALWIDTH,
then the "printer", PDFCreator, uses only one third of the page width and height. I am stuck...

Any ideas? Full code is attached - search "dirty tricks".
Title: Re: printing a file on my printer
Post by: farrier on November 01, 2009, 07:05:44 AM
jj2007,

When using EM_SETTARGETDEVICE the third parameter should be either the hDC of the edit control or the printer.  In the example you gave, it should be the hDC of the printer.  I'm going to try to use your code and the code in the "The Old New Thing" article.  Thanks for that link.

farrier
Title: Re: printing a file on my printer
Post by: jj2007 on November 01, 2009, 09:36:41 AM
Quote from: farrier on November 01, 2009, 07:05:44 AM
When using EM_SETTARGETDEVICE the third parameter should be either the hDC of the edit control or the printer.  In the example you gave, it should be the hDC of the printer.  I'm going to try to use your code and the code in the "The Old New Thing" article.  Thanks for that link.

farrier

Thanks, farrier, you are right. However, when I use...

Quotemov eax, cxPhys               ; set line width
   shr eax, 2                     ; Test
   sub eax, 127                  ; 2 mm margin right
   invoke SendMessage, hEdit, EM_SETTARGETDEVICE, prtDlg.hDC, eax
   .if eax==0
      MsgBox 0, "Error: eax==0", "Hi", MB_OK      ; never seen
   .endif

... the edit window gets narrowly wrapped but the printer output is still the same. And the message has nothing to do with the width and height problem... mysteries of Windows
Title: Re: printing a file on my printer
Post by: farrier on November 01, 2009, 12:10:19 PM
jj2007,

What you described makes perfect sense.  You get the characteristics of the printer with:

mov cxPhys, rv(GetDeviceCaps, prtDlg.hDC, PHYSICALWIDTH)

If you left this value alone, and used EM_SETTARGETDEVICE to set the screen to display your text in the same way the printer will print it, the display and print will look the same.

When you (shr eax, 2) and use EM_SETTARGETDEVICE it leaves the printer characteristics alone and set the screen to half the width of the printed output, minus 128.

EM_SETTARGETDEVICE here does not affect the printer output, just the display.  You use EM_SETTARGETDEVICE to give you WYSIWYG: so that the display will look like the printer output.

Also, if you want to set the right margin of the printed output, you must change the fr.rc.right

hth,

farrier
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 01, 2009, 01:58:14 PM
Hi JJ,
        Why not to open a new topic. Try Printer8 and say something ok ? Thanks

MichaelW,
                This is to you: can i use DrawTextEx to print more than one page. How ?
                 
                 Thanks MichaelW

Mark,
                 I wrote a quick example Printer8
                 Try Printer8. Does it work correctly in your printer ?

                  LATER: run print8 and select a text file and print it to test. works ?
Rui
Title: Re: printing a file on my printer
Post by: allynm on November 01, 2009, 04:48:13 PM
Hi RuiLoureiro -

Just downloaded it.  I had to grade a bunch of homework assignments, so I'm a bit slow catching up with you.

I'll let you know shortly.

I'm assuming you figured out how to do multiple pages using DrawText??

Regards,

Mark
Title: Re: printing a file on my printer
Post by: allynm on November 01, 2009, 05:00:53 PM
Hi again RuiLoureiro-

Well, I tried it.  Maybe I'm doing something wrong.  But, when I open the GetPrinter DC menuitem and press OK I get a message that says I need to pick a font.  But, it doesn't actually let me choose a font.  The Choose File menuitem opens up a listview box the way I would expect and appears to let me select a file.  When I use the Print Text menuitem, my printer starts up and but it doesn't print the file I selected it just runs a page thru my Laser Jet and stops.  It stops OK after passing one page thru the printer drive.

Printer8 zip file only had the .exe so I don't have any thoughts or questions about the asm file.

Please let me know you received this.  I will be happy to help in any way I can. 

Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 01, 2009, 05:36:16 PM
Quote from: allynm on November 01, 2009, 04:48:13 PM
I'm assuming you figured out how to do multiple pages using DrawText??

Hi Mark,
             the answer is no. I am using TextOut to do the work

              Please download the new Printer8.
              1.  when the prog starts you should choose the printer. ok ? no ?
              2. now goto Choose File menuiten and choose an .asm or .rc file (dont choose .exe or .obj etc. doesnt work)
              3. now goto Test Printer and choose Print Test. Doesnt print the file you choose ?
                  In my comp it prints correctly. After the first page you may choose to cancel the printing.
               4. After the printing you nedd  Get Printer DC again before choose another file etc. because i delete DC
              If it works correctly i can give you the all files (exe & asm) if you want.   
Thanks
Rui               
Title: Re: printing a file on my printer
Post by: allynm on November 01, 2009, 05:44:11 PM
Hi RuiLoureiro-

I get partway through and then it fails.  I am getting a MessageBox labeled "Test 5" and the message says "Estou acqui".   Can't close the box....

I will keep trying until we get this thing fixed...

Regards,
Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 01, 2009, 05:54:21 PM
Quote from: allynm on November 01, 2009, 05:44:11 PM
I get partway through and then it fails.  I am getting a MessageBox labeled "Test 5" and the message says "Estou acqui".   Can't close the box....

I will keep trying until we get this thing fixed...

Mark,    yes but download the last Printer8 i posted
Rui
Title: Re: printing a file on my printer
Post by: allynm on November 01, 2009, 06:06:12 PM
Hi RuiLoreiro :

IT WORKED!!  Got multiple pages of MichaelW's PrintTextFile asm file.  It looks as if you've nailed the solution.

I'm very curious about how Printer8 works.  Is it only good for asm files?

Congratulations,

Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 01, 2009, 06:13:45 PM
Quote from: allynm on November 01, 2009, 06:06:12 PM
Hi RuiLoreiro :
IT WORKED!!  Got multiple pages of MichaelW's PrintTextFile asm file.  It looks as if you've nailed the solution.
I'm very curious about how Printer8 works.  Is it only good for asm files?
Mark,
           Ok thanks. It is to print Text Files: each line end in CRLF (return linefeed).
           But Printer8 has one problem: doesnt convert TABS. but Printer9 does.
           Now you can see what i did in Printer8 (asm file)
;................................................................................................................
PrintText           proc     

                    mov     _PageNumber, 0

                    cmp     _hpdc, 0
                    jne     short @F
                    ret

@@:                 mov     ebx, offset _bufferTxt
                    cmp     dword ptr [ebx - 4], 0
                    jne     short @F
                    ret
                   
@@:                 mov    _di.cbSize, SIZEOF _di
                    mov    _di.lpszDocName, offset _DocTitle
                    mov    _di.lpszOutput, NULL
                    mov    _di.fwType, NULL
                    ;
                    invoke  StartDoc, _hpdc, addr _di
                    cmp     eax, 0
                    jg      short @F
                    ret
                   
@@:                 call    PrintPage
                    jnc     short @B
                    ;
                    ; Remove
                    ;   
                    invoke   DeleteObject, _hpFont
                    ;
                    invoke   DeleteDC, _hpdc   
                    mov      _hpdc, 0

                    ; »»»»»»»»»»»»»»»»»»»
                    ; Destroy text buffer
                    ; »»»»»»»»»»»»»»»»»»
                    mov     ebx, offset _bufferTxt
                    mov     dword ptr [ebx - 4], 0

                    ret
PrintText           endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
PrintPage           proc
                    LOCAL   LinCor:DWORD, MaxLin:DWORD
                    ;
                    invoke  StartPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc
                    stc
                    ret

@@:                 mov     MaxLin, 49             ;_mLines
                    mov     LinCor, 2

                    inc     _PageNumber
                    invoke  CnvToRcl, _PageNumber, addr _PageNum

                    invoke  RclRclCpy, addr _MsgPage, addr _PageBuf 
                    invoke  RclRclAdd, addr _PageNum, addr _PageBuf 

                    invoke  TextPrint, addr _PageBuf, 1, 95

                    ;
_start:             call    GetNxtLin
                    jnc     short @F
                    ;
                    ; Fim
                    ;
                    invoke  EndPage, _hpdc
                    invoke  EndDoc, _hpdc                   
                    stc
                    ret
                    ;                     
@@:                 invoke  TextPrint, edi, LinCor, 4
                    ;
                    inc     LinCor
                    ;
                    sub     MaxLin, 1
                    jnz     short _start
                    ;
@@:                 invoke  EndPage, _hpdc
                    cmp     eax, 0
                    jg      short @F
                    ;
                    invoke  EndDoc, _hpdc
                    stc
                    ret
                    ;
@@:                 clc
                    ret
PrintPage           endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
TextPrint           proc    pTxt:DWORD, Lin:DWORD, Col:DWORD

                    mov     ebx, pTxt
                    cmp     dword ptr [ebx - 4], 0
                    jne     short @F
                    clc
                    ret
                   
@@:                 invoke  GetTextMetrics, _hpdc, addr _tm
                    ;
                    mov     ecx, _tm.tmHeight
                    mov     eax, Lin
                    sub     eax, 1
                    mul     ecx                 
                    mov     _PosPrnY, eax
                    ;
                    ;
                    ;
                    mov     ecx, _tm.tmAveCharWidth
                    mov     eax, Col
                    sub     eax, 1
                    mul     ecx
                    mov     _PosPrnX, eax

                    invoke  TextOut, _hpdc, _PosPrnX, _PosPrnY, ebx, [ebx - 4]
                    clc
                    ret
TextPrint           endp

;.................................................................................................................
Thanks again
Rui
Title: Re: printing a file on my printer
Post by: MichaelW on November 01, 2009, 10:05:53 PM
Quote
MichaelW,
This is to you: can i use DrawTextEx to print more than one page. How ?

Hi Rui,

I seem to recall doing that at some point, but I don't remember the details and I can't find the code, and since my printer is out of ink, I can't test any printer code until I get a new cartridge.
Title: Re: printing a file on my printer
Post by: hutch-- on November 02, 2009, 01:36:19 AM
Here is a test app to run the DLL. I tweaked the DLL so it loaded the rich edit 2 library and tweaked the display page width so it should display OK.

Just run the small test app PrintMe.exe, pick a file to print and you should be in business.
Title: Re: printing a file on my printer
Post by: jj2007 on November 02, 2009, 01:41:40 AM
Quote from: RuiLoureiro on November 01, 2009, 01:58:14 PM
Hi JJ,
        Why not to open a new topic. Try Printer8 and say something ok ? Thanks

Hi Rui,

I tried Printer8, latest version from reply #36, and it gives error A2005:symbol redefinition : INVALID_SET_FILE_POINTER
When I comment this one out, it assembles (but very slowly, for whatever reason).
The exe shows the print dialog, but I see nothing happen afterwards. I run Win XP SP2.

Jochen

P.S.: I integrated my RichText print routine now in the TinyRTF (http://www.masm32.com/board/index.php?topic=10796.msg97379#msg97379) thread. It works now with PageSetupDlg instead of PrintDlg - an example PDF containing the proc is included.
Title: Re: printing a file on my printer
Post by: allynm on November 02, 2009, 05:41:58 PM
To Hutch -

Wow!  Very cool indeed.  Thanks also for sending the asm files along with the executable.  As you may recall, I am trying to understand how all this stuff works, and only by studying code can this happen.

You and RuiLoureiro and MichaelW have been really great tutors.  I wish I had something that would be of equal usefulness to contribute.

What I want to do is integrate in the printing capability with a bigger Windows program that reads some parameters for a supply chain management program and prints out the results.  I want to use common dialog box to collect the input information.  Trying to work out a nice way with the text edit box to get the parameters.

Thanks again.
Mark Allyn
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 02, 2009, 06:26:40 PM
note:  this editor doesnt work well. The caret jumps above and below
       when i write at the bottom of this box. i cannot see the text
       where the caret is
       
Hi all
       1. This was my first quick attempt to write something like it.
          I only need printing strings line X, column Y and page by page
          and not text stuff tah ends in CRLF.
          To print text files i use QE (Hutch editor);
         
       2. I did it to help Mark because he doesnt want to use QuickEditor, NotePad,
          MS Word, etc. to print text files. As far as i understood he wants to
          learn how to do it, APIs to use etc. as a GUI app.

Hi MichaelW,
                Thank you the same.
               
Hi Jochen,
           1. Thank you for reply;
           2. «it gives error A2005:symbol redefinition»

               My windows.inc doenst have INVALID_SET_FILE_POINTER
               this is why i put INVALID_SET_FILE_POINTER equ 0FFFFFFFFh
           
           3. «When I comment this one out, it assembles
               (but very slowly, for whatever reason)»

                I defined the buffers in the .data section.
                This may be the reason why it assembles very slow
               
                ; »»»»»»»»»»»
                ; File Buffer
                ; »»»»»»»»»»» 
;                dd MAXBUFSIZE
;                dd 0
;_bufferTxt      db MAXBUFSIZE dup(0)
;                db 0               
                ; »»»»»»»»»»»»»»»»»»»»»
                ; File Buffer Formatted
                ; »»»»»»»»»»»»»»»»»»»»»
;                dd 0                            ; -20 CorRegLst
;                dd 0                            ; -16 EndRegLst
;                dd MAXCOLSIZE4                  ; -12 LenRegLst
;                dd MAXLINSIZE                   ;  -8 MaxRegLst
;                dd 0                            ;  -4 First String length
;_bufferFrm      db MAXLINSIZE dup ( MAXCOLSIZE4 dup (0) )
;                db 0
               
             4. «The exe shows the print dialog, but I see nothing happen afterwards.»

                 See reply #32

                Could you test my Printer10 example, please ?
                Thanks again

Hi Mark,
             See Printer10. Try Test Printer -> Print Text.
             Now it alloc memory for 100 pages, 50 lines/page and 117 colums.
             It convert TABS too.
             It seems to work correctly for me but iam quite sure it has bugs.
             It is an attempt to help you. If something runs wrong, please tell me.

             Files below Printer10.zip (inc, exe, asm) & rsrc.zip

Hutch: Thanks for your PrintMe. I read it and learned some things :U           
RuiLoureiro
Title: Re: printing a file on my printer
Post by: allynm on November 02, 2009, 09:45:57 PM
Hi RuiLoureiro -

Just picked up your new posting.  I will download and run Printer 10 just as you suggest.

You understand exactly what I'm trying to do!  I suppose it's a little crazy of me to get this involved in the printing process, but it really is the only way to learn how to do it.

Thank you,
Mark Allyn
Title: Re: printing a file on my printer
Post by: jj2007 on November 02, 2009, 09:50:43 PM
Printer10 works fine, result attached. The font is a bit high but otherwise no problems.
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 02, 2009, 10:12:31 PM
Quote from: jj2007 on November 02, 2009, 09:50:43 PM
Printer10 works fine, result attached. The font is a bit high but otherwise no problems.

Jochen,
             Thank you for reply. i would say «... seems works fine ... »
             Thank you for your comment «The font is a big high ... » !
Rui  :thumbu
Title: Re: printing a file on my printer
Post by: jj2007 on November 03, 2009, 12:46:00 AM
Quote from: RuiLoureiro on November 02, 2009, 10:12:31 PM
             Thank you for your comment «The font is a big high ... » !

Rui,
Fine code, compliments :U
Re the "high" font:
                xor eax, eax
                mov     _lf.lfHeight, eax

Not specifying the height will provide you with a wellshaped font. There is another problem: Much of the page is wasted by a huge lower margin; however, this is probably not your code's fault but rather a problem of the PdfCreator printer driver returning wrong values for invoke  GetDeviceCaps, _hpdc, VERTRES
Do people with real printers experience a huge bottom page gap??
Title: Re: printing a file on my printer
Post by: allynm on November 03, 2009, 01:30:02 AM
Hi RuiLoureiro:

I downloaded Printer 10 and ran it.  I'm not entirely sure, but it doesn't seem to actually associate the file I would like to print with what the printer actually prints.  I use the print dialog box to select a file -- in this case a txt file -- and the printer is activated and turns out a piece of paper.  But, the stuff that is printed doesn't seem to be related to what's in the txt file.

Mebbe I'm doing something wrong??

Regards,
Mark
Title: Re: printing a file on my printer
Post by: hutch-- on November 03, 2009, 03:34:25 AM
JJ,

It usually has something to do with the paper size. I have a number of drivers loaded to create PDF, PrimoPDF works fine, the old Adobe Acrobat works fine and there are a few others. Some have setting depending on what you want, display PDF or printing PDF, for test bits I use the display option.

Another factor is if the printing software sets the margin sizes, if it is working properly you should not get the effect you mention.
Title: Re: printing a file on my printer
Post by: jj2007 on November 03, 2009, 03:50:24 AM
Quote from: hutch-- on November 03, 2009, 03:34:25 AM
JJ,

It usually has something to do with the paper size. I have a number of drivers loaded to create PDF, PrimoPDF works fine, the old Adobe Acrobat works fine and there are a few others. Some have setting depending on what you want, display PDF or printing PDF, for test bits I use the display option.

Another factor is if the printing software sets the margin sizes, if it is working properly you should not get the effect you mention.

Hutch,

I guess you saw my rant in the Colosseum (http://www.masm32.com/board/index.php?topic=12008.msg97437#msg97437). Furthermore, the GetDeviceCaps returns clearly false values. I have tested it with PdfCreator/PrimoPDF (thanks for the hint)/Ms Office Document Image Write, and get this:
   mov ebx, rv(GetDeviceCaps, hPrDC, PHYSICALWIDTH)   ; yields 4958/4961/2480 - expected 11907 for A4
   mov esi, rv(GetDeviceCaps, hPrDC, PHYSICALHEIGHT)   ; yields 7017/7016/3508 - expected 16840 for A4

MSDN (http://msdn.microsoft.com/en-us/library/dd144877%28VS.85%29.aspx) on GetDeviceCaps PHYSICALWIDTH:
For printing devices: the width of the physical page, in device units. For example, a printer
set to print at 600 dpi on 8.5-x11-inch paper has a physical width value of 5100 device units.


"device units" should be twips, but of course MS does not see a need to explain what they mean. If the above is not confusing enough, try Device vs. Design Units (http://msdn.microsoft.com/en-us/library/dd183564%28VS.85%29.aspx) on MSDN.

Anyway, I got it working perfectly for RichMasm ;-)

@Mark: Printer10.asm prints the file I want it to print. Check if you had an old job in the printer queue ;-)
@Rui: There is a potential GPF, see attachment. When I try to print ClearFPU.asm, it chokes.
Sorry for that, jj.
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 03, 2009, 11:59:13 AM
Hi Jochen,
           1. Thank you for reply. You got the bug quickly ! Thanks for that  :U

           2. The bug is here:
Quote
NxtLinFrm       proc
                mov     edi, _pFrmBuf                   
                mov     eax, dword ptr [edi - EndRegLst]
                add     eax, 1
                cmp     eax, dword ptr [edi - MaxRegLst]
                jbe     short @F
                ;
                fn   MessageBox, _hWnd, "Insufficient buffer", "Warning", MB_OK
                stc
                ret
                ;
@@:             mov     dword ptr [edi - EndRegLst], eax
                ;
                sub     eax, 1
                mul     dword ptr [edi - LenRegLst]
                add     edi, eax
                mov     edx, edi        ;<<<<<<<<<-------------- HERE ###############
                ;
                mov     dword ptr [edi - 4], 0              ; string length  = 0
                clc
                ret
NxtLinFrm       endp
           

Hi Allynm,
           Please zip the file you are using and post it if you can. Is it a text file ?
           A text file is one where each line ends in Return (13) and LineFeed (10).
           You should use print dialog box to select a file. Read the rest

            New Printer10
            I modified GetPrinterDC and
            now, with Printer10, we can print Vertically or Horizontally
            I made some comments in the code too.

            If we dont want to see the printer dialog Box,
            comment this:
            mov     _pd.Flags, PD_RETURNDC or PD_PRINTSETUP
            and uncomment this:
            ;mov     _pd.Flags, PD_RETURNDC or PD_RETURNDEFAULT
            and assemble Printer10.asm.
            It returns a printer DC without dialog box.

    LATER:  Jochen,
            In GetPrinterDC do this:
                    ;invoke    CreateFontX, addr _FontMSSSerif, edx, eax, FW_NORMAL, 0
                    invoke    CreateFontX, addr _FontMSSSerif, 0, eax, FW_NORMAL, 0
            In PrintPage do this:
                    @@:       mov     MaxLin, 78      ;49             ;_mLines
           
Rui Loureiro
Title: Re: printing a file on my printer
Post by: allynm on November 03, 2009, 09:01:14 PM
Hi RuiLoureiro-

Finally got a chance to try new Printer 10.  Seems to work fine.  I didn't realize previously that it was for txt files only.  I should have figured that out....Sorry.

The "choose printer" function works perfectly.  I have a bunch of printers in my office here at the university and it selected the Dell Laser printer I have and ran a multiple page document OK.

Great job!!

Mark
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 03, 2009, 09:38:03 PM
Hi Allynm,
               ok i hope i have helped you. If you have some problems with the code,
               please tell me. I was a teacher but retired now  :U               

Hi jj,
                Do you know how i can know the orientation that was chosen after PrintDlg returns ?
                I know it is a word in DEVMODE  (dmOrientation), but how to access it ?
                I want to call PrintDlg with hDevMode=NULL and hDevNames =NULL. No ?

                Anyone can help me ?
Thanks
Rui
Title: Re: printing a file on my printer
Post by: jj2007 on November 04, 2009, 06:15:39 AM
Quote from: RuiLoureiro on November 03, 2009, 09:38:03 PM
                Do you know how i can know the orientation that was chosen after PrintDlg returns ?

Hi Rui,

Here is a snippet. But you don't really need it if you use CreateDC as shown attached.

invoke PageSetupDlg, addr psd ; get a printer
...
pushad
mov esi, rv(GlobalLock, psd.hDevMode) ; we need to access the memory
movzx eax, word ptr [esi.DEVMODE.dmOrientation] ; it's a "short" variable, but Masm needs "word"
.if eax==DMORIENT_PORTRAIT
MsgBox 0, "Portrait", "Hi", MB_OK
.elseif eax==DMORIENT_LANDSCAPE
MsgBox 0, "Landscape", "Hi", MB_OK
.else
MsgBox 0, "WTF", 0, MB_OK
.endif
invoke GlobalUnlock, psd.hDevMode ; unlock the mem
invoke GlobalFree, psd.hDevMode ; and free it
popad

:thumbu
Title: Re: printing a file on my printer: SCALING
Post by: jj2007 on November 04, 2009, 10:31:23 AM
If anybody is interested in scaling the output, see here (http://www.masm32.com/board/index.php?topic=12460.msg97461#msg97461) and the attached algo.
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 04, 2009, 01:48:04 PM
Quote from: jj2007 on November 04, 2009, 06:15:39 AM
Here is a snippet. But you don't really need it if you use CreateDC as shown attached.
Jochen,
            Thank you for reply.
            That helped me to get the solution. Thanks
            The solution is to get the DEVMODE structure pointer using GlobalLock.
           
            First we invoke  PrintDlg, addr _pd with
           
                        mov     _pd.hDevMode, NULL
                        mov     _pd.hDevNames, NULL

            and when PrintDlg returns we use «invoke GlobalLock, _pd.hDevMode»
           
            Thank you Jochen!  :thumbu           

Quote         
GetOrientation      proc

                    mov         _Orientation, 0              ; assume 0 means vertical
                    mov         _PrinterLines, PRINTERLINESV ; number of lines
                   
                    ; »»»»»»»»»»»»»»»»»»»»»»»»
                    ; Get the Memory Pointer
                    ; to DEVMODE structure
                    ; »»»»»»»»»»»»»»»»»»»»»»»
                    invoke      GlobalLock, _pd.hDevMode           ; memory handle
                    cmp         eax, NULL
                    jne         short @F

                    fn  MessageBox, _hWnd, "GlobalLock error","Error", MB_OK
                    stc
                    ret
                    ; »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
                    ; EAX = starting memory address of DEVMODE structure
                    ; »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
@@:                 mov         ebx, eax
                    mov         eax, [ebx].DEVMODE.dmFields
                    and         eax, DM_ORIENTATION
                    jnz         short @F
                    stc
                    ret

@@:                 mov         ax, [ebx].DEVMODE.dmOrientation
                    cmp         ax, DMORIENT_PORTRAIT
                    jne         short @F                   
                    clc
                    ret
                   
@@:                 mov     ax, [ebx].DEVMODE.dmOrientation
                    cmp     ax, DMORIENT_LANDSCAPE
                    jne     short @F

                    mov         _PrinterLines, PRINTERLINESH
@@:                 clc         ; assume 0
                    ret
GetOrientation      endp
 

                Printer10 has a potential bug if number of pages are larger than 100.
               
                I followed your suggestion and in Printer12 i create a font
                with height=0 width=0. It seems to print correctly when the orientation
                is DMORIENT_LANDSCAPE or DMORIENT_PORTRAIT in A4 sheets. It prints
                number of pages like «Page 3/12» when it has 12 pages.

                This Printer12 is not a prog to print text files but to try to
                understand what to do to and to learn some things to help Mark Allynm.
                Meanwhile it prints text files. Correctly, i hope.

Allynm,
                Thanks for your words ! Now, you can read the .asm file (and .inc) and
                write your own procedures, improve others, etc. to print what you want,
                i hope. You can comment out the lines of code you are not interested in
                and assemble the .asm file again. I suggest you save it with another
                name and than comment out ... etc assemble and run...

Rui Loureiro
Title: Re: printing a file on my printer
Post by: RuiLoureiro on November 07, 2009, 02:36:47 PM
Hi
    New version: PrintIt to print text files up to 800 pages vertically or horizontally in A4
    Try it and say something
     Files: PrintIt.zip (.ini, .asm, .inc) and rsrc.zip
     LATER:Printer12 has a problem. See «GetOpenFileName causes an error»
Rui
Title: Re: printing a file on my printer
Post by: scjain on August 17, 2010, 08:10:10 AM
hi everyone,
thanks all for valuable examples and tutorials on printing subject.after going through all the posts i found that nothing is available on printing records from a database table aligning fields . can you help in this matter.The sample requirement is as below-
fields in database table-date c(10), Name C(40), Add1 C(30), Add2 C(25)
Print on row1,col 01 date
Print on row1,col 12 Name - length varies from records to records.
Print on row1,col 55 Add1  - length varies from records to records.
Print on row1,col 90 Add2  - length varies from records to records.
thanking all
scj
Title: Re: printing a file on my printer
Post by: Magnum on October 24, 2011, 10:06:28 PM
Quote from: hutch-- on October 29, 2009, 03:52:12 AM
Mark,

This is not exactly what you were after but it does print to a default printer correctly, its the complete code for a printing DLL complete with preview window and font settings. You call the DLL from this procedure,



[/quote]

This doesn't work on my computer. I use a Canon printer.

It shoots out a page, but it is blank.