File:  [WindowsNT SDKs] / mstools / mfc / samples / oclient / mainwnd.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.

// MAINWND.CXX : main window

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

static LPSTR CreateNewUniqueName(LPSTR lpstr);

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


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

CMainWnd::CMainWnd()
	: m_document(this)
{
	VERIFY(m_title.LoadString(IDS_APPNAME));
	VERIFY(LoadAccelTable(MAKEINTRESOURCE(ID_APPLICATION)));
	Create(NULL, m_title, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
		rectDefault, NULL, MAKEINTRESOURCE(ID_APPLICATION));
	ASSERT(m_hWnd != NULL);
	m_pSelection = NULL;
	m_fDirty = FALSE;
}

#pragma warning(default:4355)

// Iterator over content
COleClientItem* CMainDocument::GetNextItem(POSITION& rPosition,
		BOOL* pIsSelected)
{
	CItemWnd* pItemWnd = (CItemWnd*) rPosition;
	if (pItemWnd == NULL)
		pItemWnd = (CItemWnd*)m_pView->GetTopWindow();
	else
		pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow();

	*pIsSelected = (m_pView->GetSelection() == pItemWnd);
	rPosition = (POSITION)pItemWnd;
	return (pItemWnd == NULL) ? NULL : pItemWnd->GetEmbedded();
}


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

void CMainWnd::OnAbout()
{
	CModalDialog about(MAKEINTRESOURCE(IDDT_ABOUT), this);
	about.DoModal();
}

void CMainWnd::Hourglass(BOOL bOn)
{
	static int count = 0;
	static HCURSOR hcurWait = AfxGetApp()->LoadStandardCursor(IDC_WAIT);
	static HCURSOR hcurLast;

	ASSERT(hcurWait != NULL);
	if (bOn)
	{
		if (count++ == 0)
			hcurLast = ::SetCursor(hcurWait);
	}
	else
	{
		if (--count == 0)
			::SetCursor(hcurLast);
	}
}

void CMainWnd::OnClose()
{
	if (COleClientItem::InWaitForRelease())
	{
		ErrorMessage(E_BUSY);
		return;
	}

	if (!SaveAsNeeded())
		return;     // don't quit

	DeregisterDoc();
	DestroyWindow();
}

BOOL CMainWnd::OnQueryEndSession()
{
	if (COleClientItem::InWaitForRelease())
		return FALSE;
	return CFrameWnd::OnQueryEndSession();
}

void CMainWnd::OnDestroy()
{
	GetDocument()->Revoke();    // revoke just in case
	CFrameWnd::OnDestroy(); // will close down the app
}

/////////////////////////////////////////////////////////////////////////////
// Error reporting

void CMainWnd::ErrorMessage(UINT id)
{
	// if in exit mode no message box
	if (!GetDocument()->IsOpen())
		return;

	CString str;
	str.LoadString(id);
	MessageBox(str, AfxGetAppName(), MB_OK | MB_ICONEXCLAMATION);
}

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

void CMainWnd::OnExit()
{
	// close window - NOTE: Do _not_ call 'OnClose' message map function
	SendMessage(WM_CLOSE);
}

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


BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
	// windows messages
	ON_WM_INITMENUPOPUP()
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_WM_QUERYENDSESSION()
	ON_WM_ACTIVATE()

	// file menu commands
	ON_COMMAND(IDM_NEW, OnFileNew)
	ON_COMMAND(IDM_OPEN, OnFileOpen)
	ON_COMMAND(IDM_SAVE, OnFileSave)
	ON_COMMAND(IDM_SAVEAS, OnFileSaveAs)
	ON_COMMAND(IDM_EXIT, OnExit)
	ON_COMMAND(IDM_ABOUT, OnAbout)
	// edit menu commands
	ON_COMMAND(IDM_CUT, OnCut)
	ON_COMMAND(IDM_COPY, OnCopy)
	ON_COMMAND(IDM_PASTE, OnPaste)
	ON_COMMAND(IDM_PASTELINK, OnPasteLink)
	ON_COMMAND(IDM_CLEAR, OnClear)
	ON_COMMAND(IDM_CLEARALL, OnClearAll)
	ON_COMMAND(IDM_INSERT_OBJECT, OnInsertObject)
	ON_COMMAND(IDM_LINKS, OnEditLinks)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Most Edit Commands

void CMainWnd::OnInitMenuPopup(CMenu* pMenu, UINT iMenu, BOOL bSysMenu)
{
	if (bSysMenu || iMenu != IMENU_EDIT)
		return; // system and file menu don't do any dynamic updating

	ASSERT(pMenu != NULL);
	// only enable/diable items on the Edit menu
	CItemWnd* pSelection = GetSelection();

	//BLOCK: Simple editing
	{
		UINT    mfCanEdit = MF_GRAYED|MF_DISABLED;

		if (pSelection != NULL)
			mfCanEdit = MF_ENABLED; // have some content

		// Now enable appropriate menu items
		pMenu->EnableMenuItem(IDM_CUT, mfCanEdit);
		pMenu->EnableMenuItem(IDM_COPY, mfCanEdit);
		pMenu->EnableMenuItem(IDM_CLEAR, mfCanEdit);
		pMenu->EnableMenuItem(IDM_CLEARALL, mfCanEdit);
	}

	//BLOCK: paste variants
	{
		pMenu->EnableMenuItem(IDM_PASTE, COleClientItem::CanPaste() ?
			 MF_ENABLED : (MF_GRAYED|MF_DISABLED));
		pMenu->EnableMenuItem(IDM_PASTELINK, COleClientItem::CanPasteLink() ?
			 MF_ENABLED : (MF_GRAYED|MF_DISABLED));
	}

	//BLOCK: special case if any linked objects
	{
		UINT    mfLinks = MF_GRAYED|MF_DISABLED;

		CItemWnd* pItemWnd;
		for (pItemWnd = (CItemWnd*)GetTopWindow(); pItemWnd != NULL;
			pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow())
		{
			if (pItemWnd->GetEmbedded()->GetType() == OT_LINK)
			{
				mfLinks = MF_ENABLED;
				break;
			}
		}
		pMenu->EnableMenuItem(IDM_LINKS, mfLinks);
	}

	//BLOCK: Object menu specific
	{
		static int iItemObjectVerb = -1;    // position on the Edit menu

		if (iItemObjectVerb == -1)
		{
			// one-time init - find the position of the "Object ?" menuitem
			int nItems = pMenu->GetMenuItemCount();
			for (int iItem = 0; iItem < nItems; iItem++)
			{
				if (pMenu->GetMenuItemID(iItem) == IDM_OBJECT_VERB_MIN)
				{
					iItemObjectVerb = iItem;
					break;
				}
			}
			ASSERT(iItemObjectVerb != -1);
				// MUST BE IN THE MENU TEMPLATE ON INIT !
		}

		AfxOleSetEditMenu(pSelection == NULL ? NULL : pSelection->GetEmbedded(),
			pMenu, iItemObjectVerb, IDM_OBJECT_VERB_MIN);
	}
}

BOOL CMainWnd::OnCommand(UINT wParam, LONG lParam)
{
	// if we are waiting for release - ignore all commands
	if (COleClientItem::InWaitForRelease())
	{
		ErrorMessage(E_BUSY);
		return TRUE;        // handled
	}

	if (LOWORD(lParam) == 0 && wParam >= IDM_OBJECT_VERB_MIN &&
		wParam <= IDM_OBJECT_VERB_MAX)
	{
		// activate the current selection with the appropriate verb
		CItemWnd* pItemWnd = GetSelection();
		ASSERT(pItemWnd != NULL);
		pItemWnd->DoVerb(wParam - IDM_OBJECT_VERB_MIN);
		return TRUE;        // handled
	}
	return CFrameWnd::OnCommand(wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////
// Selection support

void CMainWnd::SetSelection(CItemWnd* pNewSelection)
{
	if (pNewSelection != GetTopWindow() && pNewSelection != NULL)
		pNewSelection->BringWindowToTop();

	if (m_pSelection != pNewSelection)
	{
		// de-select old
		if (m_pSelection != NULL)
			m_pSelection->Select(FALSE);
		// select the new
		if (pNewSelection != NULL)
		{
			pNewSelection->Select(TRUE);
		}
		m_pSelection = pNewSelection;
	}
}

void CMainWnd::OnActivate(UINT nState, CWnd*, BOOL)
{
	if (m_pSelection)
		m_pSelection->Select(nState != 0);
}

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

void CMainWnd::OnCut()
{
	if (!DoCopySelection())
	{
		ErrorMessage(E_CLIPBOARD_CUT_FAILED);
		return;
	}
	// cut it out
	OnClear();
	Dirty();
}


void CMainWnd::OnCopy()
{
	if (!DoCopySelection())
		ErrorMessage(E_CLIPBOARD_COPY_FAILED);
}

BOOL CMainWnd::DoCopySelection()
{
	CItemWnd* pSel = GetSelection();
	ASSERT(pSel != NULL);

	if (!OpenClipboard())
		return FALSE;

	/* Empty the clipboard */
	EmptyClipboard();

	TRY
		pSel->GetEmbedded()->CopyToClipboard();
	CATCH (CException, e)
		return FALSE;
	END_CATCH

	CloseClipboard();
	return TRUE;
}


void CMainWnd::OnClear()
{
	ASSERT(GetSelection() != NULL);
	CItemWnd* pSel = GetSelection();

	if (pSel)
		pSel->DestroyWindow();

	Dirty();
}

void CMainWnd::ClearAll()
{
	CWnd* pKid;
	while ((pKid = GetTopWindow()) != NULL)
	{
		VERIFY(pKid->DestroyWindow());
	}
}

void CMainWnd::OnClearAll()
{
	ClearAll();      /* Wipes out all items */
	Dirty();
}

void CMainWnd::OnPaste()
{
	if (!DoPaste(FALSE))
		ErrorMessage(E_GET_FROM_CLIPBOARD_FAILED);
	Dirty();
}

void CMainWnd::OnPasteLink()
{
	if (!DoPaste(TRUE))
		ErrorMessage(E_GET_FROM_CLIPBOARD_FAILED);
}

BOOL CMainWnd::DoPaste(BOOL fLink)
{
	if (!OpenClipboard())
		return NULL;                    /* Couldn't open the clipboard */

	Hourglass(TRUE);

	/* Don't replace the current object unless we're successful */
	CItemWnd* pItemWnd = new CItemWnd(this);
	CEmbeddedItem* pItem = pItemWnd->GetEmbedded();
	char szName[OLE_MAXNAMESIZE];
	CreateNewUniqueName(szName);

	TRY
	{
		if (fLink)
		{
			if (!pItem->CreateLinkFromClipboard(szName))
				AfxThrowMemoryException();      // any exception will do
		}
		else
		{
			// paste embedded
			if (pItem->CreateFromClipboard(szName))
			{
				TRACE("embedded an embedded OLE object\n");
			}
			else if (pItem->CreateStaticFromClipboard(szName))
			{
				TRACE("embedded a static picture object\n");
			}
			else
			{
				AfxThrowMemoryException();      // any exception will do
			}
		}
	}
	CATCH (CException, e)
	{
		// general cleanup
		TRACE("failed to embed/link an OLE object\n");
		delete pItemWnd;
		pItemWnd = NULL;
	}
	END_CATCH

	CloseClipboard();
	Hourglass(FALSE);

	if (pItemWnd == NULL)
		return FALSE;
	
	// create as a live health ItemWnd
	if (!pItemWnd->CreateItemWindow(TRUE))
	{
		delete pItemWnd;
		return FALSE;
	}

	// Success !
	//  (from this point on the PostNcCreate hook will clean up memory)
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// Insert new object

void CMainWnd::OnInsertObject()
{
	CString className;

	if (!AfxOleInsertDialog(className))
		return;

	TRACE("Trying to Insert OLE object (class '%s')\n", (const char*)className);
	CItemWnd* pItemWnd = new CItemWnd(this);
	CEmbeddedItem* pItem = pItemWnd->GetEmbedded();

	char szTmp[OLE_MAXNAMESIZE];
	TRY
	{
		if (!pItem->CreateNewObject(className, CreateNewUniqueName(szTmp)))
			AfxThrowMemoryException();      // any exception will do
	}
	CATCH (CException, e)
	{
		ErrorMessage(E_FAILED_TO_CREATE);
		// clean up item
		delete pItemWnd;
		return;
	}
	END_CATCH

	// Create invisible (will become visible later when updated)
	if (!pItemWnd->CreateItemWindow(FALSE))
		delete pItemWnd;

	// Success!
	//  (from this point on the PostNcCreate hook will clean up memory)

	Dirty();
}

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

void FixObjectBounds(CRect& rect)
{
	/* If we have an empty rectangle, start at default size */
	if (rect.IsRectNull())
	{
		rect.SetRect(0, 0, CXDEFAULT, CYDEFAULT);
	}
	else
	{
		// First map from HIMETRIC back to screen coordinates
		{
			CClientDC screenDC(NULL);

			short oldMode = screenDC.SetMapMode(MM_HIMETRIC);
			screenDC.LPtoDP(&rect);
			screenDC.SetMapMode(oldMode);
		}

		/* Preserve the Aspect Ratio of the picture */
		DWORD xDiff = (DWORD) (rect.right - rect.left + 1);
		DWORD yDiff = (DWORD) (rect.bottom - rect.top + 1);

		/* Don't use *= here because of integer arithmetic. */
		if (xDiff > CXDEFAULT || yDiff > CYDEFAULT)
		{
			if ((xDiff * CYDEFAULT) > (yDiff * CXDEFAULT))
			{
				yDiff = ((yDiff * CXDEFAULT) / xDiff);
				xDiff = CXDEFAULT;
			}
			else
			{
				xDiff = ((xDiff * CYDEFAULT) / yDiff);
				yDiff = CYDEFAULT;
			}
		}
		rect.SetRect(0, 0, (int)xDiff - 1, (int)yDiff - 1);
	}
}

/////////////////////////////////////////////////////////////////////////////
// Name generator helper

LPSTR CreateNewUniqueName(LPSTR lpstr)
{
	static int CurrentNumber = 0;
	wsprintf(lpstr, "%s%04d", (LPSTR)OBJ_NAME_PREFIX, CurrentNumber++);
	return(lpstr);
}

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

void CMainWnd::OnEditLinks()
{
	CItemWnd* pSelection = GetSelection();

	AfxOleLinksDialog(GetDocument());
}

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

#ifdef _DEBUG
void CMainWnd::AssertValid() const
{
	ASSERT(GetDocument()->IsOpen());
}
#endif

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

unix.superglobalmegacorp.com

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