|
Hey, your work is surprisingly simple and correct...congratulations.
Although i haven't deep-scanned the code, i was wondering if thre's a simple way to print only the actual window so that fits the page...any hint?
Thanks,
Alberto.
|
|
|
|
|
Hi Alberto,
Thanks for the nice words.
To change the code to always to print "fit to page size" (proportional correct off course), you would need to change the stretching section of the code.
See arround line 375, there should be this code:
scrXY = (double)sizeScreen.cx/(double)sizeScreen.cy;
prnXY = (double)sizePrn.cx/(double)sizePrn.cy;
if (scrXY>prnXY)
{
zoomx = ((double)sizeClient.cx/(double)sizeScreen.cx);
zoomy = ((double)sizeClient.cy/(double)sizeScreen.cy)*(prnXY/scrXY);
}
else
{
zoomx = ((double)sizeClient.cx/(double)sizeScreen.cx)*(scrXY/prnXY);
zoomy = ((double)sizeClient.cy/(double)sizeScreen.cy);
}
Now change it to
scrXY = (double)sizeClient.cx/(double)sizeClient.cy;
prnXY = (double)sizePrn.cx/(double)sizePrn.cy;
if (scrXY>prnXY)
{
zoomx = (double)sizeClient.cx;
zoomy = ((double)sizeClient.cy) *(prnXY/scrXY);
}
else
{
zoomx = ((double)sizeClient.cx)*(scrXY/prnXY);
zoomy = (double)sizeClient.cy;
}
and you should get the 'fit to page' printing. For active window, use the 2nd example, like
#include "PrntScreen.h"
CPrntScreen * ScrCap;
ScrCap = new CPrntScreen();
ScrCap->DoPrntScreen(1,0,true);
delete ScrCap;
ScrCap = NULL;
And please do not forget to fix that error (memory leak) at line 294, as stated in the below posts!
To do so, change line 294 from
CBitmap *oldImage = new CBitmap,srcImage;
to
CBitmap *oldImage = new CBitmap;
CBitmap srcImage;
Havn't found time to update the article, will do so soon, thought.
Greetings,
Albert Hermann
-- modified at 13:19 Wednesday 11th January, 2006
|
|
|
|
|
Exactly what I was looking for! Excellent ---!
|
|
|
|
|
I downloaded, unzipped, included and tried, it run at once. Thanks a lot.
|
|
|
|
|
Hi, thank for a class.
Function void CPrntScreen::DoPrntScreen(int fArea, int fOrientation, bool bDialog)
Change
// CBitmap *oldImage = new CBitmap,srcImage;
To
CBitmap *oldImage;
CBitmap srcImage;
|
|
|
|
|
Ahh,
of course! What a st.... mistake.
Thanks very much, Saruth, will fix this soon.
Albert
|
|
|
|
|
Hello all
Say I have a program - for which I have no source code, and it prints a "report" in this case it is actually a Point-Of-Sale RECEIPT going to either a SERIAL or PARALLEL printer port
I want tyo TRAP, the print Job, before it gets to the port, re-package it (add some Logo, and header / footer lines) and then let go of it to the intended printer..
Can this be done? Any suggestions please (using MFC / C++)
Thanks
Alex
|
|
|
|
|
No, don't have no real idea, if this can be made in an easy way. Looks like you would have to programm a device driver to capture the parallel port or something like that.
Sorry that i can´t help.
Albert
|
|
|
|
|
Albert,
Thanks for you code. I have a dialog application that needs printing and your code is perfect for it. You have saved me a lot of time!!!
Cheers
Macca
|
|
|
|
|
I´m glad that the code helped.
Thanks,
Albert
|
|
|
|
|
I saw this article 15 minutes ago. Automatic screen dump to printer is now implemented in my project. Works like a charm. I haven't even read the code yet. Just plugged it in. Talk about useful article. Got an "Excellent" vote from me. The first to receive it in here
One suggestion though, for the sake of user feedback: Encapsulate the DoPrntScreen() call with BeginWaitCursor() and EndWaitCursor(), since the call takes a couple of seconds to return. Especially informative if you use just the default printer.
DP TO THE PEOPLE
|
|
|
|
|
Thanks for the nice comments. Nice to see, that the code helps others, like i was help by a lot of the code here at the Code Project.
Actually, my private version has BeginWaitCursor() and EndWaitCursor() implemented, but i didn´t think that others would like this. It´s really time to update the code and implement the suggestion made here
Albert
|
|
|
|
|
Hi Albert,
the class works fine!
I have a suggestion:
What about making the printer dialog modal?
I've done it this way:
;<br />
CPrintDialog pd(FALSE,PD_ALLPAGES,NULL);
All over the Code, this has to be changed:
;<br />
pd.GetPrinterDC();<br />
<br />
;<br />
pd.GetDevMode();
And this is the modal call:
if(pd.DoModal()==IDOK)
Best regards
Andreas
|
|
|
|
|
Hi Andreas,
Great suggestion (why didn´t i have that idea by myself )
I will test this and add a modal version of the dialog to the article, as soon as i can free up some time (as always too occupied )
Huge thanks
Albert
|
|
|
|
|
my screen is 1024 x 768. I would like my printing to look exactly like my screen. The text is usually black on white background. the bitmap stretching makes my text blurry. Is there any way to tell the printer that i am sending it a 1024 by 768 image and that it must figure out how to scale it to full paper size so that the text is not blurry.
Just livin a dream.. dont wake me!
|
|
|
|
|
Great article. The simplest ones are always the best ones for understanding. Thanks alot!
|
|
|
|
|
I appreciate your help for me.
For one week, suffer from this work.
Thanks to you, I solved the problem easily, dine out on your code.
I'm really Thank You VeryVeryMuch~!^-^
|
|
|
|
|
Hello
Trying to figure out if my POS Epson receipt printer can print bitmaps or not,
using GetDeviceCaps(hDC,RASTERCAPS)on 4 different printers - I get the same result of the returning value = something like 28313
Anything else maybe that I can use?
Cheers
Alex
|
|
|
|
|
Alex,
the function GetDeviceCaps(hDC, RASTERCAPS) does actually not test, if the printer can print bitmaps. It returns an information, that can be tested for certain raster capabilities. So you have to check the return value if the desired bit is set. In my code, i was testing specificly the stretchblit capability with
int iRasterCaps=GetDeviceCaps(pd.hDC,RASTERCAPS);
if ((iRasterCaps&RC_STRETCHBLT)==0) ...
The GetDeviceCaps() function can retrieve diferent device-specific informations, where 'RASTERCAPS' is just one of them.
I think, if you check the TECHNOLOGY feature and then test, if the DT_RASPRINTER bit is set, the printer should be able to print graphics.
So maybe you should try something like:
int iDevCaps=GetDeviceCaps(pd.hDC, TECHNOLOGY);
if (iDevCaps & DT_RASPRINTER)
{
...printer should be able to print graphics
}
I am not 100% shure, maybe you will have to play around a bit with this.
Albert
|
|
|
|
|
Hi Albert
Thanks for that, it seems the right direction. When I tried it however, various printers are reporting back features that are not always delivered...
Thanks again
Alex
|
|
|
|
|
My boss asked me to print the display (which includes a map of North America). Within minutes (using your code)... problem solved.
Thanks for the posting.
Just one thing. I'm printing from a dual screen setup which has a resolution of 1200x3200, so I had to modify the algorithm to print the correct size.
|
|
|
|
|
Thanks for this articol, it's excellent!
I've used it for one application with success.
Now I'm developping another dialog based application and I need to print only a dialog, so I made this change:
.....
wHndle=DialogToPrint->m_hWnd;
hscreenDC = ::GetDC(wHndle);
screenDC.Attach(hscreenDC);
sizeClient.cx = 400;
sizeClient.cy = 400;
sizeScreen.cx = 400;
sizeScreen.cy = 400;
screenDC.DPtoLP(&sizeScreen);
.....
the problem is the following:
- if the user shift a block of the dialog out of the screen, the application print a piece of dialog with a black column.
I haven't any idea how to print a dialog, can you help me?
Thank in advance
mais
|
|
|
|
|
The only way how i can imagine how to solve this is to force the dialog back to visible area. Here some code which brings back the dialog to the screen center during capture:
I suppose you use "Dialog Capture", so insert into the following section
case 1:
..
..
GetWindowRect(wHndle,&rectClient);
nX = rectClient.left;
nY = rectClient.top;
nX2 = rectClient.right;
nY2 = rectClient.bottom;
<-------insert here the code below!
if (nX < 0) nX = 0;
if (nY < 0) nY = 0;
..
..
the following code:
if ((nX < 0)||(nY < 0)||(nX2 > sizeClient.cx) || (nY2 > sizeClient.cy))
{
HWND hwndOwner;
RECT rc, rcDlg, rcOwner;
hwndOwner = GetDesktopWindow();
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(wHndle, &rcDlg);
CopyRect(&rc, &rcOwner);
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
SetWindowPos(wHndle,
HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0, 0,
SWP_NOSIZE);
UpdateWindow(wHndle);
GetWindowRect(wHndle,&rectClient);
nX = rectClient.left;
nY = rectClient.top;
nX2 = rectClient.right;
nY2 = rectClient.bottom;
}
Hope that helps,
Albert
|
|
|
|
|
Thanks very much, now my application works correctly!
mais
|
|
|
|
|
When I print the client area in an SDI application I also capture the toolbar, how do I capture the client area without the toolbar?
|
|
|
|
|