15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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 be  to 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




| Вернуться в корень Архива |