summaryrefslogtreecommitdiffstats
path: root/private/oleutest/letest/outline/classfac.h
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleutest/letest/outline/classfac.h')
-rw-r--r--private/oleutest/letest/outline/classfac.h219
1 files changed, 219 insertions, 0 deletions
diff --git a/private/oleutest/letest/outline/classfac.h b/private/oleutest/letest/outline/classfac.h
new file mode 100644
index 000000000..cf3070227
--- /dev/null
+++ b/private/oleutest/letest/outline/classfac.h
@@ -0,0 +1,219 @@
+/*************************************************************************
+**
+** OLE 2 Sample Code
+**
+** classfac.c
+**
+** This file contains the implementation for IClassFactory for both the
+** server and the client version of the OUTLINE app.
+**
+** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
+**
+*************************************************************************/
+
+#include "outline.h"
+
+OLEDBGDATA
+
+extern LPOUTLINEAPP g_lpApp;
+
+
+/* OLE2NOTE: this object illustrates the manner in which to statically
+** (compile-time) initialize an interface VTBL.
+*/
+static IClassFactoryVtbl g_AppClassFactoryVtbl = {
+ AppClassFactory_QueryInterface,
+ AppClassFactory_AddRef,
+ AppClassFactory_Release,
+ AppClassFactory_CreateInstance,
+ AppClassFactory_LockServer
+};
+
+
+/* AppClassFactory_Create
+** ----------------------
+** create an instance of APPCLASSFACTORY.
+** NOTE: type of pointer returned is an IClassFactory* interface ptr.
+** the returned pointer can be directly passed to
+** CoRegisterClassObject and released later by calling the
+** Release method of the interface.
+*/
+LPCLASSFACTORY WINAPI AppClassFactory_Create(void)
+{
+ LPAPPCLASSFACTORY lpAppClassFactory;
+ LPMALLOC lpMalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR)
+ return NULL;
+
+ lpAppClassFactory = (LPAPPCLASSFACTORY)lpMalloc->lpVtbl->Alloc(
+ lpMalloc, (sizeof(APPCLASSFACTORY)));
+ lpMalloc->lpVtbl->Release(lpMalloc);
+ if (! lpAppClassFactory) return NULL;
+
+ lpAppClassFactory->m_lpVtbl = &g_AppClassFactoryVtbl;
+ lpAppClassFactory->m_cRef = 1;
+#if defined( _DEBUG )
+ lpAppClassFactory->m_cSvrLock = 0;
+#endif
+ return (LPCLASSFACTORY)lpAppClassFactory;
+}
+
+
+/*************************************************************************
+** OleApp::IClassFactory interface implementation
+*************************************************************************/
+
+STDMETHODIMP AppClassFactory_QueryInterface(
+ LPCLASSFACTORY lpThis, REFIID riid, LPVOID FAR* ppvObj)
+{
+ LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
+ SCODE scode;
+
+ // Two interfaces supported: IUnknown, IClassFactory
+
+ if (IsEqualIID(riid, &IID_IClassFactory) ||
+ IsEqualIID(riid, &IID_IUnknown)) {
+ lpAppClassFactory->m_cRef++; // A pointer to this object is returned
+ *ppvObj = lpThis;
+ scode = S_OK;
+ }
+ else { // unsupported interface
+ *ppvObj = NULL;
+ scode = E_NOINTERFACE;
+ }
+
+ return ResultFromScode(scode);
+}
+
+
+STDMETHODIMP_(ULONG) AppClassFactory_AddRef(LPCLASSFACTORY lpThis)
+{
+ LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
+ return ++lpAppClassFactory->m_cRef;
+}
+
+STDMETHODIMP_(ULONG) AppClassFactory_Release(LPCLASSFACTORY lpThis)
+{
+ LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
+ LPMALLOC lpMalloc;
+
+ if (--lpAppClassFactory->m_cRef != 0) // Still used by others
+ return lpAppClassFactory->m_cRef;
+
+ // Free storage
+ if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR)
+ return 0;
+
+ lpMalloc->lpVtbl->Free(lpMalloc, lpAppClassFactory);
+ lpMalloc->lpVtbl->Release(lpMalloc);
+ return 0;
+}
+
+
+STDMETHODIMP AppClassFactory_CreateInstance (
+ LPCLASSFACTORY lpThis,
+ LPUNKNOWN lpUnkOuter,
+ REFIID riid,
+ LPVOID FAR* lplpvObj
+)
+{
+ LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
+ LPOLEDOC lpOleDoc;
+ HRESULT hrErr;
+
+ OLEDBG_BEGIN2("AppClassFactory_CreateInstance\r\n")
+
+ /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
+ *lplpvObj = NULL;
+
+ /*********************************************************************
+ ** OLE2NOTE: this is an SDI app; it can only create and support one
+ ** instance. After the instance is created, the OLE libraries
+ ** should not call CreateInstance again. it is a good practise
+ ** to specifically guard against this.
+ *********************************************************************/
+
+ if (lpOutlineApp->m_lpDoc != NULL)
+ return ResultFromScode(E_UNEXPECTED);
+
+ /* OLE2NOTE: create a new document instance. by the time we return
+ ** from this method the document's refcnt must be 1.
+ */
+ lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
+ lpOleDoc = (LPOLEDOC)lpOutlineApp->m_lpDoc;
+ if (! lpOleDoc) {
+ OLEDBG_END2
+ return ResultFromScode(E_OUTOFMEMORY);
+ }
+
+ /* OLE2NOTE: retrieve pointer to requested interface. the ref cnt
+ ** of the object after OutlineApp_CreateDoc is 0. this call to
+ ** QueryInterface will increment the refcnt to 1. the object
+ ** returned from IClassFactory::CreateInstance should have a
+ ** refcnt of 1 and be controlled by the caller. If the caller
+ ** releases the document, the document should be destroyed.
+ */
+ hrErr = OleDoc_QueryInterface(lpOleDoc, riid, lplpvObj);
+
+ OLEDBG_END2
+ return hrErr;
+}
+
+
+STDMETHODIMP AppClassFactory_LockServer (
+ LPCLASSFACTORY lpThis,
+ BOOL fLock
+)
+{
+ LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
+ LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
+ HRESULT hrErr;
+ OLEDBG_BEGIN2("AppClassFactory_LockServer\r\n")
+
+#if defined( _DEBUG )
+ if (fLock) {
+ ++lpAppClassFactory->m_cSvrLock;
+ OleDbgOutRefCnt3(
+ "AppClassFactory_LockServer: cLock++\r\n",
+ lpAppClassFactory, lpAppClassFactory->m_cSvrLock);
+ } else {
+
+ /* OLE2NOTE: when there are no open documents and the app is not
+ ** under the control of the user and there are no outstanding
+ ** locks on the app, then revoke our ClassFactory to enable the
+ ** app to shut down.
+ */
+ --lpAppClassFactory->m_cSvrLock;
+ OleDbgAssertSz (lpAppClassFactory->m_cSvrLock >= 0,
+ "AppClassFactory_LockServer(FALSE) called with cLock == 0"
+ );
+
+ if (lpAppClassFactory->m_cSvrLock == 0) {
+ OleDbgOutRefCnt2(
+ "AppClassFactory_LockServer: UNLOCKED\r\n",
+ lpAppClassFactory, lpAppClassFactory->m_cSvrLock);
+ } else {
+ OleDbgOutRefCnt3(
+ "AppClassFactory_LockServer: cLock--\r\n",
+ lpAppClassFactory, lpAppClassFactory->m_cSvrLock);
+ }
+ }
+#endif // _DEBUG
+ /* OLE2NOTE: in order to hold the application alive we call
+ ** CoLockObjectExternal to add a strong reference to our app
+ ** object. this will keep the app alive when all other external
+ ** references release us. if the user issues File.Exit the
+ ** application will shut down in any case ignoring any
+ ** outstanding LockServer locks because CoDisconnectObject is
+ ** called in OleApp_CloseAllDocsAndExitCommand. this will
+ ** forceably break any existing strong reference counts
+ ** including counts that we add ourselves by calling
+ ** CoLockObjectExternal and guarantee that the App object gets
+ ** its final release (ie. cRefs goes to 0).
+ */
+ hrErr = OleApp_Lock(lpOleApp, fLock, TRUE /* fLastUnlockReleases */);
+
+ OLEDBG_END2
+ return hrErr;
+}