i took this code from a siteHANDLE hdl;
DEVMODE* devmode;
OpenPrinter(L"HP Deskjet F4400 series", &hdl, NULL);
int size = DocumentProperties(NULL, hdl, L"HP Deskjet F4400 series", NULL, NULL, 0);
devmode = (DEVMODE*)malloc(size);
DocumentProperties(NULL, hdl, L"HP Deskjet F4400 series", devmode, NULL, DM_OUT_BUFFER);
HDC printerDC = CreateDC(L"WINSPOOL", devmode->dmDeviceName, NULL, devmode);
DOCINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
StartDoc(printerDC, &info);
StartPage(printerDC);
Rectangle(printerDC, 100, 100, 200, 200);
EndPage(printerDC);
EndDoc(printerDC);
DeleteDC(printerDC);
and translated it into this:
.if ax==IDB_BUTTON
invoke PrintDlg,addr prndlg
invoke SendMessage,hEdit,WM_SETTEXT,0,addr devmode.dmDeviceName
invoke OpenPrinter,addr szPrinterName,addr hPrinter,NULL
mov eax,rv(DocumentProperties,hWnd,hPrinter,addr szPrinterName,NULL,NULL,0)
invoke DocumentProperties,hWnd,hPrinter,addr szPrinterName,addr devmode,0,DM_OUT_BUFFER
invoke CreateDC,addr hService,addr devmode.dmDeviceName,NULL,addr devmode
mov prndlg.hDC,eax
mov hDC,eax
invoke StartDoc,prndlg.hDC,addr dci
invoke StartPage,prndlg.hDC
invoke Rectangle,prndlg.hDC,100,100,200,200
invoke EndPage,prndlg.hDC
invoke EndDoc,prndlg.hDC
invoke DeleteDC,prndlg.hDC
.endif
but nothing happens. The devmode.dmDeviceName doesn't change when PrintDlg is called. Can anyonw give some insight into this?
If you use PrintDlg, you can use hdc from it., PD_RETURNDC
https://docs.microsoft.com/fi-fi/windows/win32/api/commdlg/ns-commdlg-printdlga?redirectedfrom=MSDN
https://docs.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes
thanks Timo
PRINTDLG.hDevMode doesn't return the printer name. Why would that be? does anyone have an example of this? Thanks
so...i lost my faith with PrintDlg and got into EnumPrinters instead. Does anyone know how to get the icon corresponding to each printer? i thought it would be PRINTER_INFO_1 but it didn't work. Can someone give me a hand? thanks
Icon are found in the resource of axecute files,dll...
If you know the full path of the printer,perhaps you can extract the icon of the resource.
PrintDlg
https://www.codeproject.com/Articles/764057/GDI-Drawing-and-Printing
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);
// Drawing code begin
//
RECT rc;
rc.top = 100;
rc.left = 100;
rc.bottom = 300;
rc.right = 300;
HBRUSH greenBrush=CreateSolidBrush(RGB(0,255,0));
FillRect(hdc, &rc, greenBrush);
DeleteObject(greenBrush);
//
// Drawing code end
EndPage (hdc);
EndDoc(hdc);
DeleteObject(hdc);
}
}
Thanks guys, it's been helpfull. ty :thumbsup:
What i trully meant was where the hell does PrinDlg get it's icons?
Timo. Thanks for the input, but, your code doesn't work. The document shows in the printer tray but it remains there unoperational. It doesn't print.
invoke StartDoc,prndlg.hDC,addr dci
invoke StartPage,prndlg.hDC
invoke CreateSolidBrush,0ffh
mov obj,eax
invoke SelectObject,prndlg.hDC,eax
invoke FillRect,prndlg.hDC,addr rect,obj
; invoke Rectangle,prndlg.hDC,100,100,200,200
invoke EndPage,prndlg.hDC
invoke EndDoc,prndlg.hDC
invoke DeleteObject,obj
A test program that works in my PC
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
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, NULL);
StartPage (hdc);
// Drawing code begin
//
RECT rc;
rc.top = 100;
rc.left = 100;
rc.bottom = 300;
rc.right = 300;
HBRUSH greenBrush=CreateSolidBrush(RGB(0,255,0));
FillRect(hdc, &rc, greenBrush);
DeleteObject(greenBrush);
//
// Drawing code end
EndPage (hdc);
EndDoc(hdc);
DeleteObject(hdc);
}
}
void __cdecl WinMainCRTStartup(void)
{
GDIDraw_Print(0);
ExitProcess(0);
}
Timo. Thanks. your little app didn't work on my end.
Do the RichMasm and qEditor print dialogs work on your machine? Both are invoked with Ctrl P
Yes. They're working. The document stays stalled i n printer tray and nothig happens. If I write it to PDF, it works. Thanks
Finally got it to work. Unmentioning an output file for the DOCINFO struct did the work.
Hi guys. I wonder why it is that the devmode.dmDeviceName doesn't return the printer chosen. does anyone know? thanks
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);
.
.
.
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);
}
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
Did you use StartDocPrinter function?
EDIT: DrawText[Ex] if good for printing plain text usind HDC.
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
i also tried EM_STERAMOUT but it doesn't work either. bollocks. :thdn:
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
How to Print the Contents of Rich Edit Controls (https://docs.microsoft.com/en-us/windows/win32/controls/printing-rich-edit-controls)
Thanks guys. You're the best always. :thumbsup:
JJ. Some code would be alright to show. Is it embeded in the executable?
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
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
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 (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1400). I guess you are curious what's under the hood - here it is.
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
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);
...
Quote from: xandaz on December 27, 2020, 01:42:05 AM
Hi. Are you sure it can't be done like this:
There are apparently several ways to print from a richedit control. Mine works fine.
Yeah JJ. Your way seems to work fine. The problem is that your code is too complex for my peanut-sized mind. Thanks anyway
I can't help you much because I did this almost 4 years ago and have forgotten the details. However, StartDoc, StartPage, EndPage, EndDoc and the EM_FORMATRANGE message are all well documented... maybe the source posted by Hutch (http://masm32.com/board/index.php?topic=9033.msg99298#msg99298) is clearer.