Solved

How to capture and print entire application window in  MFC Doc/View

Posted on 2002-07-23
6
1,414 Views
Last Modified: 2013-11-20
I have a SDI MFC application. How do I capture my entire application acreen and print the screen which includes title bar, 2 split window and status bar, and print the application window? Basically it is a snapshot of the applicaiton. I am using Doc/View.
0
Comment
Question by:nicolet
  • 2
  • 2
6 Comments
 
LVL 9

Accepted Solution

by:
BeyondWu earned 200 total points
ID: 7173660
1.Get the HBITMAP of your whole window.
a. this function can get the bitmap of the whole window, no matter it's hide or show.
HBITMAP GetWndBmp(HWND hWnd/*your main window handle*/)
{
  if(hBitMap)
     DeleteObject(hBitMap);

  HDC hCatchDC = CreateCompatibleDC(NULL);
  HDC hTempDC = ::GetDC(NULL);
  RECT rect;
  ::GetWindowRect(hWnd, &rect);
  int nWidth = rect.right - rect.left;
  int nHeight = rect.bottom - rect.top;
  hBitMap = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
  HBITMAP oldbmp = (HBITMAP)SelectObject(hCatchDC, hBitMap);
  // let the window draw itself on my hCatchDC
  SendMessage(hWnd, WM_PRINT, (WPARAM)hCatchDC, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);

  ::ReleaseDC(NULL, hTempDC);

  SelectObject(hCatchDC, oldbmp);
  DeleteDC(hCatchDC);
  return hBitMap;
}

b. this function is simple and only get the visible windows.
HBITMAP GetWndBmp(HWND hWnd/*your main window handle*/)
{
  RECT rect;
  ::GetWindowRect(hWnd, &rect);
  int nWidth = rect.right - rect.left;
  int nHeight = rect.bottom - rect.top;

  HDC dc = GetWindowDC(hWnd);
  HDC hMemDC = CreateCompatibleDC(dc);
  HBITMAP hBitMap = CreateCompatibleBitmap(dc, nWidth, nHeight);
  HBITMAP oldbmp = (HBITMAP)SelectObject(hMemDC, hBitMap);

  BitBlt(hMemDC, 0, 0, nWidth, nHeight, dc, rect.left, rect.top, SRCCOPY);
     
  SelectObject(hMemDC, oldbmp);
  //DeleteObject(hBitMap);
  DeleteDC(hMemDC);
  ReleaseDC(hWnd, dc);
  return hBitMap;
}

2.Send to the printer
After get a HBITMAP of the window, it easy to send it to printer.
a. Get printer DC
  use CDC dcPrinter;
      CWinApp::CreatePrinterDC(dcPrinter)
or
  CDC dcPrinter;
  CPrintDialog pPD(FALSE);
  pPD.m_pd.Flags |= PD_RETURNDEFAULT;
  if(pPD.DoModal()==IDOK)
      dcPrinter.Attach(pPD.GetPrinterDC());

3. now, you can print it with startdoc/startpage/.. functions.

   DOCINFO docinfo;
   memset(&docinfo, 0, sizeof(docinfo));
   docinfo.cbSize = sizeof(docinfo);
   docinfo.lpszDocName = _T("print window test");

   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
      {
         // actually do some printing
         // use StretchDIBits(hdcPrinter,0, 0, iWidth, ..
         // or use BitBlt(hdcPrinter, 0, 0, nWidth, ..
         // directly, because the Printer's DPI is higher
         // than Screen, so you maybe should resample the
         // hBitMap, so you'd better use StretchDIBits
 
         dcPrinter.EndPage();
         dcPrinter.EndDoc();
      }
   }
0
 

Author Comment

by:nicolet
ID: 7174649
In your answer to get
1.Get the HBITMAP of your whole window.
a. this function can get the bitmap of the whole window, no matter it's hide or show.

I have couple questions:
1. How did you get the hBitMap? before you check
if(hBitMap)
    DeleteObject(hBitMap);

2. When you do
// let the window draw itself on my hCatchDC
 SendMessage(hWnd, WM_PRINT, (WPARAM)hCatchDC, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);

Isn't that true that you assume ON_FILE_PRINT funciton has been implemented for printing the window in Doc/View platform? But how about the situation that application has not implemented the ON_FILE_PRINT, or the ON_FILE_PRINT will only print out parts of the document content?
In these cases how do you get your whole application window into the hCatchDC?


0
 

Author Comment

by:nicolet
ID: 7174810
Hi BeyondWu,

Also In your answer doing
       // actually do some printing
        // use StretchDIBits(hdcPrinter,0, 0, iWidth, ..
        // or use BitBlt(hdcPrinter, 0, 0, nWidth, ..
        // directly, because the Printer's DPI is higher
        // than Screen, so you maybe should resample the
        // hBitMap, so you'd better use StretchDIBits

StretchDIBits(hdcPrinter ...
or BitBlt(hdcPrinter..      

Who did you get this hdcPrinter? I suppose that hdcPrinter is different from dcPrinter.  
0
 
LVL 9

Expert Comment

by:BeyondWu
ID: 7175998
It's only a clue and pseudocode for you, I have tested it, it only describes all necessary steps which you need.

1.Call if(hBitMap)DeleteObject(hBitMap); to avoid GDI leak, if you call the functions two or more times, it should delete the previous hbitmap.

2.Have nothing to do with ON_FILE_PRINT, have you ever study it in MSDN?

3.hdcPrinter = dcPrinter, my mistake.
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question