Implement Site Shading and Draw the Object

The user interface guidelines for OLE indicate that the container should draw a hatch pattern across its site when the object in that site is active—that is, when it is open in another window. This shading appears as shown in Figure 17-6. We add this shading when IOleClientSite::OnShowWindow(TRUE) is called and remove it when the same function is called with FALSE:

Figure 17-6.

The typical appearance of a site with a loaded object and shaded with an open object. The sizing handles are optional.

Again, Patron accomplishes this shading in CTenant::ShowAsOpen, for which the fOpen argument specifies to shade or not to shade:


void CTenant::ShowAsOpen(BOOL fOpen)
{
BOOL fWasOpen;
DWORD dwState;
RECT rc;
HDC hDC;

fWasOpen=(BOOL)(TENANTSTATE_OPEN & m_dwState);

dwState=m_dwState & ~TENANTSTATE_OPEN;
m_dwState=dwState ś ((fOpen) ? TENANTSTATE_OPEN : 0);

//If this was not open, just hatch; otherwise, repaint.
if (!fWasOpen && fOpen)
{
RECTFROMRECTL(rc, m_rcl);
RectConvertMappings(&rc, NULL, TRUE);
OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);

hDC=GetDC(m_hWnd);
UIDrawShading(&rc, hDC, UI_SHADE_FULLRECT, 0);
ReleaseDC(m_hWnd, hDC);
}

if (fWasOpen && !fOpen)
Repaint();

return;
}

Besides doing the shading, the tenant also remembers the open state with TENANTSTATE_OPEN. This flag is used in its drawing function (CTenant::Draw) so that the shading is preserved across repaints.

The hatching itself is accomplished using a helper function, UIDrawShading, that you'll find in the INOLE.DLL library. (Sources are in INOLE\UIEFFECT.CPP.) This function basically creates a hatch brush and paints over a given rectangle with the GDI call PatBlt using an ROP code of 0x00A000C9, which performs the logical AND operation between the black pattern and whatever is on hDC. We get a black hatch pattern across whatever is underneath. Because this hatching is destructive, going from an open state into a loaded state requires that we repaint the entire object to remove the hatching. Fortunately for Patron, CTenant::Repaint does exactly that.

Drawing and printing an object in a site always happen inside CTenant::Draw. This does little more than call IViewObject2::Draw, but it also includes grab handles and the hatch pattern as necessary. An important point to remember is that site shading applies only to on-screen presentations! Do not draw such shading if you are sending information to the printer. That would certainly look strange.