Annotation of mstools/mfc/src/olesvr.cpp, revision 1.1.1.1

1.1       root        1: // This is a part of the Microsoft Foundation Classes C++ library. 
                      2: // Copyright (C) 1992 Microsoft Corporation 
                      3: // All rights reserved. 
                      4: //  
                      5: // This source code is only intended as a supplement to the 
                      6: // Microsoft Foundation Classes Reference and Microsoft 
                      7: // QuickHelp documentation provided with the library. 
                      8: // See these sources for detailed information regarding the 
                      9: // Microsoft Foundation Classes product. 
                     10: 
                     11: #include "afxole.h"
                     12: #pragma hdrstop
                     13: 
                     14: #include "oleptr_.h"
                     15: #include <limits.h>
                     16: 
                     17: #include "shellapi.h"
                     18: 
                     19: #ifdef AFX_OLE_SEG
                     20: #pragma code_seg(AFX_OLE_SEG)
                     21: #endif
                     22: 
                     23: #ifdef _DEBUG
                     24: #undef THIS_FILE
                     25: static char BASED_CODE THIS_FILE[] = __FILE__;
                     26: #endif
                     27: 
                     28: #define OLEEXPORT FAR PASCAL _export
                     29: 
                     30: /////////////////////////////////////////////////////////////////////////////
                     31: // Helper class for locking out main message pump during callbacks
                     32: 
                     33: class LOCK_PUMP
                     34: {
                     35: public:
                     36:        LOCK_PUMP()
                     37:        {
                     38: #ifdef _DEBUG
                     39:                AfxGetApp()->EnablePump(FALSE);
                     40: #endif
                     41:        }
                     42: 
                     43:        ~LOCK_PUMP()
                     44:        {
                     45: #ifdef _DEBUG
                     46:                AfxGetApp()->EnablePump(TRUE);
                     47: #endif
                     48:        }
                     49: };
                     50: 
                     51: #define OLE_TRACE(string)   \
                     52:        if (afxTraceFlags & 0x10)   \
                     53:                TRACE(string)
                     54: 
                     55: /////////////////////////////////////////////////////////////////////////////
                     56: // OLEOBJECT callbacks mapping to COleServerItem virtual functions
                     57: 
                     58: inline COleServerItem * COleServerItem::FromLp(LPOLEOBJECT lpObject)
                     59: {
                     60:        ASSERT(lpObject != NULL);
                     61:        COleServerItem* pItem;
                     62:        pItem = (COleServerItem*) GetPtrFromFarPtr(lpObject, sizeof(CObject));
                     63:        ASSERT(lpObject == &pItem->m_oleObject);
                     64:        return pItem;
                     65: }
                     66: 
                     67: // friend class to get access to COleServerItem protected implementations
                     68: struct _afxOleServerItemImplementation
                     69: {
                     70: 
                     71:        static LPVOID OLEEXPORT
                     72:        QueryProtocol(LPOLEOBJECT lpObject, OLE_LPCSTR lpszProtocol)
                     73:        {
                     74:                LOCK_PUMP lock;
                     75:                OLE_TRACE("COleServerItem::OnQueryProtocol()\n");
                     76:                return COleServerItem::FromLp(lpObject)->OnQueryProtocol(lpszProtocol);
                     77:        }
                     78: 
                     79:        static OLESTATUS OLEEXPORT
                     80:        Release(LPOLEOBJECT lpObject)
                     81:        {
                     82:                LOCK_PUMP lock;
                     83:                OLE_TRACE("COleServerItem::OnRelease()\n");
                     84:                return COleServerItem::FromLp(lpObject)->OnRelease();
                     85:        }
                     86: 
                     87:        static OLESTATUS OLEEXPORT
                     88:        Show(LPOLEOBJECT lpObject, BOOL bTakeFocus)
                     89:        {
                     90:                LOCK_PUMP lock;
                     91:                OLE_TRACE("COleServerItem::OnShow()\n");
                     92:                return COleServerItem::FromLp(lpObject)->OnShow(bTakeFocus);
                     93:        }
                     94: 
                     95:        static OLESTATUS OLEEXPORT
                     96:        DoVerb(LPOLEOBJECT lpObject, UINT nVerb, BOOL bShow, BOOL bTakeFocus)
                     97:        {
                     98:                LOCK_PUMP lock;
                     99:                OLE_TRACE("COleServerItem::OnDoVerb()\n");
                    100: 
                    101:                OLESTATUS status;
                    102:                status = COleServerItem::FromLp(lpObject)->OnDoVerb(nVerb, bShow,
                    103:                        bTakeFocus);
                    104: #ifdef _DEBUG
                    105:                if ((afxTraceFlags & 0x10) && status != OLE_OK)
                    106:                        TRACE("COleServerItem::OnDoVerb(%d) failed\n", nVerb);
                    107: #endif
                    108:                return status;
                    109:        }
                    110: 
                    111:        static OLESTATUS OLEEXPORT
                    112:        GetData(LPOLEOBJECT lpObject, OLECLIPFORMAT nFormat,
                    113:                LPHANDLE lphDataReturn)
                    114:        {
                    115:                LOCK_PUMP lock;
                    116:                OLE_TRACE("COleServerItem::OnGetData()\n");
                    117:                OLESTATUS status;
                    118:                status = COleServerItem::FromLp(lpObject)->OnGetData(nFormat, lphDataReturn);
                    119: #ifdef _DEBUG
                    120:                if ((afxTraceFlags & 0x10) && status != OLE_OK)
                    121:                        TRACE("COleServerItem::OnGetData() failed to get format 0x%x\n",
                    122:                                        nFormat);
                    123: #endif
                    124:                return status;
                    125:        }
                    126: 
                    127:        static OLESTATUS OLEEXPORT
                    128:        SetData(LPOLEOBJECT lpObject, OLECLIPFORMAT nFormat, HANDLE hData)
                    129:        {
                    130:                LOCK_PUMP lock;
                    131:                OLE_TRACE("COleServerItem::OnSetData()\n");
                    132:                return COleServerItem::FromLp(lpObject)->OnSetData(nFormat, hData);
                    133:        }
                    134: 
                    135:        static OLESTATUS OLEEXPORT
                    136:        SetTargetDevice(LPOLEOBJECT lpObject, HANDLE hData)
                    137:        {
                    138:                LOCK_PUMP lock;
                    139:                OLE_TRACE("COleServerItem::OnSetTargetDevice()\n");
                    140: 
                    141:                OLESTATUS status;
                    142:                status = COleServerItem::FromLp(lpObject)->OnSetTargetDevice(
                    143:                        (LPOLETARGETDEVICE)((hData == NULL) ? NULL : ::GlobalLock(hData)));
                    144: 
                    145:                if (hData != NULL)
                    146:                {
                    147:                        ::GlobalUnlock(hData);
                    148:                        ::GlobalFree(hData);
                    149:                }
                    150:                return status;
                    151:        }
                    152: 
                    153:        static OLESTATUS OLEEXPORT
                    154:        SetBounds(LPOLEOBJECT lpObject, OLE_CONST RECT FAR* lpRect)
                    155:        {
                    156:                LOCK_PUMP lock;
                    157:                OLE_TRACE("COleServerItem::SetBounds()\n");
                    158:                return COleServerItem::FromLp(lpObject)->OnSetBounds((LPRECT)lpRect);
                    159:        }
                    160: 
                    161:        static OLECLIPFORMAT OLEEXPORT
                    162:        EnumFormats(LPOLEOBJECT lpObject, OLECLIPFORMAT nFormat)
                    163:        {
                    164:                OLECLIPFORMAT wNext;
                    165:                LOCK_PUMP lock;
                    166:                wNext = COleServerItem::FromLp(lpObject)->OnEnumFormats(nFormat);
                    167: #ifdef _DEBUG
                    168:                if (afxTraceFlags & 0x10)
                    169:                        TRACE("COleServerItem::OnEnumFormats(0x%x) returns 0x%x\n",
                    170:                                nFormat, wNext);
                    171: #endif
                    172:                return wNext;
                    173:        }
                    174: 
                    175:        static OLESTATUS OLEEXPORT
                    176:        SetColorScheme(LPOLEOBJECT lpObject, OLE_CONST LOGPALETTE FAR* lpLogPalette)
                    177:        {
                    178:                LOCK_PUMP lock;
                    179:                OLE_TRACE("COleServerItem::SetColorScheme()\n");
                    180:                return COleServerItem::FromLp(lpObject)->
                    181:                                OnSetColorScheme((LPLOGPALETTE)lpLogPalette);
                    182:        }
                    183: 
                    184: };
                    185: 
                    186: static struct _OLEOBJECTVTBL NEAR objectVtbl =
                    187: {
                    188:        &_afxOleServerItemImplementation::QueryProtocol,
                    189:        &_afxOleServerItemImplementation::Release,
                    190:        &_afxOleServerItemImplementation::Show,
                    191:        &_afxOleServerItemImplementation::DoVerb,
                    192:        &_afxOleServerItemImplementation::GetData,
                    193:        &_afxOleServerItemImplementation::SetData,
                    194:        &_afxOleServerItemImplementation::SetTargetDevice,
                    195:        &_afxOleServerItemImplementation::SetBounds,
                    196:        &_afxOleServerItemImplementation::EnumFormats,
                    197:        &_afxOleServerItemImplementation::SetColorScheme,
                    198: };
                    199: 
                    200: //////////////////////////////////////////////////////////////////////////////
                    201: // Server view of embedded OLEOBJECT (includes back pointer to OLECLIENT)
                    202: 
                    203: IMPLEMENT_DYNAMIC(COleServerItem, CObject)
                    204: 
                    205: COleServerItem::COleServerItem()
                    206: {
                    207:        m_oleObject.lpvtbl = &objectVtbl;
                    208:        m_pDocument = NULL;
                    209:        m_hPalette = NULL;
                    210:        m_lpClient = NULL;  // will be set later
                    211:        m_rectBounds.SetRectEmpty();
                    212: }
                    213: 
                    214: COleServerItem::~COleServerItem()
                    215: {
                    216:        ASSERT(m_lpClient == NULL);     // must be released first
                    217:        if (m_hPalette != NULL)
                    218:                ::DeleteObject(m_hPalette);
                    219: }
                    220: 
                    221: void
                    222: COleServerItem::BeginRevoke()   // Start revoking the client connection
                    223: {
                    224:        ASSERT(m_lpClient != NULL);
                    225: 
                    226:        OLESTATUS status = ::OleRevokeObject(m_lpClient);
                    227:        ASSERT(status == OLE_OK || status == OLE_WAIT_FOR_RELEASE);
                    228:        // revoke will not be finished until OnRelease called
                    229: }
                    230: 
                    231: 
                    232: int
                    233: COleServerItem::NotifyClient(OLE_NOTIFICATION wNotify)
                    234: {
                    235:        ASSERT(m_lpClient != NULL);
                    236:        ASSERT(wNotify <= OLE_QUERY_RETRY); // last valid notification code
                    237: 
                    238: #ifdef _DEBUG
                    239:        if (afxTraceFlags & 0x10)
                    240:                TRACE("Notifying client item (wNotification = %d)\n", wNotify);
                    241: #endif
                    242:        return (*m_lpClient->lpvtbl->CallBack)(m_lpClient, wNotify, &m_oleObject);
                    243: }
                    244: 
                    245: //////////////////////////////////////////////////////////////////////////////
                    246: // Default implementations
                    247: 
                    248: OLESTATUS
                    249: COleServerItem::OnRelease()
                    250: {
                    251:        ASSERT(m_lpClient != NULL);
                    252:        m_lpClient = NULL;
                    253: 
                    254:        return OLE_OK;
                    255: }
                    256: 
                    257: 
                    258: OLESTATUS
                    259: COleServerItem::OnSetTargetDevice(LPOLETARGETDEVICE /*lpTargetDevice*/)
                    260: {
                    261:        // default to ignore request
                    262:        return OLE_OK;
                    263: }
                    264: 
                    265: 
                    266: BOOL
                    267: COleServerItem::OnGetTextData(CString& /*rStringReturn*/)
                    268: {
                    269:        // default to not supported
                    270:        return FALSE;
                    271: }
                    272: 
                    273: 
                    274: OLESTATUS
                    275: COleServerItem::OnExtraVerb(UINT /*nVerb*/)
                    276: {
                    277:        return OLE_ERROR_DOVERB;    // Error in sending do verb, or invalid
                    278: }
                    279: 
                    280: 
                    281: // Overridables you do not have to override
                    282: LPVOID
                    283: COleServerItem::OnQueryProtocol(LPCSTR lpszProtocol) const
                    284: {
                    285:        if (_fstrcmp(lpszProtocol, "StdFileEditing") == 0)
                    286:                return (LPVOID) &m_oleObject;
                    287: 
                    288:        return NULL;        // not supported
                    289: }
                    290: 
                    291: 
                    292: OLESTATUS
                    293: COleServerItem::OnSetColorScheme(LPLOGPALETTE lpLogPalette)
                    294: {
                    295:        // save in item palette
                    296:        HPALETTE hNewPal = ::CreatePalette(lpLogPalette);
                    297: 
                    298:        if (hNewPal == NULL)
                    299:                return OLE_ERROR_PALETTE;
                    300: 
                    301:        if (m_hPalette != NULL)
                    302:                ::DeleteObject(m_hPalette);
                    303:        m_hPalette = hNewPal;
                    304:        return OLE_OK;
                    305: }
                    306: 
                    307: OLESTATUS
                    308: COleServerItem::OnSetBounds(LPRECT lpRect)
                    309: {
                    310:        m_rectBounds = lpRect;
                    311:        return OLE_OK;
                    312: }
                    313: 
                    314: 
                    315: OLESTATUS
                    316: COleServerItem::OnDoVerb(UINT nVerb, BOOL bShow, BOOL bTakeFocus)
                    317: {
                    318:        OLESTATUS status;
                    319:        if (nVerb == OLEVERB_PRIMARY)
                    320:        {
                    321:                status = OLE_OK;
                    322:        }
                    323:        else
                    324:        {
                    325:                status = OnExtraVerb(nVerb);
                    326:        }
                    327: 
                    328:        if ((status == OLE_OK) && bShow)
                    329:                status = OnShow(bTakeFocus);
                    330:        return status;
                    331: }
                    332: 
                    333: 
                    334: // Clipboard formats
                    335: 
                    336: static UINT cfNative = ::RegisterClipboardFormat("Native");
                    337: static UINT cfOwnerLink = ::RegisterClipboardFormat("OwnerLink");
                    338: static UINT cfObjectLink = ::RegisterClipboardFormat("ObjectLink");
                    339: 
                    340: static UINT formats[] =
                    341: {
                    342:        cfNative,           // native data format
                    343:        CF_METAFILEPICT,    // item rendered as a metafile
                    344:        CF_TEXT,            // optionally supported if OnGetTextData implemented
                    345:        NULL
                    346: };
                    347: 
                    348: OLECLIPFORMAT
                    349: COleServerItem::OnEnumFormats(OLECLIPFORMAT nFormat) const
                    350: {
                    351:        int index = 0;
                    352:        if (nFormat != 0)
                    353:        {
                    354:                // find the last element
                    355:                while (formats[index++] != nFormat)
                    356:                        ;
                    357:        }
                    358:        return (OLECLIPFORMAT)formats[index];
                    359: }
                    360: 
                    361: HANDLE
                    362: COleServerItem::GetNativeData()
                    363: {
                    364:        // get native data via serialization
                    365:        CSharedFile memFile;
                    366: 
                    367:        TRY
                    368:        {
                    369:                CArchive    getArchive(&memFile, CArchive::store);
                    370:                this->Serialize(getArchive);        // store to archive
                    371:        }
                    372:        CATCH (CNotSupportedException, e)
                    373:        {
                    374:                memFile.Close();
                    375:                return NULL;        // not supported
                    376:        }
                    377:        AND_CATCH (CException, e)
                    378:        {
                    379:                memFile.Close();
                    380:                THROW_LAST();       // will be caught in GetData
                    381:        }
                    382:        END_CATCH
                    383:        return memFile.Detach();
                    384: }
                    385: 
                    386: HANDLE
                    387: COleServerItem::GetMetafileData()
                    388: {
                    389:        CMetaFileDC dc;
                    390:        if (!dc.Create())
                    391:                return NULL;
                    392: 
                    393:        if (m_hPalette)
                    394:        {
                    395:                ::SelectPalette(dc.m_hDC, m_hPalette, TRUE);
                    396:                dc.RealizePalette();
                    397:        }
                    398: 
                    399:        // Paint directly into the metafile.
                    400:        if (!OnDraw(&dc))
                    401:        {
                    402:                OLE_TRACE("calling COleServerItem::OnDraw() failed\n");
                    403:                return NULL;    // will destroy DC
                    404:        }
                    405: 
                    406:        HMETAFILE hMF = (HMETAFILE)dc.Close();
                    407:        if (hMF == NULL)
                    408:                return NULL;
                    409: 
                    410:        HANDLE hPict;
                    411:        if ((hPict = ::GlobalAlloc(GMEM_DDESHARE, sizeof(METAFILEPICT))) == NULL)
                    412:        {
                    413:                DeleteMetaFile(hMF);
                    414:                return NULL;
                    415:        }
                    416: 
                    417:        LPMETAFILEPICT lpPict;
                    418:        if ((lpPict = (LPMETAFILEPICT)::GlobalLock(hPict)) == NULL)
                    419:        {
                    420:                DeleteMetaFile(hMF);
                    421:                ::GlobalFree(hPict);
                    422:                return NULL;
                    423:        }
                    424: 
                    425:        lpPict->mm = MM_ANISOTROPIC;
                    426:        lpPict->hMF = hMF;
                    427:        lpPict->xExt = m_rectBounds.Width();
                    428:        lpPict->yExt = m_rectBounds.Height();   // will be negative for HiMetric
                    429:        ::GlobalUnlock(hPict);
                    430:        return hPict;
                    431: }
                    432: 
                    433: 
                    434: OLESTATUS
                    435: COleServerItem::OnGetData(OLECLIPFORMAT nFormat, LPHANDLE lphReturn)
                    436: {
                    437:        HANDLE hData = NULL;    // default to not supported
                    438: 
                    439:        TRY
                    440:        {
                    441:                if (nFormat == cfNative)
                    442:                {
                    443:                        hData = GetNativeData();
                    444:                }
                    445:                else if (nFormat == CF_METAFILEPICT)
                    446:                {
                    447:                        hData = GetMetafileData();
                    448:                }
                    449:                else if (nFormat == CF_TEXT) 
                    450:                {
                    451:                        CString text;
                    452:                        if (OnGetTextData(text))
                    453:                        {
                    454:                                // allocate a global block for the string
                    455:                                hData = ::GlobalAlloc(GMEM_DDESHARE, text.GetLength() + 1);
                    456:                                if (hData == NULL)
                    457:                                        AfxThrowMemoryException();
                    458: 
                    459:                                LPSTR  lpszText = (LPSTR)::GlobalLock(hData);
                    460:                                ASSERT(lpszText != NULL);
                    461:                                _fstrcpy(lpszText, (const char*) text);
                    462:                                ::GlobalUnlock(hData);
                    463:                        }
                    464:                }
                    465:                else
                    466:                {
                    467:                        TRACE("Warning: OLE get data, unknown format %d\n", nFormat);
                    468:                }
                    469:        }
                    470:        CATCH (COleException, e)
                    471:        {
                    472:                return e->m_status;
                    473:        }
                    474:        AND_CATCH (CException, e)
                    475:        {
                    476:                // other exceptions
                    477:                return OLE_ERROR_MEMORY;
                    478:        }
                    479:        END_CATCH
                    480: 
                    481:        if (hData == NULL)
                    482:                return OLE_ERROR_FORMAT;        // not supported
                    483: 
                    484:        // return the data
                    485:        *lphReturn = hData;
                    486:        return OLE_OK;
                    487: }
                    488: 
                    489: 
                    490: OLESTATUS
                    491: COleServerItem::OnSetData(OLECLIPFORMAT nFormat, HANDLE hData)
                    492: {
                    493:        if (nFormat != cfNative)
                    494:        {
                    495:                ::GlobalFree(hData);
                    496:                return OLE_ERROR_FORMAT;    // Requested format is not available
                    497:        }
                    498: 
                    499:        // set native data via serialization
                    500:        CSharedFile memFile;
                    501:        memFile.SetHandle(hData);
                    502: 
                    503:        TRY
                    504:        {
                    505:                CArchive    setArchive(&memFile, CArchive::load);
                    506:                this->Serialize(setArchive);        // load me
                    507:        }
                    508:        CATCH (CException, e)
                    509:        {
                    510:                memFile.Close();
                    511:                return OLE_ERROR_GENERIC;
                    512:        }
                    513:        END_CATCH
                    514: 
                    515:        return OLE_OK;
                    516: }
                    517: 
                    518: 
                    519: /////////////////////////////////////////////////////////////////////////////
                    520: /////////////////////////////////////////////////////////////////////////////
                    521: // COleServerDoc
                    522: 
                    523: inline COleServerDoc * COleServerDoc::FromLp(LPOLESERVERDOC lpServerDoc)
                    524: {
                    525:        COleServerDoc* pDoc;
                    526:        pDoc = (COleServerDoc*) GetPtrFromFarPtr(lpServerDoc, sizeof(CObject));
                    527:        ASSERT(lpServerDoc == &pDoc->m_oleServerDoc);
                    528:        return pDoc;
                    529: }
                    530: 
                    531: // friend class to get access to COleServerDoc protected implementations
                    532: struct _afxOleServerDocImplementation
                    533: {
                    534: 
                    535:        static OLESTATUS OLEEXPORT
                    536:        Save(LPOLESERVERDOC lpServerDoc)
                    537:        {
                    538:                LOCK_PUMP lock;
                    539:                OLE_TRACE("COleServerDoc::OnSave()\n");
                    540:                return COleServerDoc::FromLp(lpServerDoc)->OnSave();
                    541:        }
                    542: 
                    543:        static OLESTATUS OLEEXPORT
                    544:        Close(LPOLESERVERDOC lpServerDoc)
                    545:        {
                    546:                LOCK_PUMP lock;
                    547:                OLE_TRACE("COleServerDoc::OnClose()\n");
                    548:                return COleServerDoc::FromLp(lpServerDoc)->OnClose();
                    549:        }
                    550: 
                    551:        static OLESTATUS OLEEXPORT
                    552:        SetHostNames(LPOLESERVERDOC lpServerDoc,
                    553:                OLE_LPCSTR lpszClient, OLE_LPCSTR lpszDoc)
                    554:        {
                    555:                LOCK_PUMP lock;
                    556:                OLE_TRACE("COleServerDoc::OnSetHostNames()\n");
                    557:                OLESTATUS status = COleServerDoc::FromLp(lpServerDoc)->OnSetHostNames(
                    558:                        lpszClient, lpszDoc);
                    559:                return status;
                    560:        }
                    561: 
                    562:        static OLESTATUS OLEEXPORT
                    563:        SetDocDimensions(LPOLESERVERDOC lpServerDoc, OLE_CONST RECT FAR* lpRect)
                    564:        {
                    565:                LOCK_PUMP lock;
                    566:                OLE_TRACE("COleServerDoc::OnSetDocDimensions()\n");
                    567:                return COleServerDoc::FromLp(lpServerDoc)->OnSetDocDimensions((LPRECT)lpRect);
                    568:        }
                    569: 
                    570:        static OLESTATUS OLEEXPORT
                    571:        Release(LPOLESERVERDOC lpServerDoc)
                    572:        {
                    573:                LOCK_PUMP lock;
                    574:                OLE_TRACE("COleServerDoc::OnRelease()\n");
                    575:                return COleServerDoc::FromLp(lpServerDoc)->OnRelease();
                    576:        }
                    577: 
                    578:        static OLESTATUS OLEEXPORT
                    579:        SetColorScheme(LPOLESERVERDOC lpServerDoc,
                    580:                OLE_CONST LOGPALETTE FAR* lpLogPalette)
                    581:        {
                    582:                LOCK_PUMP lock;
                    583:                OLE_TRACE("COleServerDoc::OnSetColorScheme()\n");
                    584:                OLESTATUS status = COleServerDoc::FromLp(lpServerDoc)->OnSetColorScheme(
                    585:                        (LPLOGPALETTE)lpLogPalette);
                    586:                return status;
                    587:        }
                    588: 
                    589:        static OLESTATUS OLEEXPORT
                    590:        Execute(LPOLESERVERDOC lpServerDoc, HANDLE hCommands)
                    591:        {
                    592:                LOCK_PUMP lock;
                    593:                OLE_TRACE("COleServerDoc::OnExecute()\n");
                    594:                LPVOID  lpCommands = ::GlobalLock(hCommands);
                    595:                ASSERT(lpCommands != NULL);
                    596:                OLESTATUS status;
                    597:                status = COleServerDoc::FromLp(lpServerDoc)->OnExecute(lpCommands);
                    598:                ::GlobalUnlock(hCommands);
                    599:                return status;
                    600:        }
                    601: 
                    602:        static OLESTATUS OLEEXPORT
                    603:        GetObject(LPOLESERVERDOC lpServerDoc, OLE_LPCSTR lpszObjname,
                    604:                LPOLEOBJECT FAR * lplpObject, LPOLECLIENT lpClient)
                    605:        {
                    606:                COleServerDoc* pDoc = COleServerDoc::FromLp(lpServerDoc);
                    607:                COleServerItem* pItem;
                    608:                LOCK_PUMP lock;
                    609: 
                    610:                TRY
                    611:                {
                    612:                        if (lpszObjname == NULL || *lpszObjname == '\0')
                    613:                        {
                    614:                                OLE_TRACE("calling COleServerDoc::OnGetDocument\n");
                    615:                                pItem = pDoc->OnGetDocument();
                    616:                        }
                    617:                        else
                    618:                        {
                    619: #ifdef _DEBUG
                    620:                                if (afxTraceFlags & 0x10)
                    621:                                        TRACE("calling COleServerDoc::GetItem(%Fs)\n", lpszObjname);
                    622: #endif
                    623:                                pItem = pDoc->OnGetItem(lpszObjname);
                    624:                        }
                    625:                }
                    626:                CATCH (CException, e)
                    627:                {
                    628:                        return COleException::Process(e);
                    629:                }
                    630:                END_CATCH
                    631: 
                    632:                if (pItem == NULL)
                    633:                        return OLE_ERROR_GENERIC;
                    634: 
                    635:                pDoc->AddItem(pItem, lpClient);     // attaches everything
                    636:                *lplpObject = &pItem->m_oleObject;
                    637:                return OLE_OK;
                    638:        }
                    639: };
                    640: 
                    641: static struct _OLESERVERDOCVTBL NEAR serverDocVtbl =
                    642: {
                    643:        &_afxOleServerDocImplementation::Save,
                    644:        &_afxOleServerDocImplementation::Close,
                    645:        &_afxOleServerDocImplementation::SetHostNames,
                    646:        &_afxOleServerDocImplementation::SetDocDimensions,
                    647:        &_afxOleServerDocImplementation::GetObject,
                    648:        &_afxOleServerDocImplementation::Release,
                    649:        &_afxOleServerDocImplementation::SetColorScheme,
                    650:        &_afxOleServerDocImplementation::Execute,
                    651: };
                    652: 
                    653: /////////////////////////////////////////////////////////////////////////////
                    654: // COleServerDoc construction and other operations
                    655: 
                    656: COleServerDoc::COleServerDoc()
                    657: {
                    658:        m_oleServerDoc.lpvtbl = &serverDocVtbl;
                    659:        m_pServer = NULL;
                    660:        m_lhServerDoc = NULL;
                    661:        m_hPalette = NULL;
                    662:        m_bWaiting = FALSE;
                    663: }
                    664: 
                    665: IMPLEMENT_DYNAMIC(COleServerDoc, CObject)
                    666: 
                    667: COleServerDoc::~COleServerDoc()
                    668: {
                    669:        if (IsOpen())
                    670:                BeginRevoke();
                    671:        if (m_hPalette != NULL)
                    672:                ::DeleteObject(m_hPalette);
                    673: }
                    674: 
                    675: void
                    676: COleServerDoc::CheckAsync(OLESTATUS status)
                    677:        // throw exception if not ok to continue
                    678: {
                    679:        ASSERT(!m_bWaiting);
                    680: 
                    681:        if (status == OLE_WAIT_FOR_RELEASE)
                    682:        {
                    683:                m_bWaiting = TRUE;
                    684:                while (m_bWaiting)
                    685:                {
                    686:                        OLE_TRACE("OLE Server Doc waiting for release\n");
                    687:                        AfxGetApp()->PumpMessage();
                    688:                }
                    689:                m_bWaiting = FALSE;
                    690: 
                    691:                return;     // assume it worked
                    692:        }
                    693: 
                    694:        if (status == OLE_OK || status > OLE_WARN_DELETE_DATA)
                    695:        {
                    696:                // ok, or just a warning
                    697:                return;
                    698:        }
                    699: 
                    700:        // otherwise this error wasn't expected, so throw an exception
                    701:        TRACE("Warning: COleServerDoc operation failed %d, throwing exception\n", status);
                    702:        AfxThrowOleException(status);
                    703: }
                    704: 
                    705: OLESTATUS
                    706: COleServerDoc::BeginRevoke()
                    707:        // do not wait for async completion
                    708: {
                    709:        ASSERT(IsOpen());
                    710:        LHCLIENTDOC lh = m_lhServerDoc;
                    711:        ASSERT(lh != NULL);
                    712:        if (m_pServer != NULL)
                    713:                m_pServer->RemoveDocument(this);
                    714:        m_lhServerDoc = NULL;
                    715:        OLESTATUS status = ::OleRevokeServerDoc(lh);
                    716:        ASSERT(status == OLE_OK || status == OLE_WAIT_FOR_RELEASE);
                    717:        // revoke will not be finished until OnRelease called
                    718:        return status;
                    719: }
                    720: 
                    721: void
                    722: COleServerDoc::Revoke()
                    723:        // wait for async completion
                    724: {
                    725:        ASSERT(IsOpen());
                    726:        CheckAsync(BeginRevoke());
                    727: }
                    728: 
                    729: /////////////////////////////////////////////////////////////////////////////
                    730: // Interesting operations
                    731: 
                    732: BOOL
                    733: COleServerDoc::Register(COleServer* pServer, LPCSTR lpszDoc)
                    734: {
                    735:        ASSERT(m_lhServerDoc == NULL);      // one time only
                    736:        ASSERT(pServer != NULL);
                    737:        ASSERT(pServer->IsOpen());
                    738: 
                    739:        LHSERVERDOC lhDoc;
                    740:        if (::OleRegisterServerDoc(pServer->m_lhServer, lpszDoc,
                    741:                &m_oleServerDoc, &lhDoc) != OLE_OK)
                    742:        {
                    743:                return FALSE;
                    744:        }
                    745: 
                    746:        pServer->AddDocument(this, lhDoc);
                    747:        ASSERT(m_lhServerDoc == lhDoc); // make sure it connected it
                    748:        return TRUE;
                    749: }
                    750: 
                    751: void
                    752: COleServerDoc::NotifyRename(LPCSTR lpszNewName)
                    753: {
                    754:        ASSERT(IsOpen());
                    755:        ASSERT(lpszNewName != NULL);
                    756:        CheckAsync(::OleRenameServerDoc(m_lhServerDoc, lpszNewName));
                    757: }
                    758: 
                    759: void
                    760: COleServerDoc::NotifyRevert()
                    761: {
                    762:        ASSERT(IsOpen());
                    763:        CheckAsync(::OleRevertServerDoc(m_lhServerDoc));
                    764: }
                    765: 
                    766: void
                    767: COleServerDoc::NotifySaved()
                    768: {
                    769:        ASSERT(IsOpen());
                    770:        CheckAsync(::OleSavedServerDoc(m_lhServerDoc));
                    771: }
                    772: 
                    773: void
                    774: COleServerDoc::NotifyAllClients(OLE_NOTIFICATION wNotify)
                    775: {
                    776:        POSITION pos = GetStartPosition();
                    777:        COleServerItem* pItem;
                    778: 
                    779:        while ((pItem = GetNextItem(pos)) != NULL)
                    780:        {
                    781:                pItem->NotifyClient(wNotify);
                    782:        }
                    783: }
                    784: 
                    785: void
                    786: COleServerDoc::AddItem(COleServerItem* pItem, LPOLECLIENT lpClient)
                    787: {
                    788:        ASSERT_VALID(pItem);
                    789: 
                    790:        // Attach handle to un-attached item
                    791:        ASSERT(pItem->m_lpClient == NULL);  // must be unattached !
                    792:        ASSERT(pItem->m_pDocument == NULL); // must be unconnected !
                    793:        pItem->m_lpClient = lpClient;
                    794:        pItem->m_pDocument = this;
                    795: }
                    796: 
                    797: /////////////////////////////////////////////////////////////////////////////
                    798: // COleServerDoc standard implementation of overridables
                    799: 
                    800: OLESTATUS
                    801: COleServerDoc::OnRelease()
                    802: {
                    803:        OLE_TRACE("COleServerDoc::OnRelease\n");
                    804:        m_bWaiting = FALSE;
                    805:        // close connection to OLE server doc
                    806:        m_lhServerDoc = NULL;
                    807:        return OLE_OK;
                    808: }
                    809: 
                    810: 
                    811: OLESTATUS
                    812: COleServerDoc::OnSave()
                    813: {
                    814:        return OLE_OK;
                    815: }
                    816: 
                    817: 
                    818: OLESTATUS
                    819: COleServerDoc::OnClose()
                    820: {
                    821:        ASSERT(IsOpen());
                    822:        BeginRevoke();
                    823:        return OLE_OK;
                    824: }
                    825: 
                    826: 
                    827: OLESTATUS
                    828: COleServerDoc::OnExecute(LPVOID /*lpCommands*/) // DDE commands
                    829: {
                    830:        return OLE_ERROR_COMMAND;
                    831: }
                    832: 
                    833: 
                    834: OLESTATUS
                    835: COleServerDoc::OnSetDocDimensions(LPRECT /*lpRect*/)
                    836: {
                    837:        return OLE_OK;      // default to ignore it
                    838: }
                    839: 
                    840: 
                    841: // Overridables you do not have to override
                    842: OLESTATUS
                    843: COleServerDoc::OnSetHostNames(LPCSTR /*lpszHost*/, LPCSTR /*lpszHostObj*/)
                    844: {
                    845:        return OLE_OK;
                    846: }
                    847: 
                    848: 
                    849: OLESTATUS
                    850: COleServerDoc::OnSetColorScheme(LPLOGPALETTE lpLogPalette)
                    851: {
                    852:        // save in global document palette
                    853:        HPALETTE hNewPal = ::CreatePalette(lpLogPalette);
                    854: 
                    855:        if (hNewPal == NULL)
                    856:                return OLE_ERROR_PALETTE;
                    857: 
                    858:        if (m_hPalette != NULL)
                    859:                ::DeleteObject(m_hPalette);
                    860:        m_hPalette = hNewPal;
                    861:        return OLE_OK;
                    862: }
                    863: 
                    864: /////////////////////////////////////////////////////////////////////////////
                    865: /////////////////////////////////////////////////////////////////////////////
                    866: // COleServer
                    867: 
                    868: inline COleServer * COleServer::FromLp(LPOLESERVER lpServer)
                    869: {
                    870:        COleServer* pOleServer;
                    871:        pOleServer = (COleServer*) GetPtrFromFarPtr(lpServer, sizeof(CObject));
                    872:        ASSERT(lpServer == &pOleServer->m_oleServer);
                    873:        return pOleServer;
                    874: }
                    875: 
                    876: // friend class to get access to COleServer protected implementations
                    877: struct _afxOleServerImplementation
                    878: {
                    879:        static OLESTATUS OLEEXPORT
                    880:        Exit(LPOLESERVER lpServer)
                    881:        {
                    882:                LOCK_PUMP lock;
                    883:                OLE_TRACE("COleServer::OnExit()\n");
                    884:                return COleServer::FromLp(lpServer)->OnExit();
                    885:        }
                    886: 
                    887:        static OLESTATUS OLEEXPORT
                    888:        Release(LPOLESERVER lpServer)
                    889:        {
                    890:                LOCK_PUMP lock;
                    891:                OLE_TRACE("COleServer::OnRelease()\n");
                    892:                return COleServer::FromLp(lpServer)->OnRelease();
                    893:        }
                    894: 
                    895:        static OLESTATUS OLEEXPORT
                    896:        Execute(LPOLESERVER lpServer, HANDLE hCommands)
                    897:        {
                    898:                LOCK_PUMP lock;
                    899:                OLE_TRACE("COleServer::Execute()\n");
                    900: 
                    901:                LPVOID  lpCommands = ::GlobalLock(hCommands);
                    902:                ASSERT(lpCommands != NULL);
                    903:                OLESTATUS status;
                    904:                status = COleServer::FromLp(lpServer)->OnExecute(lpCommands);
                    905:                ::GlobalUnlock(hCommands);
                    906:                return status;
                    907:        }
                    908: 
                    909:        static OLESTATUS OLEEXPORT
                    910:        Open(LPOLESERVER lpServer, LHSERVERDOC lhServerDoc,
                    911:                OLE_LPCSTR lpszDoc, LPOLESERVERDOC FAR * lplpServerDoc)
                    912:        {
                    913:                LOCK_PUMP lock;
                    914:                OLE_TRACE("COleServer::OnOpenDoc()\n");
                    915: 
                    916:                COleServer* pServer = COleServer::FromLp(lpServer);
                    917:                COleServerDoc* pDoc;
                    918: 
                    919:                TRY
                    920:                        pDoc = pServer->OnOpenDoc(lpszDoc);
                    921:                CATCH (CException, e)
                    922:                        return COleException::Process(e);
                    923:                END_CATCH
                    924: 
                    925:                if (pDoc == NULL)
                    926:                        return OLE_ERROR_GENERIC;
                    927:                pServer->AddDocument(pDoc, lhServerDoc);
                    928:                *lplpServerDoc = &pDoc->m_oleServerDoc;
                    929:                return OLE_OK;
                    930:        }
                    931: 
                    932:        static OLESTATUS OLEEXPORT
                    933:        Create(LPOLESERVER lpServer, LHSERVERDOC lhServerDoc,
                    934:                OLE_LPCSTR lpszClass, OLE_LPCSTR lpszDoc, LPOLESERVERDOC FAR * lplpServerDoc)
                    935:        {
                    936:                LOCK_PUMP lock;
                    937:                OLE_TRACE("COleServer::OnCreateDoc()\n");
                    938: 
                    939:                COleServer* pServer = COleServer::FromLp(lpServer);
                    940:                COleServerDoc* pDoc;
                    941: 
                    942:                TRY
                    943:                        pDoc = pServer->OnCreateDoc(lpszClass, lpszDoc);
                    944:                CATCH (CException, e)
                    945:                        return COleException::Process(e);
                    946:                END_CATCH
                    947: 
                    948:                if (pDoc == NULL)
                    949:                        return OLE_ERROR_GENERIC;
                    950: 
                    951:                pServer->AddDocument(pDoc, lhServerDoc);
                    952:                *lplpServerDoc = &pDoc->m_oleServerDoc;
                    953:                return OLE_OK;
                    954:        }
                    955: 
                    956:        static OLESTATUS OLEEXPORT
                    957:        CreateFromTemplate(LPOLESERVER lpServer, LHSERVERDOC lhServerDoc,
                    958:                OLE_LPCSTR lpszClass, OLE_LPCSTR lpszDoc, OLE_LPCSTR lpszTemplate,
                    959:                LPOLESERVERDOC FAR * lplpServerDoc)
                    960:        {
                    961:                LOCK_PUMP lock;
                    962:                OLE_TRACE("COleServer::OnCreateDocFromTemplate()\n");
                    963: 
                    964:                COleServer* pServer = COleServer::FromLp(lpServer);
                    965:                COleServerDoc* pDoc;
                    966: 
                    967:                TRY
                    968:                        pDoc = pServer->OnCreateDocFromTemplate(lpszClass,
                    969:                          lpszDoc, lpszTemplate);
                    970:                CATCH (CException, e)
                    971:                        return COleException::Process(e);
                    972:                END_CATCH
                    973: 
                    974:                if (pDoc == NULL)
                    975:                        return OLE_ERROR_GENERIC;
                    976:                pServer->AddDocument(pDoc, lhServerDoc);
                    977:                *lplpServerDoc = &pDoc->m_oleServerDoc;
                    978:                return OLE_OK;
                    979:        }
                    980: 
                    981:        static OLESTATUS OLEEXPORT
                    982:        Edit(LPOLESERVER lpServer, LHSERVERDOC lhServerDoc,
                    983:                OLE_LPCSTR lpszClass, OLE_LPCSTR lpszDoc, LPOLESERVERDOC FAR * lplpServerDoc)
                    984:        {
                    985:                LOCK_PUMP lock;
                    986:                OLE_TRACE("COleServer::OnEditDoc()\n");
                    987: 
                    988:                COleServer* pServer = COleServer::FromLp(lpServer);
                    989:                COleServerDoc* pDoc;
                    990: 
                    991:                TRY
                    992:                        pDoc = pServer->OnEditDoc(lpszClass, lpszDoc);
                    993:                CATCH (CException, e)
                    994:                        return COleException::Process(e);
                    995:                END_CATCH
                    996: 
                    997:                if (pDoc == NULL)
                    998:                        return OLE_ERROR_GENERIC;
                    999:                pServer->AddDocument(pDoc, lhServerDoc);
                   1000:                *lplpServerDoc = &pDoc->m_oleServerDoc;
                   1001:                return OLE_OK;
                   1002:        }
                   1003: };
                   1004: 
                   1005: static struct _OLESERVERVTBL NEAR serverVtbl =
                   1006: {
                   1007:        &_afxOleServerImplementation::Open,
                   1008:        &_afxOleServerImplementation::Create,
                   1009:        &_afxOleServerImplementation::CreateFromTemplate,
                   1010:        &_afxOleServerImplementation::Edit,
                   1011:        &_afxOleServerImplementation::Exit,
                   1012:        &_afxOleServerImplementation::Release,
                   1013:        &_afxOleServerImplementation::Execute,
                   1014: };
                   1015: 
                   1016: //////////////////////////////////////////////////////////////////////////////
                   1017: // COleServer construction etc
                   1018: 
                   1019: COleServer::COleServer(BOOL bLaunchEmbedded)
                   1020: {
                   1021:        m_oleServer.lpvtbl = &serverVtbl;
                   1022:        m_lhServer = NULL;
                   1023: 
                   1024:        m_cOpenDocuments = 0;
                   1025:        m_bLaunchEmbedded = bLaunchEmbedded;
                   1026: }
                   1027: 
                   1028: IMPLEMENT_DYNAMIC(COleServer, CObject)
                   1029: 
                   1030: COleServer::~COleServer()
                   1031: {
                   1032:        if (IsOpen())
                   1033:                BeginRevoke();          // server death
                   1034: }
                   1035: 
                   1036: void
                   1037: COleServer::BeginRevoke()
                   1038: {
                   1039:        ASSERT(IsOpen());
                   1040:        LHSERVER lhServer = m_lhServer;
                   1041: 
                   1042:        if (lhServer != NULL)
                   1043:        {
                   1044:                m_lhServer = NULL;      // closed for all intensive purposes
                   1045:                OLESTATUS status = ::OleRevokeServer(lhServer);
                   1046:                ASSERT(status == OLE_OK || status == OLE_WAIT_FOR_RELEASE);
                   1047:        }
                   1048:        // NOTE: will return before the Revoke is acknowledged
                   1049: }
                   1050: 
                   1051: BOOL
                   1052: COleServer::Register(LPCSTR lpszClass, BOOL bMultiInstance)
                   1053: {
                   1054:        ASSERT(m_lhServer == NULL);     // one time only
                   1055:        ASSERT(lpszClass != NULL);
                   1056: 
                   1057:        OLE_SERVER_USE use = bMultiInstance ? OLE_SERVER_MULTI : OLE_SERVER_SINGLE;
                   1058:        return ::OleRegisterServer(lpszClass, &m_oleServer, &m_lhServer,
                   1059:                AfxGetInstanceHandle(), use) == OLE_OK;
                   1060: }
                   1061: 
                   1062: //////////////////////////////////////////////////////////////////////////////
                   1063: // COleServer manages COleServerDocs
                   1064: 
                   1065: void COleServer::AddDocument(COleServerDoc* pDoc, LHSERVERDOC lhServerDoc)
                   1066: {
                   1067:        // Attach handle to un-open server document
                   1068:        ASSERT_VALID(pDoc);
                   1069:        ASSERT(pDoc->m_lhServerDoc == NULL);    // must be unregistered !
                   1070:        ASSERT(pDoc->m_pServer == NULL);        // must be dis-connected
                   1071:        ASSERT(lhServerDoc != NULL);
                   1072: 
                   1073:        // connect to server
                   1074:        pDoc->m_lhServerDoc = lhServerDoc;
                   1075:        pDoc->m_pServer = this;
                   1076:        m_cOpenDocuments++;
                   1077: }
                   1078: 
                   1079: void COleServer::RemoveDocument(COleServerDoc* pDoc)
                   1080: {
                   1081:        ASSERT(pDoc != NULL);
                   1082:        ASSERT(pDoc->m_pServer == this);
                   1083:        ASSERT(m_cOpenDocuments > 0);
                   1084: 
                   1085:        pDoc->m_pServer = NULL;
                   1086:        m_cOpenDocuments--;
                   1087: }
                   1088: 
                   1089: //////////////////////////////////////////////////////////////////////////////
                   1090: // COleServer default implementation of overridables
                   1091: 
                   1092: COleServerDoc* COleServer::OnOpenDoc(LPCSTR /*lpszDoc*/)
                   1093: {
                   1094:        return NULL;
                   1095: }
                   1096: 
                   1097: COleServerDoc* COleServer::OnCreateDocFromTemplate(LPCSTR /*lpszClass*/,
                   1098:        LPCSTR /*lpszDoc*/, LPCSTR /*lpszTemplate*/)
                   1099: {
                   1100:        return NULL;
                   1101: }
                   1102: 
                   1103: OLESTATUS COleServer::OnExecute(LPVOID /*lpCommands*/)  // DDE commands
                   1104: {
                   1105:        return OLE_ERROR_COMMAND;
                   1106: }
                   1107: 
                   1108: OLESTATUS COleServer::OnExit()
                   1109: {
                   1110:        if (IsOpen())
                   1111:        {
                   1112:                OLE_TRACE("COleServer::OnExit() Revoking server\n");
                   1113:                BeginRevoke();
                   1114:        }
                   1115:        return OLE_OK;
                   1116: }
                   1117: 
                   1118: OLESTATUS COleServer::OnRelease()
                   1119: {
                   1120:        CWnd* pMainWnd = AfxGetApp()->m_pMainWnd;
                   1121: 
                   1122:        if (IsOpen() && m_bLaunchEmbedded)
                   1123:        {
                   1124:                // there is a chance we should be shutting down
                   1125:                // shut down if no open documents, or if main window is invisible
                   1126:                if (m_cOpenDocuments == 0 || 
                   1127:                        (pMainWnd != NULL && !pMainWnd->IsWindowVisible()))
                   1128:                {
                   1129:                        OLE_TRACE("COleServer::OnRelease() Revoking server\n");
                   1130:                        BeginRevoke();
                   1131:                }
                   1132:        }
                   1133: 
                   1134:        // if someone has already revoked us
                   1135:        if (!IsOpen())
                   1136:        {
                   1137:                TRACE("COleServer::OnRelease() terminating server app\n");
                   1138:                OLE_TRACE("\tcalling ::PostQuitMessage\n");
                   1139:                ::PostQuitMessage(0);
                   1140:        }
                   1141: 
                   1142:        return OLE_OK;
                   1143: }
                   1144: 
                   1145: //////////////////////////////////////////////////////////////////////////////
                   1146: // Special register for server in case user does not run REGLOAD
                   1147: 
                   1148: BOOL AfxOleRegisterServerName(LPCSTR lpszClass, LPCSTR lpszLocalClassName)
                   1149: {
                   1150:        ASSERT(lpszClass != NULL && *lpszClass != '\0');
                   1151:        LONG    lSize;
                   1152:        char    szBuffer[OLE_MAXNAMESIZE];
                   1153: 
                   1154:        if (lpszLocalClassName == NULL || *lpszLocalClassName == '\0')
                   1155:        {
                   1156:                TRACE("Warning: no localized class name provided for server,"
                   1157:                        " using %Fs\n", lpszClass);
                   1158:                lpszLocalClassName = lpszClass;
                   1159:        }
                   1160: 
                   1161:        lSize = OLE_MAXNAMESIZE;
                   1162:        if (::RegQueryValue(HKEY_CLASSES_ROOT, lpszClass, szBuffer,
                   1163:                &lSize) == ERROR_SUCCESS)
                   1164:        {
                   1165:                // don't replace an existing localized name
                   1166:                TRACE("Server already has localized class name (%s)\n", szBuffer);
                   1167:        }
                   1168:        else
                   1169:        {
                   1170:                // set localized (user visible) class name
                   1171:                if (::RegSetValue(HKEY_CLASSES_ROOT, lpszClass, REG_SZ,
                   1172:                  lpszLocalClassName, _fstrlen(lpszLocalClassName)) != ERROR_SUCCESS)
                   1173:                        return FALSE;
                   1174:        }
                   1175: 
                   1176:        // set the path name for the server for "StdFileEditing" to this app
                   1177: 
                   1178:        // get name/path of executable
                   1179:        char szPathName[256];
                   1180:        ::GetModuleFileName(AfxGetInstanceHandle(), szPathName,
                   1181:                sizeof(szPathName)-1);
                   1182: 
                   1183:        wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\server",
                   1184:                (LPCSTR)lpszClass);
                   1185:        if (::RegSetValue(HKEY_CLASSES_ROOT, szBuffer, REG_SZ,
                   1186:          szPathName, strlen(szPathName)) != ERROR_SUCCESS)
                   1187:                return FALSE;
                   1188: 
                   1189:        // if there are no verbs, throw in the default "Edit" verb
                   1190:        // (Note: we hard code the English "Edit" so you should have
                   1191:        //   a .REG file for localized verb names)
                   1192: 
                   1193:        char szOldVerb[256];
                   1194:        wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\verb",
                   1195:                (LPCSTR)lpszClass);
                   1196:        lSize = OLE_MAXNAMESIZE;
                   1197:        if (::RegQueryValue(HKEY_CLASSES_ROOT, szBuffer, szOldVerb,
                   1198:                &lSize) != ERROR_SUCCESS)
                   1199:        {
                   1200:                // no verbs, add "Edit"
                   1201:                if (::RegSetValue(HKEY_CLASSES_ROOT, szBuffer, REG_SZ,
                   1202:                  "", 0) != ERROR_SUCCESS)
                   1203:                        return FALSE;
                   1204: 
                   1205:                strcat(szBuffer, "\\0");    // backslash + zero
                   1206:                if (::RegSetValue(HKEY_CLASSES_ROOT, szBuffer, REG_SZ,
                   1207:                  "Edit", 4) != ERROR_SUCCESS)
                   1208:                        return FALSE;
                   1209:        }
                   1210: 
                   1211:        // all set
                   1212:        return TRUE;
                   1213: }
                   1214: 
                   1215: //////////////////////////////////////////////////////////////////////////////
                   1216: // Diagnostics
                   1217: 
                   1218: #ifdef _DEBUG
                   1219: void COleServerItem::AssertValid() const
                   1220: {
                   1221:        CObject::AssertValid();
                   1222: 
                   1223:        // must be completely detached or completely attached
                   1224:        ASSERT((m_pDocument == NULL && m_lpClient == NULL) ||
                   1225:                (m_pDocument != NULL && m_lpClient != NULL));
                   1226: }
                   1227: 
                   1228: void COleServerItem::Dump(CDumpContext& dc) const
                   1229: {
                   1230:        CObject::Dump(dc);
                   1231: 
                   1232:        // shallow dump
                   1233:        dc << "\n\tm_pDocument = " << (void*)m_pDocument;
                   1234:        dc << "\n\tm_lpClient = " << m_lpClient;
                   1235:        dc << "\n\tm_hPalette = " << m_hPalette;
                   1236:        dc << "\n\tm_rectBounds (HIMETRIC) = " << m_rectBounds;
                   1237: }
                   1238: 
                   1239: 
                   1240: void COleServerDoc::AssertValid() const
                   1241: {
                   1242:        CObject::AssertValid();
                   1243:        ASSERT(!m_bWaiting);    // waiting is an internal state
                   1244: }
                   1245: 
                   1246: void COleServerDoc::Dump(CDumpContext& dc) const
                   1247: {
                   1248:        CObject::Dump(dc);
                   1249:        dc << "\n\tm_pServer = " << (void*)m_pServer;
                   1250:        dc << "\n\tm_lhServerDoc = " << m_lhServerDoc;
                   1251:        dc << "\n\tm_bWaiting = " << m_bWaiting;
                   1252: }
                   1253: 
                   1254: void COleServer::AssertValid() const
                   1255: {
                   1256:        CObject::AssertValid();
                   1257:        ASSERT(m_cOpenDocuments >= 0);
                   1258: }
                   1259: 
                   1260: void COleServer::Dump(CDumpContext& dc) const
                   1261: {
                   1262:        CObject::Dump(dc);
                   1263:        dc << "\n\tm_lhServer = " << m_lhServer;
                   1264:        dc << "\n\tm_bLaunchEmbedded = " << m_bLaunchEmbedded;
                   1265:        dc << "\n\tm_cOpenDocuments = " << m_cOpenDocuments;
                   1266: }
                   1267: 
                   1268: #endif //_DEBUG
                   1269: 
                   1270: 
                   1271: //////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

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