News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Printing operation

Started by xandaz, December 18, 2020, 06:12:07 AM

Previous topic - Next topic

xandaz

    Hi guys. I wonder why it is that the devmode.dmDeviceName doesn't return the printer chosen. does anyone know? thanks

deeR44

I'll never get used to finding stuff like the following in a MASM forum:

void GDIDraw::Print(HWND hWnd)
{
   PRINTDLG pd = {0};
   pd.lStructSize = sizeof( pd );
   pd.hwndOwner = hWnd;
   pd.Flags = PD_RETURNDC;
   
   // Retrieves the printer DC
   if (PrintDlg(&pd))
   {
      HDC hdc = pd.hDC;
      StartDoc (hdc, &di);
      StartPage (hdc);   
.
.
.

TimoVJL

Quote from: xandaz on December 24, 2020, 06:57:24 AM
    Hi guys. I wonder why it is that the devmode.dmDeviceName doesn't return the printer chosen. does anyone know? thanks
A hint for that:
void ShowPrnInfo(PRINTDLG *pd)
{
LPDEVMODE devmode = (LPDEVMODE)GlobalLock(pd->hDevMode);
LPDEVNAMES devnames = (LPDEVNAMES)GlobalLock(pd->hDevNames);
LPCTSTR driver = (LPCTSTR)devnames + devnames->wDriverOffset;
LPCTSTR device = (LPCTSTR)devnames + devnames->wDeviceOffset;
LPCTSTR output = (LPCTSTR)devnames + devnames->wOutputOffset;
printf("%s\n", driver);
printf("%s\n", device);
printf("%s\n", output);
GlobalUnlock(pd->hDevNames);
GlobalUnlock(pd->hDevMode);
}
May the source be with you

xandaz

    Hi again. I've been looking into printing text documents. I used WritePrinter but it doesn't work. GetLastError gives ERROR_NO_START_DOC, but the StartDoc Function gives no error. The Printer just pushes the sheet and it comes out blank on the other side. Is there a simple way to print document files? Thanks

TimoVJL

#19
 Did you use StartDocPrinter function?

EDIT: DrawText[Ex] if good for printing plain text usind HDC.
May the source be with you

xandaz

   i have the following code: invoke PrintDlg,addr prndlg
invoke OpenPrinter,addr szPrinterName,addr hPrinter,0;addr prndef
invoke LocalAlloc,LMEM_FIXED,0ffffh
mov lpBuffer,eax
invoke SendMessage,hEdit,WM_GETTEXT,0ffffh,lpBuffer
invoke StartDocPrinter,hPrinter,1,addr dci
invoke StartPagePrinter,hPrinter
invoke WritePrinter,hPrinter,lpBuffer,0ffffh,addr BytesWritten
invoke EndPagePrinter,hPrinter
invoke EndDocPrinter,hPrinter
invoke ClosePrinter,hPrinter
.endif

...that doesn't work. The document shows as being printed in the printer's tray but then it disappears. Thanks

xandaz

   i also tried EM_STERAMOUT but it doesn't work either. bollocks. :thdn:

jj2007

GuiParas equ "Printing from a RichEdit control", w300, h200
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "RichEdit", "Select some text and hit Control P"
Event Key
  If_ VKey==VK_P || VKey==-VK_P Then <MsgBox 0, Str$("%i pages printed", PrintRtf(hMyEdit, 2)), "PrintRtf:", MB_OK>
GuiEnd


xandaz

   Thanks guys. You're the best always.  :thumbsup:

xandaz

   JJ. Some code would be alright to show. Is it embeded in the executable?

hutch--

I wrote this over 10 years ago and it the print algo in QE but its part of a more complicated method. It may be useful to you.

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

edit_print proc parent:DWORD,edit:DWORD,instance:DWORD

    LOCAL wTwip         :DWORD
    LOCAL hTwip         :DWORD
    LOCAL mLeft         :DWORD
    LOCAL mTop          :DWORD
    LOCAL mRight        :DWORD
    LOCAL mBottom       :DWORD
    LOCAL szPrint       :DWORD
    LOCAL hRes          :DWORD
    LOCAL vRes          :DWORD
    LOCAL hppli         :DWORD
    LOCAL vppli         :DWORD
    LOCAL pd            :PRINTDLG
    LOCAL fr            :FORMATRANGE
    LOCAL dinf          :DOCINFO
    LOCAL cr            :CHARRANGE

    push ebx
    push esi
    push edi

    sas szPrint,"Print"

    invoke SendMessage,edit,EM_FORMATRANGE,FALSE,NULL

  ; ------------------------
  ; zero fill the structures
  ; ------------------------
    invoke charfill,ADDR pd,SIZEOF PRINTDLG,0
    invoke charfill,ADDR fr,SIZEOF FORMATRANGE,0
    invoke charfill,ADDR dinf,SIZEOF DOCINFO,0

    mov pd.lStructSize, SIZEOF pd
    mrm pd.hwndOwner,   parent
    mov pd.Flags,       PD_RETURNDC or PD_NOPAGENUMS or PD_PRINTSETUP
    mrm pd.hInstance,   instance

  ; ------------------
  ; half inch in TWIPS
  ; ------------------
    mov mLeft,      720         ; left   margin
    mov mTop,       720         ; top    margin
    mov mRight,     720         ; right  margin
    mov mBottom,    720         ; bottom margin

    ; -----------------------------------------------

    .if rv(PrintDlg,ADDR pd)
      invoke SetCursor,rv(LoadCursor,NULL,IDC_WAIT)

      mov hRes, rv(GetDeviceCaps,pd.hDC,HORZRES)            ; horizontal resolution
      mov vRes, rv(GetDeviceCaps,pd.hDC,VERTRES)            ; vertical resolution

      mov hppli, rv(GetDeviceCaps,pd.hDC,LOGPIXELSX)        ; horizontal pixels per logical inch
      mov vppli, rv(GetDeviceCaps,pd.hDC,LOGPIXELSY)        ; vertical pixels per logical inch

      mov esi, rv(IntDiv,hRes,hppli)
      mov wTwip, rv(IntMul,esi,1440)                        ; calculate width

      mov esi, rv(IntDiv,vRes,vppli)
      mov hTwip, rv(IntMul,esi,1440)                        ; calculate height

      mrm fr.hdc,           pd.hDC
      mrm fr.hdcTarget,     pd.hDC

      mrm fr.rcPage.left, mLeft
      mrm fr.rcPage.top, mTop

      mrm fr.rcPage.right, wTwip
      mov eax, mRight
      sub fr.rcPage.right, eax

      mrm fr.rcPage.bottom, hTwip
      mov eax, mBottom
      sub fr.rcPage.bottom, eax

      mrm fr.rc.left, mLeft
      mrm fr.rc.top, mTop
      mrm fr.rc.right, fr.rcPage.right
      mrm fr.rc.bottom, fr.rcPage.bottom

    ; ------------------------
    ; whole document selection
    ; ------------------------
      mov fr.chrg.cpMin, 0
      mov fr.chrg.cpMax, -1
      invoke SendMessage,edit,EM_EXSETSEL,0,ADDR fr.chrg
      invoke SendMessage,edit,EM_EXGETSEL,0,ADDR fr.chrg

    ; -----------------------------------------------

      mov dinf.cbSize,      SIZEOF dinf
      mrm dinf.lpszDocName, szPrint
      mov dinf.lpszOutput,  NULL

      invoke StartDoc,pd.hDC,ADDR dinf

  ; ******************************

    print_loop:
      invoke StartPage,pd.hDC
      mov esi, rv(SendMessage,edit,EM_FORMATRANGE,TRUE,ADDR fr)
      cmp esi, fr.chrg.cpMax
      jge outp
      mov fr.chrg.cpMin,esi
      invoke EndPage,pd.hDC
      jmp print_loop
    outp:

  ; ******************************

      invoke SendMessage,edit,EM_FORMATRANGE,FALSE,NULL
      invoke EndPage, pd.hDC
      invoke EndDoc,  pd.hDC
      invoke DeleteDC,pd.hDC

      invoke SetCursor,rv(LoadCursor,NULL,IDC_ARROW)

      mov eax, 1
    .endif

    ; -----------------------------------------------

    pop edi
    pop esi
    pop ebx

    ret

edit_print endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

jj2007

Quote from: xandaz on December 27, 2020, 12:32:16 AM
   JJ. Some code would be alright to show. Is it embeded in the executable?

The source is what you see above - see PrintRTF. I guess you are curious what's under the hood - here it is.

xandaz

   Hi. Are you sure it can't be done like this:
.elseif uMsg==WM_COMMAND
mov eax,wParam
.if ax==IDB_BUTTON

invoke OpenPrinter,addr szPrinterName,addr hPrinter,0; addr prndef
invoke StartDocPrinter,hPrinter,1,addr dci
invoke StartPagePrinter,hPrinter
m2m EditStream.dwCookie,hPrinter
mov EditStream.pfnCallback,offset StreamOutProc
invoke SendMessage,hEdit,EM_STREAMOUT,SF_RTF,addr EditStream
invoke EndPagePrinter,hPrinter
invoke EndDocPrinter,hPrinter
invoke ClosePrinter,hPrinter
.endif
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret

WndProc endp

StreamOutProc PROC dwCookie:DWORD,pbBuff:DWORD,cb:DWORD,pcb:DWORD
invoke WriteFile,dwCookie,pbBuff,cb,pcb,0
xor eax,eax
ret
StreamOutProc endp
end start


Well it's not working but it appears in the printers tray and then it's gone

TimoVJL

#29
As HP Deskjet F4400 series use PCL3 GUI printer language, a direct printing might be a broblem.
http://www.verypdf.com/wordpress/201107/what-is-pcl3gui-format-1195.html

An old C code for text only printing with normal printer driver.
int OnPrint(HWND hWnd) {
DOCINFO di;
TEXTMETRIC tm;
int i,j,x,y,mx,my,ir;
RECT rc;
unsigned char szBuf[256];

j = SendMessage(hWndEdit, EM_GETLINECOUNT, 0, 0);
//if (!j) return 0;
memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = hWndFrame;
pd.hInstance = hInst;
pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
if (PrintDlg(&pd)) {
bUserAbort = FALSE;
hDlgPrint = CreateDialog(hInst, MAKEINTRESOURCE(1001), hWnd, PrintDlgProc);
SetAbortProc(pd.hDC, AbortProc);

memset(&di, 0, sizeof(di));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = szFileTitle;
mx = GetDeviceCaps(pd.hDC, HORZRES);
my = GetDeviceCaps(pd.hDC, VERTRES);
y = psd.rtMargin.top / 4;
x = psd.rtMargin.left / 4;
if (StartDoc(pd.hDC, &di)) {
StartPage(pd.hDC);
GetTextMetrics(pd.hDC, &tm);
for (i=0;i<j;i++) {
szBuf[0] = 255; szBuf[1] = 0;
ir = SendMessage(hWndEdit, EM_GETLINE, i, (LPARAM)&szBuf);
if (ir>0) {
rc.left = x; rc.top = y;
rc.right = mx; rc.bottom = my;
szBuf[ir] = 0;
ir = DrawText(pd.hDC, (LPSTR)&szBuf, ir, &rc,
DT_WORDBREAK | DT_EXPANDTABS);
y += ir;
} else y += tm.tmHeight;
if ((y+tm.tmHeight)>my) {
y = psd.rtMargin.top / 4;
EndPage(pd.hDC);
StartPage(pd.hDC);
}
}
EndPage(pd.hDC);
if (EndDoc(pd.hDC) <= 0) {
LoadString(hInst, IDR_PRINTERROR, szBuf, sizeof(szBuf));
MessageBox(hWndFrame, szBuf, szAppName, MB_OK);
}
if (!bUserAbort)
{
EnableWindow(hWnd, TRUE);
DestroyWindow(hDlgPrint);
}
}
}
if (pd.hDC)
DeleteDC(pd.hDC);
if (pd.hDevMode) GlobalFree(pd.hDevMode);
if (pd.hDevNames) GlobalFree(pd.hDevNames);

return 0;
}

UPDATE:...
if (pd.hDevMode) GlobalFree(pd.hDevMode);
if (pd.hDevNames) GlobalFree(pd.hDevNames);
...
May the source be with you