From 8af7cd5ee1a65a577d8e60b2cccf80b130d31006 Mon Sep 17 00:00:00 2001 From: Rich Date: Mon, 10 Dec 2007 20:53:18 +0000 Subject: [PATCH] --- PROMS/DSOFRAMER/Source2005/Lib/dsoframer.idl | 281 ++ PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.c | 93 + PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.h | 1601 ++++++ PROMS/DSOFRAMER/Source2005/Res/dso.ico | Bin 0 -> 318 bytes PROMS/DSOFRAMER/Source2005/Res/dsoframer.rc | 154 + PROMS/DSOFRAMER/Source2005/Res/resource.h | 39 + PROMS/DSOFRAMER/Source2005/Res/toolbox.bmp | Bin 0 -> 334 bytes PROMS/DSOFRAMER/Source2005/UpgradeLog.XML | 20 + .../_UpgradeReport_Files/UpgradeReport.css | 207 + .../_UpgradeReport_Files/UpgradeReport.xslt | 232 + .../UpgradeReport_Minus.gif | Bin 0 -> 69 bytes .../UpgradeReport_Plus.gif | Bin 0 -> 71 bytes PROMS/DSOFRAMER/Source2005/classfactory.cpp | 118 + PROMS/DSOFRAMER/Source2005/dsofauto.cpp | 1321 +++++ PROMS/DSOFRAMER/Source2005/dsofcontrol.cpp | 4313 +++++++++++++++++ PROMS/DSOFRAMER/Source2005/dsofdocobj.cpp | 3252 +++++++++++++ PROMS/DSOFRAMER/Source2005/dsofdocobj.h | 350 ++ PROMS/DSOFRAMER/Source2005/dsofprint.cpp | 419 ++ PROMS/DSOFRAMER/Source2005/dsoframer.def | 6 + PROMS/DSOFRAMER/Source2005/dsoframer.dsp | 205 + PROMS/DSOFRAMER/Source2005/dsoframer.dsw | 29 + PROMS/DSOFRAMER/Source2005/dsoframer.h | 689 +++ PROMS/DSOFRAMER/Source2005/dsoframer.sln | 69 + PROMS/DSOFRAMER/Source2005/dsoframer.sln.bak | 77 + PROMS/DSOFRAMER/Source2005/dsoframer.sln.old | 21 + PROMS/DSOFRAMER/Source2005/dsoframer.vcproj | 470 ++ .../Source2005/dsoframer.vcproj.7.10.old | 360 ++ ...dsoframer.vcproj.RHMDESKTOP.Rich Mark.user | 65 + PROMS/DSOFRAMER/Source2005/ipprevw.h | 88 + PROMS/DSOFRAMER/Source2005/mainentry.cpp | 318 ++ PROMS/DSOFRAMER/Source2005/rbbinder.h | 253 + PROMS/DSOFRAMER/Source2005/utilities.cpp | 1359 ++++++ PROMS/DSOFRAMER/Source2005/utilities.h | 242 + PROMS/DSOFRAMER/Source2005/version.h | 59 + 34 files changed, 16710 insertions(+) create mode 100644 PROMS/DSOFRAMER/Source2005/Lib/dsoframer.idl create mode 100644 PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.c create mode 100644 PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.h create mode 100644 PROMS/DSOFRAMER/Source2005/Res/dso.ico create mode 100644 PROMS/DSOFRAMER/Source2005/Res/dsoframer.rc create mode 100644 PROMS/DSOFRAMER/Source2005/Res/resource.h create mode 100644 PROMS/DSOFRAMER/Source2005/Res/toolbox.bmp create mode 100644 PROMS/DSOFRAMER/Source2005/UpgradeLog.XML create mode 100644 PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.css create mode 100644 PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.xslt create mode 100644 PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport_Minus.gif create mode 100644 PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport_Plus.gif create mode 100644 PROMS/DSOFRAMER/Source2005/classfactory.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/dsofauto.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/dsofcontrol.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/dsofdocobj.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/dsofdocobj.h create mode 100644 PROMS/DSOFRAMER/Source2005/dsofprint.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.def create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.dsp create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.dsw create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.h create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.sln create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.sln.bak create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.sln.old create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.vcproj create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.7.10.old create mode 100644 PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.RHMDESKTOP.Rich Mark.user create mode 100644 PROMS/DSOFRAMER/Source2005/ipprevw.h create mode 100644 PROMS/DSOFRAMER/Source2005/mainentry.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/rbbinder.h create mode 100644 PROMS/DSOFRAMER/Source2005/utilities.cpp create mode 100644 PROMS/DSOFRAMER/Source2005/utilities.h create mode 100644 PROMS/DSOFRAMER/Source2005/version.h diff --git a/PROMS/DSOFRAMER/Source2005/Lib/dsoframer.idl b/PROMS/DSOFRAMER/Source2005/Lib/dsoframer.idl new file mode 100644 index 00000000..d818958e --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/Lib/dsoframer.idl @@ -0,0 +1,281 @@ +/*************************************************************************** + * DSOFRAMER.IDL - DSO Framer ActiveX Control Type Library + * + * Copyright ©1999-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. + * + ***************************************************************************/ +/*************************************************************************** + * + * IMPORTANT: You should not attempt to modify this library unless you are + * sure you do not break binary compatibility, or you change all the GUIDs + * listed in version.h so as to build a completely new control. + * + ***************************************************************************/ +#include +#include "..\version.h" + +[ + uuid(DSOFRAMERCTL_TLIB), helpstring(DSOFRAMERCTL_FULLNAME), + version(DSOFRAMERCTL_VERSION), lcid(0x0000), control +] +library DSOFramer +{ + importlib("STDOLE2.TLB"); + + typedef enum dsoBorderStyle + { + dsoBorderNone = 0, + dsoBorderFlat, + dsoBorder3D, + dsoBorder3DThin + } dsoBorderStyle; + + typedef enum dsoShowDialogType + { + dsoDialogNew = 0, + dsoDialogOpen, + dsoDialogSave, + dsoDialogSaveCopy, + dsoDialogPrint, + dsoDialogPageSetup, + dsoDialogProperties + } dsoShowDialogType; + + typedef enum dsoFileCommandType + { + dsoFileNew = 0, + dsoFileOpen, + dsoFileClose, + dsoFileSave, + dsoFileSaveAs, + dsoFilePrint, + dsoFilePageSetup, + dsoFileProperties, + dsoFilePrintPreview + } dsoFileCommandType; + + + [ + uuid(DSOFRAMERCTL_INTERFACE), hidden, version(DSOFRAMERCTL_VERSION), + dual, oleautomation, odl + ] + interface _FramerControl : IDispatch + { + [id(0x00010001), helpstring("Activates the current document object.")] + HRESULT Activate(); + + [propget, id(0x00010002), helpstring("Returns the Automation interface of the document object.")] + HRESULT ActiveDocument([out,retval] IDispatch** ppdisp); + + [id(0x00010003), helpstring("Creates a new document based on the ProgId or Template file provided.")] + HRESULT CreateNew([in] BSTR ProgIdOrTemplate); + + [id(0x00010004), helpstring("Opens a document from a file, URL, or Automation object.")] + HRESULT Open([in] VARIANT Document, [in, optional] VARIANT ReadOnly, [in, optional] VARIANT ProgId, [in, optional] VARIANT WebUsername, [in, optional] VARIANT WebPassword); + + [id(0x00010005), helpstring("Saves the document to specified location or its original location.")] + HRESULT Save([in, optional] VARIANT SaveAsDocument, [in, optional] VARIANT OverwriteExisting, [in, optional] VARIANT WebUsername, [in, optional] VARIANT WebPassword); + + [id(0x00010008), hidden] + HRESULT _PrintOutOld([in, optional] VARIANT PromptToSelectPrinter); + + [id(0x00010009), helpstring("Closes the currently open document.")] + HRESULT Close(); + + [propput, id(0x0001000A), helpstring("Returns/sets the titlebar caption.")] + HRESULT Caption([in] BSTR bstr); + [propget, id(0x0001000A)] + HRESULT Caption([out,retval] BSTR* pbstr); + + [propput, id(0x0001000B), helpstring("Returns/sets whether the titlebar should be displayed.")] + HRESULT Titlebar([in] VARIANT_BOOL vbool); + [propget, id(0x0001000B)] + HRESULT Titlebar([out,retval] VARIANT_BOOL* pbool); + + [propput, id(0x0001000C), helpstring("Returns/sets whether toolbars should be displayed.")] + HRESULT Toolbars([in] VARIANT_BOOL vbool); + [propget, id(0x0001000C)] + HRESULT Toolbars([out,retval] VARIANT_BOOL* pbool); + + [propput, nonbrowsable, id(0x0001000D), helpstring("Returns/sets the controls modal state.")] + HRESULT ModalState([in] VARIANT_BOOL vbool); + [propget, nonbrowsable, id(0x0001000D)] + HRESULT ModalState([out,retval] VARIANT_BOOL* pbool); + + [id(0x0001000E), helpstring("Displays a modal dialog of the given type for user action.")] + HRESULT ShowDialog([in] dsoShowDialogType DlgType); + + [propput, id(0x0001000F), helpstring("Returns/sets whether a specific action item is enabled.")] + HRESULT EnableFileCommand([in] dsoFileCommandType Item, [in] VARIANT_BOOL vbool); + [propget, id(0x0001000F)] + HRESULT EnableFileCommand([in] dsoFileCommandType Item, [out,retval] VARIANT_BOOL* pbool); + + [propput, id(DISPID_BORDERSTYLE), helpstring("Returns/sets the border style for the control.")] + HRESULT BorderStyle([in] dsoBorderStyle style); + [propget, id(DISPID_BORDERSTYLE)] + HRESULT BorderStyle([out, retval] dsoBorderStyle* pstyle); + + [propput, id(DISPID_BORDERCOLOR), helpstring("Returns/sets the border color of the control.")] + HRESULT BorderColor([in] OLE_COLOR clr); + [propget, id(DISPID_BORDERCOLOR)] + HRESULT BorderColor([out,retval] OLE_COLOR* pclr); + + [propput, id(DISPID_BACKCOLOR), helpstring("Returns/sets the background color of the control.")] + HRESULT BackColor([in] OLE_COLOR clr); + [propget, id(DISPID_BACKCOLOR)] + HRESULT BackColor([out,retval] OLE_COLOR* pclr); + + [propput, id(DISPID_FORECOLOR), helpstring("Returns/sets the foreground color of the control.")] + HRESULT ForeColor([in]OLE_COLOR clr); + [propget, id(DISPID_FORECOLOR)] + HRESULT ForeColor([out,retval]OLE_COLOR* pclr); + + [propput, id(0x00010010), helpstring("Returns/sets the color of the titlebar.")] + HRESULT TitlebarColor([in] OLE_COLOR clr); + [propget, id(0x00010010)] + HRESULT TitlebarColor([out,retval] OLE_COLOR* pclr); + + [propput, id(0x00010011), helpstring("Returns/sets the color of text for the titlebar.")] + HRESULT TitlebarTextColor([in] OLE_COLOR clr); + [propget, id(0x00010011)] + HRESULT TitlebarTextColor([out,retval] OLE_COLOR* pclr); + + [id(0x00010012), helpstring("Calls IOleCommandTarget::Exec on embedded object.")] + HRESULT ExecOleCommand([in] LONG OLECMDID, [in, optional] VARIANT Options, [in, optional] VARIANT* vInParam, [in, out, optional] VARIANT* vInOutParam); + + [propput, id(0x00010013), helpstring("Returns/sets whether a menu bar should be displayed.")] + HRESULT Menubar([in] VARIANT_BOOL vbool); + [propget, id(0x00010013)] + HRESULT Menubar([out,retval] VARIANT_BOOL* pbool); + + [propput, id(0x00010014), helpstring("Returns/sets host application name (used in embedding).")] + HRESULT HostName([in] BSTR bstr); + [propget, id(0x00010014)] + HRESULT HostName([out,retval] BSTR* pbstr); + + [propget, id(0x00010015), helpstring("Returns full document path name for object.")] + HRESULT DocumentFullName([out,retval] BSTR* pbstr); + + [id(0x00010016), helpstring("Prints current document to specific printer with settings.")] + HRESULT PrintOut([in, optional] VARIANT PromptUser, [in, optional] VARIANT PrinterName, [in, optional] VARIANT Copies, + [in, optional] VARIANT FromPage, [in, optional] VARIANT ToPage, [in, optional] VARIANT OutputFile); + + [id(0x00010017), helpstring("Starts a print preview (if document supports it).")] + HRESULT PrintPreview(); + + [id(0x00010018), helpstring("Exits a current print preview.")] + HRESULT PrintPreviewExit(); + + [propget, id(0x00010019), helpstring("Returns True/False if file was open read-only, or has not been saved.")] + HRESULT IsReadOnly([out,retval] VARIANT_BOOL* pbool); + + [propget, id(0x0001001A), helpstring("Returns True/False if file has been altered or needs save.")] + HRESULT IsDirty([out,retval] VARIANT_BOOL* pbool); + + [propput, id(0x0001001B), helpstring("Sets lock on the current embed server to keep it running (document must be open first).")] + HRESULT LockServer([in] VARIANT_BOOL vbool); + [propget, id(0x0001001B)] + HRESULT LockServer([out,retval] VARIANT_BOOL* pvbool); + + [id(0x0001001C), nonbrowsable, helpstring("Gets the content of the body of the document (excluding headers/footers).")] + HRESULT GetDataObjectContent([in] VARIANT ClipFormatNameOrNumber, [out,retval] VARIANT *pvResults); + + [id(0x0001001D), nonbrowsable, helpstring("Sets the content of the body of the document.")] + HRESULT SetDataObjectContent([in] VARIANT ClipFormatNameOrNumber, [in] VARIANT DataByteArray); + + [propput, id(0x0001001E), helpstring("Allows host to set policy on activation behavior.")] + HRESULT ActivationPolicy([in] enum dsoActivationPolicy lPolicy); + [propget, id(0x0001001E)] + HRESULT ActivationPolicy([out,retval] enum dsoActivationPolicy *plPolicy); + + [propput, id(0x0001001F), helpstring("Allows host to set policy on use of the frame hook.")] + HRESULT FrameHookPolicy([in] enum dsoFrameHookPolicy lPolicy); + [propget, id(0x0001001F)] + HRESULT FrameHookPolicy([out,retval] enum dsoFrameHookPolicy *plPolicy); + + [propput, id(0x00010020), helpstring("Gets/sets whether control should try to handle menu accelerators or pass to host window.")] + HRESULT MenuAccelerators([in] VARIANT_BOOL vbool); + [propget, id(0x00010020)] + HRESULT MenuAccelerators([out,retval] VARIANT_BOOL* pvbool); + + [propput, nonbrowsable, id(0x00010021), helpstring("Gets/sets whether control events are raised.")] + HRESULT EventsEnabled([in] VARIANT_BOOL vbool); + [propget, nonbrowsable, id(0x00010021)] + HRESULT EventsEnabled([out,retval] VARIANT_BOOL* pvbool); + + [propget, id(0x00010022), helpstring("Returns just the document name (excluding path).")] + HRESULT DocumentName([out,retval] BSTR* pbstr); + }; + + [ + uuid(DSOFRAMERCTL_DISPEVTS), hidden + ] + dispinterface _DFramerCtlEvents + { + properties: + methods: + [id(DSOF_DISPID_FILECMD), helpstring("Called when File menu item is selected by user (may be canceled).")] + HRESULT OnFileCommand([in] dsoFileCommandType Item, [in,out] VARIANT_BOOL* Cancel); + + [id(DSOF_DISPID_DOCOPEN), helpstring("Called when document is opened or new document added.")] + HRESULT OnDocumentOpened([in] BSTR File, [in] IDispatch* Document); + + [id(DSOF_DISPID_DOCCLOSE), helpstring("Called when document is closed.")] + HRESULT OnDocumentClosed(); + + [id(DSOF_DISPID_ACTIVATE), helpstring("Called when component gains/loses activation.")] + HRESULT OnActivationChange([in] VARIANT_BOOL fGoingActive); + + [id(DSOF_DISPID_BDOCCLOSE), helpstring("Called before document is closed (may be canceled).")] + HRESULT BeforeDocumentClosed([in] IDispatch* Document, [in,out] VARIANT_BOOL* Cancel); + + [id(DSOF_DISPID_BDOCSAVE), helpstring("Called before document is saved (may be canceled).")] + HRESULT BeforeDocumentSaved([in] IDispatch* Document, [in] BSTR Location, [in,out] VARIANT_BOOL* Cancel); + + [id(DSOF_DISPID_ENDPREVIEW), helpstring("Called when print preview is closed.")] + HRESULT OnPrintPreviewExit(); + + [id(DSOF_DISPID_SAVECOMPLETE), helpstring("Called when save is successful.")] + HRESULT OnSaveCompleted([in] IDispatch* Document, [in] BSTR DocName, [in] BSTR FullFileLocation); + + }; + + [ + uuid(DSOFRAMERCTL_CLSID), + helpstring(DSOFRAMERCTL_SHORTNAME), control + ] + coclass FramerControl + { + [default] interface _FramerControl; + [default, source] dispinterface _DFramerCtlEvents; + }; + + + typedef enum dsoFrameHookPolicy + { + dsoNormalBehavior = 0, + dsoSetOnFirstOpen, + dsoResetNow, + dsoDisableHook = 0xFFFFFFFF + } dsoFrameHookPolicy; + + typedef enum dsoActivationPolicy + { + dsoDefaultBehavior = 0, + dsoKeepUIActiveOnAppDeactive = 0x01, + dsoCompDeactivateOnLostFocus = 0x02, + dsoIPDeactivateOnCompDeactive = 0x04 + } dsoActivationPolicy; + +}; + diff --git a/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.c b/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.c new file mode 100644 index 00000000..99ef170d --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.c @@ -0,0 +1,93 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 6.00.0361 */ +/* at Mon Oct 22 07:55:11 2007 + */ +/* Compiler settings for .\Lib\dsoframer.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#if !defined(_M_IA64) && !defined(_M_AMD64) + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_DSOFramer,0x00460180,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + + +MIDL_DEFINE_GUID(IID, IID__FramerControl,0x00460181,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + + +MIDL_DEFINE_GUID(IID, DIID__DFramerCtlEvents,0x00460185,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + + +MIDL_DEFINE_GUID(CLSID, CLSID_FramerControl,0x00460182,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + +#endif /* !defined(_M_IA64) && !defined(_M_AMD64)*/ + diff --git a/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.h b/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.h new file mode 100644 index 00000000..db6ea78e --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/Lib/dsoframerlib.h @@ -0,0 +1,1601 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 6.00.0361 */ +/* at Mon Oct 22 07:55:11 2007 + */ +/* Compiler settings for .\Lib\dsoframer.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __dsoframerlib_h__ +#define __dsoframerlib_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef ___FramerControl_FWD_DEFINED__ +#define ___FramerControl_FWD_DEFINED__ +typedef interface _FramerControl _FramerControl; +#endif /* ___FramerControl_FWD_DEFINED__ */ + + +#ifndef ___DFramerCtlEvents_FWD_DEFINED__ +#define ___DFramerCtlEvents_FWD_DEFINED__ +typedef interface _DFramerCtlEvents _DFramerCtlEvents; +#endif /* ___DFramerCtlEvents_FWD_DEFINED__ */ + + +#ifndef __FramerControl_FWD_DEFINED__ +#define __FramerControl_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class FramerControl FramerControl; +#else +typedef struct FramerControl FramerControl; +#endif /* __cplusplus */ + +#endif /* __FramerControl_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); + + +#ifndef __DSOFramer_LIBRARY_DEFINED__ +#define __DSOFramer_LIBRARY_DEFINED__ + +/* library DSOFramer */ +/* [control][lcid][version][helpstring][uuid] */ + +typedef +enum dsoBorderStyle + { dsoBorderNone = 0, + dsoBorderFlat = dsoBorderNone + 1, + dsoBorder3D = dsoBorderFlat + 1, + dsoBorder3DThin = dsoBorder3D + 1 + } dsoBorderStyle; + +typedef +enum dsoShowDialogType + { dsoDialogNew = 0, + dsoDialogOpen = dsoDialogNew + 1, + dsoDialogSave = dsoDialogOpen + 1, + dsoDialogSaveCopy = dsoDialogSave + 1, + dsoDialogPrint = dsoDialogSaveCopy + 1, + dsoDialogPageSetup = dsoDialogPrint + 1, + dsoDialogProperties = dsoDialogPageSetup + 1 + } dsoShowDialogType; + +typedef +enum dsoFileCommandType + { dsoFileNew = 0, + dsoFileOpen = dsoFileNew + 1, + dsoFileClose = dsoFileOpen + 1, + dsoFileSave = dsoFileClose + 1, + dsoFileSaveAs = dsoFileSave + 1, + dsoFilePrint = dsoFileSaveAs + 1, + dsoFilePageSetup = dsoFilePrint + 1, + dsoFileProperties = dsoFilePageSetup + 1, + dsoFilePrintPreview = dsoFileProperties + 1 + } dsoFileCommandType; + +typedef +enum dsoFrameHookPolicy + { dsoNormalBehavior = 0, + dsoSetOnFirstOpen = dsoNormalBehavior + 1, + dsoResetNow = dsoSetOnFirstOpen + 1, + dsoDisableHook = 0xffffffff + } dsoFrameHookPolicy; + +typedef +enum dsoActivationPolicy + { dsoDefaultBehavior = 0, + dsoKeepUIActiveOnAppDeactive = 0x1, + dsoCompDeactivateOnLostFocus = 0x2, + dsoIPDeactivateOnCompDeactive = 0x4 + } dsoActivationPolicy; + + +DEFINE_GUID(LIBID_DSOFramer,0x00460180,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + +#ifndef ___FramerControl_INTERFACE_DEFINED__ +#define ___FramerControl_INTERFACE_DEFINED__ + +/* interface _FramerControl */ +/* [object][oleautomation][dual][version][hidden][uuid] */ + + +DEFINE_GUID(IID__FramerControl,0x00460181,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("00460181-9E5E-11d5-B7C8-B8269041DD57") + _FramerControl : public IDispatch + { + public: + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Activate( void) = 0; + + virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_ActiveDocument( + /* [retval][out] */ IDispatch **ppdisp) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CreateNew( + /* [in] */ BSTR ProgIdOrTemplate) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Open( + /* [in] */ VARIANT Document, + /* [optional][in] */ VARIANT ReadOnly, + /* [optional][in] */ VARIANT ProgId, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Save( + /* [optional][in] */ VARIANT SaveAsDocument, + /* [optional][in] */ VARIANT OverwriteExisting, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword) = 0; + + virtual /* [hidden][id] */ HRESULT STDMETHODCALLTYPE _PrintOutOld( + /* [optional][in] */ VARIANT PromptToSelectPrinter) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Close( void) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Caption( + /* [in] */ BSTR bstr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Caption( + /* [retval][out] */ BSTR *pbstr) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Titlebar( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Titlebar( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Toolbars( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Toolbars( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][nonbrowsable][propput] */ HRESULT STDMETHODCALLTYPE put_ModalState( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][nonbrowsable][propget] */ HRESULT STDMETHODCALLTYPE get_ModalState( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE ShowDialog( + /* [in] */ dsoShowDialogType DlgType) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_EnableFileCommand( + /* [in] */ dsoFileCommandType Item, + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_EnableFileCommand( + /* [in] */ dsoFileCommandType Item, + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BorderStyle( + /* [in] */ dsoBorderStyle style) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_BorderStyle( + /* [retval][out] */ dsoBorderStyle *pstyle) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BorderColor( + /* [in] */ /* external definition not present */ OLE_COLOR clr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_BorderColor( + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_BackColor( + /* [in] */ /* external definition not present */ OLE_COLOR clr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_BackColor( + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ForeColor( + /* [in] */ /* external definition not present */ OLE_COLOR clr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_ForeColor( + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_TitlebarColor( + /* [in] */ /* external definition not present */ OLE_COLOR clr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_TitlebarColor( + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_TitlebarTextColor( + /* [in] */ /* external definition not present */ OLE_COLOR clr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_TitlebarTextColor( + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE ExecOleCommand( + /* [in] */ LONG OLECMDID, + /* [optional][in] */ VARIANT Options, + /* [optional][in] */ VARIANT *vInParam, + /* [optional][out][in] */ VARIANT *vInOutParam) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Menubar( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Menubar( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_HostName( + /* [in] */ BSTR bstr) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_HostName( + /* [retval][out] */ BSTR *pbstr) = 0; + + virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_DocumentFullName( + /* [retval][out] */ BSTR *pbstr) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PrintOut( + /* [optional][in] */ VARIANT PromptUser, + /* [optional][in] */ VARIANT PrinterName, + /* [optional][in] */ VARIANT Copies, + /* [optional][in] */ VARIANT FromPage, + /* [optional][in] */ VARIANT ToPage, + /* [optional][in] */ VARIANT OutputFile) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PrintPreview( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PrintPreviewExit( void) = 0; + + virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_IsReadOnly( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_IsDirty( + /* [retval][out] */ VARIANT_BOOL *pbool) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_LockServer( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_LockServer( + /* [retval][out] */ VARIANT_BOOL *pvbool) = 0; + + virtual /* [helpstring][nonbrowsable][id] */ HRESULT STDMETHODCALLTYPE GetDataObjectContent( + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [retval][out] */ VARIANT *pvResults) = 0; + + virtual /* [helpstring][nonbrowsable][id] */ HRESULT STDMETHODCALLTYPE SetDataObjectContent( + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [in] */ VARIANT DataByteArray) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_ActivationPolicy( + /* [in] */ enum dsoActivationPolicy lPolicy) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_ActivationPolicy( + /* [retval][out] */ enum dsoActivationPolicy *plPolicy) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_FrameHookPolicy( + /* [in] */ enum dsoFrameHookPolicy lPolicy) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_FrameHookPolicy( + /* [retval][out] */ enum dsoFrameHookPolicy *plPolicy) = 0; + + virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_MenuAccelerators( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_MenuAccelerators( + /* [retval][out] */ VARIANT_BOOL *pvbool) = 0; + + virtual /* [helpstring][id][nonbrowsable][propput] */ HRESULT STDMETHODCALLTYPE put_EventsEnabled( + /* [in] */ VARIANT_BOOL vbool) = 0; + + virtual /* [id][nonbrowsable][propget] */ HRESULT STDMETHODCALLTYPE get_EventsEnabled( + /* [retval][out] */ VARIANT_BOOL *pvbool) = 0; + + virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_DocumentName( + /* [retval][out] */ BSTR *pbstr) = 0; + + }; + +#else /* C style interface */ + + typedef struct _FramerControlVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + _FramerControl * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + _FramerControl * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + _FramerControl * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + _FramerControl * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + _FramerControl * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + _FramerControl * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + _FramerControl * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Activate )( + _FramerControl * This); + + /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ActiveDocument )( + _FramerControl * This, + /* [retval][out] */ IDispatch **ppdisp); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CreateNew )( + _FramerControl * This, + /* [in] */ BSTR ProgIdOrTemplate); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Open )( + _FramerControl * This, + /* [in] */ VARIANT Document, + /* [optional][in] */ VARIANT ReadOnly, + /* [optional][in] */ VARIANT ProgId, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Save )( + _FramerControl * This, + /* [optional][in] */ VARIANT SaveAsDocument, + /* [optional][in] */ VARIANT OverwriteExisting, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword); + + /* [hidden][id] */ HRESULT ( STDMETHODCALLTYPE *_PrintOutOld )( + _FramerControl * This, + /* [optional][in] */ VARIANT PromptToSelectPrinter); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Close )( + _FramerControl * This); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Caption )( + _FramerControl * This, + /* [in] */ BSTR bstr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Caption )( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Titlebar )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Titlebar )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Toolbars )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Toolbars )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][nonbrowsable][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ModalState )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][nonbrowsable][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ModalState )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *ShowDialog )( + _FramerControl * This, + /* [in] */ dsoShowDialogType DlgType); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_EnableFileCommand )( + _FramerControl * This, + /* [in] */ dsoFileCommandType Item, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_EnableFileCommand )( + _FramerControl * This, + /* [in] */ dsoFileCommandType Item, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BorderStyle )( + _FramerControl * This, + /* [in] */ dsoBorderStyle style); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BorderStyle )( + _FramerControl * This, + /* [retval][out] */ dsoBorderStyle *pstyle); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BorderColor )( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BorderColor )( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_BackColor )( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_BackColor )( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ForeColor )( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ForeColor )( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_TitlebarColor )( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_TitlebarColor )( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_TitlebarTextColor )( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_TitlebarTextColor )( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *ExecOleCommand )( + _FramerControl * This, + /* [in] */ LONG OLECMDID, + /* [optional][in] */ VARIANT Options, + /* [optional][in] */ VARIANT *vInParam, + /* [optional][out][in] */ VARIANT *vInOutParam); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Menubar )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Menubar )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_HostName )( + _FramerControl * This, + /* [in] */ BSTR bstr); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_HostName )( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_DocumentFullName )( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PrintOut )( + _FramerControl * This, + /* [optional][in] */ VARIANT PromptUser, + /* [optional][in] */ VARIANT PrinterName, + /* [optional][in] */ VARIANT Copies, + /* [optional][in] */ VARIANT FromPage, + /* [optional][in] */ VARIANT ToPage, + /* [optional][in] */ VARIANT OutputFile); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PrintPreview )( + _FramerControl * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PrintPreviewExit )( + _FramerControl * This); + + /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_IsReadOnly )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_IsDirty )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_LockServer )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_LockServer )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + /* [helpstring][nonbrowsable][id] */ HRESULT ( STDMETHODCALLTYPE *GetDataObjectContent )( + _FramerControl * This, + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [retval][out] */ VARIANT *pvResults); + + /* [helpstring][nonbrowsable][id] */ HRESULT ( STDMETHODCALLTYPE *SetDataObjectContent )( + _FramerControl * This, + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [in] */ VARIANT DataByteArray); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_ActivationPolicy )( + _FramerControl * This, + /* [in] */ enum dsoActivationPolicy lPolicy); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ActivationPolicy )( + _FramerControl * This, + /* [retval][out] */ enum dsoActivationPolicy *plPolicy); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_FrameHookPolicy )( + _FramerControl * This, + /* [in] */ enum dsoFrameHookPolicy lPolicy); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_FrameHookPolicy )( + _FramerControl * This, + /* [retval][out] */ enum dsoFrameHookPolicy *plPolicy); + + /* [helpstring][id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_MenuAccelerators )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_MenuAccelerators )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + /* [helpstring][id][nonbrowsable][propput] */ HRESULT ( STDMETHODCALLTYPE *put_EventsEnabled )( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + /* [id][nonbrowsable][propget] */ HRESULT ( STDMETHODCALLTYPE *get_EventsEnabled )( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + /* [helpstring][id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_DocumentName )( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + END_INTERFACE + } _FramerControlVtbl; + + interface _FramerControl + { + CONST_VTBL struct _FramerControlVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define _FramerControl_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define _FramerControl_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define _FramerControl_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define _FramerControl_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define _FramerControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define _FramerControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define _FramerControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + + +#define _FramerControl_Activate(This) \ + (This)->lpVtbl -> Activate(This) + +#define _FramerControl_get_ActiveDocument(This,ppdisp) \ + (This)->lpVtbl -> get_ActiveDocument(This,ppdisp) + +#define _FramerControl_CreateNew(This,ProgIdOrTemplate) \ + (This)->lpVtbl -> CreateNew(This,ProgIdOrTemplate) + +#define _FramerControl_Open(This,Document,ReadOnly,ProgId,WebUsername,WebPassword) \ + (This)->lpVtbl -> Open(This,Document,ReadOnly,ProgId,WebUsername,WebPassword) + +#define _FramerControl_Save(This,SaveAsDocument,OverwriteExisting,WebUsername,WebPassword) \ + (This)->lpVtbl -> Save(This,SaveAsDocument,OverwriteExisting,WebUsername,WebPassword) + +#define _FramerControl__PrintOutOld(This,PromptToSelectPrinter) \ + (This)->lpVtbl -> _PrintOutOld(This,PromptToSelectPrinter) + +#define _FramerControl_Close(This) \ + (This)->lpVtbl -> Close(This) + +#define _FramerControl_put_Caption(This,bstr) \ + (This)->lpVtbl -> put_Caption(This,bstr) + +#define _FramerControl_get_Caption(This,pbstr) \ + (This)->lpVtbl -> get_Caption(This,pbstr) + +#define _FramerControl_put_Titlebar(This,vbool) \ + (This)->lpVtbl -> put_Titlebar(This,vbool) + +#define _FramerControl_get_Titlebar(This,pbool) \ + (This)->lpVtbl -> get_Titlebar(This,pbool) + +#define _FramerControl_put_Toolbars(This,vbool) \ + (This)->lpVtbl -> put_Toolbars(This,vbool) + +#define _FramerControl_get_Toolbars(This,pbool) \ + (This)->lpVtbl -> get_Toolbars(This,pbool) + +#define _FramerControl_put_ModalState(This,vbool) \ + (This)->lpVtbl -> put_ModalState(This,vbool) + +#define _FramerControl_get_ModalState(This,pbool) \ + (This)->lpVtbl -> get_ModalState(This,pbool) + +#define _FramerControl_ShowDialog(This,DlgType) \ + (This)->lpVtbl -> ShowDialog(This,DlgType) + +#define _FramerControl_put_EnableFileCommand(This,Item,vbool) \ + (This)->lpVtbl -> put_EnableFileCommand(This,Item,vbool) + +#define _FramerControl_get_EnableFileCommand(This,Item,pbool) \ + (This)->lpVtbl -> get_EnableFileCommand(This,Item,pbool) + +#define _FramerControl_put_BorderStyle(This,style) \ + (This)->lpVtbl -> put_BorderStyle(This,style) + +#define _FramerControl_get_BorderStyle(This,pstyle) \ + (This)->lpVtbl -> get_BorderStyle(This,pstyle) + +#define _FramerControl_put_BorderColor(This,clr) \ + (This)->lpVtbl -> put_BorderColor(This,clr) + +#define _FramerControl_get_BorderColor(This,pclr) \ + (This)->lpVtbl -> get_BorderColor(This,pclr) + +#define _FramerControl_put_BackColor(This,clr) \ + (This)->lpVtbl -> put_BackColor(This,clr) + +#define _FramerControl_get_BackColor(This,pclr) \ + (This)->lpVtbl -> get_BackColor(This,pclr) + +#define _FramerControl_put_ForeColor(This,clr) \ + (This)->lpVtbl -> put_ForeColor(This,clr) + +#define _FramerControl_get_ForeColor(This,pclr) \ + (This)->lpVtbl -> get_ForeColor(This,pclr) + +#define _FramerControl_put_TitlebarColor(This,clr) \ + (This)->lpVtbl -> put_TitlebarColor(This,clr) + +#define _FramerControl_get_TitlebarColor(This,pclr) \ + (This)->lpVtbl -> get_TitlebarColor(This,pclr) + +#define _FramerControl_put_TitlebarTextColor(This,clr) \ + (This)->lpVtbl -> put_TitlebarTextColor(This,clr) + +#define _FramerControl_get_TitlebarTextColor(This,pclr) \ + (This)->lpVtbl -> get_TitlebarTextColor(This,pclr) + +#define _FramerControl_ExecOleCommand(This,OLECMDID,Options,vInParam,vInOutParam) \ + (This)->lpVtbl -> ExecOleCommand(This,OLECMDID,Options,vInParam,vInOutParam) + +#define _FramerControl_put_Menubar(This,vbool) \ + (This)->lpVtbl -> put_Menubar(This,vbool) + +#define _FramerControl_get_Menubar(This,pbool) \ + (This)->lpVtbl -> get_Menubar(This,pbool) + +#define _FramerControl_put_HostName(This,bstr) \ + (This)->lpVtbl -> put_HostName(This,bstr) + +#define _FramerControl_get_HostName(This,pbstr) \ + (This)->lpVtbl -> get_HostName(This,pbstr) + +#define _FramerControl_get_DocumentFullName(This,pbstr) \ + (This)->lpVtbl -> get_DocumentFullName(This,pbstr) + +#define _FramerControl_PrintOut(This,PromptUser,PrinterName,Copies,FromPage,ToPage,OutputFile) \ + (This)->lpVtbl -> PrintOut(This,PromptUser,PrinterName,Copies,FromPage,ToPage,OutputFile) + +#define _FramerControl_PrintPreview(This) \ + (This)->lpVtbl -> PrintPreview(This) + +#define _FramerControl_PrintPreviewExit(This) \ + (This)->lpVtbl -> PrintPreviewExit(This) + +#define _FramerControl_get_IsReadOnly(This,pbool) \ + (This)->lpVtbl -> get_IsReadOnly(This,pbool) + +#define _FramerControl_get_IsDirty(This,pbool) \ + (This)->lpVtbl -> get_IsDirty(This,pbool) + +#define _FramerControl_put_LockServer(This,vbool) \ + (This)->lpVtbl -> put_LockServer(This,vbool) + +#define _FramerControl_get_LockServer(This,pvbool) \ + (This)->lpVtbl -> get_LockServer(This,pvbool) + +#define _FramerControl_GetDataObjectContent(This,ClipFormatNameOrNumber,pvResults) \ + (This)->lpVtbl -> GetDataObjectContent(This,ClipFormatNameOrNumber,pvResults) + +#define _FramerControl_SetDataObjectContent(This,ClipFormatNameOrNumber,DataByteArray) \ + (This)->lpVtbl -> SetDataObjectContent(This,ClipFormatNameOrNumber,DataByteArray) + +#define _FramerControl_put_ActivationPolicy(This,lPolicy) \ + (This)->lpVtbl -> put_ActivationPolicy(This,lPolicy) + +#define _FramerControl_get_ActivationPolicy(This,plPolicy) \ + (This)->lpVtbl -> get_ActivationPolicy(This,plPolicy) + +#define _FramerControl_put_FrameHookPolicy(This,lPolicy) \ + (This)->lpVtbl -> put_FrameHookPolicy(This,lPolicy) + +#define _FramerControl_get_FrameHookPolicy(This,plPolicy) \ + (This)->lpVtbl -> get_FrameHookPolicy(This,plPolicy) + +#define _FramerControl_put_MenuAccelerators(This,vbool) \ + (This)->lpVtbl -> put_MenuAccelerators(This,vbool) + +#define _FramerControl_get_MenuAccelerators(This,pvbool) \ + (This)->lpVtbl -> get_MenuAccelerators(This,pvbool) + +#define _FramerControl_put_EventsEnabled(This,vbool) \ + (This)->lpVtbl -> put_EventsEnabled(This,vbool) + +#define _FramerControl_get_EventsEnabled(This,pvbool) \ + (This)->lpVtbl -> get_EventsEnabled(This,pvbool) + +#define _FramerControl_get_DocumentName(This,pbstr) \ + (This)->lpVtbl -> get_DocumentName(This,pbstr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_Activate_Proxy( + _FramerControl * This); + + +void __RPC_STUB _FramerControl_Activate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_ActiveDocument_Proxy( + _FramerControl * This, + /* [retval][out] */ IDispatch **ppdisp); + + +void __RPC_STUB _FramerControl_get_ActiveDocument_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_CreateNew_Proxy( + _FramerControl * This, + /* [in] */ BSTR ProgIdOrTemplate); + + +void __RPC_STUB _FramerControl_CreateNew_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_Open_Proxy( + _FramerControl * This, + /* [in] */ VARIANT Document, + /* [optional][in] */ VARIANT ReadOnly, + /* [optional][in] */ VARIANT ProgId, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword); + + +void __RPC_STUB _FramerControl_Open_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_Save_Proxy( + _FramerControl * This, + /* [optional][in] */ VARIANT SaveAsDocument, + /* [optional][in] */ VARIANT OverwriteExisting, + /* [optional][in] */ VARIANT WebUsername, + /* [optional][in] */ VARIANT WebPassword); + + +void __RPC_STUB _FramerControl_Save_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [hidden][id] */ HRESULT STDMETHODCALLTYPE _FramerControl__PrintOutOld_Proxy( + _FramerControl * This, + /* [optional][in] */ VARIANT PromptToSelectPrinter); + + +void __RPC_STUB _FramerControl__PrintOutOld_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_Close_Proxy( + _FramerControl * This); + + +void __RPC_STUB _FramerControl_Close_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_Caption_Proxy( + _FramerControl * This, + /* [in] */ BSTR bstr); + + +void __RPC_STUB _FramerControl_put_Caption_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_Caption_Proxy( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + +void __RPC_STUB _FramerControl_get_Caption_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_Titlebar_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_Titlebar_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_Titlebar_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_Titlebar_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_Toolbars_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_Toolbars_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_Toolbars_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_Toolbars_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][nonbrowsable][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_ModalState_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_ModalState_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][nonbrowsable][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_ModalState_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_ModalState_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_ShowDialog_Proxy( + _FramerControl * This, + /* [in] */ dsoShowDialogType DlgType); + + +void __RPC_STUB _FramerControl_ShowDialog_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_EnableFileCommand_Proxy( + _FramerControl * This, + /* [in] */ dsoFileCommandType Item, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_EnableFileCommand_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_EnableFileCommand_Proxy( + _FramerControl * This, + /* [in] */ dsoFileCommandType Item, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_EnableFileCommand_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_BorderStyle_Proxy( + _FramerControl * This, + /* [in] */ dsoBorderStyle style); + + +void __RPC_STUB _FramerControl_put_BorderStyle_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_BorderStyle_Proxy( + _FramerControl * This, + /* [retval][out] */ dsoBorderStyle *pstyle); + + +void __RPC_STUB _FramerControl_get_BorderStyle_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_BorderColor_Proxy( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + +void __RPC_STUB _FramerControl_put_BorderColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_BorderColor_Proxy( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + +void __RPC_STUB _FramerControl_get_BorderColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_BackColor_Proxy( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + +void __RPC_STUB _FramerControl_put_BackColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_BackColor_Proxy( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + +void __RPC_STUB _FramerControl_get_BackColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_ForeColor_Proxy( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + +void __RPC_STUB _FramerControl_put_ForeColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_ForeColor_Proxy( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + +void __RPC_STUB _FramerControl_get_ForeColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_TitlebarColor_Proxy( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + +void __RPC_STUB _FramerControl_put_TitlebarColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_TitlebarColor_Proxy( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + +void __RPC_STUB _FramerControl_get_TitlebarColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_TitlebarTextColor_Proxy( + _FramerControl * This, + /* [in] */ /* external definition not present */ OLE_COLOR clr); + + +void __RPC_STUB _FramerControl_put_TitlebarTextColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_TitlebarTextColor_Proxy( + _FramerControl * This, + /* [retval][out] */ /* external definition not present */ OLE_COLOR *pclr); + + +void __RPC_STUB _FramerControl_get_TitlebarTextColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_ExecOleCommand_Proxy( + _FramerControl * This, + /* [in] */ LONG OLECMDID, + /* [optional][in] */ VARIANT Options, + /* [optional][in] */ VARIANT *vInParam, + /* [optional][out][in] */ VARIANT *vInOutParam); + + +void __RPC_STUB _FramerControl_ExecOleCommand_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_Menubar_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_Menubar_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_Menubar_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_Menubar_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_HostName_Proxy( + _FramerControl * This, + /* [in] */ BSTR bstr); + + +void __RPC_STUB _FramerControl_put_HostName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_HostName_Proxy( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + +void __RPC_STUB _FramerControl_get_HostName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_DocumentFullName_Proxy( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + +void __RPC_STUB _FramerControl_get_DocumentFullName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_PrintOut_Proxy( + _FramerControl * This, + /* [optional][in] */ VARIANT PromptUser, + /* [optional][in] */ VARIANT PrinterName, + /* [optional][in] */ VARIANT Copies, + /* [optional][in] */ VARIANT FromPage, + /* [optional][in] */ VARIANT ToPage, + /* [optional][in] */ VARIANT OutputFile); + + +void __RPC_STUB _FramerControl_PrintOut_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_PrintPreview_Proxy( + _FramerControl * This); + + +void __RPC_STUB _FramerControl_PrintPreview_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_PrintPreviewExit_Proxy( + _FramerControl * This); + + +void __RPC_STUB _FramerControl_PrintPreviewExit_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_IsReadOnly_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_IsReadOnly_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_IsDirty_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pbool); + + +void __RPC_STUB _FramerControl_get_IsDirty_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_LockServer_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_LockServer_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_LockServer_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + +void __RPC_STUB _FramerControl_get_LockServer_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][nonbrowsable][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_GetDataObjectContent_Proxy( + _FramerControl * This, + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [retval][out] */ VARIANT *pvResults); + + +void __RPC_STUB _FramerControl_GetDataObjectContent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][nonbrowsable][id] */ HRESULT STDMETHODCALLTYPE _FramerControl_SetDataObjectContent_Proxy( + _FramerControl * This, + /* [in] */ VARIANT ClipFormatNameOrNumber, + /* [in] */ VARIANT DataByteArray); + + +void __RPC_STUB _FramerControl_SetDataObjectContent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_ActivationPolicy_Proxy( + _FramerControl * This, + /* [in] */ enum dsoActivationPolicy lPolicy); + + +void __RPC_STUB _FramerControl_put_ActivationPolicy_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_ActivationPolicy_Proxy( + _FramerControl * This, + /* [retval][out] */ enum dsoActivationPolicy *plPolicy); + + +void __RPC_STUB _FramerControl_get_ActivationPolicy_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_FrameHookPolicy_Proxy( + _FramerControl * This, + /* [in] */ enum dsoFrameHookPolicy lPolicy); + + +void __RPC_STUB _FramerControl_put_FrameHookPolicy_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_FrameHookPolicy_Proxy( + _FramerControl * This, + /* [retval][out] */ enum dsoFrameHookPolicy *plPolicy); + + +void __RPC_STUB _FramerControl_get_FrameHookPolicy_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_MenuAccelerators_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_MenuAccelerators_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_MenuAccelerators_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + +void __RPC_STUB _FramerControl_get_MenuAccelerators_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][nonbrowsable][propput] */ HRESULT STDMETHODCALLTYPE _FramerControl_put_EventsEnabled_Proxy( + _FramerControl * This, + /* [in] */ VARIANT_BOOL vbool); + + +void __RPC_STUB _FramerControl_put_EventsEnabled_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][nonbrowsable][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_EventsEnabled_Proxy( + _FramerControl * This, + /* [retval][out] */ VARIANT_BOOL *pvbool); + + +void __RPC_STUB _FramerControl_get_EventsEnabled_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE _FramerControl_get_DocumentName_Proxy( + _FramerControl * This, + /* [retval][out] */ BSTR *pbstr); + + +void __RPC_STUB _FramerControl_get_DocumentName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* ___FramerControl_INTERFACE_DEFINED__ */ + + +#ifndef ___DFramerCtlEvents_DISPINTERFACE_DEFINED__ +#define ___DFramerCtlEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface _DFramerCtlEvents */ +/* [hidden][uuid] */ + + +DEFINE_GUID(DIID__DFramerCtlEvents,0x00460185,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("00460185-9E5E-11d5-B7C8-B8269041DD57") + _DFramerCtlEvents : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct _DFramerCtlEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + _DFramerCtlEvents * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + _DFramerCtlEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + _DFramerCtlEvents * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + _DFramerCtlEvents * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + _DFramerCtlEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + _DFramerCtlEvents * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + _DFramerCtlEvents * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } _DFramerCtlEventsVtbl; + + interface _DFramerCtlEvents + { + CONST_VTBL struct _DFramerCtlEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define _DFramerCtlEvents_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define _DFramerCtlEvents_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define _DFramerCtlEvents_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define _DFramerCtlEvents_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define _DFramerCtlEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define _DFramerCtlEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define _DFramerCtlEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* ___DFramerCtlEvents_DISPINTERFACE_DEFINED__ */ + + +DEFINE_GUID(CLSID_FramerControl,0x00460182,0x9E5E,0x11d5,0xB7,0xC8,0xB8,0x26,0x90,0x41,0xDD,0x57); + +#ifdef __cplusplus + +class DECLSPEC_UUID("00460182-9E5E-11d5-B7C8-B8269041DD57") +FramerControl; +#endif +#endif /* __DSOFramer_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/PROMS/DSOFRAMER/Source2005/Res/dso.ico b/PROMS/DSOFRAMER/Source2005/Res/dso.ico new file mode 100644 index 0000000000000000000000000000000000000000..4dc671e54daab03fe953028cd176523b8b0461e1 GIT binary patch literal 318 zcmZutp$@_@6uf36-5ANHFbF0Q`~$x<4iB3uL+LLI}xTdw0Ei zZJHJ^9CckobuhqIN+@XvgB2MFiI<2SHA9$%%q50lpsEqmM2uPy9EwEW%AKl3&NN2q z+xetF@0@S7y<%SW>(0`b{j*DcC(m#*erCi^lUpVLqu literal 0 HcmV?d00001 diff --git a/PROMS/DSOFRAMER/Source2005/Res/dsoframer.rc b/PROMS/DSOFRAMER/Source2005/Res/dsoframer.rc new file mode 100644 index 00000000..ef7828e4 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/Res/dsoframer.rc @@ -0,0 +1,154 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" +#include "..\version.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// TYPELIB +// +#ifdef _DEBUG +IDR_TYPELIB TYPELIB DISCARDABLE "..\\Debug\\dsoframer.tlb" +#else +IDR_TYPELIB TYPELIB DISCARDABLE "..\\Release\\dsoframer.tlb" +#endif // _DEBUG + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION DSOFRAMERCTL_VERSION_MAJOR,DSOFRAMERCTL_VERSION_MINOR,DSOFRAMERCTL_VERSION_BUILD,0 + PRODUCTVERSION DSOFRAMERCTL_VERSION_MAJOR,DSOFRAMERCTL_VERSION_MINOR,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "UNSUPPORTED BY MICROSOFT\0" + VALUE "CompanyName", "Your Company\0" + VALUE "FileDescription", "Your Company's Office Framer Control Sample\0" + VALUE "FileVersion", DSOFRAMERCTL_VERSIONSTRFULL "\0" + VALUE "OriginalFilename", "dsoframer.ocx\0" + VALUE "ProductName", "DSOFRAMER\0" + VALUE "ProductVersion", DSOFRAMERCTL_VERSIONSTR "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TOOLBOX BITMAP DISCARDABLE "toolbox.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SMALLOFFDOC ICON DISCARDABLE "dso.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + RES_DSO_E_UNKNOWN "An unknown problem has occurred." + RES_DSO_E_INVALIDPROGID "The ProgID/Template could not be found or is not associated with a COM server." + RES_DSO_E_INVALIDSERVER "The associated COM server does not support ActiveX Document embedding." + RES_DSO_E_COMMANDNOTSUPPORTED + "The command is not supported by the document server." + RES_DSO_E_DOCUMENTREADONLY + "Unable to perform action because document was opened in read-only mode." + RES_DSO_E_REQUIRESMSDAIPP + "The Microsoft Internet Publishing Provider is not installed, so the URL document cannot be open for write access." + RES_DSO_E_DOCUMENTNOTOPEN "No document is open to perform the operation requested." + RES_DSO_E_INMODALSTATE "Cannot access document when in modal condition." + RES_DSO_E_NOTBEENSAVED "Cannot Save file without a file path." + RES_DSO_E_FRAMEHOOKFAILED "Unable to set frame hook for the parent window." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PROMS/DSOFRAMER/Source2005/Res/resource.h b/PROMS/DSOFRAMER/Source2005/Res/resource.h new file mode 100644 index 00000000..b9060358 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/Res/resource.h @@ -0,0 +1,39 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dsoframer.rc +// +#define IDR_TYPELIB 1 +#define RES_DSO_E_UNKNOWN 1 +#define RES_DSO_E_INVALIDPROGID 2 +#define RES_DSO_E_INVALIDSERVER 3 +#define RES_DSO_E_COMMANDNOTSUPPORTED 4 +#define RES_DSO_E_DOCUMENTREADONLY 5 +#define RES_DSO_E_REQUIRESMSDAIPP 6 +#define RES_DSO_E_DOCUMENTNOTOPEN 7 +#define RES_DSO_E_INMODALSTATE 8 +#define RES_DSO_E_NOTBEENSAVED 9 +#define RES_DSO_E_FRAMEHOOKFAILED 10 +#define IDB_TOOLBOX 102 +#define IDB_TOOLBAR 103 +#define IDR_BINDMENU 104 +#define IDI_SMALLOFFDOC 105 +#define MNU_NEW 40001 +#define MNU_OPEN 40002 +#define MNU_CLOSE 40003 +#define MNU_SAVE 40004 +#define MNU_SAVEAS 40005 +#define MNU_PGSETUP 40006 +#define MNU_PRINT 40007 +#define MNU_PROPS 40008 +#define MNU_PRINTPV 40009 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40011 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/PROMS/DSOFRAMER/Source2005/Res/toolbox.bmp b/PROMS/DSOFRAMER/Source2005/Res/toolbox.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e0e7d4d3c3ed7ce9d3d3070ac46eb1ccb9419b89 GIT binary patch literal 334 zcmZvWEpo#!5QU$WOr=bWQd(fyKa=4+Ulid1LlG0F;^r?tcS zqjA-50D#S`y z%W@2vrfF>3*5MfvLXfJi9X^b5Ysm2{0s9avIcLY=HY$JFNZ9R{{u2Zi&^;F;-g}^e zGu$%__9;qo#z4HBOIw!?%!gY_5lQpRo2GGp-&gHVY31H4&$Ik%mgQ{s5YqJyH*!

+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.css b/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.css new file mode 100644 index 00000000..fae98af0 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.css @@ -0,0 +1,207 @@ +BODY +{ + BACKGROUND-COLOR: white; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px +} +P +{ + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 70%; + LINE-HEIGHT: 12pt; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 10px +} +.note +{ + BACKGROUND-COLOR: #ffffff; + COLOR: #336699; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px; + PADDING-RIGHT: 10px +} +.infotable +{ + BACKGROUND-COLOR: #f0f0e0; + BORDER-BOTTOM: #ffffff 0px solid; + BORDER-COLLAPSE: collapse; + BORDER-LEFT: #ffffff 0px solid; + BORDER-RIGHT: #ffffff 0px solid; + BORDER-TOP: #ffffff 0px solid; + FONT-SIZE: 70%; + MARGIN-LEFT: 10px +} +.issuetable +{ + BACKGROUND-COLOR: #ffffe8; + BORDER-COLLAPSE: collapse; + COLOR: #000000; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 10px; + MARGIN-LEFT: 13px; + MARGIN-TOP: 0px +} +.issuetitle +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px; + COLOR: #003366; + FONT-WEIGHT: normal +} +.header +{ + BACKGROUND-COLOR: #cecf9c; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + COLOR: #000000; + FONT-WEIGHT: bold +} +.issuehdr +{ + BACKGROUND-COLOR: #E0EBF5; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + COLOR: #000000; + FONT-WEIGHT: normal +} +.issuenone +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: 0px; + BORDER-LEFT: 0px; + BORDER-RIGHT: 0px; + BORDER-TOP: 0px; + COLOR: #000000; + FONT-WEIGHT: normal +} +.content +{ + BACKGROUND-COLOR: #e7e7ce; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + PADDING-LEFT: 3px +} +.issuecontent +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + PADDING-LEFT: 3px +} +A:link +{ + COLOR: #cc6633; + TEXT-DECORATION: underline +} +A:visited +{ + COLOR: #cc6633; +} +A:active +{ + COLOR: #cc6633; +} +A:hover +{ + COLOR: #cc3300; + TEXT-DECORATION: underline +} +H1 +{ + BACKGROUND-COLOR: #003366; + BORDER-BOTTOM: #336699 6px solid; + COLOR: #ffffff; + FONT-SIZE: 130%; + FONT-WEIGHT: normal; + MARGIN: 0em 0em 0em -20px; + PADDING-BOTTOM: 8px; + PADDING-LEFT: 30px; + PADDING-TOP: 16px +} +H2 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 3px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px; + PADDING-LEFT: 0px +} +H3 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: -5px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px +} +H4 +{ + COLOR: #000000; + FONT-SIZE: 70%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 0px; + MARGIN-TOP: 15px; + PADDING-BOTTOM: 0px +} +UL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +OL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +LI +{ + LIST-STYLE: square; + MARGIN-LEFT: 0px +} +.expandable +{ + CURSOR: hand +} +.expanded +{ + color: black +} +.collapsed +{ + DISPLAY: none +} +.foot +{ +BACKGROUND-COLOR: #ffffff; +BORDER-BOTTOM: #cecf9c 1px solid; +BORDER-TOP: #cecf9c 2px solid +} +.settings +{ +MARGIN-LEFT: 25PX; +} +.help +{ +TEXT-ALIGN: right; +margin-right: 10px; +} diff --git a/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.xslt b/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.xslt new file mode 100644 index 00000000..83f4304a --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport.xslt @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Solution: + Project: + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + src + + + + + + + + + + + + +
FilenameStatusErrorsWarnings
+ javascript:document.images[''].click()src + + + + Converted + + + + Converted + +
+ + files + + + 1 file + + + Converted:
+ Not converted +
+ + + + + + : + + + + + + + + + Conversion Report + <xsl:if test="Properties/Property[@Name='LogNumber']"> + <xsl:value-of select="Properties/Property[@Name='LogNumber']/@Value"/> + </xsl:if> + + + + +

Conversion Report -

+ +

+ Time of Conversion:
+

+ + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + +
+ Conversion Settings +

+ + +
+ diff --git a/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport_Minus.gif b/PROMS/DSOFRAMER/Source2005/_UpgradeReport_Files/UpgradeReport_Minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..17751cb2fd5c284dfe984adc4c769982f73a0a66 GIT binary patch literal 69 zcmZ?wbhEHb23ky~TYXIqG7FYlP literal 0 HcmV?d00001 diff --git a/PROMS/DSOFRAMER/Source2005/classfactory.cpp b/PROMS/DSOFRAMER/Source2005/classfactory.cpp new file mode 100644 index 00000000..ad99d1a0 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/classfactory.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * CLASSFACTORY.CPP + * + * CDsoFramerClassFactory: The Class Factroy for the control. + * + * Copyright ©1999-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" + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory - IClassFactory Implementation +// +// This is a fairly simple CF. We don't provide support for licensing +// in this sample because it is just a sample. If licensing is important +// you should change the class to support IClassFactory2. +// + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory::QueryInterface +// +STDMETHODIMP CDsoFramerClassFactory::QueryInterface(REFIID riid, void** ppv) +{ + ODS("CDsoFramerClassFactory::QueryInterface\n"); + CHECK_NULL_RETURN(ppv, E_POINTER); + + if ((IID_IUnknown == riid) || (IID_IClassFactory == riid)) + { + SAFE_SET_INTERFACE(*ppv, (IClassFactory*)this); + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory::AddRef +// +STDMETHODIMP_(ULONG) CDsoFramerClassFactory::AddRef(void) +{ + TRACE1("CDsoFramerClassFactory::AddRef - %d\n", m_cRef+1); + return ++m_cRef; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory::Release +// +STDMETHODIMP_(ULONG) CDsoFramerClassFactory::Release(void) +{ + TRACE1("CDsoFramerClassFactory::Release - %d\n", m_cRef-1); + if (0 != --m_cRef) return m_cRef; + + ODS("CDsoFramerClassFactory delete\n"); + InterlockedDecrement((LPLONG)&v_cLocks); + delete this; + return 0; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory::CreateInstance +// +// Creates an instance of our control. +// +STDMETHODIMP CDsoFramerClassFactory::CreateInstance(LPUNKNOWN punk, REFIID riid, void** ppv) +{ + HRESULT hr; + CDsoFramerControl* pocx; + IUnknown* pnkInternal; + + ODS("CDsoFramerClassFactory::CreateInstance\n"); + CHECK_NULL_RETURN(ppv, E_POINTER); *ppv = NULL; + + // Aggregation requires you ask for (internal) IUnknown + if ((punk) && (riid != IID_IUnknown)) + return E_INVALIDARG; + + // Create a new instance of the control... + pocx = new CDsoFramerControl(punk); + CHECK_NULL_RETURN(pocx, E_OUTOFMEMORY); + + // Grab the internal IUnknown to use for the QI (you don't agg in CF:CreateInstance)... + pnkInternal = (IUnknown*)&(pocx->m_xInternalUnknown); + + // Initialize the control (windows, etc.) and QI for requested interface... + if (SUCCEEDED(hr = pocx->InitializeNewInstance()) && + SUCCEEDED(hr = pnkInternal->QueryInterface(riid, ppv))) + { + InterlockedIncrement((LPLONG)&v_cLocks); // on success, bump up the lock count... + } + else {delete pocx; *ppv = NULL;} // else cleanup the object + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerClassFactory::LockServer +// +// Keeps the server loaded in memory. +// +STDMETHODIMP CDsoFramerClassFactory::LockServer(BOOL fLock) +{ + TRACE1("CDsoFramerClassFactory::LockServer - %d\n", fLock); + if (fLock) InterlockedIncrement((LPLONG)&v_cLocks); + else InterlockedDecrement((LPLONG)&v_cLocks); + return S_OK; +} + diff --git a/PROMS/DSOFRAMER/Source2005/dsofauto.cpp b/PROMS/DSOFRAMER/Source2005/dsofauto.cpp new file mode 100644 index 00000000..a7268452 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsofauto.cpp @@ -0,0 +1,1321 @@ +/*************************************************************************** + * DSOFAUTO.CPP + * + * CDsoFramerControl: Automation interface for Binder Control + * + * Copyright ©1999-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" + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl - _FramerControl Implementation +// + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::Activate +// +// Activate the current embedded document (i.e, forward focus). +// +STDMETHODIMP CDsoFramerControl::Activate() +{ + HRESULT hr; + ODS("CDsoFramerControl::Activate\n"); + + if (m_fInControlActivate) + return S_FALSE; + + // Don't allow recursion of this function or we could get stuck in + // loop trying to constantly grab focus. + m_fInControlActivate = TRUE; + + // All we need to do is grab focus. This will tell the host to + // UI activate our OCX, set focus to our window, and set this control + // as the active component with the hook manager. + hr = UIActivate(TRUE); + + // Invalidate windows to update painting... + if (SUCCEEDED(hr)) + InvalidateAllChildWindows(m_hwnd); + + m_fInControlActivate = FALSE; + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::get_ActiveDocument +// +// Returns the automation object currently embedded. +// +// Since we only support a single instance at a time, it might have been +// better to call this property Object or simply Document, but VB reserves +// the first name for use by the control extender, and IE reserves the second +// in its extender, so we decided on the "Office sounding" name. ;-) +// +STDMETHODIMP CDsoFramerControl::get_ActiveDocument(IDispatch** ppdisp) +{ + HRESULT hr = DSO_E_DOCUMENTNOTOPEN; + IUnknown* punk; + + ODS("CDsoFramerControl::get_ActiveDocument\n"); + CHECK_NULL_RETURN(ppdisp, E_POINTER); *ppdisp = NULL; + + // Get IDispatch from open document object. + if ((m_pDocObjFrame) && (punk = (IUnknown*)(m_pDocObjFrame->GetActiveObject()))) + { + // Cannot access object if in print preview.. + if (m_pDocObjFrame->InPrintPreview()) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // Ask ip active object for IDispatch interface. If it is not supported on + // active object interface, try to get it from OLE object iface... + if (FAILED(hr = punk->QueryInterface(IID_IDispatch, (void**)ppdisp)) && + (punk = (IUnknown*)(m_pDocObjFrame->GetOleObject()))) + { + hr = punk->QueryInterface(IID_IDispatch, (void**)ppdisp); + } + ASSERT(SUCCEEDED(hr)); + } + + return ProvideErrorInfo(hr); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::ExecOleCommand +// +// Allows caller to pass commands to embedded object via IOleCommandTarget and +// gives access to a few extra commands to extend functionality for certain object +// types (not all objects may support all commands). +// +STDMETHODIMP CDsoFramerControl::ExecOleCommand(LONG OLECMDID, VARIANT Options, VARIANT* vInParam, VARIANT* vInOutParam) +{ + HRESULT hr = E_INVALIDARG; + DWORD dwOptions = (DWORD)LONG_FROM_VARIANT(Options, 0); + + TRACE1("CDsoFramerControl::DoOleCommand(%d)\n", OLECMDID); + + // Cannot access object if in modal condition... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // Handle some custom commands that don't need doc open to call... + switch (OLECMDID) + { + case OLECMDID_RESETFRAMEHOOK: + { + LONG lhwnd = (DWORD)LONG_FROM_VARIANT(*vInParam, 0); + return ResetFrameHook((HWND)lhwnd); + } + case OLECMDID_LOCKSERVER: + if (BOOL_FROM_VARIANT(Options, TRUE) == FALSE) + return put_LockServer(VARIANT_FALSE); + } + + // The rest require a doc object loaded first... + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + switch (OLECMDID) + { + case OLECMDID_GETDATAFORMAT: + // If requesting special data get... + hr = m_pDocObjFrame->HrGetDataFromObject(vInParam, vInOutParam); + break; + + case OLECMDID_SETDATAFORMAT: + // If requesting special data set... + hr = m_pDocObjFrame->HrSetDataInObject(vInParam, vInOutParam, BOOL_FROM_VARIANT(Options, TRUE)); + break; + + case OLECMDID_LOCKSERVER: // optional lock on server... + if (BOOL_FROM_VARIANT(Options, FALSE)) + hr = put_LockServer(VARIANT_TRUE); + break; + + case OLECMDID_NOTIFYACTIVE: + if (vInParam) // Force notify server that it should be active... + { + m_pDocObjFrame->OnNotifyAppActivate(BOOL_FROM_VARIANT(*vInParam, FALSE), 0); + hr = S_OK; + } + break; + + default: + // Do normal IOleCommandTarget call on object... + + // If options was not passed as long, but as bool, we expect the caller meant to + // specify if user should be prompted or not, so update the options to allow the + // assuption to still work as expected (this is for compatibility)... + if ((dwOptions == 0) && ((DsoPVarFromPVarRef(&Options)->vt & 0xFF) == VT_BOOL)) + dwOptions = (BOOL_FROM_VARIANT(Options, FALSE) ? OLECMDEXECOPT_PROMPTUSER : OLECMDEXECOPT_DODEFAULT); + + // Ask object server to do the command... + hr = m_pDocObjFrame->DoOleCommand(OLECMDID, dwOptions, vInParam, vInOutParam); + } + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::CreateNew +// +// Creates a new document object based on the passed in ProgID or Template. +// ProgID should map to the "document" object, such as "Word.Document", +// "Excel.Sheet", "PowerPoint.Slide", etc. A Template name should be full +// path to the file, whether local, UNC, or HTTP path. No relative paths. +// +STDMETHODIMP CDsoFramerControl::CreateNew(BSTR ProgIdOrTemplate) +{ + HRESULT hr; + CLSID clsid; + HCURSOR hCur; + IStorage *pstgTemplate = NULL; + LPWSTR pwszTempFile = NULL; + + TRACE1("CDsoFramerControl::CreateNew(%S)\n", ProgIdOrTemplate); + + // Check the string to make sure a valid item is passed... + if (!(ProgIdOrTemplate) || (SysStringLen(ProgIdOrTemplate) < 4)) + return E_INVALIDARG; + +// Cannot create object if we are not activate yet, or if in modal condition... + if (!(m_fInPlaceActive) || (m_fModalState)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // Make sure any open document is closed first... + if ((m_pDocObjFrame) && FAILED(hr = Close())) + return hr; + + // Make sure we are the active component for this process... + if (FAILED(hr = Activate())) return hr; + + // Let's make a doc frame for ourselves... + m_pDocObjFrame = CDsoDocObject::CreateInstance((IDsoDocObjectSite*)&m_xDsoDocObjectSite); + if (!(m_pDocObjFrame)) return E_OUTOFMEMORY; + + // Start a wait operation to notify user... + hCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); + m_fInDocumentLoad = TRUE; + + // If the string passed looks like a URL, it is a web template. We need + // to download it to temp location and use for new object... + if (LooksLikeHTTP(ProgIdOrTemplate) && + GetTempPathForURLDownload(ProgIdOrTemplate, &pwszTempFile)) + { + // Ask URLMON to download the file... + if (FAILED(hr = URLDownloadFile(NULL, ProgIdOrTemplate, pwszTempFile))) + { + DsoMemFree(pwszTempFile); pwszTempFile = NULL; + goto error_out; + } + + // If that worked, switch out the name of the template to local file... + ProgIdOrTemplate = SysAllocString(pwszTempFile); + } + + // If the string is path to file, then it must be a template. It must be + // a storage file with CLSID associated with it, like any Office templates + // (.dot,.xlt,.pot,.vst,etc.), and path must be fully qualified... + if (LooksLikeUNC(ProgIdOrTemplate) || LooksLikeLocalFile(ProgIdOrTemplate)) + { + if ((hr = StgIsStorageFile(ProgIdOrTemplate)) != S_OK) + { + hr = (FAILED(hr) ? hr : STG_E_NOTFILEBASEDSTORAGE); + goto error_out; + } + + // Open the template for read access only... + hr = StgOpenStorage(ProgIdOrTemplate, NULL, + (STGM_READ | STGM_SHARE_DENY_WRITE | STGM_TRANSACTED), + NULL, 0, &pstgTemplate); + GOTO_ON_FAILURE(hr, error_out); + + // We get the CLSID from the template... + hr = ReadClassStg(pstgTemplate, &clsid); + if (FAILED(hr) || (clsid == GUID_NULL)) + { + hr = (FAILED(hr) ? hr : STG_E_OLDFORMAT); + goto error_out; + } + // Otherwise the string passed is assumed a ProgID... + } + else if (FAILED(CLSIDFromProgID(ProgIdOrTemplate, &clsid))) + { + hr = DSO_E_INVALIDPROGID; + goto error_out; + } + + // If we are here, we must have a valid CLSID for the object... + ASSERT(clsid != GUID_NULL); + + // If we had delayed the frame hook, we should set it up now... + if (!(m_pHookManager) && FDelayFrameHookSet()) + { + m_pHookManager = CDsoFrameHookManager::RegisterFramerControl(m_hwndParent, m_hwnd); + if (!m_pHookManager) {hr = DSO_E_FRAMEHOOKFAILED; goto error_out;} + } + + SEH_TRY + + // If we are loading a template, init the storage before the create... + if (pstgTemplate) + { + hr = m_pDocObjFrame->CreateDocObject(pstgTemplate); + } + else + { + // Create a new doc object and IP activate... + hr = m_pDocObjFrame->CreateDocObject(clsid); + } + + // If the call worked, we can activate it... + if (SUCCEEDED(hr)) + { + EnableDropFile(FALSE); + + if (!m_fShowToolbars) + m_pDocObjFrame->OnNotifyChangeToolState(FALSE); + + hr = m_pDocObjFrame->IPActivateView(); + } + + SEH_EXCEPT(hr) + + // Force a close if an error occurred... + if (FAILED(hr)) + { +error_out: + m_fFreezeEvents = TRUE; + Close(); + m_fFreezeEvents = FALSE; + hr = ProvideErrorInfo(hr); + } + else + { + + // Fire the OnDocumentOpened event... + VARIANT rgargs[2]; + rgargs[0].vt = VT_DISPATCH; get_ActiveDocument(&(rgargs[0].pdispVal)); + rgargs[1].vt = VT_BSTR; rgargs[1].bstrVal = NULL; + + RaiseAutomationEvent(DSOF_DISPID_DOCOPEN, 2, rgargs); + VariantClear(&rgargs[0]); + + // Ensure we are active control... + Activate(); + + // Redraw the caption as needed... + RedrawCaption(); + } + + m_fInDocumentLoad = FALSE; + SetCursor(hCur); + + SAFE_RELEASE_INTERFACE(pstgTemplate); + + // Delete the temp file used in the URL download (if any)... + if (pwszTempFile) + { + FPerformShellOp(FO_DELETE, pwszTempFile, NULL); + DsoMemFree(pwszTempFile); + SysFreeString(ProgIdOrTemplate); + } + + return hr; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::Open +// +// Creates a document object based on a file or URL. This simulates an +// "open", but preserves the correct OLE embedding activation required +// by ActiveX Documents. Opening directly from a file is not recommended. +// We keep a lock on the original file (unless opened read-only) so the +// user cannot tell we don't have the file "open". +// +// The alternate ProgID allows us to open a file that is not associated +// with an DocObject server (like *.asp) with the server specified. Also +// the username/password are for web access (if Document is a URL). +// +STDMETHODIMP CDsoFramerControl::Open(VARIANT Document, VARIANT ReadOnly, VARIANT ProgId, VARIANT WebUsername, VARIANT WebPassword) +{ + HRESULT hr; + LPWSTR pwszDocument = LPWSTR_FROM_VARIANT(Document); + LPWSTR pwszAltProgId = LPWSTR_FROM_VARIANT(ProgId); + LPWSTR pwszUserName = LPWSTR_FROM_VARIANT(WebUsername); + LPWSTR pwszPassword = LPWSTR_FROM_VARIANT(WebPassword); + BOOL fOpenReadOnly = BOOL_FROM_VARIANT(ReadOnly, FALSE); + CLSID clsidAlt = GUID_NULL; + HCURSOR hCur; + IUnknown* punk = NULL; + + BIND_OPTS bopts = {sizeof(BIND_OPTS), BIND_MAYBOTHERUSER, 0, 10000}; + + TRACE1("CDsoFramerControl::Open(%S)\n", pwszDocument); + + // We must have either a string (file path or URL) or an object to open from... + if (!(pwszDocument) || (*pwszDocument == L'\0')) + { + if (!(pwszDocument) && ((punk = PUNK_FROM_VARIANT(Document)) == NULL)) + return E_INVALIDARG; + } + + // If the user passed the ProgId, find the alternative CLSID for server... + if ((pwszAltProgId) && FAILED(CLSIDFromProgID(pwszAltProgId, &clsidAlt))) + return E_INVALIDARG; + +// Cannot create object if we are not activate yet, or if in modal condition... + if (!(m_fInPlaceActive) || (m_fModalState)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // OK. If here, all the parameters look good and it is time to try and open + // the document object. Start by closing any existing document first... + if ((m_pDocObjFrame) && FAILED(hr = Close())) + return hr; + + // Make sure we are the active component for this process... + if (FAILED(hr = Activate())) return hr; + + // Let's make a doc frame for ourselves... + if (!(m_pDocObjFrame = CDsoDocObject::CreateInstance((IDsoDocObjectSite*)&m_xDsoDocObjectSite))) + return E_OUTOFMEMORY; + + // If we had delayed the frame hook, we should set it up now... + if (!(m_pHookManager) && FDelayFrameHookSet()) + { + m_pHookManager = CDsoFrameHookManager::RegisterFramerControl(m_hwndParent, m_hwnd); + if (!m_pHookManager) return ProvideErrorInfo(DSO_E_FRAMEHOOKFAILED); + } + + // Start a wait operation to notify user... + hCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); + m_fInDocumentLoad = TRUE; + + // Setup the bind options based on read-only flag.... + bopts.grfMode = (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | (fOpenReadOnly ? STGM_READ : STGM_READWRITE)); + + SEH_TRY + + // Normally user gives a string that is path to file... + if (pwszDocument) + { + // Check if we are opening from a URL, and load that way... + if (LooksLikeHTTP(pwszDocument)) + { + hr = m_pDocObjFrame->CreateFromURL(pwszDocument, clsidAlt, &bopts, pwszUserName, pwszPassword); + } + // Otherwise, check if it is a local file and open that... + else if (FFileExists(pwszDocument)) + { + hr = m_pDocObjFrame->CreateFromFile(pwszDocument, clsidAlt, &bopts); + } + else hr = E_INVALIDARG; + } + else if (punk) + { + // If we have an object to load from, try loading it direct... + hr = m_pDocObjFrame->CreateFromRunningObject(punk, NULL, &bopts); + } + else hr = E_UNEXPECTED; // Unhandled load type?? + + // If successful, we can activate the object... + if (SUCCEEDED(hr)) + { + EnableDropFile(FALSE); + + if (!m_fShowToolbars) + m_pDocObjFrame->OnNotifyChangeToolState(FALSE); + + hr = m_pDocObjFrame->IPActivateView(); + } + + SEH_EXCEPT(hr) + + // Force a close if an error occurred... + if (FAILED(hr)) + { + m_fFreezeEvents = TRUE; + Close(); + m_fFreezeEvents = FALSE; + hr = ProvideErrorInfo(hr); + } + else + { + // Fire the OnDocumentOpened event... + VARIANT rgargs[2]; + rgargs[0].vt = VT_DISPATCH; get_ActiveDocument(&(rgargs[0].pdispVal)); + rgargs[1].vt = VT_BSTR; rgargs[1].bstrVal = SysAllocString(pwszDocument); + + RaiseAutomationEvent(DSOF_DISPID_DOCOPEN, 2, rgargs); + VariantClear(&rgargs[1]); + VariantClear(&rgargs[0]); + + // Ensure we are active control... + Activate(); + + // Redraw the caption as needed... + RedrawCaption(); + } + + m_fInDocumentLoad = FALSE; + SetCursor(hCur); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::Save +// +// Saves the current object. The optional SaveAs paramter lets the same +// function act as a SaveAs method. +// +STDMETHODIMP CDsoFramerControl::Save(VARIANT SaveAsDocument, VARIANT OverwriteExisting, VARIANT WebUsername, VARIANT WebPassword) +{ + HCURSOR hCur; + HRESULT hr = S_FALSE; + LPWSTR pwszDocument = LPWSTR_FROM_VARIANT(SaveAsDocument); + LPWSTR pwszUserName = LPWSTR_FROM_VARIANT(WebUsername); + LPWSTR pwszPassword = LPWSTR_FROM_VARIANT(WebPassword); + BOOL fOverwrite = BOOL_FROM_VARIANT(OverwriteExisting, FALSE); + + TRACE1("CDsoFramerControl::Save(%S)\n", pwszDocument); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // Cannot access object if in modal condition... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // If user passed a value for SaveAs, it must be a valid string... + if (!(PARAM_IS_MISSING(&SaveAsDocument)) && + ((pwszDocument == NULL) || (*pwszDocument == L'\0'))) + return E_INVALIDARG; + + // Raise the BeforeDocumentSaved event to host... + if (m_dispEvents) + { + VARIANT rgargs[3]; VARIANT_BOOL vtboolCancel = VARIANT_FALSE; + rgargs[2].vt = VT_DISPATCH; get_ActiveDocument(&(rgargs[2].pdispVal)); + rgargs[1].vt = VT_BSTR; rgargs[1].bstrVal = SysAllocString(pwszDocument); + rgargs[0].vt = (VT_BOOL | VT_BYREF); rgargs[0].pboolVal = &vtboolCancel; + + RaiseAutomationEvent(DSOF_DISPID_BDOCSAVE, 3, rgargs); + VariantClear(&rgargs[2]); + VariantClear(&rgargs[1]); + + // Setting Cancel param will abort the save... + if (vtboolCancel != VARIANT_FALSE) + return E_ABORT; + } + + // Now do the save... + hCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); + + SEH_TRY + + // Determine if they want to save to a URL... + if ((pwszDocument) && LooksLikeHTTP(pwszDocument)) + { + hr = m_pDocObjFrame->SaveToURL(pwszDocument, fOverwrite, pwszUserName, pwszPassword); + } + else if (pwszDocument) + { + // Save to file (local or UNC)... + hr = m_pDocObjFrame->SaveToFile(pwszDocument, fOverwrite); + } + else + { + // Save back to open location... + hr = m_pDocObjFrame->Save(); + } + + SEH_EXCEPT(hr) + + // If save was successful... + if (SUCCEEDED(hr)) + { + // Raise the SaveComplete event to host... + if (m_dispEvents) + { + VARIANT rgargs[3]; + rgargs[2].vt = VT_DISPATCH; get_ActiveDocument(&(rgargs[2].pdispVal)); + rgargs[1].vt = VT_BSTR; rgargs[1].bstrVal = SysAllocString(m_pDocObjFrame->GetSourceDocName()); + rgargs[0].vt = VT_BSTR; rgargs[0].bstrVal = SysAllocString(m_pDocObjFrame->GetSourceName()); + RaiseAutomationEvent(DSOF_DISPID_SAVECOMPLETE, 3, rgargs); + VariantClear(&rgargs[2]); + VariantClear(&rgargs[1]); + VariantClear(&rgargs[0]); + } + + // Redraw the caption as needed... + RedrawCaption(); + } + + SetCursor(hCur); + return ProvideErrorInfo(hr); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::Close +// +// Closes the current object. +// +STDMETHODIMP CDsoFramerControl::Close() +{ + ODS("CDsoFramerControl::Close\n"); + + CDsoDocObject* pdframe = m_pDocObjFrame; + if (pdframe) + { + // Fire the BeforeDocumentClosed event to give host chance to cancel... + VARIANT rgargs[2]; VARIANT_BOOL vtboolCancel = VARIANT_FALSE; + rgargs[1].vt = VT_DISPATCH; get_ActiveDocument(&(rgargs[1].pdispVal)); + rgargs[0].vt = (VT_BOOL | VT_BYREF); rgargs[0].pboolVal = &vtboolCancel; + + // Setting Cancel param should abort the close... + RaiseAutomationEvent(DSOF_DISPID_BDOCCLOSE, 2, rgargs); + VariantClear(&rgargs[1]); + + if (vtboolCancel != VARIANT_FALSE) + return E_ABORT; + + // If not canceled, clear the member variable then call close on doc frame... + m_pDocObjFrame = NULL; + + SEH_TRY + pdframe->Close(); + SEH_EXCEPT_NULL + delete pdframe; + + // Notify host that item is now closed... + RaiseAutomationEvent(DSOF_DISPID_DOCCLOSE, 0, NULL); + } + + // Redraw the caption as needed... + RedrawCaption(); + EnableDropFile(TRUE); + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_Caption/get_Caption) +// +// Allows you to set a custom cation for the titlebar. +// +STDMETHODIMP CDsoFramerControl::put_Caption(BSTR bstr) +{ + // Free exsiting caption (if any) and save new one (always dirties control)... + SAFE_FREEBSTR(m_bstrCustomCaption); + + // Set the new one (if provided)... + if ((bstr) && (SysStringLen(bstr) > 0)) + m_bstrCustomCaption = SysAllocString(bstr); + + ViewChanged(); + m_fDirty = TRUE; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_Caption(BSTR* pbstr) +{ + if (pbstr) *pbstr = (m_bstrCustomCaption ? + SysAllocString(m_bstrCustomCaption) : + SysAllocString(L"Office Framer Control")); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_Titlebar/get_Titlebar) +// +// True/False. Should we display the titlebar or not? +// +STDMETHODIMP CDsoFramerControl::put_Titlebar(VARIANT_BOOL vbool) +{ + TRACE1("CDsoFramerControl::put_Titlebar(%d)\n", vbool); + + if (m_fModalState) // Cannot access object if in modal condition... + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + if (m_fShowTitlebar != (WORD)(BOOL)vbool) + { + m_fShowTitlebar = (BOOL)vbool; + m_fDirty = TRUE; + OnResize(); + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_Titlebar(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_Titlebar\n"); + if (pbool) *pbool = (m_fShowTitlebar ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_Toolbars/get_Toolbars) +// +// True/False. Should we display toolbars or not? +// +STDMETHODIMP CDsoFramerControl::put_Toolbars(VARIANT_BOOL vbool) +{ + TRACE1("CDsoFramerControl::put_Toolbars(%d)\n", vbool); + + // If the control is in modal state, we can't do things that + // will call the server directly, like toggle toolbars... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + if (m_fShowToolbars != (WORD)(BOOL)vbool) + { + m_fShowToolbars = (BOOL)vbool; + m_fDirty = TRUE; + + if (m_pDocObjFrame) + m_pDocObjFrame->OnNotifyChangeToolState(m_fShowToolbars); + + ViewChanged(); + OnResize(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_Toolbars(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_Toolbars\n"); + if (pbool) *pbool = (m_fShowToolbars ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_ModalState/get_ModalState) +// +// True/False. Disables the active object (if any) thereby setting it +// up to behave "modal". Any time a dialog or other blocking window +// on the same thread is called, the developer should set this to True +// to let the IP object know it should stay modal in the background. +// Set it back to False when the dialog is removed. +// +// Technically, this should be a counter to allow for nested modal states. +// However, we thought that might be confusing to some VB/Web developers +// and since this is only a sample, made it a Boolean property. +// +STDMETHODIMP CDsoFramerControl::put_ModalState(VARIANT_BOOL vbool) +{ + TRACE1("CDsoFramerControl::put_ModalState(%d)\n", vbool); + + // you can't force modal state change unless active... + if ((m_fNoInteractive) || (!m_fComponentActive)) + return ProvideErrorInfo(E_ACCESSDENIED); + + if (m_fModalState != (WORD)(BOOL)vbool) + UpdateModalState((vbool != VARIANT_FALSE), TRUE); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_ModalState(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_ModalState\n"); + if (pbool) *pbool = ((m_fModalState) ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::ShowDialog +// +// Uses IOleCommandTarget to get the embedded object to display one of +// these standard dialogs for the user. +// +STDMETHODIMP CDsoFramerControl::ShowDialog(dsoShowDialogType DlgType) +{ + HRESULT hr = E_ACCESSDENIED; + + TRACE1("CDsoFramerControl::ShowDialog(%d)\n", DlgType); + if ((DlgType < dsoFileNew) || (DlgType > dsoDialogProperties)) + return E_INVALIDARG; + + // Cannot access object if in modal condition... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // The first three dialog types we handle... + if (DlgType < dsoDialogSaveCopy) + { + hr = DoDialogAction(DlgType); + } + // The others are provided by the server via IOleCommandTarget... + else if (m_pDocObjFrame) + { + DWORD dwOleCmd; + switch (DlgType) + { + case dsoDialogSaveCopy: dwOleCmd = OLECMDID_SAVECOPYAS; break; + case dsoDialogPageSetup: dwOleCmd = OLECMDID_PAGESETUP; break; + case dsoDialogProperties: dwOleCmd = OLECMDID_PROPERTIES; break; + default: dwOleCmd = OLECMDID_PRINT; + } + hr = m_pDocObjFrame->DoOleCommand(dwOleCmd, OLECMDEXECOPT_PROMPTUSER, NULL, NULL); + } + + return ProvideErrorInfo(hr); +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_EnableFileCommand/get_EnableFileCommand) +// +// True/False. This allows the developer to disable certain menu/toolbar +// items that are considered "file-level" -- New, Save, Print, etc. +// +// We use the Item parameter to set a bit flag which is used when +// displaying the menu to enable/disable the item. The OnFileCommand +// event will not fire for disabled commands. +// +STDMETHODIMP CDsoFramerControl::put_EnableFileCommand(dsoFileCommandType Item, VARIANT_BOOL vbool) +{ + TRACE2("CDsoFramerControl::put_EnableFileCommand(%d, %d)\n", Item, vbool); + + if ((Item < dsoFileNew) || (Item > dsoFilePrintPreview)) + return E_INVALIDARG; + + // You cannot access menu when in a modal condition... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // We keep bit flags for menu state. Just set the bit and a update + // the embedded object as needed. User will see change next time menu is shown... + UINT code = (1 << Item); + if (vbool == 0) m_wFileMenuFlags &= ~(code); + else m_wFileMenuFlags |= code; + + if (m_pDocObjFrame) // This should update toolbar icon (if server supports it) + m_pDocObjFrame->DoOleCommand(OLECMDID_UPDATECOMMANDS, 0, NULL, NULL); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_EnableFileCommand(dsoFileCommandType Item, VARIANT_BOOL* pbool) +{ + TRACE1("CDsoFramerControl::get_EnableFileCommand(%d)\n", Item); + + if ((Item < dsoFileNew) || (Item > dsoFilePrintPreview)) + return E_INVALIDARG; + + UINT code = (1 << Item); + if (pbool) *pbool = ((m_wFileMenuFlags & code) ? VARIANT_TRUE : VARIANT_FALSE); + + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_BorderStyle/get_BorderStyle) +// +// Change the border style for the control. +// +STDMETHODIMP CDsoFramerControl::put_BorderStyle(dsoBorderStyle style) +{ + ODS("CDsoFramerControl::put_BorderStyle\n"); + + if ((style < dsoBorderNone) || (style > dsoBorder3DThin)) + return E_INVALIDARG; + + if (m_fModalState) // Cannot access object if in modal condition... + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + if (m_fBorderStyle != (DWORD)style) + { + m_fBorderStyle = style; + m_fDirty = TRUE; + OnResize(); + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_BorderStyle(dsoBorderStyle* pstyle) +{ + ODS("CDsoFramerControl::get_BorderStyle\n"); + if (pstyle) *pstyle = (dsoBorderStyle)m_fBorderStyle; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// Control Color Properties... +// +// +STDMETHODIMP CDsoFramerControl::put_BorderColor(OLE_COLOR clr) +{ + ODS("CDsoFramerControl::put_BorderColor\n"); + if (m_clrBorderColor != clr) + { + m_clrBorderColor = clr; + m_fDirty = TRUE; + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_BorderColor(OLE_COLOR* pclr) +{if (pclr) *pclr = m_clrBorderColor; return S_OK;} + +STDMETHODIMP CDsoFramerControl::put_BackColor(OLE_COLOR clr) +{ + ODS("CDsoFramerControl::put_BackColor\n"); + if (m_clrBackColor != clr) + { + m_clrBackColor = clr; + m_fDirty = TRUE; + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_BackColor(OLE_COLOR* pclr) +{if (pclr) *pclr = m_clrBackColor; return S_OK;} + +STDMETHODIMP CDsoFramerControl::put_ForeColor(OLE_COLOR clr) +{ + ODS("CDsoFramerControl::put_ForeColor\n"); + if (m_clrForeColor != clr) + { + m_clrForeColor = clr; + m_fDirty = TRUE; + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_ForeColor(OLE_COLOR* pclr) +{if (pclr) *pclr = m_clrForeColor; return S_OK;} + +STDMETHODIMP CDsoFramerControl::put_TitlebarColor(OLE_COLOR clr) +{ + ODS("CDsoFramerControl::put_TitlebarColor\n"); + if (m_clrTBarColor != clr) + { + m_clrTBarColor = clr; + m_fDirty = TRUE; + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_TitlebarColor(OLE_COLOR* pclr) +{if (pclr) *pclr = m_clrTBarColor; return S_OK;} + + +STDMETHODIMP CDsoFramerControl::put_TitlebarTextColor(OLE_COLOR clr) +{ + ODS("CDsoFramerControl::put_TitlebarTextColor\n"); + if (m_clrTBarTextColor != clr) + { + m_clrTBarTextColor = clr; + m_fDirty = TRUE; + ViewChanged(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_TitlebarTextColor(OLE_COLOR* pclr) +{if (pclr) *pclr = m_clrTBarTextColor; return S_OK;} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_Menubar/get_Menubar) +// +// True/False. Should we display menu bar? +// +STDMETHODIMP CDsoFramerControl::put_Menubar(VARIANT_BOOL vbool) +{ + TRACE1("CDsoFramerControl::put_Menubar(%d)\n", vbool); + + // If the control is in modal state, we can't do things that + // will call the server directly, like toggle menu bar... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + if (m_fShowMenuBar != (WORD)(BOOL)vbool) + { + m_fShowMenuBar = (BOOL)vbool; + m_fDirty = TRUE; + ViewChanged(); + OnResize(); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_Menubar(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_Menubar\n"); + if (pbool) *pbool = (m_fShowMenuBar ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::(put_HostName/get_HostName) +// +// String setting used for host application name (used in embedding) +// +STDMETHODIMP CDsoFramerControl::put_HostName(BSTR bstr) +{ + TRACE1("CDsoFramerControl::put_HostName(%S)\n", bstr); + SAFE_FREESTRING(m_pwszHostName); + + if ((bstr) && (SysStringLen(bstr) > 0)) + m_pwszHostName = DsoCopyString(bstr); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_HostName(BSTR* pbstr) +{ + ODS("CDsoFramerControl::get_HostName\n"); + if (pbstr) + *pbstr = SysAllocString((m_pwszHostName ? m_pwszHostName : L"DsoFramerControl")); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::get_DocumentFullName +// +// Gets FullName of embedded source file (where default save will save to). +// +STDMETHODIMP CDsoFramerControl::get_DocumentFullName(BSTR* pbstr) +{ + ODS("CDsoFramerControl::get_DocumentFullName\n"); + CHECK_NULL_RETURN(pbstr, E_POINTER); + // Ask doc object site for the source name... + *pbstr = (m_pDocObjFrame) ? SysAllocString(m_pDocObjFrame->GetSourceName()) : NULL; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::get_DocumentName +// +// Gets just the file name of embedded source file. +// +STDMETHODIMP CDsoFramerControl::get_DocumentName(BSTR* pbstr) +{ + ODS("CDsoFramerControl::get_DocumentName\n"); + CHECK_NULL_RETURN(pbstr, E_POINTER); + // Ask doc object site for the source doc name... + *pbstr = (m_pDocObjFrame) ? SysAllocString(m_pDocObjFrame->GetSourceDocName()) : NULL; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::get_IsReadOnly +// +// Returns if file open read-only. +// +STDMETHODIMP CDsoFramerControl::get_IsReadOnly(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_IsReadOnly\n"); + CHECK_NULL_RETURN(pbool, E_POINTER); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + *pbool = (m_pDocObjFrame->IsReadOnly() ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::get_IsDirty +// +// Returns TRUE if doc object says it has changes. +// +STDMETHODIMP CDsoFramerControl::get_IsDirty(VARIANT_BOOL* pbool) +{ + ODS("CDsoFramerControl::get_IsDirty\n"); + CHECK_NULL_RETURN(pbool, E_POINTER); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + *pbool = (m_pDocObjFrame->IsDirty() ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::LockServer +// +// Allows host to temporarily lock the current document server running, +// so that when closing and reopening files using the same server doesn't +// suffer startup/shutdown penelty of the server going away between calls. +// +STDMETHODIMP CDsoFramerControl::put_LockServer(VARIANT_BOOL vbool) +{ + BOOL fLock = (vbool != VARIANT_FALSE); + TRACE1("CDsoFramerControl::put_LockServer(%d)\n", (DWORD)vbool); + + // We must have a server open to set a lock... + if ((fLock) && (m_pDocObjFrame == NULL)) + return ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN); + + return SetTempServerLock(fLock); +} + +STDMETHODIMP CDsoFramerControl::get_LockServer(VARIANT_BOOL* pvbool) +{ + ODS("CDsoFramerControl::get_LockServer\n"); + CHECK_NULL_RETURN(pvbool, E_POINTER); + *pvbool = (VARIANT_BOOL)((m_pServerLock) ? VARIANT_TRUE : VARIANT_FALSE); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::GetDataObjectContent +// +// Allows caller to get data from document in clipboard format but without +// using the clipboard (instead it uses IDataObject). The server has to +// support the request format to return the data. Data is returned as byte array. +// +// NOTE: This only gets the document body content, not the entire document. If +// you want the entire document, use the Save method with temp filename to save to. +// +STDMETHODIMP CDsoFramerControl::GetDataObjectContent(VARIANT ClipFormatNameOrNumber, VARIANT *pvResults) +{ + ODS("CDsoFramerControl::GetDataObjectContent()\n"); + CHECK_NULL_RETURN(pvResults, E_POINTER); VariantInit(pvResults); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // If the control is in modal state, we can't do anything... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + return m_pDocObjFrame->HrGetDataFromObject(&ClipFormatNameOrNumber, pvResults); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::GetDataObjectContent +// +// Allows caller to set data into the document body (similar to a paste, but +// without using the clipboard). You must supply the format name or number and +// the data in a byte array format. +// +STDMETHODIMP CDsoFramerControl::SetDataObjectContent(VARIANT ClipFormatNameOrNumber, VARIANT DataByteArray) +{ + ODS("CDsoFramerControl::SetDataObjectContent()\n"); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // If the control is in modal state, we can't do anything... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + return m_pDocObjFrame->HrSetDataInObject(&ClipFormatNameOrNumber, &DataByteArray, TRUE); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::put_ActivationPolicy +// +// Allows caller to set policy for how activation changes affect the embedded +// object. This is actually a bit flag, so user can OR settings. +// +STDMETHODIMP CDsoFramerControl::put_ActivationPolicy(dsoActivationPolicy lPolicy) +{ + TRACE1("CDsoFramerControl::put_ActivationPolicy(%d)\n", lPolicy); + if (m_pDocObjFrame) return E_ACCESSDENIED; + + if ((lPolicy < dsoDefaultBehavior) || (lPolicy > 0x0F)) + return E_INVALIDARG; + + m_lActivationPolicy = lPolicy; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_ActivationPolicy(dsoActivationPolicy *plPolicy) +{if (plPolicy) *plPolicy = (dsoActivationPolicy)m_lActivationPolicy; return S_OK;} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::put_FrameHookPolicy +// +// Allows caller to set policy for the frame hook. +// +STDMETHODIMP CDsoFramerControl::put_FrameHookPolicy(dsoFrameHookPolicy lPolicy) +{ + HRESULT hr = E_ACCESSDENIED; + TRACE1("CDsoFramerControl::put_FrameHookPolicy(%d)\n", lPolicy); + + switch (lPolicy) + { + case dsoDisableHook: + if (m_pHookManager) break; + // else fallthrough... + + case dsoNormalBehavior: + case dsoSetOnFirstOpen: + m_lHookPolicy = lPolicy; hr = S_OK; + break; + + case dsoResetNow: + if (!FRunningInDesignMode()) + hr = ResetFrameHook(0); + break; + + default: + hr = E_INVALIDARG; + } + + return hr; +} + +STDMETHODIMP CDsoFramerControl::get_FrameHookPolicy(dsoFrameHookPolicy *plPolicy) +{if (plPolicy) *plPolicy = (dsoFrameHookPolicy)m_lHookPolicy; return S_OK;} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::put_MenuAccelerators +// +// Sets flag to determine if control should try to handle keys for menu +// shortcuts when the menus are displayed. +// +STDMETHODIMP CDsoFramerControl::put_MenuAccelerators(VARIANT_BOOL vbool) +{ + ODS("CDsoFramerControl::put_MenuAccelerators\n"); + m_fDisableMenuAccel = (vbool == VARIANT_FALSE); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_MenuAccelerators(VARIANT_BOOL* pvbool) +{ + ODS("CDsoFramerControl::get_MenuAccelerators\n"); + CHECK_NULL_RETURN(pvbool, E_POINTER); + *pvbool = (m_fDisableMenuAccel ? VARIANT_FALSE : VARIANT_TRUE); + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::put_EventsEnabled +// +// Sets flag to determine if events are frozen or not. +// +STDMETHODIMP CDsoFramerControl::put_EventsEnabled(VARIANT_BOOL vbool) +{ + ODS("CDsoFramerControl::put_EventsEnabled\n"); + m_fFreezeEvents = (vbool == VARIANT_FALSE); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::get_EventsEnabled(VARIANT_BOOL* pvbool) +{ + ODS("CDsoFramerControl::get_EventsEnabled\n"); + CHECK_NULL_RETURN(pvbool, E_POINTER); + *pvbool = (m_fFreezeEvents ? VARIANT_FALSE : VARIANT_TRUE); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl - IDispatch Implementation +// + +//////////////////////////////////////////////////////////////////////// +// Control's IDispatch Functions +// +// These are largely standard and just forward calls to the functions +// above. The only interesting thing here is the "hack" in Invoke to +// tell VB/IE that the control is always "Enabled". +// +STDMETHODIMP CDsoFramerControl::GetTypeInfoCount(UINT* pctinfo) +{if (pctinfo) *pctinfo = 1; return S_OK;} + +STDMETHODIMP CDsoFramerControl::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) +{ + HRESULT hr = S_OK; + + ODS("CDsoFramerControl::GetTypeInfo\n"); + CHECK_NULL_RETURN(ppTInfo, E_POINTER); *ppTInfo = NULL; + + // We only support default interface late bound... + CHECK_NULL_RETURN((iTInfo == 0), DISP_E_BADINDEX); + + // Load the type lib if we don't have the information already. + if (NULL == m_ptiDispType) + { + hr = DsoGetTypeInfoEx(LIBID_DSOFramer, 0, DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, + v_hModule, IID__FramerControl, &m_ptiDispType); + } + + // Return interface with ref count (if we have it, otherwise error)... + SAFE_SET_INTERFACE(*ppTInfo, m_ptiDispType); + return hr; +} + +STDMETHODIMP CDsoFramerControl::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) +{ + HRESULT hr; + ITypeInfo *pti; + + ODS("CDsoFramerControl::GetIDsOfNames\n"); + CHECK_NULL_RETURN((IID_NULL == riid), DISP_E_UNKNOWNINTERFACE); + + // Get the type info for this dispinterface... + hr = GetTypeInfo(0, lcid, &pti); + RETURN_ON_FAILURE(hr); + + // Ask OLE to translate the name... + hr = pti->GetIDsOfNames(rgszNames, cNames, rgDispId); + pti->Release(); + return hr; +} + +STDMETHODIMP CDsoFramerControl::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ + HRESULT hr; + ITypeInfo *pti;; + + // VB loves to check for this property (Enabled) during design time. + // We don't implement it for this control, but we'll return TRUE to + // to let it know if is enabled and don't bother with call to ITypeInfo... + if ((dispIdMember == DISPID_ENABLED) && (wFlags & DISPATCH_PROPERTYGET)) + { + if (pVarResult) // We are always enabled... + {pVarResult->vt = VT_BOOL; pVarResult->boolVal = VARIANT_TRUE; } + return S_OK; + } + + TRACE1("CDsoFramerControl::Invoke(dispid = %d)\n", dispIdMember); + CHECK_NULL_RETURN((IID_NULL == riid), DISP_E_UNKNOWNINTERFACE); + + // Get the type info for this dispinterface... + hr = GetTypeInfo(0, lcid, &pti); + RETURN_ON_FAILURE(hr); + + // Store pExcepInfo (to fill-in disp excepinfo if error occurs)... + m_pDispExcep = pExcepInfo; + + // Call the method using TypeInfo (OLE will call v-table method for us)... + hr = pti->Invoke((PVOID)this, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + m_pDispExcep = NULL; // Don't need this anymore... + pti->Release(); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::ProvideErrorInfo +// +// Fills in custom error information (as needed). +// +STDMETHODIMP CDsoFramerControl::ProvideErrorInfo(HRESULT hres) +{ + // Don't need to do anything on success... + if ((hres == S_OK) || SUCCEEDED(hres)) + return hres; + + // Fill in the error information as needed... + return DsoReportError(hres, NULL, m_pDispExcep); +} diff --git a/PROMS/DSOFRAMER/Source2005/dsofcontrol.cpp b/PROMS/DSOFRAMER/Source2005/dsofcontrol.cpp new file mode 100644 index 00000000..17bd4094 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsofcontrol.cpp @@ -0,0 +1,4313 @@ +/*************************************************************************** + * DSOFCONTROL.CPP + * + * CDsoFramerControl: The Base Control + * + * Copyright ©1999-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" + + +//////////////////////////////////////////////////////////////////////// +// 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); +} + +CDsoFramerControl::~CDsoFramerControl(void) +{ + ODS("CDsoFramerControl::~CDsoFramerControl\n"); + + 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); +} + +//////////////////////////////////////////////////////////////////////// +// 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 class info has not yet been registered, need to do that now... + 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); + } + + // create the window with the extent size and position... + 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); + + 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); + + + // if we were asked to UIActivate, and we currently are not, do so! + if ((lVerb == OLEIVERB_PRIMARY || + lVerb == OLEIVERB_UIACTIVATE) && (!m_fUIActive)) + { + // It is not typical to UI activate ocx during design mode, but if it happens and host + // has not customized the hook policy, let's switch to delay set so that we don't + // accidently hook the VS/VB IDE designer window. + if (FRunningInDesignMode() && (m_lHookPolicy == 0)) + m_lHookPolicy = dsoSetOnFirstOpen; + + // if we don't have it already, hook top-level parent window when we go + // ui active; this is needed to track WM_ACTIVATEAPP and other critical messages + // needed by ole docobjs.... + if ((m_pHookManager == NULL) && FUseFrameHook() && !FDelayFrameHookSet()) + { + m_pHookManager = CDsoFrameHookManager::RegisterFramerControl(m_hwndParent, m_hwnd); + if (!m_pHookManager) + { + ODS(" ** UIActivate FAILED (DSO_E_FRAMEHOOKFAILED)\n"); + return ProvideErrorInfo(DSO_E_FRAMEHOOKFAILED); + } + } + + // Now UI activate the control for the host. This implies taking focus and + // setting up the control as the current active object... + hr = UIActivate(FALSE); + + } + + // Setup drop file support (but only when there is no current embedding)... + if (m_pDocObjFrame == NULL) + EnableDropFile(TRUE); + + 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... + TRACE1(" *** InPlaceActivate FAILED (hr=0x%X) ***\n", hr); + m_fInPlaceActive = FALSE; + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::UIActivate +// +// Make sure our control is UI Active and set as ActiveObject for host. +// +STDMETHODIMP CDsoFramerControl::UIActivate(BOOL fForceUIActive) +{ + HRESULT hr = S_FALSE; + TRACE1("CDsoFramerControl::UIActivate(fForceUIActive=%d)\n", fForceUIActive); + + // We can't do anything if we aren't inplace active and visible! + if (!(m_fInPlaceActive) || !(m_fInPlaceVisible)) + return E_UNEXPECTED; + + // If we are not already UI active or are being asked to force it, do the call + if ((!(m_fUIActive) || (fForceUIActive)) && (m_pInPlaceSite)) + { + m_fUIActive = TRUE; + + // inform the container of our intent + hr = m_pInPlaceSite->OnUIActivate(); + + if (SUCCEEDED(hr) || (fForceUIActive)) + { + // take the focus [which is what UI Activation is all about !] + 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); + + // Ensure docobj component state is active as well... + if (!m_fComponentActive) + { + // Tell manager we are the active component now... + if (m_pHookManager) m_pHookManager->SetActiveComponent(m_hwnd); + else OnComponentActivationChange(TRUE); + } + } + } + + 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::OnDraw +// +// Drawing is largely limited to border and titlebar, except when in +// design mode. We don't do any background painting to avoid paint problems +// when we have an ui active DocObject. It should do any painting for us. +// +STDMETHODIMP_(void) CDsoFramerControl::OnDraw(DWORD dvAspect, HDC hdcDraw, LPRECT prcBounds, LPRECT prcWBounds, HDC hicTargetDev, BOOL fOptimize) +{ + COLORREF clrBackground, clrForeground, clrBorder, clrT; + HBRUSH hbshBackground, hbshBorder; + HFONT hfontText, hfontOld; + HPALETTE hpal, hpalOld; + LOGFONT lfText = {-11,0,0,0,FW_NORMAL,0,0,0,0,0,0,0,FF_SWISS, "Tahoma"}; + RECT rc, rcT; + int iTxtMode, iMapMode; + + // Copy out the bounding rect... + CopyRect(&rc, prcBounds); + + // On 256 color systems, we may need a palette... + if ((GetDeviceCaps(hdcDraw, RASTERCAPS) & RC_PALETTE) && + ((GetDeviceCaps(hdcDraw, BITSPIXEL) * GetDeviceCaps(hdcDraw, PLANES)) == 8)) + { + hpal = CreateHalftonePalette(hdcDraw); + hpalOld = SelectPalette(hdcDraw, hpal, TRUE); + RealizePalette(hdcDraw); + } + else hpal = NULL; + + // Translate the OLE_COLOR values to a matching COLORREF in palette... + OleTranslateColor(m_clrBackColor, hpal, &clrBackground); + OleTranslateColor(m_clrForeColor, hpal, &clrForeground); + OleTranslateColor(m_clrBorderColor, hpal, &clrBorder); + + // Create the resources we need for drawing and setting up the DC... + hbshBackground = CreateSolidBrush(clrBackground); + hbshBorder = CreateSolidBrush(clrBorder); + + hfontText = CreateFontIndirect(&lfText); + hfontOld = (HFONT)SelectObject(hdcDraw, hfontText); + iTxtMode = SetBkMode(hdcDraw, TRANSPARENT); + iMapMode = SetMapMode(hdcDraw, MM_TEXT); + + // Based on the choosen border style, draw the border and deflate the + // drawing rect accordingly... + switch (m_fBorderStyle) + { + case 1: + { + HBRUSH hbT = GetSysColorBrush(COLOR_BTNFACE); + FrameRect(hdcDraw, &rc, hbshBorder); InflateRect(&rc, -1, -1); + FrameRect(hdcDraw, &rc, hbT); InflateRect(&rc, -1, -1); + FrameRect(hdcDraw, &rc, hbshBorder); InflateRect(&rc, -1, -1); + } + break; + + case 2: + DrawEdge(hdcDraw, &rc, EDGE_SUNKEN, BF_RECT); + InflateRect(&rc, -2, -2); + break; + + case 3: + DrawEdge(hdcDraw, &rc, BDR_SUNKENOUTER, BF_RECT); + InflateRect(&rc, -1, -1); + break; + + //default: no border... + } + + // Draw the titlebar if visible... + if (m_fShowTitlebar) + { + COLORREF clrTitlebar, clrTitlebarText; + HBRUSH hbshTitlebar, hbshT; + LPWSTR pwszDCaption = NULL; + LPWSTR pwszROCaption = NULL; + LPWSTR pwszCaption = ((m_bstrCustomCaption) ? + m_bstrCustomCaption : L"KB311765: Office Framer Control Sample"); + + CopyRect(&rcT, &rc); + rcT.bottom = rcT.top + 21; + + OleTranslateColor(m_clrTBarColor, hpal, &clrTitlebar); + OleTranslateColor(m_clrTBarTextColor, hpal, &clrTitlebarText); + + hbshTitlebar = CreateSolidBrush(clrTitlebar); + FillRect(hdcDraw, &rcT, hbshTitlebar); + + DrawIconEx(hdcDraw, rcT.left+2, rcT.top+2, v_icoOffDocIcon, 16, 16, 0, NULL, DI_NORMAL); + + clrT = SetTextColor(hdcDraw, clrTitlebarText); + rcT.left += 22; + + // If we have an embedded object, check to see if it is an open doc and + // append the name to the titlebar. Also append "Read-Only" string if file + // was open in read-only mode. + if (m_pDocObjFrame) + { + if ((pwszDCaption = (LPWSTR)m_pDocObjFrame->GetSourceDocName()) != NULL) + { + LPCWSTR pwszCat[2] = {L" - ", pwszDCaption}; + pwszDCaption = DsoCopyStringCatEx(pwszCaption, 2, pwszCat); + pwszCaption = pwszDCaption; + } + + if (m_pDocObjFrame->IsReadOnly()) + { + pwszROCaption = DsoCopyStringCat(pwszCaption, L" (Read-Only)"); + pwszCaption = pwszROCaption; + } + } + + // Draw out the custom titlebar caption in Unicode if on NT/XP OS, since + // a custom caption may have non-ANSI characters... + FDrawText(hdcDraw, pwszCaption, &rcT, DT_VCENTER|DT_SINGLELINE); + + // Cleanup temp strings... + if (pwszROCaption) DsoMemFree(pwszROCaption); + if (pwszDCaption) DsoMemFree(pwszDCaption); + + CopyRect(&rcT, &rc); + rcT.bottom = rcT.top + 21; + rcT.top = rcT.bottom - 1; + + hbshT = GetSysColorBrush(COLOR_BTNSHADOW); + FillRect(hdcDraw, &rcT, hbshT); + + SetTextColor(hdcDraw, clrT); + DeleteObject(hbshTitlebar); + } + + // Draw menu bar if visible... + if (m_fShowMenuBar) + { + GetSizeRectForMenuBar(prcBounds, &rcT); + FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNFACE)); + + // When in design mode, we just draw placeholder... + if (FRunningInDesignMode()) + { + clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW)); + DrawText(hdcDraw, "Menu Bar", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + SetTextColor(hdcDraw, clrT); + } + else + { + HMENU hCurMenu; + CHAR szbuf[DSO_MAX_MENUNAME_LENGTH]; + UINT i, yTop, yBottom, xLast, xNext; + SIZE ptMItem; RECT rcMDraw; + BOOL fSelected; + DWORD dwDTFlags = (DT_SINGLELINE | DT_VCENTER); + + // Get the current menu and setup to draw the number of items in it... + if (hCurMenu = GetActivePopupMenu()) + { + yTop = rcT.top + 3; yBottom = rcT.bottom - 3; xLast = rcT.left + 2; + if (hCurMenu == m_hmenuFilePopup) + { m_cMenuItems = 1; } + else + { + if ((m_cMenuItems = (USHORT)GetMenuItemCount(hCurMenu)) > DSO_MAX_MENUITEMS) + m_cMenuItems = DSO_MAX_MENUITEMS; + } + + // If we are on an OS that supports it, hide the prefix when we are not UI active + // or if the host has disabled menu accelerators for this instance... + if (v_fWindows2KPlus && (!(m_fUIActive) || (m_fDisableMenuAccel))) + dwDTFlags |= DT_HIDEPREFIX; + + // For each item in the menu, get the menu name and draw it to the + // menu bar. We need to calculate the size taken by the font used and + // store the information in an array used by mouse move handler to + // determine which menu item the user is over... + for (i = 0; i < m_cMenuItems; i++) + { + szbuf[0] = '\0'; + if (i == 0) lstrcpy(szbuf, "&File"); + else GetMenuString(hCurMenu, i, szbuf, DSO_MAX_MENUNAME_LENGTH, MF_BYPOSITION); + + GetTextExtentPoint32(hdcDraw, szbuf, lstrlen(szbuf), &ptMItem); + xNext = (xLast + ptMItem.cx + 2); + if (xNext > (UINT)(rcT.right)){ m_cMenuItems = (USHORT)i; break; } + SetRect(&rcMDraw, xLast, yTop, xNext, yBottom); + + if (fOptimize) + CopyRect(&m_rgrcMenuItems[i], &rcMDraw); + + // If user is over this particular item, we draw it as selected... + fSelected = ((m_wSelMenuItem) && (i == (UINT)(m_wSelMenuItem - 1))); + if (fSelected) + { + FillRect(hdcDraw, &rcMDraw, GetSysColorBrush(COLOR_HIGHLIGHT)); + clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + rcMDraw.left += 4; + DrawText(hdcDraw, szbuf, lstrlen(szbuf), &rcMDraw, dwDTFlags); + + if (fSelected) + SetTextColor(hdcDraw, clrT); + + xLast = xNext + 2; + } + } + } + rcT.top = rcT.bottom - 1; // Draw a line to separate menu from workspace... + FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNSHADOW)); + } + + + // Fill in the background (but only if there is no active object)... + if (!m_pDocObjFrame) + { + GetSizeRectForDocument(prcBounds, &rcT); + FillRect(hdcDraw, &rcT, hbshBackground); + + // When in design mode, we do a little extra stuff to help the + // developer visualize some of the control settings (toolbars, + // foreground color, etc.)... + if (FRunningInDesignMode()) + { + if (m_fShowToolbars) + { + rcT.bottom = rcT.top + 25; + FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNFACE)); + clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW)); + DrawText(hdcDraw, "Toolbar Space", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + SetTextColor(hdcDraw, clrT); + + GetSizeRectForDocument(prcBounds, &rcT); + rcT.top = rcT.top + 25; + } + + clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW)); + DrawText(hdcDraw, "ActiveX Document Object", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER); + SetTextColor(hdcDraw, clrT); + } + } + else if ((m_pDocObjFrame) && (!m_fAppActive || !m_fComponentActive) && (FDrawBitmapOnAppDeactive() || FIPDeactivateOnCompChange())) + { + // In the case we have more than one component, and this component is + // has an object but is not ui active we draw a bitmap representation + // of the obect to fill the area. This gives the user a sense the object + // is there but in background, and can click to reactivate... + GetSizeRectForDocument(prcBounds, &rcT); + + if (m_hbmDeactive) + { + HDC hdcT = CreateCompatibleDC(hdcDraw); + HBITMAP bmpOld = (HBITMAP)SelectObject(hdcT, m_hbmDeactive); + BITMAP bm; + + if (GetObject(m_hbmDeactive, sizeof(BITMAP), &bm)) + { + StretchBlt(hdcDraw, rcT.left, rcT.top, + (rcT.right - rcT.left), (rcT.bottom - rcT.top), + hdcT, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); + } + else + { + BitBlt(hdcDraw, rcT.left, rcT.top, + (rcT.right - rcT.left), (rcT.bottom - rcT.top), hdcT, 0,0, SRCCOPY); + } + + SelectObject(hdcT, bmpOld); + DeleteDC(hdcT); + } + else if (!m_fInDocumentLoad) + { + FillRect(hdcDraw, &rcT, hbshBackground); + rcT.top = ((rc.bottom - rc.top) / 2); + clrT = SetTextColor(hdcDraw, clrForeground); + DrawText(hdcDraw, "Unable to display inactive document. Click here to reactivate the object.", -1, &rcT, DT_WORDBREAK | DT_CENTER); + SetTextColor(hdcDraw, clrT); + } + } // else The docobj draws the rest... + + // Cleanup the hDC as required... + DeleteObject(hbshBackground); + DeleteObject(hbshBorder); + + SelectObject(hdcDraw, hfontOld); + DeleteObject(hfontText); + + if (hpal) + { + SelectPalette(hdcDraw, hpalOld, TRUE); + DeleteObject(hpal); + } + + SetBkMode(hdcDraw, iTxtMode); + SetMapMode(hdcDraw, iMapMode); + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnDestroyWindow +// +// When the window closes make sure the object closes and release the +// subclass we have on the parent's top-level window. +// +STDMETHODIMP_(void) CDsoFramerControl::OnDestroyWindow() +{ + ODS("CDsoFramerControl::OnDestroyWindow\n"); + + if (m_pDocObjFrame) + Close(); + + if (m_pHookManager) + { + m_pHookManager->DetachComponent(m_hwnd); + m_pHookManager = NULL; + } + + m_hwnd = NULL; + + if (m_pServerLock) + SetTempServerLock(FALSE); + + if (m_hbmDeactive) + { + DeleteObject(m_hbmDeactive); + m_hbmDeactive = NULL; + } + + if (m_hmenuFilePopup) + { + DestroyMenu(m_hmenuFilePopup); + m_hmenuFilePopup = NULL; + } + +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnResize +// +// Resize the window and notify the doc site. +// +STDMETHODIMP_(void) CDsoFramerControl::OnResize() +{ + RECT rcPlace; + ODS("CDsoFramerControl::OnResize\n"); + if (m_pDocObjFrame) + { + if (FChangeObjActiveOnFocusChange() && (!m_fUIActive)) + UIActivate(FALSE); + + GetSizeRectForDocument(NULL, &rcPlace); + m_pDocObjFrame->OnNotifySizeChange(&rcPlace); + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnMouseMove +// +// We watch for mouse movement on menu bar (when visible). +// +STDMETHODIMP_(void) CDsoFramerControl::OnMouseMove(UINT x, UINT y) +{ + // TRACE2("CDsoFramerControl::OnMouseMove(%d, %d)\n", x, y); + // TRACE3(" fAppActive=%d, fUIActive=%d, fCompActive=%d\n", m_fAppActive, m_fUIActive, m_fComponentActive); + // TRACE2(" fModalState=%d, fNoInteractive=%d\n", m_fModalState, m_fNoInteractive); + + // When we are in mouse move, watch for menu selection. Only need to + // do this if bar is visible and we are not in modal state... + if ((m_fShowMenuBar) && (m_fComponentActive) && (m_fUIActive) && (m_fAppActive) && + (!m_fModalState) && (!m_fNoInteractive)) + { + UINT item; + POINT pt; pt.x = x; pt.y = y; + + // If we already have item selected, check to see if we are still + // over it. If so, we can exit now. If not, we sould unselect it. + if (m_wSelMenuItem) + { + item = m_wSelMenuItem - 1; + if (PtInRect(&m_rgrcMenuItems[item], pt)) + return; + + ReleaseCapture(); m_wSelMenuItem = 0; + InvalidateRect(m_hwnd, &m_rgrcMenuItems[item], FALSE); + } + + // Now loop through the menu items and see if mouse is over them. + // If it is, we set a mouse capture and draw item as selected... + for (item = 0; item < m_cMenuItems; item++) + { + if (PtInRect(&m_rgrcMenuItems[item], pt)) + { + SetCapture(m_hwnd); + m_wSelMenuItem = (USHORT)(item + 1); + InvalidateRect(m_hwnd, &m_rgrcMenuItems[item], FALSE); + break; + } + } + } + + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnButtonDown +// +// We watch for mouse button down events when the titlebar is visible +// so we can drop down our popup menu if the user clicks around the +// area of the file icon. This is our workaround for menu merging. +// +STDMETHODIMP_(void) CDsoFramerControl::OnButtonDown(UINT x, UINT y) +{ + HMENU hCurMenu = NULL; + RECT rc; + + // Don't do anything if we are in modal state... + if (m_fModalState) return; + + // We don't handle commands when m_fNoInteractive is set, except for the + // condition where we are in print preview and want to display custom menu + // item to end the preview. Office apps have toolbar button to do this, but + // we will provide this option just in case user needs it to exit preview mode... + if (m_fNoInteractive) + { + if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview())) + { + // If we don't have UI focus, take it... + if (!m_fUIActive) UIActivate(TRUE); + + // Create a temp popup menu. We do this on fly to save resources since + // this is only needed in rare cases... + if ((m_fShowTitlebar) && ((x < 22) && (y < 22))) + { + hCurMenu = CreatePopupMenu(); + if (hCurMenu) + { + // Add the command to the menu... + AppendMenu(hCurMenu, MF_STRING, MNU_PRINTPV, "E&xit Preview"); + // Display the menu... + GetSizeRectAfterTitlebar(NULL, &rc); + MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2); + TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL); + // Cleanup... + DestroyMenu(hCurMenu); + hCurMenu = NULL; + } + } + } + + // Otherwise we do nothing when m_fNoInteractive == TRUE. + return; + } + + // We know we must be app active if user clicked on control... + if (!m_fAppActive) m_fAppActive = TRUE; + + // If we don't have UI focus, take it... + if (!m_fUIActive) UIActivate(TRUE); + + // If the caption is showing, we are not modal, and user clicked in the + // area around the office doc icon, show the popup menu... + if ((m_fShowTitlebar) && (!m_fShowMenuBar) && ((x < 22) && (y < 22))) + { + // This will get the File menu or the merged menu based on current state... + hCurMenu = GetActivePopupMenu(); + if (hCurMenu) + { + // We'll place it right below the titlebar just like sys menu... + GetSizeRectAfterTitlebar(NULL, &rc); + MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2); + TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL); + } + } + else if ((m_fShowMenuBar) && (m_wSelMenuItem)) + { + POINT pt; + UINT item = m_wSelMenuItem - 1; + + // If we are over a visible menu bar item, find the right popup + // menu for the item using the selitem as an index... + if (item == 0) + { hCurMenu = m_hmenuFilePopup; } + else + { + hCurMenu = GetActivePopupMenu(); + if (hCurMenu) hCurMenu = GetSubMenu(hCurMenu, item); + } + + // Map the location to display the popup into screen points... + pt.x = m_rgrcMenuItems[item].left; + pt.y = m_rgrcMenuItems[item].bottom; + MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&pt, 1); + + HWND hwndCurFocus = GetFocus(); + m_fInFocusChange = TRUE; + if (hwndCurFocus && (hwndCurFocus != m_hwnd)) + SetFocus(m_hwnd); + + // Display the menu... + TrackPopupMenu(hCurMenu, 0, pt.x, pt.y, 0, m_hwnd, NULL); + + if (hwndCurFocus && (hwndCurFocus != m_hwnd)) + SetFocus(hwndCurFocus); + m_fInFocusChange = FALSE; + + // When user clicks off, we will resolve the mouse location to + // our control coordinates and call mousemove to free/reset selection... + if (GetCursorPos(&pt)) + { + RECT rcMenu; GetSizeRectForMenuBar(NULL, &rcMenu); + MapWindowPoints(HWND_DESKTOP, m_hwnd, (POINT*)&pt, 1); + if (!PtInRect(&rcMenu, pt)) {pt.x = 0; pt.y = 0;} + } + else {pt.x = 0; pt.y = 0;} + OnMouseMove(pt.x, pt.y); + } + return; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnMenuMessage +// +// We should get these messages when we are displaying the popup menu. +// The "File" menu is ours, but the popup may have other menus copied +// from the merged menu set by the ui active docobject, so we need to +// forward those messages (as needed) to the right window handler. +// +// In addition, code is added to enable/disable File menu items based +// on flags set by developer in EnableFileCommand, and/or call the +// correct function if one of those commands was selected by user. +// +STDMETHODIMP_(void) CDsoFramerControl::OnMenuMessage(UINT msg, WPARAM wParam, LPARAM lParam) +{ + HMENU hmenu, hmenuMerged = NULL; + BOOL fAlwaysSendMessage = FALSE; + HWND hwndObjectMenu = NULL; + + if (m_pDocObjFrame) + { + hwndObjectMenu = m_pDocObjFrame->GetMenuHWND(); + hmenuMerged = m_pDocObjFrame->GetMergedMenu(); + } + + switch (msg) + { + case WM_INITMENU: m_fObjectMenu = FALSE; //fall through... + case WM_ENTERIDLE: fAlwaysSendMessage = TRUE; + break; + + case WM_MENUSELECT: + if ((lParam == 0) && (HIWORD(wParam) == 0xFFFF)) + fAlwaysSendMessage = TRUE; + break; + + case WM_INITMENUPOPUP: + hmenu = (HMENU)wParam; + m_fObjectMenu = ((hmenu != m_hmenuFilePopup) && (hmenu != hmenuMerged)); + + if ((!m_fObjectMenu) && (hmenu == m_hmenuFilePopup)) + { + EnableMenuItem(hmenu, MNU_NEW, MF_BYCOMMAND | ((m_wFileMenuFlags & 1) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_OPEN, MF_BYCOMMAND | ((m_wFileMenuFlags & 2) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_CLOSE, MF_BYCOMMAND | (((m_wFileMenuFlags & 4) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_SAVE, MF_BYCOMMAND | (((m_wFileMenuFlags & 8) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_SAVEAS, MF_BYCOMMAND | (((m_wFileMenuFlags & 16) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_PGSETUP, MF_BYCOMMAND | (((m_wFileMenuFlags & 64) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_PRINTPV, MF_BYCOMMAND | (((m_wFileMenuFlags & 256) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_PRINT, MF_BYCOMMAND | (((m_wFileMenuFlags & 32) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + EnableMenuItem(hmenu, MNU_PROPS, MF_BYCOMMAND | (((m_wFileMenuFlags & 128) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); + } + break; + + case WM_COMMAND: + // We handle one special case for print preview exit, but otherwise + // we need to either forward to the merged menu handler (if enabled), + // or handle command through an asynchronous callback... + if ((m_fNoInteractive) && (LOWORD(wParam) == MNU_PRINTPV)) + { + PrintPreviewExit(); + } + else if ((m_fObjectMenu) && (hwndObjectMenu)) + { + PostMessage(hwndObjectMenu, msg, wParam, lParam); + } + else + { + DWORD dwCmd = 0; + switch ((int)LOWORD(wParam)) + { + case MNU_NEW: dwCmd = OLECMDID_NEW; break; + case MNU_OPEN: dwCmd = OLECMDID_OPEN; break; + case MNU_SAVE: dwCmd = OLECMDID_SAVE; break; + case MNU_SAVEAS: dwCmd = OLECMDID_SAVEAS; break; + case MNU_PGSETUP: dwCmd = OLECMDID_PAGESETUP; break; + case MNU_PRINT: dwCmd = OLECMDID_PRINT; break; + case MNU_PROPS: dwCmd = OLECMDID_PROPERTIES; break; + case MNU_PRINTPV: dwCmd = OLECMDID_PRINTPREVIEW; break; + } + PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, dwCmd, 0); + } + + return; // we just return + } + + if ((hwndObjectMenu) && ((m_fObjectMenu) || (fAlwaysSendMessage))) + SendMessage(hwndObjectMenu, msg, wParam, lParam); + + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnToolbarAction +// +// Does an associated OLECMDID action and raises the OnFileCommand event +// for developer to override as needed. The name comes from the fact that +// most Office servers will call this (via IOleCommandTarget) when user +// clicks on a toolbar button for file-command item. It also serves for +// our menu commands to keep the code consistant. Both menu and toolbar +// call this method asynchronously (via PostMessage) to avoid blocking the +// remote docobject server. +// +STDMETHODIMP_(void) CDsoFramerControl::OnToolbarAction(DWORD cmd) +{ + ODS("CDsoFramerControl::OnToolbarAction\n"); + HRESULT hr = S_OK; + VARIANT_BOOL wCancelAction = VARIANT_FALSE; + VARIANT rgargs[2]; + VARIANT vtT = {0}; + + // We don't reenter if in a modal state already... + if (m_fModalState) return; + + // If not interactive, we cannot run command... + if (m_fNoInteractive) + { + // unless we are in preview, in which case we can force exit + // and then run command after preview completes... + if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview())) + { + PrintPreviewExit(); + if (cmd != OLECMDID_PRINTPREVIEW) + PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, cmd, 0); + } + return; + } + + // We will do a default action by default, but give developer a chance + // to override in OnFileCommand event... + rgargs[0].vt = VT_BOOL|VT_BYREF; + rgargs[0].pboolVal = &wCancelAction; + + // Map the OLECMDID to one of our values... + rgargs[1].vt = VT_I4; + switch (cmd) + { + case OLECMDID_NEW: rgargs[1].lVal = dsoFileNew; break; + case OLECMDID_OPEN: rgargs[1].lVal = dsoFileOpen; break; + case OLECMDID_SAVE: rgargs[1].lVal = dsoFileSave; break; + case OLECMDID_SAVEAS: rgargs[1].lVal = dsoFileSaveAs; break; + case OLECMDID_PRINT: rgargs[1].lVal = dsoFilePrint; break; + case OLECMDID_PAGESETUP: rgargs[1].lVal = dsoFilePageSetup; break; + case OLECMDID_PROPERTIES: rgargs[1].lVal = dsoFileProperties; break; + case OLECMDID_PRINTPREVIEW: rgargs[1].lVal = dsoFilePrintPreview; break; + default: rgargs[1].lVal = dsoFileClose; + } + + // Only do action if item is enabled... + if ((1 << rgargs[1].lVal) & m_wFileMenuFlags) + { + // Let control developer handle the event first... + hr = RaiseAutomationEvent(DSOF_DISPID_FILECMD, 2, rgargs); + TRACE1("Disp event returned 0x%X \n", hr); + + // If the event was canceled (or event handler threw an + // unhandled error from user code), bail out now... + if ((wCancelAction) || (hr == DISP_E_EXCEPTION)) + return; + + // Do the action based on the event... + switch (rgargs[1].lVal) + { + case dsoFileClose: hr = Close(); break; + case dsoFilePrint: hr = ShowDialog(dsoDialogPrint); break; + case dsoFilePageSetup: hr = ShowDialog(dsoDialogPageSetup); break; + case dsoFileProperties: hr = ShowDialog(dsoDialogProperties); break; + case dsoFilePrintPreview: hr = PrintPreview(); break; + + case dsoFileSave: + hr = Save(vtT, vtT, vtT, vtT); + if ((hr != DSO_E_DOCUMENTREADONLY) && + (hr != DSO_E_NOTBEENSAVED)) + break; // fall through to SaveAs if file is read-only or never been saved... + + default: + hr = DoDialogAction( + (rgargs[1].lVal == dsoFileNew) ? dsoDialogNew : + (rgargs[1].lVal == dsoFileOpen) ? dsoDialogOpen : dsoDialogSave); + } + + // Display error information to user if we failed... + if (FAILED(hr) && (hr != E_ABORT)) + FAlertUser(hr, NULL); + } + + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::FAlertUser +// +// Display an error alert to the user based on failed HRESULT. +// +STDMETHODIMP_(BOOL) CDsoFramerControl::FAlertUser(HRESULT hr, LPWSTR pwsFileName) +{ + LPSTR pszError = NULL; + LPSTR pszTitle = NULL; + DWORD dwFlags = MB_ICONINFORMATION|MB_SETFOREGROUND; + + switch (hr) + { + case STG_E_ACCESSDENIED: + case STG_E_SHAREVIOLATION: + case STG_E_LOCKVIOLATION: + case MK_E_CANTOPENFILE: + case E_ACCESSDENIED: + pszError = "Unable to Open/Save the file selected due to security permissions or a share violation."; + pszTitle = "Access Denied"; + break; + + case DSO_E_DOCUMENTNOTOPEN: + pszError = "The operation could not be performed because no document is currently open."; + pszTitle = "Unable to Perform Command"; + break; + + case DSO_E_DOCUMENTREADONLY: + pszError = "The operation could not be performed because the document was opened read-only."; + pszTitle = "Unable to Update Document"; + break; + + case CO_E_MSI_ERROR: + case DSO_E_INVALIDSERVER: + case DSO_E_INVALIDPROGID: + case STG_E_NOTFILEBASEDSTORAGE: + pszError = "There is no ActiveX Document server currently registered or installed for the item selected. " + "It cannot be loaded into the control."; + pszTitle = "Unable to Insert Document"; + break; + + case DSO_E_INMODALSTATE: + MessageBeep(0); + return FALSE; // Unable to alert user if in a modal condition! + + case DSO_E_COMMANDNOTSUPPORTED: + pszError = "This operation could not be performed because the document server " + "does not support the command, or it is disabled when embedded."; + pszTitle = "Command Not Supported"; + break; + + case STG_E_TOOMANYOPENFILES: + pszError = "You can only open one document at a time. Please choose a single file to open."; + pszTitle = "Command Not Supported"; + break; + + case DSO_E_REQUIRESMSDAIPP: + pszError = "You cannot open/save to a web folder unless MDAC 2.5 is installed. The operation cannot be performed."; + pszTitle = "Unable to Gain Write Access for URL"; + break; + + default: + pszError = "The program encountered an error trying to perform the command. " + "If the problem persists, contact the program vendor for a possible solution."; + pszTitle = "Command Error"; + dwFlags = MB_ICONHAND|MB_SETFOREGROUND; + } + + MessageBox(m_hwnd, pszError, pszTitle, dwFlags); + return TRUE; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::EnableDropFile +// +// Decide when to allow file drop for open. +// +STDMETHODIMP_(void) CDsoFramerControl::EnableDropFile(BOOL fEnable) +{ + TRACE1("CDsoFramerControl::EnableDropFile(%d)\n", fEnable); + DragAcceptFiles(m_hwnd, fEnable); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnDropFile +// +// Open file dropped by user on the control. +// +STDMETHODIMP_(void) CDsoFramerControl::OnDropFile(HDROP hdrpFile) +{ + DWORD cbItems; + CHAR szFileDrop[MAX_PATH]; + VARIANT vtFile; + + ODS("CDsoFramerControl::OnDropFile()\n"); + cbItems = DragQueryFile(hdrpFile, 0xFFFFFFFF, NULL, 0); + if (cbItems == 0) + return; + + if (cbItems > 1) + { + FAlertUser(STG_E_TOOMANYOPENFILES, NULL); + return; + } + + szFileDrop[0] = 0; + vtFile.vt = VT_BSTR; + + if (DragQueryFile(hdrpFile, 0, szFileDrop, MAX_PATH) && + (vtFile.bstrVal = DsoConvertToBSTR(szFileDrop))) + { + HRESULT hr; + VARIANT vtMissing; + vtMissing.vt = VT_ERROR; + vtMissing.scode = DISP_E_PARAMNOTFOUND; + + hr = Open(vtFile, vtMissing, vtMissing, vtMissing, vtMissing); + if (FAILED(hr)) FAlertUser(hr, vtFile.bstrVal); + + VariantClear(&vtFile); + } + + return; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnTimer +// +// Timer event fired. +// +STDMETHODIMP_(void) CDsoFramerControl::OnTimer(UINT id) +{ + // TRACE1("CDsoFramerControl::OnTimer(%d)\n", id); + switch (id) + { + case SYNCPAINT_TIMER_ID: + { + DWORD dwTick = GetTickCount(); + if ((dwTick - m_uiSyncPaint) > 300) + { + ODS("CDsoFramerControl::OnSyncPaint() Invalidate\n"); + KillTimer(m_hwnd, SYNCPAINT_TIMER_ID); + m_fSyncPaintTimer = FALSE; + InvalidateAllChildWindows(m_hwnd); + } + } + break; + } + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnSyncPaint +// +// Notifies redraw is needed b/c of external window movement. +// +STDMETHODIMP_(void) CDsoFramerControl::OnSyncPaint() +{ + // ODS("CDsoFramerControl::OnSyncPaint()\n"); + m_uiSyncPaint = GetTickCount(); + if ((!m_fSyncPaintTimer) && (!m_fAppActive)) + { + SetTimer(m_hwnd, SYNCPAINT_TIMER_ID, 50, NULL); + m_fSyncPaintTimer = TRUE; + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnForegroundCompChange +// +// Shows/Hide embedding when window goes foreground/background active. +// +STDMETHODIMP_(void) CDsoFramerControl::OnForegroundCompChange(BOOL fCompActive) +{ + ODS("CDsoFramerControl::OnForegroundCompChange\n"); + if (m_pDocObjFrame) + { + HWND hwndEmbed = m_pDocObjFrame->GetDocWindow(); + + if (fCompActive) + { + // Make sure embed window is visible when active... + if (!IsWindowVisible(hwndEmbed)) + ShowWindow(hwndEmbed, SW_SHOW); + + if (m_hbmDeactive) DeleteObject(m_hbmDeactive); + m_hbmDeactive = NULL; + } + else if ((FDrawBitmapOnAppDeactive() || FIPDeactivateOnCompChange()) && (m_hbmDeactive == NULL)) + { + // The default behavior on app deactive is to grap bitmap of active object before + // telling it we lost app activation. This allows us to draw the last state of the + // object while it is deactive. There is now an option to avoid this and keep object + // UI active while app deactive, but it may not work for all DocObj servers. + m_hbmDeactive = DsoGetBitmapFromWindow(hwndEmbed); + ShowWindow(hwndEmbed, SW_HIDE); + } + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnAppActivationChange +// +// Notifes embedded object when the host app gains/loses foreground status +// as the active application. This notification is critical to DocObjects since +// it is the primary means for the host and server to synch which top-level +// frame window (the host or the server's native main window) should be on the +// z-order stack for the shared thread input state. Thus allowing dialogs and tool +// windows to appear the correct order when displayed. +// +STDMETHODIMP_(void) CDsoFramerControl::OnAppActivationChange(BOOL fAppActive, DWORD dwThreadID) +{ + TRACE2("CDsoFramerControl::OnAppActivationChange(fAppActive=%d, tid=0x%X)\n", fAppActive, dwThreadID); + m_fAppActive = fAppActive; + + if ((m_pDocObjFrame) && (m_fComponentActive)) + { + // Create/Free bitmap for background appearance.. + OnForegroundCompChange(fAppActive); + + // Notify it that it should be app active ofr deactive... + m_pDocObjFrame->OnNotifyAppActivate(fAppActive, (dwThreadID ? dwThreadID : GetCurrentThreadId())); + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnComponentActivationChange +// +// Handles showing/hiding doc object during activation state changes. +// This is needed to properly handle focus changes when more than one +// instance of the control is running on the same top-level window. +// +STDMETHODIMP_(void) CDsoFramerControl::OnComponentActivationChange(BOOL fActivate) +{ + TRACE1("CDsoFramerControl::OnComponentActivationChange(fActive=%d)\n", fActivate); + + if (fActivate) + { + // Set us active if we currently are not and raise activation change event... + if (!m_fComponentActive) + { + m_fComponentActive = TRUE; + OnForegroundCompChange(TRUE); + // Raise event to component host on state change... + PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate); + } + + // Notify the embedded object... + if (m_pDocObjFrame) + { + // Determine if we should restore from IP deactivation... + if (FIPDeactivateOnCompChange() && !(m_pDocObjFrame->IsIPActive())) + { + m_pDocObjFrame->IPActivateView(); + OnForegroundCompChange(TRUE); + } + } + } + else + { + + // Inform embedded object we lost activation... + if (m_pDocObjFrame) + { + // If we are in print preview, we need to exit in case other control will + // end up talking to same OLE server... + if (m_pDocObjFrame->InPrintPreview()) + { + PrintPreviewExit(); + UpdateWindow(m_hwnd); + } + + // Provide control host option to IP deactive view when another framer control + // takes primary focus. This helps certain resource problems if you a lot of controls + // all IP active at the same time. This should not normally be used. + if (FIPDeactivateOnCompChange() && m_pDocObjFrame->IsIPActive()) + { + OnForegroundCompChange(FALSE); + m_pDocObjFrame->IPDeactivateView(); + } + + } + + // Change the current activation state and raise event... + if (m_fComponentActive) + { + m_fComponentActive = FALSE; + OnForegroundCompChange(FALSE); + // Raise event to component host on state change... + PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate); + } + + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnCtrlFocusChange +// +// Checks if window (or one of its children) is getting or losing focus so +// that can notify both the host and embed server using OnUIFocusChange. +// +STDMETHODIMP_(void) CDsoFramerControl::OnCtrlFocusChange(BOOL fCtlGotFocus, HWND hFocusWnd) +{ + TRACE2("CDsoFramerControl::OnCtrlFocusChange(fCtlGotFocus=%d, hwndCurFocus=%x)\n", fCtlGotFocus, hFocusWnd); + if (!(m_fInFocusChange) && ((fCtlGotFocus) || !IsWindowChild(m_hwnd, hFocusWnd))) + { + OnUIFocusChange(fCtlGotFocus); + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnUIFocusChange +// +// Selectively handle focus changes to make sure both host and ui +// active docobject are in synch. +// +STDMETHODIMP_(void) CDsoFramerControl::OnUIFocusChange(BOOL fUIActive) +{ + BOOL fFocusUpdated = FALSE; + TRACE1("CDsoFramerControl::OnUIFocusChange(fUIActive=%d)\n", fUIActive); + + // We shouldn't try to do focus change when modal... + if ((m_fModalState) || (m_fInFocusChange)) + { + ODS(" -- Got focus while modal or in change (do nothing) --\n"); + return; + } + + // When IP active, notify the control host of focus change... + if ((m_fInPlaceActive) && (m_pControlSite)) + { + + // Set flag to prevent recursion during focus changes... + m_fInFocusChange = TRUE; + + if (fUIActive) // If we got focus... + { + // Notify host we have focus (we only need + // to do this if we are not already UI Active)... + if (!(m_fHasFocus)) + { + ODS(" -- Tell host app we should have focus --\n"); + m_fHasFocus = (fFocusUpdated = TRUE); + m_pControlSite->OnFocus(TRUE); + } + + // Let the hook manager know that this control is the active object... + if (m_pHookManager) + m_pHookManager->SetActiveComponent(m_hwnd); + + // If so configured, force component to show up active... + if (FChangeObjActiveOnFocusChange()) + { + ODS(" -- Do component active on focus gain --\n"); + OnComponentActivationChange(TRUE); + } + + // If we have an active document, forward the focus... + if (m_pDocObjFrame) + m_pDocObjFrame->OnNotifyControlFocus(TRUE); + + } + else // else we lost focus... + { + + // When we lose focus, only notify host if we lost to window + // that does not belong to us... + if (m_pDocObjFrame) + m_pDocObjFrame->OnNotifyControlFocus(FALSE); + + // If so configured, force component loss on focus loss... + if (FChangeObjActiveOnFocusChange()) + { + ODS(" -- Do component deactive on focus loss --\n"); + OnComponentActivationChange(FALSE); + m_fActivateOnStatus = TRUE; + } + + // If we are UI active still, we need to tell host that we lost + // focus and are now UI deactive. + if (m_fHasFocus) + { + ODS(" -- Notify host of lost focus (ie, UI deactivate us) --\n"); + m_fHasFocus = FALSE; fFocusUpdated = TRUE; + m_pControlSite->OnFocus(FALSE); + } + } + + // Clear focus change flag... + m_fInFocusChange = FALSE; + + // Redraw menu bar in case of state change + if ((fFocusUpdated) && (m_fShowMenuBar)) + { + RECT rc; GetSizeRectForMenuBar(NULL, &rc); + InvalidateRect(m_hwnd, &rc, TRUE); + } + } + + return; +} +//////////////////////////////////////////////////////////////////////// +// 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); + + // Post notification of return from modal... + if (fModeless) + PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_RETURNFROMMODAL, (LPARAM)TRUE); + } +} + +//////////////////////////////////////////////////////////////////////// +// 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... + RaiseAutomationEvent(DSOF_DISPID_ENDPREVIEW, 0, 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; + } + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnPaletteChanged +// +// This method is also called from the subclassed parent. Per docobject +// spec, a ui active object should get first chance of any palette updates. +// +STDMETHODIMP_(void) CDsoFramerControl::OnPaletteChanged(HWND hwndPalChg) +{ + ODS("CDsoFramerControl::OnPaletteChanged\n"); + if (m_pDocObjFrame) m_pDocObjFrame->OnNotifyPaletteChanged(hwndPalChg); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::OnSysCommandMenu +// +// Checks for menu shortcut keys when ui active. +// +STDMETHODIMP_(BOOL) CDsoFramerControl::OnSysCommandMenu(CHAR ch) +{ + if (m_fUIActive) + { + TRACE1("CDsoFramerControl::OnSysCommandMenu(%d)\n", (DWORD)ch); + return TRUE; + } + return FALSE; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::GetActivePopupMenu +// +// Constructs our popup menu and returns the handle. The menu can be +// either the File menu by itself (no docobj is open) or the merged +// menu as a popup. +// +STDMETHODIMP_(HMENU) CDsoFramerControl::GetActivePopupMenu() +{ + HMENU hPopup, hMergedMenu, hServerMenu; + + // If we haven't made a File menu yet, make it. Here is where you might + // want to add custom items if you have other file-level commands you would + // the control to support. These are the basics... + if (!m_hmenuFilePopup) + { + m_hmenuFilePopup = CreatePopupMenu(); m_cMenuItems = 0; + if (!m_hmenuFilePopup) return NULL; + + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_NEW, "&New...\tCtrl+N"); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_OPEN, "&Open...\tCtrl+O"); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_CLOSE, "&Close"); + AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0, NULL); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_SAVE, "&Save\tCtrl+S"); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_SAVEAS, "Save &As..."); + AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0, NULL); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_PGSETUP, "Page Set&up..."); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_PRINTPV, "Print Pre&view"); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_PRINT, "&Print..."); + AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0, NULL); + AppendMenu(m_hmenuFilePopup, MF_STRING, MNU_PROPS, "Propert&ies"); + } + + // If we have a docobj and it has a merged menu, then lets return a + // merged menu between the docobj and our file menu... + if ((m_pDocObjFrame) && (m_pDocObjFrame->GetMenuHWND())) + { + // We only need to create the merged copy once. + if (!(hMergedMenu = m_pDocObjFrame->GetMergedMenu())) + { + hMergedMenu = CreatePopupMenu(); m_cMenuItems = 0; + if ((hMergedMenu) && (hServerMenu = (m_pDocObjFrame->GetActiveMenu()))) + { + CHAR szbuf[MAX_PATH]; + HMENU hT; + CHAR *pch; + + InsertMenu(hMergedMenu, 0, MF_BYPOSITION|MF_POPUP, (UINT)m_hmenuFilePopup, "&File"); + m_rgchMenuAccel[0] = 'f'; + + int cbMenuCnt = GetMenuItemCount(hServerMenu); + if (cbMenuCnt > DSO_MAX_MENUITEMS) cbMenuCnt = DSO_MAX_MENUITEMS; + + for (int i = 0; i < cbMenuCnt; i++) + { + hT = GetSubMenu(hServerMenu, i); + if (hT) + { + szbuf[0] = '\0'; + GetMenuString(hServerMenu, i, szbuf, MAX_PATH, MF_BYPOSITION); + InsertMenu(hMergedMenu, (i + 1), MF_BYPOSITION|MF_POPUP, (UINT)hT, szbuf); + + pch = szbuf; + while (*pch && (*pch++ != '&')) + ; + m_rgchMenuAccel[i + 1] = (CHAR)((*pch) ? ASCII_LOWERCASE(*pch) : 0xFF); + } + } + + if (cbMenuCnt < DSO_MAX_MENUITEMS) + m_rgchMenuAccel[cbMenuCnt + 1] = 0x00; + + m_pDocObjFrame->SetMergedMenu(hMergedMenu); + } + } + + hPopup = hMergedMenu; + } + else + { + hPopup = m_hmenuFilePopup; + m_rgchMenuAccel[0] = 'f'; + m_rgchMenuAccel[1] = 0; + } + + return hPopup; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::FRunningInDesignMode +// +// Determines if we are in design mode. Called when painting the control +// and when deciding whether to subclass the parent. +// +STDMETHODIMP_(BOOL) CDsoFramerControl::FRunningInDesignMode() +{ + IDispatch *pdisp; + + // We must have a control site. + CHECK_NULL_RETURN(m_pClientSite, FALSE); + + // If we have done this before, we don't need to keep doing it unless + // the host has notified us of the state change (see our code in + // XOleControl::OnAmbientPropertyChange)... + if ((!m_fModeFlagValid) && + SUCCEEDED(m_pClientSite->QueryInterface(IID_IDispatch, (void **)&pdisp))) + { + VARIANT vtUserMode; + m_fDesignMode = FALSE; // assume run mode + + if (SUCCEEDED(DsoDispatchInvoke(pdisp, NULL, + DISPID_AMBIENT_USERMODE, DISPATCH_PROPERTYGET, 0, NULL, &vtUserMode))) + { + // UserMode is True when control is in Run mode, False when in design. + // We assume run mode, so we only care to set the flag if in design. + m_fDesignMode = !(BOOL_FROM_VARIANT(vtUserMode, TRUE)); + VariantClear(&vtUserMode); + } + + m_fModeFlagValid = TRUE; + // Release the IDispatch pointer... + pdisp->Release(); + } + + return m_fDesignMode; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::InvalidateAllChildWindows +// +// Invalidate all child windows attached to the window passed. +// +STDMETHODIMP_(BOOL) CDsoFramerControl::InvalidateAllChildWindows(HWND hwnd) +{ + ODS("CDsoFramerControl::InvalidateAllChildWindows()\n"); + return EnumChildWindows(hwnd, InvalidateAllChildWindowsCallback, 0); +} + +STDMETHODIMP_(BOOL) CDsoFramerControl::InvalidateAllChildWindowsCallback(HWND hwnd, LPARAM lParam) +{ + RECT rc; + GetClientRect(hwnd, &rc); + InvalidateRect(hwnd, &rc, TRUE); + return TRUE; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::RaiseAutomationEvent +// +// Raises automation events to host application. +// +STDMETHODIMP CDsoFramerControl::RaiseAutomationEvent(DISPID did, ULONG cargs, VARIANT *pvtargs) +{ + HRESULT hr = ((m_fModalState) ? DISP_E_EXCEPTION : S_FALSE); + TRACE1("CDsoFramerControl::RaiseAutomationEvent(%d)\n", did); + + // We should only raise event if we have sink, not already in a event, and + // we are not in modal condition with respect to the remote server... + if ((m_dispEvents) && (!m_fFreezeEvents) && (!m_fModalState)) + { + m_fFreezeEvents = TRUE; + hr = DsoDispatchInvoke(m_dispEvents, NULL, did, 0, cargs, pvtargs, NULL); + m_fFreezeEvents = FALSE; + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::DoDialogAction +// +// A very simple implementation of a New/Open/Save dialogs to serve as +// default actions in case developer does not override these "File" +// commands in OnFileCommand. +// +STDMETHODIMP CDsoFramerControl::DoDialogAction(dsoShowDialogType item) +{ + HRESULT hr = S_FALSE; + BSTR bstr; + BOOL fReadOnly; + VARIANT vT[3]; + + static const WCHAR v_wszFileFilter[] = + L"Microsoft Office Files\0*.doc;*.docx;*.docm;*.rtf;*.xls;*.xlsx;*.xlsm;*.csv;*.ppt;*.pptx;*.pptm;*.mpp;*.vsd;*.vdx\0" + L"Microsoft Word Files\0*.doc;*.docx;*.docm;*.rtf\0" + L"Microsoft Excel Files\0*.xls;*.xlsx;*.xlsm;*.csv\0" + L"Microsoft PowerPoint Files\0*.ppt;*.pptx;*.pptm\0" + L"Microsoft Project Files\0*.mpp\0" + L"Microsoft Visio Files\0*.vsd;*.vdx\0" + L"All Files (*.*)\0*.*\0\0"; + + // Switch on the action type... + switch (item) + { + case dsoDialogOpen: // Get file from user and call Open... + if (SUCCEEDED(DsoGetFileFromUser(m_hwnd, NULL, (OFN_FILEMUSTEXIST|OFN_EXPLORER), + v_wszFileFilter, 1, NULL, NULL, FALSE, &bstr, &fReadOnly))) + { + vT[0].vt = VT_BSTR; vT[0].bstrVal = bstr; + vT[1].vt = VT_BOOL; vT[1].boolVal = (fReadOnly ? VARIANT_TRUE : VARIANT_FALSE); + vT[2].vt = VT_ERROR; vT[2].scode = DISP_E_PARAMNOTFOUND; + + hr = Open(vT[0], vT[1], vT[2], vT[2], vT[2]); + SysFreeString(bstr); + } + break; + + case dsoDialogSave: // Get file from user and call Save... + { + LPWSTR pwszSaveType = NULL; + LPWSTR pwszDefExt = NULL; + + if (m_pDocObjFrame) + m_pDocObjFrame->GetDocumentTypeAndFileExtension(&pwszSaveType, &pwszDefExt); + + if (SUCCEEDED(DsoGetFileFromUser(m_hwnd, NULL, (OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER), + ((pwszSaveType) ? pwszSaveType : v_wszFileFilter), 1, pwszDefExt, NULL, TRUE, &bstr, NULL))) + { + vT[0].vt = VT_BSTR; vT[0].bstrVal = bstr; + vT[1].vt = VT_BOOL; vT[1].boolVal = VARIANT_TRUE; + vT[2].vt = VT_ERROR; vT[2].scode = DISP_E_PARAMNOTFOUND; + + hr = Save(vT[0], vT[1], vT[2], vT[2]); + SysFreeString(bstr); + } + + if (pwszSaveType) DsoMemFree(pwszSaveType); + if (pwszDefExt) DsoMemFree(pwszDefExt); + } + break; + + case dsoDialogNew: // Get either ProgID or File to create new object from... + if (SUCCEEDED(DsoGetOleInsertObjectFromUser(m_hwnd, L"Insert New Document Object", + (IOF_SELECTCREATENEW | IOF_DISABLELINK | IOF_DISABLEDISPLAYASICON | IOF_HIDECHANGEICON), + TRUE, FALSE, &bstr, NULL))) + { + hr = CreateNew(bstr); + SysFreeString(bstr); + } + break; + + default: MessageBeep(0); + } + + return hr; +} +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::SetTempServerLock +// +// Sets up lock of OLE server to make unload and new load of files faster +// and to avoid race conditions on reload of file. +// +STDMETHODIMP CDsoFramerControl::SetTempServerLock(BOOL fLock) +{ + HRESULT hr = S_FALSE; + TRACE1("CDsoFramerControl::SetTempServerLock(%d)\n", fLock); + + if (fLock) + { + CLSID *pclsid; + + // First get the the CLSID of the current loaded object... + pclsid = m_pDocObjFrame->GetServerCLSID(); + + // If we already have a lock, determine if user is asking us to lock + // the same server (we only lock once for a given server type)... + if (m_pServerLock) + { + if (*(m_pServerLock->GetServerCLSID()) == *pclsid) + return S_FALSE; + + // If the current document is from a different server, free the old lock... + hr = SetTempServerLock(FALSE); + ASSERT(SUCCEEDED(hr)); // Sanity check in debug... + } + + // To lock the server, just make a dummy OLE object and don't ever site it... + m_pServerLock = CDsoDocObject::CreateInstance((IDsoDocObjectSite*)&m_xDsoDocObjectSite); + hr = ((m_pServerLock) ? m_pServerLock->CreateDocObject(*pclsid) : E_OUTOFMEMORY); + if (SUCCEEDED(hr)) + { + hr = m_pServerLock->SetRunningServerLock(TRUE); + + // If we lock Excel, it steals focus from this host to the lock object, so we + // need to take it back so the real object isn't mixed up state... + if (SUCCEEDED(hr) && (m_pServerLock->IsExcelObject()) && (m_fAppActive)) + { + OnAppActivationChange(TRUE, 0); + } + } + else + { + delete m_pServerLock; + m_pServerLock = NULL; + } + + } + else if (m_pServerLock) + { + SEH_TRY + hr = m_pServerLock->SetRunningServerLock(FALSE); + hr = m_pServerLock->Close(); + SEH_EXCEPT(hr) + + ASSERT(SUCCEEDED(hr)); // Sanity check in debug... + delete m_pServerLock; + m_pServerLock = NULL; + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::ResetFrameHook +// +// Allows host to reset the frame hook. +// +STDMETHODIMP CDsoFramerControl::ResetFrameHook(HWND hwndFrameWindow) +{ + DWORD dwProcessId; + TRACE1("CDsoFramerControl::ResetFrameHook(%d)\n", hwndFrameWindow); + + // If the control is in modal state, we can't do anything... + if ((m_fModalState) || (m_fNoInteractive)) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // Verify that hwnd passed is a valid window handle and belogs to same thread + // as the control for parenting purposes... + if ((hwndFrameWindow) && (!IsWindow(hwndFrameWindow) || + (GetWindowThreadProcessId(hwndFrameWindow, &dwProcessId), dwProcessId != GetCurrentProcessId()))) + return E_INVALIDARG; + + // We must have a window already created for this to work... + if ((m_hwnd == NULL) || !IsWindow(m_hwnd) || + (m_hwndParent == NULL) || !IsWindow(m_hwndParent)) + return E_ACCESSDENIED; + + // Detach from the current window (removing that hook if this is the last component)... + if (m_pHookManager) + { + HRESULT hr = m_pHookManager->DetachComponent(m_hwnd); + if (FAILED(hr)) return hr; + m_pHookManager = NULL; + } + + // Now attach to the new parent window (or reattach based on the parent from our window)... + m_pHookManager = CDsoFrameHookManager::RegisterFramerControl((hwndFrameWindow ? hwndFrameWindow : m_hwndParent), m_hwnd); + if (m_pHookManager == NULL) return E_FAIL; + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::RaiseActivationEvent +// +// Called to raise component change event on activation switch. +// +STDMETHODIMP_(void) CDsoFramerControl::RaiseActivationEvent(BOOL fActive) +{ + VARIANT rgargs[1]; rgargs[0].vt = VT_BOOL; + rgargs[0].boolVal = (fActive ? VARIANT_TRUE : VARIANT_FALSE); + RaiseAutomationEvent(DSOF_DISPID_ACTIVATE, 1, rgargs); + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::ControlWindowProc +// +// The window proc for our control. +// +STDMETHODIMP_(LRESULT) CDsoFramerControl::ControlWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CDsoFramerControl* pCtl = (CDsoFramerControl*)GetWindowLong(hwnd, GWL_USERDATA); + if (pCtl) + { + switch (msg) + { + case WM_PAINT: + { + // call the OnDraw routine. + PAINTSTRUCT ps; + RECT rc; + HDC hdc; + hdc = BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &rc); + pCtl->OnDraw(DVASPECT_CONTENT, hdc, (RECT*)&rc, NULL, NULL, TRUE); + EndPaint(hwnd, &ps); + } + break; + + case WM_SIZE: + pCtl->OnResize(); + break; + + case WM_DESTROY: + pCtl->OnDestroyWindow(); + SetWindowLong(hwnd, GWL_USERDATA, 0); + break; + + case WM_SETFOCUS: + case WM_KILLFOCUS: + pCtl->OnCtrlFocusChange((BOOL)(msg == WM_SETFOCUS), (HWND)wParam); + break; + + case WM_MOUSEMOVE: + pCtl->OnMouseMove(LOWORD(lParam), HIWORD(lParam)); + break; + + case WM_LBUTTONDOWN: + pCtl->OnButtonDown(LOWORD(lParam), HIWORD(lParam)); + break; + + case DSO_WM_ASYNCH_OLECOMMAND: + ODS(" -- Got DSO_WM_ASYNCH_OLECOMMAND -- \n"); + pCtl->OnToolbarAction((DWORD)wParam); + break; + + case DSO_WM_ASYNCH_STATECHANGE: + TRACE1(" -- Got DSO_WM_ASYNCH_STATECHANGE %d --\n", wParam); + { + BOOL fCondition = (lParam != 0); + switch (wParam) + { + case DSO_STATE_MODAL: + pCtl->UpdateModalState(fCondition, FALSE); + break; + case DSO_STATE_ACTIVATION: + pCtl->RaiseActivationEvent(fCondition); + break; + case DSO_STATE_INTERACTIVE: + pCtl->UpdateInteractiveState(fCondition); + break; + case DSO_STATE_RETURNFROMMODAL: + { + if ((pCtl->m_fModalState == FALSE) && + (pCtl->m_fAppActive)) + { + pCtl->OnUIFocusChange(TRUE); + } + } + break; + + default: + ODS(" -- Unknown State Change!! --\n"); + break; + } + } + break; + + case DSO_WM_HOOK_NOTIFY_COMPACTIVE: + pCtl->OnComponentActivationChange((BOOL)wParam); + wParam = lParam; lParam = 0; + // falls through with wParam swapped... + + case DSO_WM_HOOK_NOTIFY_APPACTIVATE: + pCtl->OnAppActivationChange((BOOL)wParam, (DWORD)lParam); + break; + + case DSO_WM_HOOK_NOTIFY_SYNCPAINT: + pCtl->OnSyncPaint(); + break; + + case DSO_WM_HOOK_NOTIFY_PALETTECHANGE: + pCtl->OnPaletteChanged((HWND)wParam); + break; + + case WM_ENABLE: + pCtl->OnWindowEnable((BOOL)wParam); + break; + + case WM_MENUSELECT: + case WM_DRAWITEM: + case WM_MEASUREITEM: + case WM_ENTERIDLE: + case WM_INITMENU: + case WM_INITMENUPOPUP: + case WM_COMMAND: + pCtl->OnMenuMessage(msg, wParam, lParam); + break; + + case WM_DROPFILES: + pCtl->OnDropFile((HDROP)wParam); + break; + + case WM_TIMER: + pCtl->OnTimer((UINT)wParam); + break; + + case WM_SYSCOMMAND: + if ((wParam & 0xFFF0) == SC_KEYMENU) + { + if (pCtl->m_xDsoDocObjectSite.SysMenuCommand((UINT)lParam) == S_OK) + { + ODS(" -- Eat SC_KeyMenu message --\n"); + return 1; + } + } + // fall through to defwinproc... + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + + } + + return (LRESULT)0; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +//////////////////////////////////////////////////////////////////////// +// +// OCX Interfaces for CDsoFramerControl +// +// NOTE: The automation interfaces are implemented in dsofauto.cpp. +// The interfaces that follow are largely the interfaces used by the +// OCX host for normal control containment. +// + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XInternalUnknown -- Internal IUnknown interface +// !!! Controls lifetime of CDsoFramerControl !!! +// +// STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); +// STDMETHODIMP_(ULONG) AddRef(void); +// STDMETHODIMP_(ULONG) Release(void); +// +STDMETHODIMP CDsoFramerControl::XInternalUnknown::QueryInterface(REFIID riid, void** ppv) +{ + // ODS("CDsoFramerControl::InternalQueryInterface\n"); + CHECK_NULL_RETURN(ppv, E_POINTER); + + HRESULT hr = S_OK; + METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown); + + if (IID_IUnknown == riid) + { + *ppv = (IUnknown*)this; + } + else if ((IID_IDispatch == riid) || (IID__FramerControl == riid)) + { + *ppv = (_FramerControl*)pThis; + } + else if (IID_IOleObject == riid) + { + *ppv = (IOleObject*)&(pThis->m_xOleObject); + } + else if (IID_IOleControl == riid) + { + *ppv = (IOleControl*)&(pThis->m_xOleControl); + } + else if (IID_IPersistPropertyBag == riid) + { + *ppv = (IPersistPropertyBag*)&(pThis->m_xPersistPropertyBag); + } + else if ((IID_IPersistStreamInit == riid) || (IID_IPersistStream == riid) || (IID_IPersist == riid)) + { + *ppv = (IPersistStreamInit*)&(pThis->m_xPersistStreamInit); + } + else if ((IID_IOleInPlaceObject == riid) || (IID_IOleWindow == riid)) + { + *ppv = (IOleInPlaceObject*)&(pThis->m_xOleInplaceObject); + } + else if (IID_IOleInPlaceActiveObject == riid) + { + *ppv = (IOleInPlaceActiveObject*)&(pThis->m_xOleInplaceActiveObject); + } + else if ((IID_IViewObjectEx == riid) || (IID_IViewObject == riid) || (IID_IViewObject2 == riid)) + { + *ppv = (IViewObjectEx*)&(pThis->m_xViewObjectEx); + } + else if (IID_IDataObject == riid) + { + *ppv = (IDataObject*)&(pThis->m_xDataObject); + } + else if (IID_ISupportErrorInfo == riid) + { + *ppv = (ISupportErrorInfo*)&(pThis->m_xSupportErrorInfo); + } + else if (IID_IProvideClassInfo == riid) + { + *ppv = (IProvideClassInfo*)&(pThis->m_xProvideClassInfo); + } + else if (IID_IConnectionPointContainer == riid) + { + *ppv = (IConnectionPointContainer*)&(pThis->m_xConnectionPointContainer); + } + else if (IID_IConnectionPoint == riid) + { + *ppv = (IConnectionPoint*)&(pThis->m_xConnectionPoint); + } + else if (IID_IEnumConnectionPoints == riid) + { + *ppv = (IEnumConnectionPoints*)&(pThis->m_xEnumConnectionPoints); + } + else if (IID_IPersistStorage == riid) + { + *ppv = (IPersistStorage*)&(pThis->m_xPersistStorage); + } + else if (IID_IObjectSafety == riid) + { + *ppv = (IObjectSafety*)&(pThis->m_xObjectSafety); + } + else if (IID_IOleCommandTarget == riid) + { + *ppv = (IOleCommandTarget*)&(pThis->m_xOleCommandTarget); + } + else if ((IID_IDsoDocObjectSite == riid) || (IID_IServiceProvider == riid)) + { + *ppv = (IDsoDocObjectSite*)&(pThis->m_xDsoDocObjectSite); + } + else + { + *ppv = NULL; + hr = E_NOINTERFACE; + } + + if (NULL != *ppv) // AddRef those interfaces we will return... + ((IUnknown*)(*ppv))->AddRef(); + + return hr; +} + +STDMETHODIMP_(ULONG) CDsoFramerControl::XInternalUnknown::AddRef(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown); + //TRACE1("CDsoFramerControl::InternalAddRef - %d\n", (pThis->m_cRef + 1)); + return ++(pThis->m_cRef); +} + +STDMETHODIMP_(ULONG) CDsoFramerControl::XInternalUnknown::Release(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown); + //TRACE1("CDsoFramerControl::InternalRelease - %d\n", (pThis->m_cRef - 1)); + if (0 != --(pThis->m_cRef)) return (pThis->m_cRef); + ODS("CDsoFramerControl delete\n"); + InterlockedDecrement((LPLONG)&v_cLocks); + delete pThis; return 0; +} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XPersistStreamInit -- IPersistStreamInit Implementation +// +// STDMETHODIMP GetClassID(CLSID *pClassID); +// STDMETHODIMP IsDirty(void); +// STDMETHODIMP Load(LPSTREAM pStm); +// STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty); +// STDMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize); +// STDMETHODIMP InitNew(void); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistStreamInit) + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::GetClassID(CLSID *pClassID) +{ + ODS("CDsoFramerControl::XPersistStreamInit::GetClassID\n"); + if (pClassID) *pClassID = CLSID_FramerControl; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::IsDirty(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit); + ODS("CDsoFramerControl::XPersistStreamInit::IsDirty\n"); + return (pThis->m_fDirty) ? S_OK : S_FALSE; +} + + +#define STREAMHDR_SIGNATURE_OLD 0x1234ABCD // Signature to identify our format (avoid crashes!) +#define STREAMHDR_SIGNATURE_NEW 0xD501D501 // Signature to identify our format (avoid crashes!) + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::Load(LPSTREAM pStm) +{ + HRESULT hr; + DWORD dwSig, dwT; + + METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit); + ODS("CDsoFramerControl::XPersistStreamInit::Load\n"); + + // look for our header structure, so we can verify stream validity. + hr = pStm->Read(&dwSig, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + if ((dwSig != STREAMHDR_SIGNATURE_NEW) && + (dwSig != STREAMHDR_SIGNATURE_OLD)) + return E_UNEXPECTED; + + // we like the stream. let's go load in our two properties. + hr = pStm->Read(&(pThis->m_Size), sizeof(SIZEL), NULL); + RETURN_ON_FAILURE(hr); + + DsoHimetricToPixels(&(pThis->m_Size.cx), &(pThis->m_Size.cy)); + + hr = pStm->Read(&(pThis->m_clrBorderColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Read(&(pThis->m_clrBackColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Read(&(pThis->m_clrForeColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Read(&(pThis->m_clrTBarColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Read(&(pThis->m_clrTBarTextColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Read(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + pThis->m_fBorderStyle = LOBYTE(LOWORD(dwT)); + pThis->m_fShowMenuBar = HIBYTE(LOWORD(dwT)); + pThis->m_fShowToolbars = LOBYTE(HIWORD(dwT)); + pThis->m_fShowTitlebar = HIBYTE(HIWORD(dwT)); + + hr = pStm->Read(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + if (dwT) + { + LPWSTR pwsz = (LPWSTR)DsoMemAlloc(dwT+2); + if (pwsz) + { + hr = pStm->Read(pwsz, dwT, NULL); + if (SUCCEEDED(hr)) + pThis->m_bstrCustomCaption = SysAllocString(pwsz); + } + DsoMemFree(pwsz); + } + + // Read in new properties for 1.3 version control... + if (dwSig == STREAMHDR_SIGNATURE_NEW) + { + DWORD dwValue; + + hr = pStm->Read(&dwValue, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + pThis->m_lActivationPolicy = LOWORD(dwValue); + pThis->m_lHookPolicy = HIWORD(dwValue); + + hr = pStm->Read(&dwValue, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + pThis->m_fDisableMenuAccel = LOBYTE(LOWORD(dwT)); + } + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty) +{ + HRESULT hr; + DWORD dwT, dwSig = STREAMHDR_SIGNATURE_NEW; + SIZEL slSize; + + METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit); + ODS("CDsoFramerControl::XPersistStreamInit::Save\n"); + + // first thing to do is write out our stream sig... + hr = pStm->Write(&dwSig, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + // the only properties we're currently persisting here are the size + // properties for this control. make sure we do that in HiMetric + slSize = pThis->m_Size; + DsoPixelsToHimetric(&(slSize.cx), &(slSize.cy)); + + hr = pStm->Write(&slSize, sizeof(SIZEL), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Write(&(pThis->m_clrBorderColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Write(&(pThis->m_clrBackColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Write(&(pThis->m_clrForeColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Write(&(pThis->m_clrTBarColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + hr = pStm->Write(&(pThis->m_clrTBarTextColor), sizeof(OLE_COLOR), NULL); + RETURN_ON_FAILURE(hr); + + dwT = (DWORD)MAKELONG( + MAKEWORD((BYTE)(pThis->m_fBorderStyle), (BYTE)(pThis->m_fShowMenuBar)), + MAKEWORD((BYTE)(pThis->m_fShowToolbars), (BYTE)(pThis->m_fShowTitlebar))); + + hr = pStm->Write(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + dwT = 0; + if (pThis->m_bstrCustomCaption) + dwT = SysStringByteLen(pThis->m_bstrCustomCaption); + + hr = pStm->Write(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + if (dwT) + { + hr = pStm->Write(pThis->m_bstrCustomCaption, dwT, NULL); + RETURN_ON_FAILURE(hr); + } + + // Version 1.3 added properties... + dwT = (DWORD)MAKELONG((WORD)(pThis->m_lActivationPolicy), (WORD)(pThis->m_lHookPolicy)); + hr = pStm->Write(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + dwT = (DWORD)MAKELONG(MAKEWORD((BYTE)(pThis->m_fDisableMenuAccel), 0), 0); + hr = pStm->Write(&dwT, sizeof(DWORD), NULL); + RETURN_ON_FAILURE(hr); + + // clear out dirty flag and notify that we're done with save. + if (fClearDirty) + pThis->m_fDirty = FALSE; + + if (pThis->m_pOleAdviseHolder) + pThis->m_pOleAdviseHolder->SendOnSave(); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::GetSizeMax(ULARGE_INTEGER *pcbSize) +{ + ODS("CDsoFramerControl::XPersistStreamInit::GetSizeMax\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XPersistStreamInit::InitNew(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit); + ODS("CDsoFramerControl::XPersistStreamInit::InitNew\n"); + // If we are new control, we are dirty by default... + pThis->m_fDirty = TRUE; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XPersistPropertyBag -- IPersistPropertyBag Implementation +// +// STDMETHODIMP GetClassID(CLSID *pClassID); +// STDMETHODIMP InitNew(); +// STDMETHODIMP Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog); +// STDMETHODIMP Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistPropertyBag) + +STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::GetClassID(CLSID *pClassID) +{ + ODS("CDsoFramerControl::XPersistPropertyBag::GetClassID\n"); + if (pClassID) *pClassID = CLSID_FramerControl; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::InitNew() +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag); + ODS("CDsoFramerControl::XPersistPropertyBag::InitNew\n"); + return pThis->m_xPersistStreamInit.InitNew(); +} + +STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog) +{ + VARIANT v; + HRESULT hr; + SIZEL sl = {5000, 3000}; + + METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag); + ODS("CDsoFramerControl::XPersistPropertyBag::Load\n"); + + v.vt = VT_I4; + v.lVal = 0; + + hr = pPropBag->Read(L"_ExtentX", &v, pErrorLog); + if (SUCCEEDED(hr)){sl.cx = v.lVal;} + + v.lVal = 0; + hr = pPropBag->Read(L"_ExtentY", &v, pErrorLog); + if (SUCCEEDED(hr)){sl.cy = v.lVal;} + + DsoHimetricToPixels(&(sl.cx), &(sl.cy)); + pThis->m_Size = sl; + + hr = pPropBag->Read(L"Titlebar", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_fShowTitlebar = v.boolVal;} + + hr = pPropBag->Read(L"Toolbars", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_fShowToolbars = v.boolVal;} + + hr = pPropBag->Read(L"BorderStyle", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_fBorderStyle = v.lVal;} + + hr = pPropBag->Read(L"BorderColor", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_clrBorderColor = v.lVal;} + + hr = pPropBag->Read(L"BackColor", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_clrBackColor = v.lVal;} + + hr = pPropBag->Read(L"ForeColor", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_clrForeColor = v.lVal;} + + hr = pPropBag->Read(L"TitlebarColor", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_clrTBarColor = v.lVal;} + + hr = pPropBag->Read(L"TitlebarTextColor", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_clrTBarTextColor = v.lVal;} + + hr = pPropBag->Read(L"Caption", &v, pErrorLog); + if (SUCCEEDED(hr)) + { + LPWSTR pwsz = LPWSTR_FROM_VARIANT(v); + if (pwsz) pThis->m_bstrCustomCaption = SysAllocString(pwsz); + VariantClear(&v); + } + + pThis->m_fShowMenuBar = FALSE; + hr = pPropBag->Read(L"Menubar", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_fShowMenuBar = BOOL_FROM_VARIANT(v, FALSE);} + + hr = pPropBag->Read(L"ActivationPolicy", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_lActivationPolicy = LONG_FROM_VARIANT(v, 0);} + + hr = pPropBag->Read(L"FrameHookPolicy", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_lHookPolicy = LONG_FROM_VARIANT(v, 0);} + + hr = pPropBag->Read(L"MenuAccelerators", &v, pErrorLog); + if (SUCCEEDED(hr)){pThis->m_fDisableMenuAccel = !BOOL_FROM_VARIANT(v, TRUE);} + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties) +{ + HRESULT hr; + VARIANT v; + SIZEL sl; + + METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag); + ODS("CDsoFramerControl::XPersistPropertyBag::Save\n"); + + sl = pThis->m_Size; + DsoPixelsToHimetric(&(sl.cx), &(sl.cy)); + + v.vt = VT_I4; v.lVal = sl.cx; + hr = pPropBag->Write(L"_ExtentX", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = sl.cy; + hr = pPropBag->Write(L"_ExtentY", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_clrBorderColor; + hr = pPropBag->Write(L"BorderColor", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_clrBackColor; + hr = pPropBag->Write(L"BackColor", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_clrForeColor; + hr = pPropBag->Write(L"ForeColor", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_clrTBarColor; + hr = pPropBag->Write(L"TitlebarColor", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_clrTBarTextColor; + hr = pPropBag->Write(L"TitlebarTextColor", &v); + RETURN_ON_FAILURE(hr); + + v.lVal = pThis->m_fBorderStyle; + hr = pPropBag->Write(L"BorderStyle", &v); + RETURN_ON_FAILURE(hr); + + v.vt = VT_BOOL; v.boolVal = pThis->m_fShowTitlebar; + hr = pPropBag->Write(L"Titlebar", &v); + RETURN_ON_FAILURE(hr); + + v.boolVal = pThis->m_fShowToolbars; + hr = pPropBag->Write(L"Toolbars", &v); + RETURN_ON_FAILURE(hr); + + if (pThis->m_bstrCustomCaption) + { + v.vt = VT_BSTR; v.bstrVal = pThis->m_bstrCustomCaption; + hr = pPropBag->Write(L"Caption", &v); + RETURN_ON_FAILURE(hr); + } + + v.vt = VT_BOOL; v.boolVal = pThis->m_fShowMenuBar; + hr = pPropBag->Write(L"Menubar", &v); + RETURN_ON_FAILURE(hr); + + v.vt = VT_I4; v.lVal = pThis->m_lActivationPolicy; + hr = pPropBag->Write(L"ActivationPolicy", &v); + RETURN_ON_FAILURE(hr); + + v.vt = VT_I4; v.lVal = pThis->m_lHookPolicy; + hr = pPropBag->Write(L"FrameHookPolicy", &v); + RETURN_ON_FAILURE(hr); + + v.vt = VT_BOOL; v.boolVal = !(pThis->m_fDisableMenuAccel); + hr = pPropBag->Write(L"MenuAccelerators", &v); + RETURN_ON_FAILURE(hr); + + // now clear the dirty flag and send out notification + // that we're done. + if (fClearDirty) + pThis->m_fDirty = FALSE; + + if (pThis->m_pOleAdviseHolder) + pThis->m_pOleAdviseHolder->SendOnSave(); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XPersistStorage -- IPersistStorage Implementation +// +// STDMETHODIMP GetClassID(CLSID *pClassID); +// STDMETHODIMP IsDirty(void); +// STDMETHODIMP InitNew(LPSTORAGE pStg); +// STDMETHODIMP Load(LPSTORAGE pStg); +// STDMETHODIMP Save(LPSTORAGE pStg, BOOL fSameAsLoad); +// STDMETHODIMP SaveCompleted(LPSTORAGE pStg); +// STDMETHODIMP HandsOffStorage(void); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistStorage) + +STDMETHODIMP CDsoFramerControl::XPersistStorage::GetClassID(CLSID *pClassID) +{ + ODS("CDsoFramerControl::XPersistStorage::GetClassID\n"); + if (pClassID) *pClassID = CLSID_FramerControl; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::IsDirty(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::IsDirty\n"); + return (pThis->m_fDirty) ? S_OK : S_FALSE; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::InitNew(LPSTORAGE pStg) +{ + HRESULT hr; + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::InitNew\n"); + + CHECK_NULL_RETURN(pStg, E_POINTER); + SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage); + + hr = pThis->m_xPersistStreamInit.InitNew(); + if (SUCCEEDED(hr)) + { SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg); }; + + return hr; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::Load(LPSTORAGE pStg) +{ + HRESULT hr; + IStream* pstm; + DWORD dwStmMode = (STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE); + + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::Load\n"); + + CHECK_NULL_RETURN(pStg, E_POINTER); + SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage); + + hr = pStg->OpenStream(L"DsoFrameCtlContents", 0, dwStmMode, 0, &pstm); + if (SUCCEEDED(hr) && (pstm)) + { + hr = pThis->m_xPersistStreamInit.Load(pstm); + if (SUCCEEDED(hr)) + { SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg); }; + + pstm->Release(); + } + + return hr; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::Save(LPSTORAGE pStg, BOOL fSameAsLoad) +{ + HRESULT hr; + IStream* pstm; + DWORD dwStmMode = (STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE); + + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::Save\n"); + + if (fSameAsLoad) + { + if ((pThis->m_pOleStorage == NULL) || + ((pStg) && (pStg != pThis->m_pOleStorage))) + { + SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage); + SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg); + } + + CHECK_NULL_RETURN(pThis->m_pOleStorage, E_POINTER); + pStg = pThis->m_pOleStorage; + } + + CHECK_NULL_RETURN(pStg, E_POINTER); + + hr = pStg->OpenStream(L"DsoFrameCtlContents", 0, dwStmMode, 0, &pstm); + if (hr == STG_E_FILENOTFOUND) + hr = pStg->CreateStream(L"DsoFrameCtlContents", dwStmMode, 0, 0, &pstm); + + if (SUCCEEDED(hr) && (pstm)) + { + hr = pThis->m_xPersistStreamInit.Save(pstm, FALSE); + pstm->Release(); + } + + return hr; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::SaveCompleted(LPSTORAGE pStg) +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::SaveCompleted\n"); + pThis->m_fDirty = FALSE; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XPersistStorage::HandsOffStorage(void) +{ + METHOD_PROLOGUE(CDsoFramerControl, PersistStorage); + ODS("CDsoFramerControl::XPersistStorage::HandsOffStorage\n"); + SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XOleObject -- IOleObject Implementation +// +// STDMETHODIMP SetClientSite(IOleClientSite *pClientSite); +// STDMETHODIMP GetClientSite(IOleClientSite **ppClientSite); +// STDMETHODIMP SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj); +// STDMETHODIMP Close(DWORD dwSaveOption); +// STDMETHODIMP SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk); +// STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk); +// STDMETHODIMP InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved); +// STDMETHODIMP GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject); +// STDMETHODIMP DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect); +// STDMETHODIMP EnumVerbs(IEnumOleVerb **ppEnumOleVerb); +// STDMETHODIMP Update(); +// STDMETHODIMP IsUpToDate(); +// STDMETHODIMP GetUserClassID(CLSID *pClsid); +// STDMETHODIMP GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType); +// STDMETHODIMP SetExtent(DWORD dwDrawAspect, SIZEL *psizel); +// STDMETHODIMP GetExtent(DWORD dwDrawAspect, SIZEL *psizel); +// STDMETHODIMP Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection); +// STDMETHODIMP Unadvise(DWORD dwConnection); +// STDMETHODIMP EnumAdvise(IEnumSTATDATA **ppenumAdvise); +// STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus); +// STDMETHODIMP SetColorScheme(LOGPALETTE *pLogpal); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleObject) + +STDMETHODIMP CDsoFramerControl::XOleObject::SetClientSite(IOleClientSite *pClientSite) +{ + + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::SetClientSite\n"); + + SAFE_RELEASE_INTERFACE(pThis->m_pClientSite); + SAFE_RELEASE_INTERFACE(pThis->m_pControlSite); + + // store away the new client site + pThis->m_pClientSite = pClientSite; + + // if we've actually got one, then get some other interfaces we want to keep + // around, and keep a handle on it + if (pClientSite) + { + pClientSite->AddRef(); + pClientSite->QueryInterface(IID_IOleControlSite, (void **)&(pThis->m_pControlSite)); + } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetClientSite(IOleClientSite **ppClientSite) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::GetClientSite\n"); + if (ppClientSite) { SAFE_SET_INTERFACE(*ppClientSite, pThis->m_pClientSite); } + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::SetHostNames(LPCOLESTR /*szContainerApp*/, LPCOLESTR /*szContainerObj*/) +{ + ODS("CDsoFramerControl::XOleObject::SetHostNames\n"); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::Close(DWORD dwSaveOption) +{ + HRESULT hr; + + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::Close\n"); + + if (pThis->m_fInPlaceActive) + { + hr = pThis->m_xOleInplaceObject.InPlaceDeactivate(); + RETURN_ON_FAILURE(hr); + } + + // handle the save flag. + if ((pThis->m_fDirty) && (pThis->m_pClientSite) && + (dwSaveOption == OLECLOSE_SAVEIFDIRTY || + dwSaveOption == OLECLOSE_PROMPTSAVE)) + { + pThis->m_pClientSite->SaveObject(); + } + + if (pThis->m_pOleAdviseHolder) + pThis->m_pOleAdviseHolder->SendOnClose(); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk) +{ + ODS("CDsoFramerControl::XOleObject::SetMoniker\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk) +{ + ODS("CDsoFramerControl::XOleObject::GetMoniker\n"); + if (ppmk) *ppmk = NULL; + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved) +{ + ODS("CDsoFramerControl::XOleObject::InitFromData\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetClipboardData(DWORD /*dwReserved*/, IDataObject **ppDataObject) +{ + ODS("CDsoFramerControl::XOleObject::GetClipboardData\n"); + if (ppDataObject) *ppDataObject = NULL; + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::DoVerb\n"); + + switch (iVerb) + { + case OLEIVERB_PRIMARY: + case OLEIVERB_SHOW: + case OLEIVERB_INPLACEACTIVATE: + case OLEIVERB_UIACTIVATE: + return pThis->InPlaceActivate(iVerb); + + case OLEIVERB_HIDE: + pThis->m_xOleInplaceObject.UIDeactivate(); + if (pThis->m_fInPlaceVisible) + pThis->SetInPlaceVisible(FALSE); + return S_OK; + } + + return OLEOBJ_S_INVALIDVERB; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb) +{ + ODS("CDsoFramerControl::XOleObject::EnumVerbs\n"); + return OleRegEnumVerbs(CLSID_FramerControl, ppEnumOleVerb); +} + +STDMETHODIMP CDsoFramerControl::XOleObject::Update() +{ + ODS("CDsoFramerControl::XOleObject::Update\n"); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::IsUpToDate() +{ + ODS("CDsoFramerControl::XOleObject::IsUpToDate\n"); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetUserClassID(CLSID *pClsid) +{ + ODS("CDsoFramerControl::XOleObject::GetUserClassID\n"); + if (pClsid) *pClsid = CLSID_FramerControl; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType) +{ + ODS("CDsoFramerControl::XOleObject::GetUserType\n"); + return OleRegGetUserType(CLSID_FramerControl, dwFormOfType, pszUserType); +} + +STDMETHODIMP CDsoFramerControl::XOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *psizel) +{ + SIZEL sl; + + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::SetExtent\n"); + + CHECK_NULL_RETURN(psizel, E_POINTER); + sl = *psizel; + + // we don't support any other aspects. + if (!(dwDrawAspect & DVASPECT_CONTENT)) + return DV_E_DVASPECT; + + // change the units to pixels, and resize the control. + DsoHimetricToPixels(&(sl.cx), &(sl.cy)); + + // if the size already matches the extents, then don't do anything + // and don't mark the control dirty. + if (sl.cx != pThis->m_Size.cx || sl.cy != pThis->m_Size.cy) + { + pThis->m_Size = sl; + pThis->m_fDirty = TRUE; // changing size should dirty + + if (pThis->m_fInPlaceActive) + { + RECT rect; + + // Use OnPosRectChange for older OCX containters and Access + // who just refuses to get with the times (like me )... + GetWindowRect(pThis->m_hwnd, &rect); + MapWindowPoints(NULL, pThis->m_hwndParent, (LPPOINT)&rect, 2); + rect.right = rect.left + sl.cx; + rect.bottom = rect.top + sl.cy; + pThis->m_pInPlaceSite->OnPosRectChange(&rect); + + // Resize the window based on the new size... + SetWindowPos(pThis->m_hwnd, NULL, 0, 0, sl.cx, sl.cy, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + else pThis->ViewChanged(); + } + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *psizel) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::GetExtent\n"); + + CHECK_NULL_RETURN(psizel, E_POINTER); + + if (!(dwDrawAspect & DVASPECT_CONTENT)) + return DV_E_DVASPECT; + + *psizel = pThis->m_Size; + DsoPixelsToHimetric(&(psizel->cx), &(psizel->cy)); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::Advise\n"); + + if (NULL == pThis->m_pOleAdviseHolder) + { + if (FAILED(CreateOleAdviseHolder(&(pThis->m_pOleAdviseHolder)))) + return E_FAIL; + } + return pThis->m_pOleAdviseHolder->Advise(pAdvSink, pdwConnection); +} + +STDMETHODIMP CDsoFramerControl::XOleObject::Unadvise(DWORD dwConnection) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::Unadvise\n"); + + CHECK_NULL_RETURN(pThis->m_pOleAdviseHolder, CONNECT_E_NOCONNECTION); + return pThis->m_pOleAdviseHolder->Unadvise(dwConnection); +} + +STDMETHODIMP CDsoFramerControl::XOleObject::EnumAdvise(IEnumSTATDATA **ppenumAdvise) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleObject); + ODS("CDsoFramerControl::XOleObject::EnumAdvise\n"); + + CHECK_NULL_RETURN(ppenumAdvise, E_POINTER); + *ppenumAdvise = NULL; + + CHECK_NULL_RETURN(pThis->m_pOleAdviseHolder, E_FAIL); + return pThis->m_pOleAdviseHolder->EnumAdvise(ppenumAdvise); +} + +STDMETHODIMP CDsoFramerControl::XOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus) +{ + ODS("CDsoFramerControl::XOleObject::GetMiscStatus\n"); + + if (dwAspect != DVASPECT_CONTENT) + return DV_E_DVASPECT; + + if (pdwStatus) + *pdwStatus = OLEMISC_SETCLIENTSITEFIRST | + OLEMISC_ACTIVATEWHENVISIBLE | + OLEMISC_RECOMPOSEONRESIZE | + OLEMISC_CANTLINKINSIDE | + OLEMISC_INSIDEOUT; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleObject::SetColorScheme(LOGPALETTE *pLogpal) +{ + ODS("CDsoFramerControl::XOleObject::SetColorScheme\n"); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XOleControl -- IOleControl Implementation +// +// STDMETHODIMP GetControlInfo(CONTROLINFO* pCI); +// STDMETHODIMP OnMnemonic(LPMSG pMsg); +// STDMETHODIMP OnAmbientPropertyChange(DISPID dispID); +// STDMETHODIMP FreezeEvents(BOOL bFreeze); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleControl) + +STDMETHODIMP CDsoFramerControl::XOleControl::GetControlInfo(CONTROLINFO* pCI) +{ + ODS("CDsoFramerControl::XOleControl::GetControlInfo\n"); + CHECK_NULL_RETURN(pCI, E_POINTER); + pCI->hAccel = NULL; pCI->cAccel = 0; pCI->dwFlags = 0; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleControl::OnMnemonic(LPMSG pMsg) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleControl); + ODS("CDsoFramerControl::XOleControl::OnMnemonic\n"); + return pThis->InPlaceActivate(OLEIVERB_UIACTIVATE); +} + +STDMETHODIMP CDsoFramerControl::XOleControl::OnAmbientPropertyChange(DISPID dispID) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleControl); + ODS("CDsoFramerControl::XOleControl::OnAmbientPropertyChange\n"); + + // We keep track of state changes in design/run modes... + if (dispID == DISPID_AMBIENT_USERMODE || dispID == DISPID_UNKNOWN) + pThis->m_fModeFlagValid = FALSE; + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleControl::FreezeEvents(BOOL bFreeze) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleControl); + TRACE1("CDsoFramerControl::XOleControl::FreezeEvents = %s\n", (bFreeze ? "TRUE" : "FALSE")); + pThis->m_fFreezeEvents = bFreeze; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XOleInplaceObject -- IOleInplaceObject Implementation +// +// STDMETHODIMP GetWindow(HWND *phwnd); +// STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); +// STDMETHODIMP InPlaceDeactivate(); +// STDMETHODIMP UIDeactivate(); +// STDMETHODIMP SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect); +// STDMETHODIMP ReactivateAndUndo(); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleInplaceObject) + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::GetWindow(HWND *phwnd) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject); + ODS("CDsoFramerControl::XOleInplaceObject::GetWindow\n"); + if (!(pThis->m_fInPlaceActive)) return E_FAIL; + if (phwnd) *phwnd = pThis->m_hwnd; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::ContextSensitiveHelp(BOOL /*fEnterMode*/) +{ + ODS("CDsoFramerControl::XOleInplaceObject::ContextSensitiveHelp\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::InPlaceDeactivate() +{ + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject); + ODS("CDsoFramerControl::XOleInplaceObject::InPlaceDeactivate\n"); + + // if we're not in-place active yet, then this is easy. + if (!(pThis->m_fInPlaceActive)) + return S_OK; + + // transition from UIActive back to active + if (pThis->m_fUIActive) + UIDeactivate(); + + // tell the host we're going away + pThis->m_pInPlaceSite->OnInPlaceDeactivate(); + + pThis->m_fInPlaceActive = FALSE; + pThis->m_fInPlaceVisible = FALSE; + + // if we have a window, tell it to go away. + if (pThis->m_hwnd) + {DestroyWindow(pThis->m_hwnd); pThis->m_hwnd = NULL;} + + SAFE_RELEASE_INTERFACE(pThis->m_pInPlaceFrame); + SAFE_RELEASE_INTERFACE(pThis->m_pInPlaceUIWindow); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::UIDeactivate() +{ + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject); + ODS("CDsoFramerControl::XOleInplaceObject::UIDeactivate\n"); + + // if we're not UIActive, not much to do. + if (!(pThis->m_fUIActive)) + return S_OK; + + pThis->m_fUIActive = FALSE; + + // notify frame windows, if appropriate, that we're no longer ui-active. + if (pThis->m_pInPlaceUIWindow) + pThis->m_pInPlaceUIWindow->SetActiveObject(NULL, NULL); + + if (pThis->m_pInPlaceFrame) + pThis->m_pInPlaceFrame->SetActiveObject(NULL, NULL); + + pThis->OnUIFocusChange(FALSE); + + // we don't need to explicitly release the focus here since somebody + // else grabbing the focus is what is likely to cause us to get lose it + pThis->m_pInPlaceSite->OnUIDeactivate(FALSE); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect) +{ + RECT rcIXect; + + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject); + ODS("CDsoFramerControl::XOleInplaceObject::SetObjectRects\n"); + + // move our window to the new location and handle clipping. + if (pThis->m_hwnd) + { + // if asked to clip the window, we'll use a clip region... + if ((lprcClipRect) && (IntersectRect(&rcIXect, lprcPosRect, lprcClipRect)) && + (!EqualRect(&rcIXect, lprcPosRect))) + { + OffsetRect(&rcIXect, -(lprcPosRect->left), -(lprcPosRect->top)); + SetWindowRgn(pThis->m_hwnd, CreateRectRgnIndirect(&rcIXect), TRUE); + pThis->m_fUsingWindowRgn = TRUE; + } + else if (pThis->m_fUsingWindowRgn) + { + SetWindowRgn(pThis->m_hwnd, NULL, TRUE); + pThis->m_fUsingWindowRgn = FALSE; + } + + // set our control's location, but don't change it's size at all + // [people for whom zooming is important should set that up here] + SetWindowPos(pThis->m_hwnd, NULL, lprcPosRect->left, lprcPosRect->top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + + // save out our current location. + pThis->m_rcLocation = *lprcPosRect; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceObject::ReactivateAndUndo() +{ + ODS("CDsoFramerControl::XOleInplaceObject::ReactivateAndUndo\n"); + return E_NOTIMPL; +} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XOleInplaceActiveObject -- IOleInplaceActiveObject Implementation +// +// STDMETHODIMP GetWindow(HWND *phwnd); +// STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); +// STDMETHODIMP TranslateAccelerator(LPMSG lpmsg); +// STDMETHODIMP OnFrameWindowActivate(BOOL fActivate); +// STDMETHODIMP OnDocWindowActivate(BOOL fActivate); +// STDMETHODIMP ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow); +// STDMETHODIMP EnableModeless(BOOL fEnable); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleInplaceActiveObject) + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::GetWindow(HWND *phwnd) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject); + ODS("CDsoFramerControl::XOleInplaceActiveObject::GetWindow\n"); + if (phwnd) *phwnd = pThis->m_hwnd; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::ContextSensitiveHelp(BOOL /*fEnterMode*/) +{ + ODS("CDsoFramerControl::XOleInplaceActiveObject::ContextSensitiveHelp\n"); + return E_NOTIMPL; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator +// +// We handle certain keys as accelerators, but only if host does not +// implement it itself, and only when no document is open. The reason +// why is due to two factors: +// +// (1) When an out-of-proc AxDoc server is embedded and has focus, +// its thread (not ours) gets the accel keys. Word/PPT will treat +// these for us and contact us through IOleCommandTarget, so +// we don't want to handle them if AxDoc is handling them for us. +// +// (2) We cannot know if a given host uses the same accel keys for +// other tasks, and we don't want to impose ours on a host. By +// explicitly asking host to handle it first, we should be able +// to avoid any conflicts, and give developer a change to override +// our handler as needed. +// +static short _SpecialKeyState() +{ + BOOL bShift = (GetKeyState(VK_SHIFT) < 0); + BOOL bCtrl = (GetKeyState(VK_CONTROL) < 0); + BOOL bAlt = (GetKeyState(VK_MENU) < 0); + return (short)(bShift + (bCtrl << 1) + (bAlt << 2)); +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator(LPMSG lpmsg) +{ + HRESULT hr = S_FALSE; + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject); + CHECK_NULL_RETURN(lpmsg, E_POINTER); + TRACE2("CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator(msg=%d, wparam=%d)\n", lpmsg->message, lpmsg->wParam); + + // Forward it back to the site for processing on its side... + if (pThis->m_pControlSite) + { + hr = pThis->m_pControlSite->TranslateAccelerator(lpmsg, _SpecialKeyState()); + if (hr == S_OK) return S_OK; // If site handled it, nothing else we need to do.. + } + + if ((GetKeyState(VK_CONTROL) < 0) && (!(pThis->m_fModalState)) && + (lpmsg->message == WM_KEYUP) && (!(pThis->m_pDocObjFrame))) + { + TRACE1(" Handle Accelerator? (%d)\n", lpmsg->wParam); + switch (lpmsg->wParam) // Looking for Ctrl+N and Ctrl+O keys... + { + case 0x4E: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_NEW, 0); hr = S_OK; break; + case 0x4F: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_OPEN, 0); hr = S_OK; break; + case 0x53: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_SAVE, 0); hr = S_OK; break; + } + } + + // we didn't want it. + return hr; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::OnFrameWindowActivate(BOOL fActivate) +{ + TRACE1("CDsoFramerControl::XOleInplaceActiveObject::OnFrameWindowActivate - %d\n", fActivate); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::OnDocWindowActivate(BOOL fActivate) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject); + TRACE1("CDsoFramerControl::XOleInplaceActiveObject::OnDocWindowActivate - %d\n", fActivate); + + if (pThis->m_fUIActive && fActivate && pThis->m_pInPlaceFrame) + pThis->m_pInPlaceFrame->SetBorderSpace(NULL); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow) +{ + ODS("CDsoFramerControl::XOleInplaceActiveObject::ResizeBorder\n"); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::EnableModeless(BOOL fEnable) +{ + TRACE1("CDsoFramerControl::XOleInplaceActiveObject::EnableModeless(%d)\n", fEnable); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XViewObjectEx -- IViewObjectEx Implementation +// +// STDMETHODIMP Draw(DWORD dwAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, HDC hdcDraw, const LPRECTL lprcBounds, const LPRECTL lprcWBounds, BOOL(*)(DWORD)pfnContinue, DWORD dwContinue); +// STDMETHODIMP GetColorSet(DWORD dwAspect, LONG lindex, void* pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE** ppColorSet); +// STDMETHODIMP Freeze(DWORD dwAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze); +// STDMETHODIMP Unfreeze(DWORD dwFreeze); +// STDMETHODIMP SetAdvise(DWORD dwAspect, DWORD advf, IAdviseSink* pAdvSink); +// STDMETHODIMP GetAdvise(DWORD* pdwAspect, DWORD* padvf, IAdviseSink** ppAdvSink); +// STDMETHODIMP GetExtent(DWORD dwAspect, DWORD lindex, DVTARGETDEVICE ptd, LPSIZEL lpsizel); +// STDMETHODIMP GetRect(DWORD dwAspect, LPRECTL pRect); +// STDMETHODIMP GetViewStatus(DWORD* pdwStatus); +// STDMETHODIMP QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult); +// STDMETHODIMP QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult); +// STDMETHODIMP GetNaturalExtent(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ViewObjectEx) + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::Draw(DWORD dwDrawAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, HDC hdcDraw, LPCRECTL prcBounds, LPCRECTL prcWBounds, BOOL (__stdcall *pfnContinue)(DWORD dwContinue), DWORD dwContinue) +{ + RECT rc; + int iMode = 0; + POINT pVp = {0,0}; + POINT pW = {0,0}; + BOOL fOptimize = FALSE; + BOOL fMetafile = FALSE; + + METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx); + ODS("CDsoFramerControl::XViewObjectEx::Draw\n"); + + if (!((dwDrawAspect == DVASPECT_CONTENT) || + (dwDrawAspect == DVASPECT_OPAQUE))) + return DV_E_DVASPECT; + + SaveDC(hdcDraw); + + // first, have to do a little bit to support printing. + if (GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE) + { + // We are dealing with a metafile. + fMetafile = TRUE; + } +/* + // check to see if we have any flags passed in the pvAspect parameter. + if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb == sizeof(DVASPECTINFO)) + fOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE) ? TRUE : FALSE; +*/ + // Get the draw rect, if they didn't give us one, just copy over ours + memcpy(&rc, ((prcBounds) ? (RECT*)prcBounds : &(pThis->m_rcLocation)), sizeof(RECT)); + + if (!fMetafile) + { + LPtoDP(hdcDraw, (POINT*)&rc, 2); + SetViewportOrgEx(hdcDraw, 0, 0, &pVp); + SetWindowOrgEx(hdcDraw, 0, 0, &pW); + iMode = SetMapMode(hdcDraw, MM_TEXT); + } + + // prcWBounds is NULL and not used if we are not dealing with a metafile. + // For metafiles, we pass on rc as *prcBounds, we should also include prcWBounds + pThis->OnDraw(dwDrawAspect, hdcDraw, &rc, (RECT*)prcWBounds, hicTargetDevice, fOptimize); + + // clean up the DC when we're done with it, if appropriate. + if (!fMetafile) + { + SetViewportOrgEx(hdcDraw, pVp.x, pVp.y, NULL); + SetWindowOrgEx(hdcDraw, pW.x, pW.y, NULL); + SetMapMode(hdcDraw, iMode); + } + + RestoreDC(hdcDraw, -1); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetColorSet(DWORD dwAspect, LONG lindex, void* pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE** ppColorSet) +{ + ODS("CDsoFramerControl::XViewObjectEx::GetColorSet\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::Freeze(DWORD dwAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze) +{ + ODS("CDsoFramerControl::XViewObjectEx::Freeze\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::Unfreeze(DWORD dwFreeze) +{ + ODS("CDsoFramerControl::XViewObjectEx::Unfreeze\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::SetAdvise(DWORD dwAspect, DWORD advf, IAdviseSink* pAdviseSink) +{ + METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx); + ODS("CDsoFramerControl::XViewObjectEx::SetAdvise\n"); + + // if it's not a content aspect, we don't support it. + if (!(dwAspect & DVASPECT_CONTENT)) + return DV_E_DVASPECT; + + // set up some flags [we gotta stash for GetAdvise ...] + pThis->m_fViewAdvisePrimeFirst = (advf & ADVF_PRIMEFIRST) ? TRUE : FALSE; + pThis->m_fViewAdviseOnlyOnce = (advf & ADVF_ONLYONCE) ? TRUE : FALSE; + + SAFE_RELEASE_INTERFACE(pThis->m_pViewAdviseSink); + SAFE_SET_INTERFACE(pThis->m_pViewAdviseSink, pAdviseSink); + + // prime them if they want it [we need to store this so they can get flags later] + if (pThis->m_fViewAdvisePrimeFirst) + pThis->ViewChanged(); + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetAdvise(DWORD* pdwAspect, DWORD* padvf, IAdviseSink** ppAdviseSink) +{ + METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx); + ODS("CDsoFramerControl::XViewObjectEx::GetAdvise\n"); + + if (pdwAspect) + *pdwAspect = DVASPECT_CONTENT; + + if (padvf) + { + *padvf = 0; + if (pThis->m_fViewAdviseOnlyOnce) *padvf |= ADVF_ONLYONCE; + if (pThis->m_fViewAdvisePrimeFirst) *padvf |= ADVF_PRIMEFIRST; + } + + if (ppAdviseSink) + { SAFE_SET_INTERFACE(*ppAdviseSink, pThis->m_pViewAdviseSink); } + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL psizel) +{ + METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx); + ODS("CDsoFramerControl::XViewObjectEx::GetExtent\n"); + return pThis->m_xOleObject.GetExtent(dwDrawAspect, psizel); +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetRect(DWORD dwAspect, LPRECTL pRect) +{ + METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx); + ODS("CDsoFramerControl::XViewObjectEx::GetRect\n"); + + if (dwAspect != DVASPECT_CONTENT) + return DV_E_DVASPECT; + + if (pRect) + { + CopyRect((LPRECT)pRect, &(pThis->m_rcLocation)); + // Convert to himetric (according to docs, this is required) + DsoPixelsToHimetric(&(pRect->left), &(pRect->top)); + DsoPixelsToHimetric(&(pRect->right), &(pRect->bottom)); + } + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetViewStatus(DWORD* pdwStatus) +{ + ODS("CDsoFramerControl::XViewObjectEx::GetViewStatus\n"); + if (pdwStatus) *pdwStatus = VIEWSTATUS_OPAQUE; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult) +{ + // ODS("CDsoFramerControl::XViewObjectEx::QueryHitPoint\n"); + if (dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT; + CHECK_NULL_RETURN(pHitResult, E_POINTER); + *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult) +{ + RECT rc; + //ODS("CDsoFramerControl::XViewObjectEx::QueryHitRect\n"); + if (dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT; + *pHitResult = IntersectRect(&rc, pRectBounds, pRectLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetNaturalExtent(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel) +{ + ODS("CDsoFramerControl::XViewObjectEx::GetNaturalExtent\n"); + return E_NOTIMPL; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XDataObject -- IDataObject Implementation +// +// STDMETHODIMP Draw(DWORD dwAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, HDC hdcDraw, const LPRECTL lprcBounds, const LPRECTL lprcWBounds, BOOL(*)(DWORD)pfnContinue, DWORD dwContinue); +// STDMETHODIMP GetData(FORMATETC *pfmtc, STGMEDIUM *pstgm); +// STDMETHODIMP GetDataHere(FORMATETC *pfmtc, STGMEDIUM *pstgm); +// STDMETHODIMP QueryGetData(FORMATETC *pfmtc); +// STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pfmtcIn, FORMATETC *pfmtcOut); +// STDMETHODIMP SetData(FORMATETC *pfmtc, STGMEDIUM *pstgm, BOOL fRelease); +// STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum); +// STDMETHODIMP DAdvise(FORMATETC *pfmtc, DWORD advf, IAdviseSink *psink, DWORD *pdwConnection); +// STDMETHODIMP DUnadvise(DWORD dwConnection); +// STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenum); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, DataObject) + +STDMETHODIMP CDsoFramerControl::XDataObject::GetData(FORMATETC *pfmtc, STGMEDIUM *pstgm) +{ + HRESULT hr; + HMETAFILE hwmf; + LPMETAFILEPICT pwmf; + HGLOBAL hmem; + SIZE sizeMetric; + RECT rc; + HDC hdc; + + METHOD_PROLOGUE(CDsoFramerControl, DataObject); + TRACE2("CDsoFramerControl::XDataObject::GetData(%d,%d)\n", pfmtc->cfFormat, pfmtc->tymed); + CHECK_NULL_RETURN(pfmtc, E_POINTER); CHECK_NULL_RETURN(pstgm, E_POINTER); + + // Confirm data requested is a supportted type... + if (FAILED(hr = QueryGetData(pfmtc))) + return hr; + + // If caller wants a metafile of the current object, draw it... + hdc = CreateMetaFileW(NULL); + + sizeMetric.cx = pThis->m_Size.cx; + sizeMetric.cy = pThis->m_Size.cy; + + SetRect(&rc, 0, 0, sizeMetric.cx, sizeMetric.cy); + DsoPixelsToHimetric(&(sizeMetric.cx), &(sizeMetric.cy)); + sizeMetric.cy = -(sizeMetric.cy); + + SetMapMode(hdc, MM_ANISOTROPIC); + SetWindowOrgEx(hdc, 0, 0, NULL); + SetWindowExtEx(hdc, rc.right, rc.bottom, NULL); + + // Delegate to same IViewObject::Draw used by most containers for metafile... + hr = pThis->m_xViewObjectEx.Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, (RECTL*)&rc, NULL, NULL, 0); + ASSERT(SUCCEEDED(hr)); + + if ((hwmf = CloseMetaFile(hdc)) == NULL) + return E_UNEXPECTED; + + // Now allocate the transfer medium and set the metafile... + hmem = GlobalAlloc((GMEM_SHARE|GMEM_MOVEABLE), sizeof(METAFILEPICT)); + if (hmem == NULL) { DeleteMetaFile(hwmf); return STG_E_MEDIUMFULL; } + + pwmf = (LPMETAFILEPICT)GlobalLock(hmem); + if (pwmf) + { + pwmf->hMF = hwmf; + pwmf->mm = MM_ANISOTROPIC; + pwmf->xExt = sizeMetric.cx; + pwmf->yExt = sizeMetric.cy; + GlobalUnlock(hmem); + } + + pstgm->tymed = TYMED_MFPICT; + pstgm->hGlobal = hmem; + pstgm->pUnkForRelease = NULL; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XDataObject::GetDataHere(FORMATETC *pfmtc, STGMEDIUM *pstgm) +{ + ODS("CDsoFramerControl::XDataObject::GetDataHere\n"); + return DV_E_FORMATETC; +} + +STDMETHODIMP CDsoFramerControl::XDataObject::QueryGetData(FORMATETC *pfmtc) +{ + TRACE2("CDsoFramerControl::XDataObject::QueryGetData(%d,%d)\n", pfmtc->cfFormat, pfmtc->tymed); + CHECK_NULL_RETURN(pfmtc, E_POINTER); + + if (pfmtc->cfFormat != CF_METAFILEPICT) + return DV_E_FORMATETC; // We only support WMF for IDataObj presentation. + + if (pfmtc->tymed != TYMED_MFPICT) + return DV_E_TYMED; // It better be in in right format... + + if (pfmtc->dwAspect != DVASPECT_CONTENT) + return DV_E_DVASPECT; // We only do content (not thumbnail or partial)... + + return S_OK; // If here, it looks fine to us... +} + +STDMETHODIMP CDsoFramerControl::XDataObject::GetCanonicalFormatEtc(FORMATETC *pfmtcIn, FORMATETC *pfmtcOut) +{ + ODS("CDsoFramerControl::XDataObject::GetCanonicalFormatEtc\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XDataObject::SetData(FORMATETC *pfmtc, STGMEDIUM *pstgm, BOOL fRelease) +{ + ODS("CDsoFramerControl::XDataObject::SetData\n"); + return E_NOTIMPL; +} + +STDMETHODIMP CDsoFramerControl::XDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum) +{ + ODS("CDsoFramerControl::XDataObject::EnumFormatEtc\n"); + return OleRegEnumFormatEtc(CLSID_FramerControl, dwDirection, ppenum); +} + +STDMETHODIMP CDsoFramerControl::XDataObject::DAdvise(FORMATETC *pfmtc, DWORD advf, IAdviseSink *psink, DWORD *pdwConnection) +{ + METHOD_PROLOGUE(CDsoFramerControl, DataObject); + ODS("CDsoFramerControl::XDataObject::DAdvise\n"); + + // Create OLE Data advise holder to keep sink for us... + if ((NULL == pThis->m_pDataAdviseHolder) && + FAILED(CreateDataAdviseHolder(&(pThis->m_pDataAdviseHolder)))) + return E_FAIL; + + // Add this advise sink for the given format to the collection... + return pThis->m_pDataAdviseHolder->Advise((IDataObject*)&(pThis->m_xDataObject), pfmtc, advf, psink, pdwConnection); +} + +STDMETHODIMP CDsoFramerControl::XDataObject::DUnadvise(DWORD dwConnection) +{ + METHOD_PROLOGUE(CDsoFramerControl, DataObject); + ODS("CDsoFramerControl::XDataObject::DUnadvise\n"); + CHECK_NULL_RETURN(pThis->m_pDataAdviseHolder, CONNECT_E_NOCONNECTION); + return pThis->m_pDataAdviseHolder->Unadvise(dwConnection); +} + +STDMETHODIMP CDsoFramerControl::XDataObject::EnumDAdvise(IEnumSTATDATA **ppenum) +{ + METHOD_PROLOGUE(CDsoFramerControl, DataObject); + ODS("CDsoFramerControl::XDataObject::EnumDAdvise\n"); + CHECK_NULL_RETURN(pThis->m_pDataAdviseHolder, CONNECT_E_NOCONNECTION); + return pThis->m_pDataAdviseHolder->EnumAdvise(ppenum); +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XProvideClassInfo -- IProvideClassInfo Implementation +// +// STDMETHODIMP GetClassInfo(ITypeInfo** ppTI); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ProvideClassInfo) + +STDMETHODIMP CDsoFramerControl::XProvideClassInfo::GetClassInfo(ITypeInfo** ppTI) +{ + ODS("CDsoFramerControl::XProvideClassInfo::GetClassInfo\n"); + return DsoGetTypeInfoEx(LIBID_DSOFramer, 0, + DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, v_hModule, CLSID_FramerControl, ppTI); +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XConnectionPointContainer -- IConnectionPointContainer Implementation +// +// STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppEnum); +// STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ConnectionPointContainer) + +STDMETHODIMP CDsoFramerControl::XConnectionPointContainer::EnumConnectionPoints(IEnumConnectionPoints **ppEnum) +{ + METHOD_PROLOGUE(CDsoFramerControl, ConnectionPointContainer); + ODS("CDsoFramerControl::XConnectionPointContainer::EnumConnectionPoints\n"); + if (ppEnum) { SAFE_SET_INTERFACE(*ppEnum, &(pThis->m_xEnumConnectionPoints)); }; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP) +{ + METHOD_PROLOGUE(CDsoFramerControl, ConnectionPointContainer); + ODS("CDsoFramerControl::XConnectionPointContainer::FindConnectionPoint\n"); + if (riid != DIID__DFramerCtlEvents) return CONNECT_E_NOCONNECTION; + if (ppCP) { SAFE_SET_INTERFACE(*ppCP, &(pThis->m_xConnectionPoint)); }; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XEnumConnectionPoints -- IEnumConnectionPoints Implementation +// +// STDMETHODIMP Next(ULONG cConnections, IConnectionPoint **rgpcn, ULONG *pcFetched); +// STDMETHODIMP Skip(ULONG cConnections); +// STDMETHODIMP Reset(void); +// STDMETHODIMP Clone(IEnumConnectionPoints **ppEnum); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, EnumConnectionPoints) + +STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Next(ULONG cConnections, IConnectionPoint **rgpcn, ULONG *pcFetched) +{ + HRESULT hr = S_FALSE; + + METHOD_PROLOGUE(CDsoFramerControl, EnumConnectionPoints); + ODS("CDsoFramerControl::XEnumConnectionPoints::Next\n"); + + CHECK_NULL_RETURN(rgpcn, E_POINTER); + *rgpcn = NULL; + + CHECK_NULL_RETURN(pcFetched, E_POINTER); + *pcFetched = 0; + + if (pThis->m_fConCntDone) + pThis->m_fConCntDone = FALSE; + else + { + SAFE_SET_INTERFACE(*rgpcn, &(pThis->m_xConnectionPoint)); + *pcFetched = 1; + pThis->m_fConCntDone = TRUE; hr = S_OK; + } + + return hr; +} + +STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Skip(ULONG cConnections) +{return S_OK;} + +STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Reset(void) +{return S_OK;} + +STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum) +{if (ppEnum) *ppEnum = this; return S_OK;} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XConnectionPoint -- IConnectionPoint Implementation +// +// STDMETHODIMP GetConnectionInterface(IID *pIID); +// STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer **ppCPC); +// STDMETHODIMP Advise(IUnknown *pUnk, DWORD *pdwCookie); +// STDMETHODIMP Unadvise(DWORD dwCookie); +// STDMETHODIMP EnumConnections(IEnumConnections **ppEnum); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ConnectionPoint) + +STDMETHODIMP CDsoFramerControl::XConnectionPoint::GetConnectionInterface(IID *pIID) +{ + ODS("CDsoFramerControl::XConnectionPoint::GetConnectionInterface\n"); + if (pIID) *pIID = DIID__DFramerCtlEvents; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC) +{ + METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint); + ODS("CDsoFramerControl::XConnectionPoint::GetConnectionPointContainer\n"); + if (ppCPC) { SAFE_SET_INTERFACE(*ppCPC, &(pThis->m_xConnectionPointContainer)); }; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie) +{ + METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint); + ODS("CDsoFramerControl::XConnectionPoint::Advise\n"); + + CHECK_NULL_RETURN(pUnk, E_POINTER); + CHECK_NULL_RETURN(pdwCookie, E_POINTER); + + SAFE_RELEASE_INTERFACE(pThis->m_dispEvents); + + // FIX: The COM Interop layer in .NET CLR returns a different RCW for IDispatch than for a specific + // dispinterface GUID, so for events to work in .NET WinForm applications, we should explicitly use + // the RCW for that dispinterface. Other event source clients may fail QI for this GUID, so if it + // does return an error, we will QI again for IDispatch. The event issue is change in behavior from + // how VB6 implemented event sinks, and how VB7/C# does them... + HRESULT hr = pUnk->QueryInterface(DIID__DFramerCtlEvents, (void**)&(pThis->m_dispEvents)); + if (FAILED(hr)) hr = pUnk->QueryInterface(IID_IDispatch, (void**)&(pThis->m_dispEvents)); + + if (SUCCEEDED(hr)) *pdwCookie = (DWORD)(pThis); + return hr; +} + +STDMETHODIMP CDsoFramerControl::XConnectionPoint::Unadvise(DWORD dwCookie) +{ + METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint); + ODS("CDsoFramerControl::XConnectionPoint::Unadvise\n"); + if (dwCookie == (DWORD)(pThis)) + { + SAFE_RELEASE_INTERFACE(pThis->m_dispEvents); + } + return (pThis->m_dispEvents == NULL) ? S_OK : CONNECT_E_NOCONNECTION; +} + +STDMETHODIMP CDsoFramerControl::XConnectionPoint::EnumConnections(IEnumConnections **ppEnum) +{if (ppEnum) *ppEnum = NULL; return E_NOTIMPL;} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XOleCommandTarget -- IOleCommandTarget Implementation +// +// STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText); +// STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleCommandTarget) + +STDMETHODIMP CDsoFramerControl::XOleCommandTarget::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleCommandTarget); + //ODS("CDsoFramerControl::XOleCommandTarget::QueryStatus\n"); + if (pguidCmdGroup != NULL) + return OLECMDERR_E_UNKNOWNGROUP; + + if (prgCmds == NULL) + return E_INVALIDARG; + + for (int i = 0; i < (int)cCmds; i++) + { + switch (prgCmds[i].cmdID) + { + case OLECMDID_NEW: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 1) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_OPEN: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 2) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_SAVE: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 8) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_SAVEAS: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 16) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_PRINT: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 32) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_PAGESETUP: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 64) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_PROPERTIES: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 128) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + case OLECMDID_PRINTPREVIEW: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 256) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break; + default: prgCmds[i].cmdf = 0; + } + } + + if (pCmdText) + { + pCmdText->cmdtextf = MSOCMDTEXTF_NONE; + pCmdText->cwActual = 0; + } + + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XOleCommandTarget::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) +{ + METHOD_PROLOGUE(CDsoFramerControl, OleCommandTarget); + ODS("CDsoFramerControl::XOleCommandTarget::Exec\n"); + + if ((pguidCmdGroup != NULL) && (*pguidCmdGroup != GUID_NULL)) + return OLECMDERR_E_UNKNOWNGROUP; + + if (nCmdexecopt == MSOCMDEXECOPT_SHOWHELP) + return OLECMDERR_E_NOHELP; + + switch (nCmdID) + { + case OLECMDID_NEW: + case OLECMDID_OPEN: + case OLECMDID_SAVE: + case OLECMDID_SAVEAS: + case OLECMDID_PRINT: + case OLECMDID_PAGESETUP: + case OLECMDID_PROPERTIES: + case OLECMDID_PRINTPREVIEW: + PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, nCmdID, nCmdexecopt); + return S_OK; + } + + return OLECMDERR_E_NOTSUPPORTED; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XSupportErrorInfo -- ISupportErrorInfo Implementation +// +// STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, SupportErrorInfo) + +STDMETHODIMP CDsoFramerControl::XSupportErrorInfo::InterfaceSupportsErrorInfo(REFIID riid) +{ + ODS("CDsoFramerControl::XSupportErrorInfo::InterfaceSupportsErrorInfo\n"); + return ((riid == IID__FramerControl) ? S_OK : E_FAIL); +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XObjectSafety -- IObjectSafety Implementation +// +// STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions); +// STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ObjectSafety) + +STDMETHODIMP CDsoFramerControl::XObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions) +{ + ODS("CDsoFramerControl::XObjectSafety::GetInterfaceSafetyOptions\n"); + CHECK_NULL_RETURN(pdwEnabledOptions, E_POINTER); + + if (pdwSupportedOptions) + *pdwSupportedOptions = (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER); + + // We are safe for initialization, but not necessarily for scripting. Since script + // can open documents with macros, and get access to Office OM via ActiveDocument, + // we cannot be "safe" for malicious script. But this allows the control to load + // without prompt (just not scripted without prompt)... + *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XObjectSafety::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) +{ + ODS("CDsoFramerControl::XObjectSafety::SetInterfaceSafetyOptions\n"); + return ((((riid == IID_IPersist) || (riid == IID_IPersistPropertyBag)) && + (dwEnabledOptions == INTERFACESAFE_FOR_UNTRUSTED_DATA)) ? S_OK : E_FAIL); +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoFramerControl::XDsoDocObjectSite -- IDsoDocObjectSite Implementation +// +// STDMETHODIMP GetWindow(HWND* phWnd); +// STDMETHODIMP GetBorder(LPRECT prcBorder); +// STDMETHODIMP SetStatusText(LPCOLESTR pszText); +// STDMETHODIMP GetHostName(LPWSTR *ppwszHostName); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, DsoDocObjectSite) + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::QueryService(REFGUID guidService, REFIID riid, void **ppv) +{ + HRESULT hr = E_NOINTERFACE; + ODS("CDsoFramerControl::XDsoDocObjectSite::QueryService\n"); + + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + CHECK_NULL_RETURN(ppv, E_POINTER); + + // We will return control IDispatch for cross container automation... + if (guidService == SID_SContainerDispatch) + { + ODS(" -- Container Dispatch Given --\n"); + hr = pThis->QueryInterface(riid, ppv); + } + // TODO: Support IHlinkFrame services for cross hyperlinking inside control?? + + // If we don't handle the call, and our host has a provider, pass the call along to see + // if the top-level host offers the service requested (like hyperlinking to new web page)... + if (FAILED(hr) && (pThis->m_pClientSite)) + { + IServiceProvider *pprov = NULL; + if (SUCCEEDED(pThis->m_pClientSite->QueryInterface(IID_IServiceProvider, (void**)&pprov)) && (pprov)) + { + if (SUCCEEDED(hr = pprov->QueryService(guidService, riid, ppv))) + { ODS(" -- Service provided by top-level host --\n"); } + pprov->Release(); + } + } + + return hr; +} + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetWindow(HWND* phWnd) +{ + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + ODS("CDsoFramerControl::XDsoDocObjectSite::GetWindow\n"); + if (phWnd) *phWnd = pThis->m_hwnd; + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetBorder(LPRECT prcBorder) +{ + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + ODS("CDsoFramerControl::XDsoDocObjectSite::GetBorder\n"); + pThis->GetSizeRectForDocument(NULL, prcBorder); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetHostName(LPWSTR *ppwszHostName) +{ + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + ODS("CDsoFramerControl::XDsoDocObjectSite::GetHostName\n"); + if (ppwszHostName) *ppwszHostName = DsoCopyString(pThis->m_pwszHostName); + return S_OK; +} + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::SysMenuCommand(UINT uiCharCode) +{ + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + TRACE1("CDsoFramerControl::XDsoDocObjectSite::SysMenuCommand(%x)\n", uiCharCode); + + // If we are processing a sys menu command, see if it is a menu accel for our + // displayed menu, and if so we handle this with a fake click of the menu button... + if ((uiCharCode) && (pThis->m_fShowMenuBar) && !(pThis->m_fDisableMenuAccel)) + { + UINT i; + CHAR *pch; + + // Loop all the menu items and check against their accelerators... + for (i = 0; i < DSO_MAX_MENUITEMS; i++) + { + pch = &(pThis->m_rgchMenuAccel[0]); + if (*pch) + { + if ((*pch != 0xFF) && ((UINT)(*pch) == ASCII_LOWERCASE(uiCharCode))) + { + // Found one that match, so fake mouse move and button down/up to run click code... + ODS("-- Trigger Menu Accelerator --\n"); + + PostMessage(pThis->m_hwnd, WM_MOUSEMOVE, (WPARAM)0, + MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1)); + + PostMessage(pThis->m_hwnd, WM_LBUTTONDOWN, (WPARAM)MK_LBUTTON, + MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1)); + + PostMessage(pThis->m_hwnd, WM_LBUTTONUP, (WPARAM)0, + MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1)); + + // Return OK to caller to know to eat this message. + return S_OK; + } + } + else break; + } + } + + return S_FALSE; +} + +STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::SetStatusText(LPCOLESTR pszText) +{ + METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite); + + // If m_fActivateOnStatus flag is set, see if we are not UI active. If not, try to activate... + if ((pThis->m_fActivateOnStatus) && (pThis->m_fComponentActive) && (pThis->m_fAppActive) && + !(pThis->m_fUIActive) && !(pThis->m_fModalState)) + { + ODS(" -- ForceUIActiveFromSetStatusText --\n"); + pThis->m_fActivateOnStatus = FALSE; + pThis->Activate(); + } + + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameHookManager +// +CDsoFrameHookManager* vgGlobalManager = NULL; + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameHookManager::RegisterFramerControl +// +// Creates a frame hook and registers it with the active manager. If +// this is the first time called, the global manager will be created +// now. The manager can handle up to DSOF_MAX_CONTROLS controls (10). +// +STDMETHODIMP_(CDsoFrameHookManager*) CDsoFrameHookManager::RegisterFramerControl(HWND hwndParent, HWND hwndControl) +{ + CDsoFrameHookManager* pManager = NULL; + ODS("CDsoFrameHookManager::RegisterFramerControl\n"); + CHECK_NULL_RETURN(hwndControl, NULL); + + EnterCriticalSection(&v_csecThreadSynch); + pManager = vgGlobalManager; + if (pManager == NULL) + pManager = (vgGlobalManager = new CDsoFrameHookManager()); + LeaveCriticalSection(&v_csecThreadSynch); + + if (pManager) + { + if (hwndParent == NULL) + hwndParent = hwndControl; + + if (FAILED(pManager->AddComponent(hwndParent, hwndControl))) + return NULL; + } + + return pManager; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameHookManager::AddComponent +// +// Register the component and create the actual frame hook (if needed). +// +STDMETHODIMP CDsoFrameHookManager::AddComponent(HWND hwndParent, HWND hwndControl) +{ + DWORD dwHostProcessID; + CDsoFrameWindowHook* phook; + HRESULT hr = E_OUTOFMEMORY; + HWND hwndNext, hwndHost = hwndParent; + ODS("CDsoFrameHookManager::AddComponent\n"); + + // Find the top-level window this control is sited on... + while (hwndNext = GetParent(hwndHost)) + hwndHost = hwndNext; + + // We have to get valid window that is in-thread for a subclass to work... + if (!IsWindow(hwndHost) || + (GetWindowThreadProcessId(hwndHost, &dwHostProcessID), + dwHostProcessID != GetCurrentProcessId())) + return E_ACCESSDENIED; + + // Next if we have room in the array, add the component to the list and + // hook its parent window so we get messages for it. + EnterCriticalSection(&v_csecThreadSynch); + if ((vgGlobalManager) && (m_cComponents < DSOF_MAX_CONTROLS)) + { + // Hook the host window for this control... + phook = CDsoFrameWindowHook::AttachToFrameWindow(hwndHost); + if (phook) + {// Add the component to the list if hooked... + m_pComponents[m_cComponents].hwndControl = hwndControl; + m_pComponents[m_cComponents].phookFrame = phook; + m_cComponents++; hr = S_OK; + } + } + LeaveCriticalSection(&v_csecThreadSynch); + + if (SUCCEEDED(hr)) // Make sure item is the new active component + hr = SetActiveComponent(hwndControl); + + return hr; +} + +STDMETHODIMP CDsoFrameHookManager::DetachComponent(HWND hwndControl) +{ + DWORD dwIndex; + CHECK_NULL_RETURN(m_cComponents, E_FAIL); + + // Find this control in the list... + for (dwIndex = 0; dwIndex < m_cComponents; dwIndex++) + if (m_pComponents[dwIndex].hwndControl == hwndControl) break; + + if (dwIndex > m_cComponents) + return E_INVALIDARG; + + // If we found the index, remove the item and shift remaining + // items down the list. Change active index as needed... + EnterCriticalSection(&v_csecThreadSynch); + + m_pComponents[dwIndex].hwndControl = NULL; + m_pComponents[dwIndex].phookFrame->Detach(); + + // Compact the list... + while (++dwIndex < m_cComponents) + { + m_pComponents[dwIndex-1].hwndControl = m_pComponents[dwIndex].hwndControl; + m_pComponents[dwIndex-1].phookFrame = m_pComponents[dwIndex].phookFrame; + m_pComponents[dwIndex].hwndControl = NULL; + } + + // Decrement the count. If count still exists, forward activation + // to next component in the list... + if (--m_cComponents) + { + while (m_idxActive >= m_cComponents) + --m_idxActive; + + HWND hwndActive = GetActiveComponentWindow(); + if (hwndActive) + SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)TRUE, (LPARAM)(m_fAppActive)); + } + else + { + vgGlobalManager = NULL; + // If this is the last control, we can remove the manger! + delete this; + } + + LeaveCriticalSection(&v_csecThreadSynch); + + return S_OK; +} + +STDMETHODIMP CDsoFrameHookManager::SetActiveComponent(HWND hwndControl) +{ + ODS(" -- CDsoFrameHookManager::SetActiveComponent -- \n"); + CHECK_NULL_RETURN(m_cComponents, E_FAIL); + DWORD dwIndex; + + // Find the index of the control... + for (dwIndex = 0; dwIndex < m_cComponents; dwIndex++) + if (m_pComponents[dwIndex].hwndControl == hwndControl) break; + + if (dwIndex > m_cComponents) + return E_INVALIDARG; + + // If it is not already the active item, notify old component it is + // losing activation, and notify new component that it is gaining... + EnterCriticalSection(&v_csecThreadSynch); + if (dwIndex != m_idxActive) + { + HWND hwndActive = GetActiveComponentWindow(); + if (hwndActive) + SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)FALSE, (LPARAM)0); + + m_idxActive = dwIndex; + + hwndActive = GetActiveComponentWindow(); + if (hwndActive) + SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)TRUE, (LPARAM)(m_fAppActive)); + } + LeaveCriticalSection(&v_csecThreadSynch); + + return S_OK; +} + +STDMETHODIMP CDsoFrameHookManager::OnComponentNotify(DWORD msg, WPARAM wParam, LPARAM lParam) +{ + TRACE3("CDsoFrameHookManager::OnComponentNotify(%d, %d, %d)\n", msg, wParam, lParam); + HWND hwndActiveComp = GetActiveComponentWindow(); + + // The manager needs to keep track of AppActive state... + if (msg == DSO_WM_HOOK_NOTIFY_APPACTIVATE) + { + EnterCriticalSection(&v_csecThreadSynch); + m_fAppActive = (BOOL)wParam; + LeaveCriticalSection(&v_csecThreadSynch); + } + + // Send the message to the active component + SendNotifyMessage(hwndActiveComp, msg, wParam, lParam); + return S_OK; +} + +STDMETHODIMP_(BOOL) CDsoFrameHookManager::SendNotifyMessage(HWND hwnd, DWORD msg, WPARAM wParam, LPARAM lParam) +{ + BOOL fResult; + + // Check if the caller is on the same thread as the active component. If so we can + // forward the message directly for processing. If not, we have to post and wait for + // that thread to process message at a later time... + if (GetWindowThreadProcessId(hwnd, NULL) == GetCurrentThreadId()) + { // Notify now... + fResult = (BOOL)SendMessage(hwnd, msg, wParam, lParam); + } + else + { // Notify later... + fResult = PostMessage(hwnd, msg, wParam, lParam); + } + + return fResult; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook +// +//////////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook::AttachToFrameWindow +// +// Creates the frame hook for the host window. +// +STDMETHODIMP_(CDsoFrameWindowHook*) CDsoFrameWindowHook::AttachToFrameWindow(HWND hwndParent) +{ + CDsoFrameWindowHook* phook = NULL; + BOOL fHookSuccess = FALSE; + + // We have to get valid window ... + if (!IsWindow(hwndParent)) + return NULL; + + EnterCriticalSection(&v_csecThreadSynch); + phook = CDsoFrameWindowHook::GetHookFromWindow(hwndParent); + if (phook) + { // Already have this window hooked, so just addref the count. + phook->AddRef(); + } + else + { // Need to create a new hook object for this window... + if ((phook = new CDsoFrameWindowHook())) + { + phook->m_hwndTopLevelHost = hwndParent; + phook->m_fHostUnicodeWindow = (v_fUnicodeAPI && IsWindowUnicode(hwndParent)); + + // Setup the subclass using Unicode or Ansi methods depending on window + // create state. Note if either property assoc or window subclass fail... + if (phook->m_fHostUnicodeWindow) + { + fHookSuccess = SetPropW(hwndParent, L"DSOFramerWndHook", (HANDLE)phook); + if (fHookSuccess) + { + phook->m_pfnOrigWndProc = (WNDPROC)SetWindowLongW(hwndParent, GWL_WNDPROC, (LONG)(WNDPROC)HostWindowProcHook); + fHookSuccess = (phook->m_pfnOrigWndProc != NULL); + } + } + else + { + fHookSuccess = SetPropA(hwndParent, "DSOFramerWndHook", (HANDLE)phook); + if (fHookSuccess) + { + phook->m_pfnOrigWndProc = (WNDPROC)SetWindowLongA(hwndParent, GWL_WNDPROC, (LONG)(WNDPROC)HostWindowProcHook); + fHookSuccess = (phook->m_pfnOrigWndProc != NULL); + } + } + + // If we failed the subclass, kill this object and return error... + if (!fHookSuccess) + { + delete phook; + phook = NULL; + } + else phook->m_cHookCount++; + } + } + LeaveCriticalSection(&v_csecThreadSynch); + + return phook; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook::Detach +// +// Removes the hook from the frame window if this is the last control +// to reference the hook. +// +STDMETHODIMP CDsoFrameWindowHook::Detach() +{ + // Only need to call this if item is attached. + EnterCriticalSection(&v_csecThreadSynch); + if (m_cHookCount) + { + if (--m_cHookCount == 0) + { // We can remove the hook! + if (m_fHostUnicodeWindow) + { + SetWindowLongW(m_hwndTopLevelHost, GWL_WNDPROC, (LONG)(m_pfnOrigWndProc)); + RemovePropW(m_hwndTopLevelHost, L"DSOFramerWndHook"); + } + else + { + SetWindowLongA(m_hwndTopLevelHost, GWL_WNDPROC, (LONG)(m_pfnOrigWndProc)); + RemovePropA(m_hwndTopLevelHost, "DSOFramerWndHook"); + } + m_hwndTopLevelHost = NULL; + + // we can kill this object now... + delete this; + } + } + LeaveCriticalSection(&v_csecThreadSynch); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook::GetHookFromWindow +// +// Returns the hook control associated with this object. +// +STDMETHODIMP_(CDsoFrameWindowHook*) CDsoFrameWindowHook::GetHookFromWindow(HWND hwnd) +{ + CDsoFrameWindowHook* phook = (CDsoFrameWindowHook*)GetPropW(hwnd, L"DSOFramerWndHook"); + if (phook == NULL) phook = (CDsoFrameWindowHook*)GetPropA(hwnd, "DSOFramerWndHook"); + return phook; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook::HostWindowProcHook +// +// The window proc for the subclassed host window. +// +STDMETHODIMP_(LRESULT) CDsoFrameWindowHook::HostWindowProcHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CDsoFrameWindowHook* phook = CDsoFrameWindowHook::GetHookFromWindow(hwnd); + if (phook) // We better get our prop for this window! + { + // We handle the important ActiveDocument frame-level events like task + // window activation/deactivation, palette change notfication, and key/mouse + // focus notification on host app focus... + switch (msg) + { + case WM_ACTIVATEAPP: + if (vgGlobalManager) + vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_APPACTIVATE, wParam, lParam); + break; + + case WM_PALETTECHANGED: + if (vgGlobalManager) + vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_PALETTECHANGE, wParam, lParam); + break; + + case WM_SYNCPAINT: + if (vgGlobalManager) + vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_SYNCPAINT, wParam, lParam); + break; + + } + + // After processing, allow calls to fall through to host app. We need to call + // the appropriate handler for Unicode or non-Unicode windows... + if (phook->m_fHostUnicodeWindow) + return CallWindowProcW(phook->m_pfnOrigWndProc, hwnd, msg, wParam, lParam); + else + return CallWindowProcA(phook->m_pfnOrigWndProc, hwnd, msg, wParam, lParam); + } + + // Should not be reached, but just in case call default proc... + return (IsWindowUnicode(hwnd) ? + DefWindowProcW(hwnd, msg, wParam, lParam) : + DefWindowProcA(hwnd, msg, wParam, lParam)); +} \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/dsofdocobj.cpp b/PROMS/DSOFRAMER/Source2005/dsofdocobj.cpp new file mode 100644 index 00000000..64fd9faf --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsofdocobj.cpp @@ -0,0 +1,3252 @@ +/*************************************************************************** + * DSOFDOCOBJ.CPP + * + * CDsoDocObject: ActiveX Document Single Instance Frame/Site Object + * + * Copyright ©1999-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" + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject - The DocObject Site Class +// +// This class wraps the functionality for DocObject hosting. Right now +// we are setup for one active site at a time, but this could be changed +// to allow multiple sites (although only one could be UI active at any +// given time). +// +CDsoDocObject::CDsoDocObject() +{ + ODS("CDsoDocObject::CDsoDocObject\n"); + m_cRef = 1; + m_fDisplayTools = TRUE; +} + +CDsoDocObject::~CDsoDocObject(void) +{ + ODS("CDsoDocObject::~CDsoDocObject\n"); + if (m_pole) Close(); + if (m_hwnd) DestroyWindow(m_hwnd); + + SAFE_FREESTRING(m_pwszUsername); + SAFE_FREESTRING(m_pwszPassword); + SAFE_FREESTRING(m_pwszHostName); + + SAFE_RELEASE_INTERFACE(m_pstgroot); + SAFE_RELEASE_INTERFACE(m_punkIPPResource); + SAFE_RELEASE_INTERFACE(m_pcmdCtl); + SAFE_RELEASE_INTERFACE(m_psiteCtl); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateNewDocObject +// +// Static Creation Function. +// +STDMETHODIMP_(CDsoDocObject*) CDsoDocObject::CreateInstance(IDsoDocObjectSite* phost) +{ + ODS("CDsoDocObject::CreateInstance()\n"); + CDsoDocObject* pnew = new CDsoDocObject(); + if ((pnew) && FAILED(pnew->InitializeNewInstance(phost))) + { + pnew->Release(); + pnew = NULL; + } + return pnew; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::InitializeNewInstance +// +// Sets up new docobject class. We must a control site to attach this +// window to. It will call back to host for menu and IOleCommandTarget. +// +STDMETHODIMP CDsoDocObject::InitializeNewInstance(IDsoDocObjectSite* phost) +{ + HRESULT hr = E_UNEXPECTED; + WNDCLASS wndclass; + HWND hwndCtl; + + ODS("CDsoDocObject::InitializeNewInstance()\n"); + + // We need valid IDsoDocObjectSite... + if ((phost == NULL) || FAILED(phost->GetWindow(&hwndCtl))) + return hr; + + // As an AxDoc site, we need a valid parent window... + if ((!hwndCtl) || (!IsWindow(hwndCtl))) + return hr; + + // Create a temp storage for this docobj site (if one already exists, bomb out)... + if ((m_pstgroot) || FAILED(hr = StgCreateDocfile(NULL, STGM_TRANSACTED | STGM_READWRITE | + STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &m_pstgroot))) + return hr; + + // If our site window class has not been registered before, we should register it... + + // This is protected by a critical section just for fun. The fact we had to single + // instance the OCX because of the host hook makes having multiple instances conflict here + // very unlikely. However, that could change sometime, so better to be safe than sorry. + EnterCriticalSection(&v_csecThreadSynch); + + if (GetClassInfo(v_hModule, "DSOFramerDocWnd", &wndclass) == 0) + { + memset(&wndclass, 0, sizeof(WNDCLASS)); + wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wndclass.lpfnWndProc = CDsoDocObject::FrameWindowProc; + wndclass.hInstance = v_hModule; + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.lpszClassName = "DSOFramerDocWnd"; + if (RegisterClass(&wndclass) == 0) + hr = E_WIN32_LASTERROR; + } + + LeaveCriticalSection(&v_csecThreadSynch); + if (FAILED(hr)) return hr; + + // Get the position RECT (and validate as needed)... + hr = phost->GetBorder(&m_rcViewRect); + if (FAILED(hr)) return hr; + + if (m_rcViewRect.top > m_rcViewRect.bottom) + {m_rcViewRect.top = 0; m_rcViewRect.bottom = 0;} + if (m_rcViewRect.left > m_rcViewRect.right) + {m_rcViewRect.left = 0; m_rcViewRect.right = 0;} + + // Create our site window at the give location (we are child of the control window)... + m_hwnd = CreateWindowEx(0, "DSOFramerDocWnd", NULL, WS_CHILD, + m_rcViewRect.left, m_rcViewRect.top, + (m_rcViewRect.right - m_rcViewRect.left), + (m_rcViewRect.bottom - m_rcViewRect.top), + hwndCtl, NULL, v_hModule, NULL); + + if (!m_hwnd) return E_OUTOFMEMORY; + SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this); + + // Save the control info for this object... + m_hwndCtl = hwndCtl; + (m_psiteCtl = phost)->AddRef(); + + m_psiteCtl->QueryInterface(IID_IOleCommandTarget, (void**)&m_pcmdCtl); + m_psiteCtl->GetHostName(&m_pwszHostName); + if (m_pwszHostName == NULL) + m_pwszHostName = DsoCopyString(L"DsoFramerControl"); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateDocObject (From CLSID) +// +// This does embedding of new object, or loads a copy from storage. +// To activate and show the object, you must call IPActivateView(). +// +STDMETHODIMP CDsoDocObject::CreateDocObject(REFCLSID rclsid) +{ + HRESULT hr; + CLSID clsid; + DWORD dwMiscStatus = 0; + IOleObject* pole = NULL; + IPersistStorage* pipstg = NULL; + BOOL fInitNew = (m_pstgfile == NULL); + + ODS("CDsoDocObject::CreateDocObject(CLSID)\n"); + ASSERT(!(m_pole)); + + // Don't load if an object has already been loaded... + if (m_pole) return E_UNEXPECTED; + + // It is possible that someone picked an older ProgId/CLSID that + // will AutoConvert on CoCreate, so fix up the storage with the + // new CLSID info. We we actually call CoCreate on the new CLSID... + if (fInitNew && SUCCEEDED(OleGetAutoConvert(rclsid, &clsid))) + { + OleDoAutoConvert(m_pstgfile, &clsid); + } + else clsid = rclsid; + + // First, check the server to make sure it is AxDoc server... + if (FAILED(hr = ValidateDocObjectServer(rclsid))) + return hr; + + // If we haven't loaded a storage, create a new one and remember to + // call InitNew (instead of Load) later on... + if (fInitNew && FAILED(hr = CreateObjectStorage(rclsid))) + return hr; + + // We are ready to create an instance. Call CoCreate to make an + // inproc handler and ask for IOleObject (all docobjs must support this)... + if (FAILED(hr = InstantiateDocObjectServer(clsid, &pole))) + return hr; + + // Do a quick check to see if server wants us to set client site before the load.. + hr = pole->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus); + if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) + hr = pole->SetClientSite((IOleClientSite*)&m_xOleClientSite); + + // Load up the bloody thing... + if (SUCCEEDED(hr = pole->QueryInterface(IID_IPersistStorage, (void**)&pipstg))) + { + // Remember to InitNew if this is a new storage... + hr = ((fInitNew) ? pipstg->InitNew(m_pstgfile) : pipstg->Load(m_pstgfile)); + pipstg->Release(); + } + + // Assuming all the above worked we should have an OLE Embeddable + // object and should finish the initialization (set object running)... + if (SUCCEEDED(hr)) + { + // Save the IOleObject* and do a disconnect on quit... + SAFE_SET_INTERFACE(m_pole, pole); + m_fDisconnectOnQuit = TRUE; + + // Keep server CLSID for this object + m_clsidObject = clsid; + + // Ensure server is running and locked... + EnsureOleServerRunning(TRUE); + + // If we didn't do so already, set our client site... + if (!(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) + hr = m_pole->SetClientSite((IOleClientSite*)&m_xOleClientSite); + + // Set the host names for OLE embedding... + m_pole->SetHostNames(m_pwszHostName, m_pwszHostName); + + // Ask object to save (if dirty)... + if (IsDirty()) SaveObjectStorage(); + } + else + {// Be sure they disconnect from our site if we failed load... + pole->SetClientSite(NULL); + } + + // This will free the OLE server if anything above failed... + SAFE_RELEASE_INTERFACE(pole); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateDocObject (From IStorage*) +// +// This does embedding of new object, or loads a copy from storage. +// To activate and show the object, you must call IPActivateView(). +// +STDMETHODIMP CDsoDocObject::CreateDocObject(IStorage *pstg) +{ + HRESULT hr; + CLSID clsid; + + ODS("CDsoDocObject::CreateDocObject(IStorage*)\n"); + CHECK_NULL_RETURN(pstg, E_POINTER); + + // Read the clsid from the storage.. + if (FAILED(hr = ReadClassStg(pstg, &clsid))) + return hr; + + // Validate the server is AxDoc server... + if (FAILED(hr = ValidateDocObjectServer(clsid))) + return hr; + + // Create a new storage for this CLSID... + if (FAILED(hr = CreateObjectStorage(clsid))) + return hr; + + // Copy data into the new storage and commit the change... + hr = pstg->CopyTo(0, NULL, NULL, m_pstgfile); + if (SUCCEEDED(hr)) hr = m_pstgfile->Commit(STGC_OVERWRITE); + + // Then do normal create on existing storage made from copy... + return CreateDocObject(clsid); +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateFromFile +// +// Loads document into the framer control. The bind options determine if +// file should be loaded read-only or read-write. An alternate CLSID can +// be provided if the document type is not normally associated with a +// a DocObject server in OLE. +// +// To activate and show the object, you must call IPActivateView(). +// +// The code will attempt to open the file in one of three ways: +// +// 1.) Using IMoniker, we will attempt to open and load existing file +// via a passed moniker, similar to how IE loads files. +// +// 2.) Using IPersistFile, we will attempt to open via direct file path. +// +// 3.) Finally, if above two options don't work, we will try to open the +// storage, make a copy and load using IPersistStorage. This last way follows +// the (old) Binder behavior, and should *by spec* always work, but is a bit +// clunky since we open a copy, not the real file. +// +STDMETHODIMP CDsoDocObject::CreateFromFile(LPWSTR pwszFile, REFCLSID rclsid, LPBIND_OPTS pbndopts) +{ + HRESULT hr; + CLSID clsid; + CLSID clsidConv; + IOleObject *pole = NULL; + IBindCtx *pbctx = NULL; + IMoniker *pmkfile = NULL; + IStorage *pstg = NULL; + BOOL fLoadFromAltCLSID = (rclsid != GUID_NULL); + + // Sanity check of parameters... + if (!(pwszFile) || ((*pwszFile) == L'\0') || (pbndopts == NULL)) + return E_INVALIDARG; + + TRACE2("CDsoDocObject::CreateFromFile(%S, %x)\n", pwszFile, pbndopts->grfMode); + + // First. we'll try to find the associated CLSID for the given file, + // and then set it to the alternate if not found. If we don't have a + // CLSID by the end of this, because user didn't specify alternate + // and GetClassFile failed, then we error out... + if (FAILED(GetClassFile(pwszFile, &clsid)) && !(fLoadFromAltCLSID)) + return DSO_E_INVALIDSERVER; + + // We should try to load from alternate CLSID if provided one... + if (fLoadFromAltCLSID) clsid = rclsid; + + // We should also handle auto-convert to start "newest" server... + if (SUCCEEDED(OleGetAutoConvert(clsid, &clsidConv))) + clsid = clsidConv; + + // Validate that we have a DocObject server... + if ((clsid == GUID_NULL) || FAILED(ValidateDocObjectServer(clsid))) + return DSO_E_INVALIDSERVER; + + // Check for IE cache items since these are read-only as far as user is concerned... + if (FIsIECacheFile(pwszFile)) + { + pbndopts->grfMode &= ~(STGM_READWRITE); + pbndopts->grfMode &= ~(STGM_WRITE); + pbndopts->grfMode |= STGM_READ; + } + + // First, we try to bind by moniker (same as IE). We'll need a bind context + // and a file moniker for the orginal source... + if (SUCCEEDED(hr = CreateBindCtx(0, &pbctx))) + { + if (SUCCEEDED(hr = pbctx->SetBindOptions(pbndopts)) && + SUCCEEDED(hr = CreateFileMoniker(pwszFile, &pmkfile))) + { + + // Bind to the object moniker refers to... + hr = pmkfile->BindToObject(pbctx, NULL, IID_IOleObject, (void**)&pole); + + // If that failed, try to bind direct to file in new server... + if (FAILED(hr)) + { + IPersistFile *pipfile = NULL; + + if (SUCCEEDED(hr = InstantiateDocObjectServer(clsid, &pole)) && + SUCCEEDED(hr = pole->QueryInterface(IID_IPersistFile, (void**)&pipfile))) + { + hr = pipfile->Load(pwszFile, pbndopts->grfMode); + pipfile->Release(); + } + } + + // If either solution worked, setup the rest of the bind info... + if (SUCCEEDED(hr)) + { + // Save the IOleObject* and do a disconnect on quit... + SAFE_SET_INTERFACE(m_pole, pole); + m_fDisconnectOnQuit = TRUE; + + // Keep server CLSID for this object + m_clsidObject = clsid; + + // Keep the moniker and bind ctx... + SAFE_SET_INTERFACE(m_pmkSourceFile, pmkfile); + SAFE_SET_INTERFACE(m_pbctxSourceFile, pbctx); + + // Set out client site... + m_pole->SetClientSite((IOleClientSite*)&m_xOleClientSite); + + // We don't normally set host name for moniker bind, but MSWORD object + // requires it to IP activate it instead of link & show external... + if (IsWordObject()) + m_pole->SetHostNames(m_pwszHostName, m_pwszHostName); + + } + else pole->SetClientSite(NULL); + + // This will release the moniker if above failed... + pmkfile->Release(); + } + // This will release the bind ctx if above failed... + pbctx->Release(); + } + + // If binding by moniker failed, try the old fashion way of bind to OLE storage... + if (FAILED(hr)) + { + // Try to open file as OLE storage (native OLE DocFile)... + if (SUCCEEDED(hr = StgOpenStorage(pwszFile, NULL, pbndopts->grfMode, NULL, 0, &pstg))) + { + // Create our substorage, and copy the data over to it... + if (SUCCEEDED(hr = CreateObjectStorage(clsid)) && + SUCCEEDED(hr = pstg->CopyTo(0, NULL, NULL, m_pstgfile))) + { + m_pstgfile->Commit(STGC_OVERWRITE); + + // Then create the object from the storage copy... + if (SUCCEEDED(hr = CreateDocObject(clsid))) + { + SAFE_SET_INTERFACE(m_pstgSourceFile, pstg); + } + } + // This will release the storage if above failed... + pstg->Release(); + } + } + + // If all went well, we should save file name and whether it opened read-only... + if (SUCCEEDED(hr)) + { + m_pwszSourceFile = DsoCopyString(pwszFile); + m_idxSourceName = CalcDocNameIndex(m_pwszSourceFile); + m_fOpenReadOnly = ((pbndopts->grfMode & STGM_WRITE) == 0) && + ((pbndopts->grfMode & STGM_READWRITE) == 0); + } + + // This will free the OLE server if anything above failed... + SAFE_RELEASE_INTERFACE(pole); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateFromURL +// +// Loads document from a URL resource. The document can be open read-only +// using URLMON in the same context as the host client (i.e., it can be +// treated as normal navigation in host if host supports URLMON, like IE). +// Or you can choose to open read-write, which will attempt to use the +// Microsoft Internet Publishing Provider (MSDAIPP) to author on the web. +// +// The default is to open read-only with URLMON. If client wants read-write, +// we will try MSDAIPP for DAV first, then MSDAIPP for FPSE/WSS/SPS. +// +STDMETHODIMP CDsoDocObject::CreateFromURL(LPWSTR pwszUrlFile, REFCLSID rclsid, LPBIND_OPTS pbndopts, LPWSTR pwszUserName, LPWSTR pwszPassword) +{ + HRESULT hr; + BOOL fReadOnly; + LPWSTR pwszTempFile; + IStream *pstmWebResource = NULL; + + // First, a sanity check on the parameters passed... + if ((pwszUrlFile == NULL) || (pbndopts == NULL)) + return E_INVALIDARG; + + TRACE2("CDsoDocObject::CreateFromURL(%S, %x)\n", pwszUrlFile, pbndopts->grfMode); + + // Get a temp path for the download... + if (!GetTempPathForURLDownload(pwszUrlFile, &pwszTempFile)) + return E_ACCESSDENIED; + + // Save out the user name and password (if provided) for IAuthenticate... + if (pwszUserName) + { + SAFE_FREESTRING(m_pwszUsername); + m_pwszUsername = DsoCopyString(pwszUserName); + + SAFE_FREESTRING(m_pwszPassword); + m_pwszPassword = DsoCopyString(pwszPassword); + } + + // Determine if they want to open read-only using URLMON or read-write using MSDAIPP... + fReadOnly = ((pbndopts->grfMode & STGM_WRITE) == 0) && + ((pbndopts->grfMode & STGM_READWRITE) == 0); + + if (fReadOnly) // If using URLMON... + { + hr = URLDownloadFile((IUnknown*)&m_xAuthenticate, pwszUrlFile, pwszTempFile); + } + else // Otherwise we need access to MSDAIPP for writable stream... + { + hr = IPPDownloadWebResource(pwszUrlFile, pwszTempFile, &pstmWebResource); + } + + // If all goes well with the download, we can then open the temp file for write access to + // use as local file during the editing. Then we can save back on the stream if requested. + if (SUCCEEDED(hr)) + { + BIND_OPTS bopts = {sizeof(BIND_OPTS), BIND_MAYBOTHERUSER, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 10000}; + hr = CreateFromFile(pwszTempFile, rclsid, &bopts); + if (SUCCEEDED(hr)) + { + m_fOpenReadOnly = fReadOnly; + if (!m_fOpenReadOnly) + { + m_pwszWebResource = DsoCopyString(pwszUrlFile); + SAFE_SET_INTERFACE(m_pstmWebResource, pstmWebResource); + } + } + } + + SAFE_RELEASE_INTERFACE(pstmWebResource); + DsoMemFree(pwszTempFile); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateFromRunningObject +// +// Grabs a pre-existing object (such as a running object) and attempts +// to embed it. If that fails, it will make a copy of the object and open +// the copy read-only. +// +STDMETHODIMP CDsoDocObject::CreateFromRunningObject(LPUNKNOWN punkObj, LPWSTR pwszObjectName, LPBIND_OPTS pbndopts) +{ + HRESULT hr; + IPersistStorage *prststg; + IOleObject *pole; + CLSID clsid; + BOOL fReadOnly; + + ODS("CDsoDocObject::CreateFromRunningObject()\n"); + CHECK_NULL_RETURN(punkObj, E_POINTER); + CHECK_NULL_RETURN(pbndopts, E_POINTER); + + // We only can support read-only since a running object is external, and in order + // to get a copy inplace active, we end up making a copy of the storage, which means + // this control will have a copy and not control the orginal source. Since the orginal + // can be locked and not available, we have to treat this as read-only. + fReadOnly = ((pbndopts->grfMode & STGM_WRITE) == 0) && + ((pbndopts->grfMode & STGM_READWRITE) == 0); + + if (!fReadOnly) return STG_E_LOCKVIOLATION; + + // First, ensure the object passed supports embedding (i.e., we expect + // something like a Word.Document or Excel.Sheet object, not a Word.Application + // object or something else that is not a document type)... + hr = punkObj->QueryInterface(IID_IOleObject, (void**)&pole); + if (FAILED(hr)) return hr; + + // Ask the object to save its persistent state. We also collect its CLSID and + // validate that the object type supports DocObject embedding... + hr = pole->QueryInterface(IID_IPersistStorage, (void**)&prststg); + if (SUCCEEDED(hr)) + { + hr = prststg->GetClassID(&clsid); // Validate the object type... + if (FAILED(hr) || FAILED(ValidateDocObjectServer(clsid))) + { + hr = DSO_E_INVALIDSERVER; + } + else + { + // Create a matching storage for the object and save the current + // state of the file in our storage (this is our private copy)... + if (SUCCEEDED(hr = CreateObjectStorage(clsid)) && + SUCCEEDED(hr = prststg->Save(m_pstgfile, FALSE)) && + SUCCEEDED(hr = prststg->SaveCompleted(NULL))) + { + // At this point we have a read-only copy... + prststg->HandsOffStorage(); + m_fOpenReadOnly = TRUE; + + // Create the embedding... + hr = CreateDocObject(clsid); + } + } + + prststg->Release(); + } + + pole->Release(); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::IPActivateView +// +// Activates the object for inplace viewing. +// +STDMETHODIMP CDsoDocObject::IPActivateView() +{ + HRESULT hr = E_UNEXPECTED; + ODS("CDsoDocObject::IPActivateView()\n"); + ASSERT(m_pole); + + // Make sure the site window is made visible... + if (!IsWindowVisible(m_hwnd)) + ShowWindow(m_hwnd, SW_SHOW); + + // If we have an IOleDocument pointer, we can use the Show method for + // inplace activation... + if (m_pdocv) + { + hr = m_pdocv->Show(TRUE); + } + else if (m_pole) + { + // Try creating a document view and loading it... + hr = m_xOleDocumentSite.ActivateMe(NULL); + if (FAILED(hr)) // If that fails, go the old OLE route... + { + RECT rcView; GetClientRect(m_hwnd, &rcView); + + // First call IOleObject::DoVerb with OLEIVERB_INPLACEACTIVATE + // (or OLEIVERB_SHOW), and our view rect and IOleClientSite pointer... + hr = m_pole->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, + (IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView); + + // If the server doesn't recognize IP verb, try OLEIVERB_SHOW instead... + if (hr == OLEOBJ_E_INVALIDVERB) + hr = m_pole->DoVerb(OLEIVERB_SHOW, NULL, + (IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView); + + // There is an issue with Visio 2002 rejecting DoVerb when it is called while + // Visio is still loading up the main app window. OLE servers normally return RPC + // retry later error, which will spin us in the msg-filter, but Visio just rejects + // the call all together, which pops us out of the filter early. This causes the + // embed attempt to fail. So to workaround this, we will check for the condition, + // sleep a bit, and then try our own semi-msg-filter loop... + if ((hr == RPC_E_CALL_REJECTED) && IsVisioObject()) + { + DWORD dwLoopCnt = 0; + do + { + Sleep((200 * ++dwLoopCnt)); + hr = m_pole->DoVerb(OLEIVERB_SHOW, NULL, + (IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView); + } + while ((hr == RPC_E_CALL_REJECTED) && (dwLoopCnt < 4)); + } + } + } + + // Go ahead and UI activate now... + if (SUCCEEDED(hr)) + hr = UIActivateView(); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::IPDeactivateView +// +// Deactivates the object ready for close. +// +STDMETHODIMP CDsoDocObject::IPDeactivateView() +{ + HRESULT hr = S_OK; + ODS("CDsoDocObject::IPDeactivateView()\n"); + + // If we still have a UI active object, tell it to UI deactivate... + if (m_pipactive) + UIDeactivateView(); + + // Next hide the active object... + if (m_pdocv) + m_pdocv->Show(FALSE); + + // Notify object our intention to IP deactivate... + if (m_pipobj) + m_pipobj->InPlaceDeactivate(); + + // Close the object down and release pointers... + if (m_pdocv) + { + hr = m_pdocv->CloseView(0); + m_pdocv->SetInPlaceSite(NULL); + } + + SAFE_RELEASE_INTERFACE(m_pcmdt); + SAFE_RELEASE_INTERFACE(m_pdocv); + SAFE_RELEASE_INTERFACE(m_pipobj); + + // Hide the site window... + ShowWindow(m_hwnd, SW_HIDE); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::UIActivateView +// +// UI Activates the object (which should bring up toolbars and caret). +// +STDMETHODIMP CDsoDocObject::UIActivateView() +{ + HRESULT hr = S_FALSE; + ODS("CDsoDocObject::UIActivateView()\n"); + + if (m_pdocv) // Go UI active... + { + hr = m_pdocv->UIActivate(TRUE); + } + else if (m_pole) // We should never get here, but just in case pdocv is NULL, signal UI active the old way... + { + RECT rcView; GetClientRect(m_hwnd, &rcView); + m_pole->DoVerb(OLEIVERB_UIACTIVATE, NULL, (IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView); + } + + // Forward focus to the IP object... + if (SUCCEEDED(hr) && (m_hwndIPObject)) + SetFocus(m_hwndIPObject); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::UIDeactivateView +// +// UI Deactivates the object (which should hide toolbars and caret). +// +STDMETHODIMP CDsoDocObject::UIDeactivateView() +{ + HRESULT hr = S_FALSE; + ODS("CDsoDocObject::UIDeactivateView()\n"); + if (m_pdocv) + hr = m_pdocv->UIActivate(FALSE); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::IsDirty +// +// Determines if the file is dirty (by asking IPersistXXX::IsDirty). +// +STDMETHODIMP_(BOOL) CDsoDocObject::IsDirty() +{ + BOOL fDirty = TRUE; // Assume we are dirty unless object says we are not + IPersistStorage *pprststg; + IPersistFile *pprst; + + // Can't be dirty without object + CHECK_NULL_RETURN(m_pole, FALSE); + + // Ask object its dirty state... + if ((m_pmkSourceFile) && + SUCCEEDED(m_pole->QueryInterface(IID_IPersistFile, (void**)&pprst))) + { + fDirty = ((pprst->IsDirty() == S_FALSE) ? FALSE : TRUE); + pprst->Release(); + } + else if (SUCCEEDED(m_pole->QueryInterface(IID_IPersistStorage, (void**)&pprststg))) + { + fDirty = ((pprststg->IsDirty() == S_FALSE) ? FALSE : TRUE); + pprststg->Release(); + } + + return fDirty; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::Save +// +// Does default save action for existing document (if it is not read-only). +// +// There are three types of loaded doc objects we can save: +// (1) Files obtained by URL write bind via MSDAIPP; +// (2) Files opened from local file source; and +// (3) Objects already running or files linked to via OLE moniker. +// +// This function determines which type we should do the save, and call +// the right code for that type. +// +STDMETHODIMP CDsoDocObject::Save() +{ + HRESULT hr = DSO_E_NOTBEENSAVED; + + // We can't do save default if file was open read-only, + // caller must do save with new file name... + if (!IsReadOnly()) + { + // If we have a URL (write-access) resource, do MSDAIPP save... + if (m_pstmWebResource) + { + hr = SaveToURL(NULL, TRUE, NULL, NULL); + } + // Else if it is local file, do a local save... + else if (m_pwszSourceFile) + { + hr = SaveToFile(NULL, TRUE); + } + } + + return hr; +} + +STDMETHODIMP CDsoDocObject::SaveToFile(LPWSTR pwszFile, BOOL fOverwriteFile) +{ + HRESULT hr = E_UNEXPECTED; + IStorage *pstg; + LPWSTR pwszFullName = NULL; + LPWSTR pwszRename = NULL; + BOOL fDoNormalSave = FALSE; + BOOL fDoOverwriteOps = FALSE; + BOOL fFileOpSuccess = FALSE; + + TRACE2("CDsoDocObject::SaveToFile(%S, %d)\n", ((pwszFile) ? pwszFile : L"[Default]"), fOverwriteFile); + CHECK_NULL_RETURN(m_pole, hr); + + // If they passed no file, use the default if current file is not read-only... + if (fDoNormalSave = (pwszFile == NULL)) + { + // File must be read-write for normal save... + if (IsReadOnly()) return DSO_E_DOCUMENTREADONLY; + + // If we are not moniker bound, we'll use the existing file path for ole save... + if (m_pwszSourceFile == NULL) return DSO_E_NOTBEENSAVED; + + pwszFile = (pwszFullName = DsoCopyString(m_pwszSourceFile)); + if (pwszFile == NULL) return E_OUTOFMEMORY; + } + else + { + // Make sure a file extension exists for string passed by caller... + if (ValidateFileExtension(pwszFile, &pwszFullName)) + pwszFile = pwszFullName; + } + + // See if we will be overwriting, and error unless given permission to do so... + if ((fDoOverwriteOps = FFileExists(pwszFile)) && !(fOverwriteFile)) + return STG_E_FILEALREADYEXISTS; + + // If we had a previous lock on storage, we have to free it... + SAFE_RELEASE_INTERFACE(m_pstgSourceFile); + + // If we are overwriting, we do a little Shell Operation here. This is done + // for two reasons: (1) it keeps the server from asking us to overwrite the + // file as it normally would in case of normal save; and (2) it lets us + // restore the original if the save fails... + if (fDoOverwriteOps) + { + pwszRename = DsoCopyStringCat(pwszFile, L".dstmp"); + fFileOpSuccess = ((pwszRename) && FPerformShellOp(FO_RENAME, pwszFile, pwszRename)); + } + + // Time to do the save to new file. + + // First we try to save by moniker using IPersistMoniker/IPersistFile. Check for defaut + // save to the current document. If to a new doc, create new moniker and save ... + if ((fDoNormalSave) && (m_pmkSourceFile)) + { + hr = SaveDocToMoniker(m_pmkSourceFile, m_pbctxSourceFile, TRUE); + } + else if (pwszFile) + { + // Create a new moniker for the save... + IMoniker *pnewmk = NULL; + if (SUCCEEDED(hr = CreateFileMoniker(pwszFile, &pnewmk))) + { + + // If current document is read-only, we want new one to be read-write... + if ((m_fOpenReadOnly) && (m_pbctxSourceFile)) + { + BIND_OPTS bndopts; bndopts.cbStruct = sizeof(BIND_OPTS); + if (SUCCEEDED(m_pbctxSourceFile->GetBindOptions(&bndopts))) + { + bndopts.grfMode = (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE); + hr = m_pbctxSourceFile->SetBindOptions(&bndopts); + } + } + else if (m_pbctxSourceFile == NULL) + { + // May need to create a new bind context if we haven't already... + if (SUCCEEDED(hr = CreateBindCtx(0, &m_pbctxSourceFile))) + { + BIND_OPTS bndopts; bndopts.cbStruct = sizeof(BIND_OPTS); + bndopts.grfFlags = BIND_MAYBOTHERUSER; + bndopts.grfMode = (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE); + bndopts.dwTickCountDeadline = 10000; + hr = m_pbctxSourceFile->SetBindOptions(&bndopts); + } + } + + // Do the save with moniker bind option and keep lock... + if (SUCCEEDED(hr = SaveDocToMoniker(pnewmk, m_pbctxSourceFile, TRUE))) + { + SAFE_RELEASE_INTERFACE(m_pmkSourceFile); + SAFE_SET_INTERFACE(m_pmkSourceFile, pnewmk); + m_fOpenReadOnly = FALSE; // Should be read-write now... + } + + pnewmk->Release(); + } + } + + + // If we are not using moniker binding, or the save with new moniker failed, try to use + // a save copy approach and we will overwrite the file... + if (!(m_pmkSourceFile) || FAILED(hr)) + { + // Update the internal storage to the current doc state... + if (((m_pstgfile) || SUCCEEDED(hr = CreateObjectStorage(m_clsidObject))) && + SUCCEEDED(hr = SaveObjectStorage())) + { + // Ask for server to save to file in "Save Copy As" fashion. This produces a native + // OLE document file more similar to what happens in normal SaveAs dialog for BIFF file... + hr = SaveDocToFile(pwszFile, FALSE); + + // If that doesn't work, save out the storage as OLE storage and ... + if (FAILED(hr) && SUCCEEDED(hr = StgCreateDocfile(pwszFile, STGM_TRANSACTED | + STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &pstg))) + { + WriteClassStg(pstg, m_clsidObject); + + if (SUCCEEDED(hr = m_pstgfile->CopyTo(0, NULL, NULL, pstg))) + hr = pstg->Commit(STGC_OVERWRITE); + + pstg->Release(); + } + } + + // If that worked, and we once had a moniker, we have to dump it now... + if (SUCCEEDED(hr) && (m_pmkSourceFile)) + { + SAFE_RELEASE_INTERFACE(m_pmkSourceFile); + SAFE_RELEASE_INTERFACE(m_pbctxSourceFile); + } + } + + // If we made a copy to protect on overwrite, either restore or delete it as needed... + if ((fDoOverwriteOps) && (fFileOpSuccess) && (pwszRename)) + { + FPerformShellOp((FAILED(hr) ? FO_RENAME : FO_DELETE), pwszRename, pwszFile); + } + + // If this is an exisitng file save, or the operation failed, relock the + // the original file save source... + if ((m_pstgfile) && !(m_pmkSourceFile) && (m_pwszSourceFile) && + ((fDoNormalSave) || (FAILED(hr)))) + { + StgOpenStorage(m_pwszSourceFile, NULL, + ((m_pwszWebResource) ? + (STGM_READ | STGM_SHARE_DENY_WRITE) : + (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE)), + NULL, 0, &m_pstgSourceFile); + } + else if (SUCCEEDED(hr)) + { + // Otherwise if we succeeded, free any existing file info we have it and + // save the new file info for later re-saves (and lock)... + SAFE_FREESTRING(m_pwszSourceFile); + SAFE_FREESTRING(m_pwszWebResource); + SAFE_RELEASE_INTERFACE(m_pstmWebResource); + + // Save the name, and try to lock the file for editing... + if (m_pwszSourceFile = DsoCopyString(pwszFile)) + { + m_idxSourceName = CalcDocNameIndex(m_pwszSourceFile); + + if (!(m_pmkSourceFile) && (m_pstgfile)) + StgOpenStorage(m_pwszSourceFile, NULL, + (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE), NULL, 0, &m_pstgSourceFile); + } + } + + if (pwszRename) + DsoMemFree(pwszRename); + + if (pwszFullName) + DsoMemFree(pwszFullName); + + return hr; +} + +STDMETHODIMP CDsoDocObject::SaveToURL(LPWSTR pwszURL, BOOL fOverwriteFile, LPWSTR pwszUserName, LPWSTR pwszPassword) +{ + HRESULT hr = DSO_E_DOCUMENTREADONLY; + + // If we have no URL to save to and no previously open web stream, fail... + if ((!pwszURL) && (!m_pstmWebResource)) + return hr; + + // Save out the user name and password (if provided) for IAuthenticate... + if (pwszUserName) + { + SAFE_FREESTRING(m_pwszUsername); + m_pwszUsername = DsoCopyString(pwszUserName); + + SAFE_FREESTRING(m_pwszPassword); + m_pwszPassword = DsoCopyString(pwszPassword); + } + + if ((pwszURL) && (m_pwszWebResource) && + (DsoCompareStringsEx(pwszURL, -1, m_pwszWebResource, -1) == CSTR_EQUAL)) + pwszURL = NULL; + + if (pwszURL) + { + IStream *pstmT = NULL; + LPWSTR pwszFullUrl = NULL; + LPWSTR pwszTempFile; + + IStream *pstmBkupStm; + IStorage *pstgBkupStg; + LPWSTR pwszBkupFile, pwszBkupUrl; + UINT idxBkup; + + if (!GetTempPathForURLDownload(pwszURL, &pwszTempFile)) + return E_INVALIDARG; + + if (ValidateFileExtension(pwszURL, &pwszFullUrl)) + pwszURL = pwszFullUrl; + + // We are going to save out the current file info in case of + // an error we can restore it to do native saves back to open location... + pstmBkupStm = m_pstmWebResource; m_pstmWebResource = NULL; + pwszBkupUrl = m_pwszWebResource; m_pwszWebResource = NULL; + pwszBkupFile = m_pwszSourceFile; m_pwszSourceFile = NULL; + pstgBkupStg = m_pstgSourceFile; m_pstgSourceFile = NULL; + idxBkup = m_idxSourceName; m_idxSourceName = 0; + + // Save the object to a new (temp) file on the local drive... + if (SUCCEEDED(hr = SaveToFile(pwszTempFile, TRUE))) + { + // Then upload from that file... + hr = IPPUploadWebResource(pwszTempFile, &pstmT, pwszURL, fOverwriteFile); + } + + // If both calls succeed, we can free the old file/url location info + // and save the new information, otherwise restore the old info from backup... + if (SUCCEEDED(hr)) + { + SAFE_RELEASE_INTERFACE(pstgBkupStg); + + if ((pstmBkupStm) && (pwszBkupFile)) + FPerformShellOp(FO_DELETE, pwszBkupFile, NULL); + + SAFE_RELEASE_INTERFACE(pstmBkupStm); + SAFE_FREESTRING(pwszBkupUrl); + SAFE_FREESTRING(pwszBkupFile); + + m_pstmWebResource = pstmT; + m_pwszWebResource = DsoCopyString(pwszURL); + //m_pwszSourceFile already saved in SaveStorageToFile + //m_pstgSourceFile already saved in SaveStorageToFile + //m_idxSourceName already calced in SaveStorageToFile; + + } + else + { + if (m_pstgSourceFile) + m_pstgSourceFile->Release(); + + if (m_pwszSourceFile) + { + FPerformShellOp(FO_DELETE, m_pwszSourceFile, NULL); + DsoMemFree(m_pwszSourceFile); + } + + m_pstmWebResource = pstmBkupStm; + m_pwszWebResource = pwszBkupUrl; + m_pwszSourceFile = pwszBkupFile; + m_pstgSourceFile = pstgBkupStg; + m_idxSourceName = idxBkup; + } + + if (pwszFullUrl) + DsoMemFree(pwszFullUrl); + + DsoMemFree(pwszTempFile); + + } + else if ((m_pstmWebResource) && (m_pwszSourceFile)) + { + if (SUCCEEDED(hr = SaveToFile(NULL, TRUE))) + hr = IPPUploadWebResource(m_pwszSourceFile, &m_pstmWebResource, NULL, TRUE); + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::DoOleCommand +// +// Calls IOleCommandTarget::Exec on the active object to do a specific +// command (like Print, SaveCopy, Zoom, etc.). +// +STDMETHODIMP CDsoDocObject::DoOleCommand(DWORD dwOleCmdId, DWORD dwOptions, VARIANT* vInParam, VARIANT* vInOutParam) +{ + HRESULT hr; + OLECMD cmd = {dwOleCmdId, 0}; + TRACE2("CDsoDocObject::DoOleCommand(cmd=%d, Opts=%d\n", dwOleCmdId, dwOptions); + + // Can't issue OLECOMMANDs when in print preview mode (object calls us)... + if (InPrintPreview()) return E_ACCESSDENIED; + + // The server must support IOleCommandTarget, the CmdID being requested, and + // the command should be enabled. If this is the case, do the command... + if ((m_pcmdt) && SUCCEEDED(m_pcmdt->QueryStatus(NULL, 1, &cmd, NULL)) && + ((cmd.cmdf & OLECMDF_SUPPORTED) && (cmd.cmdf & OLECMDF_ENABLED))) + { + TRACE1("QueryStatus say supported = 0x%X\n", cmd.cmdf); + + // Do the command asked by caller on default command group... + hr = m_pcmdt->Exec(NULL, cmd.cmdID, dwOptions, vInParam, vInOutParam); + TRACE1("DocObj_IOleCommandTarget::Exec() = 0x%X\n", hr); + + if ((dwOptions == OLECMDEXECOPT_PROMPTUSER)) + { + // Handle bug issue for PPT when printing using prompt... + if ((hr == E_INVALIDARG) && (cmd.cmdID == OLECMDID_PRINT) && IsPPTObject()) + { + ODS("Retry command for PPT\n"); + hr = m_pcmdt->Exec(NULL, cmd.cmdID, OLECMDEXECOPT_DODEFAULT, vInParam, vInOutParam); + TRACE1("DocObj_IOleCommandTarget::Exec() = 0x%X\n", hr); + } + + // If user canceled an Office dialog, that's OK... + if (hr == 0x80040103) + hr = S_FALSE; + } + } + else + { + TRACE1("Command Not supportted (%d)\n", cmd.cmdf); + hr = DSO_E_COMMANDNOTSUPPORTED; + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::Close +// +// Close down the object and disconnect us from any handlers/proxies. +// +STDMETHODIMP CDsoDocObject::Close() +{ + HRESULT hr; + + ODS("CDsoDocObject::Close\n"); + m_fInClose = TRUE; + + // Make sure we are not in print preview before close... + if (InPrintPreview()) + ExitPrintPreview(TRUE); + + // Go ahead an IP deactivate the object... + hr = IPDeactivateView(); + + SAFE_RELEASE_INTERFACE(m_pprtprv); + SAFE_RELEASE_INTERFACE(m_pcmdt); + SAFE_RELEASE_INTERFACE(m_pdocv); + SAFE_RELEASE_INTERFACE(m_pipactive); + SAFE_RELEASE_INTERFACE(m_pipobj); + + // Release the OLE object and cleanup... + if (m_pole) + { + // Free running lock if we set it... + FreeRunningLock(); + + // Tell server to release our client site... + m_pole->SetClientSite(NULL); + + // Finally, close the object and release the pointer... + hr = m_pole->Close(OLECLOSE_NOSAVE); + + if (m_fDisconnectOnQuit) + CoDisconnectObject((IUnknown*)m_pole, 0); + + SAFE_RELEASE_INTERFACE(m_pole); + } + + SAFE_RELEASE_INTERFACE(m_pstgSourceFile); + SAFE_RELEASE_INTERFACE(m_pmkSourceFile); + SAFE_RELEASE_INTERFACE(m_pbctxSourceFile); + + // Free any temp file we might have... + if ((m_pstmWebResource) && (m_pwszSourceFile)) + FPerformShellOp(FO_DELETE, m_pwszSourceFile, NULL); + + SAFE_RELEASE_INTERFACE(m_pstmWebResource); + SAFE_FREESTRING(m_pwszWebResource); + SAFE_FREESTRING(m_pwszSourceFile); + m_idxSourceName = 0; + + if (m_fDisconnectOnQuit) + { + CoDisconnectObject((IUnknown*)this, 0); + m_fDisconnectOnQuit = FALSE; + } + + SAFE_RELEASE_INTERFACE(m_pstmview); + SAFE_RELEASE_INTERFACE(m_pstgfile); + + ClearMergedMenu(); + m_fInClose = FALSE; + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject Notification Functions - The OCX should call these to +// let the doc site update the object as needed. +// + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::OnNotifySizeChange +// +// Resets the size of the site window and tells UI active object to +// resize as well. If we are UI active, we'll call ResizeBorder to +// re-negotiate toolspace (allow toolbars to shrink and grow), otherwise +// we'll just set the IP active view rect (minus any toolspace, which +// should be none since object is not UI active!). +// +STDMETHODIMP_(void) CDsoDocObject::OnNotifySizeChange(LPRECT prc) +{ + RECT rc; + + SetRect(&rc, 0, 0, (prc->right - prc->left), (prc->bottom - prc->top)); + if (rc.right < 0) rc.right = 0; + if (rc.top < 0) rc.top = 0; + + // First, resize our frame site window tot he new size (don't change focus)... + if (m_hwnd) + { + m_rcViewRect = *prc; + + SetWindowPos(m_hwnd, NULL, m_rcViewRect.left, m_rcViewRect.top, + rc.right, rc.bottom, SWP_NOACTIVATE | SWP_NOZORDER); + + UpdateWindow(m_hwnd); + } + + // If we have an active object (i.e., Document is still UI active) we should + // tell it of the resize so it can re-negotiate border space... + if ((m_fObjectUIActive) && (m_pipactive)) + { + m_pipactive->ResizeBorder(&rc, (IOleInPlaceUIWindow*)&m_xOleInPlaceFrame, TRUE); + } + else if ((m_fObjectIPActive) && (m_pdocv)) + { + rc.left += m_bwToolSpace.left; rc.right -= m_bwToolSpace.right; + rc.top += m_bwToolSpace.top; rc.bottom -= m_bwToolSpace.bottom; + m_pdocv->SetRect(&rc); + } + + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::OnNotifyAppActivate +// +// Notify doc object when the top-level frame window goes active and +// deactive so it can handle window focs and paiting correctly. Failure +// to not forward this notification leads to bad behavior. +// +STDMETHODIMP_(void) CDsoDocObject::OnNotifyAppActivate(BOOL fActive, DWORD dwThreadID) +{ + // This is critical for DocObject servers, so forward these messages + // when the object is UI active... + if (m_pipactive) + { + // We should always tell obj server when our frame activates, but + // don't tell it to go deactive if the thread gaining focus is + // the server's since our frame may have lost focus because of + // a top-level modeless dialog (ex., the RefEdit dialog of Excel)... + if (!m_fObjectInModalCondition) + m_pipactive->OnFrameWindowActivate(fActive); + } + + m_fAppWindowActive = fActive; +} + +STDMETHODIMP_(void) CDsoDocObject::OnNotifyControlFocus(BOOL fGotFocus) +{ + HWND hwnd; + + // For UI Active DocObject server, we will tell them we gain/lose control focus... + if ((m_pipactive) && (!m_fObjectInModalCondition)) + { + // TODO: Normally we would notify object of loss of control focus (such as user + // moving focus from framer control to another text box or something on the same + // form), but this can cause PPT to drop its toolbar and XL to drop its formula + // bar, so we are skipping this call. We really should determine if it is needed + // for another host (like Visio or something?) but that is to do... + // + // m_pipactive->OnDocWindowActivate(fGotFocus); + + // We should forward the focus to the active window if window with the focus + // is not already one that is parented to us... + if ((fGotFocus) && !IsWindowChild(m_hwnd, GetFocus()) && + SUCCEEDED(m_pipactive->GetWindow(&hwnd))) + SetFocus(hwnd); + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::OnNotifyPaletteChanged +// +// Give the object first chance at realizing a palette. Important on +// 256 color machines, but not so critical these days when everyone is +// running full 32-bit True Color graphic cards. +// +STDMETHODIMP_(void) CDsoDocObject::OnNotifyPaletteChanged(HWND hwndPalChg) +{ + if ((m_fObjectUIActive) && (m_hwndUIActiveObj)) + SendMessage(m_hwndUIActiveObj, WM_PALETTECHANGED, (WPARAM)hwndPalChg, 0L); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::OnNotifyChangeToolState +// +// This should be called to get object to show/hide toolbars as needed. +// +STDMETHODIMP_(void) CDsoDocObject::OnNotifyChangeToolState(BOOL fShowTools) +{ + // Can't change toolbar state in print preview (sorry)... + if (InPrintPreview()) return; + + // If we want to show/hide toolbars, we can do the following... + if (fShowTools != (BOOL)m_fDisplayTools) + { + OLECMD cmd; + cmd.cmdID = OLECMDID_HIDETOOLBARS; + + m_fDisplayTools = fShowTools; + + // Use IOleCommandTarget(OLECMDID_HIDETOOLBARS) to toggle on/off. We have + // to check that server supports it and if its state matches our own so + // when toggle, we do the correct thing by the user... + if ((m_pcmdt) && SUCCEEDED(m_pcmdt->QueryStatus(NULL, 1, &cmd, NULL)) && + ((cmd.cmdf & OLECMDF_SUPPORTED) || (cmd.cmdf & OLECMDF_ENABLED))) + { + if (((m_fDisplayTools) && ((cmd.cmdf & OLECMDF_LATCHED) == OLECMDF_LATCHED)) || + (!(m_fDisplayTools) && !((cmd.cmdf & OLECMDF_LATCHED) == OLECMDF_LATCHED))) + { + m_pcmdt->Exec(NULL, OLECMDID_HIDETOOLBARS, OLECMDEXECOPT_PROMPTUSER, NULL, NULL); + } + else if (m_fDisplayTools && (IsWordObject() || IsPPTObject())) + { + // HACK: Word and PowerPoint 2007 do not report the correct latched state for the ribbon, + // so if we are trying to show the tools after hiding them, they will say they are already + // visible when the ribbon is not. This is an apparant trick they are using to force the + // ribbon visible in IE embed cases, but it is causing us problems. + m_pcmdt->Exec(NULL, OLECMDID_HIDETOOLBARS, OLECMDEXECOPT_PROMPTUSER, NULL, NULL); + } + + // There can be focus issues when turning them off, so make sure + // the object is on top of the z-order... + if ((!m_fDisplayTools) && (m_hwndIPObject)) + BringWindowToTop(m_hwndIPObject); + + // If user toggles off the toolbar while the object is UI active, and + // we are not still in activation process, we need to explictly tell Office + // apps to also hide the "Web" toolbar. For Office, OLECMDID_HIDETOOLBARS puts + // the app into a "web view" which (in some apps) brings up the web toolbar. + // Since we intend to have no tools, we have to turn it off by code... + if ((m_fObjectUIActive) && (m_fObjectActivateComplete)) + TurnOffWebToolbar(!m_fDisplayTools); + + } + else if (m_pdocv) + { + // If we have a DocObj server, but no IOleCommandTarget, do things the hard + // way and resize. When server attempts to resize window it will have to + // re-negotiate BorderSpace and we fail there, so server "should" not + // display its tools (at least that is the idea!)... + RECT rc; GetClientRect(m_hwnd, &rc); + MapWindowPoints(m_hwnd, m_hwndCtl, (LPPOINT)&rc, 2); + OnNotifySizeChange(&rc); + } + } + return; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject Protected Functions -- Helpers +// + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::InstantiateDocObjectServer (protected) +// +// Startup OLE Document Object server and get IOleObject pointer. +// +STDMETHODIMP CDsoDocObject::InstantiateDocObjectServer(REFCLSID rclsid, IOleObject **ppole) +{ + HRESULT hr; + IUnknown *punk = NULL; + + ODS("CDsoDocObject::InstantiateDocObjectServer()\n"); + + // We perform custom create in order of local server then inproc server... + if (SUCCEEDED(hr = CoCreateInstance(rclsid, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&punk)) || + SUCCEEDED(hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&punk))) + { + // Ask for IOleObject interface... + if (SUCCEEDED(hr = punk->QueryInterface(IID_IOleObject, (void**)ppole))) + { + // TODO: Add strong connection to remote server (IExternalConnection??)... + } + punk->Release(); + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateObjectStorage (protected) +// +// Makes the internal IStorage to host the object and assigns the CLSID. +// +STDMETHODIMP CDsoDocObject::CreateObjectStorage(REFCLSID rclsid) +{ + HRESULT hr; + LPWSTR pwszName; + DWORD dwid; + CHAR szbuf[256]; + + if ((!m_pstgroot)) return E_UNEXPECTED; + + // Next, create a new object storage (with unique name) in our + // temp root storage "file" (this keeps an OLE integrity some servers + // need to function correctly instead of IP activating from file directly). + + // We make a fake object storage name... + dwid = ((rclsid.Data1)|GetTickCount()); + wsprintf(szbuf, "OLEDocument%X", dwid); + + if (!(pwszName = DsoConvertToLPWSTR(szbuf))) + return E_OUTOFMEMORY; + + // Create the sub-storage... + hr = m_pstgroot->CreateStorage(pwszName, + STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pstgfile); + + DsoMemFree(pwszName); + + if (FAILED(hr)) return hr; + + // We'll also create a stream for OLE view settings (non-critical)... + if (pwszName = DsoConvertToLPWSTR(szbuf)) + { + m_pstgroot->CreateStream(pwszName, + STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pstmview); + DsoMemFree(pwszName); + } + + // Finally, write out the CLSID for the new substorage... + hr = WriteClassStg(m_pstgfile, rclsid); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::SaveObjectStorage (protected) +// +// Saves the object back to the internal IStorage. Returns S_FALSE if +// there is no file storage for this document (it depends on how file +// was loaded). In most cases we should have one, and this copies data +// into the internal storage for save. +// +STDMETHODIMP CDsoDocObject::SaveObjectStorage() +{ + HRESULT hr = S_FALSE; + IPersistStorage *pipstg = NULL; + + // Got to have object to save state... + if (!m_pole) return E_UNEXPECTED; + + // If we have file storage, ask for IPersist and Save (commit changes)... + if ((m_pstgfile) && + SUCCEEDED(hr = m_pole->QueryInterface(IID_IPersistStorage, (void**)&pipstg))) + { + if (SUCCEEDED(hr = pipstg->Save(m_pstgfile, TRUE))) + hr = pipstg->SaveCompleted(NULL); + + hr = m_pstgfile->Commit(STGC_DEFAULT); + pipstg->Release(); + } + + // Go ahead and save the view state if view still active (non-critical)... + if ((m_pdocv) && (m_pstmview)) + { + m_pdocv->SaveViewState(m_pstmview); + m_pstmview->Commit(STGC_DEFAULT); + } + + return hr; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::SaveDocToMoniker (protected) +// +// Saves document to location spcified by the moniker passed. The server +// needs to support either IPersistMoniker or IPersistFile. This is used +// primarily when document was opened by moniker instead of storage. +// +STDMETHODIMP CDsoDocObject::SaveDocToMoniker(IMoniker *pmk, IBindCtx *pbc, BOOL fKeepLock) +{ + HRESULT hr = E_FAIL; + IPersistMoniker *prstmk; + LPOLESTR pwszFullName = NULL; + + CHECK_NULL_RETURN(m_pole, E_UNEXPECTED); + CHECK_NULL_RETURN(pmk, E_POINTER); + + // Get IPersistMoniker interface and ask it to save context if it existing moniker... + if (SUCCEEDED(hr = m_pole->QueryInterface(IID_IPersistMoniker, (void**)&prstmk))) + { + hr = prstmk->Save(pmk, pbc, fKeepLock); + prstmk->Release(); + } + + // If that failed to work, switch to IPersistFile and use full path to the new file... + if (FAILED(hr) && SUCCEEDED(hr = pmk->GetDisplayName(pbc, NULL, &pwszFullName))) + { + hr = SaveDocToFile(pwszFullName, fKeepLock); + CoTaskMemFree(pwszFullName); + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::SaveDocToFile (protected) +// +// Saves document to location spcified by the path passed. The server +// needs to support either IPersistFile. +// +STDMETHODIMP CDsoDocObject::SaveDocToFile(LPWSTR pwszFullName, BOOL fKeepLock) +{ + HRESULT hr = E_FAIL; + IPersistFile *pipfile = NULL; + + BOOL fSameAsOpen = ((m_pwszSourceFile) && + DsoCompareStringsEx(pwszFullName, lstrlenW(pwszFullName), + m_pwszSourceFile, lstrlenW(m_pwszSourceFile)) == CSTR_EQUAL); + + if (SUCCEEDED(hr = m_pole->QueryInterface(IID_IPersistFile, (void**)&pipfile))) + { +#ifdef DSO_WORD12_PERSIST_BUG + LPOLESTR pwszWordCurFile = NULL; + // HACK: Word 2007 RTM has a bug in its IPersistFile::Save method which will cause it to save + // to the old file location and not the new one, so if the document being saved is a Word + // object and we are saving to a new file, then got to run this hack to copy the saved bits + // to the correct location... + if (IsWordObject()) + { + hr = pipfile->GetCurFile(&pwszWordCurFile); + if ((fSameAsOpen) && (pwszWordCurFile)) + { + // Check again if Word thinks the file is the same as we do... + fSameAsOpen = (DsoCompareStringsEx(pwszFullName, lstrlenW(pwszFullName), + pwszWordCurFile, lstrlenW(pwszWordCurFile)) == CSTR_EQUAL); + if (fSameAsOpen) + { // If it is the same file after all, we don't need to do the hack... + CoTaskMemFree(pwszWordCurFile); + pwszWordCurFile = NULL; + } + } + } +#endif + + // Do the save using file path or NULL if we are saving to current file... + hr = pipfile->Save((fSameAsOpen ? NULL : pwszFullName), fKeepLock); + +#ifdef DSO_WORD12_PERSIST_BUG + // HACK: If we have the pwszWordCurFile, we'll assume Word 12 RTM might have saved this, and we + // need to check if Word saved to the right path or not. So check the paths, and if the new + // file is not there, copy the file Word saved to the new location... + if (pwszWordCurFile) + { + if (SUCCEEDED(hr) && !FFileExists(pwszFullName) && FFileExists(pwszWordCurFile)) + { + if (!FPerformShellOp(FO_COPY, pwszWordCurFile, pwszFullName)) + hr = E_ACCESSDENIED; + } + CoTaskMemFree(pwszWordCurFile); + } + // Hopefully, Word should have this fixed by Office 2007 SP1 and we can remove this hack! +#endif + pipfile->Release(); + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::ValidateDocObjectServer (protected) +// +// Quick validation check to see if CLSID is for DocObject server. +// +// Officially, the only way to determine if a server supports ActiveX +// Document embedding is to IP activate it and ask for IOleDocument, +// but that means going through the IP process just to fail if IOleDoc +// is not supported. Therefore, we are going to rely on the server's +// honesty in setting its reg keys to include the "DocObject" sub key +// under their CLSID. +// +// This is 99% accurate. For those servers that fail, too bad charlie! +// +STDMETHODIMP CDsoDocObject::ValidateDocObjectServer(REFCLSID rclsid) +{ + HRESULT hr = DSO_E_INVALIDSERVER; + CHAR szKeyCheck[256]; + LPSTR pszClsid; + HKEY hkey; + + // We don't handle MSHTML even though it is DocObject server. If you plan + // to view web pages in browser-like context, best to use WebBrowser control... + if (rclsid == CLSID_MSHTML_DOCUMENT) + return hr; + + // Convert the CLSID to a string and check for DocObject sub key... + if (pszClsid = DsoCLSIDtoLPSTR(rclsid)) + { + wsprintf(szKeyCheck, "CLSID\\%s\\DocObject", pszClsid); + + if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyCheck, 0, KEY_READ, &hkey) == ERROR_SUCCESS) + { + hr = S_OK; + RegCloseKey(hkey); + } + + DsoMemFree(pszClsid); + } + else hr = E_OUTOFMEMORY; + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::GetDocumentTypeAndFileExtension +// +// Returns default file type and extension for a save of embedded object. +// +STDMETHODIMP_(BOOL) CDsoDocObject::GetDocumentTypeAndFileExtension(WCHAR** ppwszFileType, WCHAR** ppwszFileExt) +{ + DWORD dwType, dwSize; + LPWSTR pwszExt = NULL; + LPWSTR pwszType = NULL; + LPSTR pszType = NULL; + LPSTR pszClsid; + CHAR szkey[255]; + CHAR szbuf[255]; + HKEY hk; + + if ((ppwszFileType == NULL) && (ppwszFileExt == NULL)) + return FALSE; + + pszClsid = DsoCLSIDtoLPSTR(m_clsidObject); + if (!pszClsid) return FALSE; + + wsprintf(szkey, "CLSID\\%s\\DefaultExtension", pszClsid); + if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szkey, 0, KEY_READ, &hk) == ERROR_SUCCESS) + { + LPSTR pszT = szbuf; szbuf[0] = '\0'; dwSize = 255; + if (RegQueryValueEx(hk, NULL, 0, &dwType, (BYTE*)pszT, &dwSize) == ERROR_SUCCESS) + { + while (*(pszT++) && (*pszT != ',')) + (void)(0); + + if (*pszT == ',') + (pszType = pszT)++; + + *pszT = '\0'; + } + else lstrcpy(szbuf, ".ole"); + + RegCloseKey(hk); + } + else lstrcpy(szbuf, ".ole"); + + pwszExt = DsoConvertToLPWSTR(szbuf); + if (ppwszFileExt) *ppwszFileExt = pwszExt; + + if (ppwszFileType) + { + ULONG cb1, cb2; + LPWSTR pwszCombined; + CHAR szUnknownType[255]; + + if (!(*pszType)) + { + szUnknownType[0] = '\0'; + wsprintf(szUnknownType, "Native Document (*%s)", szbuf); + pszType = szUnknownType; + } + pwszType = DsoConvertToLPWSTR(pszType); + + cb1 = lstrlenW(pwszExt); + cb2 = lstrlenW(pwszType); + + pwszCombined = (LPWSTR)DsoMemAlloc(((cb1 + cb2 + 4) * sizeof(WCHAR))); + if (pwszCombined) + { + memcpy(&pwszCombined[0], pwszType,(cb2 * sizeof(WCHAR))); + pwszCombined[cb2] = L'\0'; + + pwszCombined[cb2 + 1] = L'*'; + memcpy(&pwszCombined[cb2 + 2], pwszExt, (cb1 * sizeof(WCHAR))); + pwszCombined[cb2 + 2 + cb1] = L'\0'; + pwszCombined[cb2 + 3 + cb1] = L'\0'; + + DsoMemFree(pwszType); + } + + *ppwszFileType = ((pwszCombined) ? pwszCombined : pwszType); + } + + if ((ppwszFileExt == NULL) && (pwszExt)) + DsoMemFree(pwszExt); + + DsoMemFree(pszClsid); + return (((ppwszFileExt) && (*ppwszFileExt)) || + ((ppwszFileType) && (*ppwszFileType))); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::ValidateFileExtension (protected) +// +// Adds a default extension to save file path if user didn't provide +// one (uses CLSID and registry to determine default extension). +// +STDMETHODIMP_(BOOL) CDsoDocObject::ValidateFileExtension(WCHAR* pwszFile, WCHAR** ppwszOut) +{ + BOOL fHasExt = FALSE; + BOOL fChangedExt = FALSE; + LPWSTR pwszT; + LPWSTR pwszExt = NULL; + DWORD dw; + + if ((pwszFile) && (dw = lstrlenW(pwszFile)) && (ppwszOut)) + { + *ppwszOut = NULL; + + pwszT = (pwszFile + dw); + while ((pwszT != pwszFile) && + (*(--pwszT)) && ((*pwszT != L'\\') && (*pwszT != L'/'))) + { + if (*pwszT == L'.') fHasExt = TRUE; + } + + if (!(fHasExt) && GetDocumentTypeAndFileExtension(NULL, &pwszExt)) + { + *ppwszOut = DsoCopyStringCat(pwszFile, pwszExt); + fChangedExt = ((*ppwszOut) != NULL); + } + } + + return fChangedExt; +} + + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::EnsureOleServerRunning (protected) +// +// Verifies the DocObject server is running and is optionally locked +// while the embedding is taking place. +// +STDMETHODIMP CDsoDocObject::EnsureOleServerRunning(BOOL fLockRunning) +{ + HRESULT hr = S_FALSE; + IBindCtx *pbc; + IRunnableObject *pro; + IOleContainer *pocnt; + BIND_OPTS bnd = {sizeof(BIND_OPTS), BIND_MAYBOTHERUSER, (STGM_READWRITE|STGM_SHARE_EXCLUSIVE), 10000}; + + TRACE1("CDsoDocObject::EnsureOleServerRunning(%d)\n", (DWORD)fLockRunning); + if (m_pole == NULL) return E_FAIL; + + // If we are already locked, don't need to do this again... + if (m_fLockedServerRunning) + return hr; + + // Create a bind ctx... + if (FAILED(CreateBindCtx(0, &pbc))) + return E_UNEXPECTED; + + // Setup default bind options for the run operation... + pbc->SetBindOptions(&bnd); + + // Get IRunnableObject and set server to run as OLE object. We check the + // running state first since this is proper OLE, but note that this is not + // returned from out-of-proc server, but the in-proc handler. Also note, we + // specify a timeout in case the object never starts, and "check" the object + // runs without IMessageFilter errors... + if (SUCCEEDED(m_pole->QueryInterface(IID_IRunnableObject, (void**)&pro))) + { + + // If the object is not currently running, let's run it... + if (!(pro->IsRunning())) + hr = pro->Run(pbc); + + // Set the object server as a contained object (i.e., OLE object)... + pro->SetContainedObject(TRUE); + + // Lock running if desired... + if (fLockRunning) + m_fLockedServerRunning = SUCCEEDED(pro->LockRunning(TRUE, TRUE)); + + pro->Release(); + } + else if (SUCCEEDED(m_pole->QueryInterface(IID_IOleContainer, (void**)&pocnt))) + { + if (fLockRunning) + m_fLockedServerRunning = SUCCEEDED(pocnt->LockContainer(TRUE)); + + pocnt->Release(); + } + + pbc->Release(); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::FreeRunningLock (protected) +// +// Free any previous lock made by EnsureOleServerRunning. +// +STDMETHODIMP_(void) CDsoDocObject::FreeRunningLock() +{ + IRunnableObject *pro; + IOleContainer *pocnt; + + ODS("CDsoDocObject::FreeRunningLock(%d)\n"); + ASSERT(m_pole); + + // Don't do anything if we didn't lock the server... + if (m_fLockedServerRunning == FALSE) + return; + + // Get IRunnableObject and free lock... + if (SUCCEEDED(m_pole->QueryInterface(IID_IRunnableObject, (void**)&pro))) + { + pro->LockRunning(FALSE, TRUE); + pro->Release(); + } + else if (SUCCEEDED(m_pole->QueryInterface(IID_IOleContainer, (void**)&pocnt))) + { + pocnt->LockContainer(FALSE); + pocnt->Release(); + } + + m_fLockedServerRunning = FALSE; + return; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::SetRunningServerLock +// +// Sets an external lock on the running object server. +// +STDMETHODIMP CDsoDocObject::SetRunningServerLock(BOOL fLock) +{ + HRESULT hr; + TRACE1("CDsoDocObject::SetRunningServerLock(%d)\n", (DWORD)fLock); + + // Word doesn't obey normal running lock, but does have method to explicitly + // lock the server for mail, so we'll use that in the Word case... + if (IsWordObject()) + { + IClassFactory *pcf = NULL; + interface ifoo : public IUnknown + { + STDMETHOD(_uncall)() PURE; + STDMETHOD(lock)(BOOL f) PURE; + } *pi = NULL; + const GUID iidifoo = {0x0006729A, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; + + SEH_TRY + hr = CoGetClassObject(CLSID_WORD_DOCUMENT_DOC, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void**)&pcf); + if (SUCCEEDED(hr) && (pcf)) + { + hr = pcf->QueryInterface(iidifoo, (void**)&pi); + if (SUCCEEDED(hr) && (pi)) + { + hr = pi->lock(fLock); + pi->Release(); + } + pcf->Release(); + } + SEH_EXCEPT(hr) + } + else + { + if (fLock) + { + hr = EnsureOleServerRunning(TRUE); + } + else + { + hr = (FreeRunningLock(), S_OK); + } + } + + return hr; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CreateIPPBindResource (protected) +// +// Returns an instance of MSDAIPP URL resource provider which is used by +// Office/Windows for Web Folders (DAV/FPSE server). +// +STDMETHODIMP_(IUnknown*) CDsoDocObject::CreateIPPBindResource() +{ + HRESULT hr; + IDBProperties* pdbprops = NULL; + IBindResource* pres = NULL; + DBPROPSET rdbpset; + DBPROP rdbp[4]; + BSTR bstrLock; + DWORD dw = 256; + CHAR szUserName[256]; + + if (FAILED(CoCreateInstance(CLSID_MSDAIPP_BINDER, NULL, + CLSCTX_INPROC, IID_IDBProperties, (void**)&pdbprops))) + return NULL; + + bstrLock = (GetUserName(szUserName, &dw) ? DsoConvertToBSTR(szUserName) : NULL); + + memset(rdbp, 0, sizeof(4 * sizeof(DBPROP))); + + rdbpset.cProperties = 4; + rdbpset.guidPropertySet = DBPROPSET_DBINIT; + rdbpset.rgProperties = rdbp; + + rdbp[0].dwPropertyID = DBPROP_INIT_BINDFLAGS; + rdbp[0].vValue.vt = VT_I4; + rdbp[0].vValue.lVal = DBBINDURLFLAG_OUTPUT; + + rdbp[1].dwPropertyID = DBPROP_INIT_LOCKOWNER; + rdbp[1].vValue.vt = VT_BSTR; + rdbp[1].vValue.bstrVal = bstrLock; + + rdbp[2].dwPropertyID = DBPROP_INIT_LCID; + rdbp[2].vValue.vt = VT_I4; + rdbp[2].vValue.lVal = GetThreadLocale(); + + rdbp[3].dwPropertyID = DBPROP_INIT_PROMPT; + rdbp[3].vValue.vt = VT_I2; + rdbp[3].vValue.iVal = DBPROMPT_COMPLETE; + + if (pdbprops->SetProperties(1, &rdbpset) == S_OK) + { +#ifdef DSO_MSDAIPP_USE_DAVONLY + BSTR bstrClsid = SysAllocString(L"{9FECD570-B9D4-11D1-9C78-0000F875AC61}"); + if (bstrClsid) + { + rdbpset.cProperties = 1; + rdbpset.guidPropertySet = DBPROPSET_MSDAIPP_INIT; + rdbpset.rgProperties = rdbp; + + rdbp[0].dwPropertyID = 6; // DBPROP_INIT_PROTOCOLPROVIDER; + rdbp[0].vValue.vt = VT_BSTR; + rdbp[0].vValue.bstrVal = bstrClsid; + + hr = pdbprops->SetProperties(1, &rdbpset); + SysFreeString(bstrClsid); + } +#endif + hr = pdbprops->QueryInterface(IIDX_IBindResource, (void**)&pres); + } + + SAFE_FREEBSTR(bstrLock); + pdbprops->Release(); + + return (IUnknown*)pres; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::IPPDownloadWebResource (protected) +// +// Downloads the file specified by the URL to the given temp file. Locks +// the web resource for editing if ppstmKeepForSave is requested. +// +STDMETHODIMP CDsoDocObject::IPPDownloadWebResource(LPWSTR pwszURL, LPWSTR pwszFile, IStream** ppstmKeepForSave) +{ + HRESULT hr = E_UNEXPECTED; + IStream *pstm = NULL; + IBindResource *pres = NULL; + BYTE *rgbBuf; + DWORD dwStatus, dwBindFlags; + ULONG cbRead, cbWritten; + HANDLE hFile; + + // Sanity check... + if ((pwszURL == NULL) || (pwszFile == NULL) || (ppstmKeepForSave == NULL)) + return E_INVALIDARG; + + // We need MSDAIPP for full write access... + if (!(m_punkIPPResource) && !(m_punkIPPResource = CreateIPPBindResource())) + return DSO_E_REQUIRESMSDAIPP; + + rgbBuf = new BYTE[10240]; //a 10-k buffer for reading + if (!rgbBuf) return E_OUTOFMEMORY; + + // Use IBindResource::Bind to open an IStream and copy out the date to + // the file given. This will then be used to load the object from the file... + if (SUCCEEDED(m_punkIPPResource->QueryInterface(IIDX_IBindResource, (void**)&pres))) + { + dwBindFlags = (DBBINDURLFLAG_READ | DBBINDURLFLAG_WRITE | DBBINDURLFLAG_OUTPUT | DBBINDURLFLAG_SHARE_DENY_WRITE); +callagain: + if (SUCCEEDED(hr = pres->Bind(NULL, pwszURL, dwBindFlags, DBGUIDX_STREAM, + IID_IStream, (IAuthenticate*)&m_xAuthenticate, NULL, &dwStatus, (IUnknown**)&pstm))) + { + LARGE_INTEGER lintStart; lintStart.QuadPart = 0; + hr = pstm->Seek(lintStart, STREAM_SEEK_SET, NULL); + + if (FOpenLocalFile(pwszFile, GENERIC_WRITE, 0, CREATE_ALWAYS, &hFile)) + { + while (SUCCEEDED(hr)) + { + if (FAILED(hr = pstm->Read((void*)rgbBuf, 10240, &cbRead)) || + (cbRead == 0)) + break; + + if (FALSE == WriteFile(hFile, rgbBuf, cbRead, &cbWritten, NULL)) + { + hr = E_WIN32_LASTERROR; + break; + } + } + + CloseHandle(hFile); + } + else hr = E_WIN32_LASTERROR; + + SAFE_SET_INTERFACE(*ppstmKeepForSave, pstm); + + pstm->Release(); + } + else if ((hr == DB_E_NOTSUPPORTED) && ((dwBindFlags & DBBINDURLFLAG_OUTPUT) == DBBINDURLFLAG_OUTPUT)) + { + // WEC4 does not support DBBINDURLFLAG_OUTPUT flag, but if we are using WEC + // we don't really need the flag since this is not an HTTP GET call. Flip the + // flag off and call the method again to connect to server... + dwBindFlags &= ~DBBINDURLFLAG_OUTPUT; + goto callagain; + } + + pres->Release(); + } + + // Map an OLEDB error to a common "file" error so a user + // (and VB/VBScript) would better understand... + if (FAILED(hr)) + { + switch (hr) + { + case DB_E_NOTFOUND: hr = STG_E_FILENOTFOUND; break; + case DB_E_READONLY: + case DB_E_RESOURCELOCKED: hr = STG_E_LOCKVIOLATION; break; + case DB_SEC_E_PERMISSIONDENIED: + case DB_SEC_E_SAFEMODE_DENIED: hr = E_ACCESSDENIED; break; + case DB_E_CANNOTCONNECT: + case DB_E_TIMEOUT: hr = E_VBA_NOREMOTESERVER; break; + case E_NOINTERFACE: hr = E_UNEXPECTED; break; + } + } + + delete [] rgbBuf; + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::IPPUploadWebResource (protected) +// +// Uploads the file to a URL. The code can be used two ways: +// +// 1.) If ppstmSave contains a pointer to an existing IStream*, then we +// just upload to the existing stream. This allows for normal "Save" +// on an open web resource. +// +// 2.) If ppstmSave is NULL (or contains a NULL IStream*), we create a new +// web resource at the location given by pwszURLSaveTo and save to its +// stream. If ppstmSave is passed, we return the new IStream* to the +// caller who can then use it to do the other type of save next time. +// +STDMETHODIMP CDsoDocObject::IPPUploadWebResource(LPWSTR pwszFile, IStream** ppstmSave, LPWSTR pwszURLSaveTo, BOOL fOverwriteFile) +{ + HRESULT hr = E_UNEXPECTED; + ICreateRow *pcrow = NULL; + IStream *pstm = NULL; + BYTE *rgbBuf; + HANDLE hFile; + BOOL fstmIn = FALSE; + ULONG cbRead, cbWritten; + DWORD dwStatus, dwBindFlags; + + // We need MSDAIPP for full write access... + if (!(m_punkIPPResource) && !(m_punkIPPResource = CreateIPPBindResource())) + return DSO_E_REQUIRESMSDAIPP; + + // Check if this a "Save" on existing IStream* and jump to loop... + if ((ppstmSave) && (fstmIn = (BOOL)(pstm = *ppstmSave))) + goto uploadfrominstm; + + // Check the URL string and ask for ICreateRow (to make new web resource)... + if (!(pwszURLSaveTo) || !LooksLikeHTTP(pwszURLSaveTo) || + FAILED(m_punkIPPResource->QueryInterface(IIDX_ICreateRow, (void**)&pcrow))) + return hr; + + dwBindFlags = ( DBBINDURLFLAG_READ | + DBBINDURLFLAG_WRITE | + DBBINDURLFLAG_SHARE_DENY_WRITE | + (fOverwriteFile ? DBBINDURLFLAG_OVERWRITE : 0)); + + if (SUCCEEDED(hr = pcrow->CreateRow(NULL, pwszURLSaveTo, dwBindFlags, DBGUIDX_STREAM, + IID_IStream, (IAuthenticate*)&m_xAuthenticate, NULL, &dwStatus, NULL, (IUnknown**)&pstm))) + { + + // Once we are here, we have a stream (either handed in or opened from above). + // We just loop through and read from the file to the stream... +uploadfrominstm: + if (rgbBuf = new BYTE[10240]) //a 10-k buffer for reading + { + if (FOpenLocalFile(pwszFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &hFile)) + { + LARGE_INTEGER lintStart; lintStart.QuadPart = 0; + hr = pstm->Seek(lintStart, STREAM_SEEK_SET, NULL); + + while (SUCCEEDED(hr)) + { + if (FALSE == ReadFile(hFile, rgbBuf, 10240, &cbRead, NULL)) + { + hr = E_WIN32_LASTERROR; + break; + } + + if (0 == cbRead) break; + + if (FAILED(hr = pstm->Write((void*)rgbBuf, cbRead, &cbWritten))) + break; + } + + // Need to commit the changes to make it official... + if (SUCCEEDED(hr)) + hr = pstm->Commit(STGC_DEFAULT); + + CloseHandle(hFile); + } + else hr = E_WIN32_LASTERROR; + + delete [] rgbBuf; + } + else hr = E_OUTOFMEMORY; + + // If we are not using a passed in IStream (and therefore created one), we + // should AddRef and pass back (if caller asked us to)... + if (!fstmIn) + { + if (SUCCEEDED(hr) && (ppstmSave) && (!(*ppstmSave))) + { + SAFE_SET_INTERFACE(*ppstmSave, pstm); + } + pstm->Release(); + } + + } + + // Map an OLEDB error to a common "file" error so a user + // (and VB/VBScript) would better understand... + if (FAILED(hr)) + { + switch (hr) + { + case DB_E_RESOURCEEXISTS: hr = STG_E_FILEALREADYEXISTS; break; + case DB_E_NOTFOUND: hr = STG_E_PATHNOTFOUND; break; + case DB_E_READONLY: + case DB_E_RESOURCELOCKED: hr = STG_E_LOCKVIOLATION; break; + case DB_SEC_E_PERMISSIONDENIED: + case DB_SEC_E_SAFEMODE_DENIED: hr = E_ACCESSDENIED; break; + case DB_E_CANNOTCONNECT: + case DB_E_TIMEOUT: hr = E_VBA_NOREMOTESERVER; break; + case DB_E_OUTOFSPACE: hr = STG_E_MEDIUMFULL; break; + case E_NOINTERFACE: hr = E_UNEXPECTED; break; + } + } + + if (pcrow) + pcrow->Release(); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::TurnOffWebToolbar (protected) +// +// This function "turns off" the Web toolbar used by Office apps to +// do in-site navigation. The problem is when toggling tools off the +// bar may still be visible, so we have to explicitly turn it off if +// we want a true "no tool" state. +// +// This should *only* be called when turnning off the bars after object +// if inplace active. The call to OLECMDID_HIDETOOLBARS should hide all +// the primay toolbars, so we are just catching those attached to the +// document collection itself that are not in primary set. +// +STDMETHODIMP_(void) CDsoDocObject::TurnOffWebToolbar(BOOL fTurnedOff) +{ + IDispatch *pdisp; + VARIANT vtT[5]; + + ODS("CDsoDocObject::TurnOffWebToolbar()\n"); + + // Can't change toolbar state in print preview... + if (InPrintPreview()) return; + + if ((m_pipactive) && + (SUCCEEDED(m_pipactive->QueryInterface(IID_IDispatch, (void**)&pdisp))) && (pdisp)) + { + // Get the commandbars on the document object.... + if (SUCCEEDED(DsoDispatchInvoke(pdisp, + L"CommandBars", 0, DISPATCH_PROPERTYGET, 0, NULL, &vtT[0]))) + { + // Turn off Web toolbar... + ASSERT(vtT[0].vt == VT_DISPATCH); + vtT[1].vt = VT_BSTR; vtT[1].bstrVal = SysAllocString(L"Web"); + + if (SUCCEEDED(DsoDispatchInvoke(vtT[0].pdispVal, + L"Item", 0, DISPATCH_PROPERTYGET, 1, &vtT[1], &vtT[2]))) + { + ASSERT(vtT[2].vt == VT_DISPATCH); + vtT[3].vt = VT_BOOL; vtT[3].boolVal = 0; + DsoDispatchInvoke(vtT[2].pdispVal, + L"Visible", 0, DISPATCH_PROPERTYPUT, 1, &vtT[3], &vtT[2]); + VariantClear(&vtT[2]); + } + + VariantClear(&vtT[1]); + + // Word 2002/2003 also displays Reviewing toolbar, so kill it too... + if (fTurnedOff && IsWordObject()) + { + ASSERT(vtT[0].vt == VT_DISPATCH); + vtT[1].vt = VT_BSTR; vtT[1].bstrVal = SysAllocString(L"Reviewing"); + + if (SUCCEEDED(DsoDispatchInvoke(vtT[0].pdispVal, + L"Item", 0, DISPATCH_PROPERTYGET, 1, &vtT[1], &vtT[2]))) + { + ASSERT(vtT[2].vt == VT_DISPATCH); + vtT[3].vt = VT_BOOL; vtT[3].boolVal = 0; + DsoDispatchInvoke(vtT[2].pdispVal, + L"Visible", 0, DISPATCH_PROPERTYPUT, 1, &vtT[3], &vtT[2]); + VariantClear(&vtT[2]); + } + + VariantClear(&vtT[1]); + } + + VariantClear(&vtT[0]); + } + + pdisp->Release(); + } + +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::ClearMergedMenu (protected) +// +// Frees the merged menu set by host. +// +STDMETHODIMP_(void) CDsoDocObject::ClearMergedMenu() +{ + if (m_hMenuMerged) + { + int cbMenuCnt = GetMenuItemCount(m_hMenuMerged); + for (int i = cbMenuCnt; i >= 0; --i) + RemoveMenu(m_hMenuMerged, i, MF_BYPOSITION); + + DestroyMenu(m_hMenuMerged); + m_hMenuMerged = NULL; + } +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CalcDocNameIndex (protected) +// +// Calculates position of the name portion of the full path string. +// +STDMETHODIMP_(DWORD) CDsoDocObject::CalcDocNameIndex(LPCWSTR pwszPath) +{ + DWORD cblen, idx = 0; + if ((pwszPath) && ((cblen = lstrlenW(pwszPath)) > 1)) + { + for (idx = cblen; idx > 0; --idx) + { + if (pwszPath[idx] == L'\\') + break; + } + + if ((idx) && !(++idx < cblen)) + idx = 0; + } + return idx; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::OnDraw (protected) +// +// Site drawing (does nothing in this version). +// +STDMETHODIMP_(void) CDsoDocObject::OnDraw(DWORD dvAspect, HDC hdcDraw, LPRECT prcBounds, LPRECT prcWBounds, HDC hicTargetDev, BOOL fOptimize) +{ + // Don't have to draw anything, object does all this because we are + // always UI active. If we allowed for multiple objects and had some + // non-UI active, we would have to do some drawing, but that will not + // happen in this sample. +} + + +//////////////////////////////////////////////////////////////////////// +// +// ActiveX Document Site Interfaces +// + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject IUnknown Interface Methods +// +// STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); +// STDMETHODIMP_(ULONG) AddRef(void); +// STDMETHODIMP_(ULONG) Release(void); +// +STDMETHODIMP CDsoDocObject::QueryInterface(REFIID riid, void** ppv) +{ + ODS("CDsoDocObject::QueryInterface\n"); + CHECK_NULL_RETURN(ppv, E_POINTER); + + HRESULT hr = S_OK; + + if (IID_IUnknown == riid) + { + *ppv = (IUnknown*)this; + } + else if (IID_IOleClientSite == riid) + { + *ppv = (IOleClientSite*)&m_xOleClientSite; + } + else if ((IID_IOleInPlaceSite == riid) || (IID_IOleWindow == riid)) + { + *ppv = (IOleInPlaceSite*)&m_xOleInPlaceSite; + } + else if (IID_IOleDocumentSite == riid) + { + *ppv = (IOleDocumentSite*)&m_xOleDocumentSite; + } + else if ((IID_IOleInPlaceFrame == riid) || (IID_IOleInPlaceUIWindow == riid)) + { + *ppv = (IOleInPlaceFrame*)&m_xOleInPlaceFrame; + } + else if (IID_IOleCommandTarget == riid) + { + *ppv = (IOleCommandTarget*)&m_xOleCommandTarget; + } + else if (IIDX_IAuthenticate == riid) + { + *ppv = (IAuthenticate*)&m_xAuthenticate; + } + else if (IID_IServiceProvider == riid) + { + *ppv = (IServiceProvider*)&m_xServiceProvider; + } + else if (IID_IContinueCallback == riid) + { + *ppv = (IContinueCallback*)&m_xContinueCallback; + } + else if (IID_IOlePreviewCallback == riid) + { + *ppv = (IOlePreviewCallback*)&m_xPreviewCallback; + } + else + { + *ppv = NULL; + hr = E_NOINTERFACE; + } + + if (NULL != *ppv) + ((IUnknown*)(*ppv))->AddRef(); + + return hr; +} + +STDMETHODIMP_(ULONG) CDsoDocObject::AddRef(void) +{ + TRACE1("CDsoDocObject::AddRef - %d\n", m_cRef + 1); + return ++m_cRef; +} + +STDMETHODIMP_(ULONG) CDsoDocObject::Release(void) +{ + TRACE1("CDsoDocObject::Release - %d\n", m_cRef - 1); + return --m_cRef; +} + + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XOleClientSite -- IOleClientSite Implementation +// +// STDMETHODIMP SaveObject(void); +// STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhich, LPMONIKER* ppmk); +// STDMETHODIMP GetContainer(LPOLECONTAINER* ppContainer); +// STDMETHODIMP ShowObject(void); +// STDMETHODIMP OnShowWindow(BOOL fShow); +// STDMETHODIMP RequestNewObjectLayout(void); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, OleClientSite) + +STDMETHODIMP CDsoDocObject::XOleClientSite::SaveObject(void) +{ + ODS("CDsoDocObject::XOleClientSite::SaveObject\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleClientSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk) +{ + HRESULT hr = OLE_E_CANT_GETMONIKER; + METHOD_PROLOGUE(CDsoDocObject, OleClientSite); + + TRACE2("CDsoDocObject::XOleClientSite::GetMoniker(%d, %d)\n", dwAssign, dwWhichMoniker); + CHECK_NULL_RETURN(ppmk, E_POINTER); + *ppmk = NULL; + + // Provide moniker for object opened by moniker... + switch(dwWhichMoniker) + { + case OLEWHICHMK_OBJREL: + case OLEWHICHMK_OBJFULL: + { + if (pThis->m_pmkSourceFile) + { + *ppmk = pThis->m_pmkSourceFile; + hr = S_OK; + } + else if (dwAssign == OLEGETMONIKER_FORCEASSIGN) + { + // TODO: Should we allow frce create of moniker if we don't start with it? + } + } + break; + } + + // Need to AddRef returned value to caller on success... + if ((hr == S_OK) && (*ppmk)) + ((IUnknown*)*ppmk)->AddRef(); + + return hr; +} + +STDMETHODIMP CDsoDocObject::XOleClientSite::GetContainer(IOleContainer** ppContainer) +{ + ODS("CDsoDocObject::XOleClientSite::GetContainer\n"); + if (ppContainer) *ppContainer = NULL; + return E_NOINTERFACE; +} + +STDMETHODIMP CDsoDocObject::XOleClientSite::ShowObject(void) +{ + ODS("CDsoDocObject::XOleClientSite::ShowObject\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleClientSite::OnShowWindow(BOOL fShow) +{ + ODS("CDsoDocObject::XOleClientSite::OnShowWindow\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleClientSite::RequestNewObjectLayout(void) +{ + ODS("CDsoDocObject::XOleClientSite::RequestNewObjectLayout\n"); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XOleInPlaceSite -- IOleInPlaceSite Implementation +// +// STDMETHODIMP GetWindow(HWND* phWnd); +// STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); +// STDMETHODIMP CanInPlaceActivate(void); +// STDMETHODIMP OnInPlaceActivate(void); +// STDMETHODIMP OnUIActivate(void); +// STDMETHODIMP GetWindowContext(LPOLEINPLACEFRAME* ppIIPFrame, LPOLEINPLACEUIWINDOW* ppIIPUIWindow, LPRECT prcPos, LPRECT prcClip, LPOLEINPLACEFRAMEINFO pFI); +// STDMETHODIMP Scroll(SIZE sz); +// STDMETHODIMP OnUIDeactivate(BOOL fUndoable); +// STDMETHODIMP OnInPlaceDeactivate(void); +// STDMETHODIMP DiscardUndoState(void); +// STDMETHODIMP DeactivateAndUndo(void); +// STDMETHODIMP OnPosRectChange(LPCRECT prcPos); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, OleInPlaceSite) + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::GetWindow(HWND* phwnd) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::GetWindow\n"); + if (phwnd) *phwnd = pThis->m_hwnd; + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::ContextSensitiveHelp(BOOL fEnterMode) +{ + ODS("CDsoDocObject::XOleInPlaceSite::ContextSensitiveHelp\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::CanInPlaceActivate(void) +{ + ODS("CDsoDocObject::XOleInPlaceSite::CanInPlaceActivate\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::OnInPlaceActivate(void) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::OnInPlaceActivate\n"); + + if ((!pThis->m_pole) || + FAILED(pThis->m_pole->QueryInterface(IID_IOleInPlaceObject, (void **)&(pThis->m_pipobj)))) + return E_UNEXPECTED; + + pThis->m_fObjectIPActive = TRUE; + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::OnUIActivate(void) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::OnUIActivate\n"); + pThis->m_fObjectUIActive = TRUE; + pThis->m_pipobj->GetWindow(&(pThis->m_hwndIPObject)); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::GetWindowContext(IOleInPlaceFrame** ppFrame, + IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::GetWindowContext\n"); + + if (ppFrame) + { SAFE_SET_INTERFACE(*ppFrame, &(pThis->m_xOleInPlaceFrame)); } + + if (ppDoc) + *ppDoc = NULL; + + if (lprcPosRect) + *lprcPosRect = pThis->m_rcViewRect; + + if (lprcClipRect) + *lprcClipRect = *lprcPosRect; + + memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO)); + lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO); + lpFrameInfo->hwndFrame = pThis->m_hwnd; + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::Scroll(SIZE sz) +{ + ODS("CDsoDocObject::XOleInPlaceSite::Scroll\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::OnUIDeactivate(BOOL fUndoable) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::OnUIDeactivate\n"); + + pThis->m_fObjectUIActive = FALSE; + pThis->m_xOleInPlaceFrame.SetMenu(NULL, NULL, NULL); + SetFocus(pThis->m_hwnd); + + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::OnInPlaceDeactivate(void) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::OnInPlaceDeactivate\n"); + + pThis->m_fObjectIPActive = FALSE; + pThis->m_hwndIPObject = NULL; + SAFE_RELEASE_INTERFACE((pThis->m_pipobj)); + + pThis->m_fAttemptPptPreview = FALSE; + pThis->m_fObjectActivateComplete = FALSE; + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::DiscardUndoState(void) +{ + ODS("CDsoDocObject::XOleInPlaceSite::DiscardUndoState\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::DeactivateAndUndo(void) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceSite); + ODS("CDsoDocObject::XOleInPlaceSite::DeactivateAndUndo\n"); + if (pThis->m_pipobj) pThis->m_pipobj->InPlaceDeactivate(); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceSite::OnPosRectChange(LPCRECT lprcPosRect) +{ + ODS("CDsoDocObject::XOleInPlaceSite::OnPosRectChange\n"); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XOleDocumentSite -- IOleDocumentSite Implementation +// +// STDMETHODIMP ActivateMe(IOleDocumentView* pView); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, OleDocumentSite) + +STDMETHODIMP CDsoDocObject::XOleDocumentSite::ActivateMe(IOleDocumentView* pView) +{ + METHOD_PROLOGUE(CDsoDocObject, OleDocumentSite); + ODS("CDsoDocObject::XOleDocumentSite::ActivateMe\n"); + + HRESULT hr = E_FAIL; + IOleDocument* pmsodoc; + + // If we're passed a NULL view pointer, then try to get one from + // the document object (the object within us). + if (pView) + { + // Make sure that the view has our client site + hr = pView->SetInPlaceSite((IOleInPlaceSite*)&(pThis->m_xOleInPlaceSite)); + + pView->AddRef(); // we will be keeping the object if successful.. + } + else if (pThis->m_pole) + { + // Create a new view from the OleDocument... + if (FAILED(pThis->m_pole->QueryInterface(IID_IOleDocument, (void **)&pmsodoc))) + return E_FAIL; + + hr = pmsodoc->CreateView((IOleInPlaceSite*)&(pThis->m_xOleInPlaceSite), + pThis->m_pstmview, 0, &pView); + + pmsodoc->Release(); + } + + // If we have the view, apply view state... + if (SUCCEEDED(hr) && (pThis->m_pstmview)) + hr = pView->ApplyViewState(pThis->m_pstmview); + + // If any of the above failed, release the view and return... + if (FAILED(hr)) + { + SAFE_RELEASE_INTERFACE(pView); + return hr; + } + + // keep the view pointer... + pThis->m_pdocv = pView; + + // Get a command target (if available)... + pView->QueryInterface(IID_IOleCommandTarget, (void**)&(pThis->m_pcmdt)); + + // Make sure that the view has our client site + pView->SetInPlaceSite((IOleInPlaceSite*)&(pThis->m_xOleInPlaceSite)); + + // This sets up toolbars and menus first + if (SUCCEEDED(hr = pView->UIActivate(TRUE))) + { + // Set the window size sensitive to new toolbars + pView->SetRect(&(pThis->m_rcViewRect)); + + // Makes it all active + pView->Show(TRUE); + + pThis->m_fAppWindowActive = TRUE; + pThis->m_fObjectActivateComplete = TRUE; + + // Toogle tools off if that's what user wants... + if (!(pThis->m_fDisplayTools)) + { + pThis->m_fDisplayTools = TRUE; + pThis->OnNotifyChangeToolState(FALSE); + } + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XOleInPlaceFrame -- IOleInPlaceFrame Implementation +// +// STDMETHODIMP GetWindow(HWND* phWnd); +// STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); +// STDMETHODIMP GetBorder(LPRECT prcBorder); +// STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS pBW); +// STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS pBW); +// STDMETHODIMP SetActiveObject(LPOLEINPLACEACTIVEOBJECT pIIPActiveObj, LPCOLESTR pszObj); +// STDMETHODIMP InsertMenus(HMENU hMenu, LPOLEMENUGROUPWIDTHS pMGW); +// STDMETHODIMP SetMenu(HMENU hMenu, HOLEMENU hOLEMenu, HWND hWndObj); +// STDMETHODIMP RemoveMenus(HMENU hMenu); +// STDMETHODIMP SetStatusText(LPCOLESTR pszText); +// STDMETHODIMP EnableModeless(BOOL fEnable); +// STDMETHODIMP TranslateAccelerator(LPMSG pMSG, WORD wID); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, OleInPlaceFrame) + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::GetWindow(HWND* phWnd) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::GetWindow\n"); + return pThis->m_xOleInPlaceSite.GetWindow(phWnd); +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::ContextSensitiveHelp(BOOL fEnterMode) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::ContextSensitiveHelp\n"); + return pThis->m_xOleInPlaceSite.ContextSensitiveHelp(fEnterMode); +} + + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::GetBorder(LPRECT prcBorder) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::GetBorder\n"); + CHECK_NULL_RETURN(prcBorder, E_POINTER); + + // If we don't allow Toolspace, and we are already active, give + // no space for tools (ie, hide toolabrs), otherwise give as much we can... + if (!(pThis->m_fDisplayTools) && (pThis->m_pipactive)) + SetRectEmpty(prcBorder); + else + GetClientRect(pThis->m_hwnd, prcBorder); + + TRACE_LPRECT("prcBorder", prcBorder); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::RequestBorderSpace(LPCBORDERWIDTHS pBW) +{ + ODS("CDsoDocObject::XOleInPlaceFrame::RequestBorderSpace\n"); + CHECK_NULL_RETURN(pBW, E_POINTER); + TRACE_LPRECT("pBW", pBW); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::SetBorderSpace(LPCBORDERWIDTHS pBW) +{ + RECT rc; + + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::SetBorderSpace\n"); + + if (pBW){TRACE_LPRECT("pBW", pBW);} + + GetClientRect(pThis->m_hwnd, &rc); + SetRectEmpty((RECT*)&(pThis->m_bwToolSpace)); + + if (pBW) + { + pThis->m_bwToolSpace = *pBW; + rc.left += pBW->left; rc.right -= pBW->right; + rc.top += pBW->top; rc.bottom -= pBW->bottom; + } + + // Save the current view RECT (space minus tools)... + pThis->m_rcViewRect = rc; + + // Update the active document (if alive)... + if (pThis->m_pdocv) + pThis->m_pdocv->SetRect(&(pThis->m_rcViewRect)); + + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::SetActiveObject(LPOLEINPLACEACTIVEOBJECT pIIPActiveObj, LPCOLESTR pszObj) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::SetActiveObject\n"); + + SAFE_RELEASE_INTERFACE((pThis->m_pipactive)); + pThis->m_hwndUIActiveObj = NULL; + pThis->m_dwObjectThreadID = 0; + + if (pIIPActiveObj) + { + SAFE_SET_INTERFACE(pThis->m_pipactive, pIIPActiveObj); + pIIPActiveObj->GetWindow(&(pThis->m_hwndUIActiveObj)); + pThis->m_dwObjectThreadID = GetWindowThreadProcessId(pThis->m_hwndUIActiveObj, NULL); + } + + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::InsertMenus(HMENU hMenu, LPOLEMENUGROUPWIDTHS pMGW) +{ + ODS("CDsoDocObject::XOleInPlaceFrame::InsertMenus\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::SetMenu(HMENU hMenu, HOLEMENU hOLEMenu, HWND hWndObj) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::SetMenu\n"); + + pThis->CheckForPPTPreviewChange(); + + // We really don't do anything here. We will merge the menu and set it + // later if the menubar is visible or user chooses dropdown from titlebar. + // All we do is stash current values or clear them depending on call. + if (hMenu) + { + pThis->m_hMenuActive = hMenu; + pThis->m_holeMenu = hOLEMenu; + pThis->m_hwndMenuObj = hWndObj; + + // Handle a special case where menu is being updated after initial set + // and not in close. In such a case we should force redraw control we + // are in so new menu changes are visible as soon as possible... + if ((!(pThis->m_fInClose)) && (pThis->m_hwndCtl)) + InvalidateRect(pThis->m_hwndCtl, NULL, FALSE); + } + else + { + pThis->m_hMenuActive = NULL; + pThis->m_holeMenu = NULL; + pThis->m_hwndMenuObj = NULL; + } + + // Regardless of call, make sure to cleanup a merged menu if + // one was previously created for the control... + pThis->ClearMergedMenu(); + + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::RemoveMenus(HMENU hMenu) +{ + ODS("CDsoDocObject::XOleInPlaceFrame::RemoveMenus\n"); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::SetStatusText(LPCOLESTR pszText) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + ODS("CDsoDocObject::XOleInPlaceFrame::SetStatusText\n"); + if ((pszText) && (*pszText)){TRACE1(" Status Text = %S \n", pszText);} + return ((pThis->m_psiteCtl) ? pThis->m_psiteCtl->SetStatusText(pszText) : S_OK); +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::EnableModeless(BOOL fEnable) +{ + METHOD_PROLOGUE(CDsoDocObject, OleInPlaceFrame); + TRACE1("CDsoDocObject::XOleInPlaceFrame::EnableModeless(%d)\n", fEnable); + pThis->m_fObjectInModalCondition = !fEnable; + SendMessage(pThis->m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_MODAL, (LPARAM)fEnable); + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XOleInPlaceFrame::TranslateAccelerator(LPMSG pMSG, WORD wID) +{ + ODS("CDsoDocObject::XOleInPlaceFrame::TranslateAccelerator\n"); + return S_FALSE; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XOleCommandTarget -- IOleCommandTarget Implementation +// +// STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText); +// STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, OleCommandTarget) + +STDMETHODIMP CDsoDocObject::XOleCommandTarget::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +{ + HRESULT hr = OLECMDERR_E_UNKNOWNGROUP; + METHOD_PROLOGUE(CDsoDocObject, OleCommandTarget); + if (pThis->m_pcmdCtl) + hr = pThis->m_pcmdCtl->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText); + return hr; +} + +STDMETHODIMP CDsoDocObject::XOleCommandTarget::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut) +{ + HRESULT hr = OLECMDERR_E_NOTSUPPORTED; + METHOD_PROLOGUE(CDsoDocObject, OleCommandTarget); + if (pThis->m_pcmdCtl) + hr = pThis->m_pcmdCtl->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XServiceProvider -- IServiceProvider Implementation +// +// STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, ServiceProvider) + +STDMETHODIMP CDsoDocObject::XServiceProvider::QueryService(REFGUID guidService, REFIID riid, void **ppv) +{ + METHOD_PROLOGUE(CDsoDocObject, ServiceProvider); + ODS("CDsoDocObject::XServiceProvider::QueryService\n"); + + if (pThis->m_psiteCtl) // Forward to host control/container... + return pThis->m_psiteCtl->QueryService(guidService, riid, ppv); + + return E_NOINTERFACE; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XAuthenticate -- IAuthenticate Implementation +// +// STDMETHODIMP Authenticate(HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, Authenticate) + +STDMETHODIMP CDsoDocObject::XAuthenticate::Authenticate(HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword) +{ + METHOD_PROLOGUE(CDsoDocObject, Authenticate); + ODS("CDsoDocObject::XAuthenticate::Authenticate\n"); + if (phwnd) *phwnd = ((pThis->m_pwszUsername) ? (HWND)INVALID_HANDLE_VALUE : pThis->m_hwndCtl); + if (pszUsername) *pszUsername = DsoConvertToLPOLESTR(pThis->m_pwszUsername); + if (pszPassword) *pszPassword = DsoConvertToLPOLESTR(pThis->m_pwszPassword); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XContinueCallback -- IContinueCallback Implementation +// +// STDMETHODIMP FContinue(void); +// STDMETHODIMP FContinuePrinting(LONG cPagesPrinted, LONG nCurrentPage, LPOLESTR pwszPrintStatus); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, ContinueCallback) + +STDMETHODIMP CDsoDocObject::XContinueCallback::FContinue(void) +{ // We don't support asynchronous cancel of printing, but if you wanted to add + // such functionality, this is where you could do so... + return S_OK; +} + +STDMETHODIMP CDsoDocObject::XContinueCallback::FContinuePrinting(LONG cPagesPrinted, LONG nCurrentPage, LPOLESTR pwszPrintStatus) +{ + TRACE3("CDsoDocObject::XContinueCallback::FContinuePrinting(%d, %d, %S)\n", cPagesPrinted, nCurrentPage, pwszPrintStatus); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::XPreviewCallback -- IPreviewCallback Implementation +// +// STDMETHODIMP Notify(DWORD wStatus, LONG nLastPage, LPOLESTR pwszPreviewStatus); +// +IMPLEMENT_INTERFACE_UNKNOWN(CDsoDocObject, PreviewCallback) + +STDMETHODIMP CDsoDocObject::XPreviewCallback::Notify(DWORD wStatus, LONG nLastPage, LPOLESTR pwszPreviewStatus) +{ + METHOD_PROLOGUE(CDsoDocObject, PreviewCallback); + TRACE3("CDsoDocObject::XPreviewCallback::Notify(%d, %d, %S)\n", wStatus, nLastPage, pwszPreviewStatus); + + // The only notification we act on is when the preview is done... + if ((wStatus == NOTIFY_FORCECLOSEPREVIEW) || + (wStatus == NOTIFY_FINISHED) || + (wStatus == NOTIFY_UNABLETOPREVIEW)) + pThis->ExitPrintPreview(FALSE); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::HrGetDataFromObject +// +// Function designed to give indirect access to the content in an existing +// loaded object, in a clipboard format specified in vtType. In other words, +// a call to HrGetDataFromObject("Rich Text Format", [out] array) will get the +// content of the current document in RTF format and return it as a byte array +// vector in VB6-safe safearray. This array can be converted to a string for +// display or saved to database (etc.) without saving to disk. +// +// For this to work, the object embedded must support IDataObject and the clip +// format that you request. +// +STDMETHODIMP CDsoDocObject::HrGetDataFromObject(VARIANT *pvtType, VARIANT *pvtOutput) +{ + HRESULT hr; + IDataObject *pdo = NULL; + LPWSTR pwszTypeName; + LPSTR pszFormatName; + SAFEARRAY* psa; + VOID HUGEP* prawdata; + FORMATETC ftc; + STGMEDIUM stgm; + LONG cfType; + + if ((pvtType == NULL) || PARAM_IS_MISSING(pvtType) || + (pvtOutput == NULL) || PARAM_IS_MISSING(pvtOutput)) + return E_INVALIDARG; + + VariantClear(pvtOutput); + + // We take the name and find the right clipformat for the data type... + pwszTypeName = LPWSTR_FROM_VARIANT(*pvtType); + if ((pwszTypeName) && (pszFormatName = DsoConvertToMBCS(pwszTypeName))) + { + cfType = RegisterClipboardFormat(pszFormatName); + DsoMemFree(pszFormatName); + } + else cfType = LONG_FROM_VARIANT(*pvtType, 0); + CHECK_NULL_RETURN(cfType, E_INVALIDARG); + + // We must be able to get IDataObject for the transfer to work... + if ((m_pole == NULL) || + (FAILED(m_pole->GetClipboardData(0, &pdo)) && + FAILED(m_pole->QueryInterface(IID_IDataObject, (void**)&pdo)))) + return OLE_E_CANT_GETMONIKER; + + ASSERT(pdo); CHECK_NULL_RETURN(pdo, E_UNEXPECTED); + + // We are going to ask for HGLOBAL data format only. This is majority + // of the non-binary formats, which should be sufficient here... + memset(&ftc, 0, sizeof(ftc)); + ftc.cfFormat = (WORD)cfType; + ftc.dwAspect = DVASPECT_CONTENT; + ftc.lindex = -1; ftc.tymed = TYMED_HGLOBAL; + + memset(&stgm, 0, sizeof(stgm)); + stgm.tymed = TYMED_HGLOBAL; + + // Ask the object for the data... + if (SUCCEEDED(hr = pdo->QueryGetData(&ftc)) && + SUCCEEDED(hr = pdo->GetData(&ftc, &stgm))) + { + ULONG ulSize; + if ((stgm.tymed == TYMED_HGLOBAL) && (stgm.hGlobal) && + (ulSize = GlobalSize(stgm.hGlobal))) + { + LPVOID lpv = GlobalLock(stgm.hGlobal); + if (lpv) + { + // We will return data as safearray vector of VB6 Byte type... + psa = SafeArrayCreateVector(VT_UI1, 1, ulSize); + if (psa) + { + pvtOutput->vt = VT_ARRAY|VT_UI1; + pvtOutput->parray = psa; + prawdata = NULL; + + if (SUCCEEDED(SafeArrayAccessData(psa, &prawdata))) + { + memcpy(prawdata, lpv, ulSize); + SafeArrayUnaccessData(psa); + } + } + else hr = E_OUTOFMEMORY; + + GlobalUnlock(stgm.hGlobal); + } + else hr = E_ACCESSDENIED; + } + else hr = E_FAIL; + + ReleaseStgMedium(&stgm); + } + + pdo->Release(); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// +// CDsoDocObject::HrSetDataInObject +// +// Function to take format type and either string or VB6-safe byte array +// as data and set it into the current object (that is, it will replace the +// current document content with this content). The fMbcsString flag determines +// if BSTR passed should be converted to MBCS format before being set. For example, +// if you previously got data as RTF (MBCS), then converted to Unicode BSTR and +// passed it back, it would need to be converted back to MBCS for the set to work. +// If the string data is binary, pass FALSE. If data is array, the param is ignored. +// +// The function sets the data using IDataObject::SetData. Note that some objects +// will allow you to get a format but not set it, so this may not work for a previously +// acquired data type. It is up to the host DocObject server, so test carefully before +// depending on this functionality. +// +STDMETHODIMP CDsoDocObject::HrSetDataInObject(VARIANT *pvtType, VARIANT *pvtInput, BOOL fMbcsString) +{ + HRESULT hr; + IDataObject *pdo = NULL; + LPWSTR pwszTypeName; + LPSTR pszFormatName; + SAFEARRAY* psa; + VOID HUGEP* prawdata; + FORMATETC ftc; + STGMEDIUM stgm; + LONG cfType; + ULONG ulSize; + BOOL fIsArrayData = FALSE; + BOOL fCleanupString = FALSE; + + if ((pvtType == NULL) || PARAM_IS_MISSING(pvtType) || + (pvtInput == NULL) || PARAM_IS_MISSING(pvtInput)) + return E_INVALIDARG; + + // Find the clipboard format for the given data type... + pwszTypeName = LPWSTR_FROM_VARIANT(*pvtType); + if ((pwszTypeName) && (pszFormatName = DsoConvertToMBCS(pwszTypeName))) + { + cfType = RegisterClipboardFormat(pszFormatName); + DsoMemFree(pszFormatName); + } + else cfType = LONG_FROM_VARIANT(*pvtType, 0); + CHECK_NULL_RETURN(cfType, E_INVALIDARG); + + // Depending on the type of data passed, and if we need to do any Unicode-to-MBCS + // conversion for the caller, set up the data size and data pointer we will use + // to create the global memory object we'll pass to the doc object server... + prawdata = LPWSTR_FROM_VARIANT(*pvtInput); + if (prawdata) + { + if (fMbcsString) + { + prawdata = (void*)DsoConvertToMBCS((BSTR)prawdata); + CHECK_NULL_RETURN(prawdata, E_OUTOFMEMORY); + fCleanupString = TRUE; + ulSize = lstrlen((LPSTR)prawdata); + } + else + ulSize = SysStringByteLen((BSTR)prawdata); + } + else + { + psa = PSARRAY_FROM_VARIANT(*pvtInput); + if (psa) + { + LONG lb, ub, elSize; + + if ((SafeArrayGetDim(psa) > 1) || + FAILED(SafeArrayGetLBound(psa, 1, &lb)) || (lb < 0) || + FAILED(SafeArrayGetUBound(psa, 1, &ub)) || (ub < lb) || + ((elSize = SafeArrayGetElemsize(psa)) < 1)) + return E_INVALIDARG; + + ulSize = (((ub + 1) - lb) * elSize); + fIsArrayData = TRUE; + if (FAILED(SafeArrayAccessData(psa, &prawdata))) + return E_ACCESSDENIED; + } + + CHECK_NULL_RETURN(prawdata, E_INVALIDARG); + } + + // We must have a server and it must support IDataObject... + if ((m_pole) && SUCCEEDED(m_pole->QueryInterface(IID_IDataObject, (void**)&pdo)) && (pdo)) + { + memset(&ftc, 0, sizeof(ftc)); + ftc.cfFormat = (WORD)cfType; + ftc.dwAspect = DVASPECT_CONTENT; + ftc.lindex = -1; ftc.tymed = TYMED_HGLOBAL; + + memset(&stgm, 0, sizeof(stgm)); + stgm.tymed = TYMED_HGLOBAL; + stgm.hGlobal = GlobalAlloc(GPTR, ulSize); + if (stgm.hGlobal) + { + LPVOID lpv = GlobalLock(stgm.hGlobal); + if ((lpv) && (ulSize)) + { + // Copy the data into transfer object... + memcpy(lpv, prawdata, ulSize); + GlobalUnlock(stgm.hGlobal); + + // Do the actual SetData call to transfer the data... + hr = pdo->SetData(&ftc, &stgm, TRUE); + } + else hr = E_UNEXPECTED; + + if (FAILED(hr)) + ReleaseStgMedium(&stgm); + } + else hr = E_OUTOFMEMORY; + + pdo->Release(); + } + else hr = OLE_E_CANT_GETMONIKER; + + if (fIsArrayData) + SafeArrayUnaccessData(psa); + + if (fCleanupString) + DsoMemFree(prawdata); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::FrameWindowProc +// +// Site window procedure. Not much to do here except forward focus. +// +STDMETHODIMP_(LRESULT) CDsoDocObject::FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CDsoDocObject* pbndr = (CDsoDocObject*)GetWindowLong(hwnd, GWL_USERDATA); + if (pbndr) + { + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + RECT rc; GetClientRect(hwnd, &rc); + BeginPaint(hwnd, &ps); + pbndr->OnDraw(DVASPECT_CONTENT, ps.hdc, (RECT*)&rc, NULL, NULL, TRUE); + EndPaint(hwnd, &ps); + } + return 0; + + case WM_NCDESTROY: + SetWindowLong(hwnd, GWL_USERDATA, 0); + pbndr->m_hwnd = NULL; + break; + + case WM_SETFOCUS: + if (pbndr->m_hwndUIActiveObj) + SetFocus(pbndr->m_hwndUIActiveObj); + return 0; + + case WM_SYSCOMMAND: + if ((wParam & 0xFFF0) == SC_KEYMENU) + { + if ((pbndr->m_psiteCtl) && (pbndr->m_psiteCtl->SysMenuCommand((UINT)lParam) == S_OK)) + return 0; + } + break; + + case WM_ERASEBKGND: + return 1; + } + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + + diff --git a/PROMS/DSOFRAMER/Source2005/dsofdocobj.h b/PROMS/DSOFRAMER/Source2005/dsofdocobj.h new file mode 100644 index 00000000..504ddf05 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsofdocobj.h @@ -0,0 +1,350 @@ +/*************************************************************************** + * DSOFDOCOBJ.H + * + * DSOFramer: OLE DocObject Site component (used by the control) + * + * Copyright ©1999-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. + * + ***************************************************************************/ +#ifndef DS_DSOFDOCOBJ_H +#define DS_DSOFDOCOBJ_H + +//////////////////////////////////////////////////////////////////// +// Declarations for Interfaces used in DocObject Containment +// +#include // Standard DocObjects (common to all AxDocs) +#include "ipprevw.h" // PrintPreview (for select Office apps) +#include "rbbinder.h" // Internet Publishing (for Web Folder write access) + +//////////////////////////////////////////////////////////////////////// +// Microsoft Office 97-2003 Document Object GUIDs +// +DEFINE_GUID(CLSID_WORD_DOCUMENT_DOC, 0x00020906, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_EXCEL_WORKBOOK_XLS, 0x00020820, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_EXCEL_CHART_XLS, 0x00020821, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_PPT_PRESENTATION_PPT, 0x64818D10, 0x4F9B, 0x11CF, 0x86, 0xEA, 0x00, 0xAA, 0x00, 0xB9, 0x29, 0xE8); +DEFINE_GUID(CLSID_VISIO_DRAWING_VSD, 0x00021A13, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_PROJECT_DOCUMENT_MPP, 0x74B78F3A, 0xC8C8, 0x11D1, 0xBE, 0x11, 0x00, 0xC0, 0x4F, 0xB6, 0xFA, 0xF1); +DEFINE_GUID(CLSID_MSHTML_DOCUMENT, 0x25336920, 0x03F9, 0x11CF, 0x8F, 0xD0, 0x00, 0xAA, 0x00, 0x68, 0x6F, 0x13); + +//////////////////////////////////////////////////////////////////////// +// Microsoft Office 2007 Document GUIDs +// +DEFINE_GUID(CLSID_WORD_DOCUMENT_DOCX, 0xF4754C9B, 0x64F5, 0x4B40, 0x8A, 0xF4, 0x67, 0x97, 0x32, 0xAC, 0x06, 0x07); +DEFINE_GUID(CLSID_WORD_DOCUMENT_DOCM, 0x18A06B6B, 0x2F3F, 0x4E2B, 0xA6, 0x11, 0x52, 0xBE, 0x63, 0x1B, 0x2D, 0x22); +DEFINE_GUID(CLSID_EXCEL_WORKBOOK_XLSX, 0x00020830, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_EXCEL_WORKBOOK_XLSM, 0x00020832, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_EXCEL_WORKBOOK_XLSB, 0x00020833, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +DEFINE_GUID(CLSID_PPT_PRESENTATION_PPTX, 0xCF4F55F4, 0x8F87, 0x4D47, 0x80, 0xBB, 0x58, 0x08, 0x16, 0x4B, 0xB3, 0xF8); +DEFINE_GUID(CLSID_PPT_PRESENTATION_PPTM, 0xDC020317, 0xE6E2, 0x4A62, 0xB9, 0xFA, 0xB3, 0xEF, 0xE1, 0x66, 0x26, 0xF4); + +//////////////////////////////////////////////////////////////////// +// IDsoDocObjectSite -- {444CA1F7-B405-4002-95C3-A455BC9F4F55} +// +// Implemented by control host for callbacks. Required interface. +// +interface IDsoDocObjectSite : public IServiceProvider +{ + STDMETHOD(GetWindow)(HWND* phWnd) PURE; + STDMETHOD(GetBorder)(LPRECT prcBorder) PURE; + STDMETHOD(SetStatusText)(LPCOLESTR pszText) PURE; + STDMETHOD(GetHostName)(LPWSTR *ppwszHostName) PURE; + STDMETHOD(SysMenuCommand)(UINT uiCharCode) PURE; +}; +DEFINE_GUID(IID_IDsoDocObjectSite, 0x444CA1F7, 0xB405, 0x4002, 0x95, 0xC3, 0xA4, 0x55, 0xBC, 0x9F, 0x4F, 0x55); + + +//////////////////////////////////////////////////////////////////// +// CDsoDocObject -- ActiveDocument Container Site Object +// +// The CDsoDocObject object handles all the DocObject embedding for the +// control and os fairly self-contained. Like the control it has its +// own window, but it merely acts as a parent for the embedded object +// window(s) which it activates. +// +// CDsoDocObject works by taking a file (or automation object) and +// copying out the OLE storage used for its persistent data. It then +// creates a new embedding based on the data. If a storage is not +// avaiable, it will attempt to oad the file directly, but the results +// are less predictable using this manner since DocObjects are embeddings +// and not links and this component has limited support for links. As a +// result, we will attempt to keep our own storage copy in most cases. +// +// You should note that this approach is different than one taken by the +// web browser control, which is basically a link container which will +// try to embed (ip activate) if allowed, but if not it opens the file +// externally and keeps the link. If CDsoDocObject cannot embed the object, +// it returns an error. It will not open the object external. +// +// Like the control, this object also uses nested classes for the OLE +// interfaces used in the embedding. They are easier to track and easier +// to debug if a specific interface is over/under released. Again this was +// a design decision to make the sample easier to break apart, but not required. +// +// Because the object is not tied to the top-level window, it constructs +// the OLE merged menu as a set of popup menus which the control then displays +// in whatever form it wants. You would need to customize this if you used +// the control in a host and wanted the menus to merge with the actual host +// menu bar (on the top-level window or form). +// +class CDsoDocObject : public IUnknown +{ +public: + CDsoDocObject(); + ~CDsoDocObject(); + + // Static Create Method (Host Provides Site Interface) + static STDMETHODIMP_(CDsoDocObject*) CreateInstance(IDsoDocObjectSite* phost); + + // IUnknown Implementation + STDMETHODIMP QueryInterface(REFIID riid, void** ppv); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // IOleClientSite Implementation + BEGIN_INTERFACE_PART(OleClientSite, IOleClientSite) + STDMETHODIMP SaveObject(void); + STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk); + STDMETHODIMP GetContainer(IOleContainer** ppContainer); + STDMETHODIMP ShowObject(void); + STDMETHODIMP OnShowWindow(BOOL fShow); + STDMETHODIMP RequestNewObjectLayout(void); + END_INTERFACE_PART(OleClientSite) + + // IOleInPlaceSite Implementation + BEGIN_INTERFACE_PART(OleInPlaceSite, IOleInPlaceSite) + STDMETHODIMP GetWindow(HWND* phwnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + STDMETHODIMP CanInPlaceActivate(void); + STDMETHODIMP OnInPlaceActivate(void); + STDMETHODIMP OnUIActivate(void); + STDMETHODIMP GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo); + STDMETHODIMP Scroll(SIZE sz); + STDMETHODIMP OnUIDeactivate(BOOL fUndoable); + STDMETHODIMP OnInPlaceDeactivate(void); + STDMETHODIMP DiscardUndoState(void); + STDMETHODIMP DeactivateAndUndo(void); + STDMETHODIMP OnPosRectChange(LPCRECT lprcPosRect); + END_INTERFACE_PART(OleInPlaceSite) + + // IOleDocumentSite Implementation + BEGIN_INTERFACE_PART(OleDocumentSite, IOleDocumentSite) + STDMETHODIMP ActivateMe(IOleDocumentView* pView); + END_INTERFACE_PART(OleDocumentSite) + + // IOleInPlaceFrame Implementation + BEGIN_INTERFACE_PART(OleInPlaceFrame, IOleInPlaceFrame) + STDMETHODIMP GetWindow(HWND* phWnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + STDMETHODIMP GetBorder(LPRECT prcBorder); + STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS pBW); + STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS pBW); + STDMETHODIMP SetActiveObject(LPOLEINPLACEACTIVEOBJECT pIIPActiveObj, LPCOLESTR pszObj); + STDMETHODIMP InsertMenus(HMENU hMenu, LPOLEMENUGROUPWIDTHS pMGW); + STDMETHODIMP SetMenu(HMENU hMenu, HOLEMENU hOLEMenu, HWND hWndObj); + STDMETHODIMP RemoveMenus(HMENU hMenu); + STDMETHODIMP SetStatusText(LPCOLESTR pszText); + STDMETHODIMP EnableModeless(BOOL fEnable); + STDMETHODIMP TranslateAccelerator(LPMSG pMSG, WORD wID); + END_INTERFACE_PART(OleInPlaceFrame) + + // IOleCommandTarget Implementation + BEGIN_INTERFACE_PART(OleCommandTarget , IOleCommandTarget) + STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText); + STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut); + END_INTERFACE_PART(OleCommandTarget) + + // IServiceProvider Implementation + BEGIN_INTERFACE_PART(ServiceProvider , IServiceProvider) + STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv); + END_INTERFACE_PART(ServiceProvider) + + // IAuthenticate Implementation + BEGIN_INTERFACE_PART(Authenticate , IAuthenticate) + STDMETHODIMP Authenticate(HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword); + END_INTERFACE_PART(Authenticate) + + // IContinueCallback Implementation + BEGIN_INTERFACE_PART(ContinueCallback , IContinueCallback) + STDMETHODIMP FContinue(void); + STDMETHODIMP FContinuePrinting(LONG cPagesPrinted, LONG nCurrentPage, LPOLESTR pwszPrintStatus); + END_INTERFACE_PART(ContinueCallback) + + // IOlePreviewCallback Implementation + BEGIN_INTERFACE_PART(PreviewCallback , IOlePreviewCallback) + STDMETHODIMP Notify(DWORD wStatus, LONG nLastPage, LPOLESTR pwszPreviewStatus); + END_INTERFACE_PART(PreviewCallback) + + // DocObject Class Methods IDsoDocObjectSite + STDMETHODIMP InitializeNewInstance(IDsoDocObjectSite* phost); + STDMETHODIMP CreateDocObject(REFCLSID rclsid); + STDMETHODIMP CreateDocObject(IStorage *pstg); + STDMETHODIMP CreateFromFile(LPWSTR pwszFile, REFCLSID rclsid, LPBIND_OPTS pbndopts); + STDMETHODIMP CreateFromURL(LPWSTR pwszUrlFile, REFCLSID rclsid, LPBIND_OPTS pbndopts, LPWSTR pwszUserName, LPWSTR pwszPassword); + STDMETHODIMP CreateFromRunningObject(LPUNKNOWN punkObj, LPWSTR pwszObjectName, LPBIND_OPTS pbndopts); + STDMETHODIMP IPActivateView(); + STDMETHODIMP IPDeactivateView(); + STDMETHODIMP UIActivateView(); + STDMETHODIMP UIDeactivateView(); + STDMETHODIMP_(BOOL) IsDirty(); + STDMETHODIMP Save(); + STDMETHODIMP SaveToFile(LPWSTR pwszFile, BOOL fOverwriteFile); + STDMETHODIMP SaveToURL(LPWSTR pwszURL, BOOL fOverwriteFile, LPWSTR pwszUserName, LPWSTR pwszPassword); + STDMETHODIMP PrintDocument(LPCWSTR pwszPrinter, LPCWSTR pwszOutput, UINT cCopies, UINT nFrom, UINT nTo, BOOL fPromptUser); + STDMETHODIMP StartPrintPreview(); + STDMETHODIMP ExitPrintPreview(BOOL fForceExit); + STDMETHODIMP DoOleCommand(DWORD dwOleCmdId, DWORD dwOptions, VARIANT* vInParam, VARIANT* vInOutParam); + STDMETHODIMP Close(); + + // Control should notify us on these conditions (so we can pass to IP object)... + STDMETHODIMP_(void) OnNotifySizeChange(LPRECT prc); + STDMETHODIMP_(void) OnNotifyAppActivate(BOOL fActive, DWORD dwThreadID); + STDMETHODIMP_(void) OnNotifyPaletteChanged(HWND hwndPalChg); + STDMETHODIMP_(void) OnNotifyChangeToolState(BOOL fShowTools); + STDMETHODIMP_(void) OnNotifyControlFocus(BOOL fGotFocus); + + STDMETHODIMP HrGetDataFromObject(VARIANT *pvtType, VARIANT *pvtOutput); + STDMETHODIMP HrSetDataInObject(VARIANT *pvtType, VARIANT *pvtInput, BOOL fMbcsString); + + STDMETHODIMP_(BOOL) GetDocumentTypeAndFileExtension(WCHAR** ppwszFileType, WCHAR** ppwszFileExt); + + // Inline accessors for control to get IP object info... + inline IOleInPlaceActiveObject* GetActiveObject(){return m_pipactive;} + inline IOleObject* GetOleObject(){return m_pole;} + inline HWND GetDocWindow(){return m_hwnd;} + inline HWND GetActiveWindow(){return m_hwndUIActiveObj;} + inline BOOL IsReadOnly(){return m_fOpenReadOnly;} + inline BOOL InPrintPreview(){return ((m_pprtprv != NULL) || (m_fInPptSlideShow));} + inline HWND GetMenuHWND(){return m_hwndMenuObj;} + inline HMENU GetActiveMenu(){return m_hMenuActive;} + inline HMENU GetMergedMenu(){return m_hMenuMerged;} + inline void SetMergedMenu(HMENU h){m_hMenuMerged = h;} + inline LPCWSTR GetSourceName(){return ((m_pwszWebResource) ? m_pwszWebResource : m_pwszSourceFile);} + inline LPCWSTR GetSourceDocName(){return ((m_pwszSourceFile) ? &m_pwszSourceFile[m_idxSourceName] : NULL);} + inline CLSID* GetServerCLSID(){return &m_clsidObject;} + inline BOOL IsIPActive(){return (m_pipobj != NULL);} + + BOOL IsWordObject() + {return ((m_clsidObject == CLSID_WORD_DOCUMENT_DOC) || + (m_clsidObject == CLSID_WORD_DOCUMENT_DOCX) || + (m_clsidObject == CLSID_WORD_DOCUMENT_DOCM)); + } + BOOL IsExcelObject() + {return ((m_clsidObject == CLSID_EXCEL_WORKBOOK_XLS) || + (m_clsidObject == CLSID_EXCEL_WORKBOOK_XLSX) || + (m_clsidObject == CLSID_EXCEL_WORKBOOK_XLSM) || + (m_clsidObject == CLSID_EXCEL_WORKBOOK_XLSB) || + (m_clsidObject == CLSID_EXCEL_CHART_XLS)); + } + BOOL IsPPTObject() + {return ((m_clsidObject == CLSID_PPT_PRESENTATION_PPT) || + (m_clsidObject == CLSID_PPT_PRESENTATION_PPTX) || + (m_clsidObject == CLSID_PPT_PRESENTATION_PPTM)); + } + BOOL IsVisioObject() + {return (m_clsidObject == CLSID_VISIO_DRAWING_VSD);} + + STDMETHODIMP SetRunningServerLock(BOOL fLock); + +protected: + // Internal helper methods... + STDMETHODIMP InstantiateDocObjectServer(REFCLSID rclsid, IOleObject **ppole); + STDMETHODIMP CreateObjectStorage(REFCLSID rclsid); + STDMETHODIMP SaveObjectStorage(); + STDMETHODIMP SaveDocToMoniker(IMoniker *pmk, IBindCtx *pbc, BOOL fKeepLock); + STDMETHODIMP SaveDocToFile(LPWSTR pwszFullName, BOOL fKeepLock); + STDMETHODIMP ValidateDocObjectServer(REFCLSID rclsid); + STDMETHODIMP_(BOOL) ValidateFileExtension(WCHAR* pwszFile, WCHAR** ppwszOut); + + STDMETHODIMP_(void) OnDraw(DWORD dvAspect, HDC hdcDraw, LPRECT prcBounds, LPRECT prcWBounds, HDC hicTargetDev, BOOL fOptimize); + + STDMETHODIMP EnsureOleServerRunning(BOOL fLockRunning); + STDMETHODIMP_(void) FreeRunningLock(); + STDMETHODIMP_(void) TurnOffWebToolbar(BOOL fTurnedOff); + STDMETHODIMP_(void) ClearMergedMenu(); + STDMETHODIMP_(DWORD) CalcDocNameIndex(LPCWSTR pwszPath); + STDMETHODIMP_(void) CheckForPPTPreviewChange(); + + // These functions allow the component to access files in a Web Folder for + // write access using the Microsoft Provider for Internet Publishing (MSDAIPP), + // which is installed by Office and comes standard in Windows 2000/ME/XP/2003. The + // provider is not required to use the component, only if you wish to save to + // an FPSE or DAV Web Folder (URL). + STDMETHODIMP_(IUnknown*) CreateIPPBindResource(); + STDMETHODIMP IPPDownloadWebResource(LPWSTR pwszURL, LPWSTR pwszFile, IStream** ppstmKeepForSave); + STDMETHODIMP IPPUploadWebResource(LPWSTR pwszFile, IStream** ppstmSave, LPWSTR pwszURLSaveTo, BOOL fOverwriteFile); + + static STDMETHODIMP_(LRESULT) FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + // The private class variables... +private: + ULONG m_cRef; // Reference count + HWND m_hwnd; // our window + HWND m_hwndCtl; // The control's window + RECT m_rcViewRect; // Viewable area (set by host) + IDsoDocObjectSite *m_psiteCtl; // The control's site interface + IOleCommandTarget *m_pcmdCtl; // IOCT of host (for frame msgs) + + LPWSTR m_pwszHostName; // Ole Host Name for container + LPWSTR m_pwszSourceFile; // Path to Source File (on Open) + IMoniker *m_pmkSourceFile; // Moniker to original source file + IBindCtx *m_pbctxSourceFile; // Bind context used to original source file + IStorage *m_pstgSourceFile; // Original File Storage (if open/save file) + DWORD m_idxSourceName; // Index to doc name in m_pwszSourceFile + + CLSID m_clsidObject; // CLSID of the embedded object + IStorage *m_pstgroot; // Root temp storage + IStorage *m_pstgfile; // In-memory file storage + IStream *m_pstmview; // In-memory view info stream + + LPWSTR m_pwszWebResource; // The full URL to the web resource + IStream *m_pstmWebResource; // Original Download Stream (if open/save URL) + IUnknown *m_punkIPPResource; // MSDAIPP provider resource (for URL authoring) + LPWSTR m_pwszUsername; // Username and password used by MSDAIPP + LPWSTR m_pwszPassword; // for Authentication (see IAuthenticate) + + IOleObject *m_pole; // Embedded OLE Object (OLE) + IOleInPlaceObject *m_pipobj; // The IP object methods (OLE) + IOleInPlaceActiveObject *m_pipactive; // The UI Active object methods (OLE) + IOleDocumentView *m_pdocv; // MSO Document View (DocObj) + IOleCommandTarget *m_pcmdt; // MSO Command Target (DocObj) + IOleInplacePrintPreview *m_pprtprv; // MSO Print Preview (DocObj) + + HMENU m_hMenuActive; // The menu supplied by embedded object + HMENU m_hMenuMerged; // The merged menu (set by control host) + HOLEMENU m_holeMenu; // The OLE Menu Descriptor + HWND m_hwndMenuObj; // The window for menu commands + HWND m_hwndIPObject; // IP active object window + HWND m_hwndUIActiveObj; // UI Active object window + DWORD m_dwObjectThreadID; // Thread Id of UI server + BORDERWIDTHS m_bwToolSpace; // Toolspace... + + // Bitflags (state info)... + unsigned int m_fDisplayTools:1; + unsigned int m_fDisconnectOnQuit:1; + unsigned int m_fAppWindowActive:1; + unsigned int m_fOpenReadOnly:1; + unsigned int m_fObjectInModalCondition:1; + unsigned int m_fObjectIPActive:1; + unsigned int m_fObjectUIActive:1; + unsigned int m_fObjectActivateComplete:1; + unsigned int m_fLockedServerRunning:1; + unsigned int m_fLoadedFromAuto:1; + unsigned int m_fInClose:1; + unsigned int m_fAttemptPptPreview:1; + unsigned int m_fInPptSlideShow:1; + +}; + + +#endif //DS_DSOFDOCOBJ_H \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/dsofprint.cpp b/PROMS/DSOFRAMER/Source2005/dsofprint.cpp new file mode 100644 index 00000000..280cefa2 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsofprint.cpp @@ -0,0 +1,419 @@ +/*************************************************************************** + * DSOFPRINT.CPP + * + * CDsoDocObject: Print Code for CDsoDocObject object + * + * Copyright ©1999-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" + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::_PrintOutOld +// +// Prints the current object by calling IOleCommandTarget for Print. +// +STDMETHODIMP CDsoFramerControl::_PrintOutOld(VARIANT PromptToSelectPrinter) +{ + DWORD dwOption = BOOL_FROM_VARIANT(PromptToSelectPrinter, FALSE) + ? OLECMDEXECOPT_PROMPTUSER : OLECMDEXECOPT_DODEFAULT; + + TRACE1("CDsoFramerControl::_PrintOutOld(%d)\n", dwOption); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // Cannot access object if in modal condition... + if ((m_fModalState) || (m_pDocObjFrame->InPrintPreview())) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + return m_pDocObjFrame->DoOleCommand(OLECMDID_PRINT, dwOption, NULL, NULL); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::PrintOut +// +// Prints document using either IPrint or IOleCommandTarget, depending +// on parameters passed. This offers a bit more control over printing if +// the doc object server supports IPrint interface. +// +STDMETHODIMP CDsoFramerControl::PrintOut(VARIANT PromptUser, VARIANT PrinterName, + VARIANT Copies, VARIANT FromPage, VARIANT ToPage, VARIANT OutputFile) +{ + HRESULT hr; + BOOL fPromptUser = BOOL_FROM_VARIANT(PromptUser, FALSE); + LPWSTR pwszPrinter = LPWSTR_FROM_VARIANT(PrinterName); + LPWSTR pwszOutput = LPWSTR_FROM_VARIANT(OutputFile); + LONG lCopies = LONG_FROM_VARIANT(Copies, 1); + LONG lFrom = LONG_FROM_VARIANT(FromPage, 0); + LONG lTo = LONG_FROM_VARIANT(ToPage, 0); + + TRACE3("CDsoFramerControl::PrintOut(%d, %S, %d)\n", fPromptUser, pwszPrinter, lCopies); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // First we do validation of all parameters passed to the function... + if ((pwszPrinter) && (*pwszPrinter == L'\0')) + return E_INVALIDARG; + + if ((pwszOutput) && (*pwszOutput == L'\0')) + return E_INVALIDARG; + + if ((lCopies < 1) || (lCopies > 200)) + return E_INVALIDARG; + + if (((lFrom != 0) || (lTo != 0)) && ((lFrom < 1) || (lTo < lFrom))) + return E_INVALIDARG; + + // Cannot access object if in modal condition... + if ((m_fModalState) || (m_pDocObjFrame->InPrintPreview())) + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // If no printer name was provided, we can print to the default device + // using IOleCommandTarget with OLECMDID_PRINT... + if (pwszPrinter == NULL) + return _PrintOutOld(PromptUser); + + // Ask the embedded document to print itself to specific printer... + hr = m_pDocObjFrame->PrintDocument(pwszPrinter, pwszOutput, (UINT)lCopies, + (UINT)lFrom, (UINT)lTo, fPromptUser); + + // If call failed because interface doesn't exist, change error + // to let caller know it is because DocObj doesn't support this command... + if (FAILED(hr) && (hr == E_NOINTERFACE)) + hr = DSO_E_COMMANDNOTSUPPORTED; + + return ProvideErrorInfo(hr); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::PrintPreview +// +// Asks embedded object to attempt a print preview (only Office docs do this). +// +STDMETHODIMP CDsoFramerControl::PrintPreview() +{ + HRESULT hr; + ODS("CDsoFramerControl::PrintPreview\n"); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + if (m_fModalState) // Cannot access object if in modal condition... + return ProvideErrorInfo(DSO_E_INMODALSTATE); + + // Try to set object into print preview mode... + hr = m_pDocObjFrame->StartPrintPreview(); + + // If call failed because interface doesn't exist, change error + // to let caller know it is because DocObj doesn't support this command... + if (FAILED(hr) && (hr == E_NOINTERFACE)) + hr = DSO_E_COMMANDNOTSUPPORTED; + + return ProvideErrorInfo(hr); +} + +//////////////////////////////////////////////////////////////////////// +// CDsoFramerControl::PrintPreviewExit +// +// Closes an active preview. +// +STDMETHODIMP CDsoFramerControl::PrintPreviewExit() +{ + ODS("CDsoFramerControl::PrintPreviewExit\n"); + CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN)); + + // Try to set object out of print preview mode... + if (m_pDocObjFrame->InPrintPreview()) + m_pDocObjFrame->ExitPrintPreview(TRUE); + + return S_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::PrintDocument +// +// We can use the IPrint interface for an ActiveX Document object to +// selectively print object to a given printer. +// +STDMETHODIMP CDsoDocObject::PrintDocument(LPCWSTR pwszPrinter, LPCWSTR pwszOutput, UINT cCopies, UINT nFrom, UINT nTo, BOOL fPromptUser) +{ + HRESULT hr; + IPrint *print; + HANDLE hPrint; + DVTARGETDEVICE* ptd = NULL; + + ODS("CDsoDocObject::PrintDocument\n"); + CHECK_NULL_RETURN(m_pole, E_UNEXPECTED); + + // First thing we need to do is ask object for IPrint. If it does not + // support it, we cannot continue. It is up to DocObj if this is allowed... + hr = m_pole->QueryInterface(IID_IPrint, (void**)&print); + RETURN_ON_FAILURE(hr); + + // Now setup printer settings into DEVMODE for IPrint. Open printer + // settings and gather default DEVMODE... + if (FOpenPrinter(pwszPrinter, &hPrint)) + { + LPDEVMODEW pdevMode = NULL; + LPWSTR pwszDefProcessor = NULL; + LPWSTR pwszDefDriver = NULL; + LPWSTR pwszDefPort = NULL; + LPWSTR pwszPort; + DWORD cbDevModeSize; + + if (FGetPrinterSettings(hPrint, &pwszDefProcessor, + &pwszDefDriver, &pwszDefPort, &pdevMode, &cbDevModeSize) && (pdevMode)) + { + DWORD cbPrintName, cbDeviceName, cbOutputName; + DWORD cbDVTargetSize; + + pdevMode->dmFields |= DM_COPIES; + pdevMode->dmCopies = (WORD)((cCopies) ? cCopies : 1); + + pwszPort = ((pwszOutput) ? (LPWSTR)pwszOutput : pwszDefPort); + + // We calculate the size we will need for the TARGETDEVICE structure... + cbPrintName = ((lstrlenW(pwszDefProcessor) + 1) * sizeof(WCHAR)); + cbDeviceName = ((lstrlenW(pwszDefDriver) + 1) * sizeof(WCHAR)); + cbOutputName = ((lstrlenW(pwszPort) + 1) * sizeof(WCHAR)); + + cbDVTargetSize = sizeof(DWORD) + sizeof(DEVNAMES) + cbPrintName + + cbDeviceName + cbOutputName + cbDevModeSize; + + // Allocate new target device using COM Task Allocator... + ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(cbDVTargetSize); + if (ptd) + { + // Copy all the data in the DVT... + DWORD dwOffset = sizeof(DWORD) + sizeof(DEVNAMES); + ptd->tdSize = cbDVTargetSize; + + ptd->tdDriverNameOffset = (WORD)dwOffset; + memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszDefProcessor, cbPrintName); + dwOffset += cbPrintName; + + ptd->tdDeviceNameOffset = (WORD)dwOffset; + memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszDefDriver, cbDeviceName); + dwOffset += cbDeviceName; + + ptd->tdPortNameOffset = (WORD)dwOffset; + memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszPort, cbOutputName); + dwOffset += cbOutputName; + + ptd->tdExtDevmodeOffset = (WORD)dwOffset; + memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pdevMode, cbDevModeSize); + dwOffset += cbDevModeSize; + + ASSERT(dwOffset == cbDVTargetSize); + } + else hr = E_OUTOFMEMORY; + + // We're done with the devmode... + DsoMemFree(pdevMode); + } + else hr = E_WIN32_LASTERROR; + + SAFE_FREESTRING(pwszDefPort); + SAFE_FREESTRING(pwszDefDriver); + SAFE_FREESTRING(pwszDefProcessor); + ClosePrinter(hPrint); + } + else hr = E_WIN32_LASTERROR; + + // If we were successful in getting TARGETDEVICE struct, provide the page range + // for the print job and ask docobj server to print it... + if (SUCCEEDED(hr)) + { + PAGESET *ppgset; + DWORD cbPgRngSize = sizeof(PAGESET) + sizeof(PAGERANGE); + LONG cPages, cLastPage; + DWORD grfPrintFlags; + + // Setup the page range to print... + if ((ppgset = (PAGESET*)CoTaskMemAlloc(cbPgRngSize)) != NULL) + { + ppgset->cbStruct = cbPgRngSize; + ppgset->cPageRange = 1; + ppgset->fOddPages = TRUE; + ppgset->fEvenPages = TRUE; + ppgset->cPageRange = 1; + ppgset->rgPages[0].nFromPage = ((nFrom) ? nFrom : 1); + ppgset->rgPages[0].nToPage = ((nTo) ? nTo : PAGESET_TOLASTPAGE); + + // Give indication we are waiting (on the print)... + HCURSOR hCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); + + SEH_TRY + + // Setup the initial page number (optional)... + print->SetInitialPageNum(ppgset->rgPages[0].nFromPage); + + grfPrintFlags = (PRINTFLAG_MAYBOTHERUSER | PRINTFLAG_RECOMPOSETODEVICE); + if (fPromptUser) grfPrintFlags |= PRINTFLAG_PROMPTUSER; + if (pwszOutput) grfPrintFlags |= PRINTFLAG_PRINTTOFILE; + + // Now ask server to print it using settings passed... + hr = print->Print(grfPrintFlags, &ptd, &ppgset, NULL, (IContinueCallback*)&m_xContinueCallback, + ppgset->rgPages[0].nFromPage, &cPages, &cLastPage); + + SEH_EXCEPT(hr) + + SetCursor(hCur); + + if (ppgset) + CoTaskMemFree(ppgset); + } + else hr = E_OUTOFMEMORY; + } + + // We are done... + if (ptd) CoTaskMemFree(ptd); + print->Release(); + return hr; +} + + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::StartPrintPreview +// +// Ask embedded object to go into print preview (if supportted). +// +STDMETHODIMP CDsoDocObject::StartPrintPreview() +{ + HRESULT hr; + IOleInplacePrintPreview *prev; + HCURSOR hCur; + + ODS("CDsoDocObject::StartPrintPreview\n"); + CHECK_NULL_RETURN(m_pole, E_UNEXPECTED); + + // No need to do anything if already in preview... + if (InPrintPreview()) return S_FALSE; + + // Otherwise, ask document server if it supports preview... + hr = m_pole->QueryInterface(IID_IOleInplacePrintPreview, (void**)&prev); + if (SUCCEEDED(hr)) + { + // Tell user we waiting (switch to preview can be slow for very large docs)... + hCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); + + // If it does, make sure it can go into preview mode... + hr = prev->QueryStatus(); + if (SUCCEEDED(hr)) + { + SEH_TRY + + if (m_hwndCtl) // Notify the control that preview started... + SendMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)FALSE); + + // We will allow application to bother user and switch printers... + hr = prev->StartPrintPreview( + (PREVIEWFLAG_MAYBOTHERUSER | PREVIEWFLAG_PROMPTUSER | PREVIEWFLAG_USERMAYCHANGEPRINTER), + NULL, (IOlePreviewCallback*)&m_xPreviewCallback, 1); + + SEH_EXCEPT(hr) + + // If the call succeeds, we keep hold of interface to close preview later + if (SUCCEEDED(hr)) + { + SAFE_SET_INTERFACE(m_pprtprv, prev); + } + else + { // Otherwise, notify the control that preview failed... + if (m_hwndCtl) + PostMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)TRUE); + } + } + + SetCursor(hCur); + prev->Release(); + } + else if (IsPPTObject() && (m_hwndUIActiveObj)) + { + // PowerPoint doesn't have print preview, but it does have slide show mode, so we can use this to + // toggle the viewing into slideshow... + if (PostMessage(m_hwndUIActiveObj, WM_KEYDOWN, VK_F5, 0x00000001) && + PostMessage(m_hwndUIActiveObj, WM_KEYUP, VK_F5, 0xC0000001)) + { + hr = S_OK; m_fAttemptPptPreview = TRUE; + } + } + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::ExitPrintPreview +// +// Drop out of print preview and restore items as needed. +// +STDMETHODIMP CDsoDocObject::ExitPrintPreview(BOOL fForceExit) +{ + TRACE1("CDsoDocObject::ExitPrintPreview(fForceExit=%d)\n", (DWORD)fForceExit); + + // Need to be in preview to run this function... + if (!InPrintPreview()) return S_FALSE; + + // If the user closes the app or otherwise terminates the preview, we need + // to notify the ActiveDocument server to leave preview mode... + if (m_pprtprv) + { + if (fForceExit) // Tell docobj we want to end preview... + { + HRESULT hr = m_pprtprv->EndPrintPreview(TRUE); + ASSERT(SUCCEEDED(hr)); (void)hr; + } + } + else if (m_fInPptSlideShow) + { + if ((fForceExit) && (m_hwndUIActiveObj)) + { + // HACK: When it goes into slideshow, PPT 2007 changes the active window but + // doesn't call SetActiveObject to update us with new object and window handle. + // If we post VK_ESCAPE to the window handle we have, it can fail. It needs to go + // to the slideshow window that PPT failed to give us handle for. As workaround, + // setting focus to the UI window we have handle for will automatically forward + // to the right window, so we can use that trick to get the right window and + // make the call in a way that that should succeed regardless of PPT version... + SetFocus(m_hwndUIActiveObj); + PostMessage(GetFocus(), WM_KEYDOWN, VK_ESCAPE, 0x00000001); + PostMessage(GetFocus(), WM_KEYUP, VK_ESCAPE, 0xC0000001); + } + m_fAttemptPptPreview = FALSE; + m_fInPptSlideShow = FALSE; + } + + if (m_hwndCtl) // Notify the control that preview ended... + SendMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)TRUE); + + // Free our reference to preview interface... + SAFE_RELEASE_INTERFACE(m_pprtprv); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// CDsoDocObject::CheckForPPTPreviewChange +// +// Used to update control when PPT goes in/out of slideshow asynchronously. +// +STDMETHODIMP_(void) CDsoDocObject::CheckForPPTPreviewChange() +{ + if (m_fInPptSlideShow) + { + ExitPrintPreview(FALSE); + } + else if (m_fAttemptPptPreview) + { + m_fInPptSlideShow = TRUE; + m_fAttemptPptPreview = FALSE; + if (m_hwndCtl) // Notify the control that preview started... + SendMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)FALSE); + } +} \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.def b/PROMS/DSOFRAMER/Source2005/dsoframer.def new file mode 100644 index 00000000..cb32e274 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.def @@ -0,0 +1,6 @@ +LIBRARY dsoframer.ocx +EXPORTS + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.dsp b/PROMS/DSOFRAMER/Source2005/dsoframer.dsp new file mode 100644 index 00000000..0a9d2843 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.dsp @@ -0,0 +1,205 @@ +# Microsoft Developer Studio Project File - Name="dsoframer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=dsoframer - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dsoframer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dsoframer.mak" CFG="dsoframer - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dsoframer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "dsoframer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dsoframer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /G5 /Gz /Zp4 /W3 /Zi /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib oledlg.lib winspool.lib shell32.lib urlmon.lib /nologo /base:"0x22000000" /version:1.2 /subsystem:windows /dll /map /debug /machine:I386 /out:"Release/dsoframer.ocx" /pdbtype:con /opt:nowin98 /merge:.rdata=.text +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build - Performing registration +OutDir=.\Release +TargetPath=.\Release\dsoframer.ocx +InputPath=.\Release\dsoframer.ocx +SOURCE="$(InputPath)" + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "dsoframer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /G6 /Zp4 /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib oledlg.lib winspool.lib shell32.lib urlmon.lib /nologo /base:"0x22000000" /version:1.2 /subsystem:windows /dll /map /debug /machine:I386 /out:"Debug/dsoframer.ocx" /pdbtype:con +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build - Performing registration +OutDir=.\Debug +TargetPath=.\Debug\dsoframer.ocx +InputPath=.\Debug\dsoframer.ocx +SOURCE="$(InputPath)" + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "dsoframer - Win32 Release" +# Name "dsoframer - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "c;cpp;rc;idl" +# Begin Source File + +SOURCE=.\classfactory.cpp +# End Source File +# Begin Source File + +SOURCE=.\dsofauto.cpp +# End Source File +# Begin Source File + +SOURCE=.\dsofcontrol.cpp +# End Source File +# Begin Source File + +SOURCE=.\dsofdocobj.cpp +# End Source File +# Begin Source File + +SOURCE=.\dsofprint.cpp +# End Source File +# Begin Source File + +SOURCE=.\lib\dsoframer.idl +# ADD MTL /h "lib/dsoframerlib.h" /iid "lib/dsoframerlib.c" +# End Source File +# Begin Source File + +SOURCE=.\res\dsoframer.rc +# End Source File +# Begin Source File + +SOURCE=.\mainentry.cpp + +!IF "$(CFG)" == "dsoframer - Win32 Release" + +# ADD CPP /D "DSO_MIN_CRT_STARTUP" + +!ELSEIF "$(CFG)" == "dsoframer - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\utilities.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;def" +# Begin Source File + +SOURCE=.\dsofdocobj.h +# End Source File +# Begin Source File + +SOURCE=.\dsoframer.def +# End Source File +# Begin Source File + +SOURCE=.\dsoframer.h +# End Source File +# Begin Source File + +SOURCE=.\utilities.h +# End Source File +# Begin Source File + +SOURCE=.\version.h +# End Source File +# End Group +# Begin Group "Resources" + +# PROP Default_Filter "ico;cur;tlb;bmp" +# Begin Source File + +SOURCE=.\res\dso.ico +# End Source File +# Begin Source File + +SOURCE=.\lib\dsoframer.olb +# End Source File +# Begin Source File + +SOURCE=.\res\toolbox.bmp +# End Source File +# End Group +# End Target +# End Project diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.dsw b/PROMS/DSOFRAMER/Source2005/dsoframer.dsw new file mode 100644 index 00000000..c64fc6a9 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "dsoframer"=.\dsoframer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.h b/PROMS/DSOFRAMER/Source2005/dsoframer.h new file mode 100644 index 00000000..59eb956a --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.h @@ -0,0 +1,689 @@ +/*************************************************************************** + * DSOFRAMER.H + * + * Developer Support Office ActiveX Document Framer Control Sample + * + * Copyright ©1999-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. + * + * You have a royalty-free right to use, modify, reproduce and distribute + * this sample application, and/or any modified version, in any way you + * find useful, provided that you agree that Microsoft has no warranty, + * obligations or liability for the code or information provided herein. + * + * 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. + * + * See the EULA.TXT file included in the KB download for full terms of use + * and restrictions. You should consult documentation on MSDN Library for + * possible updates or changes to behaviors or interfaces used in this sample. + * + ***************************************************************************/ +#ifndef DS_DSOFRAMER_H +#define DS_DSOFRAMER_H + +//////////////////////////////////////////////////////////////////// +// We compile at level 4 and disable some unnecessary warnings... +// +#pragma warning(push, 4) // Compile at level-4 warnings +#pragma warning(disable: 4100) // unreferenced formal parameter (in OLE this is common) +#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable: 4268) // const static/global data initialized with compiler generated default constructor +#pragma warning(disable: 4310) // cast truncates constant value +#pragma warning(disable: 4786) // identifier was truncated in the debug information + +//////////////////////////////////////////////////////////////////// +// Compile Options For Modified Behavior... +// +#define DSO_MSDAIPP_USE_DAVONLY // Default to WebDAV protocol for open by HTTP/HTTPS +#define DSO_WORD12_PERSIST_BUG // Perform workaround for IPersistFile bug in Word 2007 + +//////////////////////////////////////////////////////////////////// +// Needed include files (both standard and custom) +// +#include +#include +#include +#include +#include + +#include "version.h" +#include "utilities.h" +#include "dsofdocobj.h" +#include ".\lib\dsoframerlib.h" +#include ".\res\resource.h" + +//////////////////////////////////////////////////////////////////// +// Global Variables +// +extern HINSTANCE v_hModule; +extern CRITICAL_SECTION v_csecThreadSynch; +extern HICON v_icoOffDocIcon; +extern ULONG v_cLocks; +extern BOOL v_fUnicodeAPI; +extern BOOL v_fWindows2KPlus; + +//////////////////////////////////////////////////////////////////// +// Custom Errors - we support a very limited set of custom error messages +// +#define DSO_E_ERR_BASE 0x80041100 +#define DSO_E_UNKNOWN 0x80041101 // "An unknown problem has occurred." +#define DSO_E_INVALIDPROGID 0x80041102 // "The ProgID/Template could not be found or is not associated with a COM server." +#define DSO_E_INVALIDSERVER 0x80041103 // "The associated COM server does not support ActiveX Document embedding." +#define DSO_E_COMMANDNOTSUPPORTED 0x80041104 // "The command is not supported by the document server." +#define DSO_E_DOCUMENTREADONLY 0x80041105 // "Unable to perform action because document was opened in read-only mode." +#define DSO_E_REQUIRESMSDAIPP 0x80041106 // "The Microsoft Internet Publishing Provider is not installed, so the URL document cannot be open for write access." +#define DSO_E_DOCUMENTNOTOPEN 0x80041107 // "No document is open to perform the operation requested." +#define DSO_E_INMODALSTATE 0x80041108 // "Cannot access document when in modal condition." +#define DSO_E_NOTBEENSAVED 0x80041109 // "Cannot Save file without a file path." +#define DSO_E_FRAMEHOOKFAILED 0x8004110A // "Unable to set frame hook for the parent window." +#define DSO_E_ERR_MAX 0x8004110B + +//////////////////////////////////////////////////////////////////// +// Custom OLE Command IDs - we use for special tasks +// +#define OLECMDID_GETDATAFORMAT 0x7001 // 28673 +#define OLECMDID_SETDATAFORMAT 0x7002 // 28674 +#define OLECMDID_LOCKSERVER 0x7003 // 28675 +#define OLECMDID_RESETFRAMEHOOK 0x7009 // 28681 +#define OLECMDID_NOTIFYACTIVE 0x700A // 28682 + +//////////////////////////////////////////////////////////////////// +// Custom Window Messages (only apply to CDsoFramerControl window proc) +// +#define DSO_WM_ASYNCH_OLECOMMAND (WM_USER + 300) +#define DSO_WM_ASYNCH_STATECHANGE (WM_USER + 301) + +#define DSO_WM_HOOK_NOTIFY_COMPACTIVE (WM_USER + 400) +#define DSO_WM_HOOK_NOTIFY_APPACTIVATE (WM_USER + 401) +#define DSO_WM_HOOK_NOTIFY_FOCUSCHANGE (WM_USER + 402) +#define DSO_WM_HOOK_NOTIFY_SYNCPAINT (WM_USER + 403) +#define DSO_WM_HOOK_NOTIFY_PALETTECHANGE (WM_USER + 404) + +// State Flags for DSO_WM_ASYNCH_STATECHANGE: +#define DSO_STATE_MODAL 1 +#define DSO_STATE_ACTIVATION 2 +#define DSO_STATE_INTERACTIVE 3 +#define DSO_STATE_RETURNFROMMODAL 4 + + +//////////////////////////////////////////////////////////////////// +// Menu Bar Items +// +#define DSO_MAX_MENUITEMS 16 +#define DSO_MAX_MENUNAME_LENGTH 32 + +#ifndef DT_HIDEPREFIX +#define DT_HIDEPREFIX 0x00100000 +#define DT_PREFIXONLY 0x00200000 +#endif + +#define SYNCPAINT_TIMER_ID 4 + + +//////////////////////////////////////////////////////////////////// +// Control Class Factory +// +class CDsoFramerClassFactory : public IClassFactory +{ +public: + CDsoFramerClassFactory(): m_cRef(0){} + ~CDsoFramerClassFactory(void){} + + // IUnknown Implementation + STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // IClassFactory Implementation + STDMETHODIMP CreateInstance(LPUNKNOWN punk, REFIID riid, void** ppv); + STDMETHODIMP LockServer(BOOL fLock); + +private: + ULONG m_cRef; // Reference count + +}; + +//////////////////////////////////////////////////////////////////// +// CDsoFramerControl -- Main Control (OCX) Object +// +// The CDsoFramerControl control is standard OLE control designed around +// the OCX94 specification. Because we plan on doing custom integration to +// act as both OLE object and OLE host, it does not use frameworks like ATL +// or MFC which would only complicate the nature of the sample. +// +// The control inherits from its automation interface, but uses nested +// classes for all OLE interfaces. This is not a requirement but does help +// to clearly seperate the tasks done by each interface and makes finding +// ref count problems easier to spot since each interface carries its own +// counter and will assert (in debug) if interface is over or under released. +// +// The control is basically a stage for the ActiveDocument embedding, and +// handles any external (user) commands. The task of actually acting as +// a DocObject host is done in the site object CDsoDocObject, which this +// class creates and uses for the embedding. +// +class CDsoFramerControl : public _FramerControl +{ +public: + CDsoFramerControl(LPUNKNOWN punk); + ~CDsoFramerControl(void); + + // IUnknown Implementation -- Always delgates to outer unknown... + STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){return m_pOuterUnknown->QueryInterface(riid, ppv);} + STDMETHODIMP_(ULONG) AddRef(void){return m_pOuterUnknown->AddRef();} + STDMETHODIMP_(ULONG) Release(void){return m_pOuterUnknown->Release();} + + // IDispatch Implementation + STDMETHODIMP GetTypeInfoCount(UINT* pctinfo); + STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo); + STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId); + STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr); + + // _FramerControl Implementation + STDMETHODIMP Activate(); + STDMETHODIMP get_ActiveDocument(IDispatch** ppdisp); + STDMETHODIMP CreateNew(BSTR ProgIdOrTemplate); + STDMETHODIMP Open(VARIANT Document, VARIANT ReadOnly, VARIANT ProgId, VARIANT WebUsername, VARIANT WebPassword); + STDMETHODIMP Save(VARIANT SaveAsDocument, VARIANT OverwriteExisting, VARIANT WebUsername, VARIANT WebPassword); + STDMETHODIMP _PrintOutOld(VARIANT PromptToSelectPrinter); + STDMETHODIMP Close(); + STDMETHODIMP put_Caption(BSTR bstr); + STDMETHODIMP get_Caption(BSTR* pbstr); + STDMETHODIMP put_Titlebar(VARIANT_BOOL vbool); + STDMETHODIMP get_Titlebar(VARIANT_BOOL* pbool); + STDMETHODIMP put_Toolbars(VARIANT_BOOL vbool); + STDMETHODIMP get_Toolbars(VARIANT_BOOL* pbool); + STDMETHODIMP put_ModalState(VARIANT_BOOL vbool); + STDMETHODIMP get_ModalState(VARIANT_BOOL* pbool); + STDMETHODIMP ShowDialog(dsoShowDialogType DlgType); + STDMETHODIMP put_EnableFileCommand(dsoFileCommandType Item, VARIANT_BOOL vbool); + STDMETHODIMP get_EnableFileCommand(dsoFileCommandType Item, VARIANT_BOOL* pbool); + STDMETHODIMP put_BorderStyle(dsoBorderStyle style); + STDMETHODIMP get_BorderStyle(dsoBorderStyle* pstyle); + STDMETHODIMP put_BorderColor(OLE_COLOR clr); + STDMETHODIMP get_BorderColor(OLE_COLOR* pclr); + STDMETHODIMP put_BackColor(OLE_COLOR clr); + STDMETHODIMP get_BackColor(OLE_COLOR* pclr); + STDMETHODIMP put_ForeColor(OLE_COLOR clr); + STDMETHODIMP get_ForeColor(OLE_COLOR* pclr); + STDMETHODIMP put_TitlebarColor(OLE_COLOR clr); + STDMETHODIMP get_TitlebarColor(OLE_COLOR* pclr); + STDMETHODIMP put_TitlebarTextColor(OLE_COLOR clr); + STDMETHODIMP get_TitlebarTextColor(OLE_COLOR* pclr); + STDMETHODIMP ExecOleCommand(LONG OLECMDID, VARIANT Options, VARIANT* vInParam, VARIANT* vInOutParam); + STDMETHODIMP put_Menubar(VARIANT_BOOL vbool); + STDMETHODIMP get_Menubar(VARIANT_BOOL* pbool); + STDMETHODIMP put_HostName(BSTR bstr); + STDMETHODIMP get_HostName(BSTR* pbstr); + STDMETHODIMP get_DocumentFullName(BSTR* pbstr); + STDMETHODIMP PrintOut(VARIANT PromptUser, VARIANT PrinterName, VARIANT Copies, VARIANT FromPage, VARIANT ToPage, VARIANT OutputFile); + STDMETHODIMP PrintPreview(); + STDMETHODIMP PrintPreviewExit(); + STDMETHODIMP get_IsReadOnly(VARIANT_BOOL* pbool); + STDMETHODIMP get_IsDirty(VARIANT_BOOL* pbool); + STDMETHODIMP put_LockServer(VARIANT_BOOL vbool); + STDMETHODIMP get_LockServer(VARIANT_BOOL* pvbool); + STDMETHODIMP GetDataObjectContent(VARIANT ClipFormatNameOrNumber, VARIANT *pvResults); + STDMETHODIMP SetDataObjectContent(VARIANT ClipFormatNameOrNumber, VARIANT DataByteArray); + STDMETHODIMP put_ActivationPolicy(dsoActivationPolicy lPolicy); + STDMETHODIMP get_ActivationPolicy(dsoActivationPolicy *plPolicy); + STDMETHODIMP put_FrameHookPolicy(dsoFrameHookPolicy lPolicy); + STDMETHODIMP get_FrameHookPolicy(dsoFrameHookPolicy *plPolicy); + STDMETHODIMP put_MenuAccelerators(VARIANT_BOOL vbool); + STDMETHODIMP get_MenuAccelerators(VARIANT_BOOL* pvbool); + STDMETHODIMP put_EventsEnabled(VARIANT_BOOL vbool); + STDMETHODIMP get_EventsEnabled(VARIANT_BOOL* pvbool); + STDMETHODIMP get_DocumentName(BSTR* pbstr); + + // IInternalUnknown Implementation + BEGIN_INTERFACE_PART(InternalUnknown, IUnknown) + END_INTERFACE_PART(InternalUnknown) + + // IPersistStreamInit Implementation + BEGIN_INTERFACE_PART(PersistStreamInit, IPersistStreamInit) + STDMETHODIMP GetClassID(CLSID *pClassID); + STDMETHODIMP IsDirty(void); + STDMETHODIMP Load(LPSTREAM pStm); + STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty); + STDMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize); + STDMETHODIMP InitNew(void); + END_INTERFACE_PART(PersistStreamInit) + + // IPersistPropertyBag Implementation + BEGIN_INTERFACE_PART(PersistPropertyBag, IPersistPropertyBag) + STDMETHODIMP GetClassID(CLSID *pClassID); + STDMETHODIMP InitNew(void); + STDMETHODIMP Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog); + STDMETHODIMP Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties); + END_INTERFACE_PART(PersistPropertyBag) + + // IPersistStorage Implementation + BEGIN_INTERFACE_PART(PersistStorage, IPersistStorage) + STDMETHODIMP GetClassID(CLSID *pClassID); + STDMETHODIMP IsDirty(void); + STDMETHODIMP InitNew(LPSTORAGE pStg); + STDMETHODIMP Load(LPSTORAGE pStg); + STDMETHODIMP Save(LPSTORAGE pStg, BOOL fSameAsLoad); + STDMETHODIMP SaveCompleted(LPSTORAGE pStg); + STDMETHODIMP HandsOffStorage(void); + END_INTERFACE_PART(PersistStorage) + + // IOleObject Implementation + BEGIN_INTERFACE_PART(OleObject, IOleObject) + STDMETHODIMP SetClientSite(IOleClientSite *pClientSite); + STDMETHODIMP GetClientSite(IOleClientSite **ppClientSite); + STDMETHODIMP SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj); + STDMETHODIMP Close(DWORD dwSaveOption); + STDMETHODIMP SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk); + STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk); + STDMETHODIMP InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved); + STDMETHODIMP GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject); + STDMETHODIMP DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect); + STDMETHODIMP EnumVerbs(IEnumOLEVERB **ppEnumOleVerb); + STDMETHODIMP Update(); + STDMETHODIMP IsUpToDate(); + STDMETHODIMP GetUserClassID(CLSID *pClsid); + STDMETHODIMP GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType); + STDMETHODIMP SetExtent(DWORD dwDrawAspect, SIZEL *psizel); + STDMETHODIMP GetExtent(DWORD dwDrawAspect, SIZEL *psizel); + STDMETHODIMP Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection); + STDMETHODIMP Unadvise(DWORD dwConnection); + STDMETHODIMP EnumAdvise(IEnumSTATDATA **ppenumAdvise); + STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus); + STDMETHODIMP SetColorScheme(LOGPALETTE *pLogpal); + END_INTERFACE_PART(OleObject) + + // IOleControl Implementation + BEGIN_INTERFACE_PART(OleControl, IOleControl) + STDMETHODIMP GetControlInfo(CONTROLINFO* pCI); + STDMETHODIMP OnMnemonic(LPMSG pMsg); + STDMETHODIMP OnAmbientPropertyChange(DISPID dispID); + STDMETHODIMP FreezeEvents(BOOL bFreeze); + END_INTERFACE_PART(OleControl) + + // IOleInplaceObject Implementation + BEGIN_INTERFACE_PART(OleInplaceObject, IOleInPlaceObject) + STDMETHODIMP GetWindow(HWND *phwnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + STDMETHODIMP InPlaceDeactivate(); + STDMETHODIMP UIDeactivate(); + STDMETHODIMP SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect); + STDMETHODIMP ReactivateAndUndo(); + END_INTERFACE_PART(OleInplaceObject) + + // IOleInplaceActiveObject Implementation + BEGIN_INTERFACE_PART(OleInplaceActiveObject, IOleInPlaceActiveObject) + STDMETHODIMP GetWindow(HWND *phwnd); + STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode); + STDMETHODIMP TranslateAccelerator(LPMSG lpmsg); + STDMETHODIMP OnFrameWindowActivate(BOOL fActivate); + STDMETHODIMP OnDocWindowActivate(BOOL fActivate); + STDMETHODIMP ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow); + STDMETHODIMP EnableModeless(BOOL fEnable); + END_INTERFACE_PART(OleInplaceActiveObject) + + // IViewObjectEx Implementation + BEGIN_INTERFACE_PART(ViewObjectEx, IViewObjectEx) + STDMETHODIMP Draw(DWORD dwDrawAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, HDC hdcDraw, LPCRECTL prcBounds, LPCRECTL prcWBounds, BOOL (__stdcall *pfnContinue)(DWORD dwContinue), DWORD dwContinue); + STDMETHODIMP GetColorSet(DWORD dwAspect, LONG lindex, void* pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE** ppColorSet); + STDMETHODIMP Freeze(DWORD dwAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze); + STDMETHODIMP Unfreeze(DWORD dwFreeze); + STDMETHODIMP SetAdvise(DWORD dwAspect, DWORD advf, IAdviseSink* pAdviseSink); + STDMETHODIMP GetAdvise(DWORD* pdwAspect, DWORD* padvf, IAdviseSink** ppAdviseSink); + STDMETHODIMP GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL psizel); + STDMETHODIMP GetRect(DWORD dwAspect, LPRECTL pRect); + STDMETHODIMP GetViewStatus(DWORD* pdwStatus); + STDMETHODIMP QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult); + STDMETHODIMP QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult); + STDMETHODIMP GetNaturalExtent(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel); + END_INTERFACE_PART(ViewObjectEx) + + // IDataObject Implementation + BEGIN_INTERFACE_PART(DataObject, IDataObject) + STDMETHODIMP GetData(FORMATETC *pfmtc, STGMEDIUM *pstgm); + STDMETHODIMP GetDataHere(FORMATETC *pfmtc, STGMEDIUM *pstgm); + STDMETHODIMP QueryGetData(FORMATETC *pfmtc); + STDMETHODIMP GetCanonicalFormatEtc(FORMATETC * pfmtcIn, FORMATETC * pfmtcOut); + STDMETHODIMP SetData(FORMATETC *pfmtc, STGMEDIUM *pstgm, BOOL fRelease); + STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum); + STDMETHODIMP DAdvise(FORMATETC *pfmtc, DWORD advf, IAdviseSink *psink, DWORD *pdwConnection); + STDMETHODIMP DUnadvise(DWORD dwConnection); + STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenum); + END_INTERFACE_PART(DataObject) + + // IProvideClassInfo Implementation + BEGIN_INTERFACE_PART(ProvideClassInfo, IProvideClassInfo) + STDMETHODIMP GetClassInfo(ITypeInfo** ppTI); + END_INTERFACE_PART(ProvideClassInfo) + + // IConnectionPointContainer Implementation + BEGIN_INTERFACE_PART(ConnectionPointContainer, IConnectionPointContainer) + STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppEnum); + STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP); + END_INTERFACE_PART(ConnectionPointContainer) + + // IEnumConnectionPoints Implementation + BEGIN_INTERFACE_PART(EnumConnectionPoints, IEnumConnectionPoints) + STDMETHODIMP Next(ULONG cConnections, IConnectionPoint **rgpcn, ULONG *pcFetched); + STDMETHODIMP Skip(ULONG cConnections); + STDMETHODIMP Reset(void); + STDMETHODIMP Clone(IEnumConnectionPoints **ppEnum); + END_INTERFACE_PART(EnumConnectionPoints) + + // IConnectionPoint Implementation + BEGIN_INTERFACE_PART(ConnectionPoint, IConnectionPoint) + STDMETHODIMP GetConnectionInterface(IID *pIID); + STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer **ppCPC); + STDMETHODIMP Advise(IUnknown *pUnk, DWORD *pdwCookie); + STDMETHODIMP Unadvise(DWORD dwCookie); + STDMETHODIMP EnumConnections(IEnumConnections **ppEnum); + END_INTERFACE_PART(ConnectionPoint) + + // IOleCommandTarget Implementation + BEGIN_INTERFACE_PART(OleCommandTarget , IOleCommandTarget) + STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText); + STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut); + END_INTERFACE_PART(OleCommandTarget) + + // ISupportErrorInfo Implementation + BEGIN_INTERFACE_PART(SupportErrorInfo, ISupportErrorInfo) + STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid); + END_INTERFACE_PART(SupportErrorInfo) + + // IObjectSafety Implementation + BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety) + STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions); + STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions); + END_INTERFACE_PART(ObjectSafety) + + // IDsoDocObjectSite Implementation (for DocObject Callbacks to control) + BEGIN_INTERFACE_PART(DsoDocObjectSite, IDsoDocObjectSite) + STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv); + STDMETHODIMP GetWindow(HWND* phWnd); + STDMETHODIMP GetBorder(LPRECT prcBorder); + STDMETHODIMP GetHostName(LPWSTR *ppwszHostName); + STDMETHODIMP SysMenuCommand(UINT uiCharCode); + STDMETHODIMP SetStatusText(LPCOLESTR pszText); + END_INTERFACE_PART(DsoDocObjectSite) + + STDMETHODIMP InitializeNewInstance(); + + STDMETHODIMP InPlaceActivate(LONG lVerb); + STDMETHODIMP UIActivate(BOOL fForceUIActive); + STDMETHODIMP_(void) SetInPlaceVisible(BOOL fShow); + STDMETHODIMP_(void) UpdateModalState(BOOL fModeless, BOOL fNotifyIPObject); + STDMETHODIMP_(void) UpdateInteractiveState(BOOL fActive); + STDMETHODIMP_(void) EnableDropFile(BOOL fEnable); + + STDMETHODIMP_(void) OnDraw(DWORD dvAspect, HDC hdcDraw, LPRECT prcBounds, LPRECT prcWBounds, HDC hicTargetDev, BOOL fOptimize); + STDMETHODIMP_(void) OnDestroyWindow(); + STDMETHODIMP_(void) OnResize(); + STDMETHODIMP_(void) OnMouseMove(UINT x, UINT y); + STDMETHODIMP_(void) OnButtonDown(UINT x, UINT y); + STDMETHODIMP_(void) OnMenuMessage(UINT msg, WPARAM wParam, LPARAM lParam); + STDMETHODIMP_(void) OnToolbarAction(DWORD cmd); + STDMETHODIMP_(void) OnDropFile(HDROP hdrpFile); + STDMETHODIMP_(void) OnTimer(UINT id); + + STDMETHODIMP_(void) OnForegroundCompChange(BOOL fCompActive); + STDMETHODIMP_(void) OnAppActivationChange(BOOL fActive, DWORD dwThreadID); + STDMETHODIMP_(void) OnComponentActivationChange(BOOL fActivate); + STDMETHODIMP_(void) OnCtrlFocusChange(BOOL fCtlGotFocus, HWND hFocusWnd); + STDMETHODIMP_(void) OnUIFocusChange(BOOL fUIActive); + + STDMETHODIMP_(void) OnPaletteChanged(HWND hwndPalChg); + STDMETHODIMP_(void) OnSyncPaint(); + STDMETHODIMP_(void) OnWindowEnable(BOOL fEnable){TRACE1("CDsoFramerControl::OnWindowEnable(%d)\n", fEnable);} + STDMETHODIMP_(BOOL) OnSysCommandMenu(CHAR ch); + + STDMETHODIMP_(HMENU) GetActivePopupMenu(); + STDMETHODIMP_(BOOL) FAlertUser(HRESULT hr, LPWSTR pwsFileName); + STDMETHODIMP_(BOOL) FRunningInDesignMode(); + STDMETHODIMP DoDialogAction(dsoShowDialogType item); + + STDMETHODIMP_(void) RaiseActivationEvent(BOOL fActive); + + STDMETHODIMP ProvideErrorInfo(HRESULT hres); + STDMETHODIMP RaiseAutomationEvent(DISPID did, ULONG cargs, VARIANT *pvtargs); + + STDMETHODIMP SetTempServerLock(BOOL fLock); + STDMETHODIMP ResetFrameHook(HWND hwndFrameWindow); + + // Some inline methods are provided for common tasks such as site notification + // or calculation of draw size based on user selection of tools and border style. + + void __fastcall ViewChanged() + { + if (m_pDataAdviseHolder) // Send data change notification. + m_pDataAdviseHolder->SendOnDataChange((IDataObject*)&m_xDataObject, NULL, 0); + + if (m_pViewAdviseSink) // Send the view change notification.... + { + m_pViewAdviseSink->OnViewChange(DVASPECT_CONTENT, -1); + if (m_fViewAdviseOnlyOnce) // If they asked to be advised once, kill the connection + m_xViewObjectEx.SetAdvise(DVASPECT_CONTENT, 0, NULL); + } + InvalidateRect(m_hwnd, NULL, TRUE); // Ensure a full repaint... + } + + void __fastcall GetSizeRectAfterBorder(LPRECT lprcx, LPRECT lprc) + { + if (lprcx) CopyRect(lprc, lprcx); + else SetRect(lprc, 0, 0, m_Size.cx, m_Size.cy); + if (m_fBorderStyle) InflateRect(lprc, -(4-m_fBorderStyle), -(4-m_fBorderStyle)); + } + + void __fastcall GetSizeRectAfterTitlebar(LPRECT lprcx, LPRECT lprc) + { + GetSizeRectAfterBorder(lprcx, lprc); + if (m_fShowTitlebar) lprc->top += 21; + } + + void __fastcall GetSizeRectForMenuBar(LPRECT lprcx, LPRECT lprc) + { + GetSizeRectAfterTitlebar(lprcx, lprc); + lprc->bottom = lprc->top + 24; + } + + void __fastcall GetSizeRectForDocument(LPRECT lprcx, LPRECT lprc) + { + GetSizeRectAfterTitlebar(lprcx, lprc); + if (m_fShowMenuBar) lprc->top += 24; + if (lprc->top > lprc->bottom) lprc->top = lprc->bottom; + } + + + void __fastcall RedrawCaption() + { + RECT rcT; + if ((m_hwnd) && (m_fShowTitlebar)) + { GetClientRect(m_hwnd, &rcT); rcT.bottom = 21; + InvalidateRect(m_hwnd, &rcT, FALSE); + } + if ((m_hwnd) && (m_fShowMenuBar)) + { GetSizeRectForMenuBar(NULL, &rcT); + InvalidateRect(m_hwnd, &rcT, FALSE); + } + } + + BOOL __fastcall FUseFrameHook(){return (m_lHookPolicy != dsoDisableHook);}; + BOOL __fastcall FDelayFrameHookSet(){return (m_lHookPolicy == dsoSetOnFirstOpen);}; + + BOOL __fastcall FDrawBitmapOnAppDeactive(){return (!(m_lActivationPolicy & dsoKeepUIActiveOnAppDeactive));} + BOOL __fastcall FChangeObjActiveOnFocusChange(){return (m_lActivationPolicy & dsoCompDeactivateOnLostFocus);}; + BOOL __fastcall FIPDeactivateOnCompChange(){return (m_lActivationPolicy & dsoIPDeactivateOnCompDeactive);}; + + // The control window proceedure is handled through static class method. + static STDMETHODIMP_(LRESULT) ControlWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + // Force redaw of all child windows... + STDMETHODIMP_(BOOL) InvalidateAllChildWindows(HWND hwnd); + static STDMETHODIMP_(BOOL) InvalidateAllChildWindowsCallback(HWND hwnd, LPARAM lParam); + + // The variables for the control are kept private but accessible to the + // nested classes for each interface. +private: + + ULONG m_cRef; // Reference count + IUnknown *m_pOuterUnknown; // Outer IUnknown (points to m_xInternalUnknown if not agg) + ITypeInfo *m_ptiDispType; // ITypeInfo Pointer (IDispatch Impl) + EXCEPINFO *m_pDispExcep; // EXCEPINFO Pointer (IDispatch Impl) + + HWND m_hwnd; // our window + HWND m_hwndParent; // immediate parent window + SIZEL m_Size; // the size of this control + RECT m_rcLocation; // where we at + + IOleClientSite *m_pClientSite; // active client site of host containter + IOleControlSite *m_pControlSite; // control site + IOleInPlaceSite *m_pInPlaceSite; // inplace site + IOleInPlaceFrame *m_pInPlaceFrame; // inplace frame + IOleInPlaceUIWindow *m_pInPlaceUIWindow; // inplace ui window + + IAdviseSink *m_pViewAdviseSink; // advise sink for view (only 1 allowed) + IOleAdviseHolder *m_pOleAdviseHolder; // OLE advise holder (for oleobject sinks) + IDataAdviseHolder *m_pDataAdviseHolder; // OLE data advise holder (for dataobject sink) + IDispatch *m_dispEvents; // event sink (we only support 1 at a time) + IStorage *m_pOleStorage; // IStorage for OLE hosts. + + CDsoDocObject *m_pDocObjFrame; // The Embedding Class + CDsoDocObject *m_pServerLock; // Optional Server Lock for out-of-proc DocObject + + OLE_COLOR m_clrBorderColor; // Control Colors + OLE_COLOR m_clrBackColor; // " + OLE_COLOR m_clrForeColor; // " + OLE_COLOR m_clrTBarColor; // " + OLE_COLOR m_clrTBarTextColor; // " + + BSTR m_bstrCustomCaption; // A custom caption (if provided) + HMENU m_hmenuFilePopup; // The File menu popup + WORD m_wFileMenuFlags; // Bitflags of enabled file menu items. + WORD m_wSelMenuItem; // Which item (if any) is selected + WORD m_cMenuItems; // Count of items on menu bar + RECT m_rgrcMenuItems[DSO_MAX_MENUITEMS]; // Menu bar items + CHAR m_rgchMenuAccel[DSO_MAX_MENUITEMS]; // Menu bar accelerators + LPWSTR m_pwszHostName; // Custom name for SetHostNames + + class CDsoFrameHookManager* m_pHookManager; // Frame Window Hook Manager Class + LONG m_lHookPolicy; // Policy on how to use frame hook for this host. + LONG m_lActivationPolicy; // Policy on activation behavior for comp focus + HBITMAP m_hbmDeactive; // Bitmap used for IPDeactiveOnXXX policies + UINT m_uiSyncPaint; // Sync paint counter for draw issues with UIDeactivateOnXXX + + unsigned int m_fDirty:1; // does the control need to be resaved? + unsigned int m_fInPlaceActive:1; // are we in place active or not? + unsigned int m_fInPlaceVisible:1; // we are in place visible or not? + unsigned int m_fUIActive:1; // are we UI active or not. + unsigned int m_fHasFocus:1; // do we have current focus. + unsigned int m_fViewAdvisePrimeFirst: 1;// for IViewobject2::setadvise + unsigned int m_fViewAdviseOnlyOnce: 1; // for IViewobject2::setadvise + unsigned int m_fUsingWindowRgn:1; // for SetObjectRects and clipping + unsigned int m_fFreezeEvents:1; // should events be frozen? + unsigned int m_fDesignMode:1; // are we in design mode? + unsigned int m_fModeFlagValid:1; // has mode changed since last check? + unsigned int m_fBorderStyle:2; // the border style + unsigned int m_fShowTitlebar:1; // should we show titlebar? + unsigned int m_fShowToolbars:1; // should we show toolbars? + unsigned int m_fModalState:1; // are we modal? + unsigned int m_fObjectMenu:1; // are we over obj menu item? + unsigned int m_fConCntDone:1; // for enum connectpts + unsigned int m_fAppActive:1; // is the app active? + unsigned int m_fComponentActive:1; // is the component active? + unsigned int m_fShowMenuBar:1; // should we show menubar? + unsigned int m_fInDocumentLoad:1; // set when loading file + unsigned int m_fNoInteractive:1; // set when we don't allow interaction with docobj + unsigned int m_fShowMenuPrev:1; // were menus visible before loss of interactivity? + unsigned int m_fShowToolsPrev:1; // were toolbars visible before loss of interactivity? + unsigned int m_fSyncPaintTimer:1; // is syncpaint timer running? + unsigned int m_fInControlActivate:1; // is currently in activation call? + unsigned int m_fInFocusChange:1; // are we in a focus change? + unsigned int m_fActivateOnStatus:1; // we need to activate on change of status + unsigned int m_fDisableMenuAccel:1; // using menu accelerators + unsigned int m_fBkgrdPaintTimer:1; // using menu accelerators + +}; + + +//////////////////////////////////////////////////////////////////// +// CDsoFrameWindowHook -- Frame Window Hook Class +// +// Used by the control to allow for proper host notification of focus +// and activation events occurring at top-level window frame. Because +// this DocObject host is an OCX, we don't own these notifications and +// have to "steal" them from our parent using a subclass. +// +// IMPORTANT: Since the parent frame may exist on a separate thread, this +// class does nothing but the hook. The code to notify the active component +// is in a separate global class that is shared by all threads. +// +class CDsoFrameWindowHook +{ +public: + CDsoFrameWindowHook(){ODS("CDsoFrameWindowHook created\n");m_cHookCount=0;m_hwndTopLevelHost=NULL;m_pfnOrigWndProc=NULL;m_fHostUnicodeWindow=FALSE;} + ~CDsoFrameWindowHook(){ODS("CDsoFrameWindowHook deleted\n");} + + static STDMETHODIMP_(CDsoFrameWindowHook*) AttachToFrameWindow(HWND hwndParent); + STDMETHODIMP Detach(); + + static STDMETHODIMP_(CDsoFrameWindowHook*) GetHookFromWindow(HWND hwnd); + inline STDMETHODIMP_(void) AddRef(){InterlockedIncrement((LONG*)&m_cHookCount);} + + static STDMETHODIMP_(LRESULT) + HostWindowProcHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +protected: + DWORD m_cHookCount; + HWND m_hwndTopLevelHost; // Top-level host window (hooked) + WNDPROC m_pfnOrigWndProc; + BOOL m_fHostUnicodeWindow; +}; + +// THE MAX NUMBER OF DSOFRAMER CONTROLS PER PROCESS +#define DSOF_MAX_CONTROLS 20 + +//////////////////////////////////////////////////////////////////// +// CDsoFrameHookManager -- Hook Manager Class +// +// Used to keep track of which control is active and forward notifications +// to it using window messages (to cross thread boundaries). +// +class CDsoFrameHookManager +{ +public: + CDsoFrameHookManager(){ODS("CDsoFrameHookManager created\n"); m_fAppActive=TRUE; m_idxActive=DSOF_MAX_CONTROLS; m_cComponents=0;} + ~CDsoFrameHookManager(){ODS("CDsoFrameHookManager deleted\n");} + + static STDMETHODIMP_(CDsoFrameHookManager*) + RegisterFramerControl(HWND hwndParent, HWND hwndControl); + + STDMETHODIMP AddComponent(HWND hwndParent, HWND hwndControl); + STDMETHODIMP DetachComponent(HWND hwndControl); + STDMETHODIMP SetActiveComponent(HWND hwndControl); + STDMETHODIMP OnComponentNotify(DWORD msg, WPARAM wParam, LPARAM lParam); + + inline STDMETHODIMP_(HWND) + GetActiveComponentWindow(){return m_pComponents[m_idxActive].hwndControl;} + + inline STDMETHODIMP_(CDsoFrameWindowHook*) + GetActiveComponentFrame(){return m_pComponents[m_idxActive].phookFrame;} + + STDMETHODIMP_(BOOL) SendNotifyMessage(HWND hwnd, DWORD msg, WPARAM wParam, LPARAM lParam); + +protected: + BOOL m_fAppActive; + DWORD m_idxActive; + DWORD m_cComponents; + struct FHOOK_COMPONENTS + { + HWND hwndControl; + CDsoFrameWindowHook *phookFrame; + } m_pComponents[DSOF_MAX_CONTROLS]; +}; + +#endif //DS_DSOFRAMER_H \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.sln b/PROMS/DSOFRAMER/Source2005/dsoframer.sln new file mode 100644 index 00000000..2c94c084 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.sln @@ -0,0 +1,69 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsoframer", "dsoframer.vcproj", "{005801E1-A867-4CBB-995F-BA2EF4360BDF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Win32.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Win32.Build.0 = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Any CPU.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Mixed Platforms.Build.0 = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Win32.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Win32.Build.0 = Release|Win32 + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Any CPU.Build.0 = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Win32.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Any CPU.Build.0 = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Win32.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Win32.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Any CPU.Build.0 = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Win32.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Any CPU.Build.0 = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Win32.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.sln.bak b/PROMS/DSOFRAMER/Source2005/dsoframer.sln.bak new file mode 100644 index 00000000..02fbc1ed --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.sln.bak @@ -0,0 +1,77 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsoframer", "dsoframer.vcproj", "{005801E1-A867-4CBB-995F-BA2EF4360BDF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleCSharp", "..\SampleCSharp\SampleCSharp.csproj", "{E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestC1DockingTab", "..\TestC1DockingTab\TestC1DockingTab.csproj", "{D066A5C4-72B8-45F8-A117-B967019F41AE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetBarDockable", "..\DotNetBarDockable\DotNetBarDockable.csproj", "{96DC8B48-A4E2-4826-A182-BE112B628B50}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetBarControl", "..\DotNetBarControl\DotNetBarControl.csproj", "{9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Win32.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug|Win32.Build.0 = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Any CPU.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Mixed Platforms.Build.0 = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Win32.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release|Win32.Build.0 = Release|Win32 + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Any CPU.Build.0 = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E7C7BC82-10A6-459B-8D48-9CE1C070E9FD}.Release|Win32.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Debug|Win32.ActiveCfg = Debug|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Any CPU.Build.0 = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D066A5C4-72B8-45F8-A117-B967019F41AE}.Release|Win32.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Debug|Win32.ActiveCfg = Debug|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Any CPU.Build.0 = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {96DC8B48-A4E2-4826-A182-BE112B628B50}.Release|Win32.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Any CPU.Build.0 = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9939DC3D-AFB6-4B0D-813A-3EBE3FF7249D}.Release|Win32.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.sln.old b/PROMS/DSOFRAMER/Source2005/dsoframer.sln.old new file mode 100644 index 00000000..2996d403 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.sln.old @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsoframer", "dsoframer.vcproj", "{005801E1-A867-4CBB-995F-BA2EF4360BDF}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug.ActiveCfg = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Debug.Build.0 = Debug|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release.ActiveCfg = Release|Win32 + {005801E1-A867-4CBB-995F-BA2EF4360BDF}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj new file mode 100644 index 00000000..e933b00d --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.7.10.old b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.7.10.old new file mode 100644 index 00000000..3fa47abc --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.7.10.old @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.RHMDESKTOP.Rich Mark.user b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.RHMDESKTOP.Rich Mark.user new file mode 100644 index 00000000..d2e6cf73 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/dsoframer.vcproj.RHMDESKTOP.Rich Mark.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/PROMS/DSOFRAMER/Source2005/ipprevw.h b/PROMS/DSOFRAMER/Source2005/ipprevw.h new file mode 100644 index 00000000..22ace9fe --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/ipprevw.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * IPPREVIEW.H + * + * DSOFramer: IOleInplacePrintPreview/IOlePreviewCallback + * + * Copyright ©1999-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. + * + ***************************************************************************/ +#ifndef __IPPREVIEW_H +#define __IPPREVIEW_H + +//////////////////////////////////////////////////////////////////////// +// +// IOlePreviewCallback +// +// Implemented by host to receive notifaction messages +// from ip object while displaying a print preview. +// +DEFINE_GUID(IID_IOlePreviewCallback, 0xB722BCD5, 0x4E68, 0x101B, 0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70); + +#undef INTERFACE +#define INTERFACE IOlePreviewCallback +DECLARE_INTERFACE_(IOlePreviewCallback, IUnknown) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + // IUnknown methods + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +#endif + // IOlePreviewCallback methods + STDMETHOD(Notify)(THIS_ DWORD wStatus, LONG nLastPage, LPOLESTR pwszPreviewStatus) PURE; +}; + +#define NOTIFY_FINISHED 1 +#define NOTIFY_BUSY 2 +#define NOTIFY_IDLE 4 +#define NOTIFY_DISABLERESIZE 8 +#define NOTIFY_QUERYCLOSEPREVIEW 16 +#define NOTIFY_FORCECLOSEPREVIEW 32 +#define NOTIFY_UIACTIVE 64 +#define NOTIFY_UNABLETOPREVIEW 128 + +//////////////////////////////////////////////////////////////////////// +// +// IOleInplacePrintPreview +// +// Implemented by server to start/stop print preview. Hosts should +// call QueryStatus to make sure server is able to enter preview mode +// before calling StartPrintPreview. +// +DEFINE_GUID(IID_IOleInplacePrintPreview, 0xB722BCD4, 0x4E68, 0x101B, 0xA2, 0xBC, 0x00, 0xAA, 0x00, 0x40, 0x47, 0x70); + +#undef INTERFACE +#define INTERFACE IOleInplacePrintPreview +DECLARE_INTERFACE_(IOleInplacePrintPreview, IUnknown) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + // IUnknown methods + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +#endif + // IOleInplacePrintPreview methods + STDMETHOD(StartPrintPreview)(THIS_ DWORD grfFlags, DVTARGETDEVICE *ptd, IOlePreviewCallback *ppCallback, LONG nFirstPage) PURE; + STDMETHOD(EndPrintPreview)(THIS_ BOOL fForceClose) PURE; + STDMETHOD(QueryStatus)(THIS_ void) PURE; +}; + +#define PREVIEWFLAG_MAYBOTHERUSER 1 +#define PREVIEWFLAG_PROMPTUSER 2 +#define PREVIEWFLAG_USERMAYCHANGEPRINTER 4 +#define PREVIEWFLAG_RECOMPOSETODEVICE 8 + + +#endif //__IPPREVIEW_H diff --git a/PROMS/DSOFRAMER/Source2005/mainentry.cpp b/PROMS/DSOFRAMER/Source2005/mainentry.cpp new file mode 100644 index 00000000..ef36e7e1 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/mainentry.cpp @@ -0,0 +1,318 @@ +/*************************************************************************** + * MAINENTRY.CPP + * + * Main DLL Entry and Required COM Entry Points. + * + * Copyright ©1999-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. + * + ***************************************************************************/ +#define INITGUID // Init the GUIDS for the control... +#include "dsoframer.h" + +HINSTANCE v_hModule = NULL; // DLL module handle +HANDLE v_hPrivateHeap = NULL; // Private Memory Heap +ULONG v_cLocks = 0; // Count of server locks +HICON v_icoOffDocIcon = NULL; // Small office icon (for caption bar) +BOOL v_fUnicodeAPI = FALSE; // Flag to determine if we should us Unicode API +BOOL v_fWindows2KPlus = FALSE; +CRITICAL_SECTION v_csecThreadSynch; + +//////////////////////////////////////////////////////////////////////// +// DllMain -- OCX Main Entry +// +// +extern "C" BOOL APIENTRY DllMain(HINSTANCE hDllHandle, DWORD dwReason, LPVOID /*lpReserved*/) +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + v_hModule = hDllHandle; + v_hPrivateHeap = HeapCreate(0, 0x1000, 0); + v_icoOffDocIcon = (HICON)LoadImage(hDllHandle, MAKEINTRESOURCE(IDI_SMALLOFFDOC), IMAGE_ICON, 16, 16, 0); + { + DWORD dwVersion = GetVersion(); + v_fUnicodeAPI = ((dwVersion & 0x80000000) == 0); + v_fWindows2KPlus = ((v_fUnicodeAPI) && (LOBYTE(LOWORD(dwVersion)) > 4)); + } + InitializeCriticalSection(&v_csecThreadSynch); + DisableThreadLibraryCalls(hDllHandle); + break; + + case DLL_PROCESS_DETACH: + if (v_icoOffDocIcon) DeleteObject(v_icoOffDocIcon); + if (v_hPrivateHeap) HeapDestroy(v_hPrivateHeap); + DeleteCriticalSection(&v_csecThreadSynch); + break; + } + return TRUE; +} + +#ifdef DSO_MIN_CRT_STARTUP +extern "C" BOOL APIENTRY _DllMainCRTStartup(HINSTANCE hDllHandle, DWORD dwReason, LPVOID lpReserved) +{return DllMain(hDllHandle, dwReason, lpReserved);} +#endif + +//////////////////////////////////////////////////////////////////////// +// Standard COM DLL Entry Points +// +// +//////////////////////////////////////////////////////////////////////// +// DllCanUnloadNow +// +// +STDAPI DllCanUnloadNow() +{ + return ((v_cLocks == 0) ? S_OK : S_FALSE); +} + +//////////////////////////////////////////////////////////////////////// +// DllGetClassObject +// +// Returns IClassFactory instance for FramerControl. We only support +// this one object for creation. +// +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) +{ + HRESULT hr; + CDsoFramerClassFactory* pcf; + + CHECK_NULL_RETURN(ppv, E_POINTER); + *ppv = NULL; + + // The only component we can create is the BinderControl... + if (rclsid != CLSID_FramerControl) + return CLASS_E_CLASSNOTAVAILABLE; + + // Create the needed class factory... + pcf = new CDsoFramerClassFactory(); + CHECK_NULL_RETURN(pcf, E_OUTOFMEMORY); + + // Get requested interface. + if (FAILED(hr = pcf->QueryInterface(riid, ppv))) + { + *ppv = NULL; delete pcf; + } + else InterlockedIncrement((LPLONG)&v_cLocks); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// DllRegisterServer +// +// Registration of the OCX. +// +STDAPI DllRegisterServer() +{ + HRESULT hr = S_OK; + HKEY hk, hk2; + DWORD dwret; + CHAR szbuffer[256]; + LPWSTR pwszModule; + ITypeInfo* pti; + + // If we can't find the path to the DLL, we can't register... + if (!FGetModuleFileName(v_hModule, &pwszModule)) + return E_FAIL; + + // Setup the CLSID. This is the most important. If there is a critical failure, + // we will set HR = GetLastError and return... + if ((dwret = RegCreateKeyEx(HKEY_CLASSES_ROOT, + "CLSID\\"DSOFRAMERCTL_CLSIDSTR, 0, NULL, 0, KEY_WRITE, NULL, &hk, NULL)) != ERROR_SUCCESS) + { + DsoMemFree(pwszModule); + return HRESULT_FROM_WIN32(dwret); + } + + lstrcpy(szbuffer, DSOFRAMERCTL_SHORTNAME); + RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + + // Setup the InprocServer32 key... + dwret = RegCreateKeyEx(hk, "InprocServer32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, "Apartment"); + RegSetValueEx(hk2, "ThreadingModel", 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + + // We call a wrapper function for this setting since the path should be + // stored in Unicode to handle non-ANSI file path names on some systems. + // This wrapper will convert the path to ANSI if we are running on Win9x. + // The rest of the Reg calls should be OK in ANSI since they do not + // contain non-ANSI/Unicode-specific characters... + if (!FSetRegKeyValue(hk2, pwszModule)) + hr = E_ACCESSDENIED; + + RegCloseKey(hk2); + + dwret = RegCreateKeyEx(hk, "ProgID", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, DSOFRAMERCTL_PROGID); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + + } + else hr = HRESULT_FROM_WIN32(dwret); + + if (SUCCEEDED(hr)) + { + dwret = RegCreateKeyEx(hk, "Control", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + RegCloseKey(hk2); + } + else hr = HRESULT_FROM_WIN32(dwret); + } + + + // If we succeeded so far, andle the remaining (non-critical) reg keys... + if (SUCCEEDED(hr)) + { + dwret = RegCreateKeyEx(hk, "ToolboxBitmap32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + LPWSTR pwszT = DsoCopyStringCat(pwszModule, L",102"); + if (pwszT) + { + FSetRegKeyValue(hk2, pwszT); + DsoMemFree(pwszT); + } + RegCloseKey(hk2); + } + + dwret = RegCreateKeyEx(hk, "TypeLib", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, DSOFRAMERCTL_TLIBSTR); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + + dwret = RegCreateKeyEx(hk, "Version", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, DSOFRAMERCTL_VERSIONSTR); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + + dwret = RegCreateKeyEx(hk, "MiscStatus", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, "131473"); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + + dwret = RegCreateKeyEx(hk, "DataFormats\\GetSet\\0", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); + if (dwret == ERROR_SUCCESS) + { + lstrcpy(szbuffer, "3,1,32,1"); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + } + + RegCloseKey(hk); + DsoMemFree(pwszModule); + + // This should catch any critical failures during setup of CLSID... + RETURN_ON_FAILURE(hr); + + // Setup the ProgID (non-critical)... + if (RegCreateKeyEx(HKEY_CLASSES_ROOT, DSOFRAMERCTL_PROGID, 0, + NULL, 0, KEY_WRITE, NULL, &hk, NULL) == ERROR_SUCCESS) + { + lstrcpy(szbuffer, DSOFRAMERCTL_FULLNAME); + RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + + if (RegCreateKeyEx(hk, "CLSID", 0, + NULL, 0, KEY_WRITE, NULL, &hk2, NULL) == ERROR_SUCCESS) + { + lstrcpy(szbuffer, DSOFRAMERCTL_CLSIDSTR); + RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); + RegCloseKey(hk2); + } + RegCloseKey(hk); + } + + // Load the type info (this should register the lib once)... + hr = DsoGetTypeInfoEx(LIBID_DSOFramer, 0, + DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, v_hModule, CLSID_FramerControl, &pti); + if (SUCCEEDED(hr)) pti->Release(); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// RegRecursiveDeleteKey +// +// Helper function called by DllUnregisterServer for nested key removal. +// +static HRESULT RegRecursiveDeleteKey(HKEY hkParent, LPCSTR pszSubKey) +{ + HRESULT hr = S_OK; + HKEY hk; + DWORD dwret, dwsize; + FILETIME time ; + CHAR szbuffer[512]; + + dwret = RegOpenKeyEx(hkParent, pszSubKey, 0, KEY_ALL_ACCESS, &hk); + if (dwret != ERROR_SUCCESS) + return HRESULT_FROM_WIN32(dwret); + + // Enumerate all of the decendents of this child... + dwsize = 510 ; + while (RegEnumKeyEx(hk, 0, szbuffer, &dwsize, NULL, NULL, NULL, &time) == ERROR_SUCCESS) + { + // If there are any sub-folders, delete them first (to make NT happy)... + hr = RegRecursiveDeleteKey(hk, szbuffer); + if (FAILED(hr)) break; + dwsize = 510; + } + + // Close the child... + RegCloseKey(hk); + + RETURN_ON_FAILURE(hr); + + // Delete this child. + dwret = RegDeleteKey(hkParent, pszSubKey); + if (dwret != ERROR_SUCCESS) + hr = HRESULT_FROM_WIN32(dwret); + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// DllUnregisterServer +// +// Removal code for the OCX. +// +STDAPI DllUnregisterServer() +{ + HRESULT hr; + hr = RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, "CLSID\\"DSOFRAMERCTL_CLSIDSTR); + if (SUCCEEDED(hr)) + { + RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, DSOFRAMERCTL_PROGID); + RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, "TypeLib\\"DSOFRAMERCTL_TLIBSTR); + } + + // This means the key does not exist (i.e., the DLL + // was alreay unregistered, so return OK)... + if (hr == 0x80070002) hr = S_OK; + + return hr; +} diff --git a/PROMS/DSOFRAMER/Source2005/rbbinder.h b/PROMS/DSOFRAMER/Source2005/rbbinder.h new file mode 100644 index 00000000..c312a2bb --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/rbbinder.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * RBBINDER.H + * + * DSOFramer: Internet Publishing Provider (MSDAIPP) Compatible Header + * + * Copyright ©1999-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. + * + ***************************************************************************/ +#ifndef DS_RBBINDER_H +#define DS_RBBINDER_H + +//////////////////////////////////////////////////////////////////////// +// The Microsoft OLEDB Provider for Internet Publishing (MSDAIPP) is now +// standard with MDAC 2.5. However, it will run with MDAC 2.1, so this +// header will allow us to safely compile without 2.5. +// +#define OLEDBVER 0x0250 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include // 2-byte structure packing + +#ifndef BEGIN_INTERFACE +#define BEGIN_INTERFACE +#endif + + +//////////////////////////////////////////////////////////////////////// +// MSDAIPP Specific GUIDs (not defined in OLEDB.H) +// +DEFINE_GUID(CLSID_MSDAIPP_DSO, 0xAF320921L, 0x9381, 0x11d1, 0x9C, 0x3C, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x61); +DEFINE_GUID(CLSID_MSDAIPP_BINDER, 0xE1D2BF40L, 0xA96B, 0x11d1, 0x9C, 0x6B, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x61); +DEFINE_GUID(DBPROPSET_MSDAIPP_INIT, 0x8F1033E3L, 0xB2CD, 0x11d1, 0x9C, 0x74, 0x00, 0x00, 0xF8, 0x75, 0xAC, 0x61); + + +//////////////////////////////////////////////////////////////////////// +// OLEDB Additional defines -- included for machines with MDAC 2.0/2.1 +// + +//////////////////////////////////////////////////////////////////////// +// OLEDB 2.5 GUIDS Redefined for use here; this is to avoid linker errors +// on machines that have different versions of MDAC libs. +// +DEFINE_GUID(IIDX_IBindResource, 0x0c733ab1L, 0x2a1c, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); +DEFINE_GUID(IIDX_IDBBinderProperties, 0x0c733ab3L, 0x2a1c, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); +DEFINE_GUID(IIDX_ICreateRow, 0x0c733ab2L, 0x2a1c, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); +DEFINE_GUID(IIDX_IAuthenticate, 0x79eac9d0L, 0xbaf9, 0x11ce, 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b); +DEFINE_GUID(DBGUIDX_STREAM, 0xc8b522f9L, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); + + +/////////////////////////////////////////////////////////////////////// +// MSDAIPP Binding Interfaces (all this should be standard in MDAC 2.5) +// +#ifndef __IBindResource_FWD_DEFINED__ +#define __IBindResource_FWD_DEFINED__ + +typedef interface IBindResource IBindResource; + +typedef DWORD DBBINDURLFLAG; +enum DBBINDURLFLAGENUM +{ + DBBINDURLFLAG_READ = 0x1L, + DBBINDURLFLAG_WRITE = 0x2L, + DBBINDURLFLAG_READWRITE = 0x3L, + DBBINDURLFLAG_SHARE_DENY_READ = 0x4L, + DBBINDURLFLAG_SHARE_DENY_WRITE = 0x8L, + DBBINDURLFLAG_SHARE_EXCLUSIVE = 0xcL, + DBBINDURLFLAG_SHARE_DENY_NONE = 0x10L, + DBBINDURLFLAG_ASYNCHRONOUS = 0x1000L, + DBBINDURLFLAG_COLLECTION = 0x2000L, + DBBINDURLFLAG_DELAYFETCHSTREAM = 0x4000L, + DBBINDURLFLAG_DELAYFETCHCOLUMNS = 0x8000L, + DBBINDURLFLAG_RECURSIVE = 0x400000L, + DBBINDURLFLAG_OUTPUT = 0x800000L, + DBBINDURLFLAG_WAITFORINIT = 0x1000000L, + DBBINDURLFLAG_OPENIFEXISTS = 0x2000000L, + DBBINDURLFLAG_OVERWRITE = 0x4000000L, + DBBINDURLFLAG_ISSTRUCTUREDDOCUMENT = 0x8000000L +}; + +typedef DWORD DBBINDURLSTATUS; +enum DBBINDURLSTATUSENUM +{ + DBBINDURLSTATUS_S_OK = 0L, + DBBINDURLSTATUS_S_DENYNOTSUPPORTED = 0x1L, + DBBINDURLSTATUS_S_DENYTYPENOTSUPPORTED = 0x4L, + DBBINDURLSTATUS_S_REDIRECTED = 0x8L +}; + +enum DBPROP_OLEDB25_RB +{ + DBPROP_INIT_BINDFLAGS = 0x10eL, + DBPROP_INIT_LOCKOWNER = 0x10fL +}; + +typedef ULONG DBCOUNTITEM; + +typedef struct tagDBIMPLICITSESSION + { + IUnknown __RPC_FAR *pUnkOuter; + IID __RPC_FAR *piid; + IUnknown __RPC_FAR *pSession; + } DBIMPLICITSESSION; + +#endif //__IBindResource_FWD_DEFINED__ + + +#ifndef __IBindResource_INTERFACE_DEFINED__ +#define __IBindResource_INTERFACE_DEFINED__ + +#undef INTERFACE +#define INTERFACE IBindResource +DECLARE_INTERFACE_(IBindResource, IUnknown) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +#endif + /* IBindResource methods */ + STDMETHOD(Bind)(THIS_ + /* [in] */ IUnknown __RPC_FAR *pUnkOuter, + /* [in] */ LPCOLESTR pwszURL, + /* [in] */ DBBINDURLFLAG dwBindURLFlags, + /* [in] */ REFGUID rguid, + /* [in] */ REFIID riid, + /* [in] */ IAuthenticate __RPC_FAR *pAuthenticate, + /* [unique][out][in] */ DBIMPLICITSESSION __RPC_FAR *pImplSession, + /* [unique][out][in] */ DBBINDURLSTATUS __RPC_FAR *pdwBindStatus, + /* [iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) PURE; +}; + +#endif //__IBindResource_INTERFACE_DEFINED__ + + + +#ifndef __ICreateRow_INTERFACE_DEFINED__ +#define __ICreateRow_INTERFACE_DEFINED__ + +#undef INTERFACE +#define INTERFACE ICreateRow +DECLARE_INTERFACE_(ICreateRow, IUnknown) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +#endif + /* ICreateRow methods */ + STDMETHOD(CreateRow)(THIS_ + /* [unique][in] */ IUnknown __RPC_FAR *pUnkOuter, + /* [in] */ LPCOLESTR pwszURL, + /* [in] */ DBBINDURLFLAG dwBindURLFlags, + /* [in] */ REFGUID rguid, + /* [in] */ REFIID riid, + /* [unique][in] */ IAuthenticate __RPC_FAR *pAuthenticate, + /* [unique][out][in] */ IUnknown __RPC_FAR *pImplSession, + /* [unique][out][in] */ DBBINDURLSTATUS __RPC_FAR *pdwBindStatus, + /* [out] */ LPOLESTR __RPC_FAR *ppwszNewURL, + /* [iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) PURE; +}; + +#endif //__ICreateRow_INTERFACE_DEFINED__ + + +#ifndef __IDBBinderProperties_INTERFACE_DEFINED__ +#define __IDBBinderProperties_INTERFACE_DEFINED__ + +#undef INTERFACE +#define INTERFACE IDBBinderProperties +DECLARE_INTERFACE_(IDBBinderProperties, IDBProperties) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + /* IDBProperties methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + STDMETHOD(GetProperties)(THIS_ ULONG cPropertyIDSets, const DBPROPIDSET __RPC_FAR rgPropertyIDSets[], ULONG __RPC_FAR *pcPropertySets, DBPROPSET __RPC_FAR *__RPC_FAR *prgPropertySets) PURE; + STDMETHOD(GetPropertyInfo)(THIS_ ULONG cPropertyIDSets, const DBPROPIDSET __RPC_FAR rgPropertyIDSets[], ULONG __RPC_FAR *pcPropertyInfoSets, DBPROPINFOSET __RPC_FAR *__RPC_FAR *prgPropertyInfoSets, OLECHAR __RPC_FAR *__RPC_FAR *ppDescBuffer) PURE; + STDMETHOD(SetProperties)(THIS_ ULONG cPropertySets, DBPROPSET __RPC_FAR rgPropertySets[]) PURE; +#endif + /* IDBBinderProperties methods */ + STDMETHOD(Reset)(THIS) PURE; +}; + +#endif //__IDBBinderProperties_INTERFACE_DEFINED__ + + +//////////////////////////////////////////////////////////////////////// +// IAuthenticate (borrowed from urlmon.h to avoid extra includes) +// +#ifndef __IAuthenticate_INTERFACE_DEFINED__ +#define __IAuthenticate_INTERFACE_DEFINED__ + +#undef INTERFACE +#define INTERFACE IAuthenticate +DECLARE_INTERFACE_(IAuthenticate, IUnknown) +{ +BEGIN_INTERFACE +#ifndef NO_BASEINTERFACE_FUNCS + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +#endif + /* IAuthenticate methods */ + STDMETHOD(Authenticate)(THIS_ HWND __RPC_FAR *phwnd, LPWSTR __RPC_FAR *pszUsername, LPWSTR __RPC_FAR *pszPassword) PURE; +}; + +#endif //__IAuthenticate_INTERFACE_DEFINED__ + +//OLEDB 2.1 Error values +#ifndef DB_E_READONLY +#define DB_E_READONLY ((HRESULT)0x80040E94L) +#define DB_E_RESOURCELOCKED ((HRESULT)0x80040E92L) +#define DB_E_CANNOTCONNECT ((HRESULT)0x80040E96L) +#define DB_E_TIMEOUT ((HRESULT)0x80040E97L) +#define DB_E_RESOURCEEXISTS ((HRESULT)0x80040E98L) +#define DB_E_OUTOFSPACE ((HRESULT)0x80040E9AL) +#endif + +//OLEDB 2.5 Error values +#ifndef DB_SEC_E_SAFEMODE_DENIED +#define DB_SEC_E_SAFEMODE_DENIED ((HRESULT)0x80040E9BL) +#endif + +#ifdef __cplusplus +} //extern "C" +#endif + +#endif // DS_RBBINDER_H + diff --git a/PROMS/DSOFRAMER/Source2005/utilities.cpp b/PROMS/DSOFRAMER/Source2005/utilities.cpp new file mode 100644 index 00000000..9b34cdf1 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/utilities.cpp @@ -0,0 +1,1359 @@ +/*************************************************************************** + * UTILITIES.CPP + * + * Shared helper functions and routines. + * + * Copyright ©1999-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" + +//////////////////////////////////////////////////////////////////////// +// Core Utility Functions +// +//////////////////////////////////////////////////////////////////////// +// Heap Allocation (Private Heap) +// +extern HANDLE v_hPrivateHeap; +STDAPI_(LPVOID) DsoMemAlloc(DWORD cbSize) +{ + CHECK_NULL_RETURN(v_hPrivateHeap, NULL); + return HeapAlloc(v_hPrivateHeap, HEAP_ZERO_MEMORY, cbSize); +} + +STDAPI_(void) DsoMemFree(LPVOID ptr) +{ + if ((v_hPrivateHeap) && (ptr)) + HeapFree(v_hPrivateHeap, 0, ptr); +} + +void * _cdecl operator new(size_t size){ return DsoMemAlloc(size);} +void _cdecl operator delete(void *ptr){ DsoMemFree(ptr); } +int __cdecl _purecall(){__asm{int 3}; return 0;} + +//////////////////////////////////////////////////////////////////////// +// Global String Functions +// +//////////////////////////////////////////////////////////////////////// +// DsoConvertToUnicodeEx +// +STDAPI DsoConvertToUnicodeEx(LPCSTR pszMbcsString, DWORD cbMbcsLen, LPWSTR pwszUnicode, DWORD cbUniLen, UINT uiCodePage) +{ + DWORD cbRet; + UINT iCode = CP_ACP; + + if (IsValidCodePage(uiCodePage)) + iCode = uiCodePage; + + CHECK_NULL_RETURN(pwszUnicode, E_POINTER); + pwszUnicode[0] = L'\0'; + + CHECK_NULL_RETURN(pszMbcsString, E_POINTER); + CHECK_NULL_RETURN(cbMbcsLen, E_INVALIDARG); + CHECK_NULL_RETURN(cbUniLen, E_INVALIDARG); + + cbRet = MultiByteToWideChar(iCode, 0, pszMbcsString, cbMbcsLen, pwszUnicode, cbUniLen); + if (cbRet == 0) return E_WIN32_LASTERROR; + + pwszUnicode[cbRet] = L'\0'; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// DsoConvertToMBCSEx +// +STDAPI DsoConvertToMBCSEx(LPCWSTR pwszUnicodeString, DWORD cbUniLen, LPSTR pszMbcsString, DWORD cbMbcsLen, UINT uiCodePage) +{ + DWORD cbRet; + UINT iCode = CP_ACP; + + if (IsValidCodePage(uiCodePage)) + iCode = uiCodePage; + + CHECK_NULL_RETURN(pszMbcsString, E_POINTER); + pszMbcsString[0] = L'\0'; + + CHECK_NULL_RETURN(pwszUnicodeString, E_POINTER); + CHECK_NULL_RETURN(cbMbcsLen, E_INVALIDARG); + CHECK_NULL_RETURN(cbUniLen, E_INVALIDARG); + + cbRet = WideCharToMultiByte(iCode, 0, pwszUnicodeString, -1, pszMbcsString, cbMbcsLen, NULL, NULL); + if (cbRet == 0) return E_WIN32_LASTERROR; + + pszMbcsString[cbRet] = '\0'; + return S_OK; +} + +//////////////////////////////////////////////////////////////////////// +// DsoConvertToLPWSTR +// +// Takes a MBCS string and returns a LPWSTR allocated on private heap. +// +STDAPI_(LPWSTR) DsoConvertToLPWSTR(LPCSTR pszMbcsString) +{ + LPWSTR pwsz = NULL; + UINT cblen, cbnew; + + if ((pszMbcsString) && + ((cblen = lstrlen(pszMbcsString)) > 0)) + { + cbnew = ((cblen + 1) * sizeof(WCHAR)); + if ((pwsz = (LPWSTR)DsoMemAlloc(cbnew)) != NULL) + { + if (FAILED(DsoConvertToUnicodeEx(pszMbcsString, cblen, pwsz, cbnew, GetACP()))) + { + DsoMemFree(pwsz); + pwsz = NULL; + } + } + } + + return pwsz; +} +//////////////////////////////////////////////////////////////////////// +// DsoConvertToMBCS +// +// Takes a WCHAR string and returns a LPSTR on the private heap. +// +STDAPI_(LPSTR) DsoConvertToMBCS(LPCWSTR pwszUnicodeString) +{ + LPSTR psz = NULL; + UINT cblen, cbnew; + + if ((pwszUnicodeString) && + ((cblen = lstrlenW(pwszUnicodeString)) > 0)) + { + cbnew = ((cblen + 1) * sizeof(WCHAR)); + if ((psz = (LPSTR)DsoMemAlloc(cbnew)) != NULL) + { + if (FAILED(DsoConvertToMBCSEx(pwszUnicodeString, cblen, psz, cbnew, GetACP()))) + { + DsoMemFree(psz); psz = NULL; + } + } + } + + return psz; +} + +//////////////////////////////////////////////////////////////////////// +// DsoConvertToBSTR +// +// Takes a MBCS string and returns a BSTR. NULL is returned if the +// function fails or the string is empty. +// +STDAPI_(BSTR) DsoConvertToBSTR(LPCSTR pszMbcsString) +{ + BSTR bstr = NULL; + LPWSTR pwsz = DsoConvertToLPWSTR(pszMbcsString); + if (pwsz) + { + bstr = SysAllocString(pwsz); + DsoMemFree(pwsz); + } + return bstr; +} + +//////////////////////////////////////////////////////////////////////// +// DsoConvertToLPOLESTR +// +// Returns Unicode string in COM Task Memory (CoTaskMemAlloc). +// +STDAPI_(LPWSTR) DsoConvertToLPOLESTR(LPCWSTR pwszUnicodeString) +{ + LPWSTR pwsz; + UINT cblen; + + CHECK_NULL_RETURN(pwszUnicodeString, NULL); + cblen = lstrlenW(pwszUnicodeString); + + pwsz = (LPWSTR)CoTaskMemAlloc((cblen * sizeof(WCHAR)) + 2); + if (pwsz) + { + memcpy(pwsz, pwszUnicodeString, (cblen * sizeof(WCHAR))); + pwsz[cblen] = L'\0'; // Make sure it is NULL terminated. + } + + return pwsz; +} + +//////////////////////////////////////////////////////////////////////// +// DsoCopyString +// +// Duplicates the string into private heap string. +// +STDAPI_(LPWSTR) DsoCopyString(LPCWSTR pwszString) +{ + LPWSTR pwsz; + UINT cblen; + + CHECK_NULL_RETURN(pwszString, NULL); + cblen = lstrlenW(pwszString); + + pwsz = (LPWSTR)DsoMemAlloc((cblen * sizeof(WCHAR)) + 2); + if (pwsz) + { + memcpy(pwsz, pwszString, (cblen * sizeof(WCHAR))); + pwsz[cblen] = L'\0'; // Make sure it is NULL terminated. + } + + return pwsz; +} + +//////////////////////////////////////////////////////////////////////// +// DsoCopyStringCat +// +STDAPI_(LPWSTR) DsoCopyStringCat(LPCWSTR pwszString1, LPCWSTR pwszString2) +{return DsoCopyStringCatEx(pwszString1, 1, &pwszString2);} + +//////////////////////////////////////////////////////////////////////// +// DsoCopyStringCatEx +// +// Duplicates the string into private heap string and appends one or more +// strings to the end (concatenation). +// +STDAPI_(LPWSTR) DsoCopyStringCatEx(LPCWSTR pwszBaseString, UINT cStrs, LPCWSTR *ppwszStrs) +{ + LPWSTR pwsz; + UINT i, cblenb, cblent; + UINT *pcblens; + + // We assume you have a base string to start with. If not, we return NULL... + if ((pwszBaseString == NULL) || + ((cblenb = lstrlenW(pwszBaseString)) < 1)) + return NULL; + + // If we have nothing to append, just do a plain copy... + if ((cStrs == 0) || (ppwszStrs == NULL)) + return DsoCopyString(pwszBaseString); + + // Determine the size of the final string by finding the lengths + // of each. We create an array of sizes to use later on... + cblent = cblenb; + pcblens = new UINT[cStrs]; + CHECK_NULL_RETURN(pcblens, NULL); + + for (i = 0; i < cStrs; i++) + { + pcblens[i] = lstrlenW(ppwszStrs[i]); + cblent += pcblens[i]; + } + + // If we have data to append, create the new string and append the + // data by copying them in place. We expect UTF-16 Unicode strings + // for this to work, but this should be normal... + if (cblent > cblenb) + { + pwsz = (LPWSTR)DsoMemAlloc(((cblent + 1) * sizeof(WCHAR))); + CHECK_NULL_RETURN(pwsz, NULL); + + memcpy(pwsz, pwszBaseString, (cblenb * sizeof(WCHAR))); + cblent = cblenb; + + for (i = 0; i < cStrs; i++) + { + memcpy((pwsz + cblent), ppwszStrs[i], (pcblens[i] * sizeof(WCHAR))); + cblent += pcblens[i]; + } + } + else pwsz = DsoCopyString(pwszBaseString); + + delete [] pcblens; + return pwsz; +} + +//////////////////////////////////////////////////////////////////////// +// DsoCLSIDtoLPSTR +// +STDAPI_(LPSTR) DsoCLSIDtoLPSTR(REFCLSID clsid) +{ + LPSTR psz = NULL; + LPWSTR pwsz; + if (SUCCEEDED(StringFromCLSID(clsid, &pwsz))) + { + psz = DsoConvertToMBCS(pwsz); + CoTaskMemFree(pwsz); + } + return psz; +} + + +/////////////////////////////////////////////////////////////////////////////////// +// DsoCompareStringsEx +// +// Calls CompareString API using Unicode version (if available on OS). Otherwise, +// we have to thunk strings down to MBCS to compare. This is fairly inefficient for +// Win9x systems that don't handle Unicode, but hey...this is only a sample. +// +STDAPI_(UINT) DsoCompareStringsEx(LPCWSTR pwsz1, INT cch1, LPCWSTR pwsz2, INT cch2) +{ + UINT iret; + LCID lcid = GetThreadLocale(); + UINT cblen1, cblen2; + + // Check that valid parameters are passed and then contain somethimg... + if ((pwsz1 == NULL) || (cch1 == 0) || + ((cblen1 = ((cch1 > 0) ? cch1 : lstrlenW(pwsz1))) == 0)) + return CSTR_LESS_THAN; + + if ((pwsz2 == NULL) || (cch2 == 0) || + ((cblen2 = ((cch2 > 0) ? cch2 : lstrlenW(pwsz2))) == 0)) + return CSTR_GREATER_THAN; + + // If the string is of the same size, then we do quick compare to test for + // equality (this is slightly faster than calling the API, but only if we + // expect the calls to find an equal match)... + if (cblen1 == cblen2) + { + for (iret = 0; iret < cblen1; iret++) + { + if (pwsz1[iret] == pwsz2[iret]) + continue; + + if (((pwsz1[iret] >= 'A') && (pwsz1[iret] <= 'Z')) && + ((pwsz1[iret] + ('a' - 'A')) == pwsz2[iret])) + continue; + + if (((pwsz2[iret] >= 'A') && (pwsz2[iret] <= 'Z')) && + ((pwsz2[iret] + ('a' - 'A')) == pwsz1[iret])) + continue; + + break; // don't continue if we can't quickly match... + } + + // If we made it all the way, then they are equal... + if (iret == cblen1) + return CSTR_EQUAL; + } + + // Now ask the OS to check the strings and give us its read. (We prefer checking + // in Unicode since this is faster and we may have strings that can't be thunked + // down to the local ANSI code page)... + if (v_fUnicodeAPI) + { + iret = CompareStringW(lcid, NORM_IGNORECASE | NORM_IGNOREWIDTH, pwsz1, cblen1, pwsz2, cblen2); + } + else + { + // If we are on Win9x, we don't have much of choice (thunk the call)... + LPSTR psz1 = DsoConvertToMBCS(pwsz1); + LPSTR psz2 = DsoConvertToMBCS(pwsz2); + iret = CompareStringA(lcid, NORM_IGNORECASE, psz1, -1, psz2, -1); + DsoMemFree(psz2); + DsoMemFree(psz1); + } + + return iret; +} + + +//////////////////////////////////////////////////////////////////////// +// URL Helpers +// +//////////////////////////////////////////////////////////////////////// +// General Functions (checks to see if we can recognize type) +// +STDAPI_(BOOL) LooksLikeUNC(LPCWSTR pwsz) +{ + return ((pwsz) && (*pwsz == L'\\') && (*(pwsz + 1) == L'\\') && (*(pwsz + 2) != L'\\')); +} + +STDAPI_(BOOL) LooksLikeLocalFile(LPCWSTR pwsz) +{ + return ((pwsz) && + (((*pwsz > 64) && (*pwsz < 91)) || ((*pwsz > 96) && (*pwsz < 123))) && + (*(pwsz + 1) == L':') && (*(pwsz + 2) == L'\\')); +} + +STDAPI_(BOOL) LooksLikeHTTP(LPCWSTR pwsz) +{ + return ((pwsz) && ((*pwsz == L'H') || (*pwsz == L'h')) && + ((*(pwsz + 1) == L'T') || (*(pwsz + 1) == L't')) && + ((*(pwsz + 2) == L'T') || (*(pwsz + 2) == L't')) && + ((*(pwsz + 3) == L'P') || (*(pwsz + 3) == L'p')) && + ((*(pwsz + 4) == L':') || (((*(pwsz + 4) == L'S') || (*(pwsz + 4) == L's')) && (*(pwsz + 5) == L':')))); +} + +//////////////////////////////////////////////////////////////////////// +// GetTempPathForURLDownload +// +// Constructs a temp path for a downloaded file. Note we scan the URL +// to find the name of the file so we can use its exention for server +// association (in case it is a non-docfile -- like RTF) and also +// create our own subfolder to try and avoid name conflicts in temp +// folder itself. +// +STDAPI_(BOOL) GetTempPathForURLDownload(WCHAR* pwszURL, WCHAR** ppwszLocalFile) +{ + DWORD dw; + LPWSTR pwszTPath = NULL; + LPWSTR pwszTFile = NULL; + CHAR szTmpPath[MAX_PATH]; + + // Do a little parameter checking and find length of the URL... + if (!(pwszURL) || ((dw = lstrlenW(pwszURL)) < 6) || + !(LooksLikeHTTP(pwszURL)) || !(ppwszLocalFile)) + return FALSE; + + *ppwszLocalFile = NULL; + + if (GetTempPath(MAX_PATH, szTmpPath)) + { + DWORD dwtlen = lstrlen(szTmpPath); + if (dwtlen > 0 && szTmpPath[dwtlen-1] != '\\') + lstrcat(szTmpPath, "\\"); + + lstrcat(szTmpPath, "DsoFramer"); + + if (CreateDirectory(szTmpPath, NULL) || GetLastError() == ERROR_ALREADY_EXISTS) + { + lstrcat(szTmpPath, "\\"); + pwszTPath = DsoConvertToLPWSTR(szTmpPath); + } + } + + if (pwszTPath) + { + if (pwszTFile = DsoCopyString(pwszURL)) + { + LPWSTR pwszT = pwszTFile; + while (*(++pwszT)) + if (*pwszT == L'?'){*pwszT = L'\0'; break;} + + while (*(--pwszT)) + if (*pwszT == L'/'){++pwszT; break;} + + *ppwszLocalFile = DsoCopyStringCat(pwszTPath, pwszT); + + DsoMemFree(pwszTFile); + } + + DsoMemFree(pwszTPath); + } + + return (BOOL)(*ppwszLocalFile); +} + +//////////////////////////////////////////////////////////////////////// +// URLDownloadFile +// +// Does a simple URLMON download of file (no save back to server allowed), +// and no dependent files will be downloaded (just one temp file). +// +STDAPI URLDownloadFile(LPUNKNOWN punk, WCHAR* pwszURL, WCHAR* pwszLocalFile) +{ + typedef HRESULT (WINAPI *PFN_URLDTFW)(LPUNKNOWN, LPCWSTR, LPCWSTR, DWORD, LPUNKNOWN); + static PFN_URLDTFW pfnURLDownloadToFileW = NULL; + HMODULE hUrlmon; + + if (pfnURLDownloadToFileW == NULL) + { + if (hUrlmon = LoadLibrary("URLMON.DLL")) + pfnURLDownloadToFileW = (PFN_URLDTFW)GetProcAddress(hUrlmon, "URLDownloadToFileW"); + } + + if (pfnURLDownloadToFileW == NULL) + return E_UNEXPECTED; + + return pfnURLDownloadToFileW(punk, pwszURL, pwszLocalFile, 0, NULL); +} + + +//////////////////////////////////////////////////////////////////////// +// OLE Conversion Functions +// +#define HIMETRIC_PER_INCH 2540 // number HIMETRIC units per inch +#define PTS_PER_INCH 72 // number points (font size) per inch + +#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) +#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH) + +//////////////////////////////////////////////////////////////////////// +// DsoHimetricToPixels +// +STDAPI_(void) DsoHimetricToPixels(LONG* px, LONG* py) +{ + HDC hdc = GetDC(NULL); + if (px) *px = MAP_LOGHIM_TO_PIX(*px, GetDeviceCaps(hdc, LOGPIXELSX)); + if (py) *py = MAP_LOGHIM_TO_PIX(*py, GetDeviceCaps(hdc, LOGPIXELSY)); + ReleaseDC(NULL, hdc); +} + +//////////////////////////////////////////////////////////////////////// +// DsoPixelsToHimetric +// +STDAPI_(void) DsoPixelsToHimetric(LONG* px, LONG* py) +{ + HDC hdc = GetDC(NULL); + if (px) *px = MAP_PIX_TO_LOGHIM(*px, GetDeviceCaps(hdc, LOGPIXELSX)); + if (py) *py = MAP_PIX_TO_LOGHIM(*py, GetDeviceCaps(hdc, LOGPIXELSY)); + ReleaseDC(NULL, hdc); +} + +//////////////////////////////////////////////////////////////////////// +// GDI Helper Functions +// +STDAPI_(HBITMAP) DsoGetBitmapFromWindow(HWND hwnd) +{ + HBITMAP hbmpold, hbmp = NULL; + HDC hdcWin, hdcMem; + RECT rc; + INT x, y; + + if (!GetWindowRect(hwnd, &rc)) + return NULL; + + x = (rc.right - rc.left); if (x < 0) x = 1; + y = (rc.bottom - rc.top); if (y < 0) y = 1; + + hdcWin = GetDC(hwnd); + hdcMem = CreateCompatibleDC(hdcWin); + + hbmp = CreateCompatibleBitmap(hdcWin, x, y); + hbmpold = (HBITMAP)SelectObject(hdcMem, hbmp); + + BitBlt(hdcMem, 0,0, x, y, hdcWin, 0,0, SRCCOPY); + + SelectObject(hdcMem, hbmpold); + DeleteDC(hdcMem); + ReleaseDC(hwnd, hdcWin); + + return hbmp; +} + +//////////////////////////////////////////////////////////////////////// +// Windows Helper Functions +// +STDAPI_(BOOL) IsWindowChild(HWND hwndParent, HWND hwndChild) +{ + HWND hwnd; + + if ((hwndChild == NULL) || !IsWindow(hwndChild)) + return FALSE; + + if (hwndParent == NULL) + return TRUE; + + if (!IsWindow(hwndParent)) + return FALSE; + + hwnd = hwndChild; + + while (hwnd = GetParent(hwnd)) + if (hwnd == hwndParent) + return TRUE; + + return FALSE; +} + +//////////////////////////////////////////////////////////////////////// +// DsoGetTypeInfoEx +// +// Gets an ITypeInfo from the LIBID specified. Optionally can load and +// register the typelib from a module resource (if specified). Used to +// load our typelib on demand. +// +STDAPI DsoGetTypeInfoEx(REFGUID rlibid, LCID lcid, WORD wVerMaj, WORD wVerMin, HMODULE hResource, REFGUID rguid, ITypeInfo** ppti) +{ + HRESULT hr; + ITypeLib* ptlib; + + CHECK_NULL_RETURN(ppti, E_POINTER); + *ppti = NULL; + + // Try to pull information from the registry... + hr = LoadRegTypeLib(rlibid, wVerMaj, wVerMin, lcid, &ptlib); + + // If that failed, and we have a resource module to load from, + // try loading it from the module... + if (FAILED(hr) && (hResource)) + { + LPWSTR pwszPath; + if (FGetModuleFileName(hResource, &pwszPath)) + { + // Now, load the type library from module resource file... + hr = LoadTypeLib(pwszPath, &ptlib); + + // Register library to make things easier next time... + if (SUCCEEDED(hr)) + RegisterTypeLib(ptlib, pwszPath, NULL); + + DsoMemFree(pwszPath); + } + } + + // We have the typelib. Now get the requested typeinfo... + if (SUCCEEDED(hr)) + hr = ptlib->GetTypeInfoOfGuid(rguid, ppti); + + // Release the type library interface. + SAFE_RELEASE_INTERFACE(ptlib); + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// DsoDispatchInvoke +// +// Wrapper for IDispatch::Invoke calls to event sinks, or late bound call +// to embedded object to get ambient property. +// +STDAPI DsoDispatchInvoke(LPDISPATCH pdisp, LPOLESTR pwszname, DISPID dspid, WORD wflags, DWORD cargs, VARIANT* rgargs, VARIANT* pvtret) +{ + HRESULT hr = S_FALSE; + DISPID dspidPut = DISPID_PROPERTYPUT; + DISPPARAMS dspparm = {NULL, NULL, 0, 0}; + + CHECK_NULL_RETURN(pdisp, E_POINTER); + + dspparm.rgvarg = rgargs; + dspparm.cArgs = cargs; + + if ((wflags & DISPATCH_PROPERTYPUT) || (wflags & DISPATCH_PROPERTYPUTREF)) + { + dspparm.rgdispidNamedArgs = &dspidPut; + dspparm.cNamedArgs = 1; + } + + SEH_TRY + + if (pwszname) + hr = pdisp->GetIDsOfNames(IID_NULL, &pwszname, 1, LOCALE_USER_DEFAULT, &dspid); + + if (SUCCEEDED(hr)) + hr = pdisp->Invoke(dspid, IID_NULL, LOCALE_USER_DEFAULT, (WORD)(DISPATCH_METHOD | wflags), &dspparm, pvtret, NULL, NULL); + + SEH_EXCEPT(hr) + + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// DsoReportError -- Report Error for both ComThreadError and DispError. +// +STDAPI DsoReportError(HRESULT hr, LPWSTR pwszCustomMessage, EXCEPINFO* peiDispEx) +{ + BSTR bstrSource, bstrDescription; + ICreateErrorInfo* pcerrinfo; + IErrorInfo* perrinfo; + CHAR szError[MAX_PATH]; + UINT nID = 0; + + // Don't need to do anything unless this is an error. + if ((hr == S_OK) || SUCCEEDED(hr)) return hr; + + // Is this one of our custom errors (if so we will pull description from resource)... + if ((hr > DSO_E_ERR_BASE) && (hr < DSO_E_ERR_MAX)) + nID = (hr & 0xFF); + + // Set the source name... + bstrSource = SysAllocString(L"DsoFramerControl"); + + // Set the error description... + if (pwszCustomMessage) + { + bstrDescription = SysAllocString(pwszCustomMessage); + } + else if (((nID) && LoadString(v_hModule, nID, szError, sizeof(szError))) || + (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szError, sizeof(szError), NULL))) + { + bstrDescription = DsoConvertToBSTR(szError); + } + else bstrDescription = NULL; + + // Set ErrorInfo so that vtable clients can get rich error information... + if (SUCCEEDED(CreateErrorInfo(&pcerrinfo))) + { + pcerrinfo->SetSource(bstrSource); + pcerrinfo->SetDescription(bstrDescription); + + if (SUCCEEDED(pcerrinfo->QueryInterface(IID_IErrorInfo, (void**) &perrinfo))) + { + SetErrorInfo(0, perrinfo); + perrinfo->Release(); + } + pcerrinfo->Release(); + } + + // Fill-in DispException Structure for late-boud clients... + if (peiDispEx) + { + peiDispEx->scode = hr; + peiDispEx->bstrSource = SysAllocString(bstrSource); + peiDispEx->bstrDescription = SysAllocString(bstrDescription); + } + + // Free temp strings... + SAFE_FREEBSTR(bstrDescription); + SAFE_FREEBSTR(bstrSource); + + // We always return error passed (so caller can chain this in return call). + return hr; +} + +//////////////////////////////////////////////////////////////////////// +// Variant Type Helpers (Fast Access to Variant Data) +// +VARIANT* __fastcall DsoPVarFromPVarRef(VARIANT* px) +{return ((px->vt == (VT_VARIANT|VT_BYREF)) ? (px->pvarVal) : px);} + +BOOL __fastcall DsoIsVarParamMissing(VARIANT* px) +{return ((px->vt == VT_EMPTY) || ((px->vt & VT_ERROR) == VT_ERROR));} + +LPWSTR __fastcall DsoPVarWStrFromPVar(VARIANT* px) +{return ((px->vt == VT_BSTR) ? px->bstrVal : ((px->vt == (VT_BSTR|VT_BYREF)) ? *(px->pbstrVal) : NULL));} + +SAFEARRAY* __fastcall DsoPVarArrayFromPVar(VARIANT* px) +{return (((px->vt & (VT_BYREF|VT_ARRAY)) == (VT_BYREF|VT_ARRAY)) ? *(px->pparray) : (((px->vt & VT_ARRAY) == VT_ARRAY) ? px->parray : NULL));} + +IUnknown* __fastcall DsoPVarUnkFromPVar(VARIANT* px) +{return (((px->vt == VT_DISPATCH) || (px->vt == VT_UNKNOWN)) ? px->punkVal : (((px->vt == (VT_DISPATCH|VT_BYREF)) || (px->vt == (VT_UNKNOWN|VT_BYREF))) ? *(px->ppunkVal) : NULL));} + +SHORT __fastcall DsoPVarShortFromPVar(VARIANT* px, SHORT fdef) +{return (((px->vt & 0xFF) != VT_I2) ? fdef : ((px->vt & VT_BYREF) == VT_BYREF) ? *(px->piVal) : px->iVal);} + +LONG __fastcall DsoPVarLongFromPVar(VARIANT* px, LONG fdef) +{return (((px->vt & 0xFF) != VT_I4) ? (LONG)DsoPVarShortFromPVar(px, (SHORT)fdef) : ((px->vt & VT_BYREF) == VT_BYREF) ? *(px->plVal) : px->lVal);} + +BOOL __fastcall DsoPVarBoolFromPVar(VARIANT* px, BOOL fdef) +{return (((px->vt & 0xFF) != VT_BOOL) ? (BOOL)DsoPVarLongFromPVar(px, (LONG)fdef) : ((px->vt & VT_BYREF) == VT_BYREF) ? (BOOL)(*(px->pboolVal)) : (BOOL)(px->boolVal));} + + +//////////////////////////////////////////////////////////////////////// +// Win32 Unicode API wrappers +// +// This project is not compiled to Unicode in order for it to run on Win9x +// machines. However, in order to try to keep the code language/locale neutral +// we use these wrappers to call the Unicode API functions when supported, +// and thunk down strings to local code page if must run MBCS API. +// + +//////////////////////////////////////////////////////////////////////// +// FFileExists +// +// Returns TRUE if the given file exists. Does not handle URLs. +// +STDAPI_(BOOL) FFileExists(WCHAR* wzPath) +{ + DWORD dw = 0xFFFFFFFF; + if (v_fUnicodeAPI) + { + dw = GetFileAttributesW(wzPath); + } + else + { + LPSTR psz = DsoConvertToMBCS(wzPath); + if (psz) dw = GetFileAttributesA(psz); + DsoMemFree(psz); + } + return (dw != 0xFFFFFFFF); +} + +//////////////////////////////////////////////////////////////////////// +// FOpenLocalFile +// +// Returns TRUE if the file can be opened with the access required. +// Use the handle for ReadFile/WriteFile operations as normal. +// +STDAPI_(BOOL) FOpenLocalFile(WCHAR* wzFilePath, DWORD dwAccess, DWORD dwShareMode, DWORD dwCreate, HANDLE* phFile) +{ + CHECK_NULL_RETURN(phFile, FALSE); + *phFile = INVALID_HANDLE_VALUE; + if (v_fUnicodeAPI) + { + *phFile = CreateFileW(wzFilePath, dwAccess, dwShareMode, NULL, dwCreate, FILE_ATTRIBUTE_NORMAL, NULL); + } + else + { + LPSTR psz = DsoConvertToMBCS(wzFilePath); + if (psz) *phFile = CreateFileA(psz, dwAccess, dwShareMode, NULL, dwCreate, FILE_ATTRIBUTE_NORMAL, NULL); + DsoMemFree(psz); + } + return (*phFile != INVALID_HANDLE_VALUE); +} + + +//////////////////////////////////////////////////////////////////////// +// FPerformShellOp +// +// This function started as a wrapper for SHFileOperation, but that +// shell function had an enormous performance hit, especially on Win9x +// and NT4. To speed things up we removed the shell32 call and are +// using the kernel32 APIs instead. The only drawback is we can't +// handle multiple files, but that is not critical for this project. +// +STDAPI_(BOOL) FPerformShellOp(DWORD dwOp, WCHAR* wzFrom, WCHAR* wzTo) +{ + BOOL f = FALSE; + if (v_fUnicodeAPI) + { + switch (dwOp) + { + case FO_COPY: f = CopyFileW(wzFrom, wzTo, FALSE); break; + case FO_MOVE: + case FO_RENAME: f = MoveFileW(wzFrom, wzTo); break; + case FO_DELETE: f = DeleteFileW(wzFrom); break; + } + } + else + { + LPSTR pszFrom = DsoConvertToMBCS(wzFrom); + LPSTR pszTo = DsoConvertToMBCS(wzTo); + + switch (dwOp) + { + case FO_COPY: f = CopyFileA(pszFrom, pszTo, FALSE); break; + case FO_MOVE: + case FO_RENAME: f = MoveFileA(pszFrom, pszTo); break; + case FO_DELETE: f = DeleteFileA(pszFrom); break; + } + + if (pszFrom) DsoMemFree(pszFrom); + if (pszTo) DsoMemFree(pszTo); + } + + return f; +} + +//////////////////////////////////////////////////////////////////////// +// FGetModuleFileName +// +// Handles Unicode/ANSI paths from a module handle. +// +STDAPI_(BOOL) FGetModuleFileName(HMODULE hModule, WCHAR** wzFileName) +{ + LPWSTR pwsz; + DWORD dw; + + CHECK_NULL_RETURN(wzFileName, FALSE); + *wzFileName = NULL; + + pwsz = (LPWSTR)DsoMemAlloc((MAX_PATH * sizeof(WCHAR))); + CHECK_NULL_RETURN(pwsz, FALSE); + + if (v_fUnicodeAPI) + { + dw = GetModuleFileNameW(hModule, pwsz, MAX_PATH); + if (dw == 0) + { + DsoMemFree(pwsz); + return FALSE; + } + } + else + { + dw = GetModuleFileNameA(hModule, (LPSTR)pwsz, MAX_PATH); + if (dw == 0) + { + DsoMemFree(pwsz); + return FALSE; + } + + LPWSTR pwsz2 = DsoConvertToLPWSTR((LPSTR)pwsz); + if (pwsz2 == NULL) + { + DsoMemFree(pwsz); + return FALSE; + } + + DsoMemFree(pwsz); + pwsz = pwsz2; + } + + *wzFileName = pwsz; + return TRUE; +} + + +//////////////////////////////////////////////////////////////////////// +// FIsIECacheFile +// +// Determines if file came from IE Cache (treat as read-only). +// +STDAPI_(BOOL) FIsIECacheFile(LPWSTR pwszFile) +{ + BOOL fIsCacheFile = FALSE; + LPWSTR pwszTmpCache = NULL; + BYTE rgbuffer[MAX_PATH * sizeof(WCHAR)]; + HKEY hk; + + if (RegOpenKey(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hk) == ERROR_SUCCESS) + { + DWORD dwT, dwS; dwT = MAX_PATH; + memset(rgbuffer, 0, (MAX_PATH * sizeof(WCHAR))); + + if (v_fUnicodeAPI) + { + if ((RegQueryValueExA(hk, "Cache", 0, &dwT, rgbuffer, &dwS) == ERROR_SUCCESS) && + (dwT == REG_SZ) && (dwS > 1)) + pwszTmpCache = DsoConvertToLPWSTR((LPSTR)rgbuffer); + } + else + { + if ((RegQueryValueExW(hk, L"Cache", 0, &dwT, rgbuffer, &dwS) == ERROR_SUCCESS) && + (dwT == REG_SZ) && (dwS > 1)) + pwszTmpCache = DsoCopyString((LPWSTR)rgbuffer); + } + + RegCloseKey(hk); + + if (pwszTmpCache) + { + dwS = lstrlenW(pwszTmpCache); + dwT = lstrlenW(pwszFile); + fIsCacheFile = ((dwS < dwT) && + (DsoCompareStringsEx(pwszTmpCache, dwS, pwszFile, dwS) == CSTR_EQUAL)); + DsoMemFree(pwszTmpCache); + } + } + + return fIsCacheFile; +} + +//////////////////////////////////////////////////////////////////////// +// FDrawText +// +// This is used by the control for drawing the caption in the titlebar. +// Since a custom caption could contain Unicode characters only printable +// on Unicode OS, we should try to use the Unicode version when available. +// +STDAPI_(BOOL) FDrawText(HDC hdc, WCHAR* pwsz, LPRECT prc, UINT fmt) +{ + BOOL f; + if (v_fUnicodeAPI) + { + f = (BOOL)DrawTextW(hdc, pwsz, -1, prc, fmt); + } + else + { + LPSTR psz = DsoConvertToMBCS(pwsz); + f = (BOOL)DrawTextA(hdc, psz, -1, prc, fmt); + DsoMemFree(psz); + } + return f; +} + + +//////////////////////////////////////////////////////////////////////// +// FSetRegKeyValue +// +// We use this for registration when dealing with the file path, since +// that path may have Unicode characters on some systems. Win9x boxes +// will have to be converted to ANSI. +// +STDAPI_(BOOL) FSetRegKeyValue(HKEY hk, WCHAR* pwsz) +{ + LONG lret; + if (v_fUnicodeAPI) + { + lret = RegSetValueExW(hk, NULL, 0, REG_SZ, (BYTE*)pwsz, (lstrlenW(pwsz) * sizeof(WCHAR))); + } + else + { + LPSTR psz = DsoConvertToMBCS(pwsz); + lret = RegSetValueExA(hk, NULL, 0, REG_SZ, (BYTE*)psz, lstrlen(psz)); + DsoMemFree(psz); + } + return (lret == ERROR_SUCCESS); +} + +//////////////////////////////////////////////////////////////////////// +// FOpenPrinter +// +// Open the specified printer by name. +// +STDAPI_(BOOL) FOpenPrinter(LPCWSTR pwszPrinter, LPHANDLE phandle) +{ + BOOL fRet = FALSE; + DWORD dwLastError = 0; + if (v_fUnicodeAPI) + { + PRINTER_DEFAULTSW prtdef; + memset(&prtdef, 0, sizeof(PRINTER_DEFAULTSW)); + prtdef.DesiredAccess = PRINTER_ACCESS_USE; + fRet = OpenPrinterW((LPWSTR)pwszPrinter, phandle, &prtdef); + } + else + { + LPSTR psz = DsoConvertToMBCS(pwszPrinter); + fRet = OpenPrinterA(psz, phandle, NULL); + if (!fRet) dwLastError = GetLastError(); + DsoMemFree(psz); + } + if (dwLastError) SetLastError(dwLastError); + return fRet; +} + +//////////////////////////////////////////////////////////////////////// +// FGetPrinterSettings +// +// Returns the default device, port name, and DEVMODE structure for the +// printer passed. Handles Unicode translation of DEVMODE if on Win9x. +// +STDAPI_(BOOL) FGetPrinterSettings(HANDLE hprinter, LPWSTR *ppwszProcessor, LPWSTR *ppwszDevice, LPWSTR *ppwszOutput, LPDEVMODEW *ppdvmode, DWORD *pcbSize) +{ + BOOL fRet = FALSE; + DWORD dwLastError = 0; + DWORD cbNeed, cbAlloc = 0; + + if ((ppwszProcessor == NULL) || (ppwszDevice == NULL) || (ppwszOutput == NULL) || + (ppdvmode == NULL) || (pcbSize == NULL)) + return FALSE; + + *ppwszProcessor = NULL; *ppwszDevice = NULL; *ppwszOutput = NULL; + *ppdvmode = NULL; *pcbSize = 0; + + if (v_fUnicodeAPI) // Use Unicode API if possible (much easier)... + { + GetPrinterW(hprinter, 2, NULL, 0, &cbAlloc); + PRINTER_INFO_2W *pinfo = (PRINTER_INFO_2W*)DsoMemAlloc(++cbAlloc); + if (pinfo) + { + fRet = GetPrinterW(hprinter, 2, (BYTE*)pinfo, cbAlloc, &cbNeed); + if (fRet) + { + *ppwszProcessor = DsoConvertToLPWSTR("winspool"); + *ppwszDevice = DsoCopyString(pinfo->pDriverName); + *ppwszOutput = DsoCopyString(pinfo->pPortName); + + if (pinfo->pDevMode) // If we have the devmode, just need to copy it... + { + DWORD cbData = (pinfo->pDevMode->dmSize) + (pinfo->pDevMode->dmDriverExtra); + *ppdvmode = (DEVMODEW*)DsoMemAlloc(cbData); + if (*ppdvmode) + { + memcpy(*ppdvmode, pinfo->pDevMode, cbData); + *pcbSize = cbData; + } + } + } + else dwLastError = GetLastError(); + + DsoMemFree(pinfo); + } + else dwLastError = ERROR_NOT_ENOUGH_MEMORY; + } + else + { + GetPrinterA(hprinter, 2, NULL, 0, &cbAlloc); + PRINTER_INFO_2A *pinfo = (PRINTER_INFO_2A*)DsoMemAlloc(++cbAlloc); + if (pinfo) + { + fRet = GetPrinterA(hprinter, 2, (BYTE*)pinfo, cbAlloc, &cbNeed); + if (fRet) + { + *ppwszProcessor = DsoConvertToLPWSTR("winspool"); + *ppwszDevice = DsoConvertToLPWSTR(pinfo->pDriverName); + *ppwszOutput = DsoConvertToLPWSTR(pinfo->pPortName); + + if (pinfo->pDevMode) // For Win9x API, we have to convert the DEVMODEA + { // into DEVMODEW so we have Unicode names for TARGETDEVICE... + DWORD cbData = sizeof(DEVMODEW) + + ((pinfo->pDevMode->dmSize > sizeof(DEVMODEA)) ? (pinfo->pDevMode->dmSize - sizeof(DEVMODEA)) : 0) + + pinfo->pDevMode->dmDriverExtra; + + *ppdvmode = (DEVMODEW*)DsoMemAlloc(cbData); + if (*ppdvmode) + { + DsoConvertToUnicodeEx( + (LPSTR)(pinfo->pDevMode->dmDeviceName), CCHDEVICENAME, + (LPWSTR)((*ppdvmode)->dmDeviceName), CCHDEVICENAME, 0); + + // The rest of the copy depends on the default size of the DEVMODE. + // Just check the size and convert the form name if it exists... + if (pinfo->pDevMode->dmSize <= FIELD_OFFSET(DEVMODEA, dmFormName)) + { + memcpy(&((*ppdvmode)->dmSpecVersion), + &(pinfo->pDevMode->dmSpecVersion), + pinfo->pDevMode->dmSize - CCHDEVICENAME); + } + else + { + memcpy(&((*ppdvmode)->dmSpecVersion), + &(pinfo->pDevMode->dmSpecVersion), + FIELD_OFFSET(DEVMODEA, dmFormName) - + FIELD_OFFSET(DEVMODEA, dmSpecVersion)); + + DsoConvertToUnicodeEx( + (LPSTR)(pinfo->pDevMode->dmFormName), CCHFORMNAME, + (LPWSTR)((*ppdvmode)->dmFormName), CCHFORMNAME, 0); + + if (pinfo->pDevMode->dmSize > FIELD_OFFSET(DEVMODEA, dmLogPixels)) + memcpy(&((*ppdvmode)->dmLogPixels), + &(pinfo->pDevMode->dmLogPixels), + pinfo->pDevMode->dmSize - FIELD_OFFSET(DEVMODEA, dmLogPixels)); + } + + (*ppdvmode)->dmSize = (WORD)((pinfo->pDevMode->dmSize > sizeof(DEVMODEA)) ? + (sizeof(DEVMODEW) + (pinfo->pDevMode->dmSize - sizeof(DEVMODEA))) : + sizeof(DEVMODEW)); + + memcpy((((BYTE*)(*ppdvmode)) + ((*ppdvmode)->dmSize)), + (((BYTE*)(pinfo->pDevMode)) + (pinfo->pDevMode->dmSize)), + pinfo->pDevMode->dmDriverExtra); + + *pcbSize = cbData; + } + } + } + else dwLastError = GetLastError(); + + DsoMemFree(pinfo); + } + else dwLastError = ERROR_NOT_ENOUGH_MEMORY; + } + if (dwLastError) SetLastError(dwLastError); + return fRet; +} + + +/////////////////////////////////////////////////////////////////////////////////// +// DsoGetFileFromUser +// +// Displays the Open/Save dialog using Unicode version if available. Returns the +// path as a unicode BSTR regardless of OS. +// +STDAPI DsoGetFileFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags, + LPCWSTR pwzFilter, DWORD dwFiltIdx, LPCWSTR pwszDefExt, LPCWSTR pwszCurrentItem, BOOL fShowSave, + BSTR *pbstrFile, BOOL *pfReadOnly) +{ + BYTE buffer[MAX_PATH * sizeof(WCHAR)]; + BOOL fSuccess; + DWORD dw; + + // Make sure they pass a *bstr... + CHECK_NULL_RETURN(pbstrFile, E_POINTER); + *pbstrFile = NULL; + + buffer[0] = 0; buffer[1] = 0; + + // See if we have Unicode function to call. If so, we use OPENFILENAMEW and + // get the file path in Unicode, returned as BSTR... + if (v_fUnicodeAPI) + { + OPENFILENAMEW ofnw; + memset(&ofnw, 0, sizeof(OPENFILENAMEW)); + ofnw.lStructSize = sizeof(OPENFILENAMEW); + ofnw.hwndOwner = hwndOwner; + ofnw.lpstrFilter = pwzFilter; + ofnw.nFilterIndex = dwFiltIdx; + ofnw.lpstrDefExt = pwszDefExt; + ofnw.lpstrTitle = pwzTitle; + ofnw.lpstrFile = (LPWSTR)&buffer[0]; + ofnw.nMaxFile = MAX_PATH; + ofnw.Flags = dwFlags; + + if (pwszCurrentItem) + { + dw = lstrlenW(pwszCurrentItem); + if ((dw) && (dw < MAX_PATH)) + { + memcpy(ofnw.lpstrFile, pwszCurrentItem, dw * sizeof(WCHAR)); + ofnw.lpstrFile[dw] = L'\0'; + } + } + + if (fShowSave) + fSuccess = GetSaveFileNameW(&ofnw); + else + fSuccess = GetOpenFileNameW(&ofnw); + + if (fSuccess) + { + *pbstrFile = SysAllocString((LPWSTR)&buffer[0]); + if (pfReadOnly) *pfReadOnly = (ofnw.Flags & OFN_READONLY); + } + } + else + { // If not, then we use OPENFILENAMEA and thunk down our params to + // the MBCS of the system, and then thunk back the Unicode for the return... + OPENFILENAMEA ofn; + memset(&ofn, 0, sizeof(OPENFILENAMEA)); + ofn.lStructSize = sizeof(OPENFILENAMEA); + ofn.hwndOwner = hwndOwner; + ofn.lpstrFilter = DsoConvertToMBCS(pwzFilter); + ofn.nFilterIndex = dwFiltIdx; + ofn.lpstrDefExt = DsoConvertToMBCS(pwszDefExt); + ofn.lpstrTitle = DsoConvertToMBCS(pwzTitle); + ofn.lpstrFile = (LPSTR)&buffer[0]; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = dwFlags; + + if (pwszCurrentItem) + DsoConvertToMBCSEx(pwszCurrentItem, lstrlenW(pwszCurrentItem), (LPSTR)&buffer[0], MAX_PATH, GetACP()); + + if (fShowSave) + fSuccess = GetSaveFileNameA(&ofn); + else + fSuccess = GetOpenFileNameA(&ofn); + + + if (fSuccess) + { + *pbstrFile = DsoConvertToBSTR((LPCSTR)&buffer[0]); + if (pfReadOnly) *pfReadOnly = (ofn.Flags & OFN_READONLY); + } + + DsoMemFree((void*)(ofn.lpstrDefExt)); + DsoMemFree((void*)(ofn.lpstrFilter)); + DsoMemFree((void*)(ofn.lpstrTitle)); + } + + // If we got a string, then success. All other errors (even user cancel) should + // be treated as a general failure (feel free to change this for more full function). + return ((*pbstrFile == NULL) ? E_FAIL : S_OK); +} + +/////////////////////////////////////////////////////////////////////////////////// +// DsoGetOleInsertObjectFromUser +// +// Displays the OLE InsertObject dialog using Unicode version if available. +// +STDAPI DsoGetOleInsertObjectFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags, + BOOL fDocObjectOnly, BOOL fAllowControls, BSTR *pbstrResult, UINT *ptype) +{ + BYTE buffer[MAX_PATH * sizeof(WCHAR)]; + LPCLSID lpNewExcludeList = NULL; + int nNewExcludeCount = 0; + int nNewExcludeLen = 0; + + // Make sure they pass a *bstr... + CHECK_NULL_RETURN(pbstrResult, E_POINTER); + *pbstrResult = NULL; + + // To limit list to just those marked as DocObject servers, you have to enum + // the registry and create an exclude list for OLE dialog. Exclude all except + // those that are marked DocObject under their ProgID. + if (fDocObjectOnly) + { + HKEY hkCLSID; + HKEY hkItem; + HKEY hkDocObject; + DWORD dwIndex = 0; + CHAR szName[MAX_PATH+1]; + + if (RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ|KEY_ENUMERATE_SUB_KEYS, &hkCLSID) == ERROR_SUCCESS) + { + while (RegEnumKey(hkCLSID, dwIndex++, szName, MAX_PATH) == ERROR_SUCCESS) + { + if (RegOpenKeyEx(hkCLSID, szName, 0, KEY_READ, &hkItem) == ERROR_SUCCESS) + { + if ((RegOpenKeyEx(hkItem, "DocObject", 0, KEY_READ, &hkDocObject) != ERROR_SUCCESS)) + { + CLSID clsid; + LPWSTR pwszClsid = DsoConvertToLPWSTR(szName); + if ((pwszClsid) && SUCCEEDED(CLSIDFromString(pwszClsid, &clsid))) + { + if (lpNewExcludeList == NULL) + { + nNewExcludeCount = 0; + nNewExcludeLen = 16; + lpNewExcludeList = new CLSID[nNewExcludeLen]; + } + if (nNewExcludeCount == nNewExcludeLen) + { + LPCLSID lpOldList = lpNewExcludeList; + nNewExcludeLen <<= 2; + lpNewExcludeList = new CLSID[nNewExcludeLen]; + memcpy(lpNewExcludeList, lpOldList, sizeof(CLSID) * nNewExcludeCount); + delete [] lpOldList; + } + + lpNewExcludeList[nNewExcludeCount] = clsid; + nNewExcludeCount++; + } + SAFE_FREESTRING(pwszClsid); + RegCloseKey(hkDocObject); + } + + RegCloseKey(hkItem); + } + } + RegCloseKey(hkCLSID); + } + } + buffer[0] = 0; buffer[1] = 0; + + // See if we have Unicode function to call... + if (v_fUnicodeAPI) + { + OLEUIINSERTOBJECTW oidlg = {0}; + oidlg.cbStruct = sizeof(OLEUIINSERTOBJECTW); + oidlg.dwFlags = dwFlags; + oidlg.hWndOwner = hwndOwner; + oidlg.lpszCaption = pwzTitle; + oidlg.lpszFile = (LPWSTR)buffer; + oidlg.cchFile = MAX_PATH; + oidlg.lpClsidExclude = lpNewExcludeList; + oidlg.cClsidExclude = nNewExcludeCount; + + if (OleUIInsertObjectW(&oidlg) == OLEUI_OK) + { + if ((oidlg.dwFlags & IOF_SELECTCREATENEW) && (oidlg.clsid != GUID_NULL)) + { + LPOLESTR posz; + if (SUCCEEDED(ProgIDFromCLSID(oidlg.clsid, &posz))) + { + *pbstrResult = SysAllocString(posz); + CoTaskMemFree(posz); + } + if (ptype) *ptype = IOF_SELECTCREATENEW; + } + else if ((oidlg.dwFlags & IOF_SELECTCREATEFROMFILE) && (buffer[0] != 0)) + { + *pbstrResult = SysAllocString((LPWSTR)buffer); + if (ptype) *ptype = IOF_SELECTCREATEFROMFILE; + } + } + } + else + { + OLEUIINSERTOBJECTA oidlg = {0}; + oidlg.cbStruct = sizeof(OLEUIINSERTOBJECTA); + oidlg.dwFlags = dwFlags; + oidlg.hWndOwner = hwndOwner; + oidlg.lpszCaption = DsoConvertToMBCS(pwzTitle); + oidlg.lpszFile = (LPSTR)buffer; + oidlg.cchFile = MAX_PATH; + oidlg.lpClsidExclude = lpNewExcludeList; + oidlg.cClsidExclude = nNewExcludeCount; + + if (OleUIInsertObjectA(&oidlg) == OLEUI_OK) + { + if ((oidlg.dwFlags & IOF_SELECTCREATENEW) && (oidlg.clsid != GUID_NULL)) + { + LPOLESTR posz; + if (SUCCEEDED(ProgIDFromCLSID(oidlg.clsid, &posz))) + { + *pbstrResult = SysAllocString(posz); + CoTaskMemFree(posz); + } + if (ptype) *ptype = IOF_SELECTCREATENEW; + } + else if ((oidlg.dwFlags & IOF_SELECTCREATEFROMFILE) && (buffer[0] != 0)) + { + *pbstrResult = DsoConvertToBSTR((LPSTR)buffer); + if (ptype) *ptype = IOF_SELECTCREATEFROMFILE; + } + } + + DsoMemFree((void*)(oidlg.lpszCaption)); + } + + if (lpNewExcludeList) + delete [] lpNewExcludeList; + + // If we got a string, then success. All other errors (even user cancel) should + // be treated as a general failure (feel free to change this for more full function). + return ((*pbstrResult == NULL) ? E_FAIL : S_OK); +} diff --git a/PROMS/DSOFRAMER/Source2005/utilities.h b/PROMS/DSOFRAMER/Source2005/utilities.h new file mode 100644 index 00000000..b0da4dec --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/utilities.h @@ -0,0 +1,242 @@ +/*************************************************************************** + * UTILITIES.H + * + * DSOFramer: Common Utilities and Macros (Shared) + * + * Copyright ©1999-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. + * + ***************************************************************************/ +#ifndef DS_UTILITIES_H +#define DS_UTILITIES_H + +#include +#include + +//////////////////////////////////////////////////////////////////////// +// Fixed Win32 Errors as HRESULTs +// +#define E_WIN32_BUFFERTOOSMALL 0x8007007A //HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) +#define E_WIN32_ACCESSVIOLATION 0x800701E7 //HRESULT_FROM_WIN32(ERROR_INVALID_ADDRESS) +#define E_WIN32_LASTERROR (0x80070000 | GetLastError()) // Assured Error with last Win32 code +#define E_VBA_NOREMOTESERVER 0x800A01CE + +//////////////////////////////////////////////////////////////////////// +// Heap Allocation +// +STDAPI_(LPVOID) DsoMemAlloc(DWORD cbSize); +STDAPI_(void) DsoMemFree(LPVOID ptr); + +// Override new/delete to use our task allocator +// (removing CRT dependency will improve code performance and size)... +void * _cdecl operator new(size_t size); +void _cdecl operator delete(void *ptr); + +//////////////////////////////////////////////////////////////////////// +// String Manipulation Functions +// +STDAPI DsoConvertToUnicodeEx(LPCSTR pszMbcsString, DWORD cbMbcsLen, LPWSTR pwszUnicode, DWORD cbUniLen, UINT uiCodePage); +STDAPI DsoConvertToMBCSEx(LPCWSTR pwszUnicodeString, DWORD cbUniLen, LPSTR pwszMbcsString, DWORD cbMbcsLen, UINT uiCodePage); + +STDAPI_(LPWSTR) DsoConvertToLPWSTR(LPCSTR pszMbcsString); +STDAPI_(BSTR) DsoConvertToBSTR(LPCSTR pszMbcsString); +STDAPI_(LPWSTR) DsoConvertToLPOLESTR(LPCWSTR pwszUnicodeString); +STDAPI_(LPSTR) DsoConvertToMBCS(LPCWSTR pwszUnicodeString); +STDAPI_(UINT) DsoCompareStringsEx(LPCWSTR pwsz1, INT cch1, LPCWSTR pwsz2, INT cch2); +STDAPI_(LPWSTR) DsoCopyString(LPCWSTR pwszString); +STDAPI_(LPWSTR) DsoCopyStringCat(LPCWSTR pwszString1, LPCWSTR pwszString2); +STDAPI_(LPWSTR) DsoCopyStringCatEx(LPCWSTR pwszBaseString, UINT cStrs, LPCWSTR *ppwszStrs); +STDAPI_(LPSTR) DsoCLSIDtoLPSTR(REFCLSID clsid); + +//////////////////////////////////////////////////////////////////////// +// URL Helpers +// +STDAPI_(BOOL) LooksLikeLocalFile(LPCWSTR pwsz); +STDAPI_(BOOL) LooksLikeUNC(LPCWSTR pwsz); +STDAPI_(BOOL) LooksLikeHTTP(LPCWSTR pwsz); +STDAPI_(BOOL) GetTempPathForURLDownload(WCHAR* pwszURL, WCHAR** ppwszLocalFile); +STDAPI URLDownloadFile(LPUNKNOWN punk, WCHAR* pwszURL, WCHAR* pwszLocalFile); + +//////////////////////////////////////////////////////////////////////// +// OLE Conversion Functions +// +STDAPI_(void) DsoHimetricToPixels(LONG* px, LONG* py); +STDAPI_(void) DsoPixelsToHimetric(LONG* px, LONG* py); + +//////////////////////////////////////////////////////////////////////// +// GDI Helper Functions +// +STDAPI_(HBITMAP) DsoGetBitmapFromWindow(HWND hwnd); + +//////////////////////////////////////////////////////////////////////// +// Windows Helper Functions +// +STDAPI_(BOOL) IsWindowChild(HWND hwndParent, HWND hwndChild); + +//////////////////////////////////////////////////////////////////////// +// OLE/Typelib Function Wrappers +// +STDAPI DsoGetTypeInfoEx(REFGUID rlibid, LCID lcid, WORD wVerMaj, WORD wVerMin, HMODULE hResource, REFGUID rguid, ITypeInfo** ppti); +STDAPI DsoDispatchInvoke(LPDISPATCH pdisp, LPOLESTR pwszname, DISPID dspid, WORD wflags, DWORD cargs, VARIANT* rgargs, VARIANT* pvtret); +STDAPI DsoReportError(HRESULT hr, LPWSTR pwszCustomMessage, EXCEPINFO* peiDispEx); + +//////////////////////////////////////////////////////////////////////// +// Unicode Win32 API wrappers (handles thunk down for Win9x) +// +STDAPI_(BOOL) FFileExists(WCHAR* wzPath); +STDAPI_(BOOL) FOpenLocalFile(WCHAR* wzFilePath, DWORD dwAccess, DWORD dwShareMode, DWORD dwCreate, HANDLE* phFile); +STDAPI_(BOOL) FPerformShellOp(DWORD dwOp, WCHAR* wzFrom, WCHAR* wzTo); +STDAPI_(BOOL) FGetModuleFileName(HMODULE hModule, WCHAR** wzFileName); +STDAPI_(BOOL) FIsIECacheFile(LPWSTR pwszFile); +STDAPI_(BOOL) FDrawText(HDC hdc, WCHAR* pwsz, LPRECT prc, UINT fmt); +STDAPI_(BOOL) FSetRegKeyValue(HKEY hk, WCHAR* pwsz); + +STDAPI_(BOOL) FOpenPrinter(LPCWSTR pwszPrinter, LPHANDLE phandle); +STDAPI_(BOOL) FGetPrinterSettings(HANDLE hprinter, LPWSTR *ppwszProcessor, LPWSTR *ppwszDevice, LPWSTR *ppwszOutput, LPDEVMODEW *ppdvmode, DWORD *pcbSize); + +STDAPI DsoGetFileFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags, + LPCWSTR pwzFilter, DWORD dwFiltIdx, LPCWSTR pwszDefExt, LPCWSTR pwszCurrentItem, BOOL fShowSave, + BSTR *pbstrFile, BOOL *pfReadOnly); + +STDAPI DsoGetOleInsertObjectFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags, + BOOL fDocObjectOnly, BOOL fAllowControls, BSTR *pbstrResult, UINT *ptype); + +//////////////////////////////////////////////////////////////////////// +// Common macros -- Used to make code more readable. +// +#define SEH_TRY __try { +#define SEH_EXCEPT(hr) } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION){hr = E_WIN32_ACCESSVIOLATION;} +#define SEH_EXCEPT_NULL } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION){} +#define SEH_START_FINALLY } __finally { +#define SEH_END_FINALLY } + +#define RETURN_ON_FAILURE(x) if (FAILED(x)) return (x) +#define GOTO_ON_FAILURE(x, lbl) if (FAILED(x)) goto lbl +#define CHECK_NULL_RETURN(v, e) if ((v) == NULL) return (e) + +#define SAFE_ADDREF_INTERFACE if (x) { (x)->AddRef(); } +#define SAFE_RELEASE_INTERFACE(x) if (x) { (x)->Release(); (x) = NULL; } +#define SAFE_SET_INTERFACE(x, y) if (((x) = (y)) != NULL) ((IUnknown*)(x))->AddRef() +#define SAFE_FREESTRING(s) if (s) { DsoMemFree(s); (s) = NULL; } +#define SAFE_FREEBSTR(s) if (s) { SysFreeString(s); (s) = NULL; } + +VARIANT* __fastcall DsoPVarFromPVarRef(VARIANT* px); +BOOL __fastcall DsoIsVarParamMissing(VARIANT* px); +LPWSTR __fastcall DsoPVarWStrFromPVar(VARIANT* px); +SAFEARRAY* __fastcall DsoPVarArrayFromPVar(VARIANT* px); +IUnknown* __fastcall DsoPVarUnkFromPVar(VARIANT* px); +SHORT __fastcall DsoPVarShortFromPVar(VARIANT* px, SHORT fdef); +LONG __fastcall DsoPVarLongFromPVar(VARIANT* px, LONG fdef); +BOOL __fastcall DsoPVarBoolFromPVar(VARIANT* px, BOOL fdef); + +#define PARAM_IS_MISSING(x) DsoIsVarParamMissing(DsoPVarFromPVarRef((x))) +#define LPWSTR_FROM_VARIANT(x) DsoPVarWStrFromPVar(DsoPVarFromPVarRef(&(x))) +#define LONG_FROM_VARIANT(x, y) DsoPVarLongFromPVar(DsoPVarFromPVarRef(&(x)), (y)) +#define BOOL_FROM_VARIANT(x, y) DsoPVarBoolFromPVar(DsoPVarFromPVarRef(&(x)), (y)) +#define PUNK_FROM_VARIANT(x) DsoPVarUnkFromPVar(DsoPVarFromPVarRef(&(x))) +#define PSARRAY_FROM_VARIANT(x) DsoPVarArrayFromPVar(DsoPVarFromPVarRef(&(x))) + +#define ASCII_UPPERCASE(x) ((((x) > 96) && ((x) < 123)) ? (x) - 32 : (x)) +#define ASCII_LOWERCASE(x) ((((x) > 64) && ((x) < 91)) ? (x) + 32 : (x)) + +//////////////////////////////////////////////////////////////////////// +// Debug macros +// +#ifdef _DEBUG + +#define ASSERT(x) if(!(x)) DebugBreak() +#define ODS(x) OutputDebugString(x) + +#define TRACE1(sz, arg1) { \ + CHAR ach[1024]; \ + wsprintf(ach, (sz), (arg1)); \ + ODS(ach); } + +#define TRACE2(sz, arg1, arg2) { \ + CHAR ach[1024]; \ + wsprintf(ach, (sz), (arg1), (arg2)); \ + ODS(ach); } + +#define TRACE3(sz, arg1, arg2, arg3) { \ + CHAR ach[1024]; \ + wsprintf(ach, (sz), (arg1), (arg2), (arg3)); \ + ODS(ach); } + +#define TRACE_LPRECT(sz, lprc) { \ + CHAR ach[1024]; \ + wsprintf(ach, "RECT %s - left=%d, top=%d, right=%d, bottom=%d\n", \ + (sz), (lprc)->left, (lprc)->top, (lprc)->right, (lprc)->bottom); \ + ODS(ach); } + +#else // !defined(_DEBUG) + +#define ASSERT(x) +#define ODS(x) +#define TRACE1(sz, arg1) +#define TRACE2(sz, arg1, arg2) +#define TRACE3(sz, arg1, arg2, arg3) +#define TRACE_LPRECT(sz, lprc) + +#endif // (_DEBUG) + +//////////////////////////////////////////////////////////////////////// +// Macros for Nested COM Interfaces +// +#ifdef _DEBUG +#define DEFINE_REFCOUNT ULONG m_cRef; +#define IMPLEMENT_DEBUG_ADDREF m_cRef++; +#define IMPLEMENT_DEBUG_RELEASE(x) ASSERT(m_cRef > 0); m_cRef--; if (m_cRef == 0){ODS(" > I" #x " released\n");} +#define IMPLEMENT_DEBUG_REFSET m_cRef = 0; +#define IMPLEMENT_DEBUG_REFCHECK(x) ASSERT(m_cRef == 0); if (m_cRef != 0){ODS(" * I" #x " NOT released!!\n");} +#else +#define DEFINE_REFCOUNT +#define IMPLEMENT_DEBUG_ADDREF +#define IMPLEMENT_DEBUG_RELEASE(x) +#define IMPLEMENT_DEBUG_REFSET +#define IMPLEMENT_DEBUG_REFCHECK(x) +#endif /* !_DEBUG */ + +#define BEGIN_INTERFACE_PART(localClass, baseClass) \ +class X##localClass : public baseClass \ +{ public: X##localClass(){IMPLEMENT_DEBUG_REFSET} \ + ~X##localClass(){IMPLEMENT_DEBUG_REFCHECK(##localClass)} \ + STDMETHOD(QueryInterface)(REFIID iid, PVOID* ppvObj); \ + STDMETHOD_(ULONG, AddRef)(); \ + STDMETHOD_(ULONG, Release)(); \ + DEFINE_REFCOUNT + +#define END_INTERFACE_PART(localClass) \ +} m_x##localClass; \ +friend class X##localClass; + +#define METHOD_PROLOGUE(theClass, localClass) \ + theClass* pThis = \ + ((theClass*)(((BYTE*)this) - (size_t)&(((theClass*)0)->m_x##localClass))); + +#define IMPLEMENT_INTERFACE_UNKNOWN(theClass, localClass) \ + ULONG theClass::X##localClass::AddRef() { \ + METHOD_PROLOGUE(theClass, localClass) \ + IMPLEMENT_DEBUG_ADDREF \ + return pThis->AddRef(); \ + } \ + ULONG theClass::X##localClass::Release() { \ + METHOD_PROLOGUE(theClass, localClass) \ + IMPLEMENT_DEBUG_RELEASE(##localClass) \ + return pThis->Release(); \ + } \ + STDMETHODIMP theClass::X##localClass::QueryInterface(REFIID iid, void **ppvObj) { \ + METHOD_PROLOGUE(theClass, localClass) \ + return pThis->QueryInterface(iid, ppvObj); \ + } + + +#endif //DS_UTILITIES_H \ No newline at end of file diff --git a/PROMS/DSOFRAMER/Source2005/version.h b/PROMS/DSOFRAMER/Source2005/version.h new file mode 100644 index 00000000..fcc71283 --- /dev/null +++ b/PROMS/DSOFRAMER/Source2005/version.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * VERSION.H - Contol version defines + * + * DSOFramer: Version Information Header (Shared) + * + * Copyright ©1999-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. + * + ***************************************************************************/ +/*************************************************************************** + * + * IMPORTANT: If you modify this sample, you should change all of the values + * below to differentiate your control from this sample. + * + ***************************************************************************/ +#ifndef DS_VERSION_H +#define DS_VERSION_H + +#define DSOFRAMERCTL_VERSION 1.3 +#define DSOFRAMERCTL_VERSION_MAJOR 1 +#define DSOFRAMERCTL_VERSION_MINOR 3 +#define DSOFRAMERCTL_VERSION_BUILD 1323 +#define DSOFRAMERCTL_VERSIONSTR "1.3" +#define DSOFRAMERCTL_VERSIONSTRFULL "1.3.1323.1" + +#define DSOFRAMERCTL_FULLNAME "DSO ActiveX Document Framer Control" +#define DSOFRAMERCTL_SHORTNAME "DSO Framer Control Object" + +#define DSOFRAMERCTL_PROGID "DSOFramer.FramerControl" + +#define DSOFRAMERCTL_TLIB 00460180-9E5E-11d5-B7C8-B8269041DD57 +#define DSOFRAMERCTL_TLIBSTR "{00460180-9E5E-11d5-B7C8-B8269041DD57}" + +#define DSOFRAMERCTL_INTERFACE 00460181-9E5E-11d5-B7C8-B8269041DD57 + +#define DSOFRAMERCTL_CLSID 00460182-9E5E-11d5-B7C8-B8269041DD57 +#define DSOFRAMERCTL_CLSIDSTR "{00460182-9E5E-11d5-B7C8-B8269041DD57}" + +#define DSOFRAMERCTL_DISPEVTS 00460185-9E5E-11d5-B7C8-B8269041DD57 + +#define DSOF_DISPID_FILECMD 1 +#define DSOF_DISPID_DOCOPEN 2 +#define DSOF_DISPID_DOCCLOSE 3 +#define DSOF_DISPID_ACTIVATE 4 +#define DSOF_DISPID_BDOCCLOSE 5 +#define DSOF_DISPID_BDOCSAVE 6 +#define DSOF_DISPID_ENDPREVIEW 7 +#define DSOF_DISPID_SAVECOMPLETE 8 + +#endif //DS_VERSION_H