OLEDOCVW.CPP

/************************************************************************** 
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright 1997 Microsoft Corporation. All Rights Reserved.
**************************************************************************/

/**************************************************************************

File: OleDocVw.cpp

Description: COleDocumentView implementation.

**************************************************************************/

/**************************************************************************
#include statements
**************************************************************************/

#include "OleDocVw.h"
#include <windowsx.h>

/**************************************************************************

COleDocumentView::COleDocumentView()

**************************************************************************/

COleDocumentView::COleDocumentView(COleDocument *pOleDoc)
{
OutputDebugString(TEXT("COleDocumentView's constructor\n"));

m_pInPlaceSite = NULL;
m_pInPlaceFrame = NULL;
m_pInPlaceUIWindow = NULL;
m_hwndView = NULL;
m_fUIActive = FALSE;
m_fInPlaceActive = FALSE;
m_hSharedMenu = NULL;
m_hOleMenu = NULL;

m_pOleDoc = pOleDoc;

CreateViewWindow();
}

/**************************************************************************

COleDocumentView::~COleDocumentView()

**************************************************************************/

COleDocumentView::~COleDocumentView()
{
OutputDebugString(TEXT("COleDocumentView's destructor\n"));

if(m_pInPlaceFrame)
m_pInPlaceFrame->Release();

if(m_pInPlaceUIWindow)
m_pInPlaceUIWindow->Release();

if(m_pInPlaceSite)
m_pInPlaceSite->Release();
}

///////////////////////////////////////////////////////////////////////////
//
// IUnknown Implementation
//

/**************************************************************************

COleDocumentView::QueryInterface

**************************************************************************/

STDMETHODIMP COleDocumentView::QueryInterface( REFIID riid,
LPVOID *ppReturn)
{
OutputDebugString(TEXT("COleDocumentView::QueryInterface\n"));

return m_pOleDoc->QueryInterface(riid, ppReturn);
}

/**************************************************************************

COleDocumentView::AddRef

**************************************************************************/

STDMETHODIMP_(DWORD) COleDocumentView::AddRef()
{
OutputDebugString(TEXT("COleDocumentView::AddRef\n"));

return m_pOleDoc->AddRef();
}


/**************************************************************************

COleDocumentView::Release

**************************************************************************/

STDMETHODIMP_(DWORD) COleDocumentView::Release()
{
OutputDebugString(TEXT("COleDocumentView::Release\n"));

return m_pOleDoc->Release();
}

/**************************************************************************

COleDocumentView::SetInPlaceSite()

**************************************************************************/

STDMETHODIMP COleDocumentView::SetInPlaceSite(IOleInPlaceSite *pNewSite)
{
OutputDebugString(TEXT("COleDocumentView::SetInPlaceSite\n"));

//clean up previous site if it exists
if(m_pInPlaceSite)
{
if(m_fUIActive)
{
DeactivateUI();
}

if(m_fInPlaceActive)
{
DeactivateInPlace();
}

if(m_pInPlaceFrame)
{
m_pInPlaceFrame->Release();
m_pInPlaceFrame = NULL;
}

if(m_pInPlaceUIWindow)
{
m_pInPlaceUIWindow->Release();
m_pInPlaceUIWindow = NULL;
}

m_pInPlaceSite->Release();
m_pInPlaceSite = NULL;
}

m_pInPlaceSite = pNewSite;

if(m_pInPlaceSite)
{
m_pInPlaceSite->AddRef();

RECT rcClip;

m_FrameInfo.cb = sizeof(m_FrameInfo);

m_pInPlaceSite->GetWindowContext( &m_pInPlaceFrame,
&m_pInPlaceUIWindow,
&m_Rect,
&rcClip,
&m_FrameInfo);
}

return S_OK;
}

/**************************************************************************

COleDocumentView::GetInPlaceSite()

**************************************************************************/

STDMETHODIMP COleDocumentView::GetInPlaceSite(IOleInPlaceSite **ppInPlaceSite)
{
OutputDebugString(TEXT("COleDocumentView::GetInPlaceSite\n"));

HRESULT hr = E_FAIL;

*ppInPlaceSite = m_pInPlaceSite;

if(*ppInPlaceSite)
{
(*ppInPlaceSite)->AddRef();
hr = S_OK;
}

return hr;
}

/**************************************************************************

COleDocumentView::GetDocument()

**************************************************************************/

STDMETHODIMP COleDocumentView::GetDocument(IUnknown **ppUnk)
{
OutputDebugString(TEXT("COleDocumentView::GetDocument\n"));

*ppUnk = m_pOleDoc;

if(*ppUnk)
(*ppUnk)->AddRef();

return S_OK;
}

/**************************************************************************

COleDocumentView::SetRect()

**************************************************************************/

STDMETHODIMP COleDocumentView::SetRect(LPRECT pRect)
{
OutputDebugString(TEXT("COleDocumentView::SetRect - "));

if(!pRect)
return E_INVALIDARG;

m_Rect = *pRect;

TCHAR szText[MAX_PATH];
wsprintf(szText, TEXT("%d, %d, %d, %d\n"), m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom);
OutputDebugString(szText);

MoveWindow(m_hwndView, m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom, TRUE);

return S_OK;
}

/**************************************************************************

COleDocumentView::GetRect()

**************************************************************************/

STDMETHODIMP COleDocumentView::GetRect(LPRECT pRect)
{
OutputDebugString(TEXT("COleDocumentView::GetRect\n"));

if(!pRect)
return E_INVALIDARG;

*pRect = m_Rect;

return S_OK;
}

/**************************************************************************

COleDocumentView::SetRectComplex()

**************************************************************************/

STDMETHODIMP COleDocumentView::SetRectComplex( LPRECT prcView,
LPRECT prcHScroll,
LPRECT prcVScroll,
LPRECT prcSizeBox)
{
OutputDebugString(TEXT("COleDocumentView::SetRectComplex\n"));

return E_NOTIMPL;
}

/**************************************************************************

COleDocumentView::Show()

**************************************************************************/

STDMETHODIMP COleDocumentView::Show(BOOL bShow)
{
OutputDebugString(TEXT("COleDocumentView::Show\n"));

if(bShow)
{
//if the object is not in-place active, make it that way
if(!m_fInPlaceActive)
ActivateInPlace();

//show the window
BringWindowToTop(m_hwndView);
ShowWindow(m_hwndView, SW_SHOW);
UpdateWindow(m_hwndView);
}
else
{
//if the object is UI active, make remove that state
if(m_fUIActive)
DeactivateUI();

//hide the window
ShowWindow(m_hwndView, SW_HIDE);
}

return S_OK;
}

/**************************************************************************

COleDocumentView::UIActivate()

**************************************************************************/

STDMETHODIMP COleDocumentView::UIActivate(BOOL bActivate)
{
OutputDebugString(TEXT("COleDocumentView::UIActivate\n"));

if(bActivate)
{
return ActivateUI();
}

return DeactivateUI();
}

/**************************************************************************

COleDocumentView::ActivateUI()

**************************************************************************/

STDMETHODIMP COleDocumentView::ActivateUI()
{
OutputDebugString(TEXT("COleDocumentView::ActivateUI\n"));

//set the active object
//either one of these could be good
if(m_pInPlaceFrame)
{
m_pInPlaceFrame->SetActiveObject(m_pOleDoc->m_pOleInPlaceActiveObject, NULL);
}

if(m_pInPlaceUIWindow)
{
m_pInPlaceUIWindow->SetActiveObject(m_pOleDoc->m_pOleInPlaceActiveObject, NULL);
}

if(m_pInPlaceSite)
{
m_fUIActive = TRUE;

ActivateInPlace();

m_pInPlaceSite->OnUIActivate();

MergeMenus();

SetFocus(m_hwndView);
}

return S_OK;
}

/**************************************************************************

COleDocumentView::DeactivateUI()

**************************************************************************/

STDMETHODIMP COleDocumentView::DeactivateUI()
{
OutputDebugString(TEXT("COleDocumentView::DeactivateUI\n"));

m_fUIActive = FALSE;

RemoveMenus();

//remove the active object
//either one of these could be good
if(m_pInPlaceFrame)
{
m_pInPlaceFrame->SetActiveObject(NULL, NULL);
}

if(m_pInPlaceUIWindow)
{
m_pInPlaceUIWindow->SetActiveObject(NULL, NULL);
}

if(m_pInPlaceSite)
{
m_pInPlaceSite->OnUIDeactivate(FALSE);
}

return S_OK;
}

/**************************************************************************

COleDocumentView::Open()

**************************************************************************/

STDMETHODIMP COleDocumentView::Open(void)
{
OutputDebugString(TEXT("COleDocumentView::Open\n"));

return S_OK;
}

/**************************************************************************

COleDocumentView::CloseView()

**************************************************************************/

STDMETHODIMP COleDocumentView::CloseView(DWORD dwReserved)
{
OutputDebugString(TEXT("COleDocumentView::CloseView\n"));

SetInPlaceSite(NULL);

return S_OK;
}

/**************************************************************************

COleDocumentView::SaveViewState()

**************************************************************************/

STDMETHODIMP COleDocumentView::SaveViewState(IStream *pStream)
{
OutputDebugString(TEXT("COleDocumentView::SaveViewState\n"));

return E_NOTIMPL;
}

/**************************************************************************

COleDocumentView::ApplyViewState()

**************************************************************************/

STDMETHODIMP COleDocumentView::ApplyViewState(IStream *pStream)
{
OutputDebugString(TEXT("COleDocumentView::ApplyViewState\n"));

return E_NOTIMPL;
}

/**************************************************************************

COleDocumentView::Clone()

**************************************************************************/

STDMETHODIMP COleDocumentView::Clone(IOleInPlaceSite *pIPSite, IOleDocumentView **ppView)
{
OutputDebugString(TEXT("COleDocumentView::Clone\n"));

*ppView = NULL;

return E_NOTIMPL;
}

/**************************************************************************

COleDocumentView::ActivateInPlace()

**************************************************************************/

STDMETHODIMP COleDocumentView::ActivateInPlace()
{
OutputDebugString(TEXT("COleDocumentView::ActivateInPlace\n"));

m_fInPlaceActive = TRUE;

if(m_pInPlaceSite)
{
// tell the site we are in-place activating
m_pInPlaceSite->OnInPlaceActivate();

HWND hwndParent;
m_pInPlaceSite->GetWindow(&hwndParent);
SetParent(m_hwndView, hwndParent);

//show the view
Show(TRUE);
}

return S_OK;
}

/**************************************************************************

COleDocumentView::DeactivateInPlace()

**************************************************************************/

STDMETHODIMP COleDocumentView::DeactivateInPlace()
{
OutputDebugString(TEXT("COleDocumentView::InPlaceDeactivate\n"));

//UI deactivate, if necessary and hide the view window
Show(FALSE);

m_fInPlaceActive = FALSE;

if(m_pInPlaceSite)
{
// tell the site we are in-place deactivating
m_pInPlaceSite->OnInPlaceDeactivate();
}

//set the parent to NULL
SetParent(m_hwndView, GetDesktopWindow());

return S_OK;
}

/**************************************************************************

COleDocumentView::CreateDocWindow()

**************************************************************************/

STDMETHODIMP COleDocumentView::CreateViewWindow()
{
OutputDebugString(TEXT("COleDocumentView::CreateViewWindow\n"));

WNDCLASS wc;

//if our window class has not been registered, then do so
if(!GetClassInfo(g_hInst, VIEW_CLASS_NAME, &wc))
{
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)ViewWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = VIEW_CLASS_NAME;

if(!RegisterClass(&wc))
return E_FAIL;
}

m_hwndView = CreateWindowEx( WS_EX_CLIENTEDGE,
VIEW_CLASS_NAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS,
0,
0,
0,
0,
GetDesktopWindow(),
NULL,
g_hInst,
(LPVOID)this);

if(!m_hwndView)
{
DWORD dwError = GetLastError();
return E_FAIL;
}

return S_OK;
}

/**************************************************************************

COleDocumentView::ViewWndProc()

**************************************************************************/

LRESULT CALLBACK COleDocumentView::ViewWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
COleDocumentView *pThis = (COleDocumentView*)GetWindowLong(hWnd, GWL_USERDATA);

switch (uMessage)
{
case WM_NCCREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
pThis = (COleDocumentView*)(lpcs->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
}
break;

case WM_CREATE:
return pThis->OnCreate();

case WM_COMMAND:
return pThis->OnCommand( GET_WM_COMMAND_ID(wParam, lParam),
GET_WM_COMMAND_CMD(wParam, lParam),
GET_WM_COMMAND_HWND(wParam, lParam));

case WM_PAINT:
return pThis->OnPaint();

case WM_INITMENUPOPUP:
return pThis->UpdateMenu((HMENU)wParam);

}

return DefWindowProc(hWnd, uMessage, wParam, lParam);
}

/**************************************************************************

COleDocumentView::OnCreate()

**************************************************************************/

LRESULT COleDocumentView::OnCreate(void)
{
return 0;
}

/**************************************************************************

COleDocumentView::OnCommand()

**************************************************************************/

LRESULT COleDocumentView::OnCommand(UINT uID, UINT uCmd, HWND hwndCmd)
{
switch(uID)
{
case IDM_RED:
m_pOleDoc->m_Color = RED_COLOR;
InvalidateRect(m_hwndView, NULL, TRUE);
UpdateWindow(m_hwndView);
m_pOleDoc->m_fDirty = TRUE;
break;

case IDM_GREEN:
m_pOleDoc->m_Color = GREEN_COLOR;
InvalidateRect(m_hwndView, NULL, TRUE);
UpdateWindow(m_hwndView);
m_pOleDoc->m_fDirty = TRUE;
break;

case IDM_BLUE:
m_pOleDoc->m_Color = BLUE_COLOR;
InvalidateRect(m_hwndView, NULL, TRUE);
UpdateWindow(m_hwndView);
m_pOleDoc->m_fDirty = TRUE;
break;

}

return 0;
}

/**************************************************************************

COleDocumentView::OnPaint()

**************************************************************************/

LRESULT COleDocumentView::OnPaint(void)
{
PAINTSTRUCT ps;

BeginPaint(m_hwndView, &ps);

RECT rc;
HBRUSH hBrush = CreateSolidBrush(m_pOleDoc->m_Color);
GetClientRect(m_hwndView, &rc);

FillRect(ps.hdc, &rc, hBrush);

DeleteObject(hBrush);

EndPaint(m_hwndView, &ps);

return 0;
}

/**************************************************************************

COleDocumentView::MergeMenus()

**************************************************************************/

BOOL COleDocumentView::MergeMenus(void)
{
if(!m_hSharedMenu)
{
// Create the menu resource
m_hSharedMenu = CreateMenu();

ZeroMemory(&m_mgw, sizeof(m_mgw));

// have the contaner insert its menus
if(SUCCEEDED(m_pInPlaceFrame->InsertMenus(m_hSharedMenu, &m_mgw)))
{
int nFirstGroup = (int) m_mgw.width[0];
HMENU hMenu,
hSubMenu;
TCHAR szText[MAX_PATH];

hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_COLOR_MENU));
hSubMenu = GetSubMenu(hMenu, 0);

//get the menu item's text
GetMenuString(hMenu, 0, szText, ARRAYSIZE(szText), MF_BYPOSITION);

// insert the server menus
InsertMenu( m_hSharedMenu,
nFirstGroup,
MF_BYPOSITION | MF_POPUP,
(UINT)hSubMenu,
szText);

//update the OLEMENUGROUPWIDTHS structure
m_mgw.width[1] += 1;
m_mgw.width[3] += 0;
m_mgw.width[5] += 0;
}
else
{
// Destroy the menu resource
DestroyMenu(m_hSharedMenu);
m_hSharedMenu = NULL;
}
}

if(!m_hOleMenu)
{
// tell OLE to create the menu descriptor
m_hOleMenu = OleCreateMenuDescriptor(m_hSharedMenu, &m_mgw);
}

m_pInPlaceFrame->SetMenu(m_hSharedMenu, m_hOleMenu, m_hwndView);

return TRUE;
}

/**************************************************************************

COleDocumentView::RemoveMenus()

**************************************************************************/

BOOL COleDocumentView::RemoveMenus(void)
{
if(m_hSharedMenu)
{
int nFirstGroup = (int) m_mgw.width[0];

m_pInPlaceFrame->SetMenu(NULL, NULL, NULL);

// remove the menus that we added
RemoveMenu(m_hSharedMenu, nFirstGroup, MF_BYPOSITION);

// have the container remove its menus
m_pInPlaceFrame->RemoveMenus(m_hSharedMenu);

// Destroy the menu resource
DestroyMenu(m_hSharedMenu);

m_hSharedMenu = NULL;
}

if(m_hOleMenu)
{
// destroy the menu descriptor
OleDestroyMenuDescriptor(m_hOleMenu);

m_hOleMenu = NULL;
}

return TRUE;
}

/**************************************************************************

COleDocumentView::UpdateMenu()

**************************************************************************/

BOOL COleDocumentView::UpdateMenu(HMENU hMenu)
{
UINT uCheck;

switch(m_pOleDoc->m_Color)
{
case RED_COLOR:
uCheck = IDM_RED;
break;

case GREEN_COLOR:
uCheck = IDM_GREEN;
break;

case BLUE_COLOR:
uCheck = IDM_BLUE;
break;

default:
uCheck = 0;
break;
}

return CheckMenuRadioItem( hMenu,
IDM_RED,
IDM_BLUE,
uCheck,
MF_BYCOMMAND);
}