|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.