Solved

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

Posted on 2002-07-23
6
1,479 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Do you have a plan for Continuity?

It's inevitable. People leave organizations creating a gap in your service. That's where Percona comes in.

See how Pepper.com relies on Percona to:
-Manage their database
-Guarantee data safety and protection
-Provide database expertise that is available for any situation

Question has a verified solution.

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

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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.
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

628 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