mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2336 lines
58 KiB
2336 lines
58 KiB
// Copyright (C) Microsoft Corporation 1996-1997, All Rights reserved.
|
|
|
|
#include "header.h"
|
|
#include "contain.h"
|
|
#include "autocont.h"
|
|
#include "htmlpriv.h"
|
|
#include "htmlhelp.h"
|
|
#include "strtable.h"
|
|
#include <exdisp.h>
|
|
#include "unicode.h"
|
|
|
|
static const WCHAR gszHHRegKey[] = L"Software\\Microsoft\\HtmlHelp";
|
|
|
|
// pointer to external IServiceProvider (fix for HelpCenter)
|
|
//
|
|
IServiceProvider *g_pExternalHostServiceProvider = NULL;
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static const char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/*
|
|
* CContainer::CContainer
|
|
* CContainer::~CContainer
|
|
*
|
|
* Constructor Parameters:
|
|
*/
|
|
CContainer::CContainer()
|
|
{
|
|
m_cRef = 0;
|
|
m_pIStorage = NULL;
|
|
m_pOleObject = NULL;
|
|
m_pIAdviseSink = NULL;
|
|
m_pIOleInPlaceSite = NULL;
|
|
m_pIOleClientSite = NULL;
|
|
m_pIOleInPlaceFrame = NULL;
|
|
m_pIOleControlSite = NULL;
|
|
m_pWebBrowser = NULL;
|
|
m_pWebBrowserApp = NULL;
|
|
m_pIDispatch = NULL;
|
|
m_pIOleItemContainer = NULL;
|
|
// m_pCallback = NULL;
|
|
m_pIE3CmdTarget = NULL;
|
|
m_dwEventCookie = 0;
|
|
m_pWebBrowserEvents = NULL;
|
|
m_pCDocHostUIHandler = NULL;
|
|
m_pCDocHostShowUI = NULL;
|
|
m_pInPlaceActive = 0;
|
|
|
|
#ifdef _DEBUG
|
|
m_fDeleting = FALSE;
|
|
#endif
|
|
}
|
|
|
|
CContainer::~CContainer(void)
|
|
{
|
|
#ifdef _DEBUG
|
|
ASSERT(!m_fDeleting)
|
|
m_fDeleting = TRUE;
|
|
#endif
|
|
|
|
// if (m_pInPlaceActive)
|
|
// m_pInPlaceActive->Release();
|
|
|
|
// do this before we release m_pIAdviseSink
|
|
// Reset the View Advise
|
|
LPVIEWOBJECT2 lpViewObject2;
|
|
if (m_pOleObject && SUCCEEDED(m_pOleObject->QueryInterface(IID_IViewObject2, (LPVOID FAR *) &lpViewObject2))) {
|
|
lpViewObject2->SetAdvise(DVASPECT_CONTENT, ADVF_PRIMEFIRST, NULL );
|
|
lpViewObject2->Release();
|
|
}
|
|
|
|
if (m_pIAdviseSink)
|
|
m_pIAdviseSink->Release();
|
|
|
|
if (m_pIOleInPlaceSite)
|
|
m_pIOleInPlaceSite->Release();
|
|
|
|
if (m_pIOleClientSite)
|
|
m_pIOleClientSite->Release();
|
|
|
|
if (m_pIOleInPlaceFrame)
|
|
m_pIOleInPlaceFrame->Release();
|
|
|
|
if (m_pIOleItemContainer)
|
|
m_pIOleItemContainer->Release();
|
|
|
|
if (m_pIOleControlSite)
|
|
delete m_pIOleControlSite;
|
|
|
|
// if (m_pIPropNoteSink)
|
|
// delete m_pIPropNoteSink;
|
|
|
|
if (m_pIE3CmdTarget)
|
|
m_pIE3CmdTarget->Release();
|
|
|
|
if ( m_pCDocHostUIHandler )
|
|
m_pCDocHostUIHandler->Release();
|
|
|
|
if ( m_pCDocHostShowUI )
|
|
m_pCDocHostShowUI->Release();
|
|
|
|
if (m_pWebBrowserApp) {
|
|
m_pWebBrowserApp->Quit();
|
|
delete m_pWebBrowserApp;
|
|
}
|
|
|
|
if (m_pIStorage)
|
|
m_pIStorage->Release();
|
|
if (m_pOleObject)
|
|
m_pOleObject->Release();
|
|
|
|
return;
|
|
}
|
|
|
|
HRESULT CContainer::ShutDown(void)
|
|
{
|
|
if (m_pIDispatch)
|
|
{
|
|
// Unhook event interface, delete our interface object
|
|
//
|
|
LPCONNECTIONPOINTCONTAINER pCPC;
|
|
if (SUCCEEDED(m_pOleObject->QueryInterface(IID_IConnectionPointContainer, (void **) &pCPC)))
|
|
{
|
|
LPCONNECTIONPOINT pCP;
|
|
if (SUCCEEDED(pCPC->FindConnectionPoint(IID_IDispatch, &pCP)))
|
|
{
|
|
pCP->Unadvise(m_dwEventCookie);
|
|
pCP->Release();
|
|
}
|
|
|
|
// Cleanup
|
|
pCPC->Release() ;
|
|
}
|
|
|
|
// Cleanup m_pIDispatch pointer
|
|
m_pIDispatch->Release();
|
|
m_pIDispatch = NULL; // part of fix for 4373
|
|
}
|
|
if(m_pOleObject)
|
|
{
|
|
m_pOleObject->Close(OLECLOSE_NOSAVE);
|
|
m_pOleObject->SetClientSite(NULL);
|
|
}
|
|
|
|
delete this;
|
|
return S_OK;
|
|
}
|
|
|
|
/*
|
|
* CContainer::QueryInterface
|
|
*
|
|
* Purpose:
|
|
* IUnknown members for CContainer object.
|
|
*/
|
|
STDMETHODIMP CContainer::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
#ifdef DEBUG
|
|
char sz[256];
|
|
|
|
wsprintf(sz,"CContainer::QueryInterface('{%8.8X-%4.4X-%4.4X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X}',...);\r\n",
|
|
riid.Data1, riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1],
|
|
riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6],riid.Data4[7]);
|
|
|
|
OutputDebugString(sz);
|
|
#endif
|
|
|
|
*ppv=NULL;
|
|
|
|
if ((IID_IUnknown == riid) || (IID_IServiceProvider == riid))
|
|
*ppv = this;
|
|
|
|
else if (IID_IOleClientSite == riid)
|
|
*ppv = m_pIOleClientSite;
|
|
|
|
else if (IID_IAdviseSink2==riid || IID_IAdviseSink==riid)
|
|
*ppv = m_pIAdviseSink;
|
|
|
|
else if (IID_IOleWindow==riid || IID_IOleInPlaceSite==riid)
|
|
*ppv = m_pIOleInPlaceSite;
|
|
|
|
else if (IID_IOleItemContainer == riid || IID_IOleContainer == riid || IID_IParseDisplayName == riid)
|
|
*ppv = m_pIOleItemContainer;
|
|
|
|
else if (riid == DIID_DWebBrowserEvents) {
|
|
DBWIN("QueryInterface for DIID_DWebBrowserEvents");
|
|
*ppv = (LPDISPATCH)m_pIDispatch;
|
|
}
|
|
else if (riid == DIID_DWebBrowserEvents2) {
|
|
DBWIN("QueryInterface for DIID_DWebBrowserEvents2");
|
|
*ppv = (LPDISPATCH)m_pIDispatch;
|
|
}
|
|
else if (IID_IOleControlSite==riid)
|
|
{
|
|
DBWIN("QueryInterface for IID_IOleControlSite");
|
|
*ppv=m_pIOleControlSite;
|
|
}
|
|
else if ( riid == IID_IDocHostUIHandler )
|
|
{
|
|
DBWIN("QueryInterface for IID_IDocHostUIHandler");
|
|
*ppv = m_pCDocHostUIHandler;
|
|
}
|
|
else if ( riid == IID_IDocHostShowUI )
|
|
{
|
|
DBWIN("QueryInterface for IID_IDocHostShowUI");
|
|
*ppv = m_pCDocHostShowUI;
|
|
}
|
|
|
|
// BUGBUG what to do about this ?
|
|
|
|
// Queries for IDispatch return the ambient properties interface *ppv=m_pIDispatch;
|
|
else if (IID_IDispatch==riid)
|
|
{
|
|
DBWIN("QueryInterface for IID_IDispatch");
|
|
*ppv = (IDispatch*)m_pIDispatch;
|
|
}
|
|
|
|
//End CONTROLMOD
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
STDMETHODIMP CContainer::QueryService(REFGUID rsid, REFIID riid, void ** pv)
|
|
{
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
// Hack for HelpCenter...
|
|
if (g_pExternalHostServiceProvider)
|
|
{
|
|
hr = g_pExternalHostServiceProvider->QueryService(rsid, riid, pv);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CContainer::AddRef(void)
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CContainer::Release(void)
|
|
{
|
|
ULONG cRefT = --m_cRef;
|
|
|
|
// we only delete when specifically told to
|
|
// if (m_cRef == 0)
|
|
// delete this;
|
|
|
|
return cRefT;
|
|
}
|
|
|
|
HRESULT CContainer::Create(HWND hWnd, LPRECT lpRect, BOOL bInstallEventSink)
|
|
{
|
|
LPUNKNOWN pObj;
|
|
CLSID clsidWB1 = { 0xeab22ac3, 0x30c1, 0x11cf, { 0xa7, 0xeb, 0x0, 0x0, 0xc0, 0x5b, 0xae, 0xb } };
|
|
CLSID clsidWB2 = { 0x8856f961, 0x340a, 0x11d0, { 0xa9, 0x6b, 0x0, 0xc0, 0x4f, 0xd7, 0x5, 0xa2 } };
|
|
UINT uRet = (UINT) E_FAIL;
|
|
HRESULT hr;
|
|
|
|
m_hWnd = hWnd;
|
|
|
|
// Create storage, use OLE's temporary compound file support. (ie NULL as first arg.)
|
|
|
|
if ((hr = StgCreateDocfile(NULL, (STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE),
|
|
0, &m_pIStorage)) != S_OK) {
|
|
DEBUG_ReportOleError(hr);
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Create the client site.
|
|
|
|
m_pIOleClientSite = new CIOleClientSite(this);
|
|
m_pIOleClientSite->AddRef();
|
|
|
|
// Create the control site.
|
|
|
|
m_pIOleControlSite = new CIOleControlSite(this);
|
|
m_pIOleControlSite->AddRef();
|
|
|
|
// Create the advise sink.
|
|
|
|
m_pIAdviseSink = new CIAdviseSink(this);
|
|
m_pIAdviseSink->AddRef();
|
|
|
|
// Create the InPlaceSite.
|
|
|
|
m_pIOleInPlaceSite = new CIOleInPlaceSite(this);
|
|
m_pIOleInPlaceSite->AddRef();
|
|
|
|
// Create the InPlaceFrame;
|
|
|
|
m_pIOleInPlaceFrame = new CIOleInPlaceFrame(this);
|
|
m_pIOleInPlaceFrame->AddRef();
|
|
|
|
//
|
|
// We don't install a sink for the special printing instance. HtmlHelp bug 5550.
|
|
//
|
|
if ( bInstallEventSink )
|
|
{
|
|
m_pIDispatch = new CAutomateContent(this);
|
|
m_pIDispatch->AddRef();
|
|
}
|
|
|
|
m_pIOleItemContainer = new CIOleItemContainer(this);
|
|
m_pIOleItemContainer->AddRef();
|
|
|
|
/*
|
|
* The OLE Control specifications mention that a a control might
|
|
* implement IPersistStreamInit instead of IPersistStorage. In that
|
|
* case you cannot use OleCreate on a control but must rather use
|
|
* CoCreateInstance since OleCreate assumes that IPersistStorage is
|
|
* available. With a control, you would have to create the object
|
|
* first, then check if OLEMISC_SETCLIENTSITEFIRST is set, then send it
|
|
* your IOleClientSite first. Then you check for IPersistStorage and
|
|
* failing that, try IPersistStreamInit.
|
|
|
|
* In this sample we do none of this and just assume controls are
|
|
* normal embedded objects because there are questions as to dealing
|
|
* with loading and initialization that are not resolved.
|
|
*/
|
|
|
|
// These are IE4 specific.
|
|
//
|
|
m_pCDocHostUIHandler = new CDocHostUIHandler(this);
|
|
m_pCDocHostUIHandler->AddRef();
|
|
|
|
m_pCDocHostShowUI = new CDocHostShowUI(this);
|
|
m_pCDocHostShowUI->AddRef();
|
|
|
|
|
|
// first try for the IE4 object, if that fails, try for the IE3 object.
|
|
//
|
|
if ((hr = OleCreate(clsidWB2, IID_IOleObject, OLERENDER_NONE, NULL, m_pIOleClientSite, m_pIStorage, (void**)&pObj)) != S_OK )
|
|
{
|
|
if ((hr = OleCreate(clsidWB1, IID_IOleObject, OLERENDER_NONE, NULL, m_pIOleClientSite, m_pIStorage, (void**)&pObj)) != S_OK )
|
|
{
|
|
m_pIStorage->Release();
|
|
m_pIOleClientSite->Release();
|
|
return hr;
|
|
}
|
|
m_bIE4 = FALSE;
|
|
}
|
|
else
|
|
m_bIE4 = TRUE;
|
|
|
|
if ((hr = pObj->QueryInterface(IID_IOleObject, (void **) &m_pOleObject)) == S_OK) {
|
|
LPVIEWOBJECT2 lpViewObject2;
|
|
|
|
// Set a View Advise
|
|
if (SUCCEEDED(m_pOleObject->QueryInterface(IID_IViewObject2, (LPVOID FAR *) &lpViewObject2))) {
|
|
lpViewObject2->SetAdvise(DVASPECT_CONTENT, ADVF_PRIMEFIRST, m_pIAdviseSink);
|
|
lpViewObject2->Release();
|
|
}
|
|
|
|
// 13-Oct-1997 [ralphw] Shouldn't need this...
|
|
// m_pOleObject->SetHostNames(OLESTR("DevIV Package"), OLESTR("DevIV Container"));
|
|
|
|
// inform object handler/DLL object that it is used in the embedding container's context
|
|
|
|
OleSetContainedObject(m_pOleObject, TRUE);
|
|
|
|
// Hook iDispatch up to COleDispatchDriver interface.
|
|
|
|
LPDISPATCH pDispatch;
|
|
|
|
if ((hr = m_pOleObject->QueryInterface(IID_IDispatch, (void **) &pDispatch)) == S_OK) {
|
|
m_pWebBrowserApp = new IWebBrowserAppImpl(pDispatch);
|
|
}
|
|
|
|
//
|
|
// We don't install a sink for the special printing instance. HtmlHelp bug 5550.
|
|
//
|
|
if ( bInstallEventSink )
|
|
{
|
|
// Hook event interface.
|
|
|
|
LPCONNECTIONPOINTCONTAINER pCPC;
|
|
if (SUCCEEDED(hr = m_pOleObject->QueryInterface(IID_IConnectionPointContainer, (void **) &pCPC)))
|
|
{
|
|
LPCONNECTIONPOINT pCP;
|
|
if (SUCCEEDED(pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &pCP))) {
|
|
pCP->Advise((IDispatch*)m_pIDispatch, &m_dwEventCookie);
|
|
pCP->Release();
|
|
}
|
|
else
|
|
if (SUCCEEDED(pCPC->FindConnectionPoint(DIID_DWebBrowserEvents, &pCP))) {
|
|
pCP->Advise((IDispatch*)m_pIDispatch, &m_dwEventCookie);
|
|
pCP->Release();
|
|
}
|
|
|
|
pCPC->Release();
|
|
}
|
|
}
|
|
|
|
// Let's get an interface pointer to IOleCommandTarget
|
|
|
|
hr = m_pOleObject->QueryInterface(IID_IOleCommandTarget, (void **)&m_pIE3CmdTarget);
|
|
if (FAILED(hr))
|
|
m_pIE3CmdTarget = NULL;
|
|
|
|
// Show the control.
|
|
m_pOleObject->DoVerb(OLEIVERB_SHOW, NULL, m_pIOleClientSite, -1, m_hWnd, lpRect);
|
|
uRet = S_OK;
|
|
}
|
|
|
|
|
|
pObj->Release(); // always release this ?
|
|
|
|
|
|
if (uRet != S_OK) {
|
|
m_pIStorage->Release();
|
|
m_pIOleClientSite->Release();
|
|
return uRet;
|
|
}
|
|
|
|
return uRet;
|
|
}
|
|
|
|
//
|
|
// Called when the window containing IE is losing activation (focus).
|
|
//
|
|
void CContainer::UIDeactivateIE()
|
|
{
|
|
IOleInPlaceObject* pIOleInPlaceObject;
|
|
HRESULT hr;
|
|
|
|
if ( SUCCEEDED((hr = m_pOleObject->QueryInterface(IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject))) )
|
|
{
|
|
pIOleInPlaceObject->UIDeactivate();
|
|
pIOleInPlaceObject->Release();
|
|
}
|
|
}
|
|
|
|
void CContainer::SetFocus(BOOL bForceActivation)
|
|
{
|
|
HWND hwnd_child;
|
|
TCHAR szClassName[150];
|
|
|
|
if (! m_pInPlaceActive || bForceActivation )
|
|
m_pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_pIOleClientSite, -1, m_hWnd, NULL);
|
|
|
|
m_hwndChild = m_hWnd;
|
|
while ((hwnd_child = GetWindow(m_hwndChild, GW_CHILD)) && IsWindowEnabled(hwnd_child) )
|
|
{
|
|
m_hwndChild = hwnd_child;
|
|
GetClassName(hwnd_child, szClassName, sizeof(szClassName));
|
|
if ( strstr(szClassName, "Internet Explorer") )
|
|
break;
|
|
}
|
|
if ( hwnd_child && !IsWindowEnabled(hwnd_child) )
|
|
m_hwndChild = GetParent(m_hwndChild);
|
|
|
|
::SetFocus(m_hwndChild);
|
|
}
|
|
|
|
//
|
|
// This needs to be called from the apps message pump to give shdocvw a crack at accelerators
|
|
// it implements. For example ^C for copy selected text.
|
|
//
|
|
// This function will return TRUE if shdocvw traslated the message and FALSE if it did not.
|
|
// Note that you can run into trouble if the app and shdocvw share acclerators. We'll want to
|
|
// always call TranslateAccelartor() from the message pump for the apps accelators and only if
|
|
// it returns false will we call this function to give IE a crack at the message.
|
|
//
|
|
// mikecole
|
|
//
|
|
unsigned CContainer::TranslateMessage(MSG * pMsg)
|
|
{
|
|
if (m_pInPlaceActive)
|
|
{
|
|
if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1 )
|
|
return TAMSG_NOT_IE_ACCEL;
|
|
|
|
if (pMsg->message == WM_KEYDOWN)
|
|
{
|
|
if (GetKeyState(VK_CONTROL))
|
|
{
|
|
if (pMsg->wParam == 0x4F ||
|
|
pMsg->wParam == 0x4C ||
|
|
pMsg->wParam == 0x4E)
|
|
return TAMSG_NOT_IE_ACCEL;
|
|
}
|
|
}
|
|
|
|
|
|
if (m_pInPlaceActive->TranslateAccelerator(pMsg) == S_OK)
|
|
return TAMSG_IE_ACCEL;
|
|
else
|
|
{
|
|
if ( (pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) )
|
|
{
|
|
if ( IsUIActive() && !m_bIE4)
|
|
{ // translateAccelerator does not work for the tab key in IE3,
|
|
// so forward the VK_TAB key message to IE3
|
|
ForwardMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
|
|
return TAMSG_IE_ACCEL;
|
|
}
|
|
UIDeactivateIE();
|
|
SetFocus();
|
|
}
|
|
}
|
|
}
|
|
return TAMSG_NOT_IE_ACCEL;
|
|
}
|
|
|
|
LRESULT CContainer::ForwardMessage(UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hwnd_child;
|
|
HWND hwnd = m_hWnd;
|
|
|
|
while ( (hwnd_child = GetWindow(hwnd, GW_CHILD)) && IsWindowEnabled(hwnd_child) )
|
|
hwnd = hwnd_child;
|
|
|
|
if ( hwnd_child && !IsWindowEnabled(hwnd_child) )
|
|
hwnd = GetParent(hwnd);
|
|
|
|
if (hwnd)
|
|
return ::SendMessage(hwnd, msg, wParam, lParam);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void CContainer::SizeIt(int width, int height)
|
|
{
|
|
IOleInPlaceObject* pIOleInPlaceObject;
|
|
|
|
if ( m_bIE4 )
|
|
{
|
|
if ( SUCCEEDED((m_pOleObject->QueryInterface(IID_IOleInPlaceObject, (void**)&pIOleInPlaceObject))) )
|
|
{
|
|
RECT rc;
|
|
rc.left = rc.top = 0;
|
|
rc.bottom = height;
|
|
rc.right = width;
|
|
pIOleInPlaceObject->SetObjectRects(&rc,&rc);
|
|
pIOleInPlaceObject->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SIZEL sizel;
|
|
sizel.cx = width;
|
|
sizel.cy = height;
|
|
|
|
HDC hdc = GetDC(NULL);
|
|
SetMapMode(hdc, MM_HIMETRIC);
|
|
DPtoLP(hdc, (LPPOINT) &sizel, 1);
|
|
ReleaseDC(NULL, hdc);
|
|
sizel.cy = abs(sizel.cy);
|
|
|
|
m_pOleObject->SetExtent(DVASPECT_CONTENT, &sizel);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************************
|
|
|
|
* AdviseSink code
|
|
*
|
|
*
|
|
* CIAdviseSink implementation begins here!
|
|
*
|
|
**************************************************************************************/
|
|
|
|
/*
|
|
* CIAdviseSink::CIAdviseSink
|
|
* CIAdviseSink::~CIAdviseSink
|
|
*
|
|
* Parameters (Constructor):
|
|
* pCContainer pCContainer of the Container we're in.
|
|
* pUnkOuter LPUNKNOWN to which we delegate.
|
|
*/
|
|
CIAdviseSink::CIAdviseSink(PCONTAINER pCContainer)
|
|
{
|
|
m_cRef=0;
|
|
m_pUnkOuter = m_pContainer = pCContainer;
|
|
return;
|
|
}
|
|
|
|
CIAdviseSink::~CIAdviseSink(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::QueryInterface
|
|
* CIAdviseSink::AddRef
|
|
* CIAdviseSink::Release
|
|
*
|
|
* Purpose:
|
|
* IUnknown members for CIAdviseSink object.
|
|
*/
|
|
STDMETHODIMP CIAdviseSink::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
return m_pUnkOuter->QueryInterface(riid, ppv);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIAdviseSink::AddRef(void)
|
|
{
|
|
m_pUnkOuter->AddRef();
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIAdviseSink::Release(void)
|
|
{
|
|
ULONG ul = --m_cRef;
|
|
|
|
m_pUnkOuter->Release();
|
|
if (ul <= 0)
|
|
delete this;
|
|
|
|
return ul;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::OnDataChange
|
|
*
|
|
* Unused since we don't IDataObject::Advise.
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnDataChange(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::OnViewChange
|
|
*
|
|
* Purpose:
|
|
* Notifes the advise sink that presentation data changed in the
|
|
* data object to which we're connected providing the right time
|
|
* to update displays using such presentations.
|
|
*
|
|
* Parameters:
|
|
* dwAspect DWORD indicating which aspect has changed.
|
|
* lindex LONG indicating the piece that changed.
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnViewChange(DWORD dwAspect, LONG lindex)
|
|
{
|
|
//Repaint only if this is the right aspect
|
|
//m_pContainer->Repaint();
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::OnRename
|
|
*
|
|
* Purpose:
|
|
* Informs the advise sink that a linked object has been renamed.
|
|
* Generally only the OLE default handler cares about this.
|
|
*
|
|
* Parameters:
|
|
* pmk LPMONIKER providing the new name of the object
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnRename(LPMONIKER pmk)
|
|
{
|
|
/*
|
|
* As a container this is unimportant to us since it really
|
|
* tells the handler's implementation of IOleLink that the
|
|
* object's moniker has changed. Since we get this call
|
|
* from the handler, we don't have to do anything ourselves.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::OnSave
|
|
*
|
|
* Purpose:
|
|
* Informs the advise sink that the OLE object has been saved
|
|
* persistently. The primary purpose of this is for containers
|
|
* that want to make optimizations for objects that are not in a
|
|
* saved state, so on this you have to disable such optimizations.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnSave(void)
|
|
{
|
|
/*
|
|
* A Container has nothing to do here as this notification is
|
|
* only useful when we have an ADVFCACHE_ONSAVE advise set up,
|
|
* which we don't. So we ignore it.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink::OnClose
|
|
*
|
|
* Purpose:
|
|
* Informs the advise sink that the OLE object has closed and is
|
|
* no longer bound in any way.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnClose(void)
|
|
{
|
|
/*
|
|
* This doesn't have anything to do with us again as it's only
|
|
* used to notify the handler's IOleLink implementation of the
|
|
* change in the object. We don't have to do anything since
|
|
* we'll also get an IOleClientSite::OnShowWindow(FALSE) to
|
|
* tell us to repaint.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIAdviseSink2::OnLinkSrcChange
|
|
*
|
|
* Purpose:
|
|
* Informs the advise sink that a linked compound document object
|
|
* has changed its link source to the object identified by the
|
|
* given moniker. This is generally only of interest to the OLE
|
|
* default handler's implementation of linked objects.
|
|
*
|
|
* Parameters:
|
|
* pmk LPMONIKER specifying the new link source.
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
STDMETHODIMP_(void) CIAdviseSink::OnLinkSrcChange(LPMONIKER pmk)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
*
|
|
* ClientSite code
|
|
*
|
|
*
|
|
* CIOleClientSite implementation begins here!
|
|
*
|
|
**************************************************************************************/
|
|
|
|
/*
|
|
* CIOleClientSite::CIOleClientSite
|
|
* CIOleClientSite::~CIOleClientSite
|
|
*
|
|
* Parameters (Constructor):
|
|
* pCContainer PCContainer of the container we're in.
|
|
* pUnkOuter LPUNKNOWN to which we delegate.
|
|
*/
|
|
CIOleClientSite::CIOleClientSite(PCONTAINER pCContainer)
|
|
{
|
|
m_cRef=0;
|
|
m_pUnkOuter = m_pContainer = pCContainer;
|
|
return;
|
|
}
|
|
|
|
CIOleClientSite::~CIOleClientSite(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::QueryInterface
|
|
* CIOleClientSite::AddRef
|
|
* CIOleClientSite::Release
|
|
*
|
|
* Purpose:
|
|
* IUnknown members for CIOleClientSite object.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
return m_pUnkOuter->QueryInterface(riid, ppv);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CIOleClientSite::AddRef(void)
|
|
{
|
|
m_pUnkOuter->AddRef();
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleClientSite::Release(void)
|
|
{
|
|
ULONG ul = --m_cRef;
|
|
|
|
m_pUnkOuter->Release();
|
|
if (ul <= 0)
|
|
delete this;
|
|
|
|
return ul;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::SaveObject
|
|
*
|
|
* Purpose:
|
|
* Requests that the container call OleSave for the object that
|
|
* lives here. Typically this happens on server shutdown.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::SaveObject(void)
|
|
{
|
|
// We're already set up with the tenant to save; this is trivial.
|
|
//pCContainer->Update();
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::GetMoniker
|
|
*
|
|
* Purpose:
|
|
* Retrieves the moniker for the site in which this object lives,
|
|
* either the moniker relative to the container or the full
|
|
* moniker.
|
|
*
|
|
* Parameters:
|
|
* dwAssign DWORD specifying that the object wants moniker
|
|
* assignment. Yeah. Right. Got any bridges to
|
|
* sell?
|
|
* dwWhich DWORD identifying which moniker the object
|
|
* wants, either the container's moniker, the
|
|
* moniker relative to this client site, or the
|
|
* full moniker.
|
|
*
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::GetMoniker(DWORD dwAssign, DWORD dwWhich, LPMONIKER *ppmk)
|
|
{
|
|
*ppmk=NULL;
|
|
|
|
switch (dwWhich)
|
|
{
|
|
case OLEWHICHMK_CONTAINER:
|
|
//This is just the file we're living in.
|
|
break;
|
|
|
|
case OLEWHICHMK_OBJREL:
|
|
//This is everything but the filename.
|
|
break;
|
|
|
|
case OLEWHICHMK_OBJFULL:
|
|
//Concatenate file and relative monikers for this one.
|
|
break;
|
|
}
|
|
|
|
if (NULL==*ppmk)
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
(*ppmk)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::GetContainer
|
|
*
|
|
* Purpose:
|
|
* Returns a pointer to the document's IOleContainer interface.
|
|
*
|
|
* Parameters:
|
|
* ppContainer LPOLECONTAINER * in which to return the
|
|
* interface.
|
|
*
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::GetContainer(LPOLECONTAINER* ppContainer)
|
|
{
|
|
if (m_pContainer)
|
|
return m_pContainer->QueryInterface(IID_IOleItemContainer, (LPVOID *)ppContainer);
|
|
|
|
return ResultFromScode(E_FAIL);
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::ShowObject
|
|
*
|
|
* Purpose:
|
|
* Tells the container to bring the object fully into view as much
|
|
* as possible, that is, scroll the document.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::ShowObject(void)
|
|
{
|
|
// deligate back to CContainer
|
|
// m_pContainer->ShowObject();
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::OnShowWindow
|
|
*
|
|
* Purpose:
|
|
* Informs the container if the object is showing itself or
|
|
* hiding itself. This is done only in the opening mode and allows
|
|
* the container to know when to shade or unshade the object.
|
|
*
|
|
* Parameters:
|
|
* fShow BOOL indiciating that the object is being shown
|
|
* (TRUE) or hidden (FALSE).
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::OnShowWindow(BOOL fShow)
|
|
{
|
|
// deligate back to CContainer
|
|
// m_pContainer->OnShowWindow(fShow);
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleClientSite::RequestNewObjectLayout
|
|
*
|
|
* Purpose:
|
|
* Called when the object would like to have its layout
|
|
* reinitialized. This is used by OLE Controls.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT Standard.
|
|
*/
|
|
STDMETHODIMP CIOleClientSite::RequestNewObjectLayout(void)
|
|
{
|
|
// deligate back to CContainer
|
|
// m_pContainer->RequestNewObjectLayout();
|
|
return NOERROR;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
*
|
|
* InPlaceSite code
|
|
*
|
|
*
|
|
* CIOleInPlaceSite implementation begins here!
|
|
*
|
|
**************************************************************************************/
|
|
|
|
/*
|
|
* CIOleInPlaceSite::CIOleInPlaceSite
|
|
* CIOleInPlaceSite::~CIOleInPlaceSite
|
|
*
|
|
* Parameters (Constructor):
|
|
* pCContainer Pointer to the container we're in.
|
|
* pUnkOuter LPUNKNOWN to which we delegate.
|
|
*/
|
|
CIOleInPlaceSite::CIOleInPlaceSite(PCONTAINER pCContainer)
|
|
{
|
|
m_cRef=0;
|
|
m_pUnkOuter = m_pContainer = pCContainer;
|
|
return;
|
|
}
|
|
|
|
CIOleInPlaceSite::~CIOleInPlaceSite(void)
|
|
{
|
|
ASSERT(m_cRef == 0);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::QueryInterface
|
|
* CIOleInPlaceSite::AddRef
|
|
* CIOleInPlaceSite::Release
|
|
*
|
|
* Purpose:
|
|
* IUnknown members for CIOleInPlaceSite object.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
return m_pUnkOuter->QueryInterface(riid, ppv);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CIOleInPlaceSite::AddRef(void)
|
|
{
|
|
m_pUnkOuter->AddRef();
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleInPlaceSite::Release(void)
|
|
{
|
|
ULONG ul = --m_cRef;
|
|
|
|
m_pUnkOuter->Release();
|
|
if (ul <= 0)
|
|
delete this;
|
|
|
|
return ul;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceActiveObject::GetWindow
|
|
*
|
|
* Purpose:
|
|
* Retrieves the handle of the window associated with the object
|
|
* on which this interface is implemented.
|
|
*
|
|
* Parameters:
|
|
* phWnd HWND * in which to store the window handle.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if successful, E_FAIL if there is no
|
|
* window.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::GetWindow(HWND *phWnd)
|
|
{
|
|
*phWnd = m_pContainer->m_hWnd;
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceActiveObject::ContextSensitiveHelp
|
|
*
|
|
* Purpose:
|
|
* Instructs the object on which this interface is implemented to
|
|
* enter or leave a context-sensitive help mode.
|
|
*
|
|
* Parameters:
|
|
* fEnterMode BOOL TRUE to enter the mode, FALSE otherwise.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::CanInPlaceActivate
|
|
*
|
|
* Purpose:
|
|
* Answers the server whether or not we can currently in-place
|
|
* activate its object. By implementing this interface we say
|
|
* that we support in-place activation, but through this function
|
|
* we indicate whether the object can currently be activated
|
|
* in-place. Iconic aspects, for example, cannot, meaning we
|
|
* return S_FALSE.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if we can in-place activate the object
|
|
* in this site, S_FALSE if not.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::CanInPlaceActivate(void)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::OnInPlaceActivate
|
|
*
|
|
* Purpose:
|
|
* Informs the container that an object is being activated in-place
|
|
* such that the container can prepare appropriately. The
|
|
* container does not, however, make any user interface changes at
|
|
* this point. See OnUIActivate.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::OnInPlaceActivate(void)
|
|
{
|
|
|
|
// BUGBUG: Mikecole - Does this belong here ?
|
|
|
|
//if (FAILED(m_pOleObject->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&m_pInPlaceActive)))
|
|
// m_pInPlaceActive = 0;
|
|
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::OnInPlaceDeactivate
|
|
*
|
|
* Purpose:
|
|
* Notifies the container that the object has deactivated itself
|
|
* from an in-place state. Opposite of OnInPlaceActivate. The
|
|
* container does not change any UI at this point.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::OnInPlaceDeactivate(void)
|
|
{
|
|
|
|
// BUGBUG: Mikecole - Does this belong here ?
|
|
|
|
//if (FAILED(m_pOleObject->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&m_pInPlaceActive)))
|
|
// m_pInPlaceActive = 0;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::OnUIActivate
|
|
*
|
|
* Purpose:
|
|
* Informs the container that the object is going to start munging
|
|
* around with user interface, like replacing the menu. The
|
|
* container should remove any relevant UI in preparation.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::OnUIActivate(void)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::OnUIDeactivate
|
|
*
|
|
* Purpose:
|
|
* Informs the container that the object is deactivating its
|
|
* in-place user interface at which time the container may
|
|
* reinstate its own. Opposite of OnUIActivate.
|
|
*
|
|
* Parameters:
|
|
* fUndoable BOOL indicating if the object will actually
|
|
* perform an Undo if the container calls
|
|
* ReactivateAndUndo.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::OnUIDeactivate(BOOL fUndoable)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::DeactivateAndUndo
|
|
*
|
|
* Purpose:
|
|
* If immediately after activation the object does an Undo, the
|
|
* action being undone is the activation itself, and this call
|
|
* informs the container that this is, in fact, what happened.
|
|
* The container should call IOleInPlaceObject::UIDeactivate.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::DeactivateAndUndo(void)
|
|
{
|
|
//CONTROLMOD
|
|
/*
|
|
* Note that we don't pay attention to the locking
|
|
* from IOleControlSite::LockInPlaceActive since only
|
|
* the object calls this function and should know
|
|
* that it's going to be deactivated.
|
|
*/
|
|
//End CONTROLMOD
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::DiscardUndoState
|
|
*
|
|
* Purpose:
|
|
* Informs the container that something happened in the object
|
|
* that means the container should discard any undo information
|
|
* it currently maintains for the object.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or an appropriate error code.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::DiscardUndoState(void)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::GetWindowContext
|
|
*
|
|
* Purpose:
|
|
* Provides an in-place object with pointers to the frame and
|
|
* document level in-place interfaces (IOleInPlaceFrame and
|
|
* IOleInPlaceUIWindow) such that the object can do border
|
|
* negotiation and so forth. Also requests the position and
|
|
* clipping rectangles of the object in the container and a
|
|
* pointer to an OLEINPLACEFRAME info structure which contains
|
|
* accelerator information.
|
|
*
|
|
* Note that the two interfaces this call returns are not
|
|
* available through QueryInterface on IOleInPlaceSite since they
|
|
* live with the frame and document, but not the site.
|
|
*
|
|
* Parameters:
|
|
* ppIIPFrame LPOLEINPLACEFRAME * in which to return the
|
|
* AddRef'd pointer to the container's
|
|
* IOleInPlaceFrame.
|
|
* ppIIPUIWindow LPOLEINPLACEUIWINDOW * in which to return
|
|
* the AddRef'd pointer to the container document's
|
|
* IOleInPlaceUIWindow.
|
|
* prcPos LPRECT in which to store the object's position.
|
|
* prcClip LPRECT in which to store the object's visible
|
|
* region.
|
|
* pFI LPOLEINPLACEFRAMEINFO to fill with accelerator
|
|
* stuff.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::GetWindowContext(LPOLEINPLACEFRAME FAR* lplpFrame,
|
|
LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPRECT lprcPosRect,
|
|
LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
|
{
|
|
RECT rect;
|
|
|
|
// the frame is associated with the application object.
|
|
// need to AddRef() it...
|
|
|
|
m_pContainer->m_pIOleInPlaceFrame->AddRef();
|
|
*lplpFrame = m_pContainer->m_pIOleInPlaceFrame;
|
|
*lplpDoc = NULL; // must be NULL, cause we're SDI.
|
|
|
|
// get the size of the object in pixels
|
|
::GetClientRect(m_pContainer->m_hWnd, &rect); // This may be bogus!
|
|
|
|
// Copy this to the passed buffer
|
|
CopyRect(lprcPosRect, &rect);
|
|
|
|
// fill the clipping region
|
|
CopyRect(lprcClipRect, &rect);
|
|
|
|
// fill the FRAMEINFO
|
|
lpFrameInfo->fMDIApp = FALSE;
|
|
lpFrameInfo->hwndFrame = m_pContainer->m_hWnd;
|
|
lpFrameInfo->haccel = NULL;
|
|
lpFrameInfo->cAccelEntries = 0;
|
|
|
|
return ResultFromScode(S_OK);
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::Scroll
|
|
*
|
|
* Purpose:
|
|
* Asks the container to scroll the document, and thus the object,
|
|
* by the given amounts in the sz parameter.
|
|
*
|
|
* Parameters:
|
|
* sz SIZE containing signed horizontal and vertical
|
|
* extents by which the container should scroll.
|
|
* These are in device units.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
|
|
STDMETHODIMP CIOleInPlaceSite::Scroll(SIZE sz)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceSite::OnPosRectChange
|
|
*
|
|
* Purpose:
|
|
* Informs the container that the in-place object was resized.
|
|
* The container must call IOleInPlaceObject::SetObjectRects.
|
|
* This does not change the site's rectangle in any case.
|
|
*
|
|
* Parameters:
|
|
* prcPos LPCRECT containing the new size of the object.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceSite::OnPosRectChange(LPCRECT prcPos)
|
|
{
|
|
// m_pContainer->UpdateInPlaceObjectRects(prcPos, FALSE);
|
|
return NOERROR;
|
|
}
|
|
|
|
/**************************************************************************************
|
|
*
|
|
* InPlaceFrame code
|
|
*
|
|
*
|
|
* CIOleInPlaceFrame implementation begins here!
|
|
*
|
|
**************************************************************************************/
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::CIOleInPlaceFrame
|
|
* CIOleInPlaceFrame::~CIOleInPlaceFrame
|
|
*
|
|
* Parameters (Constructor):
|
|
* pTen PCTenant of the tenant we're in.
|
|
* pUnkOuter LPUNKNOWN to which we delegate.
|
|
*/
|
|
CIOleInPlaceFrame::CIOleInPlaceFrame(PCONTAINER pCContainer)
|
|
{
|
|
m_cRef=0;
|
|
m_pUnkOuter = m_pContainer = pCContainer;
|
|
return;
|
|
}
|
|
|
|
CIOleInPlaceFrame::~CIOleInPlaceFrame(void)
|
|
{
|
|
ASSERT(m_cRef == 0);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::QueryInterface
|
|
* CIOleInPlaceFrame::AddRef
|
|
* CIOleInPlaceFrame::Release
|
|
*
|
|
* Purpose:
|
|
* IUnknown members for CIOleInPlaceFrame object.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
//We only know IUnknown and IOleInPlaceFrame
|
|
*ppv=NULL;
|
|
|
|
//Remember to do ALL base interfaces
|
|
if ( IID_IUnknown == riid ||
|
|
IID_IOleInPlaceUIWindow == riid ||
|
|
IID_IOleWindow == riid ||
|
|
IID_IOleInPlaceFrame == riid )
|
|
*ppv=(LPOLEINPLACEFRAME)this;
|
|
|
|
if (NULL!=*ppv)
|
|
{
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CIOleInPlaceFrame::AddRef(void)
|
|
{
|
|
m_pUnkOuter->AddRef();
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleInPlaceFrame::Release(void)
|
|
{
|
|
ULONG ul = --m_cRef;
|
|
|
|
m_pUnkOuter->Release();
|
|
if (ul <= 0)
|
|
delete this;
|
|
|
|
return ul;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::GetWindow
|
|
*
|
|
* Purpose:
|
|
* Retrieves the handle of the window associated with the object
|
|
* on which this interface is implemented.
|
|
*
|
|
* Parameters:
|
|
* phWnd HWND * in which to store the window handle.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if successful, E_FAIL if there is no
|
|
* window.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::GetWindow(HWND *phWnd)
|
|
{
|
|
*phWnd = m_pContainer->m_hWnd;
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::ContextSensitiveHelp
|
|
*
|
|
* Purpose:
|
|
* Instructs the object on which this interface is implemented to
|
|
* enter or leave a context-sensitive help mode.
|
|
*
|
|
* Parameters:
|
|
* fEnterMode BOOL TRUE to enter the mode, FALSE otherwise.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
|
|
// If we had an embedded control with menus, this would get called on an
|
|
// f1 keypress with a menu pulled down.
|
|
//
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::GetBorder
|
|
*
|
|
* Purpose:
|
|
* Returns the rectangle in which the container is willing to
|
|
* negotiate about an object's adornments.
|
|
*
|
|
* Parameters:
|
|
* prcBorder LPRECT in which to store the rectangle.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if all is well, INPLACE_E_NOTOOLSPACE
|
|
* if there is no negotiable space.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::GetBorder(LPRECT prcBorder)
|
|
{
|
|
if (NULL==prcBorder)
|
|
return ResultFromScode(E_INVALIDARG);
|
|
/*
|
|
* We return all the client area space sans the StatStrip,
|
|
* which we control
|
|
*/
|
|
GetClientRect(m_pContainer->m_hWnd, prcBorder);
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::RequestBorderSpace
|
|
*
|
|
* Purpose:
|
|
* Asks the container if it can surrender the amount of space
|
|
* in pBW that the object would like for it's adornments. The
|
|
* container does nothing but validate the spaces on this call.
|
|
*
|
|
* Parameters:
|
|
* pBW LPCBORDERWIDTHS containing the requested space.
|
|
* The values are the amount of space requested
|
|
* from each side of the relevant window.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if we can give up space,
|
|
* INPLACE_E_NOTOOLSPACE otherwise.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::RequestBorderSpace(LPCBORDERWIDTHS pBW)
|
|
{
|
|
//Everything is fine with us, so always return an OK.
|
|
|
|
// mikecole/douglash Should either return inplace_e_notoolspace or we should honor the
|
|
// request for border space below in setborderspace().
|
|
|
|
return INPLACE_E_NOTOOLSPACE;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::SetBorderSpace
|
|
*
|
|
* Purpose:
|
|
* Called when the object now officially requests that the
|
|
* container surrender border space it previously allowed
|
|
* in RequestBorderSpace. The container should resize windows
|
|
* appropriately to surrender this space.
|
|
*
|
|
* Parameters:
|
|
* pBW LPCBORDERWIDTHS containing the amount of space
|
|
* from each side of the relevant window that the
|
|
* object is now reserving.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::SetBorderSpace(LPCBORDERWIDTHS pBW)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::InsertMenus
|
|
*
|
|
* Purpose:
|
|
* Instructs the container to place its in-place menu items where
|
|
* necessary in the given menu and to fill in elements 0, 2, and 4
|
|
* of the OLEMENUGROUPWIDTHS array to indicate how many top-level
|
|
* items are in each group.
|
|
*
|
|
* Parameters:
|
|
* hMenu HMENU in which to add popups.
|
|
* pMGW LPOLEMENUGROUPWIDTHS in which to store the
|
|
* width of each container menu group.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::InsertMenus(HMENU hMenu, LPOLEMENUGROUPWIDTHS pMGW)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::SetMenu
|
|
*
|
|
* Purpose:
|
|
* Instructs the container to replace whatever menu it's currently
|
|
* using with the given menu and to call OleSetMenuDescritor so OLE
|
|
* knows to whom to dispatch messages.
|
|
*
|
|
* Parameters:
|
|
* hMenu HMENU to show.
|
|
* hOLEMenu HOLEMENU to the menu descriptor.
|
|
* hWndObj HWND of the active object to which messages are
|
|
* dispatched.
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::SetMenu(HMENU hMenu, HOLEMENU hOLEMenu, HWND hWndObj)
|
|
{
|
|
/*
|
|
* Our responsibilities here are to put the menu on the frame
|
|
* window and call OleSetMenuDescriptor.
|
|
* CPatronClient::SetMenu which we call here takes care of
|
|
* MDI/SDI differences.
|
|
*
|
|
* We also want to save the object's hWnd for use in WM_SETFOCUS
|
|
* processing.
|
|
*/
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::RemoveMenus
|
|
*
|
|
* Purpose:
|
|
* Asks the container to remove any menus it put into hMenu in
|
|
* InsertMenus.
|
|
*
|
|
* Parameters:
|
|
* hMenu HMENU from which to remove the container's
|
|
* items.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::RemoveMenus(HMENU hMenu)
|
|
{
|
|
/*
|
|
* To be defensive, loop through this menu removing anything
|
|
* we recognize (that is, anything in m_phMenu) just in case
|
|
* the server didn't clean it up right. At least we can
|
|
* give ourselves the prophylactic benefit.
|
|
*/
|
|
|
|
/*
|
|
* Walk backwards down the menu. For each popup, see if it
|
|
* matches any other popup we know about, and if so, remove
|
|
* it from the shared menu.
|
|
*/
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::SetStatusText
|
|
*
|
|
* Purpose:
|
|
* Asks the container to place some text in a status line, if one
|
|
* exists. If the container does not have a status line it
|
|
* should return E_FAIL here in which case the object could
|
|
* display its own.
|
|
*
|
|
* Parameters:
|
|
* pszText LPCTSTR to display.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if successful, S_TRUNCATED if not all
|
|
* of the text could be displayed, or E_FAIL if
|
|
* the container has no status line.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::SetStatusText(LPCOLESTR pszText)
|
|
{
|
|
/*
|
|
* Just send this to the StatStrip. Unfortunately it won't tell
|
|
* us about truncation. Oh well, we'll just act like it worked.
|
|
*/
|
|
if (pszText) {
|
|
#if 0
|
|
char buf[256];
|
|
25-Sep-1997 [ralphw] Can't find SetPrompt in IV source code
|
|
if (ConvertWz(pszText, buf, sizeof(buf))) {
|
|
if (*pszText)
|
|
SetPrompt(buf, TRUE);
|
|
else
|
|
SetPrompt();
|
|
}
|
|
#endif
|
|
}
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::EnableModeless
|
|
*
|
|
* Purpose:
|
|
* Instructs the container to show or hide any modeless popup
|
|
* windows that it may be using.
|
|
*
|
|
* Parameters:
|
|
* fEnable BOOL indicating to enable/show the windows
|
|
* (TRUE) or to hide them (FALSE).
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::EnableModeless(BOOL fEnable)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleInPlaceFrame::TranslateAccelerator
|
|
*
|
|
* Purpose:
|
|
* When dealing with an in-place object from an EXE server, this
|
|
* is called to give the container a chance to process accelerators
|
|
* after the server has looked at the message.
|
|
*
|
|
* Parameters:
|
|
* pMSG LPMSG for the container to examine.
|
|
* wID WORD the identifier in the container's
|
|
* accelerator table (from IOleInPlaceSite
|
|
* ::GetWindowContext) for this message (OLE does
|
|
* some translation before calling).
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR if the keystroke was used,
|
|
* S_FALSE otherwise.
|
|
*/
|
|
STDMETHODIMP CIOleInPlaceFrame::TranslateAccelerator(LPMSG pMSG, WORD wID)
|
|
{
|
|
/*
|
|
* wID already has anything translated from m_hAccelIP for us,
|
|
* so we can just check for the commands we want and process
|
|
* them instead of calling TranslateAccelerator which would be
|
|
* redundant and which also has a possibility of dispatching to
|
|
* the wrong window.
|
|
*/
|
|
|
|
// if (pMSG->message == WM_KEYDOWN && pMSG->wParam == VK_ESCAPE)
|
|
// PostMessage(CUR_HWND, WM_CLOSE, 0, 0);
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* COleInPlaceFrame::SetActiveObject
|
|
*
|
|
* Purpose:
|
|
*
|
|
*
|
|
* Parameters:
|
|
*
|
|
* LPOLEINPLACEACTIVEOBJECT lpActiveObject - Pointer to the
|
|
* objects
|
|
* IOleInPlaceActiveObject
|
|
* interface
|
|
*
|
|
* @@WTK WIN32, UNICODE
|
|
* //LPCSTR lpszObjName - Name of the object
|
|
* LPCOLESTR lpszObjName - Name of the object
|
|
*
|
|
* Return Value:
|
|
*
|
|
* S_OK
|
|
*
|
|
* Function Calls:
|
|
* Function Location
|
|
*
|
|
* OutputDebugString Windows API
|
|
* IOleInPlaceActiveObject::AddRef Object
|
|
* IOleInPlaceActiveObject::Release Object
|
|
* ResultFromScode OLE API
|
|
*
|
|
* Comments:
|
|
*
|
|
********************************************************************/
|
|
STDMETHODIMP CIOleInPlaceFrame::SetActiveObject(LPOLEINPLACEACTIVEOBJECT lpActiveObject,
|
|
LPCOLESTR lpszObjName)
|
|
{
|
|
// in an MDI app, this method really shouldn't be called,
|
|
// this method associated with the doc is called instead.
|
|
// should set window title here
|
|
|
|
if ( m_pContainer->m_pInPlaceActive )
|
|
m_pContainer->m_pInPlaceActive->Release();
|
|
|
|
if (lpActiveObject)
|
|
lpActiveObject->AddRef();
|
|
|
|
m_pContainer->m_pInPlaceActive = lpActiveObject;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* CIOleControlSite Implementation starts here.
|
|
*
|
|
*
|
|
|
|
/*
|
|
* CIOleControlSite::CIOleControlSite
|
|
* CIOleControlSite::~CIOleControlSite
|
|
*
|
|
* Parameters (Constructor):
|
|
* pTen PCTenant of the object we're in.
|
|
* pUnkOuter LPUNKNOWN to which we delegate.
|
|
*/
|
|
CIOleControlSite::CIOleControlSite(PCONTAINER pCContainer)
|
|
{
|
|
m_cRef=0;
|
|
m_pUnkOuter = m_pContainer = pCContainer;
|
|
return;
|
|
}
|
|
|
|
CIOleControlSite::~CIOleControlSite(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::QueryInterface
|
|
* CIOleControlSite::AddRef
|
|
* CIOleControlSite::Release
|
|
*
|
|
* Purpose:
|
|
* Delegating IUnknown members for CIOleControlSite.
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
return m_pUnkOuter->QueryInterface(riid, ppv);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CIOleControlSite::AddRef(void)
|
|
{
|
|
++m_cRef;
|
|
return m_pUnkOuter->AddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleControlSite::Release(void)
|
|
{
|
|
--m_cRef;
|
|
return m_pUnkOuter->Release();
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::OnControlInfoChanged
|
|
*
|
|
* Purpose:
|
|
* Informs the site that the CONTROLINFO for the control has
|
|
* changed and we thus need to reload the data.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::OnControlInfoChanged(void)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::LockInPlaceActive
|
|
*
|
|
* Purpose:
|
|
* Forces the container to keep this control in-place active
|
|
* (but not UI active) regardless of other considerations, or
|
|
* removes this lock.
|
|
*
|
|
* Parameters:
|
|
* fLock BOOL indicating to lock (TRUE) or unlock (FALSE)
|
|
* in-place activation.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::LockInPlaceActive(BOOL fLock)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::GetExtendedControl
|
|
*
|
|
* Purpose:
|
|
* Returns a pointer to the container's extended control that wraps
|
|
* the actual control in this site, if one exists.
|
|
*
|
|
* Parameters:
|
|
* ppDispatch LPDISPATCH * in which to return the pointer
|
|
* to the extended control's IDispatch interface.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or a general error value.
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::GetExtendedControl(LPDISPATCH* ppDispatch)
|
|
{
|
|
*ppDispatch=NULL;
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::TransformCoords
|
|
*
|
|
* Purpose:
|
|
* Converts coordinates in HIMETRIC units into those used by the
|
|
* container.
|
|
*
|
|
* Parameters:
|
|
* pptlHiMet POINTL * containing either the coordinates to
|
|
* transform to container or where to store the
|
|
* transformed container coordinates.
|
|
* pptlCont POINTF * containing the container coordinates.
|
|
* dwFlags DWORD containing instructional flags.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or a general error value.
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::TransformCoords(POINTL *pptlHiMet, POINTF *pptlCont, DWORD dwFlags)
|
|
{
|
|
if (NULL==pptlHiMet || NULL==pptlCont)
|
|
return ResultFromScode(E_POINTER);
|
|
|
|
/*
|
|
* Convert coordinates. We use MM_LOMETRIC which means that
|
|
* to convert from HIMETRIC we divide by 10 and negate the y
|
|
* coordinate. Conversion to HIMETRIC means negate the y
|
|
* and multiply by 10. Note that size and position are
|
|
* considered the same thing, that is, we don't differentiate
|
|
* the two.
|
|
*/
|
|
|
|
if (XFORMCOORDS_HIMETRICTOCONTAINER & dwFlags)
|
|
{
|
|
pptlCont->x=(float)(pptlHiMet->x/10);
|
|
pptlCont->y=(float)-(pptlHiMet->y/10);
|
|
}
|
|
else
|
|
{
|
|
pptlHiMet->x=(long)(pptlCont->x*10);
|
|
pptlHiMet->y=(long)-(pptlCont->y*10);
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::TranslateAccelerator
|
|
*
|
|
* Purpose:
|
|
* Instructs the container to translate a keyboard accelerator
|
|
* message that the control has picked up instead.
|
|
*
|
|
* Parameters:
|
|
* pMsg LPMSG to the message to translate.
|
|
* grfModifiers DWORD flags with additional instructions.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or a general error value.
|
|
*/
|
|
STDMETHODIMP CIOleControlSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
|
|
{
|
|
#ifdef _DEBUG
|
|
char sz[1000];
|
|
HWND hWnd;
|
|
hWnd = GetFocus();
|
|
wsprintf(sz,"CIOleControlSite::TranslateAccelerator()\nGetFocus == %X\npMsg->hwnd = %X\npMsg->message = %X\npMsg->wParam = %X\npMsg->lParam = %X\npMsg->time = %X\npMsg->pt.x = %X\npMsg->pt.y = %X\n",
|
|
hWnd,pMsg->hwnd,pMsg->message,pMsg->wParam,pMsg->lParam,pMsg->time,pMsg->pt.x,pMsg->pt.y);
|
|
OutputDebugString(sz);
|
|
#endif
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::OnFocus
|
|
*
|
|
* Purpose:
|
|
* Informs the container that focus has either been lost or
|
|
* gained in the control.
|
|
*
|
|
* Parameters:
|
|
* fGotFocus BOOL indicating that the control gained (TRUE)
|
|
* or lost (FALSE) focus.
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or a general error value.
|
|
*/
|
|
|
|
STDMETHODIMP CIOleControlSite::OnFocus(BOOL fGotFocus)
|
|
{
|
|
//We don't handle default buttons, so this is not interesting
|
|
return NOERROR;
|
|
}
|
|
|
|
/*
|
|
* CIOleControlSite::ShowPropertyFrame
|
|
*
|
|
* Purpose:
|
|
* Instructs the container to show the property frame if
|
|
* this is, in fact, an extended object.
|
|
*
|
|
* Parameters:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* HRESULT NOERROR or a general error value.
|
|
*/
|
|
|
|
STDMETHODIMP CIOleControlSite::ShowPropertyFrame(void)
|
|
{
|
|
//We don't do extended objects, so nothing to do here.
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
//#endif // CIOleControlSite
|
|
|
|
/********************************************************************
|
|
*
|
|
* Implementation of IOleItemContainer
|
|
*
|
|
* We don't actually use this interface, but need to return one so
|
|
* the IE control can QI it for IDispatch. Why they don't just QI the
|
|
* site I don't know.
|
|
*/
|
|
|
|
CIOleItemContainer::CIOleItemContainer(IUnknown * pOuter)
|
|
{
|
|
m_cRef = 0;
|
|
m_pOuter = pOuter;
|
|
}
|
|
|
|
// aggregating IUnknown methods
|
|
|
|
STDMETHODIMP CIOleItemContainer::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
*ppv = 0;
|
|
|
|
if (m_pOuter)
|
|
return m_pOuter->QueryInterface(riid,ppv);
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
#if 0
|
|
if (riid == IID_IUnknown || riid == IID_IOleItemContainer
|
|
|| riid == IID_IOleContainer || riid == IID_IParseDisplayName)
|
|
{
|
|
*ppv = (LPVOID)(IDispatch*)this;
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
#endif
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleItemContainer::AddRef(void)
|
|
{
|
|
m_cRef++;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->AddRef();
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CIOleItemContainer::Release(void)
|
|
{
|
|
ULONG c = --m_cRef;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->Release();
|
|
|
|
if (c <= 0)
|
|
delete this;
|
|
|
|
return c;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::ParseDisplayName(IBindCtx *, LPOLESTR,ULONG*,IMoniker**)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::EnumObjects(DWORD,LPENUMUNKNOWN*)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::LockContainer(BOOL)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::GetObject(LPOLESTR,DWORD,IBindCtx*,REFIID,void**)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::GetObjectStorage(LPOLESTR,IBindCtx*,REFIID,void**)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CIOleItemContainer::IsRunning(LPOLESTR)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
int ConvertWz(const WCHAR * pwz, char * psz, int len)
|
|
{
|
|
BOOL fDefault = FALSE;
|
|
return WideCharToMultiByte(CP_ACP, 0, pwz, wcslen(pwz) + 1, psz, len, "*", &fDefault);
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* CDocHostUIHandler
|
|
*
|
|
* IE4 only QI()'s our control site for one of these. Most of these functions are called from
|
|
* IE's IOleInPlaceActiveObject coorisponding members. This gives us a great deal of control
|
|
* over UI compared to what we had with IE3. Using IDocHostUIHandler members me can:
|
|
*
|
|
* Control the right click context menu.
|
|
* Control the window border.
|
|
* Keep seperate registry settings from IE.
|
|
* Handle keyboard accelarators more intelegently.
|
|
*/
|
|
|
|
CDocHostUIHandler::CDocHostUIHandler(IUnknown * pOuter)
|
|
{
|
|
m_cRef = 0;
|
|
m_pOuter = pOuter;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
*ppv = 0;
|
|
|
|
if (m_pOuter)
|
|
return m_pOuter->QueryInterface(riid,ppv);
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDocHostUIHandler::AddRef(void)
|
|
{
|
|
m_cRef++;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->AddRef();
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDocHostUIHandler::Release(void)
|
|
{
|
|
ULONG c = --m_cRef;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->Release();
|
|
|
|
if (c <= 0)
|
|
delete this;
|
|
|
|
return c;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CDocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved)
|
|
{
|
|
|
|
// We cannot define these below since they are already incorrectly defined in include\mshtmlhst.h
|
|
// so we will just use the hard-coded values instead
|
|
//#define CONTEXT_MENU_DEFAULT 0 // typically blank areas in the topic
|
|
//#define CONTEXT_MENU_IMAGE 1 // bitmaps, etc.
|
|
//#define CONTEXT_MENU_CONTROL 2
|
|
//#define CONTEXT_MENU_TABLE 3
|
|
//#define CONTEXT_MENU_DEBUG 4 // seleted text uses this id
|
|
//#define CONTEXT_MENU_1DSELECT 5 // these are links
|
|
//#define CONTEXT_MENU_ANCHOR 6
|
|
//#define CONTEXT_MENU_IMGDYNSRC 7
|
|
|
|
if( dwID == 0 || dwID == 1 || dwID == 5 ) {
|
|
|
|
if( HMENU hMenu = CreatePopupMenu() ) {
|
|
#define IDTB_REBASE 1000
|
|
#define HTMLID_REBASE 2000
|
|
|
|
if( dwID == 0 ) {
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, IDTB_REBASE+IDTB_BACK, GetStringResource(IDS_OPTION_BACK) );
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, IDTB_REBASE+IDTB_FORWARD, GetStringResource(IDS_OPTION_FORWARD) );
|
|
AppendMenu( hMenu, MF_SEPARATOR, -1, NULL );
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, OLECMDID_SELECTALL, GetStringResource(IDS_OPTION_SELECTALL) );
|
|
AppendMenu( hMenu, MF_SEPARATOR, -1, NULL );
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, HTMLID_REBASE+HTMLID_VIEWSOURCE, GetStringResource(IDS_OPTION_VIEWSOURCE) );
|
|
AppendMenu( hMenu, MF_SEPARATOR, -1, NULL );
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, OLECMDID_PRINT, GetStringResource(IDS_OPTION_PRINT) );
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, OLECMDID_REFRESH, GetStringResource(IDS_OPTION_REFRESH) );
|
|
AppendMenu( hMenu, MF_SEPARATOR, -1, NULL );
|
|
}
|
|
|
|
if( dwID == 1 ) {
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, OLECMDID_COPY, GetStringResource(IDS_OPTION_COPY) );
|
|
AppendMenu( hMenu, MF_SEPARATOR, -1, NULL );
|
|
}
|
|
|
|
HxAppendMenu( hMenu, MF_STRING | MF_ENABLED, OLECMDID_PROPERTIES, GetStringResource(IDS_OPTION_PROPERTIES) );
|
|
|
|
VARIANT vaIn;
|
|
VARIANT vaOut;
|
|
::VariantInit(&vaIn);
|
|
::VariantInit(&vaOut);
|
|
|
|
HWND hWndParent = NULL;
|
|
hWndParent = ((CContainer*) m_pOuter)->m_hwndChild;
|
|
if( !IsValidWindow(hWndParent) )
|
|
hWndParent = GetActiveWindow();
|
|
if( !hWndParent )
|
|
hWndParent = GetDesktopWindow();
|
|
|
|
int iCmd = TrackPopupMenu( hMenu,
|
|
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
|
|
(*ppt).x, (*ppt).y, 0, hWndParent, NULL);
|
|
DestroyMenu( hMenu );
|
|
|
|
if( iCmd < IDTB_REBASE ) {
|
|
if( iCmd == OLECMDID_PROPERTIES ) { // Trident folks say the In value must be set to the mouse pos
|
|
V_VT(&vaIn) = VT_I4;
|
|
V_I4(&vaIn) = MAKELONG((*ppt).x,(*ppt).y);
|
|
}
|
|
((IOleCommandTarget*)pcmdtReserved)->Exec( NULL, iCmd,
|
|
OLECMDEXECOPT_DODEFAULT, &vaIn, &vaOut );
|
|
}
|
|
else if( iCmd < HTMLID_REBASE ) {
|
|
iCmd -=IDTB_REBASE;
|
|
if( iCmd == IDTB_BACK )
|
|
((CContainer*) m_pOuter)->m_pWebBrowserApp->GoBack();
|
|
else if( iCmd == IDTB_FORWARD )
|
|
((CContainer*) m_pOuter)->m_pWebBrowserApp->GoForward();
|
|
}
|
|
else {
|
|
iCmd -=HTMLID_REBASE;
|
|
((IOleCommandTarget*)pcmdtReserved)->Exec( &CGID_IWebBrowserPriv, iCmd,
|
|
OLECMDEXECOPT_DODEFAULT, &vaIn, &vaOut );
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
|
|
{
|
|
pInfo->dwFlags = 0;
|
|
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
|
|
IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::HideUI(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::UpdateUI(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::EnableModeless(BOOL fEnable)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey, DWORD dw)
|
|
{
|
|
#if 0
|
|
// The key given will be stored under HKEY_CURRETN_USER.
|
|
//
|
|
if ( (*pchKey = (LPOLESTR)CoTaskMemAlloc((lstrlenW(gszHHRegKey)*sizeof(WCHAR))+sizeof(WCHAR))) )
|
|
{
|
|
wcscpy(*pchKey, gszHHRegKey);
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::GetExternal(IDispatch **ppDispatch)
|
|
{
|
|
*ppDispatch = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::TranslateUrl(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
*
|
|
* CDocHostShowUI
|
|
*
|
|
*/
|
|
|
|
CDocHostShowUI::CDocHostShowUI(IUnknown * pOuter)
|
|
{
|
|
m_cRef = 0;
|
|
m_pOuter = pOuter;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostShowUI::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
*ppv = 0;
|
|
|
|
if (m_pOuter)
|
|
return m_pOuter->QueryInterface(riid,ppv);
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDocHostShowUI::AddRef(void)
|
|
{
|
|
m_cRef++;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->AddRef();
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDocHostShowUI::Release(void)
|
|
{
|
|
ULONG c = --m_cRef;
|
|
|
|
if (m_pOuter)
|
|
m_pOuter->Release();
|
|
|
|
if (c <= 0)
|
|
delete this;
|
|
|
|
return c;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostShowUI::ShowHelp( HWND hwnd, LPOLESTR pszHelpFile, UINT uCommand, DWORD dwData, POINT ptMouse, IDispatch* pDispatchObjectHit )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CDocHostShowUI::ShowMessage( HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT* plResult )
|
|
{
|
|
return S_FALSE;
|
|
}
|