Annotation of mstools/samples/ole/srvrdemo/server.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   OLE SERVER DEMO           
                      3:   Server.c             
                      4:                                                                      
                      5:   This file contains server methods and various server-related support 
                      6:   functions.
                      7:                                                                      
                      8:   (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved   
                      9: */                                                                     
                     10:  
                     11: 
                     12: 
                     13: #define SERVERONLY
                     14: #include <windows.h>
                     15: #include <ole.h>
                     16: 
                     17: #include "srvrdemo.h"
                     18: 
                     19: CLASS_STRINGS  ClassStrings = {
                     20:     "ServerDemo", "*.sd", "Server Demo", "srvrdemo.exe"
                     21: };
                     22: 
                     23: /* 
                     24:    Important Note:
                     25: 
                     26:    No method should ever dispatch a DDE message or allow a DDE message to
                     27:    be dispatched.
                     28:    Therefore, no method should ever enter a message dispatch loop.
                     29:    Also, a method should not show a dialog or message box, because the 
                     30:    processing of the dialog box messages will allow DDE messages to be
                     31:    dispatched.
                     32: */
                     33: BOOL RegServer(){
                     34: 
                     35:     LONG        fRet;
                     36:     HKEY        hKey;
                     37:     CHAR        szKeyName[300]; //Get better value
                     38:     BOOL        retVal = FALSE;
                     39:     
                     40:     lstrcpy(szKeyName, ClassStrings.pClassName);
                     41:     lstrcat(szKeyName, "\\protocol\\StdFileEditing\\verb");
                     42: 
                     43:     //Check if Class is installed, following should hold correct if class is installed.
                     44:     if ((fRet = RegOpenKey(HKEY_CLASSES_ROOT, szKeyName, &hKey)) == ERROR_SUCCESS)
                     45:         return FALSE;
                     46: 
                     47:     RegCloseKey(hKey);
                     48: 
                     49:     if ((fRet = RegSetValue(HKEY_CLASSES_ROOT, (LPSTR)(ClassStrings.pFileSpec+1), 
                     50:             REG_SZ, ClassStrings.pClassName, 7)) != ERROR_SUCCESS)
                     51:                return FALSE;
                     52: 
                     53:     if((fRet = RegSetValue(HKEY_CLASSES_ROOT, ClassStrings.pClassName, REG_SZ, 
                     54:                   ClassStrings.pHumanReadable, 7)) != ERROR_SUCCESS)
                     55:                return FALSE;
                     56: 
                     57:     lstrcat(szKeyName, "\\0");
                     58:     if((fRet = RegSetValue(HKEY_CLASSES_ROOT, (LPSTR)szKeyName, REG_SZ, "PLAY", 4)) 
                     59:                   != ERROR_SUCCESS)
                     60:                return FALSE;
                     61: 
                     62:     szKeyName[lstrlen(szKeyName) - 1] = '1';  
                     63:     if((fRet = RegSetValue(HKEY_CLASSES_ROOT, (LPSTR)szKeyName, REG_SZ, "EDIT", 4)) 
                     64:          != ERROR_SUCCESS)
                     65:                return FALSE;
                     66: 
                     67:     lstrcpy(szKeyName, ClassStrings.pClassName);
                     68:     lstrcat(szKeyName, "\\protocol\\StdFileEditing\\Server");
                     69:     if((fRet = RegSetValue(HKEY_CLASSES_ROOT, (LPSTR)szKeyName, REG_SZ, ClassStrings.pExeName, 11)) 
                     70:          != ERROR_SUCCESS)
                     71:                return FALSE;
                     72: 
                     73:     lstrcpy(szKeyName, ClassStrings.pClassName);
                     74:     lstrcat(szKeyName, "\\protocol\\StdExecute\\Server");
                     75:     if((fRet = RegSetValue(HKEY_CLASSES_ROOT, (LPSTR)szKeyName, REG_SZ, ClassStrings.pExeName, 11)) 
                     76:          != ERROR_SUCCESS)
                     77:                return FALSE;
                     78: 
                     79:        
                     80:     return TRUE;
                     81: 
                     82: }
                     83: 
                     84: 
                     85: /* Abbrev
                     86:  * ------
                     87:  *
                     88:  * Return a pointer to the filename part of a fully-qualified pathname.
                     89:  *
                     90:  * LPSTR lpsz - Fully qualified pathname
                     91:  * 
                     92:  * CUSTOMIZATION: May be useful, but not necessary.
                     93:  *
                     94:  */
                     95: LPSTR Abbrev (LPSTR lpsz)
                     96: {
                     97:    LPSTR lpszTemp;
                     98:    
                     99:    lpszTemp = lpsz + lstrlen(lpsz) - 1;
                    100:    while (lpszTemp > lpsz && lpszTemp[-1] != '\\')
                    101:       lpszTemp--;
                    102:    return lpszTemp;
                    103: }
                    104: 
                    105: 
                    106: 
                    107: 
                    108: 
                    109: /* InitServer
                    110:  * ----------
                    111:  *
                    112:  * Initialize the server by allocating memory for it, and calling
                    113:  * the OleRegisterServer method.  Requires that the server method table
                    114:  * has been properly initialized.
                    115:  * 
                    116:  * HWND hwnd      - Handle to the main window
                    117:  * LPSTR lpszLine - The Windows command line
                    118:  * 
                    119:  * RETURNS: TRUE if the memory could be allocated, and the server
                    120:  *          was properly registered.
                    121:  *          FALSE otherwise
                    122:  *
                    123:  * CUSTOMIZATION: Your application might not use a global variable 
                    124:  *                for srvrMain.
                    125:  *
                    126:  */
                    127: BOOL InitServer (HWND hwnd, HANDLE hInst)
                    128: {
                    129:     RegServer();
                    130:     srvrMain.olesrvr.lpvtbl = &srvrvtbl;
                    131: 
                    132:     if (OLE_OK != OleRegisterServer
                    133:          (szClassName, (LPOLESERVER) &srvrMain, &srvrMain.lhsrvr, hInst, 
                    134:           OLE_SERVER_MULTI))
                    135:       return FALSE;
                    136:     else
                    137:       return TRUE;
                    138: }
                    139: 
                    140: 
                    141: 
                    142: /* InitVTbls
                    143:  * ---------
                    144:  *
                    145:  * Create procedure instances for all the OLE methods.
                    146:  * 
                    147:  * 
                    148:  * CUSTOMIZATION: Your application might not use global variables for srvrvtbl,
                    149:  *                docvtbl, and objvtbl.
                    150:  */
                    151: VOID InitVTbls (VOID)
                    152: {
                    153:    typedef LPVOID ( APIENTRY *LPVOIDPROC) (LPOLEOBJECT, LPSTR);
                    154: 
                    155:    // Server method table
                    156:    srvrvtbl.Create          = SrvrCreate;
                    157:    srvrvtbl.CreateFromTemplate = SrvrCreateFromTemplate;
                    158:    srvrvtbl.Edit            = SrvrEdit;
                    159:    srvrvtbl.Execute         = SrvrExecute;
                    160:    srvrvtbl.Exit            = SrvrExit;
                    161:    srvrvtbl.Open            = SrvrOpen;
                    162:    srvrvtbl.Release         = SrvrRelease;
                    163: 
                    164:    // Document method table
                    165:    docvtbl.Close            = DocClose;
                    166:    docvtbl.GetObject        = DocGetObject;
                    167:    docvtbl.Execute          = DocExecute;
                    168:    docvtbl.Release          = DocRelease;
                    169:    docvtbl.Save             = DocSave;
                    170:    docvtbl.SetColorScheme   = DocSetColorScheme;
                    171:    docvtbl.SetDocDimensions = DocSetDocDimensions;
                    172:    docvtbl.SetHostNames     = DocSetHostNames;
                    173: 
                    174:    // Object method table
                    175:    objvtbl.DoVerb           = ObjDoVerb;
                    176:    objvtbl.EnumFormats      = ObjEnumFormats;
                    177:    objvtbl.GetData          = ObjGetData;
                    178:    objvtbl.QueryProtocol    = ObjQueryProtocol;
                    179:    objvtbl.Release          = ObjRelease;
                    180:    objvtbl.SetBounds        = ObjSetBounds;
                    181:    objvtbl.SetColorScheme   = ObjSetColorScheme;
                    182:    objvtbl.SetData          = ObjSetData;
                    183:    objvtbl.SetTargetDevice  = ObjSetTargetDevice;
                    184:    objvtbl.Show             = ObjShow;
                    185: 
                    186: }
                    187: 
                    188: 
                    189: 
                    190: /* SetTitle 
                    191:  * --------
                    192:  *
                    193:  * Sets the main window's title bar. The format of the title bar is as follows
                    194:  *   
                    195:  * If embedded
                    196:  *        <Server App name> - <object type> in <client doc name>
                    197:  *   
                    198:  *      Example:  "Server Demo - SrvrDemo Shape in OLECLI.DOC"
                    199:  *                where OLECLI.DOC is a Winword document
                    200:  *   
                    201:  * otherwise
                    202:  *        <Server App name> - <server document name>     
                    203:  *   
                    204:  *      Example:  "Server Demo - OLESVR.SD" 
                    205:  *                where OLESVR.SD is a Server demo document
                    206:  *
                    207:  * LPSTR lpszDoc    - document name
                    208:  * BOOL  fEmbedded  - If TRUE embedded document, else normal document      
                    209:  * 
                    210:  * RETURNS: OLE_OK
                    211:  *
                    212:  * 
                    213:  * CUSTOMIZATION: Your application may store the document's name somewhere
                    214:  *                other than docMain.aName.  Other than that, you may
                    215:  *                find this a useful utility function as is.
                    216:  *
                    217:  */
                    218: VOID SetTitle (LPSTR lpszDoc, BOOL fEmbedded)
                    219: {
                    220:    CHAR szBuf[cchFilenameMax];
                    221: 
                    222:    if (lpszDoc && lpszDoc[0])
                    223:    {
                    224:       // Change document name.
                    225:       if (docMain.aName)
                    226:          GlobalDeleteAtom (docMain.aName);
                    227:       docMain.aName = GlobalAddAtom (lpszDoc);
                    228:    }
                    229: 
                    230:    if (fEmbedded)
                    231:    {
                    232:      // 
                    233:       if (lpszDoc && lpszDoc[0]) 
                    234:       {
                    235:          wsprintf (szBuf, "%s - SrvrDemo Shape in %s", (LPSTR) szAppName, 
                    236:              Abbrev (lpszDoc));
                    237:       }
                    238:       else
                    239:       {
                    240:          // Use name from docMain
                    241:          CHAR szDoc [cchFilenameMax];
                    242:      
                    243:          GlobalGetAtomName (docMain.aName, szDoc, cchFilenameMax);
                    244:          wsprintf (szBuf, "%s - SrvrDemo Shape in %s", (LPSTR) szAppName, 
                    245:              Abbrev (szDoc));
                    246:       }
                    247:       SetWindowText (hwndMain, (LPSTR)szBuf);
                    248:    } 
                    249:    else if (lpszDoc && lpszDoc[0])
                    250:    {
                    251:       wsprintf (szBuf, "%s - %s", (LPSTR) szAppName, Abbrev(lpszDoc));
                    252:       SetWindowText (hwndMain, szBuf);
                    253:    }
                    254: }
                    255: 
                    256: 
                    257: 
                    258: 
                    259: /* SrvrCreate                SERVER "Create" METHOD
                    260:  * ----------
                    261:  *
                    262:  * Create a document, allocate and initialize the OLESERVERDOC structure,
                    263:  * and associate the library's handle with it.
                    264:  * In this demo server, we also create an object for the user to edit.
                    265:  * 
                    266:  * LPOLESERVER lpolesrvr          - The server structure registered by
                    267:  *                                  the application
                    268:  * LHSERVERDOC lhdoc              - The library's handle
                    269:  * LPSTR lpszClassName            - The class of document to create
                    270:  * LPSTR lpszDoc                  - The name of the document
                    271:  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure to be
                    272:  *                                  created
                    273:  * 
                    274:  * RETURNS:        OLE_OK if the named document was created.
                    275:  *                 OLE_ERROR_NEW if the document could not be created.
                    276:  * 
                    277:  * CUSTOMIZATION: Your application might not call CreateNewObj.
                    278:  *
                    279:  */
                    280: OLESTATUS  APIENTRY SrvrCreate
                    281:    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
                    282:     LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
                    283: {
                    284:     if (!CreateNewDoc (lhdoc, lpszDoc, doctypeEmbedded)) 
                    285:         return OLE_ERROR_NEW;
                    286: 
                    287:     // Although the document has not actually been changed, the client has not
                    288:     // received any data from the server yet, so the client will need to be
                    289:     // updated.  Therefore, CreateNewObj sets fDocChanged to TRUE.
                    290:     CreateNewObj (TRUE);
                    291:     *lplpoledoc = (LPOLESERVERDOC) &docMain;
                    292:     EmbeddingModeOn();
                    293:     return OLE_OK;
                    294: }
                    295: 
                    296: 
                    297: 
                    298: /* SrvrCreateFromTemplate        SERVER "CreateFromTemplate" METHOD
                    299:  * ----------------------
                    300:  *
                    301:  * Create a document, allocate and initialize the OLESERVERDOC structure, 
                    302:  * initializing the document with the contents named in the template name, 
                    303:  * and associate the library's handle with the document structure.
                    304:  * 
                    305:  * LPOLESERVER lpolesrvr        - The server structure registered by
                    306:  *                                the application
                    307:  * LHSERVERDOC lhdoc            - The library's handle
                    308:  * LPSTR lpszClassName          - The class of document to create
                    309:  * LPSTR lpszDoc                - The name of the document
                    310:  * LPSTR lpszTemplate           - The name of the template
                    311:  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure 
                    312:  *                                  to be created
                    313:  * 
                    314:  * RETURNS:        OLE_OK if the named document was created.
                    315:  *                 OLE_ERROR_TEMPLATE if the document could not be created.
                    316:  *
                    317:  * CUSTOMIZATION: None
                    318:  *
                    319:  */
                    320: OLESTATUS  APIENTRY SrvrCreateFromTemplate
                    321:    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
                    322:     LPSTR lpszDoc, LPSTR lpszTemplate, LPOLESERVERDOC FAR *lplpoledoc)
                    323: {
                    324:     if (!CreateDocFromFile(lpszTemplate, lhdoc, doctypeEmbedded)) 
                    325:         return OLE_ERROR_TEMPLATE;
                    326: 
                    327:     *lplpoledoc = (LPOLESERVERDOC) &docMain;
                    328: 
                    329:     // Although the document has not actually been changed, the client has not
                    330:     // received any data from the server yet, so the client will need to be
                    331:     // updated.
                    332:     fDocChanged = TRUE;
                    333:     EmbeddingModeOn();
                    334:     return OLE_OK;
                    335: }
                    336: 
                    337: 
                    338: 
                    339: /* SrvrEdit                SERVER "Edit" METHOD
                    340:  * --------
                    341:  *
                    342:  * A request by the libraries to create a document, allocate and
                    343:  * initialize the OLESERVERDOC structure, and associate the
                    344:  * library's handle with the document structure.
                    345:  * We create an object which will be modified by the SetData method
                    346:  * before the user has a chance to touch it.
                    347:  * 
                    348:  * LPOLESERVER lpolesrvr          - The server structure registered by
                    349:  *                                  the application
                    350:  * LHSERVERDOC lhdoc              - The library's handle
                    351:  * LPSTR lpszClassName            - The class of document to create
                    352:  * LPSTR lpszDoc                  - The name of the document
                    353:  * LPOLESERVERDOC FAR *lplpoledoc - Indicates the server doc structure to be
                    354:  *                                  created
                    355:  * 
                    356:  * RETURNS:        OLE_OK if the named document was created.
                    357:  *                 OLE_ERROR_EDIT if the document could not be created.
                    358:  * 
                    359:  * CUSTOMIZATION: None
                    360:  *
                    361:  */
                    362: OLESTATUS  APIENTRY SrvrEdit 
                    363:    (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpszClassName, 
                    364:     LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
                    365: {
                    366:     if (!CreateNewDoc (lhdoc, lpszDoc, doctypeEmbedded))
                    367:         return OLE_ERROR_EDIT;
                    368: 
                    369:     // The client is creating an embedded object for the server to edit,
                    370:     // so initially the client and server are in sync.
                    371:     fDocChanged = FALSE;
                    372:     *lplpoledoc = (LPOLESERVERDOC) &docMain;
                    373:     EmbeddingModeOn();
                    374:     return OLE_OK;
                    375: 
                    376: }
                    377: 
                    378: 
                    379: /* SrvrExecute                SERVER "Execute" METHOD
                    380:  * --------
                    381:  *
                    382:  * This application does not support the execution of DDE execution commands.
                    383:  * 
                    384:  * LPOLESERVER lpolesrvr - The server structure registered by
                    385:  *                         the application
                    386:  * HANDLE hCommands      - DDE execute commands
                    387:  * 
                    388:  * RETURNS: OLE_ERROR_COMMAND
                    389:  *
                    390:  * CUSTOMIZATION: Re-implement if your application supports the execution of
                    391:  *                DDE commands.
                    392:  *
                    393:  */
                    394: OLESTATUS  APIENTRY SrvrExecute (LPOLESERVER lpolesrvr, HANDLE hCommands)
                    395: {
                    396:    return OLE_ERROR_COMMAND;
                    397: }
                    398: 
                    399: 
                    400: 
                    401: /* SrvrExit                SERVER "Exit" METHOD
                    402:  * --------
                    403:  *
                    404:  * This method is called the library to instruct the server to exit.
                    405:  * 
                    406:  * LPOLESERVER lpolesrvr - The server structure registered by
                    407:  *                         the application
                    408:  * 
                    409:  * RETURNS: OLE_OK
                    410:  * 
                    411:  * CUSTOMIZATION: None
                    412:  *
                    413:  */
                    414: OLESTATUS  APIENTRY SrvrExit (LPOLESERVER lpolesrvr)
                    415: {
                    416:    if (srvrMain.lhsrvr)
                    417:    // If we haven't already tried to revoke the server.
                    418:    {
                    419:       StartRevokingServer();
                    420:    }
                    421:    return OLE_OK;
                    422: }
                    423: 
                    424: 
                    425: 
                    426: /* SrvrOpen                SERVER "Open" METHOD
                    427:  * --------
                    428:  *
                    429:  * Open the named document, allocate and initialize the OLESERVERDOC 
                    430:  * structure, and associate the library's handle with it.
                    431:  * 
                    432:  * LPOLESERVER lpolesrvr          - The server structure registered by
                    433:  *                                  the application
                    434:  * LHSERVERDOC lhdoc              - The library's handle
                    435:  * LPSTR lpszDoc                  - The name of the document
                    436:  * LPOLESERVERDOC FAR *lplpoledoc - Indicates server doc structure to be
                    437:  *                                  created
                    438:  * 
                    439:  * RETURNS:        OLE_OK if the named document was opened.
                    440:  *                 OLE_ERROR_OPEN if document could not be opened correctly.
                    441:  * 
                    442:  * CUSTOMIZATION: None
                    443:  *
                    444:  */
                    445: OLESTATUS  APIENTRY SrvrOpen (LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc,
                    446:                                LPSTR lpszDoc, LPOLESERVERDOC FAR *lplpoledoc)
                    447: {
                    448:     if (!CreateDocFromFile (lpszDoc, lhdoc, doctypeFromFile))
                    449:         return OLE_ERROR_OPEN;
                    450: 
                    451:     *lplpoledoc = (LPOLESERVERDOC) &docMain;
                    452:     return OLE_OK;
                    453: }
                    454: 
                    455: 
                    456: 
                    457: /* SrvrRelease                SERVER "Release" METHOD
                    458:  * -----------
                    459:  *
                    460:  * This library calls the SrvrRelease method when it is safe to quit the
                    461:  * application.  Note that the server application is not required to quit.
                    462:  * 
                    463:  * srvrMain.lhsrvr != NULL indicates that SrvrRelease has been called
                    464:  * because the client is no longer connected, not because the server called
                    465:  * OleRevokeServer.
                    466:  * Therefore, only start the revoking process if the document is of type
                    467:  * doctypeEmbedded or if the server was opened for an invisible update.
                    468:  * 
                    469:  * srvrmain.lhsrvr == NULL indicates that OleRevokeServer has already 
                    470:  * been called (by the server application), and srvrMain is a lame duck.
                    471:  * It is safe to quit now because SrvrRelease has just been called.
                    472:  *
                    473:  * Note that this method may be called twice: when OleRevokeServer is 
                    474:  * called in StartRevokingServer, SrvrRelease is called again.  
                    475:  * Therefore we need to be reentrant.
                    476:  * 
                    477:  * LPOLESERVER lpolesrvr - The server structure to release
                    478:  * 
                    479:  * RETURNS: OLE_OK
                    480:  * 
                    481:  * CUSTOMIZATION: None
                    482:  *
                    483:  */
                    484: OLESTATUS  APIENTRY SrvrRelease (LPOLESERVER lpolesrvr)
                    485: {
                    486:    if (srvrMain.lhsrvr)
                    487:    {
                    488:       if (fRevokeSrvrOnSrvrRelease 
                    489:           && (docMain.doctype == doctypeEmbedded 
                    490:               || !IsWindowVisible (hwndMain)))
                    491:          StartRevokingServer();
                    492:    }
                    493:    else      
                    494:    {
                    495:       fWaitingForSrvrRelease = FALSE;
                    496:       // Here you should free any memory that had been allocated for the server.
                    497:       PostQuitMessage (0);
                    498:    }
                    499:    return OLE_OK;
                    500: }
                    501: 
                    502: 
                    503: 
                    504: /* StartRevokingServer
                    505:  * -------------------
                    506:  *
                    507:  * Hide the window, and start to revoke the server.  
                    508:  * Revoking the server will let the library close any registered documents.
                    509:  * OleRevokeServer may return OLE_WAIT_FOR_RELEASE.
                    510:  * Calling StartRevokingServer starts a chain of events that will eventually
                    511:  * lead to the application being terminated.
                    512:  *
                    513:  * RETURNS: The return value from OleRevokeServer
                    514:  *
                    515:  * CUSTOMIZATION: None
                    516:  *
                    517:  */
                    518: OLESTATUS StartRevokingServer (VOID)
                    519: {
                    520:    OLESTATUS olestatus;
                    521: 
                    522:    if (srvrMain.lhsrvr)
                    523:    {
                    524:       LHSERVER lhserver;
                    525:       // Hide the window so user can do nothing while we are waiting. 
                    526:       ShowWindow (hwndMain, SW_HIDE);
                    527:       lhserver = srvrMain.lhsrvr;
                    528:       // Set lhsrvr to NULL to indicate that srvrMain is a lame duck and that
                    529:       // if SrvrRelease is called, then it is ok to quit the application.
                    530:       srvrMain.lhsrvr = NULL;
                    531:       olestatus = OleRevokeServer (lhserver);
                    532:    }
                    533:    else
                    534:       // The programmer should ensure that this never happens.
                    535:       ErrorBox ("Fatal Error: StartRevokingServer called on NULL server.");
                    536:    return olestatus;
                    537: }
                    538: 

unix.superglobalmegacorp.com

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