News:

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

Printing Setup Question

Started by z941998, November 24, 2009, 07:11:57 PM

Previous topic - Next topic

z941998

I initialize the PageSetupDlg.flags with PSD_INHUNDREDTHSOFMILLIMETERS or PSD_MARGINS and have been using A4 = 210 mm x 294 mm as my default papersize.

I then have been converting the formated range of a richedit control to twips by multiplying the mm dimensions by the factor 56.7, before sending to the printer.  This works OK for me.

My problem is this, when I use PSD_INTHOUSANDTHSOFINCHES or PSD_MARGINS and select Letter (8.5 inch x 12 inch) as my papersize, I have a problem with the twips procedure because its setup for mm conversion and not inch conversion.

My question is this, can some demonstrate a English twips procedure or a procedure that can be applied to any selected papersize, whether English format or metric format is required or used by the user on the fly, or at least provide me a good convsersion formula.

Thanks, Steve

MichaelW

"There are 1440 twips to an inch, 567 twips to a centimeter"

http://support.microsoft.com/kb/76388
eschew obfuscation

jj2007

Here is an excerpt from my print routine. The twips macro might be helpful (although I must admit I have not fully understood your problem - it's a very simple conversion...).

twips MACRO arg
  push arg
  call twipsP
  EXITM <eax>
ENDM
; 567 twips per cm: A4 = 21 X 29,7 cm
; twips = 21*567 X 29.7X567 = 11907 * 16839,9

PrintRTF proc
LOCAL fSuccess:SDWORD
LOCAL hPrDC:DWORD
LOCAL OldSel:CHARRANGE
LOCAL psd:PAGESETUPDLG
LOCAL docInfo:DOCINFO
LOCAL fr:FORMATRANGE
  call ClearLocVars ; clear all structure elements
  push edi
  push esi
  mov psd.lStructSize, sizeof PAGESETUPDLG
.data
  prtMargins dd 700, 100, 900, 700
.code
  mov esi, offset prtMargins
  lea edi, psd.rtMargin
  m2m ecx, 4
  push ecx
  push esi
  push edi
  mov psd.Flags, PSD_INHUNDREDTHSOFMILLIMETERS or PSD_DEFAULTMINMARGINS ;PSD_MARGINS
;  mov psd.DEVMODE.dmScale, 50
  rep movsd
  m2m psd.hwndOwner, hWin
  invoke PageSetupDlg, addr psd ; get a printer device context
  pop esi ; the unchanged order is
  pop edi ; intentional: we swap the pointers
  pop ecx
  .if eax==0
invoke CommDlgExtendedError
test eax, eax
jne PriError
  .else
rep movsd
invoke GlobalLock, psd.hDevMode
push eax
; mov [eax.DEVMODE.dmScale], 80 ; optional scaling of output
mov esi, rv(GlobalLock, psd.hDevNames)
movzx eax, word ptr [esi.DEVNAMES.wOutputOffset]
add eax, esi
push eax
movzx eax, word ptr [esi.DEVNAMES.wDeviceOffset]
add eax, esi
push eax
movzx eax, word ptr [esi.DEVNAMES.wDriverOffset]
add eax, esi
push eax
call CreateDC ;  hPrDC=CreateDC(lpszDriver, lpszDevice, lpszOutput, pDeviceMode)
mov hPrDC, eax
invoke GlobalUnlock, psd.hDevNames
invoke GlobalUnlock, psd.hDevMode
ShowDevCaps = 0
if ShowDevCaps eq 0
invoke GlobalFree, psd.hDevNames
invoke GlobalFree, psd.hDevMode
else
pushad

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

mov ebx, rv(GetDeviceCaps, hPrDC, PHYSICALWIDTH) ; yields 4960, a factor 2.x too small
mov esi, rv(GetDeviceCaps, hPrDC, PHYSICALHEIGHT) ; yields 7015 - expected 16840 for A4
mov edi, rv(GetDeviceCaps, hPrDC, PHYSICALOFFSETY) ; yields 100
deb 1, "GdCaps", ebx, esi, edi
popad
jmp @F
endif

mov docInfo.cbSize, sizeof DOCINFO
mov docInfo.lpszDocName, chr$("TinyRtf")
invoke StartDoc, hPrDC, addr docInfo ; start a print job
.if eax==SP_ERROR
invoke DeleteDC, hPrDC
jmp PriError
.endif
; invoke SendMessage, hEdit, EM_SETTARGETDEVICE, hPrDC, cxPhys ; not needed
m2m fr.hdc, hPrDC
m2m fr.hdcTarget, hPrDC

mov fr.rc.left, twips(psd.rtMargin.left) ; psd:PAGESETUPDLG
neg eax
mov fr.rc.right, eax
add fr.rc.right, twips(psd.ptPaperSize.x)
sub fr.rc.right, twips(psd.rtMargin.right)

mov fr.rc.top, twips(psd.rtMargin.top)
neg eax
mov fr.rc.bottom, eax
add fr.rc.bottom, twips(psd.ptPaperSize.y)
sub fr.rc.bottom, twips(psd.rtMargin.bottom)

; Get the current selection into a CHARRANGE
invoke SendMessage, hEdit, EM_EXGETSEL, 0, addr fr.chrg
mov eax, fr.chrg.cpMax
mov edx, fr.chrg.cpMin
mov OldSel.cpMax, eax
mov OldSel.cpMin, edx
sub eax, edx
.if sdword ptr eax<=127 ; User has not selected a lot of text, therefore print all pages
invoke SendMessage, hEdit, EM_SETSEL, 0, -1
invoke SendMessage, hEdit, EM_EXGETSEL, 0, addr fr.chrg
.endif

; Use GDI to print successive pages
.Repeat
invoke StartPage, hPrDC
mov fSuccess, eax
.Break .if sdword ptr eax<=0
push fr.rc.bottom
invoke SendMessage, hEdit, EM_FORMATRANGE, 1, addr fr
pop fr.rc.bottom
; The rc.bottom member may be changed after the message is sent. If it is changed, it must indicate the
; largest rectangle that can fit within the bounds of the original rectangle and still contain the specified
; text without printing partial lines. It may be necessary to reset this value after each page is printed.
; These dimensions are given in TWIPS.  ([url=http://support.microsoft.com/kb/129860]MS Support[/url])
; deb 1, "Loop", eax, fr.chrg.cpMin, fr.chrg.cpMax
.Break .if eax<=fr.chrg.cpMin
.Break .if eax>=fr.chrg.cpMax
mov fr.chrg.cpMin, eax
invoke EndPage, hPrDC
mov fSuccess, eax
.Until sdword ptr eax<=0
invoke SendMessage, hEdit, EM_FORMATRANGE, 0, 0 ; free the cache, important
.if fSuccess>0
invoke EndDoc, hPrDC
.else
invoke AbortDoc, hPrDC
.endif
invoke DeleteDC, hPrDC
invoke SendMessage, hEdit, EM_EXSETSEL, 0, addr OldSel ; restore old selection
  .endif
;  mov eax, fSuccess
@@:
  pop esi
  pop edi
  ret
PriError:
  MsgBox 0, "Printing problem", 0, MB_OK
  jmp @B
PrintRTF endp

twipsP proc
.data
  tw2cm REAL4 0.567
.code
  ffree st(7)
  ffree st(7)
  fld tw2cm
  fild dword ptr [esp+4]
  fmul
  fistp dword ptr [esp+4]
  pop edx
  pop eax
  jmp edx
twipsP endp

z941998

Thanks JJ I will look thru your example.

Thanks Michael, I knew there was as standard, just could not find it.

Steve