how print without a printer dialog?

can i print, what is on window, without a printer dialog?
Yes, see:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx

Example:
1
2
      const bool ok = (ShellExecute(NULL, "print", filename.c_str()
        , NULL, NULL, SW_SHOWNORMAL) > HINSTANCE(32));

sorry, i mean window hdc.
See this:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd162931%28v=vs.85%29.aspx

Use EnumPrinters(...)
Then printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
The ShellExecute "print" verb is for printing files. It launches the registered app (identified by the file association) to do the work. It doesn't request a running app to print. Depending on the app that might be possible by a .NET or COM automation API (e.g. Microsoft Office apps) or DDE.

Note that the "print" verb only works with ShellExecute() if the system knows how to print that file type. i.e. there is an appropriate file association.

My PC has the default assoc for .txt -> txtfile

[HKEY_CLASSES_ROOT\txtfile\shell\print\command]
@ = "%SystemRoot%\system32\NOTEPAD.EXE /p %1"

so "print" works for .txt files (notepad is launched to print the file.)

But when I try to "print" an .xml file I get error SE_ERR_NOASSOC as I have no app installed which handles this shell verb.

So this approach only works with apps that play ball!

Andy
Last edited on
using GetDefaultPrinter(), i can get the printer default name.
now i need understand how can i start printer.
- the GetDefaultPrinter(), gives me the printer default;
- the:
printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
give me the the printer HDC;
- now i need understand how i start printing.
thanks for all, i will came back.
can i print, what is on window, without a printer dialog?

Are you talking about a window of your own app? In that case, it's easy enough to do.

Or are you asking how to get an existing app to print without displaying a printer dialog? That depends entirely on how the app is coded!

Andy
i'm getting, again, problems with wchar :(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::wstring towstring(const std::string& v)
{
    std::wstring out(v.size()+1,L'\0');

    int size = MultiByteToWideChar(CP_UTF8, 0, v.c_str(), -1, &out[0], out.size());

    out.resize(size-1);
    return out;
}
//............

//getting the default printer name
            char szPrinterName[255];
            unsigned long lPrinterNameLength;
            GetDefaultPrinter( szPrinterName, &lPrinterNameLength );
            
            //getting printer DC
            HDC printerDC = CreateDC( L"WINSPOOL",towstring(szPrinterName), NULL, NULL);

please can anyone advice me?
theres so many win32 strings styles that can kill me :(
error message: "cannot convert 'const wchar_t*' to 'LPCSTR {aka const char*}' for argument '1' to 'HDC__* CreateDCA(LPCSTR, LPCSTR, LPCSTR, const DEVMODEA*)'|"
Last edited on
So why are you trying that wstring stuff? your project isn't UNICODE.

HDC printerDC = CreateDC( L"WINSPOOL",towstring(szPrinterName), NULL, NULL);

You can explecitely choose the version you want:

CreateDCA(...) is 'ANSI'

CreateDCW(...) is 'UNICODE'
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void print()
        {
            //getting the default printer name
            char szPrinterName[255];
            unsigned long lPrinterNameLength;
            GetDefaultPrinter( szPrinterName, &lPrinterNameLength );

            //getting printer DC
            HDC printerDC = CreateDC( "WINSPOOL",szPrinterName, NULL, NULL);

            //starting doc and pages:
            DOCINFO doc;
            doc.cbSize = sizeof(DOCINFO);
            doc.lpszDocName = "1st doc";
            StartDoc(printerDC, &doc);
            StartPage(printerDC);

            //draw on printer using GDI functions
            RECT windowRect;
            BitBlt(printerDC,0,0,windowRect.right,windowRect.bottom,GetDC(hwnd),0,0,SRCCOPY);

            //end pages and doc
            EndPage(printerDC);
            EndDoc(printerDC);

            //delete the printer DC
            DeleteDC(printerDC);
        }

- why i get a small image resolution?
- i used ClientRect() and BitBlt(), but why the scrollbars are printed to?
- can i print, to, what's is on other scroll position?
(these function is for print what is inside of window... the RECT it's only the window client size... but i'm testing it)
- why i get a small image resolution?
Because the printer has a much higher resolution (about 3 times) hence your image is [3 times] smaller.

Take a look here:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd144877%28v=vs.85%29.aspx

See whether SCALINGFACTORX/SCALINGFACTORY are helpfull

- i used ClientRect() and BitBlt(), but why the scrollbars are printed to?
I would think that scrollbars are part of the client.

- can i print, to, what's is on other scroll position?
(these function is for print what is inside of window... the RECT it's only the window client size... but i'm testing it)
Line 20 does only copy the visible client area.
nothing is printed :(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void print()
        {
            //getting the default printer name
            char szPrinterName[255];
            unsigned long lPrinterNameLength;
            GetDefaultPrinter( szPrinterName, &lPrinterNameLength );

            //getting printer DC
            HDC printerDC = CreateDC( "WINSPOOL",szPrinterName, NULL, NULL);

            //starting doc and pages:
            DOCINFO doc;
            doc.cbSize = sizeof(DOCINFO);
            doc.lpszDocName = "1st doc";
            StartDoc(printerDC, &doc);
            StartPage(printerDC);

            //draw on printer using GDI functions
            RECT windowRect;
            GetClientRect(hwnd,&windowRect);
            //SetMapMode(printerDC, GetMapMode(GetDC(hwnd)));
            long width=GetDeviceCaps(printerDC,SCALINGFACTORX);
            long height=GetDeviceCaps(printerDC,SCALINGFACTORX);

            StretchBlt(printerDC,0,0,windowRect.right*width,windowRect.bottom*height,GetDC(hwnd),0,0,windowRect.right,windowRect.bottom,SRCCOPY);

            //end pages and doc
            EndPage(printerDC);
            EndDoc(printerDC);

            //delete the printer DC
            DeleteDC(printerDC);
        }

what i'm doing wrong?
Check what value width and height contain. It might not work.

GetDeviceCaps(...) has other indexes like

ASPECTX, ASPECTY, ASPECTXY
HORZRES, VERTRES
LOGPIXELSX, LOGPIXELSY

See the comments:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd144877%28v=vs.85%29.aspx

Using one of them (screen and printer) should let you calculate the scaling factor as well.
before enter on calculations, i must admite that i'm totaly confused :(
1 - the printer scale mode is realy twips?
2 - the images(screen or memory) are in pixels... so i need convert the pixel width\height to printer scale mode... right?
3 - why i can't change the printer scale mode with SetMapMode()?
The problem is that you need cope with both display and printer driver and what they provide. I suggest to try the following in a separate project before you continue:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd145174%28v=vs.85%29.aspx

As soon as you are familiar with transformation it should be easier to do that for the printer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void print()
        {
            //getting window title for use it on print name
            string windowtitle;
            GetWindowString(hwnd,windowtitle);
            DOCINFO doc = {sizeof(DOCINFO), windowtitle.c_str()};
            
            //getting the default printer name:
            //getting the string size for the printer name
            //and then the printer name
            unsigned long lPrinterNameLength;
            GetDefaultPrinter( NULL, &lPrinterNameLength );
            char szPrinterName[lPrinterNameLength];
            GetDefaultPrinter( szPrinterName, &lPrinterNameLength );
            
            //getting the printer DC, using the deafault printer name
            HDC PrinterDC =CreateDC( "WINSPOOL",szPrinterName, NULL, NULL);
            
            //getting the window DC and it client rect
            HDC WindowDC=GetDC(hwnd);
            RECT windowrect;
            GetClientRect(hwnd, &windowrect);

            //convert from pixels to twips
            int PrinterWidth = MulDiv(windowrect.right, GetDeviceCaps(PrinterDC , LOGPIXELSX), GetDeviceCaps(WindowDC, LOGPIXELSX));;
            int PrinterHeight = MulDiv(windowrect.bottom, GetDeviceCaps(PrinterDC , LOGPIXELSY), GetDeviceCaps(WindowDC , LOGPIXELSY)); ;
            
            //start doc and page
            //the print thing starts here
            StartDoc(PrinterDC, &doc);
            StartPage(PrinterDC);
            //here we can draw what we want using GDI functions
            //but never forget convert from pixels to twips
            
            //draw the windc to printerdc
            StretchBlt(PrinterDC, 0,0, PrinterWidth, PrinterHeight, WindowDC, 0, 0, windowrect.right, windowrect.bottom, SRCCOPY);
            
            //end page and doc
            //the print thing ends here
            EndPage (PrinterDC);
            EndDoc(PrinterDC);
            
            //delete GDI resources
            DeleteDC(PrinterDC);
            ReleaseDC(hwnd,WindowDC);
            DeleteDC(WindowDC);
        }

finally i put the code working fine..
thanks for all.
if these code have any errors or something, then tell me
Topic archived. No new replies allowed.