Printing child windows
Peter Moss -- pmoss@bbn.com Friday, January 31, 1997 Environment: VC++ 4.2b, NT 4.0 I am struggling with printing child windows drawn in a View, and I am wondering if anyone can shed some light on this matter. I have a View derived from CView, and I interactively create some child windows in this View. These child windows are all derived from CWnd in a class I call CPlotLabel. I am also using MM_ANISOTROPIC mode for my drawing as I want my View to be "sized to fit." Things work fine and my CPlotLabel::OnPaint handler draws my labels just fine. My problem is when I go to print (and do Print Preview). The default CView::OnPrint method calls the CView::OnDraw. It seems that my child window CPlotLabel::OnPaint is not getting called in this case. The best solution I could come up with was to override OnPrint, and enumerate the child windows using CWnd::GetWindow. My code in OnPrint looks something like this: void CMyView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { // Scale the pDC and use MM_ANISOTROPIC .. // Code to draw the View .. // Here is my attempt to paint the Child Windows for (CWnd* pChildWnd = GetWindow(GW_CHILD); pChildWnd != NULL; pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT)) { pChildWnd->SendMessage(WM_PAINT, (HDC)pDC->m_hDC, 0); } The good news is that the CPlotLabel::OnPaint gets the message, but the normal call to CPaintDC dc(this); seems to return some DC that doesn't draw where it's supposed to. I was able to get a CDC I could draw to by doing the following in the OnPaint handler: const MSG* pMsg = GetCurrentMessage(); HDC hDC = (HDC)pMsg->wParam; TRACE1("CPlotLabel::PrintLabel hDC = %x\n", hDC); CDC* pDC = CDC::FromHandle(hDC); ASSERT(pDC); This at least allowed me to draw into the Print Preview window. So I'm making progress. One of my biggest problems is with the scaling, however. For the Print Preview operation, if I call pDC->GetWindowExt(), the CSize returned seems to beto the scaling I set in my View, but multiplied by 2! And if I naively call pDC->SetWindowExt(), I get some strange placement. Can anyone shed some light on this problem? It seems that I'm probably missing something very fundamental here. Is there an easier way to do what I'm trying to do? Thanks, Pete Moss pmoss@bbn.com
Roma -- roma@neonet.lv Monday, February 03, 1997 [Mini-digest: 2 responses] Peter Moss wrote: > > Environment: VC++ 4.2b, NT 4.0 > > I am struggling with printing child windows drawn in a View, and I am > wondering if anyone can shed some light on this matter. > > I have a View derived from CView, and I interactively create some child > windows in this View. These child windows are all derived from CWnd in a > class I call CPlotLabel. I am also using MM_ANISOTROPIC mode for my drawing > as I want my View to be "sized to fit." Things work fine and my > CPlotLabel::OnPaint handler draws my labels just fine. > > My problem is when I go to print (and do Print Preview). The default > CView::OnPrint method calls the CView::OnDraw. It seems that my child window > CPlotLabel::OnPaint is not getting called in this case. Yes, you are right - they will not be called. > The best solution I > could come up with was to override OnPrint, and enumerate the child windows > using CWnd::GetWindow. You can also do that in the OnDraw() like this: void CMyView::OnDraw(CDC *pDC) { ... if(pDC->IsPrinting()) { for (CWnd* pChildWnd = GetWindow(GW_CHILD); pChildWnd != NULL; pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT)) { pChildWnd->SendMessage(WM_PAINT, (HDC)pDC->m_hDC, 0); } } } And instead of sending WM_PAINT, send user-defined message to your child window and in your class add a handler for this message. Or, better, if you have a list of objects of class CPlotLabel, you can add a special function like CPlotLabel::PaintMeHere(CDC *pDc) with drawing code, and call it from the above loop, thus avoiding involving of the messaging mechanism. Like this: void CPlotLabel::PaintMeHere(CDC *pDC, CPoint &pt) { //Draw label in the pDC, assuming top-left corner at (pt.x, pt.y) ... } void CPlotLabel::OnPaint() { PAINTSTRUCT ps; CDC *pDC = BeginPaint(&ps); PaintMeHere(pDC, CPoint(0,0)); EndPaint(&ps) } ... void CMyView::OnDraw(CDC *pDC) { ... if(pDC->IsPrinting()) { CWnd* pChildWnd = GetWindow(GW_CHILD); CRect rect; while(pChildWnd) { pChildWnd->GetWindowRect(&rect); ScreenToClient(&rect); pChildWnd->PaintMeHere(pDC, rect.TopLeft()); pChildWnd->GetWindow(GW_HWNDNEXT); } } } > Thanks, > Pete Moss > pmoss@bbn.com HTH, -Roma -----From: "Kenneth A. Argo"There is an MFC example on how to do this. The example is based on a = CFormView, but I would think that the methods are the same as what you = are trying. Ken ---------- From: Peter Moss[SMTP:pmoss@bbn.com] Sent: Friday, January 31, 1997 12:13 PM To: mfc-l@netcom.com Cc: Peter Moss Subject: Printing child windows Environment: VC++ 4.2b, NT 4.0 I am struggling with printing child windows drawn in a View, and I am=20 wondering if anyone can shed some light on this matter. I have a View derived from CView, and I interactively create some child=20 windows in this View. These child windows are all derived from CWnd in = a=20 class I call CPlotLabel. I am also using MM_ANISOTROPIC mode for my = drawing=20 as I want my View to be "sized to fit." Things work fine and my=20 CPlotLabel::OnPaint handler draws my labels just fine. My problem is when I go to print (and do Print Preview). The default=20 CView::OnPrint method calls the CView::OnDraw. It seems that my child = window=20 CPlotLabel::OnPaint is not getting called in this case. The best = solution I=20 could come up with was to override OnPrint, and enumerate the child = windows=20 using CWnd::GetWindow. My code in OnPrint looks something like this: void CMyView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { // Scale the pDC and use MM_ANISOTROPIC
| Вернуться в корень Архива |