Annotation of mstools/ole20/samples/outline/classfac.c, revision 1.1

1.1     ! root        1: /*************************************************************************
        !             2: **
        !             3: **    OLE 2 Sample Code
        !             4: **
        !             5: **    classfac.c
        !             6: **
        !             7: **    This file contains the implementation for IClassFactory for both the
        !             8: **    server and the client version of the OUTLINE app. 
        !             9: **
        !            10: **    (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
        !            11: **
        !            12: *************************************************************************/
        !            13: 
        !            14: #include "outline.h"
        !            15: 
        !            16: OLEDBGDATA
        !            17: 
        !            18: extern LPOUTLINEAPP             g_lpApp;
        !            19: 
        !            20: 
        !            21: /* OLE2NOTE: this object illustrates the manner in which to statically
        !            22: **    (compile-time) initialize an interface VTBL.
        !            23: */
        !            24: static IClassFactoryVtbl g_AppClassFactoryVtbl = {
        !            25:     AppClassFactory_QueryInterface,
        !            26:     AppClassFactory_AddRef,
        !            27:     AppClassFactory_Release,
        !            28:     AppClassFactory_CreateInstance,
        !            29:     AppClassFactory_LockServer
        !            30: };
        !            31: 
        !            32: 
        !            33: /* AppClassFactory_Create
        !            34: ** ----------------------
        !            35: **    create an instance of APPCLASSFACTORY. 
        !            36: **    NOTE: type of pointer returned is an IClassFactory* interface ptr.
        !            37: **                     the returned pointer can be directly passed to
        !            38: **                     CoRegisterClassObject and released later by calling the
        !            39: **                     Release method of the interface.
        !            40: */
        !            41: LPCLASSFACTORY WINAPI AppClassFactory_Create(void)
        !            42: {
        !            43:     LPAPPCLASSFACTORY lpAppClassFactory;
        !            44:     LPMALLOC lpMalloc;
        !            45:     
        !            46:     if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
        !            47:         return NULL;
        !            48:     
        !            49:     lpAppClassFactory = (LPAPPCLASSFACTORY)lpMalloc->lpVtbl->Alloc(
        !            50:             lpMalloc, (sizeof(APPCLASSFACTORY)));
        !            51:     lpMalloc->lpVtbl->Release(lpMalloc);
        !            52:     if (! lpAppClassFactory) return NULL;
        !            53: 
        !            54:     lpAppClassFactory->m_lpVtbl = &g_AppClassFactoryVtbl;
        !            55:     lpAppClassFactory->m_cRef   = 1;
        !            56:     lpAppClassFactory->m_cLock  = 0;
        !            57: 
        !            58:     return (LPCLASSFACTORY)lpAppClassFactory;
        !            59: }
        !            60: 
        !            61: 
        !            62: /*************************************************************************
        !            63: ** OleApp::IClassFactory interface implementation
        !            64: *************************************************************************/
        !            65: 
        !            66: STDMETHODIMP AppClassFactory_QueryInterface(
        !            67:         LPCLASSFACTORY lpThis, REFIID riid, LPVOID FAR* ppvObj)
        !            68: {
        !            69:     LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
        !            70:     SCODE scode;
        !            71: 
        !            72:     // Two interfaces supported: IUnknown, IClassFactory
        !            73: 
        !            74:     if (IsEqualIID(riid, &IID_IClassFactory) || 
        !            75:                        IsEqualIID(riid, &IID_IUnknown)) {
        !            76:         lpAppClassFactory->m_cRef++;   // A pointer to this object is returned
        !            77:         *ppvObj = lpThis;
        !            78:         scode = S_OK;
        !            79:     }
        !            80:     else {                 // unsupported interface
        !            81:         *ppvObj = NULL;
        !            82:         scode = E_NOINTERFACE;
        !            83:     }
        !            84: 
        !            85:     return ResultFromScode(scode);
        !            86: }
        !            87: 
        !            88: 
        !            89: STDMETHODIMP_(ULONG) AppClassFactory_AddRef(LPCLASSFACTORY lpThis)
        !            90: {
        !            91:     LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
        !            92:     return ++lpAppClassFactory->m_cRef;
        !            93: }
        !            94: 
        !            95: STDMETHODIMP_(ULONG) AppClassFactory_Release(LPCLASSFACTORY lpThis)
        !            96: {
        !            97:     LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
        !            98:     LPMALLOC lpMalloc;
        !            99: 
        !           100:     if (--lpAppClassFactory->m_cRef != 0) // Still used by others
        !           101:         return lpAppClassFactory->m_cRef;
        !           102: 
        !           103:     // Free storage
        !           104:     if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) 
        !           105:         return 0;
        !           106: 
        !           107:     lpMalloc->lpVtbl->Free(lpMalloc, lpAppClassFactory);
        !           108:     lpMalloc->lpVtbl->Release(lpMalloc);
        !           109:     return 0;
        !           110: }
        !           111: 
        !           112: 
        !           113: STDMETHODIMP AppClassFactory_CreateInstance (
        !           114:         LPCLASSFACTORY      lpThis,
        !           115:         LPUNKNOWN           lpUnkOuter,
        !           116:         REFIID              riid,
        !           117:         LPVOID FAR*         lplpvObj
        !           118: )
        !           119: {
        !           120:     LPOUTLINEAPP       lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
        !           121:     LPOLEDOC           lpOleDoc;
        !           122:     HRESULT                    hrErr;
        !           123: 
        !           124:     OLEDBG_BEGIN2("AppClassFactory_CreateInstance\r\n")
        !           125: 
        !           126:     /* OLE2NOTE: we must make sure to set all out parameters to NULL. */
        !           127:     *lplpvObj = NULL;
        !           128: 
        !           129:     /*********************************************************************
        !           130:     ** OLE2NOTE: this is an SDI app; it can only create and support one
        !           131:     **    instance. After the instance is created, the OLE libraries
        !           132:     **    should not call CreateInstance again. it is a good practise
        !           133:     **    to specifically guard against this.
        !           134:     *********************************************************************/
        !           135: 
        !           136:     if (lpOutlineApp->m_lpDoc != NULL)
        !           137:         return ResultFromScode(E_UNEXPECTED);
        !           138: 
        !           139:     /* OLE2NOTE: create a new document instance. by the time we return
        !           140:        **    from this method the document's refcnt must be 1.
        !           141:     */
        !           142:     lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE);
        !           143:     lpOleDoc = (LPOLEDOC)lpOutlineApp->m_lpDoc;
        !           144:     if (! lpOleDoc) {
        !           145:         OLEDBG_END2
        !           146:         return ResultFromScode(E_OUTOFMEMORY);
        !           147:     }
        !           148: 
        !           149:     /* OLE2NOTE: retrieve pointer to requested interface. the ref cnt
        !           150:     **    of the object after OutlineApp_CreateDoc is 0. this call to
        !           151:     **    QueryInterface will increment the refcnt to 1. the object
        !           152:     **    returned from IClassFactory::CreateInstance should have a
        !           153:     **    refcnt of 1 and be controlled by the caller. If the caller
        !           154:     **    releases the document, the document should be destroyed.
        !           155:     */
        !           156:     hrErr = OleDoc_QueryInterface(lpOleDoc, riid, lplpvObj);
        !           157: 
        !           158:     OLEDBG_END2
        !           159:     return hrErr;
        !           160: }
        !           161: 
        !           162: 
        !           163: STDMETHODIMP AppClassFactory_LockServer (
        !           164:         LPCLASSFACTORY      lpThis,
        !           165:         BOOL                fLock
        !           166: )
        !           167: {
        !           168:     LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis;
        !           169:     LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
        !           170:        HRESULT hrErr;
        !           171: 
        !           172:     OLEDBG_BEGIN2("AppClassFactory_LockServer\r\n")
        !           173: 
        !           174: #if defined( _DEBUG )
        !           175:     if (fLock) {
        !           176:         ++lpAppClassFactory->m_cLock;
        !           177: 
        !           178:         OleDbgOutRefCnt3(
        !           179:                 "AppClassFactory_LockServer: cLock++\r\n", 
        !           180:                                lpAppClassFactory, lpAppClassFactory->m_cLock);
        !           181:     } else {
        !           182: 
        !           183:         /* OLE2NOTE: when there are no open documents and the app is not
        !           184:         **    under the control of the user and there are no outstanding
        !           185:         **    locks on the app, then revoke our ClassFactory to enable the
        !           186:         **    app to shut down.
        !           187:         */
        !           188:         OleDbgAssertSz (lpAppClassFactory->m_cLock > 0,
        !           189:                 "AppClassFactory_LockServer(FALSE) called with cLock == 0"
        !           190:         );
        !           191: 
        !           192:                --lpAppClassFactory->m_cLock;
        !           193: 
        !           194:         if (lpAppClassFactory->m_cLock == 0) {
        !           195:             OleDbgOutRefCnt2(
        !           196:                     "AppClassFactory_LockServer: UNLOCKED\r\n", 
        !           197:                                        lpAppClassFactory, lpAppClassFactory->m_cLock);
        !           198:         } else {
        !           199:             OleDbgOutRefCnt3(
        !           200:                     "AppClassFactory_LockServer: cLock--\r\n",
        !           201:                                        lpAppClassFactory, lpAppClassFactory->m_cLock);
        !           202:         }
        !           203:     }
        !           204: #endif // _DEBUG
        !           205:                
        !           206:        /* OLE2NOTE: in order to hold the application alive we call
        !           207:        **    CoLockObjectExternal to add a strong reference to our app
        !           208:        **    object. this will keep the app alive when all other external
        !           209:        **    references release us. if the user issues File.Exit the
        !           210:        **    application will shut down in any case ignoring any
        !           211:        **    outstanding LockServer locks because CoDisconnectObject is
        !           212:        **    called in OleApp_CloseAllDocsAndExitCommand. this will
        !           213:        **    forceably break any existing strong reference counts
        !           214:        **    including counts that we add ourselves by calling
        !           215:        **    CoLockObjectExternal and guarantee that the App object gets
        !           216:        **    its final release (ie. cRefs goes to 0).
        !           217:        */
        !           218:        hrErr = OleApp_Lock(lpOleApp, fLock, TRUE /* fLastUnlockReleases */);
        !           219: 
        !           220:     OLEDBG_END2
        !           221:        return hrErr;
        !           222: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.