Link to home
Start Free TrialLog in
Avatar of tullhead
tullheadFlag for United States of America

asked on

Print a Dialog panel?

Standard printing in MFC prints a view
of the document (using OnDraw).  But is
there an easy way to print a dialog
panel's image?  Its kinda like a screen
capture of just that panel, and print
it....  The "output" of my application
is a big panel full of fields with
numbers in them -- this is the real output, so this is what the PRINT button
should print.  How?


When I previously asked this question,
vachooho had given me this code:

// get the default printer
CPrintDialog dlg(FALSE);
dlg.GetDefaults();

// is a default printer set up?
HDC hdcPrinter = dlg.GetPrinterDC();
if (hdcPrinter == NULL)
{
   MessageBox(_T("Buy a printer!"));
}
else
{
   // create a CDC and attach it to the default printer
   CDC dcPrinter;
   dcPrinter.Attach(hdcPrinter);

   // call StartDoc() to begin printing
   DOCINFO docinfo;
   memset(&docinfo, 0, sizeof(docinfo));
   docinfo.cbSize = sizeof(docinfo);
   docinfo.lpszDocName = _T("CDC::StartDoc() Code Fragment");

   // if it fails, complain and exit gracefully
   if (dcPrinter.StartDoc(&docinfo) < 0)
   {
      MessageBox(_T("Printer wouldn't initalize"));
   }
   else
   {
      // start a page
      if (dcPrinter.StartPage() < 0)
      {
         MessageBox(_T("Could not start page"));
         dcPrinter.AbortDoc();
      }
      else
      {
         // set viewportorg and ext
         // ....
         // actually do some printing
         pDialog->SendMessage(WM_PAINT, (WPARAM)dcPrinter.m_hDC);
      }
   }
}


And then he told me to add:
you will need to add
dcPrinter.EndPage();
dcPrinter.EndDoc();

just AFTER the line

pDialog->SendMessage(WM_PAINT, (WPARAM)dcPrinter.m_hDC);


But, the bottom line is that when this
executes, the printer spits out a blank
page.  Perhaps it is close, and I'm
just missing something simple?  Or is
this approach destined not to work?

Help!

Avatar of tullhead
tullhead
Flag of United States of America image

ASKER

Points increased to 150!
Try

pDialog->Print(&dcPrinter, PRF_CHILDREN | PRF_CLIENT | PRF_NONCLIENT | PRF_OWNED);
Do you mean to do this instead of (or in
addition to) the SendMessage(WM_PAINT...?

I tried throwing it in (in addition to
the existing code) and now instead of
the page being entirely blank, there
is one very tiny thing draw in the
corner of the page.  Do I just need
to set the vieworg or viewext or
something?  Can you tell me how to do
that?
I tried the same things and other variations to print a dialog. I found this in VC++ VIEWFORM.CPP OnDraw():

void CFormView::OnDraw(CDC* pDC)
{
  ASSERT_VALID(this);

  // do nothing - dialog controls will paint themselves,
  //   and Windows dialog controls do not support printing
#ifdef _DEBUG
  if (pDC->IsPrinting())
    TRACE0("Warning: CFormView does not support printing.\n");
#endif

  UNUSED(pDC);     // unused in release build
}

It appears as if there isn't any canned way to do this... I'll throw in 200 points to anyone who can come up with a usable solution.

Steve
>Do you mean to do this instead of (or in addition to) the SendMessage(WM_PAINT...?

Yes.

>Do I just need to set the vieworg or viewext or something?  Can you tell me how to do that?

Probably. Try the following code AFTER dcPrinter.StartPage.

CDC dcScrn;
dcScrn.CreateIC(_T("DISPLAY"), NULL, NULL, NULL);

dcPrinter.SetMapMode(MM_ANISOTROPIC);
dcPrinter.SetWindowExt(dcScrn.GetDeviceCaps(LOGPIXELSX), dcScrn.GetDeviceCaps(LOGPIXELSY));
dcPrinter.SetViewportExt(dcPrinter.GetDeviceCaps(LOGPIXELSX), dcPrinter.GetDeviceCaps(LOGPIXELSY));
dcPrinter.SetWindowOrg(0, 0);
dcPrinter.SetViewportOrg(0, 0);
Hmmmm....  Well, that helped to make
the stuff thats printed a little bigger
so I can actually kinda see it --
however, its not a good rendering of
my dialog panel -- its very confusing
but it appears that what was printed
was all (or some) of the controls on
that dialog all printed on top of each
other in the upper left hand corner
of the page.  Although is such a mess
that I can't be sure thats what happened.

Any other ideas?

Maybe as the comment from steveGTR was
suggesting, this is not easily done?
(However, I don't understand how the
 CFormView class relates to Dialogs,
 so...)

Chensu (or others) have you seen applications that print an image of
one of their Dialog panels?  It didn't
seem like such an odd thing to want to
do, but I'm beginning to worry....
CFormView uses a dialog template (i.e. puts a dialog in a view).
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is a good start. It performs exactly like an ALT-PRTSCRN. So if any part of the dialog (window) is not visible it isn't printed. Definately a good start. Let's see what tullhead has to say. If he finds this acceptable, I'll give you the points Chensu. Thanks!
OK, yup, thats pretty much what I was
looking for. Thanks!

Say, what the deal with the listing on
that support/kb/articles page??  I had
to fix up the code, like:

 change "&amp;" to "&"
 change "-&gt;" to "->"

and to get it to compile I had to add
a cast:

  (void **) pBits

and I had to change the code a little
and get rid of "hLogPal" altogether...

steveGTR - did you have to do all that
twiddling too?

That was a pain
in the butt, but otherwise, its just
what I needed, so I'm now happy as a
clam!  steveGTR -- toss your points to
chensu also!
Yeah, the code was a mess. I got a copy off of the MSDN CD and it had some compiler errors --- but what do you want for free? Oh, I mean 200 points. I'll post a message for you chensu. Deals a deal! Good job.