Urgent Help Req'd: Rendering a .NET control to an MFC CDC.

M

mmacrobert

We have an MFC application mixed with a few .NET controls. I would like
to be able to render the content of a .NET control to an MFC device
context - specifically a printing device context.

We wrote the MFC app and the .NET control, so we can add hook functions
into either module if necessary.

The .NET control is hosted in the MFC app using the CWinFormsControl
template.

How can I make this happen? Does anyone have any links to sample source
code?

Any help greatly appreciated.
Thanks,
Martin
 
A

Andy Bates

If your control is derived from the System.Windows.Forms.Control then you
can retrieve the window handle from the control via the IWin32Window
interface. This interface will give you access to the Handle method which
returns an IntPtr. This can be converted into a HWND which in turn can be
converted to a DC using HDC dc = GetDC(hwnd). The MFC application can then
create a BITMAP being the size of the control and blit the content into it;
alternatively you could blit the controls content directly into the printers
DC (providing no windows are over the top of it).

It should be possible with a little messing around to get the .NET control
to render to the printer DC. Depending on what your control provides it may
be easier to render the controls content to a BITMAP and then output that on
the DC in the MFC application (for print, display etc.).

HTH

- Andy
 
M

mmacrobert

Hi Andy,
I have tried what you said, but not having any success. I can't figure
out how to get the .NET control to actually do the drawing onto the MFC
DC. I thought that if I got the window handle (.net window) and its
associated DC then that would suffice. I had thought that if I had the
actual device context of the .NET control then it should already have
rendered it's content to the DC, but apparently this is not the case.

Perhaps you might be able to spot the problem in the code below

Thanks in advance,
Martin

m_ContainedControl->Visible = true;
IWin32Window^ win32Win =
cli::safe_cast<IWin32Window^>(m_ContainedControl.GetControl());
System::IntPtr ptr = win32Win->Handle;
HWND hwnd = (HWND)ptr.ToPointer();
CWnd* pWnd = CWnd::FromHandle(hwnd);
ASSERT(pWnd);
CClientDC netCtrlDC(pWnd); // This will automatically GetDC and
ReleaseDC

// After creating and configuring the memDC
CRect boundingBox(0,0,0,0);
netCtrlDC.GetClipBox(&boundingBox);

CDC memDC;
CBitmap memBitmap;
memDC.CreateCompatibleDC(&netCtrlDC);
netCtrlDC.LPtoDP(&boundingBox);

memBitmap.CreateCompatibleBitmap(&netCtrlDC, boundingBox.Width(),
boundingBox.Height());

AutoSelector selectBitmap(&memDC, &memBitmap);
memDC.SetMapMode(netCtrlDC.GetMapMode());
memDC.SetWindowExt(netCtrlDC.GetWindowExt());
memDC.SetViewportExt(netCtrlDC.GetViewportExt());
netCtrlDC.DPtoLP(&boundingBox);
memDC.SetWindowOrg(boundingBox.left, boundingBox.top);
memDC.FillSolidRect(boundingBox, netCtrlDC.GetBkColor());

// Blit the contents of the .NetCtrl to the memDC
memDC.BitBlt(boundingBox.left,
boundingBox.top,
boundingBox.Width(),
boundingBox.Height(),
&netCtrlDC,
boundingBox.left,
boundingBox.top,
SRCCOPY);

// Debugging Crap Just Draw an X
AutoSelector selectPen(&memDC, BLACK_PEN); // Automatically Deslect
on exit
memDC.MoveTo(boundingBox.TopLeft());
memDC.LineTo(boundingBox.BottomRight());
memDC.MoveTo(boundingBox.right, boundingBox.top);
memDC.LineTo(boundingBox.left, boundingBox.bottom);
// End Debugging Crap

m_ContainedControl->Visible = false;

// Blit the contents of the MemDC to the real DC
CRect thisBoundingBox = GetBaseRgn().GetBounds();

pDC->BitBlt(thisBoundingBox.left,
thisBoundingBox.top,
thisBoundingBox.Width(),
thisBoundingBox.Height(),
&memDC,
boundingBox.left,
boundingBox.top,
SRCCOPY);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top