📄 dsofcontrol.cpp
字号:
/***************************************************************************
* DSOFCONTROL.CPP
*
* CDsoFramerControl: The Base Control
*
* Copyright ?999-2004; Microsoft Corporation. All rights reserved.
* Written by Microsoft Developer Support Office Integration (PSS DSOI)
*
* This code is provided via KB 311765 as a sample. It is not a formal
* product and has not been tested with all containers or servers. Use it
* for educational purposes only. See the EULA.TXT file included in the
* KB download for full terms of use and restrictions.
*
* THIS CODE 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.
*
***************************************************************************/
#include "dsoframer.h"
#include <afxcmn.h>
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl - The Main Control Class
//
// Serves as a base for the ActiveX Document site object which will do
// the actual embedding.
//
CDsoFramerControl::CDsoFramerControl(LPUNKNOWN punk)
{
ODS("CDsoFramerControl::CDsoFramerControl\n");
m_pOuterUnknown = ((punk) ? punk : (IUnknown*)&m_xInternalUnknown);
m_nOriginalFileType = 0;
m_cRef = 0;
m_ptiDispType = NULL;
m_pDispExcep = NULL;
m_bstrCustomCaption = NULL;
m_hwnd = NULL;
m_hwndParent = NULL;
m_Size.cx = m_Size.cy = 0;
m_rcLocation.left = m_rcLocation.top = m_rcLocation.right = m_rcLocation.bottom = 0; // where we at
memset(m_rgrcMenuItems, 0, sizeof(RECT) * DSO_MAX_MENUITEMS);
m_clrBorderColor = 0;
m_clrBackColor = 0;
m_clrForeColor = 0;
m_clrTBarColor = 0;
m_clrTBarTextColor = 0;
m_pClientSite = NULL;
m_pControlSite = NULL;
m_pInPlaceSite = NULL;
m_pInPlaceFrame = NULL;
m_pInPlaceUIWindow = NULL;
m_pViewAdviseSink = NULL;
m_pOleAdviseHolder = NULL;
m_pDataAdviseHolder = NULL;
m_dispEvents = NULL;
m_pOleStorage = NULL;
m_pDocObjFrame = NULL;
m_hmenuFilePopup = NULL;
m_wFileMenuFlags = 0;
m_wSelMenuItem = 0;
m_cMenuItems = 0;
m_pFrameHook = NULL;
m_hbmDeactive = NULL;
m_pwszHostName = NULL;
m_fDirty = 0;
m_fInPlaceActive = 0;
m_fInPlaceVisible = 0;
m_fUIActive = 0;
m_fViewAdvisePrimeFirst = 0;
m_fViewAdviseOnlyOnce = 0;
m_fUsingWindowRgn = 0;
m_fFreezeEvents = 0;
m_fDesignMode = 0;
m_fModeFlagValid = 0;
m_fBorderStyle = 0;
m_fShowTitlebar = 0;
m_fShowToolbars = 0;
m_fModalState = 0;
m_fObjectMenu = 0;
m_fConCntDone = 0;
m_fComponentActive = 0;
m_fShowMenuBar = 0;
m_fInDocumentLoad = 0;
m_fNoInteractive = 0;
m_fShowMenuPrev = 0;
m_fShowToolsPrev = 0;
m_pHttp = NULL;
m_nOriginalFileType = FILE_TYPE_NULL;
m_pFtpConnection = NULL;
m_bConnect = FALSE;
m_pSession = NULL;
memset(m_cUrl,0,1024);
memset(m_cPassWord,0,128);//Excel的只读密码
memset(m_cPWWrite,0,128);//Excel的可写密码
m_spDoc = NULL;
}
CDsoFramerControl::~CDsoFramerControl(void)
{
ODS("CDsoFramerControl::~CDsoFramerControl\n");
Close();
m_nOriginalFileType = FILE_TYPE_NULL;
ClearFile();
SAFE_RELEASE_INTERFACE(m_ptiDispType);
SAFE_RELEASE_INTERFACE(m_pClientSite);
SAFE_RELEASE_INTERFACE(m_pControlSite);
SAFE_RELEASE_INTERFACE(m_pInPlaceSite);
SAFE_RELEASE_INTERFACE(m_pInPlaceFrame);
SAFE_RELEASE_INTERFACE(m_pInPlaceUIWindow);
SAFE_RELEASE_INTERFACE(m_pViewAdviseSink);
SAFE_RELEASE_INTERFACE(m_pOleAdviseHolder);
SAFE_RELEASE_INTERFACE(m_pDataAdviseHolder);
SAFE_RELEASE_INTERFACE(m_dispEvents);
SAFE_RELEASE_INTERFACE(m_pOleStorage);
SAFE_FREESTRING(m_pwszHostName);
if(m_pHttp)
delete m_pHttp;
m_pHttp = NULL;
if(m_pSession){
delete m_pSession;
m_pSession = NULL;
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::InitializeNewInstance
//
// Sets up the inital state for the control. Any other member variable
// not set here will be NULL/FALSE thanks to zero-init in MemAlloc.
//
STDMETHODIMP CDsoFramerControl::InitializeNewInstance()
{
m_clrBorderColor = 0x80000010; // System Button Shadow Color
m_clrBackColor = 0x80000005; // System Window Background Color
m_clrForeColor = 0x80000008; // System Window Text Color
m_clrTBarColor = 0x8000000D; // System Highlight Color
m_clrTBarTextColor = 0x8000000E; // System Highlight Text Color
m_fBorderStyle = dsoBorderFlat;
m_fShowTitlebar = TRUE;
m_fShowToolbars = TRUE;
m_fShowMenuBar = TRUE;
m_wFileMenuFlags = 0xFFFF; // All items are "enabled" by default
m_Size.cx = 240;
m_Size.cy = 240;
return S_OK;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::InPlaceActivate
//
// Does all the work in-place activating and/or ui activating the
// control when asked to do so. Sets up the main control window, the
// needed interfaces, and (if not in design) subclasses the main top-level
// window we can monitor messages that must be forwarded to an ip active
// DocObject when we have one loaded.
//
STDMETHODIMP CDsoFramerControl::InPlaceActivate(LONG lVerb)
{
HRESULT hr;
SIZEL sizel;
TRACE1("CDsoFramerControl::InPlaceActivate - %d\n", lVerb);
// if we don't have a client site, then there's not much to do.
if (!m_pClientSite) return S_OK;
// get an InPlace site pointer.
if (NULL == m_pInPlaceSite)
{
hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
RETURN_ON_FAILURE(hr);
}
// if we're not already active, go and do it.
if (!m_fInPlaceActive)
{
OLEINPLACEFRAMEINFO InPlaceFrameInfo;
RECT rcPos, rcClip;
hr = m_pInPlaceSite->CanInPlaceActivate();
if (hr != S_OK){ if (!FAILED(hr)) hr = E_FAIL; goto cleanup;}
// if we are here, then we have permission to go in-place active.
// now, announce our intentions to actually go ahead and do this.
hr = m_pInPlaceSite->OnInPlaceActivate();
GOTO_ON_FAILURE(hr, cleanup);
// if we're here, we're ready to go in-place active. we just need
// to set up some flags, and then create the window [if we have one]
m_fInPlaceActive = TRUE;
// we need to get some information about our location in the parent
// window, as well as some information about the parent
hr = m_pInPlaceSite->GetWindow(&m_hwndParent);
if (FAILED(hr) || !IsWindow(m_hwndParent))
{
hr = OLE_E_INVALIDHWND;
goto cleanup;
}
InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
hr = m_pInPlaceSite->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow, &rcPos, &rcClip, &InPlaceFrameInfo);
GOTO_ON_FAILURE(hr, cleanup);
// make sure we'll display ourselves in the correct location with the correct size
sizel.cx = rcPos.right - rcPos.left;
sizel.cy = rcPos.bottom - rcPos.top;
m_Size = sizel;
m_xOleInplaceObject.SetObjectRects(&rcPos, &rcClip);
// finally, create our window if we have to!
if (NULL == m_hwnd)
{
WNDCLASS wndclass;
EnterCriticalSection(&v_csecThreadSynch);
if (GetClassInfo(v_hModule, "DSOFramerOCXWnd", &wndclass) == 0)
{
memset(&wndclass, 0, sizeof(WNDCLASS));
wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wndclass.lpfnWndProc = CDsoFramerControl::ControlWindowProc;
wndclass.hInstance = v_hModule;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.lpszClassName = "DSOFramerOCXWnd";
RegisterClass(&wndclass);
}
m_hwnd = CreateWindowEx(0, "DSOFramerOCXWnd", NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
rcPos.left, rcPos.top, m_Size.cx, m_Size.cy,
m_hwndParent, NULL, v_hModule, NULL);
if (m_hwnd) SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this);
if(m_dispEvents)
DsoDispatchInvoke(m_dispEvents, L"NotifyCtrlReady", DSOF_DISPID_NotifyCtrlReady, 0, 0, NULL, NULL);
LeaveCriticalSection(&v_csecThreadSynch);
if (!m_hwnd) {hr = E_FAIL; goto cleanup;}
}
// finally, tell the host of this
m_pClientSite->ShowObject();
}
// if we're not inplace visible yet, do so now.
if (!m_fInPlaceVisible)
SetInPlaceVisible(TRUE);
// Hook top-level parent window if in RunMode. This let's us
// track WM_ACTIVATEAPP messages, which are critical for DocObjs...
if (!m_pFrameHook)
m_pFrameHook = CDsoFrameWindowHook::AttachToFrameWindow(m_hwnd, this);
// if we were asked to UIActivate, and we currently are not, do so!
if ((lVerb == OLEIVERB_PRIMARY ||
lVerb == OLEIVERB_UIACTIVATE) && (!m_fUIActive))
{
m_fUIActive = TRUE;
// inform the container of our intent
m_pInPlaceSite->OnUIActivate();
// notify the hook we have taked focus...
if (m_pFrameHook)
m_pFrameHook->SetActiveComponent(this);
// take the focus [which is what UI Activation is all about !]
Activate(); // SetFocus(m_hwnd);
// set ourselves up in the host.
if (m_pInPlaceFrame)
m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject*)&m_xOleInplaceActiveObject, NULL);
if (m_pInPlaceUIWindow)
m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject*)&m_xOleInplaceActiveObject, NULL);
// we have to explicitly say we don't wany any border space.
if (m_pInPlaceFrame)
m_pInPlaceFrame->SetBorderSpace(NULL);
if (m_pInPlaceUIWindow)
m_pInPlaceUIWindow->SetBorderSpace(NULL);
}
return S_OK; // be-de-be-de-be-de that's all folks!
cleanup:
// something catastrophic happened [or, at least something bad].
// die a horrible fiery mangled painful death...
m_fInPlaceActive = FALSE;
return hr;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::SetInPlaceVisible
//
// Make sure our control is visible or not (does not actually take ui
// focus, that should be done in InPlaceActivate).
//
STDMETHODIMP_(void) CDsoFramerControl::SetInPlaceVisible(BOOL fShow)
{
BOOL fVisible;
m_fInPlaceVisible = fShow;
// don't do anything if we don't have a window. otherwise, set it
if (m_hwnd)
{
fVisible = IsWindowVisible(m_hwnd);
if (fVisible && !fShow)
ShowWindow(m_hwnd, SW_HIDE);
else if (!fVisible && fShow)
ShowWindow(m_hwnd, SW_SHOWNA);
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::UpdateModalState
//
// Called either by developer (ModalState property) or by the embedded
// DocObject to notify host (VB/IE) that we are modal.
//
STDMETHODIMP_(void) CDsoFramerControl::UpdateModalState(BOOL fModeless, BOOL fNotifyIPObject)
{
TRACE2("CDsoFramerControl::UpdateModalState(AllowModeless=%d, NotifyIP=%d)\n", fModeless, fNotifyIPObject);
if (fModeless == (int)m_fModalState)
{
IOleInPlaceActiveObject* pipao;
m_fModalState = !(fModeless);
ODS("Modal state changed\n");
// Excel doesn't like us to notify the host of changes in modality
// if it is the one who initialied the call. So, we check the
// NotifyIPObj flag and only notify host when the IPObj is not the caller...
if ((fNotifyIPObject) && (m_pInPlaceFrame))
m_pInPlaceFrame->EnableModeless(fModeless);
// Again, if IPObj is not the caller and we have Ipobj, let it know
// of the change in modal state...
if ((fNotifyIPObject) && (m_pDocObjFrame) &&
(pipao = m_pDocObjFrame->GetActiveObject()))
pipao->EnableModeless(fModeless);
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::UpdateInteractiveState
//
// Called when interactivity changes (mostly due to print preview).
//
STDMETHODIMP_(void) CDsoFramerControl::UpdateInteractiveState(BOOL fActive)
{
if (fActive)
{
m_fNoInteractive = FALSE;
if (m_fShowMenuPrev) put_Menubar(VARIANT_TRUE);
if (!m_fShowToolsPrev) put_Toolbars(VARIANT_FALSE);
// Notify control host that preview mode has ended...
if ((m_dispEvents) && !(m_fFreezeEvents))
DsoDispatchInvoke(m_dispEvents, NULL, DSOF_DISPID_ENDPREVIEW, 0, 0, NULL, NULL);
}
else
{
m_fShowMenuPrev = m_fShowMenuBar;
m_fShowToolsPrev = m_fShowToolbars;
if (m_fShowMenuBar) put_Menubar(VARIANT_FALSE);
if (!m_fShowToolbars) put_Toolbars(VARIANT_TRUE);
m_fNoInteractive = TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -