Annotation of mstools/ole20/samples/outline/classfac.c, revision 1.1.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.