File:  [WindowsNT SDKs] / mstools / mfc / samples / oclient / itemwnd.cpp
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:21:00 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-oct-1992, ntsdk-jun-1992, ntsdk-jul-1993, HEAD
Microsoft Windows NT Build 297 06-28-1992

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and Microsoft
// QuickHelp documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

// user interface to OLE embedded objects
//
// Each OLE embedded object is given it's own window to draw in
// We use the windows thick frame to provide sizing (NOTE: this is not
//      UISG conformant!)

#include "oclient.h"

#include "mainwnd.h"
#include "itemwnd.h"

/////////////////////////////////////////////////////////////////////////////
// Static members for dragging state

CRect CItemWnd::dragRect;
CPoint CItemWnd::dragPt;

/////////////////////////////////////////////////////////////////////////////
// Message map for ItemWnd

BEGIN_MESSAGE_MAP(CItemWnd, CWnd)
	// windows messages
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Creation

#pragma warning(disable:4355)
// C4355 is "'this' used in base initializer list" warning

CItemWnd::CItemWnd(CMainWnd* pContainer)
	: m_embedded(pContainer->GetDocument(), this)
{
	m_pContainer = pContainer;
	m_fVisible = m_fTrackSize = FALSE;
	m_fCaptured = FALSE;
}

#pragma warning(default:4355)


BOOL CItemWnd::CreateItemWindow(BOOL fShow)
{
	ASSERT(m_pContainer != NULL);
	CRect   rectBounds;

	if (!GetEmbedded()->GetBounds(&rectBounds))
		rectBounds.SetRectEmpty(); // server doesn't know about the bounds

	FixObjectBounds(rectBounds);

	rectBounds.OffsetRect(2 * GetSystemMetrics(SM_CXFRAME),
					2 * GetSystemMetrics(SM_CYFRAME));

	if (!CWnd::Create(NULL, NULL /* no title */,
		WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME,
		rectBounds, m_pContainer, 0))
	{
		return FALSE;
	}

	m_fVisible = fShow;
	m_fTrackSize = TRUE;

	GetEmbedded()->SetNames();
	/* Make the object visible, and paint it if fShow == TRUE */
	if (fShow)
	{
		ShowWindow(SW_SHOW);
		m_pContainer->SetSelection(this);
	}

	return TRUE;
}

BOOL CItemWnd::RestoreItemWindow(const RECT& rect)
{
	ASSERT(m_pContainer != NULL);
	CRect rectBounds = rect;

	rectBounds.OffsetRect(2 * GetSystemMetrics(SM_CXFRAME),
					2 * GetSystemMetrics(SM_CYFRAME));

	if (!CWnd::Create(NULL, NULL /* no title */,
		WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME,
		rectBounds, m_pContainer, 0))
	{
		return FALSE;
	}

	GetEmbedded()->SetNames();

	if (m_fVisible)
		ShowWindow(SW_SHOW);
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////

void CItemWnd::PostNcDestroy()
{
	ASSERT(m_hWnd == NULL);     // must be detached

	if (m_pContainer->GetSelection() == this)
		m_pContainer->SetSelection(NULL);

	// finally free up the C++ object and memory
		// (will destroy embedded object as needed)
	delete this;
}


BOOL CItemWnd::OnEraseBkgnd(CDC* pDC)
{
	CBrush myBrush(GetSysColor(COLOR_WINDOW));
	CRect rect;
	GetClientRect(&rect);
	pDC->FillRect(rect, &myBrush);
	return TRUE;        // we handled it
}


void CItemWnd::OnPaint()
{
	CPaintDC dc(this);
	CRect   rect;

	// set up a reasonable default context
	dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
	dc.SetBkColor(::GetSysColor(COLOR_WINDOW));

	// Draw the item
	GetClientRect(&rect);
	GetEmbedded()->Draw(&dc, &rect, NULL, &dc);
		// ignore if can't draw
}


void CItemWnd::OnSize(UINT, int, int)
{
	Dirty();

	// Stop tracking size.  If user didn't change size, the flag
	// will be reset later.
	m_fTrackSize = FALSE;
}


void CItemWnd::DoVerb(UINT nVerb)
	// "run" the object
{
	if (GetEmbedded()->GetType() == OT_STATIC)
		return;
	CRect   rect;
	GetClientRect(&rect);

	TRY
	{
		GetEmbedded()->Activate(nVerb, TRUE, TRUE, this, &rect);
	}
	CATCH (COleException, e)
	{
		GetEmbedded()->ReportError(e->m_status);
	}
	AND_CATCH (CException, e)
	{
		// general error when playing
		m_pContainer->ErrorMessage(E_FAILED_TO_LAUNCH);
	}
	END_CATCH
}

/////////////////////////////////////////////////////////////////////////////
// Mouse messages

void CItemWnd::OnLButtonDblClk(UINT, CPoint)
{
	DoVerb(OLEVERB_PRIMARY);
}

void CItemWnd::OnLButtonDown(UINT, CPoint point)
{
	m_pContainer->SetSelection(this);

	GetWindowRect(&dragRect);
	GetParent()->ScreenToClient(&dragRect);

	dragPt = point;

	ClientToScreen(&dragPt);
	GetParent()->ScreenToClient(&dragPt);

	SetCapture();
	m_fCaptured = TRUE;
}

void CItemWnd::OnLButtonUp(UINT, CPoint)
{
	if (!m_fCaptured)
		return;

	ReleaseCapture();
	m_fCaptured = FALSE;

	/* The object moved */
	Dirty();
}

void CItemWnd::OnMouseMove(UINT, CPoint point)
{
	if (!m_fCaptured)
		return;

	ClientToScreen(&point);
	GetParent()->ScreenToClient(&point);

	dragRect.OffsetRect(point.x - dragPt.x, point.y - dragPt.y);
	MoveWindow(dragRect);
	dragPt = point;
}

/////////////////////////////////////////////////////////////////////////////
// Serialization

// first WORD in stream is 0x5500 + extra bits

void CItemWnd::Serialize(CArchive& ar)
{
	// save the window information + embedded
	CRect   rect;

	if (ar.IsStoring())
	{
		// First save our window part
		ASSERT(m_fVisible);     // only serialize visible window
		WORD w = 0x5500;        // magic value
		if (m_fTrackSize)
			w += 1;
		ar << w;

		// get window position (parent relative)
		GetClientRect(&rect);
		ClientToScreen(&rect);
		GetParent()->ScreenToClient(&rect);
		rect -= CPoint(GetSystemMetrics(SM_CXFRAME),
			 GetSystemMetrics(SM_CYFRAME));
		ar << rect;
	}
	else // loading
	{
		WORD w;
		ar >> w;

		// First load our window part
		if (HIBYTE(w) != 0x55)
		{
			TRACE("Bad magic number in front of an item wnd\n");
			AfxThrowArchiveException(CArchiveException::generic);
		}
		m_fVisible = TRUE;
		m_fTrackSize = (w & 1) != 0;
		ar >> rect;
	}

	// now do the OLE Embedded part
	GetEmbedded()->Serialize(ar);

	if (ar.IsLoading())
	{
		// Wrap-up loading - create an ItemWnd as appropriate
		if (!RestoreItemWindow(rect))
			AfxThrowArchiveException(CArchiveException::generic);
	}
}

/////////////////////////////////////////////////////////////////////////////
// Special handling for OLE Client notification

void CEmbeddedItem::SetNames()
{
	if (GetType() == OT_EMBEDDED)
		SetHostNames(AfxGetAppName(), GetName());
}

// turn on hourglass when waiting for server

void CEmbeddedItem::WaitForServer()
{
	m_pView->m_pContainer->Hourglass(TRUE);
	COleClientItem::WaitForServer();
	m_pView->m_pContainer->Hourglass(FALSE);
}

void CEmbeddedItem::OnChange(OLE_NOTIFICATION wNotification)
{
	/* Item just created or we are updating size */
	if (m_pView->m_hWnd == NULL)
		return;         // no window created yet

	if (m_pView->CanChangeBounds())
	{
		CRect rect;

		if (GetBounds(&rect))
		{
			FixObjectBounds(rect);
			m_pView->SetInitialBounds(rect);
		}
		else
		{
			// Blank object
			if (wNotification == OLE_CLOSED)
			{
				// no data received for the object - destroy it
				// we can't call destroy window here since we are
				//   and OLE callback - so we post a close message instead
				m_pView->PostMessage(WM_CLOSE);
				return;
			}
		}
	}

	m_pView->InvalidateRect(NULL, TRUE);    // erase it
	m_pView->Dirty();
}

void CItemWnd::SetInitialBounds(const CRect& rect)
{
	BOOL fTrackSizeSave = m_fTrackSize; // save since OnSize will change it
	SetWindowPos(NULL, 0, 0,
		rect.right - rect.left + 2*GetSystemMetrics(SM_CXFRAME),
		rect.bottom - rect.top + 2*GetSystemMetrics(SM_CYFRAME),
		SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME);
	m_fTrackSize = fTrackSizeSave;

	// show it
	m_fVisible = TRUE;
	ShowWindow(SW_SHOW);
	m_pContainer->SetSelection(this);
}

/////////////////////////////////////////////////////////////////////////////
// A way to get the thick frame window to look good
	// not a generally useful trick

void CItemWnd::Select(BOOL bOn)
{
	if (m_hWnd != NULL)
		SendMessage(WM_NCACTIVATE, bOn);
}

/////////////////////////////////////////////////////////////////////////////
// Diagnostics

#ifdef _DEBUG
void CItemWnd::AssertValid() const
{
	ASSERT(m_pContainer != NULL);
}
#endif

/////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.