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
| Вернуться в корень Архива
|