News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

printing a file on my printer

Started by allynm, October 29, 2009, 02:30:19 AM

Previous topic - Next topic

RuiLoureiro

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

allynm

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

RuiLoureiro

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

allynm

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

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

RuiLoureiro

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

allynm

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

RuiLoureiro

#22
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

allynm

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

RuiLoureiro

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

jj2007

I have implemented a print function for a RichEdit control, based on The Old New Thing.

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".

farrier

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
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

jj2007

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

farrier

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
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

RuiLoureiro

#29
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