|
|
1.1 ! root 1: /************************************************************************* ! 2: ** ! 3: ** OLE 2 Sample Code ! 4: ** ! 5: ** oleapp.c ! 6: ** ! 7: ** This file contains functions and methods that are common to ! 8: ** server and the client version of the app. This includes the class ! 9: ** factory methods and all OleApp functions. ! 10: ** ! 11: ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved ! 12: ** ! 13: *************************************************************************/ ! 14: ! 15: #include "outline.h" ! 16: #include <ole2ver.h> ! 17: ! 18: OLEDBGDATA ! 19: ! 20: extern LPOUTLINEAPP g_lpApp; ! 21: ! 22: extern IUnknownVtbl g_OleApp_UnknownVtbl; ! 23: ! 24: extern IUnknownVtbl g_OleDoc_UnknownVtbl; ! 25: extern IPersistFileVtbl g_OleDoc_PersistFileVtbl; ! 26: extern IOleItemContainerVtbl g_OleDoc_OleItemContainerVtbl; ! 27: extern IDataObjectVtbl g_OleDoc_DataObjectVtbl; ! 28: ! 29: #if defined( USE_DRAGDROP ) ! 30: extern IDropTargetVtbl g_OleDoc_DropTargetVtbl; ! 31: extern IDropSourceVtbl g_OleDoc_DropSourceVtbl; ! 32: #endif // USE_DRAGDROP ! 33: ! 34: #if defined( OLE_SERVER ) ! 35: extern IOleObjectVtbl g_SvrDoc_OleObjectVtbl; ! 36: extern IPersistStorageVtbl g_SvrDoc_PersistStorageVtbl; ! 37: ! 38: #if defined( SVR_TREATAS ) ! 39: extern IStdMarshalInfoVtbl g_SvrDoc_StdMarshalInfoVtbl; ! 40: #endif // SVR_TREATAS ! 41: ! 42: extern IUnknownVtbl g_PseudoObj_UnknownVtbl; ! 43: extern IOleObjectVtbl g_PseudoObj_OleObjectVtbl; ! 44: extern IDataObjectVtbl g_PseudoObj_DataObjectVtbl; ! 45: ! 46: #if defined( INPLACE_SVR ) ! 47: extern IOleInPlaceObjectVtbl g_SvrDoc_OleInPlaceObjectVtbl; ! 48: extern IOleInPlaceActiveObjectVtbl g_SvrDoc_OleInPlaceActiveObjectVtbl; ! 49: #endif // INPLACE_SVR ! 50: ! 51: #endif // OLE_SERVER ! 52: ! 53: #if defined( OLE_CNTR ) ! 54: ! 55: extern IOleUILinkContainerVtbl g_CntrDoc_OleUILinkContainerVtbl; ! 56: extern IUnknownVtbl g_CntrLine_UnknownVtbl; ! 57: extern IOleClientSiteVtbl g_CntrLine_OleClientSiteVtbl; ! 58: extern IAdviseSinkVtbl g_CntrLine_AdviseSinkVtbl; ! 59: ! 60: #if defined( INPLACE_CNTR ) ! 61: extern IOleInPlaceSiteVtbl g_CntrLine_OleInPlaceSiteVtbl; ! 62: extern IOleInPlaceFrameVtbl g_CntrApp_OleInPlaceFrameVtbl; ! 63: extern BOOL g_fInsideOutContainer; ! 64: #endif // INPLACE_CNTR ! 65: ! 66: #endif // OLE_CNTR ! 67: ! 68: // REVIEW: these are NOT useful end-user messages ! 69: static char ErrMsgCreateCF[] = "Can't create Class Factory!"; ! 70: static char ErrMsgRegCF[] = "Can't register Class Factory!"; ! 71: static char ErrMsgRegMF[] = "Can't register Message Filter!"; ! 72: ! 73: extern UINT g_uMsgHelp; ! 74: ! 75: /* OleApp_InitInstance ! 76: * ------------------- ! 77: * ! 78: * Initialize the app instance by creating the main frame window and ! 79: * performing app instance specific initializations ! 80: * (eg. initializing interface Vtbls). ! 81: * ! 82: * RETURNS: TRUE if the memory could be allocated, and the server app ! 83: * was properly initialized. ! 84: * FALSE otherwise ! 85: * ! 86: */ ! 87: BOOL OleApp_InitInstance(LPOLEAPP lpOleApp, HINSTANCE hInst, int nCmdShow) ! 88: { ! 89: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 90: HRESULT hrErr; ! 91: DWORD dwBuildVersion = OleBuildVersion(); ! 92: ! 93: OLEDBG_BEGIN3("OleApp_InitInstance\r\n") ! 94: ! 95: lpOleApp->m_fOleInitialized = FALSE; ! 96: ! 97: /* OLE2NOTE: check if the build version of the OLE2 DLL's match ! 98: ** what our application is expecting. ! 99: */ ! 100: if (HIWORD(dwBuildVersion) != rmm || LOWORD(dwBuildVersion) < rup) { ! 101: OleDbgAssertSz(0, "ERROR: OLE 2.0 DLL's are NOT compatible!"); ! 102: ! 103: #if !defined( _DEBUG ) ! 104: return FALSE; // Wrong version of DLL's ! 105: #endif ! 106: } ! 107: ! 108: /* OLE2NOTE: the OLE libraries must be properly initialized before ! 109: ** making any calls. OleInitialize automatically calls ! 110: ** CoInitialize. we will use the default task memory allocator ! 111: ** therefore we pass NULL to OleInitialize. ! 112: */ ! 113: OLEDBG_BEGIN2("OleInitialize called\r\n") ! 114: hrErr = OleInitialize(NULL); ! 115: OLEDBG_END2 ! 116: ! 117: if (hrErr != NOERROR) { ! 118: OutlineApp_ErrorMessage(lpOutlineApp,"OLE initialization failed!"); ! 119: goto error; ! 120: } ! 121: ! 122: /***************************************************************** ! 123: ** OLE2NOTE: we must remember the fact that OleInitialize has ! 124: ** been call successfully. the very last thing an app must ! 125: ** be do is properly shut down OLE by calling ! 126: ** OleUninitialize. This call MUST be guarded! it is only ! 127: ** allowable to call OleUninitialize if OleInitialize has ! 128: ** been called SUCCESSFULLY. ! 129: *****************************************************************/ ! 130: ! 131: lpOleApp->m_fOleInitialized = TRUE; ! 132: ! 133: // Initialize the OLE 2.0 interface method tables. ! 134: if (! OleApp_InitVtbls(lpOleApp)) ! 135: goto error; ! 136: ! 137: // Register OLE 2.0 clipboard formats. ! 138: lpOleApp->m_cfEmbedSource = RegisterClipboardFormat(CF_EMBEDSOURCE); ! 139: lpOleApp->m_cfEmbeddedObject = RegisterClipboardFormat( ! 140: CF_EMBEDDEDOBJECT ! 141: ); ! 142: lpOleApp->m_cfLinkSource = RegisterClipboardFormat(CF_LINKSOURCE); ! 143: lpOleApp->m_cfFileName = RegisterClipboardFormat(CF_FILENAME); ! 144: lpOleApp->m_cfObjectDescriptor = ! 145: RegisterClipboardFormat(CF_OBJECTDESCRIPTOR); ! 146: lpOleApp->m_cfLinkSrcDescriptor = ! 147: RegisterClipboardFormat(CF_LINKSRCDESCRIPTOR); ! 148: ! 149: lpOleApp->m_cRef = 0; ! 150: lpOleApp->m_cDoc = 0; ! 151: lpOleApp->m_fUserCtrl = FALSE; ! 152: lpOleApp->m_dwRegClassFac = 0; ! 153: lpOleApp->m_lpClassFactory = NULL; ! 154: ! 155: INIT_INTERFACEIMPL( ! 156: &lpOleApp->m_Unknown, ! 157: &g_OleApp_UnknownVtbl, ! 158: lpOleApp ! 159: ); ! 160: ! 161: #if defined( USE_DRAGDROP ) ! 162: // time delay (in msec) before scroll ! 163: lpOleApp->m_nScrollDelay = GetProfileInt( ! 164: "windows", ! 165: "ScrollDelay", ! 166: DD_DEFSCROLLDELAY ! 167: ); ! 168: ! 169: // Border threshold to start drag scroll ! 170: lpOleApp->m_nScrollInset = GetProfileInt( ! 171: "windows", ! 172: "ScrollInset", ! 173: DD_DEFSCROLLINSET ! 174: ); ! 175: ! 176: /* OLE2NOTE: even though OLE provides default cursors for ! 177: ** drag/drop, we need to have a copy of the dragmove cursor so ! 178: ** that we can give immediate feedback on cursor down of a ! 179: ** pending drag operation. we do not call DoDragDrop immediately ! 180: ** on button down; the user must move the mouse a minimum ! 181: ** distance to start the drag. we will show this cursor ! 182: ** immediately, however, to show the user there is a drag ! 183: ** pending. ! 184: */ ! 185: lpOleApp->m_hcursorDragMove = LoadCursor ( hInst, "DragMoveCur" ); ! 186: ! 187: #if defined( IF_SPECIAL_DD_CURSORS_NEEDED ) ! 188: // This would be used if the app wanted to have custom drag/drop cursors ! 189: lpOleApp->m_hcursorDragNone = LoadCursor ( hInst, "DragNoneCur" ); ! 190: lpOleApp->m_hcursorDragCopy = LoadCursor ( hInst, "DragCopyCur" ); ! 191: lpOleApp->m_hcursorDragLink = LoadCursor ( hInst, "DragLinkCur" ); ! 192: #endif // IF_SPECIAL_DD_CURSORS_NEEDED ! 193: ! 194: #endif // USE_DRAGDROP ! 195: ! 196: lpOleApp->m_lpMsgFilter = NULL; ! 197: ! 198: #if defined( USE_MSGFILTER ) ! 199: /* OLE2NOTE: Register our message filter upon app startup. the ! 200: ** message filter is used to handle concurrency. ! 201: ** we will use a standard implementation of IMessageFilter that ! 202: ** is included as part of the OLE2UI library. ! 203: */ ! 204: lpOleApp->m_lpMsgFilter = NULL; ! 205: if (! OleApp_RegisterMessageFilter(lpOleApp)) ! 206: goto error; ! 207: ! 208: /* OLE2NOTE: because our app is initially INVISIBLE, we must ! 209: ** DISABLE the busy dialog. we should NOT put up any dialogs if ! 210: ** our app is invisible. when our app window is made visible, ! 211: ** then the busy dialog will be enabled. ! 212: */ ! 213: OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, FALSE); ! 214: #endif // USE_MSGFILTER ! 215: ! 216: #if defined( OLE_SERVER ) ! 217: ! 218: /* OLE2NOTE: perform initialization specific for an OLE server */ ! 219: if (! ServerApp_InitInstance((LPSERVERAPP)lpOutlineApp, hInst, nCmdShow)) ! 220: goto error; ! 221: ! 222: #elif defined( OLE_CNTR ) ! 223: ! 224: /* OLE2NOTE: perform initialization specific for an OLE container */ ! 225: ! 226: // Register help message ! 227: g_uMsgHelp = RegisterWindowMessage(SZOLEUI_MSG_HELP); ! 228: ! 229: if (! ContainerApp_InitInstance((LPCONTAINERAPP)lpOutlineApp, hInst, nCmdShow)) ! 230: goto error; ! 231: ! 232: #endif ! 233: ! 234: OLEDBG_END3 ! 235: return TRUE; ! 236: ! 237: error: ! 238: OLEDBG_END3 ! 239: return FALSE; ! 240: } ! 241: ! 242: ! 243: /* ! 244: * OleApp_TerminateApplication ! 245: * --------------------------- ! 246: * Perform proper OLE application cleanup before shutting down ! 247: */ ! 248: void OleApp_TerminateApplication(LPOLEAPP lpOleApp) ! 249: { ! 250: OLEDBG_BEGIN3("OleApp_TerminateApplication\r\n") ! 251: ! 252: /* OLE2NOTE: perform a clean shut down for OLE. at this point our ! 253: ** App refcnt should be 0, or else we should never have reached ! 254: ** this point! ! 255: */ ! 256: OleDbgAssertSz(lpOleApp->m_cRef == 0, "App NOT shut down properly"); ! 257: ! 258: if(lpOleApp->m_fOleInitialized) { ! 259: OLEDBG_BEGIN2("OleUninitialize called\r\n") ! 260: ! 261: OleUninitialize(); ! 262: ! 263: OLEDBG_END2 ! 264: } ! 265: OLEDBG_END3 ! 266: } ! 267: ! 268: ! 269: /* OleApp_ParseCmdLine ! 270: * ------------------- ! 271: * ! 272: * Parse the command line for any execution flags/arguments. ! 273: * OLE2NOTE: check if "-Embedding" switch is given. ! 274: */ ! 275: BOOL OleApp_ParseCmdLine(LPOLEAPP lpOleApp, LPSTR lpszCmdLine, int nCmdShow) ! 276: { ! 277: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 278: char szFileName[256]; /* buffer for filename in command line */ ! 279: BOOL fStatus = TRUE; ! 280: BOOL fEmbedding = FALSE; ! 281: ! 282: OLEDBG_BEGIN3("OleApp_ParseCmdLine\r\n") ! 283: ! 284: szFileName[0] = '\0'; ! 285: ParseCmdLine(lpszCmdLine, &fEmbedding, (LPSTR)szFileName); ! 286: ! 287: #if defined( MDI_VERSION ) ! 288: /* OLE2NOTE: an MDI app would ALWAYS register its ClassFactory. it ! 289: ** can handle multiple objects at the same time, while an SDI ! 290: ** application can only handle a single embedded or file-based ! 291: ** object at a time. ! 292: */ ! 293: fStatus = OleApp_RegisterClassFactory(lpOleApp); ! 294: #endif ! 295: ! 296: if(fEmbedding) { ! 297: ! 298: if (szFileName[0] == '\0') { ! 299: ! 300: /***************************************************************** ! 301: ** App was launched with /Embedding. ! 302: ** We must register our ClassFactory with OLE, remain hidden ! 303: ** (the app window is initially created not visible), and ! 304: ** wait for OLE to call IClassFactory::CreateInstance ! 305: ** method. We do not automatically create a document as we ! 306: ** do when the app is launched by the user from the ! 307: ** FileManager. We must NOT make our app window visible ! 308: ** until told to do so by our container. ! 309: ** ! 310: ** OLE2NOTE: Because we are an SDI app, we only register our ! 311: ** ClassFactory if we are launched with the /Embedding ! 312: ** flag WITHOUT a filename. an MDI app would ALWAYS ! 313: ** register its ClassFactory. it can handle multiple ! 314: ** objects at the same time, while an SDI application ! 315: ** can only handle a single embedded or file-based ! 316: ** object at a time. ! 317: *****************************************************************/ ! 318: ! 319: #if defined( SDI_VERSION ) ! 320: fStatus = OleApp_RegisterClassFactory(lpOleApp); ! 321: #endif ! 322: } else { ! 323: ! 324: /***************************************************************** ! 325: ** App was launched with /Embedding <Filename>. ! 326: ** We must create a document and load the file and ! 327: ** register it in the RunningObjectTable BEFORE we ! 328: ** enter our GetMessage loop (ie. before we yield). ! 329: ** One way to perform these tasks is to call the same ! 330: ** interface methods that OLE 2.0 calls for linking to a ! 331: ** file: ! 332: ** IClassFactory::CreateInstance ! 333: ** IPersistFile::Load ! 334: ** ! 335: ** We must NOT make our app window visible until told to ! 336: ** do so by our container. An application will be ! 337: ** launched in this manner by an OLE 1.0 application ! 338: ** link situation (eg. double clicking a linked object ! 339: ** or OleCreateLinkFromFile called). ! 340: ** ! 341: ** OLE2NOTE: Because we are an SDI app, we should NOT ! 342: ** register our ClassFactory when we are launched with the ! 343: ** /Embedding <Filename> flag. our SDI instance can only ! 344: ** handle a single embedded or file-based object. ! 345: ** an MDI app WOULD register its ClassFactory at all ! 346: ** times because it can handle multiple objects. ! 347: *****************************************************************/ ! 348: ! 349: // allocate a new document object ! 350: lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); ! 351: if (! lpOutlineApp->m_lpDoc) { ! 352: OLEDBG_END3 ! 353: return FALSE; ! 354: } ! 355: ! 356: /* OLE2NOTE: initially the Doc object is created with a 0 ref ! 357: ** count. in order to have a stable Doc object during the ! 358: ** process of initializing the new Doc instance, ! 359: ** we intially AddRef the Doc ref cnt and later ! 360: ** Release it. This initial AddRef is artificial; it is simply ! 361: ** done to guarantee that a harmless QueryInterface followed by ! 362: ** a Release does not inadvertantly force our object to destroy ! 363: ** itself prematurely. ! 364: */ ! 365: OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 366: ! 367: /* OLE2NOTE: OutlineDoc_LoadFromFile will register our document ! 368: ** in the RunningObjectTable. this registration will ! 369: ** AddRef our document. therefore our document will not ! 370: ** be destroyed when we release the artificial AddRef ! 371: */ ! 372: fStatus = OutlineDoc_LoadFromFile( ! 373: lpOutlineApp->m_lpDoc, (LPSTR)szFileName); ! 374: ! 375: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel AddRef ! 376: ! 377: OLEDBG_END3 ! 378: return fStatus; ! 379: } ! 380: } else { ! 381: ! 382: /***************************************************************** ! 383: ** App was launched by the user (without /Embedding) and ! 384: ** therefore is marked to be under user control. ! 385: ** In this case, because we are an SDI app, we do NOT ! 386: ** register our ClassFactory with OLE. This app instance can ! 387: ** only manage one document at a time (either a user ! 388: ** document or an embedded object document). An MDI app ! 389: ** would register its ClassFactory here. ! 390: ** ! 391: ** We must create a document for the user (either ! 392: ** initialized from a file given on the command line or ! 393: ** initialized as an untitled document. We must also make ! 394: ** our app window visible to the user. ! 395: *****************************************************************/ ! 396: ! 397: // allocate a new document object ! 398: lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); ! 399: if (! lpOutlineApp->m_lpDoc) goto error; ! 400: ! 401: /* OLE2NOTE: initially the Doc object is created with a 0 ref ! 402: ** count. in order to have a stable Doc object during the ! 403: ** process of initializing the new Doc instance, ! 404: ** we intially AddRef the Doc ref cnt and later ! 405: ** Release it. This initial AddRef is artificial; it is simply ! 406: ** done to guarantee that a harmless QueryInterface followed by ! 407: ** a Release does not inadvertantly force our object to destroy ! 408: ** itself prematurely. ! 409: */ ! 410: OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 411: ! 412: if(*szFileName) { ! 413: // initialize the document from the specified file ! 414: if (! OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, szFileName)) ! 415: goto error; ! 416: } else { ! 417: // set the doc to an (Untitled) doc. ! 418: if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc)) ! 419: goto error; ! 420: } ! 421: ! 422: // position and size the new doc window ! 423: OutlineApp_ResizeWindows(lpOutlineApp); ! 424: OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock ! 425: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc);// rel AddRef above ! 426: ! 427: // show main app window ! 428: ShowWindow(lpOutlineApp->m_hWndApp, nCmdShow); ! 429: UpdateWindow(lpOutlineApp->m_hWndApp); ! 430: ! 431: #if defined( OLE_CNTR ) ! 432: ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc); ! 433: #endif ! 434: ! 435: } ! 436: ! 437: OLEDBG_END3 ! 438: return fStatus; ! 439: ! 440: error: ! 441: // REVIEW: should load string from string resource ! 442: OutlineApp_ErrorMessage( ! 443: lpOutlineApp, ! 444: "Could not create document--Out of Memory" ! 445: ); ! 446: if (lpOutlineApp->m_lpDoc) // rel artificial AddRef above ! 447: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 448: ! 449: OLEDBG_END3 ! 450: return FALSE; ! 451: } ! 452: ! 453: ! 454: /* OleApp_CloseAllDocsAndExitCommand ! 455: * --------------------------------- ! 456: * ! 457: * Close all active documents and exit the app. ! 458: * Because this is an SDI, there is only one document ! 459: * If the doc was modified, prompt the user if he wants to save it. ! 460: * ! 461: * Returns: ! 462: * TRUE if the app is successfully closed ! 463: * FALSE if failed or aborted ! 464: * ! 465: * OLE2NOTE: in the OLE version, we can NOT directly ! 466: * destroy the App object. we can only take all ! 467: * necessary actions to ensure that our object receives ! 468: * all of its Releases from clients holding onto ! 469: * pointers (eg. closing all docs and flushing the ! 470: * clipboard) and then we must hide our window and wait ! 471: * actually for our refcnt to reach 0. when it reaches 0, ! 472: * our destructor (OutlineApp_Destroy) will be called. ! 473: * each document addref's the app object in order to ! 474: * guarentee that the app does not shut down while the doc ! 475: * is still open. closing all docs, will release these ! 476: * refcnt's. if there are now more open documents AND the ! 477: * app is not under the control of the user (ie. launched by ! 478: * OLE) then the app will now shut down. the OleApp_Release ! 479: * function executes this shut down procedure. after closing ! 480: * all docs, then releasing the user refcnt will force the ! 481: * app to shut down. ! 482: */ ! 483: BOOL OleApp_CloseAllDocsAndExitCommand(LPOLEAPP lpOleApp) ! 484: { ! 485: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 486: DWORD dwSaveOption = OLECLOSE_PROMPTSAVE; ! 487: ! 488: /* OLE2NOTE: in order to have a stable App object during the ! 489: ** process of closing, we intially AddRef the App ref cnt and ! 490: ** later Release it. This initial AddRef is artificial; it is ! 491: ** simply done to guarantee that our App object does not ! 492: ** destroy itself until the end of this routine. ! 493: */ ! 494: OleApp_AddRef(lpOleApp); ! 495: ! 496: /* Because this is an SDI app, there is only one document. ! 497: ** Close the doc. if it is successfully closed and the app will ! 498: ** not automatically exit, then also exit the app. ! 499: ** if this were an MDI app, we would loop through and close all ! 500: ** open MDI child documents. ! 501: */ ! 502: ! 503: #if defined( OLE_SERVER ) ! 504: if (lpOutlineApp->m_lpDoc->m_docInitType == DOCTYPE_EMBEDDED) ! 505: dwSaveOption = OLECLOSE_SAVEIFDIRTY; ! 506: #endif ! 507: if (! OutlineDoc_Close(lpOutlineApp->m_lpDoc, dwSaveOption)) { ! 508: OleApp_Release(lpOleApp); ! 509: return FALSE; // User Aborted shutdown ! 510: } ! 511: ! 512: OleDbgAssertSz( ! 513: lpOutlineApp->m_lpDoc==NULL, ! 514: "Closed doc NOT properly destroyed" ! 515: ); ! 516: ! 517: #if defined( OLE_CNTR ) ! 518: /* if we currently have data on the clipboard then we must tell ! 519: ** the clipboard to release our clipboard data object ! 520: ** (document) ! 521: */ ! 522: if (lpOutlineApp->m_lpClipboardDoc) ! 523: OleApp_FlushClipboard(lpOleApp); ! 524: #endif ! 525: ! 526: OleApp_HideWindow(lpOleApp); ! 527: ! 528: /* OLE2NOTE: this call forces all external connections to our ! 529: ** object to close down and therefore guarantees that we receive ! 530: ** all releases associated with those external connections. ! 531: */ ! 532: OLEDBG_BEGIN2("CoDisconnectObject(lpApp) called\r\n") ! 533: CoDisconnectObject((LPUNKNOWN)&lpOleApp->m_Unknown, 0); ! 534: OLEDBG_END2 ! 535: ! 536: OleApp_Release(lpOleApp); // release artificial AddRef above ! 537: ! 538: return TRUE; ! 539: } ! 540: ! 541: ! 542: /* OleApp_ShowWindow ! 543: * ----------------- ! 544: * ! 545: * Show the window of the app to the user. ! 546: * make sure app window is visible and bring the app to the top. ! 547: * IF fGiveUserCtrl == TRUE ! 548: * THEN give the user the control over the life-time of the app. ! 549: */ ! 550: void OleApp_ShowWindow(LPOLEAPP lpOleApp, BOOL fGiveUserCtrl) ! 551: { ! 552: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 553: ! 554: OLEDBG_BEGIN3("OleApp_ShowWindow\r\n") ! 555: ! 556: /* OLE2NOTE: while the application is visible and under user ! 557: ** control, we do NOT want it to be prematurely destroyed when ! 558: ** the user closes a document. thus we must inform OLE to hold ! 559: ** an external lock on our application on behalf of the user. ! 560: ** this arranges that OLE holds at least 1 reference to our ! 561: ** application that will NOT be released until we release this ! 562: ** external lock. later, when the application window is hidden, we ! 563: ** will release this external lock. ! 564: */ ! 565: if (fGiveUserCtrl && ! lpOleApp->m_fUserCtrl) { ! 566: lpOleApp->m_fUserCtrl = TRUE; ! 567: OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */); ! 568: } ! 569: ! 570: // we must show our App window and force it to have input focus ! 571: ShowWindow(lpOutlineApp->m_hWndApp, SW_SHOWNORMAL); ! 572: SetFocus(lpOutlineApp->m_hWndApp); ! 573: ! 574: /* OLE2NOTE: because our app is now visible, we can enable the busy ! 575: ** dialog. we should NOT put up any dialogs if our app is ! 576: ** invisible. ! 577: */ ! 578: if (lpOleApp->m_lpMsgFilter != NULL) ! 579: OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, TRUE); ! 580: ! 581: OLEDBG_END3 ! 582: } ! 583: ! 584: ! 585: /* OleApp_HideWindow ! 586: * ----------------- ! 587: * ! 588: * Hide the window of the app from the user. ! 589: * take away the control of the app by the user. ! 590: */ ! 591: void OleApp_HideWindow(LPOLEAPP lpOleApp) ! 592: { ! 593: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 594: ! 595: OLEDBG_BEGIN3("OleApp_HideWindow\r\n") ! 596: ! 597: /* OLE2NOTE: the application is now being hidden, so we must release ! 598: ** the external lock that was made on behalf of the user. ! 599: ** if this is that last external lock on our application, thus ! 600: ** enabling our application to complete its shutdown operation. ! 601: */ ! 602: if (lpOleApp->m_fUserCtrl) { ! 603: lpOleApp->m_fUserCtrl = FALSE; ! 604: OleApp_Lock(lpOleApp, FALSE /*fLock*/, TRUE /*fLastUnlockReleases*/); ! 605: } ! 606: ! 607: ShowWindow(lpOutlineApp->m_hWndApp, SW_HIDE); ! 608: ! 609: /* OLE2NOTE: because our app is now INVISIBLE, we must DISABLE the busy ! 610: ** dialog. we should NOT put up any dialogs if our app is ! 611: ** invisible. ! 612: */ ! 613: if (lpOleApp->m_lpMsgFilter != NULL) ! 614: OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, FALSE); ! 615: ! 616: OLEDBG_END3 ! 617: } ! 618: ! 619: ! 620: /* OleApp_Lock ! 621: ** ----------- ! 622: ** Lock/Unlock the App object. if the last lock is unlocked and ! 623: ** fLastUnlockReleases == TRUE, then the app object will shut down ! 624: ** (ie. it will recieve its final release and its refcnt will go to 0). ! 625: */ ! 626: HRESULT OleApp_Lock(LPOLEAPP lpOleApp, BOOL fLock, BOOL fLastUnlockReleases) ! 627: { ! 628: HRESULT hrErr; ! 629: ! 630: #if defined( _DEBUG ) ! 631: if (fLock) { ! 632: OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,TRUE) called\r\n") ! 633: } else { ! 634: if (fLastUnlockReleases) ! 635: OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,TRUE) called\r\n") ! 636: else ! 637: OLEDBG_BEGIN2("CoLockObjectExternal(lpApp,FALSE,FALSE) called\r\n") ! 638: } ! 639: #endif // _DEBUG ! 640: ! 641: OleApp_AddRef(lpOleApp); // artificial AddRef to make object stable ! 642: ! 643: hrErr = CoLockObjectExternal( ! 644: (LPUNKNOWN)&lpOleApp->m_Unknown, fLock, fLastUnlockReleases); ! 645: ! 646: OleApp_Release(lpOleApp); // release artificial AddRef above ! 647: ! 648: OLEDBG_END2 ! 649: return hrErr; ! 650: } ! 651: ! 652: ! 653: /* OleApp_Destroy ! 654: * -------------- ! 655: * ! 656: * Free all OLE related resources that had been allocated for the app. ! 657: */ ! 658: void OleApp_Destroy(LPOLEAPP lpOleApp) ! 659: { ! 660: // OLE2NOTE: Revoke our message filter upon app shutdown. ! 661: OleApp_RevokeMessageFilter(lpOleApp); ! 662: ! 663: // OLE2NOTE: Revoke our ClassFactory upon app shutdown. ! 664: OleApp_RevokeClassFactory(lpOleApp); ! 665: ! 666: #if defined( DRAGDROP ) ! 667: ! 668: DestroyCursor(lpOleApp->m_hcursorDragMove); ! 669: ! 670: #if defined( IF_SPECIAL_DD_CURSORS_NEEDED ) ! 671: // This would be used if the app wanted to have custom drag/drop cursors ! 672: DestroyCursor(lpOleApp->m_hcursorDragNone); ! 673: DestroyCursor(lpOleApp->m_hcursorDragCopy); ! 674: DestroyCursor(lpOleApp->m_hcursorDragLink); ! 675: #endif // IF_SPECIAL_DD_CURSORS_NEEDED ! 676: ! 677: #endif // DRAGDROP ! 678: ! 679: } ! 680: ! 681: ! 682: /* OleApp_DocLockApp ! 683: ** ----------------- ! 684: ** Add a lock on the App on behalf of the Doc. the App may not close ! 685: ** while the Doc exists. ! 686: ** ! 687: ** when a document is first created, it calls this method to ! 688: ** guarantee that the application stays alive (OleDoc_Init). ! 689: ** when a document is destroyed, it calls ! 690: ** OleApp_DocUnlockApp to release this hold on the app. ! 691: */ ! 692: void OleApp_DocLockApp(LPOLEAPP lpOleApp) ! 693: { ! 694: ULONG cDoc; ! 695: ! 696: OLEDBG_BEGIN3("OleApp_DocLockApp\r\n") ! 697: ! 698: cDoc = ++lpOleApp->m_cDoc; ! 699: ! 700: OleDbgOutRefCnt3( ! 701: "OleApp_DocLockApp: cDoc++\r\n", lpOleApp, cDoc); ! 702: ! 703: OleApp_Lock(lpOleApp, TRUE /* fLock */, 0 /* not applicable */); ! 704: ! 705: OLEDBG_END3 ! 706: return; ! 707: } ! 708: ! 709: ! 710: /* OleApp_DocUnlockApp ! 711: ** ------------------- ! 712: ** Forget all references to a closed document. ! 713: ** Release the lock on the App on behalf of the Doc. if this was the ! 714: ** last lock on the app, then it will shutdown. ! 715: */ ! 716: void OleApp_DocUnlockApp(LPOLEAPP lpOleApp, LPOUTLINEDOC lpOutlineDoc) ! 717: { ! 718: ULONG cDoc; ! 719: ! 720: OLEDBG_BEGIN3("OleApp_DocUnlockApp\r\n") ! 721: ! 722: /* OLE2NOTE: when there are no open documents and the app is not ! 723: ** under the control of the user then revoke our ClassFactory to ! 724: ** enable the app to shut down. ! 725: */ ! 726: OleDbgAssertSz (lpOleApp->m_cDoc > 0, "DocUnlockApp called with cDoc == 0"); ! 727: ! 728: cDoc = --lpOleApp->m_cDoc; ! 729: ! 730: OleDbgOutRefCnt3( ! 731: "OleApp_DocUnlockApp: cDoc--\r\n", lpOleApp, cDoc); ! 732: ! 733: OleApp_Lock(lpOleApp, FALSE /* fLock */, TRUE /* fLastUnlockReleases */); ! 734: ! 735: OLEDBG_END3 ! 736: return; ! 737: } ! 738: ! 739: ! 740: /* OleApp_HideIfNoReasonToStayVisible ! 741: ** ---------------------------------- ! 742: ** ! 743: ** if there are no more documents visible to the user and the app ! 744: ** itself is not under user control, then it has no reason to stay ! 745: ** visible. we thus should hide the app. we can not directly destroy ! 746: ** the app, because it may be validly being used programatically by ! 747: ** another client application and should remain running. the app ! 748: ** should simply be hidden from the user. ! 749: */ ! 750: void OleApp_HideIfNoReasonToStayVisible(LPOLEAPP lpOleApp) ! 751: { ! 752: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 753: LPOUTLINEDOC lpOutlineDoc; ! 754: ! 755: OLEDBG_BEGIN3("OleApp_HideIfNoReasonToStayVisible\r\n") ! 756: ! 757: if (lpOleApp->m_fUserCtrl) { ! 758: OLEDBG_END3 ! 759: return; // remain visible; user in control of app ! 760: } ! 761: ! 762: /* Because this is an SDI app, there is only one user document. ! 763: ** check if it is visible to the user. an MDI app would loop over ! 764: ** all open MDI child documents to see if any are visible. ! 765: */ ! 766: lpOutlineDoc = (LPOUTLINEDOC)lpOutlineApp->m_lpDoc; ! 767: if (lpOutlineDoc && IsWindowVisible(lpOutlineDoc->m_hWndDoc)) ! 768: return; // remain visible; the doc is visible to the user ! 769: ! 770: // if we reached here, the app should be hidden ! 771: OleApp_HideWindow(lpOleApp); ! 772: ! 773: OLEDBG_END3 ! 774: } ! 775: ! 776: ! 777: /* OleApp_AddRef ! 778: ** ------------- ! 779: ** ! 780: ** increment the ref count of the App object. ! 781: ** ! 782: ** Returns the new ref count on the object ! 783: */ ! 784: ULONG OleApp_AddRef(LPOLEAPP lpOleApp) ! 785: { ! 786: ++lpOleApp->m_cRef; ! 787: ! 788: OleDbgOutRefCnt4( ! 789: "OleApp_AddRef: cRef++\r\n", ! 790: lpOleApp, ! 791: lpOleApp->m_cRef ! 792: ); ! 793: ! 794: return lpOleApp->m_cRef; ! 795: } ! 796: ! 797: ! 798: /* OleApp_Release ! 799: ** -------------- ! 800: ** ! 801: ** decrement the ref count of the App object. ! 802: ** if the ref count goes to 0, then the app object is destroyed. ! 803: ** ! 804: ** Returns the remaining ref count on the object ! 805: */ ! 806: ULONG OleApp_Release (LPOLEAPP lpOleApp) ! 807: { ! 808: ULONG cRef; ! 809: ! 810: OleDbgAssertSz (lpOleApp->m_cRef > 0, "Release called with cRef == 0"); ! 811: ! 812: cRef = --lpOleApp->m_cRef; ! 813: ! 814: OleDbgOutRefCnt4( ! 815: "OleApp_AddRef: cRef--\r\n", lpOleApp, cRef); ! 816: ! 817: /********************************************************************* ! 818: ** OLE2NOTE: when the ClassFactory refcnt == 0, then destroy it. ** ! 819: ** otherwise the ClassFactory is still in use. ** ! 820: *********************************************************************/ ! 821: ! 822: if(cRef == 0) ! 823: OutlineApp_Destroy((LPOUTLINEAPP)lpOleApp); ! 824: ! 825: return cRef; ! 826: } ! 827: ! 828: ! 829: ! 830: /* OleApp_QueryInterface ! 831: ** --------------------- ! 832: ** ! 833: ** Retrieve a pointer to an interface on the app object. ! 834: ** ! 835: ** OLE2NOTE: this function will AddRef the ref cnt of the object. ! 836: ** ! 837: ** Returns NOERROR if interface is successfully retrieved. ! 838: ** S_FALSE if the interface is not supported ! 839: */ ! 840: HRESULT OleApp_QueryInterface ( ! 841: LPOLEAPP lpOleApp, ! 842: REFIID riid, ! 843: LPVOID FAR* lplpvObj ! 844: ) ! 845: { ! 846: SCODE sc; ! 847: ! 848: /* OLE2NOTE: we must make sure to set all out ptr parameters to NULL. */ ! 849: *lplpvObj = NULL; ! 850: ! 851: if (IsEqualIID(riid, &IID_IUnknown)) { ! 852: OleDbgOut4("OleApp_QueryInterface: IUnknown* RETURNED\r\n"); ! 853: ! 854: *lplpvObj = (LPVOID) &lpOleApp->m_Unknown; ! 855: OleApp_AddRef(lpOleApp); ! 856: sc = S_OK; ! 857: } ! 858: else { ! 859: sc = E_NOINTERFACE; ! 860: } ! 861: ! 862: OleDbgQueryInterfaceMethod(*lplpvObj); ! 863: return ResultFromScode(sc); ! 864: } ! 865: ! 866: ! 867: /* OleApp_RejectInComingCalls ! 868: ** ------------------------- ! 869: ** Reject/Handle in coming OLE (LRPC) calls. ! 870: ** ! 871: ** OLE2NOTE: if the app is in a state when it can NOT handle in ! 872: ** coming OLE method calls from an external process (via the LRPC ! 873: ** interprocess commnunication mechanism), then it should call ! 874: ** OleApp_RejectInComingCalls(TRUE). in this state the ! 875: ** IMessageFilter::HandleInComingCall method will return ! 876: ** SERVERCALL_RETRYLATER. this tells the caller to try again in a ! 877: ** little while. normally the calling app will put up a dialog (see ! 878: ** OleUIBusy dialog) in this situation informing the user of the ! 879: ** situation. the user then is normally given the option to ! 880: ** "Switch To..." the busy application, retry, or cancel the ! 881: ** operation. when the app is ready to continue processing such ! 882: ** calls, it should call OleApp_RejectInComingCalls(FALSE). in this ! 883: ** state, SERVERCALL_ISHANDLED is returned by ! 884: ** IMessageFilter::HandleInComingCall. ! 885: */ ! 886: void OleApp_RejectInComingCalls(LPOLEAPP lpOleApp, BOOL fReject) ! 887: { ! 888: OleDbgAssert(lpOleApp->m_lpMsgFilter != NULL); ! 889: if (! lpOleApp->m_lpMsgFilter) ! 890: return; ! 891: ! 892: OleStdMsgFilter_SetInComingCallStatus( ! 893: lpOleApp->m_lpMsgFilter, ! 894: (fReject ? SERVERCALL_RETRYLATER : SERVERCALL_ISHANDLED) ! 895: ); ! 896: } ! 897: ! 898: ! 899: /* OleApp_InitVtbls ! 900: * ---------------- ! 901: * ! 902: * initialize the methods in all of the interface Vtbl's ! 903: * ! 904: * OLE2NOTE: we only need one copy of each Vtbl. When an object which ! 905: * exposes an interface is instantiated, its lpVtbl is intialized ! 906: * to point to the single copy of the Vtbl. ! 907: * ! 908: */ ! 909: BOOL OleApp_InitVtbls (LPOLEAPP lpOleApp) ! 910: { ! 911: BOOL fStatus; ! 912: ! 913: // OleApp::IUnknown method table ! 914: OleStdInitVtbl(&g_OleApp_UnknownVtbl, sizeof(IUnknownVtbl)); ! 915: g_OleApp_UnknownVtbl.QueryInterface = OleApp_Unk_QueryInterface; ! 916: g_OleApp_UnknownVtbl.AddRef = OleApp_Unk_AddRef; ! 917: g_OleApp_UnknownVtbl.Release = OleApp_Unk_Release; ! 918: fStatus = OleStdCheckVtbl( ! 919: &g_OleApp_UnknownVtbl, ! 920: sizeof(IUnknownVtbl), ! 921: "IUnknown" ! 922: ); ! 923: if (! fStatus) return FALSE; ! 924: ! 925: // OleDoc::IUnknown method table ! 926: OleStdInitVtbl(&g_OleDoc_UnknownVtbl, sizeof(IUnknownVtbl)); ! 927: g_OleDoc_UnknownVtbl.QueryInterface = OleDoc_Unk_QueryInterface; ! 928: g_OleDoc_UnknownVtbl.AddRef = OleDoc_Unk_AddRef; ! 929: g_OleDoc_UnknownVtbl.Release = OleDoc_Unk_Release; ! 930: fStatus = OleStdCheckVtbl( ! 931: &g_OleDoc_UnknownVtbl, ! 932: sizeof(IUnknownVtbl), ! 933: "IUnknown" ! 934: ); ! 935: if (! fStatus) return FALSE; ! 936: ! 937: // OleDoc::IPersistFile method table ! 938: OleStdInitVtbl(&g_OleDoc_PersistFileVtbl, sizeof(IPersistFileVtbl)); ! 939: g_OleDoc_PersistFileVtbl.QueryInterface = OleDoc_PFile_QueryInterface; ! 940: g_OleDoc_PersistFileVtbl.AddRef = OleDoc_PFile_AddRef; ! 941: g_OleDoc_PersistFileVtbl.Release = OleDoc_PFile_Release; ! 942: g_OleDoc_PersistFileVtbl.GetClassID = OleDoc_PFile_GetClassID; ! 943: g_OleDoc_PersistFileVtbl.IsDirty = OleDoc_PFile_IsDirty; ! 944: g_OleDoc_PersistFileVtbl.Load = OleDoc_PFile_Load; ! 945: g_OleDoc_PersistFileVtbl.Save = OleDoc_PFile_Save; ! 946: g_OleDoc_PersistFileVtbl.SaveCompleted = OleDoc_PFile_SaveCompleted; ! 947: g_OleDoc_PersistFileVtbl.GetCurFile = OleDoc_PFile_GetCurFile; ! 948: fStatus = OleStdCheckVtbl( ! 949: &g_OleDoc_PersistFileVtbl, ! 950: sizeof(IPersistFileVtbl), ! 951: "IPersistFile" ! 952: ); ! 953: if (! fStatus) return FALSE; ! 954: ! 955: // OleDoc::IOleItemContainer method table ! 956: OleStdInitVtbl(&g_OleDoc_OleItemContainerVtbl, sizeof(IOleItemContainerVtbl)); ! 957: g_OleDoc_OleItemContainerVtbl.QueryInterface = ! 958: OleDoc_ItemCont_QueryInterface; ! 959: g_OleDoc_OleItemContainerVtbl.AddRef = OleDoc_ItemCont_AddRef; ! 960: g_OleDoc_OleItemContainerVtbl.Release = OleDoc_ItemCont_Release; ! 961: g_OleDoc_OleItemContainerVtbl.ParseDisplayName = ! 962: OleDoc_ItemCont_ParseDisplayName; ! 963: g_OleDoc_OleItemContainerVtbl.EnumObjects= OleDoc_ItemCont_EnumObjects; ! 964: g_OleDoc_OleItemContainerVtbl.LockContainer = ! 965: OleDoc_ItemCont_LockContainer; ! 966: g_OleDoc_OleItemContainerVtbl.GetObject = OleDoc_ItemCont_GetObject; ! 967: g_OleDoc_OleItemContainerVtbl.GetObjectStorage = ! 968: OleDoc_ItemCont_GetObjectStorage; ! 969: g_OleDoc_OleItemContainerVtbl.IsRunning = OleDoc_ItemCont_IsRunning; ! 970: fStatus = OleStdCheckVtbl( ! 971: &g_OleDoc_OleItemContainerVtbl, ! 972: sizeof(IOleItemContainerVtbl), ! 973: "IOleItemContainer" ! 974: ); ! 975: if (! fStatus) return FALSE; ! 976: ! 977: // OleDoc::IDataObject method table ! 978: OleStdInitVtbl(&g_OleDoc_DataObjectVtbl, sizeof(IDataObjectVtbl)); ! 979: g_OleDoc_DataObjectVtbl.QueryInterface = OleDoc_DataObj_QueryInterface; ! 980: g_OleDoc_DataObjectVtbl.AddRef = OleDoc_DataObj_AddRef; ! 981: g_OleDoc_DataObjectVtbl.Release = OleDoc_DataObj_Release; ! 982: g_OleDoc_DataObjectVtbl.GetData = OleDoc_DataObj_GetData; ! 983: g_OleDoc_DataObjectVtbl.GetDataHere = OleDoc_DataObj_GetDataHere; ! 984: g_OleDoc_DataObjectVtbl.QueryGetData = OleDoc_DataObj_QueryGetData; ! 985: g_OleDoc_DataObjectVtbl.GetCanonicalFormatEtc = ! 986: OleDoc_DataObj_GetCanonicalFormatEtc; ! 987: g_OleDoc_DataObjectVtbl.SetData = OleDoc_DataObj_SetData; ! 988: g_OleDoc_DataObjectVtbl.EnumFormatEtc = OleDoc_DataObj_EnumFormatEtc; ! 989: g_OleDoc_DataObjectVtbl.DAdvise = OleDoc_DataObj_DAdvise; ! 990: g_OleDoc_DataObjectVtbl.DUnadvise = OleDoc_DataObj_DUnadvise; ! 991: g_OleDoc_DataObjectVtbl.EnumDAdvise = OleDoc_DataObj_EnumDAdvise; ! 992: ! 993: fStatus = OleStdCheckVtbl( ! 994: &g_OleDoc_DataObjectVtbl, ! 995: sizeof(IDataObjectVtbl), ! 996: "IDataObject" ! 997: ); ! 998: if (! fStatus) return FALSE; ! 999: ! 1000: #if defined( USE_DRAGDROP ) ! 1001: ! 1002: // OleDoc::IDropTarget method table ! 1003: OleStdInitVtbl(&g_OleDoc_DropTargetVtbl, sizeof(IDropTargetVtbl)); ! 1004: g_OleDoc_DropTargetVtbl.QueryInterface= OleDoc_DropTarget_QueryInterface; ! 1005: g_OleDoc_DropTargetVtbl.AddRef = OleDoc_DropTarget_AddRef; ! 1006: g_OleDoc_DropTargetVtbl.Release = OleDoc_DropTarget_Release; ! 1007: ! 1008: g_OleDoc_DropTargetVtbl.DragEnter = OleDoc_DropTarget_DragEnter; ! 1009: g_OleDoc_DropTargetVtbl.DragOver = OleDoc_DropTarget_DragOver; ! 1010: g_OleDoc_DropTargetVtbl.DragLeave = OleDoc_DropTarget_DragLeave; ! 1011: g_OleDoc_DropTargetVtbl.Drop = OleDoc_DropTarget_Drop; ! 1012: ! 1013: fStatus = OleStdCheckVtbl( ! 1014: &g_OleDoc_DropTargetVtbl, ! 1015: sizeof(IDropTargetVtbl), ! 1016: "IDropTarget" ! 1017: ); ! 1018: if (! fStatus) ! 1019: return FALSE; ! 1020: ! 1021: // OleDoc::IDropSource method table ! 1022: OleStdInitVtbl(&g_OleDoc_DropSourceVtbl, sizeof(IDropSourceVtbl)); ! 1023: g_OleDoc_DropSourceVtbl.QueryInterface = ! 1024: OleDoc_DropSource_QueryInterface; ! 1025: g_OleDoc_DropSourceVtbl.AddRef = OleDoc_DropSource_AddRef; ! 1026: g_OleDoc_DropSourceVtbl.Release = OleDoc_DropSource_Release; ! 1027: ! 1028: g_OleDoc_DropSourceVtbl.QueryContinueDrag = ! 1029: OleDoc_DropSource_QueryContinueDrag; ! 1030: g_OleDoc_DropSourceVtbl.GiveFeedback = OleDoc_DropSource_GiveFeedback; ! 1031: ! 1032: fStatus = OleStdCheckVtbl( ! 1033: &g_OleDoc_DropSourceVtbl, ! 1034: sizeof(IDropSourceVtbl), ! 1035: "IDropSource" ! 1036: ); ! 1037: if (! fStatus) return FALSE; ! 1038: #endif // USE_DRAGDROP ! 1039: ! 1040: #if defined( OLE_SERVER ) ! 1041: ! 1042: // Initialize the server specific interface method tables. ! 1043: if (! ServerApp_InitVtbls((LPSERVERAPP)lpOleApp)) ! 1044: return FALSE; ! 1045: ! 1046: #elif defined( OLE_CNTR ) ! 1047: ! 1048: // Initialize the container specific interface method tables. ! 1049: if (! ContainerApp_InitVtbls((LPCONTAINERAPP)lpOleApp)) ! 1050: return FALSE; ! 1051: ! 1052: #endif ! 1053: return TRUE; ! 1054: }; ! 1055: ! 1056: ! 1057: ! 1058: /* OleApp_InitMenu ! 1059: * --------------- ! 1060: * ! 1061: * Enable or Disable menu items depending on the state of ! 1062: * the appliation. ! 1063: * The OLE versions of the Outline sample app add a PasteSpecial command. ! 1064: * Also, the container version add InsertObject and ObjectVerb menu items. ! 1065: */ ! 1066: void OleApp_InitMenu( ! 1067: LPOLEAPP lpOleApp, ! 1068: LPOLEDOC lpOleDoc, ! 1069: HMENU hMenu ! 1070: ) ! 1071: { ! 1072: BOOL bMsgFilterInstalled = FALSE; ! 1073: BOOL bRejecting = FALSE; ! 1074: ! 1075: if (!lpOleApp || !hMenu) ! 1076: return; ! 1077: ! 1078: OLEDBG_BEGIN3("OleApp_InitMenu\r\n") ! 1079: ! 1080: /* ! 1081: ** Enable/disable menu items for Message Filter ! 1082: */ ! 1083: bMsgFilterInstalled = (lpOleApp->m_lpMsgFilter != NULL); ! 1084: bRejecting = bMsgFilterInstalled && ! 1085: OleStdMsgFilter_GetInComingCallStatus(lpOleApp->m_lpMsgFilter) != SERVERCALL_ISHANDLED; ! 1086: ! 1087: CheckMenuItem(hMenu, ! 1088: IDM_D_INSTALLMSGFILTER, ! 1089: bMsgFilterInstalled ? MF_CHECKED : MF_UNCHECKED); ! 1090: ! 1091: EnableMenuItem(hMenu, ! 1092: IDM_D_REJECTINCOMING, ! 1093: bMsgFilterInstalled ? MF_ENABLED : MF_GRAYED); ! 1094: ! 1095: CheckMenuItem(hMenu, ! 1096: IDM_D_REJECTINCOMING, ! 1097: bRejecting ? MF_CHECKED : MF_UNCHECKED); ! 1098: ! 1099: #if defined( OLE_CNTR ) ! 1100: { ! 1101: LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOleDoc; ! 1102: BOOL fShowObject; ! 1103: ! 1104: fShowObject = ContainerDoc_GetShowObjectFlag(lpContainerDoc); ! 1105: CheckMenuItem( ! 1106: hMenu, ! 1107: IDM_O_SHOWOBJECT, ! 1108: (fShowObject ? MF_CHECKED : MF_UNCHECKED) ! 1109: ); ! 1110: ! 1111: #if defined( INPLACE_CNTR ) && defined( _DEBUG ) ! 1112: CheckMenuItem( ! 1113: hMenu, ! 1114: IDM_D_INSIDEOUT, ! 1115: g_fInsideOutContainer ? MF_CHECKED:MF_UNCHECKED); ! 1116: #endif // INPLACE_CNTR && _DEBUG ! 1117: ! 1118: } ! 1119: #endif // OLE_CNTR ! 1120: ! 1121: OLEDBG_END3 ! 1122: } ! 1123: ! 1124: ! 1125: ! 1126: /* OleApp_UpdateEditMenu ! 1127: * --------------------- ! 1128: * ! 1129: * Purpose: ! 1130: * Update the Edit menuitems of the App according to the state of ! 1131: * OutlineDoc ! 1132: * ! 1133: * Parameter: ! 1134: * lpOutlineDoc pointer to the document ! 1135: * hMenuEdit edit menu handle ! 1136: */ ! 1137: void OleApp_UpdateEditMenu( ! 1138: LPOLEAPP lpOleApp, ! 1139: LPOUTLINEDOC lpOutlineDoc, ! 1140: HMENU hMenuEdit ! 1141: ) ! 1142: { ! 1143: int nFmtEtc; ! 1144: UINT uEnablePaste = MF_GRAYED; ! 1145: UINT uEnablePasteLink = MF_GRAYED; ! 1146: LPDATAOBJECT lpClipboardDataObj; ! 1147: LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; ! 1148: HRESULT hrErr; ! 1149: BOOL bMsgFilterInstalled = (lpOleApp->m_lpMsgFilter != NULL); ! 1150: ! 1151: ! 1152: if (!lpOleApp || !lpOutlineDoc || !hMenuEdit) ! 1153: return; ! 1154: ! 1155: if (!OleDoc_GetUpdateEditMenuFlag(lpOleDoc)) ! 1156: /* OLE2NOTE: if the flag is not set, we don't have to update ! 1157: ** the edit menu again. This blocks repetitive updating when ! 1158: ** the user move the mouse across Edit menu while holding ! 1159: ** down the button ! 1160: */ ! 1161: return; ! 1162: ! 1163: OLEDBG_BEGIN3("OleApp_InitEditMenu\r\n") ! 1164: ! 1165: /* OLE2NOTE: we do not want to ever give the busy dialog when we ! 1166: ** are trying to put up our menus. eg. even if the source of ! 1167: ** data on the clipboard is busy, we do not want put up the busy ! 1168: ** dialog. thus we will disable the dialog and at the end ! 1169: ** re-enable it. ! 1170: */ ! 1171: if (bMsgFilterInstalled) ! 1172: OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, FALSE); ! 1173: ! 1174: // check if there is data on the clipboard that we can paste/paste link ! 1175: ! 1176: OLEDBG_BEGIN2("OleGetClipboard called\r\n") ! 1177: hrErr = OleGetClipboard((LPDATAOBJECT FAR*)&lpClipboardDataObj); ! 1178: OLEDBG_END2 ! 1179: ! 1180: if (hrErr == NOERROR) { ! 1181: nFmtEtc = OleStdGetPriorityClipboardFormat( ! 1182: lpClipboardDataObj, ! 1183: lpOleApp->m_arrPasteEntries, ! 1184: lpOleApp->m_nPasteEntries ! 1185: ); ! 1186: ! 1187: if (nFmtEtc >= 0) ! 1188: uEnablePaste = MF_ENABLED; // there IS a format we like ! 1189: ! 1190: OLEDBG_BEGIN2("OleQueryLinkFromData called\r\n") ! 1191: hrErr = OleQueryLinkFromData(lpClipboardDataObj); ! 1192: OLEDBG_END2 ! 1193: ! 1194: if(hrErr == NOERROR) ! 1195: uEnablePasteLink = MF_ENABLED; ! 1196: ! 1197: OleStdRelease((LPUNKNOWN)lpClipboardDataObj); ! 1198: } ! 1199: ! 1200: EnableMenuItem(hMenuEdit, IDM_E_PASTE, uEnablePaste); ! 1201: EnableMenuItem(hMenuEdit, IDM_E_PASTESPECIAL, uEnablePaste); ! 1202: ! 1203: ! 1204: #if defined( OLE_CNTR ) ! 1205: if (ContainerDoc_GetNextLink((LPCONTAINERDOC)lpOutlineDoc, NULL)) ! 1206: EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_ENABLED); ! 1207: else ! 1208: EnableMenuItem(hMenuEdit, IDM_E_EDITLINKS, MF_GRAYED); ! 1209: ! 1210: ! 1211: { ! 1212: LPCONTAINERAPP lpContainerApp = (LPCONTAINERAPP)lpOleApp; ! 1213: HMENU hMenuVerb = NULL; ! 1214: LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc); ! 1215: int nIndex = LineList_GetFocusLineIndex(lpLL); ! 1216: LPLINE lpLine = LineList_GetLine(lpLL, nIndex); ! 1217: LPOLEOBJECT lpOleObj = NULL; ! 1218: LPCONTAINERLINE lpContainerLine = NULL; ! 1219: BOOL fSelIsOleObject; ! 1220: ! 1221: EnableMenuItem(hMenuEdit, IDM_E_PASTELINK, uEnablePasteLink); ! 1222: ! 1223: /* check if selection is a single line that contains an OleObject */ ! 1224: ! 1225: fSelIsOleObject = ContainerDoc_IsSelAnOleObject( ! 1226: (LPCONTAINERDOC)lpOutlineDoc, ! 1227: &IID_IOleObject, ! 1228: (LPUNKNOWN FAR*)&lpOleObj, ! 1229: NULL, /* we don't need the line index */ ! 1230: (LPCONTAINERLINE FAR*)&lpContainerLine ! 1231: ); ! 1232: ! 1233: if (hMenuEdit != NULL) { ! 1234: ! 1235: /* If the current line is an ContainerLine, add the object ! 1236: ** verb sub menu to the Edit menu. if the line is not an ! 1237: ** ContainerLine, (lpOleObj==NULL) then disable the ! 1238: ** Edit.Object command. this helper API takes care of ! 1239: ** building the verb menu as appropriate. ! 1240: */ ! 1241: OleUIAddVerbMenu( ! 1242: (LPOLEOBJECT)lpOleObj, ! 1243: (lpContainerLine ? lpContainerLine->m_lpszShortType:NULL), ! 1244: hMenuEdit, ! 1245: POS_OBJECT, ! 1246: IDM_E_OBJECTVERBMIN, ! 1247: TRUE, // Add Convert menu item ! 1248: IDM_E_CONVERTVERB, // ID for Convert menu item ! 1249: (HMENU FAR*) &hMenuVerb ! 1250: ); ! 1251: ! 1252: #if defined( USE_STATUSBAR_LATER ) ! 1253: /* setup status messages for the object verb menu */ ! 1254: if (hMenuVerb) { ! 1255: // REVIEW: this string should come from a string resource. ! 1256: // REVIEW: this doesn't work for dynamically created menus ! 1257: AssignPopupMessage( ! 1258: hMenuVerb, ! 1259: "Open, edit or interact with an object" ! 1260: ); ! 1261: } ! 1262: #endif // USE_STATUSBAR_LATER ! 1263: } ! 1264: ! 1265: if (lpOleObj) ! 1266: OleStdRelease((LPUNKNOWN)lpOleObj); ! 1267: } ! 1268: ! 1269: #endif // OLE_CNTR ! 1270: ! 1271: // re-enable the busy dialog ! 1272: if (bMsgFilterInstalled) ! 1273: OleStdMsgFilter_EnableBusyDialog(lpOleApp->m_lpMsgFilter, TRUE); ! 1274: ! 1275: OleDoc_SetUpdateEditMenuFlag(lpOleDoc, FALSE); ! 1276: ! 1277: OLEDBG_END3 ! 1278: } ! 1279: ! 1280: ! 1281: /* OleApp_RegisterClassFactory ! 1282: * --------------------------- ! 1283: * ! 1284: * Register our app's ClassFactory with OLE. ! 1285: * ! 1286: */ ! 1287: BOOL OleApp_RegisterClassFactory(LPOLEAPP lpOleApp) ! 1288: { ! 1289: HRESULT hrErr; ! 1290: ! 1291: if (lpOleApp->m_lpClassFactory) ! 1292: return TRUE; // already registered ! 1293: ! 1294: OLEDBG_BEGIN3("OleApp_RegisterClassFactory\r\n") ! 1295: ! 1296: /****************************************************************** ! 1297: ** An SDI app must register its ClassFactory if it is launched ! 1298: ** for embedding (/Embedding command line option specified). ! 1299: ** An MDI app must register its ClassFactory in all cases, ! 1300: ******************************************************************/ ! 1301: ! 1302: lpOleApp->m_lpClassFactory = AppClassFactory_Create(); ! 1303: if (! lpOleApp->m_lpClassFactory) { ! 1304: OutlineApp_ErrorMessage(g_lpApp, ErrMsgCreateCF); ! 1305: goto error; ! 1306: } ! 1307: ! 1308: OLEDBG_BEGIN2("CoRegisterClassObject called\r\n") ! 1309: hrErr = CoRegisterClassObject( ! 1310: &CLSID_APP, ! 1311: (LPUNKNOWN)lpOleApp->m_lpClassFactory, ! 1312: CLSCTX_LOCAL_SERVER, ! 1313: REGCLS_SINGLEUSE, ! 1314: &lpOleApp->m_dwRegClassFac ! 1315: ); ! 1316: OLEDBG_END2 ! 1317: ! 1318: if(hrErr != NOERROR) { ! 1319: OleDbgOutHResult("CoRegisterClassObject returned", hrErr); ! 1320: OutlineApp_ErrorMessage(g_lpApp, ErrMsgRegCF); ! 1321: goto error; ! 1322: } ! 1323: ! 1324: OLEDBG_END3 ! 1325: return TRUE; ! 1326: ! 1327: error: ! 1328: ! 1329: if (lpOleApp->m_lpClassFactory) { ! 1330: OleStdRelease((LPUNKNOWN)lpOleApp->m_lpClassFactory); ! 1331: lpOleApp->m_lpClassFactory = NULL; ! 1332: } ! 1333: OLEDBG_END3 ! 1334: return FALSE; ! 1335: } ! 1336: ! 1337: ! 1338: /* OleApp_RevokeClassFactory ! 1339: * ------------------------- ! 1340: * ! 1341: * Revoke our app's ClassFactory. ! 1342: * ! 1343: */ ! 1344: void OleApp_RevokeClassFactory(LPOLEAPP lpOleApp) ! 1345: { ! 1346: HRESULT hrErr; ! 1347: ! 1348: if (lpOleApp->m_lpClassFactory) { ! 1349: ! 1350: OLEDBG_BEGIN2("CoRevokeClassObject called\r\n") ! 1351: hrErr = CoRevokeClassObject(lpOleApp->m_dwRegClassFac); ! 1352: OLEDBG_END2 ! 1353: if (hrErr != NOERROR) { ! 1354: OleDbgOutHResult("CoRevokeClassObject returned", hrErr); ! 1355: } ! 1356: ! 1357: OleStdVerifyRelease( ! 1358: (LPUNKNOWN)lpOleApp->m_lpClassFactory, ! 1359: "ClassFactory NOT released properly!" ! 1360: ); ! 1361: lpOleApp->m_lpClassFactory = NULL; ! 1362: } ! 1363: } ! 1364: ! 1365: ! 1366: #if defined( USE_MSGFILTER ) ! 1367: ! 1368: /* OleApp_RegisterMessageFilter ! 1369: * ---------------------------- ! 1370: * Register our IMessageFilter*. the message filter is used to handle ! 1371: * concurrency. we will use a standard implementation of IMessageFilter ! 1372: * that is included as part of the OLE2UI library. ! 1373: */ ! 1374: BOOL OleApp_RegisterMessageFilter(LPOLEAPP lpOleApp) ! 1375: { ! 1376: HRESULT hrErr; ! 1377: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 1378: ! 1379: if (lpOleApp->m_lpMsgFilter == NULL) { ! 1380: // Register our message filter. ! 1381: lpOleApp->m_lpfnMsgPending = (MSGPENDINGPROC)MessagePendingProc; ! 1382: lpOleApp->m_lpMsgFilter = OleStdMsgFilter_Create( ! 1383: g_lpApp->m_hWndApp, ! 1384: (LPSTR)APPNAME, ! 1385: lpOleApp->m_lpfnMsgPending ! 1386: ); ! 1387: ! 1388: OLEDBG_BEGIN2("CoRegisterMessageFilter called\r\n") ! 1389: hrErr = CoRegisterMessageFilter( ! 1390: lpOleApp->m_lpMsgFilter, ! 1391: NULL /* don't need previous message filter */ ! 1392: ); ! 1393: OLEDBG_END2 ! 1394: ! 1395: if(hrErr != NOERROR) { ! 1396: OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgRegMF); ! 1397: return FALSE; ! 1398: } ! 1399: } ! 1400: return TRUE; ! 1401: } ! 1402: ! 1403: ! 1404: /* OleApp_RevokeMessageFilter ! 1405: * -------------------------- ! 1406: * Revoke our IMessageFilter*. the message filter is used to handle ! 1407: * concurrency. we will use a standard implementation of IMessageFilter ! 1408: * that is included as part of the OLE2UI library. ! 1409: */ ! 1410: void OleApp_RevokeMessageFilter(LPOLEAPP lpOleApp) ! 1411: { ! 1412: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; ! 1413: ! 1414: if (lpOleApp->m_lpMsgFilter != NULL) { ! 1415: // Revoke our message filter ! 1416: OLEDBG_BEGIN2("CoRegisterMessageFilter(NULL) called\r\n") ! 1417: CoRegisterMessageFilter(NULL, NULL); ! 1418: OLEDBG_END2 ! 1419: ! 1420: if (lpOleApp->m_lpfnMsgPending) { ! 1421: lpOleApp->m_lpfnMsgPending = NULL; ! 1422: } ! 1423: ! 1424: OleStdVerifyRelease( ! 1425: (LPUNKNOWN)lpOleApp->m_lpMsgFilter, ! 1426: "Release MessageFilter FAILED!" ! 1427: ); ! 1428: lpOleApp->m_lpMsgFilter = NULL; ! 1429: } ! 1430: } ! 1431: ! 1432: ! 1433: /* MessagePendingProc ! 1434: * ------------------ ! 1435: * ! 1436: * Callback function for the IMessageFilter::MessagePending procedure. This ! 1437: * function is called when a message is received by our application while ! 1438: * we are waiting for an OLE call to complete. We are essentially ! 1439: * blocked at this point, waiting for a response from the other OLE application. ! 1440: * We should not process any messages which might cause another OLE call ! 1441: * to become blocked, or any other call which might cause re-entrancy problems. ! 1442: * ! 1443: * For this application, only process WM_PAINT messages. A more sophisticated ! 1444: * application might allow certain menu messages and menu items to be processed ! 1445: * also. ! 1446: * ! 1447: * RETURNS: TRUE if we processed the message, FALSE if we did not. ! 1448: */ ! 1449: ! 1450: BOOL FAR PASCAL EXPORT MessagePendingProc(MSG FAR *lpMsg) ! 1451: { ! 1452: BOOL fMsgDispatched = FALSE; ! 1453: ! 1454: // Our application is only handling WM_PAINT messages when we are blocked ! 1455: switch (lpMsg->message) { ! 1456: case WM_PAINT: ! 1457: ! 1458: OleDbgOut2("WM_PAINT dispatched while blocked\r\n"); ! 1459: ! 1460: DispatchMessage(lpMsg); ! 1461: ! 1462: fMsgDispatched = TRUE; ! 1463: break; ! 1464: } ! 1465: ! 1466: return fMsgDispatched; ! 1467: } ! 1468: #endif // USE_MSGFILTER ! 1469: ! 1470: ! 1471: /* OleApp_FlushClipboard ! 1472: * --------------------- ! 1473: * ! 1474: * Force the Windows clipboard to release our clipboard DataObject. ! 1475: */ ! 1476: void OleApp_FlushClipboard(LPOLEAPP lpOleApp) ! 1477: { ! 1478: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 1479: LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc; ! 1480: ! 1481: OLEDBG_BEGIN3("OleApp_FlushClipboard\r\n") ! 1482: ! 1483: /* OLE2NOTE: if for some reason our clipboard data transfer ! 1484: ** document is still held on to by an external client, we want ! 1485: ** to forceably break all external connections. ! 1486: */ ! 1487: OLEDBG_BEGIN2("CoDisconnectObject called\r\n") ! 1488: CoDisconnectObject((LPUNKNOWN)&lpClipboardDoc->m_Unknown, 0); ! 1489: OLEDBG_END2 ! 1490: ! 1491: OLEDBG_BEGIN2("OleFlushClipboard called\r\n") ! 1492: OleFlushClipboard(); ! 1493: OLEDBG_END2 ! 1494: ! 1495: lpOutlineApp->m_lpClipboardDoc = NULL; ! 1496: ! 1497: OLEDBG_END3 ! 1498: } ! 1499: ! 1500: ! 1501: /* OleApp_NewCommand ! 1502: * ----------------- ! 1503: * ! 1504: * Start a new untitled document (File.New command). ! 1505: */ ! 1506: void OleApp_NewCommand(LPOLEAPP lpOleApp) ! 1507: { ! 1508: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 1509: LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc; ! 1510: ! 1511: if (! OutlineDoc_Close(lpOutlineDoc, OLECLOSE_PROMPTSAVE)) { ! 1512: return; ! 1513: } ! 1514: ! 1515: OleDbgAssertSz(lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed"); ! 1516: ! 1517: lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); ! 1518: if (! lpOutlineApp->m_lpDoc) goto error; ! 1519: ! 1520: /* OLE2NOTE: initially the Doc object is created with a 0 ref ! 1521: ** count. in order to have a stable Doc object during the ! 1522: ** process of initializing the new Doc instance, ! 1523: ** we intially AddRef the Doc ref cnt and later ! 1524: ** Release it. This initial AddRef is artificial; it is simply ! 1525: ** done to guarantee that a harmless QueryInterface followed by ! 1526: ** a Release does not inadvertantly force our object to destroy ! 1527: ** itself prematurely. ! 1528: */ ! 1529: OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1530: ! 1531: // set the doc to an (Untitled) doc. ! 1532: if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc)) ! 1533: goto error; ! 1534: ! 1535: // position and size the new doc window ! 1536: OutlineApp_ResizeWindows(lpOutlineApp); ! 1537: OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); // calls OleDoc_Lock ! 1538: ! 1539: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef ! 1540: ! 1541: return; ! 1542: ! 1543: error: ! 1544: // REVIEW: should load string from string resource ! 1545: OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document"); ! 1546: ! 1547: if (lpOutlineApp->m_lpDoc) { ! 1548: // releasing the artificial AddRef above will destroy the document ! 1549: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1550: lpOutlineApp->m_lpDoc = NULL; ! 1551: } ! 1552: ! 1553: return; ! 1554: } ! 1555: ! 1556: ! 1557: /* OleApp_OpenCommand ! 1558: * ------------------ ! 1559: * ! 1560: * Load a document from file (File.Open command). ! 1561: */ ! 1562: void OleApp_OpenCommand(LPOLEAPP lpOleApp) ! 1563: { ! 1564: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpOleApp; ! 1565: LPOUTLINEDOC lpOutlineDoc = lpOutlineApp->m_lpDoc; ! 1566: OPENFILENAME ofn; ! 1567: char szFilter[]=APPFILENAMEFILTER; ! 1568: char szFileName[256]; ! 1569: UINT i; ! 1570: BOOL fStatus = TRUE; ! 1571: ! 1572: if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, OLECLOSE_PROMPTSAVE)) ! 1573: return; // abort opening new doc ! 1574: ! 1575: for(i=0; szFilter[i]; i++) ! 1576: if(szFilter[i]=='|') szFilter[i]='\0'; ! 1577: ! 1578: _fmemset((LPOPENFILENAME)&ofn,0,sizeof(OPENFILENAME)); ! 1579: ! 1580: szFileName[0]='\0'; ! 1581: ! 1582: ofn.lStructSize=sizeof(OPENFILENAME); ! 1583: ofn.hwndOwner=lpOutlineApp->m_hWndApp; ! 1584: ofn.lpstrFilter=(LPSTR)szFilter; ! 1585: ofn.lpstrFile=(LPSTR)szFileName; ! 1586: ofn.nMaxFile=sizeof(szFileName); ! 1587: ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ! 1588: ofn.lpstrDefExt=DEFEXTENSION; ! 1589: ! 1590: if(! GetOpenFileName((LPOPENFILENAME)&ofn)) ! 1591: return; // user canceled file open dialog ! 1592: ! 1593: OutlineDoc_Close(lpOutlineDoc, OLECLOSE_NOSAVE); ! 1594: OleDbgAssertSz( ! 1595: lpOutlineApp->m_lpDoc==NULL,"Closed doc NOT properly destroyed"); ! 1596: ! 1597: lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); ! 1598: if (! lpOutlineApp->m_lpDoc) goto error; ! 1599: ! 1600: /* OLE2NOTE: initially the Doc object is created with a 0 ref ! 1601: ** count. in order to have a stable Doc object during the ! 1602: ** process of initializing the new Doc instance, ! 1603: ** we intially AddRef the Doc ref cnt and later ! 1604: ** Release it. This initial AddRef is artificial; it is simply ! 1605: ** done to guarantee that a harmless QueryInterface followed by ! 1606: ** a Release does not inadvertantly force our object to destroy ! 1607: ** itself prematurely. ! 1608: */ ! 1609: OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1610: ! 1611: fStatus=OutlineDoc_LoadFromFile(lpOutlineApp->m_lpDoc, (LPSTR)szFileName); ! 1612: ! 1613: if (! fStatus) { ! 1614: // loading the doc failed; create an untitled instead ! 1615: ! 1616: // releasing the artificial AddRef above will destroy the document ! 1617: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1618: ! 1619: lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); ! 1620: if (! lpOutlineApp->m_lpDoc) goto error; ! 1621: OleDoc_AddRef((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1622: ! 1623: if (! OutlineDoc_InitNewFile(lpOutlineApp->m_lpDoc)) ! 1624: goto error; ! 1625: } ! 1626: ! 1627: // position and size the new doc window ! 1628: OutlineApp_ResizeWindows(lpOutlineApp); ! 1629: OutlineDoc_ShowWindow(lpOutlineApp->m_lpDoc); ! 1630: ! 1631: #if defined( OLE_CNTR ) ! 1632: UpdateWindow(lpOutlineApp->m_hWndApp); ! 1633: ContainerDoc_UpdateLinks((LPCONTAINERDOC)lpOutlineApp->m_lpDoc); ! 1634: #endif ! 1635: ! 1636: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); // rel artificial AddRef ! 1637: ! 1638: return; ! 1639: ! 1640: error: ! 1641: // REVIEW: should load string from string resource ! 1642: OutlineApp_ErrorMessage(lpOutlineApp, "Could not create new document"); ! 1643: ! 1644: if (lpOutlineApp->m_lpDoc) { ! 1645: // releasing the artificial AddRef above will destroy the document ! 1646: OleDoc_Release((LPOLEDOC)lpOutlineApp->m_lpDoc); ! 1647: lpOutlineApp->m_lpDoc = NULL; ! 1648: } ! 1649: ! 1650: return; ! 1651: } ! 1652: ! 1653: ! 1654: /************************************************************************* ! 1655: ** OleApp::IUnknown interface implementation ! 1656: *************************************************************************/ ! 1657: ! 1658: STDMETHODIMP OleApp_Unk_QueryInterface( ! 1659: LPUNKNOWN lpThis, ! 1660: REFIID riid, ! 1661: LPVOID FAR* lplpvObj ! 1662: ) ! 1663: { ! 1664: LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp; ! 1665: ! 1666: return OleApp_QueryInterface(lpOleApp, riid, lplpvObj); ! 1667: } ! 1668: ! 1669: ! 1670: STDMETHODIMP_(ULONG) OleApp_Unk_AddRef(LPUNKNOWN lpThis) ! 1671: { ! 1672: LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp; ! 1673: ! 1674: OleDbgAddRefMethod(lpThis, "IUnknown"); ! 1675: ! 1676: return OleApp_AddRef(lpOleApp); ! 1677: } ! 1678: ! 1679: ! 1680: STDMETHODIMP_(ULONG) OleApp_Unk_Release (LPUNKNOWN lpThis) ! 1681: { ! 1682: LPOLEAPP lpOleApp = ((struct CAppUnknownImpl FAR*)lpThis)->lpOleApp; ! 1683: ! 1684: OleDbgReleaseMethod(lpThis, "IUnknown"); ! 1685: ! 1686: return OleApp_Release(lpOleApp); ! 1687: } ! 1688: ! 1689: ! 1690: ! 1691: #if defined( OLE_SERVER ) ! 1692: ! 1693: /************************************************************************* ! 1694: ** ServerDoc Supprt Functions Used by Server versions ! 1695: *************************************************************************/ ! 1696: ! 1697: /* ServerApp_InitInstance ! 1698: * ---------------------- ! 1699: * ! 1700: * Initialize the app instance by creating the main frame window and ! 1701: * performing app instance specific initializations ! 1702: * (eg. initializing interface Vtbls). ! 1703: * ! 1704: * RETURNS: TRUE if the memory could be allocated, and the server app ! 1705: * was properly initialized. ! 1706: * FALSE otherwise ! 1707: * ! 1708: */ ! 1709: ! 1710: BOOL ServerApp_InitInstance( ! 1711: LPSERVERAPP lpServerApp, ! 1712: HINSTANCE hInst, ! 1713: int nCmdShow ! 1714: ) ! 1715: { ! 1716: LPOLEAPP lpOleApp = (LPOLEAPP)lpServerApp; ! 1717: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpServerApp; ! 1718: ! 1719: /* Setup arrays used by IDataObject::EnumFormatEtc. ! 1720: ** ! 1721: ** OLE2NOTE: The order that the formats are listed for GetData is very ! 1722: ** significant. It should be listed in order of highest fidelity ! 1723: ** formats to least fidelity formats. A common ordering will be: ! 1724: ** 1. private app formats ! 1725: ** 2. EmbedSource ! 1726: ** 3. lower fidelity interchange formats ! 1727: ** 4. pictures (metafile, dib, etc.) ! 1728: ** (graphic-related apps offer pictures 1st!) ! 1729: ** 5. LinkSource ! 1730: */ ! 1731: ! 1732: /* m_arrDocGetFmts array enumerates the formats that a ServerDoc ! 1733: ** DataTransferDoc object can offer (give) through a ! 1734: ** IDataObject::GetData call. a ServerDoc DataTransferDoc offers ! 1735: ** data formats in the following order: ! 1736: ** 1. CF_OUTLINE ! 1737: ** 2. CF_EMBEDSOURCE ! 1738: ** 3. CF_OBJECTDESCRIPTOR ! 1739: ** 4. CF_TEXT ! 1740: ** 5. CF_METAFILEPICT ! 1741: ** 6. CF_LINKSOURCE * ! 1742: ** 7. CF_LINKSRCDESCRIPTOR * ! 1743: ** ! 1744: ** * NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only ! 1745: ** offered if the doc is able to give ! 1746: ** a Moniker which references the data. CF_LINKSOURCE is ! 1747: ** deliberately listed last in this array of possible formats. ! 1748: ** if the doc does not have a Moniker then the last element of ! 1749: ** this array is not used. (see SvrDoc_DataObj_EnumFormatEtc). ! 1750: ** ! 1751: ** NOTE: The list of formats that a USER ServerDoc document can ! 1752: ** offer is a static list and is registered in the registration ! 1753: ** database for the SVROUTL class. The ! 1754: ** IDataObject::EnumFormatEtc method returns OLE_S_USEREG in the ! 1755: ** case the document is a user docuemt (ie. created via ! 1756: ** File.New, File.Open, InsertObject in a container, or ! 1757: ** IPersistFile::Load during binding a link source). this tells ! 1758: ** OLE to enumerate the formats automatically using the data the ! 1759: ** the REGDB. ! 1760: */ ! 1761: ! 1762: lpOleApp->m_arrDocGetFmts[0].cfFormat = lpOutlineApp->m_cfOutline; ! 1763: lpOleApp->m_arrDocGetFmts[0].ptd = NULL; ! 1764: lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT; ! 1765: lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_HGLOBAL; ! 1766: lpOleApp->m_arrDocGetFmts[0].lindex = -1; ! 1767: ! 1768: lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOleApp->m_cfEmbedSource; ! 1769: lpOleApp->m_arrDocGetFmts[1].ptd = NULL; ! 1770: lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT; ! 1771: lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_ISTORAGE; ! 1772: lpOleApp->m_arrDocGetFmts[1].lindex = -1; ! 1773: ! 1774: lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT; ! 1775: lpOleApp->m_arrDocGetFmts[2].ptd = NULL; ! 1776: lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT; ! 1777: lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL; ! 1778: lpOleApp->m_arrDocGetFmts[2].lindex = -1; ! 1779: ! 1780: lpOleApp->m_arrDocGetFmts[3].cfFormat = CF_METAFILEPICT; ! 1781: lpOleApp->m_arrDocGetFmts[3].ptd = NULL; ! 1782: lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT; ! 1783: lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_MFPICT; ! 1784: lpOleApp->m_arrDocGetFmts[3].lindex = -1; ! 1785: ! 1786: lpOleApp->m_arrDocGetFmts[4].cfFormat = lpOleApp->m_cfObjectDescriptor; ! 1787: lpOleApp->m_arrDocGetFmts[4].ptd = NULL; ! 1788: lpOleApp->m_arrDocGetFmts[4].dwAspect = DVASPECT_CONTENT; ! 1789: lpOleApp->m_arrDocGetFmts[4].tymed = TYMED_HGLOBAL; ! 1790: lpOleApp->m_arrDocGetFmts[4].lindex = -1; ! 1791: ! 1792: lpOleApp->m_arrDocGetFmts[5].cfFormat = lpOleApp->m_cfLinkSource; ! 1793: lpOleApp->m_arrDocGetFmts[5].ptd = NULL; ! 1794: lpOleApp->m_arrDocGetFmts[5].dwAspect = DVASPECT_CONTENT; ! 1795: lpOleApp->m_arrDocGetFmts[5].tymed = TYMED_ISTREAM; ! 1796: lpOleApp->m_arrDocGetFmts[5].lindex = -1; ! 1797: ! 1798: lpOleApp->m_arrDocGetFmts[6].cfFormat = lpOleApp->m_cfLinkSrcDescriptor; ! 1799: lpOleApp->m_arrDocGetFmts[6].ptd = NULL; ! 1800: lpOleApp->m_arrDocGetFmts[6].dwAspect = DVASPECT_CONTENT; ! 1801: lpOleApp->m_arrDocGetFmts[6].tymed = TYMED_HGLOBAL; ! 1802: lpOleApp->m_arrDocGetFmts[6].lindex = -1; ! 1803: ! 1804: lpOleApp->m_nDocGetFmts = 7; ! 1805: ! 1806: /* m_arrPasteEntries array enumerates the formats that a ServerDoc ! 1807: ** object can accept (get) from the clipboard. ! 1808: ** The formats are listed in priority order. ! 1809: ** ServerDoc accept data formats in the following order: ! 1810: ** 1. CF_OUTLINE ! 1811: ** 2. CF_TEXT ! 1812: */ ! 1813: // REVIEW: strings should be loaded from string resource ! 1814: lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat =lpOutlineApp->m_cfOutline; ! 1815: lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL; ! 1816: lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT; ! 1817: lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_HGLOBAL; ! 1818: lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1; ! 1819: lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Outline Data"; ! 1820: lpOleApp->m_arrPasteEntries[0].lpstrResultText = "as Outline Data"; ! 1821: lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY; ! 1822: ! 1823: lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat = CF_TEXT; ! 1824: lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL; ! 1825: lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT; ! 1826: lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL; ! 1827: lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1; ! 1828: lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Text"; ! 1829: lpOleApp->m_arrPasteEntries[1].lpstrResultText = "as text"; ! 1830: lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY; ! 1831: ! 1832: lpOleApp->m_nPasteEntries = 2; ! 1833: ! 1834: /** m_arrLinkTypes array enumerates the link types that a ServerDoc ! 1835: ** object can accept from the clipboard. ServerDoc does NOT ! 1836: ** accept any type of link from the clipboard. ServerDoc can ! 1837: ** only be the source of a link. it can not contain links. ! 1838: */ ! 1839: ! 1840: lpOleApp->m_nLinkTypes = 0; ! 1841: ! 1842: #if defined( INPLACE_SVR ) ! 1843: ! 1844: lpServerApp->m_hAccelIPSvr = LoadAccelerators( ! 1845: hInst, ! 1846: "InPlaceSvrOutlAccel" ! 1847: ); ! 1848: ! 1849: lpServerApp->m_lpIPData = NULL; ! 1850: ! 1851: lpServerApp->m_hMenuEdit = GetSubMenu ( ! 1852: lpOutlineApp->m_hMenuApp, ! 1853: POS_EDITMENU ! 1854: ); ! 1855: lpServerApp->m_hMenuLine = GetSubMenu ( ! 1856: lpOutlineApp->m_hMenuApp, ! 1857: POS_LINEMENU ! 1858: ); ! 1859: lpServerApp->m_hMenuName = GetSubMenu ( ! 1860: lpOutlineApp->m_hMenuApp, ! 1861: POS_NAMEMENU ! 1862: ); ! 1863: lpServerApp->m_hMenuOptions = GetSubMenu ( ! 1864: lpOutlineApp->m_hMenuApp, ! 1865: POS_OPTIONSMENU ! 1866: ); ! 1867: lpServerApp->m_hMenuDebug = GetSubMenu ( ! 1868: lpOutlineApp->m_hMenuApp, ! 1869: POS_DEBUGMENU ! 1870: ); ! 1871: lpServerApp->m_hMenuHelp = GetSubMenu ( ! 1872: lpOutlineApp->m_hMenuApp, ! 1873: POS_HELPMENU ! 1874: ); ! 1875: ! 1876: #endif // INPLACE_SVR ! 1877: ! 1878: return TRUE; ! 1879: } ! 1880: ! 1881: ! 1882: /* ServerApp_InitVtbls ! 1883: * ------------------- ! 1884: * ! 1885: * initialize the methods in all of the interface Vtbl's ! 1886: * ! 1887: * OLE2NOTE: we only need one copy of each Vtbl. When an object which ! 1888: * exposes an interface is instantiated, its lpVtbl is intialized ! 1889: * to point to the single copy of the Vtbl. ! 1890: * ! 1891: */ ! 1892: BOOL ServerApp_InitVtbls (LPSERVERAPP lpServerApp) ! 1893: { ! 1894: BOOL fStatus; ! 1895: ! 1896: // ServerDoc::IOleObject method table ! 1897: OleStdInitVtbl(&g_SvrDoc_OleObjectVtbl, sizeof(IOleObjectVtbl)); ! 1898: g_SvrDoc_OleObjectVtbl.QueryInterface = SvrDoc_OleObj_QueryInterface; ! 1899: g_SvrDoc_OleObjectVtbl.AddRef = SvrDoc_OleObj_AddRef; ! 1900: g_SvrDoc_OleObjectVtbl.Release = SvrDoc_OleObj_Release; ! 1901: g_SvrDoc_OleObjectVtbl.SetClientSite = SvrDoc_OleObj_SetClientSite; ! 1902: g_SvrDoc_OleObjectVtbl.GetClientSite = SvrDoc_OleObj_GetClientSite; ! 1903: g_SvrDoc_OleObjectVtbl.SetHostNames = SvrDoc_OleObj_SetHostNames; ! 1904: g_SvrDoc_OleObjectVtbl.Close = SvrDoc_OleObj_Close; ! 1905: g_SvrDoc_OleObjectVtbl.SetMoniker = SvrDoc_OleObj_SetMoniker; ! 1906: g_SvrDoc_OleObjectVtbl.GetMoniker = SvrDoc_OleObj_GetMoniker; ! 1907: g_SvrDoc_OleObjectVtbl.InitFromData = SvrDoc_OleObj_InitFromData; ! 1908: g_SvrDoc_OleObjectVtbl.GetClipboardData = SvrDoc_OleObj_GetClipboardData; ! 1909: g_SvrDoc_OleObjectVtbl.DoVerb = SvrDoc_OleObj_DoVerb; ! 1910: g_SvrDoc_OleObjectVtbl.EnumVerbs = SvrDoc_OleObj_EnumVerbs; ! 1911: g_SvrDoc_OleObjectVtbl.Update = SvrDoc_OleObj_Update; ! 1912: g_SvrDoc_OleObjectVtbl.IsUpToDate = SvrDoc_OleObj_IsUpToDate; ! 1913: g_SvrDoc_OleObjectVtbl.GetUserClassID = SvrDoc_OleObj_GetUserClassID; ! 1914: g_SvrDoc_OleObjectVtbl.GetUserType = SvrDoc_OleObj_GetUserType; ! 1915: g_SvrDoc_OleObjectVtbl.SetExtent = SvrDoc_OleObj_SetExtent; ! 1916: g_SvrDoc_OleObjectVtbl.GetExtent = SvrDoc_OleObj_GetExtent; ! 1917: g_SvrDoc_OleObjectVtbl.Advise = SvrDoc_OleObj_Advise; ! 1918: g_SvrDoc_OleObjectVtbl.Unadvise = SvrDoc_OleObj_Unadvise; ! 1919: g_SvrDoc_OleObjectVtbl.EnumAdvise = SvrDoc_OleObj_EnumAdvise; ! 1920: g_SvrDoc_OleObjectVtbl.GetMiscStatus = SvrDoc_OleObj_GetMiscStatus; ! 1921: g_SvrDoc_OleObjectVtbl.SetColorScheme = SvrDoc_OleObj_SetColorScheme; ! 1922: fStatus = OleStdCheckVtbl( ! 1923: &g_SvrDoc_OleObjectVtbl, ! 1924: sizeof(IOleObjectVtbl), ! 1925: "IOleObject" ! 1926: ); ! 1927: if (! fStatus) return FALSE; ! 1928: ! 1929: // ServerDoc::IPersistStorage method table ! 1930: OleStdInitVtbl(&g_SvrDoc_PersistStorageVtbl, sizeof(IPersistStorageVtbl)); ! 1931: g_SvrDoc_PersistStorageVtbl.QueryInterface = SvrDoc_PStg_QueryInterface; ! 1932: g_SvrDoc_PersistStorageVtbl.AddRef = SvrDoc_PStg_AddRef; ! 1933: g_SvrDoc_PersistStorageVtbl.Release = SvrDoc_PStg_Release; ! 1934: g_SvrDoc_PersistStorageVtbl.GetClassID = SvrDoc_PStg_GetClassID; ! 1935: g_SvrDoc_PersistStorageVtbl.IsDirty = SvrDoc_PStg_IsDirty; ! 1936: g_SvrDoc_PersistStorageVtbl.InitNew = SvrDoc_PStg_InitNew; ! 1937: g_SvrDoc_PersistStorageVtbl.Load = SvrDoc_PStg_Load; ! 1938: g_SvrDoc_PersistStorageVtbl.Save = SvrDoc_PStg_Save; ! 1939: g_SvrDoc_PersistStorageVtbl.SaveCompleted = SvrDoc_PStg_SaveCompleted; ! 1940: g_SvrDoc_PersistStorageVtbl.HandsOffStorage = SvrDoc_PStg_HandsOffStorage; ! 1941: fStatus = OleStdCheckVtbl( ! 1942: &g_SvrDoc_PersistStorageVtbl, ! 1943: sizeof(IPersistStorageVtbl), ! 1944: "IPersistStorage" ! 1945: ); ! 1946: if (! fStatus) return FALSE; ! 1947: ! 1948: #if defined( SVR_TREATAS ) ! 1949: // ServerDoc::IStdMarshalInfo method table ! 1950: OleStdInitVtbl( ! 1951: &g_SvrDoc_StdMarshalInfoVtbl, sizeof(IStdMarshalInfoVtbl)); ! 1952: g_SvrDoc_StdMarshalInfoVtbl.QueryInterface = ! 1953: SvrDoc_StdMshl_QueryInterface; ! 1954: g_SvrDoc_StdMarshalInfoVtbl.AddRef = SvrDoc_StdMshl_AddRef; ! 1955: g_SvrDoc_StdMarshalInfoVtbl.Release = SvrDoc_StdMshl_Release; ! 1956: g_SvrDoc_StdMarshalInfoVtbl.GetClassForHandler = ! 1957: SvrDoc_StdMshl_GetClassForHandler; ! 1958: fStatus = OleStdCheckVtbl( ! 1959: &g_SvrDoc_StdMarshalInfoVtbl, ! 1960: sizeof(IStdMarshalInfoVtbl), ! 1961: "IStdMarshalInfo" ! 1962: ); ! 1963: if (! fStatus) return FALSE; ! 1964: #endif // SVR_TREATAS ! 1965: ! 1966: #if defined( INPLACE_SVR ) ! 1967: // ServerDoc::IOleInPlaceObject method table ! 1968: OleStdInitVtbl( ! 1969: &g_SvrDoc_OleInPlaceObjectVtbl, ! 1970: sizeof(IOleInPlaceObjectVtbl) ! 1971: ); ! 1972: g_SvrDoc_OleInPlaceObjectVtbl.QueryInterface ! 1973: = SvrDoc_IPObj_QueryInterface; ! 1974: g_SvrDoc_OleInPlaceObjectVtbl.AddRef ! 1975: = SvrDoc_IPObj_AddRef; ! 1976: g_SvrDoc_OleInPlaceObjectVtbl.Release ! 1977: = SvrDoc_IPObj_Release; ! 1978: g_SvrDoc_OleInPlaceObjectVtbl.GetWindow ! 1979: = SvrDoc_IPObj_GetWindow; ! 1980: g_SvrDoc_OleInPlaceObjectVtbl.ContextSensitiveHelp ! 1981: = SvrDoc_IPObj_ContextSensitiveHelp; ! 1982: g_SvrDoc_OleInPlaceObjectVtbl.InPlaceDeactivate ! 1983: = SvrDoc_IPObj_InPlaceDeactivate; ! 1984: g_SvrDoc_OleInPlaceObjectVtbl.UIDeactivate ! 1985: = SvrDoc_IPObj_UIDeactivate; ! 1986: g_SvrDoc_OleInPlaceObjectVtbl.SetObjectRects ! 1987: = SvrDoc_IPObj_SetObjectRects; ! 1988: g_SvrDoc_OleInPlaceObjectVtbl.ReactivateAndUndo ! 1989: = SvrDoc_IPObj_ReactivateAndUndo; ! 1990: fStatus = OleStdCheckVtbl( ! 1991: &g_SvrDoc_OleInPlaceObjectVtbl, ! 1992: sizeof(IOleInPlaceObjectVtbl), ! 1993: "IOleInPlaceObject" ! 1994: ); ! 1995: if (! fStatus) return FALSE; ! 1996: ! 1997: // ServerDoc::IOleInPlaceActiveObject method table ! 1998: OleStdInitVtbl( ! 1999: &g_SvrDoc_OleInPlaceActiveObjectVtbl, ! 2000: sizeof(IOleInPlaceActiveObjectVtbl) ! 2001: ); ! 2002: g_SvrDoc_OleInPlaceActiveObjectVtbl.QueryInterface ! 2003: = SvrDoc_IPActiveObj_QueryInterface; ! 2004: g_SvrDoc_OleInPlaceActiveObjectVtbl.AddRef ! 2005: = SvrDoc_IPActiveObj_AddRef; ! 2006: g_SvrDoc_OleInPlaceActiveObjectVtbl.Release ! 2007: = SvrDoc_IPActiveObj_Release; ! 2008: g_SvrDoc_OleInPlaceActiveObjectVtbl.GetWindow ! 2009: = SvrDoc_IPActiveObj_GetWindow; ! 2010: g_SvrDoc_OleInPlaceActiveObjectVtbl.ContextSensitiveHelp ! 2011: = SvrDoc_IPActiveObj_ContextSensitiveHelp; ! 2012: g_SvrDoc_OleInPlaceActiveObjectVtbl.TranslateAccelerator ! 2013: = SvrDoc_IPActiveObj_TranslateAccelerator; ! 2014: g_SvrDoc_OleInPlaceActiveObjectVtbl.OnFrameWindowActivate ! 2015: = SvrDoc_IPActiveObj_OnFrameWindowActivate; ! 2016: g_SvrDoc_OleInPlaceActiveObjectVtbl.OnDocWindowActivate ! 2017: = SvrDoc_IPActiveObj_OnDocWindowActivate; ! 2018: g_SvrDoc_OleInPlaceActiveObjectVtbl.ResizeBorder ! 2019: = SvrDoc_IPActiveObj_ResizeBorder; ! 2020: g_SvrDoc_OleInPlaceActiveObjectVtbl.EnableModeless ! 2021: = SvrDoc_IPActiveObj_EnableModeless; ! 2022: fStatus = OleStdCheckVtbl( ! 2023: &g_SvrDoc_OleInPlaceActiveObjectVtbl, ! 2024: sizeof(IOleInPlaceActiveObjectVtbl), ! 2025: "IOleInPlaceActiveObject" ! 2026: ); ! 2027: if (! fStatus) return FALSE; ! 2028: ! 2029: #endif ! 2030: ! 2031: ! 2032: // PseudoObj::IUnknown method table ! 2033: OleStdInitVtbl(&g_PseudoObj_UnknownVtbl, sizeof(IUnknownVtbl)); ! 2034: g_PseudoObj_UnknownVtbl.QueryInterface = PseudoObj_Unk_QueryInterface; ! 2035: g_PseudoObj_UnknownVtbl.AddRef = PseudoObj_Unk_AddRef; ! 2036: g_PseudoObj_UnknownVtbl.Release = PseudoObj_Unk_Release; ! 2037: fStatus = OleStdCheckVtbl( ! 2038: &g_PseudoObj_UnknownVtbl, ! 2039: sizeof(IUnknownVtbl), ! 2040: "IUnknown" ! 2041: ); ! 2042: if (! fStatus) return FALSE; ! 2043: ! 2044: // PseudoObj::IOleObject method table ! 2045: OleStdInitVtbl(&g_PseudoObj_OleObjectVtbl, sizeof(IOleObjectVtbl)); ! 2046: g_PseudoObj_OleObjectVtbl.QueryInterface= PseudoObj_OleObj_QueryInterface; ! 2047: g_PseudoObj_OleObjectVtbl.AddRef = PseudoObj_OleObj_AddRef; ! 2048: g_PseudoObj_OleObjectVtbl.Release = PseudoObj_OleObj_Release; ! 2049: g_PseudoObj_OleObjectVtbl.SetClientSite = PseudoObj_OleObj_SetClientSite; ! 2050: g_PseudoObj_OleObjectVtbl.GetClientSite = PseudoObj_OleObj_GetClientSite; ! 2051: g_PseudoObj_OleObjectVtbl.SetHostNames = PseudoObj_OleObj_SetHostNames; ! 2052: g_PseudoObj_OleObjectVtbl.Close = PseudoObj_OleObj_Close; ! 2053: g_PseudoObj_OleObjectVtbl.SetMoniker = PseudoObj_OleObj_SetMoniker; ! 2054: g_PseudoObj_OleObjectVtbl.GetMoniker = PseudoObj_OleObj_GetMoniker; ! 2055: g_PseudoObj_OleObjectVtbl.InitFromData = PseudoObj_OleObj_InitFromData; ! 2056: g_PseudoObj_OleObjectVtbl.GetClipboardData = ! 2057: PseudoObj_OleObj_GetClipboardData; ! 2058: g_PseudoObj_OleObjectVtbl.DoVerb = PseudoObj_OleObj_DoVerb; ! 2059: g_PseudoObj_OleObjectVtbl.EnumVerbs = PseudoObj_OleObj_EnumVerbs; ! 2060: g_PseudoObj_OleObjectVtbl.Update = PseudoObj_OleObj_Update; ! 2061: g_PseudoObj_OleObjectVtbl.IsUpToDate = PseudoObj_OleObj_IsUpToDate; ! 2062: g_PseudoObj_OleObjectVtbl.GetUserType = PseudoObj_OleObj_GetUserType; ! 2063: g_PseudoObj_OleObjectVtbl.GetUserClassID= PseudoObj_OleObj_GetUserClassID; ! 2064: g_PseudoObj_OleObjectVtbl.SetExtent = PseudoObj_OleObj_SetExtent; ! 2065: g_PseudoObj_OleObjectVtbl.GetExtent = PseudoObj_OleObj_GetExtent; ! 2066: g_PseudoObj_OleObjectVtbl.Advise = PseudoObj_OleObj_Advise; ! 2067: g_PseudoObj_OleObjectVtbl.Unadvise = PseudoObj_OleObj_Unadvise; ! 2068: g_PseudoObj_OleObjectVtbl.EnumAdvise = PseudoObj_OleObj_EnumAdvise; ! 2069: g_PseudoObj_OleObjectVtbl.GetMiscStatus = PseudoObj_OleObj_GetMiscStatus; ! 2070: g_PseudoObj_OleObjectVtbl.SetColorScheme= PseudoObj_OleObj_SetColorScheme; ! 2071: fStatus = OleStdCheckVtbl( ! 2072: &g_PseudoObj_OleObjectVtbl, ! 2073: sizeof(IOleObjectVtbl), ! 2074: "IOleObject" ! 2075: ); ! 2076: if (! fStatus) return FALSE; ! 2077: ! 2078: // ServerDoc::IDataObject method table ! 2079: OleStdInitVtbl(&g_PseudoObj_DataObjectVtbl, sizeof(IDataObjectVtbl)); ! 2080: g_PseudoObj_DataObjectVtbl.QueryInterface = ! 2081: PseudoObj_DataObj_QueryInterface; ! 2082: g_PseudoObj_DataObjectVtbl.AddRef = PseudoObj_DataObj_AddRef; ! 2083: g_PseudoObj_DataObjectVtbl.Release = PseudoObj_DataObj_Release; ! 2084: g_PseudoObj_DataObjectVtbl.GetData = PseudoObj_DataObj_GetData; ! 2085: g_PseudoObj_DataObjectVtbl.GetDataHere = PseudoObj_DataObj_GetDataHere; ! 2086: g_PseudoObj_DataObjectVtbl.QueryGetData = PseudoObj_DataObj_QueryGetData; ! 2087: g_PseudoObj_DataObjectVtbl.GetCanonicalFormatEtc = ! 2088: PseudoObj_DataObj_GetCanonicalFormatEtc; ! 2089: g_PseudoObj_DataObjectVtbl.SetData = PseudoObj_DataObj_SetData; ! 2090: g_PseudoObj_DataObjectVtbl.EnumFormatEtc= PseudoObj_DataObj_EnumFormatEtc; ! 2091: g_PseudoObj_DataObjectVtbl.DAdvise = PseudoObj_DataObj_Advise; ! 2092: g_PseudoObj_DataObjectVtbl.DUnadvise = PseudoObj_DataObj_Unadvise; ! 2093: g_PseudoObj_DataObjectVtbl.EnumDAdvise = PseudoObj_DataObj_EnumAdvise; ! 2094: ! 2095: fStatus = OleStdCheckVtbl( ! 2096: &g_PseudoObj_DataObjectVtbl, ! 2097: sizeof(IDataObjectVtbl), ! 2098: "IDataObject" ! 2099: ); ! 2100: if (! fStatus) return FALSE; ! 2101: ! 2102: return TRUE; ! 2103: } ! 2104: ! 2105: #endif // OLE_SERVER ! 2106: ! 2107: ! 2108: ! 2109: #if defined( OLE_CNTR ) ! 2110: ! 2111: /************************************************************************* ! 2112: ** ContainerDoc Supprt Functions Used by Container versions ! 2113: *************************************************************************/ ! 2114: ! 2115: ! 2116: /* ContainerApp_InitInstance ! 2117: * ------------------------- ! 2118: * ! 2119: * Initialize the app instance by creating the main frame window and ! 2120: * performing app instance specific initializations ! 2121: * (eg. initializing interface Vtbls). ! 2122: * ! 2123: * RETURNS: TRUE if the memory could be allocated, and the server app ! 2124: * was properly initialized. ! 2125: * FALSE otherwise ! 2126: * ! 2127: */ ! 2128: ! 2129: BOOL ContainerApp_InitInstance( ! 2130: LPCONTAINERAPP lpContainerApp, ! 2131: HINSTANCE hInst, ! 2132: int nCmdShow ! 2133: ) ! 2134: { ! 2135: LPOLEAPP lpOleApp = (LPOLEAPP)lpContainerApp; ! 2136: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)lpContainerApp; ! 2137: ! 2138: lpContainerApp->m_cfCntrOutl=RegisterClipboardFormat(CONTAINERDOCFORMAT); ! 2139: if(! lpContainerApp->m_cfCntrOutl) { ! 2140: // REVIEW: should load string from string resource ! 2141: OutlineApp_ErrorMessage(lpOutlineApp, "Can't register clipboard format!"); ! 2142: return FALSE; ! 2143: } ! 2144: ! 2145: #if defined( INPLACE_CNTR ) ! 2146: ! 2147: lpContainerApp->m_fPendingUIDeactivate = FALSE; ! 2148: lpContainerApp->m_lpIPActiveObj = NULL; ! 2149: lpContainerApp->m_hAccelIPCntr = LoadAccelerators( ! 2150: hInst, ! 2151: "InPlaceCntrOutlAccel" ! 2152: ); ! 2153: lpContainerApp->m_hMenuFile = GetSubMenu ( ! 2154: lpOutlineApp->m_hMenuApp, ! 2155: POS_FILEMENU ! 2156: ); ! 2157: lpContainerApp->m_hMenuView = GetSubMenu ( ! 2158: lpOutlineApp->m_hMenuApp, ! 2159: POS_VIEWMENU ! 2160: ); ! 2161: lpContainerApp->m_hMenuDebug = GetSubMenu ( ! 2162: lpOutlineApp->m_hMenuApp, ! 2163: POS_DEBUGMENU ! 2164: ); ! 2165: ! 2166: INIT_INTERFACEIMPL( ! 2167: &lpContainerApp->m_OleInPlaceFrame, ! 2168: &g_CntrApp_OleInPlaceFrameVtbl, ! 2169: lpContainerApp ! 2170: ); ! 2171: ! 2172: #endif ! 2173: ! 2174: /* Setup arrays used by IDataObject::EnumFormatEtc. This is used to ! 2175: ** support copy/paste and drag/drop operations. ! 2176: ** ! 2177: ** OLE2NOTE: The order that the formats are listed for GetData is very ! 2178: ** significant. It should be listed in order of highest fidelity ! 2179: ** formats to least fidelity formats. A common ordering will be: ! 2180: ** 1. private app formats ! 2181: ** 2. CF_EMBEDSOURCE or CF_EMBEDOBJECT (as appropriate) ! 2182: ** 3. lower fidelity interchange formats ! 2183: ** 4. CF_METAFILEPICT ! 2184: ** (graphic-related apps might offer picture 1st!) ! 2185: ** 5. CF_OBJECTDESCRIPTOR ! 2186: ** 6. CF_LINKSOURCE ! 2187: ** 6. CF_LINKSRCDESCRIPTOR ! 2188: */ ! 2189: ! 2190: /* m_arrDocGetFmts array enumerates the formats that a ContainerDoc ! 2191: ** object can offer (give) through a IDataObject::GetData call ! 2192: ** when the selection copied is NOT a single embedded object. ! 2193: ** when a single embedded object this list of formats available ! 2194: ** is built dynamically depending on the object copied. (see ! 2195: ** ContainerDoc_SetupDocGetFmts). ! 2196: ** The formats are listed in priority order. ! 2197: ** ContainerDoc objects accept data formats in the following order: ! 2198: ** 1. CF_CNTROUTL ! 2199: ** 2. CF_OUTLINE ! 2200: ** 3. CF_TEXT ! 2201: ** 4. CF_OBJECTDESCRIPTOR ! 2202: ** ! 2203: ** OLE2NOTE: CF_OBJECTDESCRIPTOR format is used to describe the ! 2204: ** data on the clipboard. this information is intended to be ! 2205: ** used, for example, to drive the PasteSpecial dialog. it is ! 2206: ** useful to render CF_OBJECTDESCRIPTOR format even when the ! 2207: ** data on the clipboard does NOT include CF_EMBEDDEDOBJECT ! 2208: ** format or CF_EMBEDSOURCE format as when a selection that is ! 2209: ** not a single OLE object is copied from the container only ! 2210: ** version CNTROUTL. by rendering CF_OBJECTDESCRIPTOR format the ! 2211: ** app can indicate a useful string to identifiy the source of ! 2212: ** the copy to the user. ! 2213: */ ! 2214: ! 2215: lpOleApp->m_arrDocGetFmts[0].cfFormat = lpContainerApp->m_cfCntrOutl; ! 2216: lpOleApp->m_arrDocGetFmts[0].ptd = NULL; ! 2217: lpOleApp->m_arrDocGetFmts[0].dwAspect = DVASPECT_CONTENT; ! 2218: lpOleApp->m_arrDocGetFmts[0].tymed = TYMED_ISTORAGE; ! 2219: lpOleApp->m_arrDocGetFmts[0].lindex = -1; ! 2220: ! 2221: lpOleApp->m_arrDocGetFmts[1].cfFormat = lpOutlineApp->m_cfOutline; ! 2222: lpOleApp->m_arrDocGetFmts[1].ptd = NULL; ! 2223: lpOleApp->m_arrDocGetFmts[1].dwAspect = DVASPECT_CONTENT; ! 2224: lpOleApp->m_arrDocGetFmts[1].tymed = TYMED_HGLOBAL; ! 2225: lpOleApp->m_arrDocGetFmts[1].lindex = -1; ! 2226: ! 2227: lpOleApp->m_arrDocGetFmts[2].cfFormat = CF_TEXT; ! 2228: lpOleApp->m_arrDocGetFmts[2].ptd = NULL; ! 2229: lpOleApp->m_arrDocGetFmts[2].dwAspect = DVASPECT_CONTENT; ! 2230: lpOleApp->m_arrDocGetFmts[2].tymed = TYMED_HGLOBAL; ! 2231: lpOleApp->m_arrDocGetFmts[2].lindex = -1; ! 2232: ! 2233: lpOleApp->m_arrDocGetFmts[3].cfFormat = lpOleApp->m_cfObjectDescriptor; ! 2234: lpOleApp->m_arrDocGetFmts[3].ptd = NULL; ! 2235: lpOleApp->m_arrDocGetFmts[3].dwAspect = DVASPECT_CONTENT; ! 2236: lpOleApp->m_arrDocGetFmts[3].tymed = TYMED_HGLOBAL; ! 2237: lpOleApp->m_arrDocGetFmts[3].lindex = -1; ! 2238: ! 2239: lpOleApp->m_nDocGetFmts = 4; ! 2240: ! 2241: /* m_arrSingleObjGetFmts array enumerates the formats that a ! 2242: ** ContainerDoc object can offer (give) through a ! 2243: ** IDataObject::GetData call when the selection copied IS a ! 2244: ** single OLE object. ! 2245: ** ContainerDoc objects accept data formats in the following order: ! 2246: ** 1. CF_CNTROUTL ! 2247: ** 2. CF_EMBEDDEDOBJECT ! 2248: ** 3. CF_OBJECTDESCRIPTOR ! 2249: ** 4. CF_METAFILEPICT (note DVASPECT will vary) ! 2250: ** 5. CF_OUTLINE ! 2251: ** 6. CF_TEXT ! 2252: ** 7. CF_LINKSOURCE * ! 2253: ** 8. CF_LINKSRCDESCRIPTOR * ! 2254: ** ! 2255: ** * OLE2NOTE: CF_LINKSOURCE and CF_LINKSRCDESCRIPTOR is only ! 2256: ** offered if the OLE object is allowed to be linked to from the ! 2257: ** inside (ie. we are allowed to give out a moniker which binds ! 2258: ** to the running OLE object), then we want to offer ! 2259: ** CF_LINKSOURCE format. if the object is an OLE 2.0 embedded ! 2260: ** object then it is allowed to be linked to from the inside. if ! 2261: ** the object is either an OleLink or an OLE 1.0 embedding then ! 2262: ** it can not be linked to from the inside. if we were a ! 2263: ** container/server app then we could offer linking to the ! 2264: ** outside of the object (ie. a pseudo object within our ! 2265: ** document). we are a container only app that does not support ! 2266: ** linking to ranges of its data. ! 2267: ** the simplest way to determine if an object can be linked to ! 2268: ** on the inside is to call IOleObject::GetMiscStatus and test ! 2269: ** to see if the OLEMISC_CANTLINKINSIDE bit is NOT set. ! 2270: ** ! 2271: ** OLE2NOTE: optionally, a container that wants to have a ! 2272: ** potentially richer data transfer, can enumerate the data ! 2273: ** formats from the OLE object's cache and offer them too. if ! 2274: ** the object has a special handler, then it might be able to ! 2275: ** render additional data formats. ! 2276: */ ! 2277: lpContainerApp->m_arrSingleObjGetFmts[0].cfFormat = ! 2278: lpContainerApp->m_cfCntrOutl; ! 2279: lpContainerApp->m_arrSingleObjGetFmts[0].ptd = NULL; ! 2280: lpContainerApp->m_arrSingleObjGetFmts[0].dwAspect = DVASPECT_CONTENT; ! 2281: lpContainerApp->m_arrSingleObjGetFmts[0].tymed = TYMED_ISTORAGE; ! 2282: lpContainerApp->m_arrSingleObjGetFmts[0].lindex = -1; ! 2283: ! 2284: lpContainerApp->m_arrSingleObjGetFmts[1].cfFormat = ! 2285: lpOleApp->m_cfEmbeddedObject; ! 2286: lpContainerApp->m_arrSingleObjGetFmts[1].ptd = NULL; ! 2287: lpContainerApp->m_arrSingleObjGetFmts[1].dwAspect = DVASPECT_CONTENT; ! 2288: lpContainerApp->m_arrSingleObjGetFmts[1].tymed = TYMED_ISTORAGE; ! 2289: lpContainerApp->m_arrSingleObjGetFmts[1].lindex = -1; ! 2290: ! 2291: lpContainerApp->m_arrSingleObjGetFmts[2].cfFormat = ! 2292: lpOleApp->m_cfObjectDescriptor; ! 2293: lpContainerApp->m_arrSingleObjGetFmts[2].ptd = NULL; ! 2294: lpContainerApp->m_arrSingleObjGetFmts[2].dwAspect = DVASPECT_CONTENT; ! 2295: lpContainerApp->m_arrSingleObjGetFmts[2].tymed = TYMED_HGLOBAL; ! 2296: lpContainerApp->m_arrSingleObjGetFmts[2].lindex = -1; ! 2297: ! 2298: lpContainerApp->m_arrSingleObjGetFmts[3].cfFormat = CF_METAFILEPICT; ! 2299: lpContainerApp->m_arrSingleObjGetFmts[3].ptd = NULL; ! 2300: lpContainerApp->m_arrSingleObjGetFmts[3].dwAspect = DVASPECT_CONTENT; ! 2301: lpContainerApp->m_arrSingleObjGetFmts[3].tymed = TYMED_MFPICT; ! 2302: lpContainerApp->m_arrSingleObjGetFmts[3].lindex = -1; ! 2303: ! 2304: lpContainerApp->m_arrSingleObjGetFmts[4].cfFormat = ! 2305: lpOutlineApp->m_cfOutline; ! 2306: lpContainerApp->m_arrSingleObjGetFmts[4].ptd = NULL; ! 2307: lpContainerApp->m_arrSingleObjGetFmts[4].dwAspect = DVASPECT_CONTENT; ! 2308: lpContainerApp->m_arrSingleObjGetFmts[4].tymed = TYMED_HGLOBAL; ! 2309: lpContainerApp->m_arrSingleObjGetFmts[4].lindex = -1; ! 2310: ! 2311: lpContainerApp->m_arrSingleObjGetFmts[5].cfFormat = CF_TEXT; ! 2312: lpContainerApp->m_arrSingleObjGetFmts[5].ptd = NULL; ! 2313: lpContainerApp->m_arrSingleObjGetFmts[5].dwAspect = DVASPECT_CONTENT; ! 2314: lpContainerApp->m_arrSingleObjGetFmts[5].tymed = TYMED_HGLOBAL; ! 2315: lpContainerApp->m_arrSingleObjGetFmts[5].lindex = -1; ! 2316: ! 2317: lpContainerApp->m_arrSingleObjGetFmts[6].cfFormat = ! 2318: lpOleApp->m_cfLinkSource; ! 2319: lpContainerApp->m_arrSingleObjGetFmts[6].ptd = NULL; ! 2320: lpContainerApp->m_arrSingleObjGetFmts[6].dwAspect = DVASPECT_CONTENT; ! 2321: lpContainerApp->m_arrSingleObjGetFmts[6].tymed = TYMED_ISTREAM; ! 2322: lpContainerApp->m_arrSingleObjGetFmts[6].lindex = -1; ! 2323: ! 2324: lpContainerApp->m_arrSingleObjGetFmts[7].cfFormat = ! 2325: lpOleApp->m_cfLinkSrcDescriptor; ! 2326: lpContainerApp->m_arrSingleObjGetFmts[7].ptd = NULL; ! 2327: lpContainerApp->m_arrSingleObjGetFmts[7].dwAspect = DVASPECT_CONTENT; ! 2328: lpContainerApp->m_arrSingleObjGetFmts[7].tymed = TYMED_HGLOBAL; ! 2329: lpContainerApp->m_arrSingleObjGetFmts[7].lindex = -1; ! 2330: ! 2331: lpContainerApp->m_nSingleObjGetFmts = 8; ! 2332: ! 2333: /* NOTE: the Container-Only version of Outline does NOT offer ! 2334: ** IDataObject interface from its User documents and the ! 2335: ** IDataObject interface available from DataTransferDoc's do NOT ! 2336: ** support SetData. IDataObject interface is required by objects ! 2337: ** which can be embedded or linked. the Container-only app only ! 2338: ** allows linking to its contained objects, NOT the data of the ! 2339: ** container itself. ! 2340: */ ! 2341: ! 2342: /* m_arrPasteEntries array enumerates the formats that a ContainerDoc ! 2343: ** object can accept from the clipboard. this array is used to ! 2344: ** support the PasteSpecial dialog. ! 2345: ** The formats are listed in priority order. ! 2346: ** ContainerDoc objects accept data formats in the following order: ! 2347: ** 1. CF_CNTROUTL ! 2348: ** 2. CF_OUTLINE ! 2349: ** 3. CF_EMBEDDEDOBJECT ! 2350: ** 4. CF_TEXT ! 2351: ** 5. CF_METAFILEPICT ! 2352: ** 6. CF_DIB ! 2353: ** 7. CF_BITMAP ! 2354: ** 8. CF_LINKSOURCE ! 2355: ** ! 2356: ** NOTE: specifying CF_EMBEDDEDOBJECT in the PasteEntry array ! 2357: ** indicates that the caller is interested in pasting OLE ! 2358: ** objects (ie. the caller calls OleCreateFromData). the ! 2359: ** OleUIPasteSpecial dialog and OleStdGetPriorityClipboardFormat ! 2360: ** call OleQueryCreateFromData to see if an OLE object format is ! 2361: ** available. thus, in fact if CF_EMBEDSOURCE or CF_FILENAME are ! 2362: ** available from the data source then and OLE object can be ! 2363: ** created and this entry will be matched. the caller should ! 2364: ** only specify one object type format. ! 2365: ** CF_FILENAME format (as generated by copying a file to ! 2366: ** the clipboard from the FileManager) is considered an object ! 2367: ** format; OleCreatFromData creates an object if the file has an ! 2368: ** associated class (see GetClassFile API) or if no class it ! 2369: ** creates an OLE 1.0 Package object. this format can also be ! 2370: ** paste linked by calling OleCreateLinkFromData. ! 2371: */ ! 2372: // REVIEW: strings should be loaded from string resource ! 2373: ! 2374: lpOleApp->m_arrPasteEntries[0].fmtetc.cfFormat = ! 2375: lpContainerApp->m_cfCntrOutl; ! 2376: lpOleApp->m_arrPasteEntries[0].fmtetc.ptd = NULL; ! 2377: lpOleApp->m_arrPasteEntries[0].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2378: lpOleApp->m_arrPasteEntries[0].fmtetc.tymed = TYMED_ISTORAGE; ! 2379: lpOleApp->m_arrPasteEntries[0].fmtetc.lindex = -1; ! 2380: lpOleApp->m_arrPasteEntries[0].lpstrFormatName = "Container Outline Data"; ! 2381: lpOleApp->m_arrPasteEntries[0].lpstrResultText = ! 2382: "as Container Outline Data"; ! 2383: lpOleApp->m_arrPasteEntries[0].dwFlags = OLEUIPASTE_PASTEONLY; ! 2384: ! 2385: lpOleApp->m_arrPasteEntries[1].fmtetc.cfFormat =lpOutlineApp->m_cfOutline; ! 2386: lpOleApp->m_arrPasteEntries[1].fmtetc.ptd = NULL; ! 2387: lpOleApp->m_arrPasteEntries[1].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2388: lpOleApp->m_arrPasteEntries[1].fmtetc.tymed = TYMED_HGLOBAL; ! 2389: lpOleApp->m_arrPasteEntries[1].fmtetc.lindex = -1; ! 2390: lpOleApp->m_arrPasteEntries[1].lpstrFormatName = "Outline Data"; ! 2391: lpOleApp->m_arrPasteEntries[1].lpstrResultText = "as Outline Data"; ! 2392: lpOleApp->m_arrPasteEntries[1].dwFlags = OLEUIPASTE_PASTEONLY; ! 2393: ! 2394: lpOleApp->m_arrPasteEntries[2].fmtetc.cfFormat = ! 2395: lpOleApp->m_cfEmbeddedObject; ! 2396: lpOleApp->m_arrPasteEntries[2].fmtetc.ptd = NULL; ! 2397: lpOleApp->m_arrPasteEntries[2].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2398: lpOleApp->m_arrPasteEntries[2].fmtetc.tymed = TYMED_ISTORAGE; ! 2399: lpOleApp->m_arrPasteEntries[2].fmtetc.lindex = -1; ! 2400: lpOleApp->m_arrPasteEntries[2].lpstrFormatName = "%s"; ! 2401: lpOleApp->m_arrPasteEntries[2].lpstrResultText = "%s"; ! 2402: lpOleApp->m_arrPasteEntries[2].dwFlags = ! 2403: OLEUIPASTE_PASTE | OLEUIPASTE_ENABLEICON; ! 2404: ! 2405: lpOleApp->m_arrPasteEntries[3].fmtetc.cfFormat = CF_TEXT; ! 2406: lpOleApp->m_arrPasteEntries[3].fmtetc.ptd = NULL; ! 2407: lpOleApp->m_arrPasteEntries[3].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2408: lpOleApp->m_arrPasteEntries[3].fmtetc.tymed = TYMED_HGLOBAL; ! 2409: lpOleApp->m_arrPasteEntries[3].fmtetc.lindex = -1; ! 2410: lpOleApp->m_arrPasteEntries[3].lpstrFormatName = "Text"; ! 2411: lpOleApp->m_arrPasteEntries[3].lpstrResultText = "as text"; ! 2412: lpOleApp->m_arrPasteEntries[3].dwFlags = OLEUIPASTE_PASTEONLY; ! 2413: ! 2414: lpOleApp->m_arrPasteEntries[4].fmtetc.cfFormat = CF_METAFILEPICT; ! 2415: lpOleApp->m_arrPasteEntries[4].fmtetc.ptd = NULL; ! 2416: lpOleApp->m_arrPasteEntries[4].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2417: lpOleApp->m_arrPasteEntries[4].fmtetc.tymed = TYMED_MFPICT; ! 2418: lpOleApp->m_arrPasteEntries[4].fmtetc.lindex = -1; ! 2419: lpOleApp->m_arrPasteEntries[4].lpstrFormatName = "Picture (Metafile)"; ! 2420: lpOleApp->m_arrPasteEntries[4].lpstrResultText = "as a static picture"; ! 2421: lpOleApp->m_arrPasteEntries[4].dwFlags = OLEUIPASTE_PASTEONLY; ! 2422: ! 2423: lpOleApp->m_arrPasteEntries[5].fmtetc.cfFormat = CF_DIB; ! 2424: lpOleApp->m_arrPasteEntries[5].fmtetc.ptd = NULL; ! 2425: lpOleApp->m_arrPasteEntries[5].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2426: lpOleApp->m_arrPasteEntries[5].fmtetc.tymed = TYMED_HGLOBAL; ! 2427: lpOleApp->m_arrPasteEntries[5].fmtetc.lindex = -1; ! 2428: lpOleApp->m_arrPasteEntries[5].lpstrFormatName = "Picture (DIB)"; ! 2429: lpOleApp->m_arrPasteEntries[5].lpstrResultText = "as a static picture"; ! 2430: lpOleApp->m_arrPasteEntries[5].dwFlags = OLEUIPASTE_PASTEONLY; ! 2431: ! 2432: lpOleApp->m_arrPasteEntries[6].fmtetc.cfFormat = CF_BITMAP; ! 2433: lpOleApp->m_arrPasteEntries[6].fmtetc.ptd = NULL; ! 2434: lpOleApp->m_arrPasteEntries[6].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2435: lpOleApp->m_arrPasteEntries[6].fmtetc.tymed = TYMED_GDI; ! 2436: lpOleApp->m_arrPasteEntries[6].fmtetc.lindex = -1; ! 2437: lpOleApp->m_arrPasteEntries[6].lpstrFormatName = "Picture (Bitmap)"; ! 2438: lpOleApp->m_arrPasteEntries[6].lpstrResultText = "as a static picture"; ! 2439: lpOleApp->m_arrPasteEntries[6].dwFlags = OLEUIPASTE_PASTEONLY; ! 2440: ! 2441: lpOleApp->m_arrPasteEntries[7].fmtetc.cfFormat = lpOleApp->m_cfLinkSource; ! 2442: lpOleApp->m_arrPasteEntries[7].fmtetc.ptd = NULL; ! 2443: lpOleApp->m_arrPasteEntries[7].fmtetc.dwAspect = DVASPECT_CONTENT; ! 2444: lpOleApp->m_arrPasteEntries[7].fmtetc.tymed = TYMED_ISTREAM; ! 2445: lpOleApp->m_arrPasteEntries[7].fmtetc.lindex = -1; ! 2446: lpOleApp->m_arrPasteEntries[7].lpstrFormatName = "%s"; ! 2447: lpOleApp->m_arrPasteEntries[7].lpstrResultText = "%s"; ! 2448: lpOleApp->m_arrPasteEntries[7].dwFlags = ! 2449: OLEUIPASTE_LINKTYPE1 | OLEUIPASTE_ENABLEICON; ! 2450: ! 2451: lpOleApp->m_nPasteEntries = 8; ! 2452: ! 2453: /* m_arrLinkTypes array enumerates the link types that a ContainerDoc ! 2454: ** object can accept from the clipboard ! 2455: */ ! 2456: ! 2457: lpOleApp->m_arrLinkTypes[0] = lpOleApp->m_cfLinkSource; ! 2458: lpOleApp->m_nLinkTypes = 1; ! 2459: ! 2460: return TRUE; ! 2461: } ! 2462: ! 2463: ! 2464: /* ContainerApp_InitVtbls ! 2465: ** ---------------------- ! 2466: ** ! 2467: ** initialize the interface Vtbl's used to support the OLE 2.0 ! 2468: ** Container functionality. ! 2469: */ ! 2470: ! 2471: BOOL ContainerApp_InitVtbls(LPCONTAINERAPP lpApp) ! 2472: { ! 2473: BOOL fStatus; ! 2474: ! 2475: // ContainerDoc::IOleUILinkContainer method table ! 2476: OleStdInitVtbl( ! 2477: &g_CntrDoc_OleUILinkContainerVtbl, ! 2478: sizeof(IOleUILinkContainerVtbl) ! 2479: ); ! 2480: g_CntrDoc_OleUILinkContainerVtbl.QueryInterface = ! 2481: CntrDoc_LinkCont_QueryInterface; ! 2482: g_CntrDoc_OleUILinkContainerVtbl.AddRef = CntrDoc_LinkCont_AddRef; ! 2483: g_CntrDoc_OleUILinkContainerVtbl.Release = CntrDoc_LinkCont_Release; ! 2484: g_CntrDoc_OleUILinkContainerVtbl.GetNextLink = ! 2485: CntrDoc_LinkCont_GetNextLink; ! 2486: g_CntrDoc_OleUILinkContainerVtbl.SetLinkUpdateOptions = ! 2487: CntrDoc_LinkCont_SetLinkUpdateOptions; ! 2488: g_CntrDoc_OleUILinkContainerVtbl.GetLinkUpdateOptions = ! 2489: CntrDoc_LinkCont_GetLinkUpdateOptions; ! 2490: g_CntrDoc_OleUILinkContainerVtbl.SetLinkSource = ! 2491: CntrDoc_LinkCont_SetLinkSource; ! 2492: g_CntrDoc_OleUILinkContainerVtbl.GetLinkSource = ! 2493: CntrDoc_LinkCont_GetLinkSource; ! 2494: g_CntrDoc_OleUILinkContainerVtbl.OpenLinkSource = ! 2495: CntrDoc_LinkCont_OpenLinkSource; ! 2496: g_CntrDoc_OleUILinkContainerVtbl.UpdateLink = ! 2497: CntrDoc_LinkCont_UpdateLink; ! 2498: g_CntrDoc_OleUILinkContainerVtbl.CancelLink = ! 2499: CntrDoc_LinkCont_CancelLink; ! 2500: fStatus = OleStdCheckVtbl( ! 2501: &g_CntrDoc_OleUILinkContainerVtbl, ! 2502: sizeof(IOleUILinkContainerVtbl), ! 2503: "IOleUILinkContainer" ! 2504: ); ! 2505: if (! fStatus) return FALSE; ! 2506: ! 2507: #if defined( INPLACE_CNTR ) ! 2508: ! 2509: // ContainerApp::IOleInPlaceFrame interface method table ! 2510: OleStdInitVtbl( ! 2511: &g_CntrApp_OleInPlaceFrameVtbl, ! 2512: sizeof(g_CntrApp_OleInPlaceFrameVtbl) ! 2513: ); ! 2514: ! 2515: g_CntrApp_OleInPlaceFrameVtbl.QueryInterface ! 2516: = CntrApp_IPFrame_QueryInterface; ! 2517: g_CntrApp_OleInPlaceFrameVtbl.AddRef ! 2518: = CntrApp_IPFrame_AddRef; ! 2519: g_CntrApp_OleInPlaceFrameVtbl.Release ! 2520: = CntrApp_IPFrame_Release; ! 2521: g_CntrApp_OleInPlaceFrameVtbl.GetWindow ! 2522: = CntrApp_IPFrame_GetWindow; ! 2523: g_CntrApp_OleInPlaceFrameVtbl.ContextSensitiveHelp ! 2524: = CntrApp_IPFrame_ContextSensitiveHelp; ! 2525: ! 2526: g_CntrApp_OleInPlaceFrameVtbl.GetBorder ! 2527: = CntrApp_IPFrame_GetBorder; ! 2528: g_CntrApp_OleInPlaceFrameVtbl.RequestBorderSpace ! 2529: = CntrApp_IPFrame_RequestBorderSpace; ! 2530: g_CntrApp_OleInPlaceFrameVtbl.SetBorderSpace ! 2531: = CntrApp_IPFrame_SetBorderSpace; ! 2532: g_CntrApp_OleInPlaceFrameVtbl.SetActiveObject ! 2533: = CntrApp_IPFrame_SetActiveObject; ! 2534: g_CntrApp_OleInPlaceFrameVtbl.InsertMenus ! 2535: = CntrApp_IPFrame_InsertMenus; ! 2536: g_CntrApp_OleInPlaceFrameVtbl.SetMenu ! 2537: = CntrApp_IPFrame_SetMenu; ! 2538: g_CntrApp_OleInPlaceFrameVtbl.RemoveMenus ! 2539: = CntrApp_IPFrame_RemoveMenus; ! 2540: g_CntrApp_OleInPlaceFrameVtbl.SetStatusText ! 2541: = CntrApp_IPFrame_SetStatusText; ! 2542: g_CntrApp_OleInPlaceFrameVtbl.EnableModeless ! 2543: = CntrApp_IPFrame_EnableModeless; ! 2544: g_CntrApp_OleInPlaceFrameVtbl.TranslateAccelerator ! 2545: = CntrApp_IPFrame_TranslateAccelerator; ! 2546: ! 2547: fStatus = OleStdCheckVtbl( ! 2548: &g_CntrApp_OleInPlaceFrameVtbl, ! 2549: sizeof(g_CntrApp_OleInPlaceFrameVtbl), ! 2550: "IOleInPlaceFrame" ! 2551: ); ! 2552: if (! fStatus) return FALSE; ! 2553: ! 2554: #endif // INPLACE_CNTR ! 2555: ! 2556: ! 2557: // ContainerLine::IUnknown interface method table ! 2558: OleStdInitVtbl( ! 2559: &g_CntrLine_UnknownVtbl, ! 2560: sizeof(g_CntrLine_UnknownVtbl) ! 2561: ); ! 2562: g_CntrLine_UnknownVtbl.QueryInterface = CntrLine_Unk_QueryInterface; ! 2563: g_CntrLine_UnknownVtbl.AddRef = CntrLine_Unk_AddRef; ! 2564: g_CntrLine_UnknownVtbl.Release = CntrLine_Unk_Release; ! 2565: fStatus = OleStdCheckVtbl( ! 2566: &g_CntrLine_UnknownVtbl, ! 2567: sizeof(g_CntrLine_UnknownVtbl), ! 2568: "IUnknown" ! 2569: ); ! 2570: if (! fStatus) return FALSE; ! 2571: ! 2572: // ContainerLine::IOleClientSite interface method table ! 2573: OleStdInitVtbl( ! 2574: &g_CntrLine_OleClientSiteVtbl, ! 2575: sizeof(g_CntrLine_OleClientSiteVtbl) ! 2576: ); ! 2577: g_CntrLine_OleClientSiteVtbl.QueryInterface = ! 2578: CntrLine_CliSite_QueryInterface; ! 2579: g_CntrLine_OleClientSiteVtbl.AddRef = CntrLine_CliSite_AddRef; ! 2580: g_CntrLine_OleClientSiteVtbl.Release = CntrLine_CliSite_Release; ! 2581: g_CntrLine_OleClientSiteVtbl.SaveObject = CntrLine_CliSite_SaveObject; ! 2582: g_CntrLine_OleClientSiteVtbl.GetMoniker = CntrLine_CliSite_GetMoniker; ! 2583: g_CntrLine_OleClientSiteVtbl.GetContainer = CntrLine_CliSite_GetContainer; ! 2584: g_CntrLine_OleClientSiteVtbl.ShowObject = CntrLine_CliSite_ShowObject; ! 2585: g_CntrLine_OleClientSiteVtbl.OnShowWindow = CntrLine_CliSite_OnShowWindow; ! 2586: g_CntrLine_OleClientSiteVtbl.RequestNewObjectLayout = ! 2587: CntrLine_CliSite_RequestNewObjectLayout; ! 2588: fStatus = OleStdCheckVtbl( ! 2589: &g_CntrLine_OleClientSiteVtbl, ! 2590: sizeof(g_CntrLine_OleClientSiteVtbl), ! 2591: "IOleClientSite" ! 2592: ); ! 2593: if (! fStatus) return FALSE; ! 2594: ! 2595: // ContainerLine::IAdviseSink interface method table ! 2596: OleStdInitVtbl( ! 2597: &g_CntrLine_AdviseSinkVtbl, ! 2598: sizeof(g_CntrLine_AdviseSinkVtbl) ! 2599: ); ! 2600: g_CntrLine_AdviseSinkVtbl.QueryInterface= CntrLine_AdvSink_QueryInterface; ! 2601: g_CntrLine_AdviseSinkVtbl.AddRef = CntrLine_AdvSink_AddRef; ! 2602: g_CntrLine_AdviseSinkVtbl.Release = CntrLine_AdvSink_Release; ! 2603: g_CntrLine_AdviseSinkVtbl.OnDataChange = CntrLine_AdvSink_OnDataChange; ! 2604: g_CntrLine_AdviseSinkVtbl.OnViewChange = CntrLine_AdvSink_OnViewChange; ! 2605: g_CntrLine_AdviseSinkVtbl.OnRename = CntrLine_AdvSink_OnRename; ! 2606: g_CntrLine_AdviseSinkVtbl.OnSave = CntrLine_AdvSink_OnSave; ! 2607: g_CntrLine_AdviseSinkVtbl.OnClose = CntrLine_AdvSink_OnClose; ! 2608: fStatus = OleStdCheckVtbl( ! 2609: &g_CntrLine_AdviseSinkVtbl, ! 2610: sizeof(g_CntrLine_AdviseSinkVtbl), ! 2611: "IAdviseSink" ! 2612: ); ! 2613: if (! fStatus) return FALSE; ! 2614: ! 2615: ! 2616: #if defined( INPLACE_CNTR ) ! 2617: ! 2618: // ContainerLine::IOleInPlaceSite interface method table ! 2619: OleStdInitVtbl( ! 2620: &g_CntrLine_OleInPlaceSiteVtbl, ! 2621: sizeof(g_CntrLine_OleInPlaceSiteVtbl) ! 2622: ); ! 2623: ! 2624: g_CntrLine_OleInPlaceSiteVtbl.QueryInterface ! 2625: = CntrLine_IPSite_QueryInterface; ! 2626: g_CntrLine_OleInPlaceSiteVtbl.AddRef ! 2627: = CntrLine_IPSite_AddRef; ! 2628: g_CntrLine_OleInPlaceSiteVtbl.Release ! 2629: = CntrLine_IPSite_Release; ! 2630: g_CntrLine_OleInPlaceSiteVtbl.GetWindow ! 2631: = CntrLine_IPSite_GetWindow; ! 2632: g_CntrLine_OleInPlaceSiteVtbl.ContextSensitiveHelp ! 2633: = CntrLine_IPSite_ContextSensitiveHelp; ! 2634: g_CntrLine_OleInPlaceSiteVtbl.CanInPlaceActivate ! 2635: = CntrLine_IPSite_CanInPlaceActivate; ! 2636: g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceActivate ! 2637: = CntrLine_IPSite_OnInPlaceActivate; ! 2638: g_CntrLine_OleInPlaceSiteVtbl.OnUIActivate ! 2639: = CntrLine_IPSite_OnUIActivate; ! 2640: g_CntrLine_OleInPlaceSiteVtbl.GetWindowContext ! 2641: = CntrLine_IPSite_GetWindowContext; ! 2642: g_CntrLine_OleInPlaceSiteVtbl.Scroll ! 2643: = CntrLine_IPSite_Scroll; ! 2644: g_CntrLine_OleInPlaceSiteVtbl.OnUIDeactivate ! 2645: = CntrLine_IPSite_OnUIDeactivate; ! 2646: ! 2647: g_CntrLine_OleInPlaceSiteVtbl.OnInPlaceDeactivate ! 2648: = CntrLine_IPSite_OnInPlaceDeactivate; ! 2649: g_CntrLine_OleInPlaceSiteVtbl.DiscardUndoState ! 2650: = CntrLine_IPSite_DiscardUndoState; ! 2651: g_CntrLine_OleInPlaceSiteVtbl.DeactivateAndUndo ! 2652: = CntrLine_IPSite_DeactivateAndUndo; ! 2653: g_CntrLine_OleInPlaceSiteVtbl.OnPosRectChange ! 2654: = CntrLine_IPSite_OnPosRectChange; ! 2655: ! 2656: fStatus = OleStdCheckVtbl( ! 2657: &g_CntrLine_OleInPlaceSiteVtbl, ! 2658: sizeof(g_CntrLine_OleInPlaceSiteVtbl), ! 2659: "IOleInPlaceSite" ! 2660: ); ! 2661: if (! fStatus) return FALSE; ! 2662: ! 2663: #endif // INPLACE_CNTR ! 2664: ! 2665: return TRUE; ! 2666: } ! 2667: ! 2668: #endif // OLE_CNTR
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.