Microsoft KB Archive/127192

= How To Draw Controls in an OLE Metafile =

Article ID: 127192

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 1.5 Professional Edition

 Microsoft Visual C++ 1.51

 Microsoft Visual C++ 1.52 Professional Edition

 Microsoft Visual C++ 2.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.1</li></ul>

 Microsoft Visual C++ 4.0 Standard Edition</li></ul>

 Microsoft Visual C++ 4.1 Subscription</li></ul>

 Microsoft Visual C++ 5.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 5.0 Professional Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q127192

<div class="summary_section">

SUMMARY
You can use controls, either directly on a CView or from a dialog template on a CFormView, in an OLE enabled MFC application. However, when the item is embedded but not active, the controls on these views will not be drawn to the Windows metafile supplied to the COleServerItem::OnDraw function. In this case, you must "draw" the controls manually into the metafile. This article shows you how.

<div class="moreinformation_section">

MORE INFORMATION
The simplest way to get controls to "draw" in a metafile is to use the same method the VIEWEX sample uses to draw its CInputView to a printer device context. VIEWEX's OnPrint routine draws each control as a rectangle, circle, text, and so on. Override the COleServerItem::OnDraw function and insert your code into it. As an example, use the COleServerItem::OnDraw function listed in this article; it shows both the VIEWEX code to insert in the OnDraw member function and the helper function PaintChildWindows that actually does the painting of each control.

Sample Code
/* Compile options needed: Standard

void CMyServerItem::OnDraw(CDC* pDC) // pDC is actually a metafile {   //BLOCK: Set up scale mode {       CClientDC dcScreen(NULL); pDC->SetMapMode(MM_ANISOTROPIC); // map 1 screen logical inch to 1 printer (/output) logical inch pDC->SetWindowExt(dcScreen.GetDeviceCaps(LOGPIXELSX),               dcScreen.GetDeviceCaps(LOGPIXELSX)); pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),               pDC->GetDeviceCaps(LOGPIXELSX)); }   // we must also offset the window positions relative to the scroll // offset

// We cheat here since some controls do not paint if they are // invisible, so we temporary make set the appropriate visible bits // during preview mode so the controls think they are visible even // though they aren't.

HWND hWndCheatVisible = NULL; if (!IsWindowVisible) {       // walk up to the top until we find the invisible window for (HWND hWnd = m_hWnd;           hWnd != NULL; hWnd = ::GetParent(hWnd)) {           ASSERT(hWnd != NULL); DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); if ((dwStyle & WS_VISIBLE) == 0) {               ::SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_VISIBLE); hWndCheatVisible = hWnd; break; }       }        ASSERT(hWndCheatVisible != NULL); }

CPen pen(PS_SOLID, 1, RGB(0,0,0)); // solid black pen CPen* pOldPen = pDC->SelectObject(&pen);

ASSERT(pDC->GetWindowOrg == CPoint(0,0)); CRect pRect = new CRect(-50,-50,600,600);

PaintChildWindows(m_hWnd, pDC, GetDeviceScrollPosition); ASSERT(pDC->GetWindowOrg == CPoint(0,0)); pDC->SelectObject(pOldPen);

if (hWndCheatVisible != NULL) ::SetWindowLong(hWndCheatVisible, GWL_STYLE,           ::GetWindowLong(hWndCheatVisible, GWL_STYLE) &~ WS_VISIBLE); }

void CMyServerItem::PaintChildWindows(HWND hWndParent,                                     CDC* pDC, CPoint ptOffset) {   for (HWND hWndChild = ::GetTopWindow(hWndParent);        hWndChild != NULL;        hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT)) {       CRect rect; ::GetWindowRect(hWndChild, rect); // wnd rect in screen coords ScreenToClient(&rect);            // relative to this view

HDC hdcOut = pDC->m_hDC; CPoint pt = pDC->GetWindowOrg; ASSERT(pt.x == 0 && pt.y == 0);
 * 1) ifdef _DEBUG
 * 1) endif

DWORD dwStyle = ::GetWindowLong(hWndChild, GWL_STYLE); if (dwStyle & (WS_HSCROLL|WS_VSCROLL)) {           TRACE("Warning: printing control with scrollbars not supported\n"); }       if (dwStyle & WS_BORDER) {           // the only case we special case - manually drawn border ::Rectangle(hdcOut, rect.left, rect.top, rect.right,                       rect.bottom); rect.InflateRect(-1,-1);       // 1 logical pixel }

pDC->SaveDC; {           CPoint pt(ptOffset.x + rect.left, ptOffset.y + rect.top); pDC->LPtoDP(&pt); pDC->OffsetViewportOrg(pt.x, pt.y); // set the viewport origin so that the window origin // can be changed by the control

// draw it using a non-virtual HDC ::SendMessage(hWndChild, WM_PAINT, (WPARAM)hdcOut, 0L); }       pDC->RestoreDC(-1);

if (::GetTopWindow(hWndChild) != NULL) PaintChildWindows(hWndChild, pDC, ptOffset); } }

Additional query words: mfc ole inplace embed

Keywords: kbctrl kbhowto kbinplaceact kbmetafile KB127192

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.