Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

695 lines
22 KiB

  1. /*---------------------------------------------------------------------------
  2. | SERVER.C
  3. | This file has the IClassFactory Interface implementation. It also has
  4. | the Vtbl initializations.
  5. |
  6. | Created By: Vij Rajarajan (VijR)
  7. +---------------------------------------------------------------------------*/
  8. #define SERVERONLY
  9. #include <windows.h>
  10. #include "mpole.h"
  11. #include "mplayer.h"
  12. extern IID iidUnknownObject;
  13. extern IID iidClassFactory;
  14. HMODULE hMciOle;
  15. static SZCODE aszMCIOLE[] = TEXT("MCIOLE32.DLL"); // WOW-proofing
  16. static ANSI_SZCODE aszOleQueryObjPos[] = ANSI_TEXT("OleQueryObjPos");
  17. /**************************************************************************
  18. * The VTBLs are initialized here.
  19. **************************************************************************/
  20. // Method tables.
  21. IClassFactoryVtbl srvrVtbl=
  22. {
  23. // IOleClassFactory method table
  24. /* srvrVtbl.QueryInterface = */ SrvrQueryInterface,
  25. /* srvrVtbl.AddRef = */ SrvrAddRef,
  26. /* srvrVtbl.Release = */ SrvrRelease,
  27. /* srvrVtbl.CreateInstance = */ SrvrCreateInstance,
  28. /* srvrVtbl.LockServer = */ SrvrLockServer
  29. };
  30. IOleObjectVtbl oleVtbl =
  31. {
  32. // IOleObject method table
  33. /* oleVtbl.QueryInterface = */ OleObjQueryInterface,
  34. /* oleVtbl.AddRef = */ OleObjAddRef,
  35. /* oleVtbl.Release = */ OleObjRelease,
  36. /* oleVtbl.SetClientSite = */ OleObjSetClientSite,
  37. /* oleVtbl.GetClientSite = */ OleObjGetClientSite,
  38. /* oleVtbl.SetHostNames = */ OleObjSetHostNames,
  39. /* oleVtbl.Close = */ OleObjClose,
  40. /* oleVtbl.SetMoniker = */ OleObjSetMoniker,
  41. /* oleVtbl.GetMoniker = */ OleObjGetMoniker,
  42. /* oleVtbl.InitFromData = */ OleObjInitFromData,
  43. /* oleVtbl.GetClipboardData = */ OleObjGetClipboardData,
  44. /* oleVtbl.DoVerb = */ OleObjDoVerb,
  45. /* oleVtbl.EnumVerbs = */ OleObjEnumVerbs,
  46. /* oleVtbl.Update = */ OleObjUpdate,
  47. /* oleVtbl.IsUpToDate = */ OleObjIsUpToDate,
  48. /* oleVtbl.GetUserClassID = */ OleObjGetUserClassID,
  49. /* oleVtbl.GetUserType = */ OleObjGetUserType,
  50. /* oleVtbl.SetExtent = */ OleObjSetExtent,
  51. /* oleVtbl.GetExtent = */ OleObjGetExtent,
  52. /* oleVtbl.Advise = */ OleObjAdvise,
  53. /* oleVtbl.Unadvise = */ OleObjUnadvise,
  54. /* oleVtbl.EnumAdvise = */ OleObjEnumAdvise,
  55. /* oleVtbl.GetMiscStatus = */ OleObjGetMiscStatus,
  56. /* oleVtbl.SetColorScheme = */ OleObjSetColorScheme,
  57. };
  58. IDataObjectVtbl dataVtbl =
  59. {
  60. // IDataObject method table
  61. /* dataVtbl.QueryInterface = */ DataObjQueryInterface,
  62. /* dataVtbl.AddRef = */ DataObjAddRef,
  63. /* dataVtbl.Release = */ DataObjRelease,
  64. /* dataVtbl.GetData = */ DataObjGetData,
  65. /* dataVtbl.GetDataHere = */ DataObjGetDataHere,
  66. /* dataVtbl.QueryGetData = */ DataObjQueryGetData,
  67. /* dataVtbl.GetCanonicalFormatEtc = */ DataObjGetCanonicalFormatEtc,
  68. /* dataVtbl.SetData = */ DataObjSetData,
  69. /* dataVtbl.EnumFormatEtc = */ DataObjEnumFormatEtc,
  70. /* dataVtbl.Advise = */ DataObjAdvise,
  71. /* dataVtbl.Unadvise = */ DataObjUnadvise,
  72. /* dataVtbl.EnumAdvise = */ DataObjEnumAdvise
  73. };
  74. IEnumFORMATETCVtbl ClipDragEnumVtbl =
  75. {
  76. // Clipboard dataobject's formatetc enumerator method table
  77. /* ClipDragEnumVtbl.QueryInterface = */ ClipDragEnumQueryInterface,
  78. /* ClipDragEnumVtbl.AddRef = */ ClipDragEnumAddRef,
  79. /* ClipDragEnumVtbl.Release = */ ClipDragEnumRelease,
  80. /* ClipDragEnumVtbl.Next = */ ClipDragEnumNext,
  81. /* ClipDragEnumVtbl.Skip = */ ClipDragEnumSkip,
  82. /* ClipDragEnumVtbl.Reset = */ ClipDragEnumReset,
  83. /* ClipDragEnumVtbl.Clone = */ ClipDragEnumClone
  84. };
  85. IPersistStorageVtbl persistStorageVtbl =
  86. {
  87. /* persistStorageVtbl.QueryInterface = */ PSQueryInterface,
  88. /* persistStorageVtbl.AddRef = */ PSAddRef,
  89. /* persistStorageVtbl.Release = */ PSRelease,
  90. /* persistStorageVtbl.GetClassID = */ PSGetClassID,
  91. /* persistStorageVtbl.IsDirty = */ PSIsDirty,
  92. /* persistStorageVtbl.InitNew = */ PSInitNew,
  93. /* persistStorageVtbl.Load = */ PSLoad,
  94. /* persistStorageVtbl.Save = */ PSSave,
  95. /* persistStorageVtbl.SaveCompleted = */ PSSaveCompleted,
  96. /* persistStorageVtbl.HandsOffStorage = */ PSHandsOffStorage
  97. };
  98. IOleInPlaceObjectVtbl ipVtbl =
  99. {
  100. // IOleInPlaceObject method table
  101. /* ipVtbl.QueryInterface = */ IPObjQueryInterface,
  102. /* ipVtbl.AddRef = */ IPObjAddRef,
  103. /* ipVtbl.Release = */ IPObjRelease,
  104. /* ipVtbl.GetWindow = */ IPObjGetWindow,
  105. /* ipVtbl.ContextSensitiveHelp = */ IPObjContextSensitiveHelp,
  106. /* ipVtbl.InPlaceDeactivate = */ IPObjInPlaceDeactivate,
  107. /* ipVtbl.UIDeactivate = */ IPObjUIDeactivate,
  108. /* ipVtbl.SetObjectRects = */ IPObjSetObjectRects,
  109. /* ipVtbl.ReactivateAndUndo = */ IPObjReactivateAndUndo
  110. };
  111. IOleInPlaceActiveObjectVtbl ipActiveVtbl =
  112. {
  113. // IOleInPlaceActiveObject method table
  114. /* ipActiveVtbl.QueryInterface = */ IPActiveQueryInterface,
  115. /* ipActiveVtbl.AddRef = */ IPActiveAddRef,
  116. /* ipActiveVtbl.Release = */ IPActiveRelease,
  117. /* ipActiveVtbl.GetWindow = */ IPActiveGetWindow,
  118. /* ipActiveVtbl.ContextSensitiveHelp = */ IPActiveContextSensitiveHelp,
  119. /* ipActiveVtbl.TranslateAccelerator = */ IPActiveTranslateAccelerator,
  120. /* ipActiveVtbl.OnFrameWindowActivate = */ IPActiveOnFrameWindowActivate,
  121. /* ipActiveVtbl.OnDocWindowActivate = */ IPActiveOnDocWindowActivate,
  122. /* ipActiveVtbl.ResizeBorder = */ IPActiveResizeBorder,
  123. /* ipActiveVtbl.EnableModeless = */ IPActiveEnableModeless
  124. };
  125. IDataObjectVtbl clipdragVtbl =
  126. {
  127. // ClipDrag IDataObject method table
  128. /* clipdragVtbl.QueryInterface = */ ClipDragQueryInterface,
  129. /* clipdragVtbl.AddRef = */ ClipDragAddRef,
  130. /* clipdragVtbl.Release = */ ClipDragRelease,
  131. /* clipdragVtbl.GetData = */ ClipDragGetData,
  132. /* clipdragVtbl.GetDataHere = */ ClipDragGetDataHere,
  133. /* clipdragVtbl.QueryGetData = */ ClipDragQueryGetData,
  134. /* clipdragVtbl.GetCanonicalFormatEtc = */ ClipDragGetCanonicalFormatEtc,
  135. /* clipdragVtbl.SetData = */ ClipDragSetData,
  136. /* clipdragVtbl.EnumFormatEtc = */ ClipDragEnumFormatEtc,
  137. /* clipdragVtbl.Advise = */ ClipDragAdvise,
  138. /* clipdragVtbl.Unadvise = */ ClipDragUnadvise,
  139. /* clipdragVtbl.EnumAdvise = */ ClipDragEnumAdvise
  140. };
  141. IDropSourceVtbl dropsourceVtbl =
  142. {
  143. // DragDrop IDropSource method table
  144. /* dropsourceVtbl.QueryInterface = */ DropSourceQueryInterface,
  145. /* dropsourceVtbl.AddRef = */ DropSourceAddRef,
  146. /* dropsourceVtbl.Release = */ DropSourceRelease,
  147. /* dropsourceVtbl.QueryContinueDrag = */ DropSourceQueryContinueDrag,
  148. /* dropsourceVtbl.GiveFeedback = */ DropSourceGiveFeedback
  149. };
  150. #ifdef LATER
  151. IDropTargetVtbl droptargetVtbl =
  152. {
  153. // DragDrop IDropTarget method table
  154. /* droptargetVtbl.QueryInterface = */ DropTargetQueryInterface,
  155. /* droptargetVtbl.AddRef = */ DropTargetAddRef,
  156. /* droptargetVtbl.Release = */ DropTargetRelease,
  157. /* droptargetVtbl.DragEnter = */ DropTargetDragEnter,
  158. /* droptargetVtbl.DragOver = */ DropTargetDragOver,
  159. /* droptargetVtbl.DragLeave = */ DropTargetDragLeave,
  160. /* droptargetVtbl.Drop = */ DropTargetDrop
  161. };
  162. #endif
  163. IPersistFileVtbl persistFileVtbl =
  164. {
  165. /* persistFileVtbl.QueryInterface = */ PFQueryInterface,
  166. /* persistFileVtbl.AddRef = */ PFAddRef,
  167. /* persistFileVtbl.Release = */ PFRelease,
  168. /* persistFileVtbl.GetClassID = */ PFGetClassID,
  169. /* persistFileVtbl.IsDirty = */ PFIsDirty,
  170. /* persistFileVtbl.Load = */ PFLoad,
  171. /* persistFileVtbl.Save = */ PFSave,
  172. /* persistFileVtbl.SaveCompleted = */ PFSaveCompleted,
  173. /* persistFileVtbl.GetCurFile = */ PFGetCurFile
  174. };
  175. /**************************************************************************
  176. *************** IClassFactory INTERFACE IMPLEMENTATION.
  177. ***************************************************************************/
  178. STDMETHODIMP SrvrQueryInterface (
  179. LPCLASSFACTORY lpolesrvr,
  180. REFIID riid,
  181. LPVOID FAR *lplpunkObj
  182. )
  183. {
  184. LPSRVR lpsrvr;
  185. DPF("*srvrqi");
  186. lpsrvr = (LPSRVR)lpolesrvr;
  187. if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
  188. *lplpunkObj = (LPVOID)lpsrvr;
  189. lpsrvr->cRef++;
  190. return NOERROR;
  191. } else {
  192. *lplpunkObj = (LPVOID) NULL;
  193. RETURN_RESULT( E_NOINTERFACE);
  194. }
  195. }
  196. STDMETHODIMP_(ULONG) SrvrAddRef(
  197. LPCLASSFACTORY lpolesrvr
  198. )
  199. {
  200. LPSRVR lpsrvr;
  201. DPF("*srvrAR");
  202. lpsrvr = (LPSRVR)lpolesrvr;
  203. return ++lpsrvr->cRef;
  204. }
  205. STDMETHODIMP_(ULONG) SrvrRelease (
  206. LPCLASSFACTORY lpolesrvr
  207. )
  208. {
  209. LPSRVR lpsrvr;
  210. DPF("*srvrREL");
  211. lpsrvr = (LPSRVR)lpolesrvr;
  212. DPFI("* SRVR CREF: %d*",lpsrvr->cRef);
  213. if (--lpsrvr->cRef == 0) {
  214. DestroyServer(lpsrvr);
  215. return 0;
  216. }
  217. return lpsrvr->cRef;
  218. }
  219. STDMETHODIMP SrvrCreateInstance (
  220. LPCLASSFACTORY lpolesrvr,
  221. LPUNKNOWN lpUnkOuter,
  222. REFIID riid,
  223. LPVOID FAR *lplpunkObj
  224. )
  225. {
  226. static BOOL fInstanceCreated = FALSE;
  227. DPF("*srvrcreateinst");
  228. /*********************************************************************
  229. ** OLE2NOTE: this is an SDI app; it can only create and support one
  230. ** instance. After the instance is created, the OLE libraries
  231. ** should not call CreateInstance again. it is a good practise
  232. ** to specifically guard against this.
  233. *********************************************************************/
  234. if (fInstanceCreated)
  235. RETURN_RESULT( E_FAIL);
  236. else {
  237. fInstanceCreated = TRUE;
  238. }
  239. /*********************************************************************
  240. ** OLE2NOTE: create and initialize a new document instance. the **
  241. ** document's refcnt should start out as 1. **
  242. *********************************************************************/
  243. if (!InitNewDocObj(&docMain))
  244. RETURN_RESULT( E_OUTOFMEMORY);
  245. *lplpunkObj = (LPUNKNOWN) &docMain;
  246. return NOERROR;
  247. }
  248. //Increment or decrement the lock count as required. The server should not
  249. //quit when there is a lock on the server.
  250. STDMETHODIMP SrvrLockServer(
  251. LPCLASSFACTORY lpolesrvr,
  252. BOOL fLock
  253. )
  254. {
  255. LPSRVR lpsrvr;
  256. DPF("*srvrLOCKSERVER");
  257. lpsrvr = (LPSRVR)lpolesrvr;
  258. if (fLock)
  259. {
  260. lpsrvr->cLock++;
  261. DPFI("CLOCK = %d\n", lpsrvr->cLock);
  262. }
  263. else if ((--lpsrvr->cLock == 0) && (docMain.cRef == 0))
  264. {
  265. DPFI("CLOCK UNLOCK ZERO = %d\n", lpsrvr->cLock);
  266. PostCloseMessage();
  267. }
  268. return NOERROR;
  269. }
  270. /**************************************************************************
  271. Stub routine if we can't find MCIOLE.DLL
  272. ***************************************************************************/
  273. OLE1_OLESTATUS FAR PASCAL NullOleQueryObjPos(LPOLEOBJECT lpobj, HWND FAR* lphwnd, LPRECT lprc, LPRECT lprcWBounds)
  274. {
  275. DPF("NullQueryObjPos called, MCIOLE.DLL was not loaded\n");
  276. return OLE1_OLEERROR_GENERIC;
  277. }
  278. #ifdef OLE1_HACK
  279. BOOL FAR PASCAL InitOle1Server(HWND hwnd, HANDLE hInst);
  280. #endif
  281. /**************************************************************************
  282. * InitServer:
  283. * This function initializes the server object with the IClassFactory
  284. * Vtbl and also load the mciole.dll library to support OLE 1.0 apps.
  285. **************************************************************************/
  286. BOOL InitServer (HWND hwnd, HANDLE hInst)
  287. {
  288. int err;
  289. OQOPROC fp;
  290. srvrMain.olesrvr.lpVtbl = &srvrVtbl;
  291. srvrMain.dwRegCF=0;
  292. srvrMain.cRef = 0;
  293. srvrMain.cLock = 0;
  294. err = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  295. hMciOle = LoadLibrary(aszMCIOLE);
  296. SetErrorMode(err);
  297. fp = (OQOPROC)GetProcAddress(hMciOle, aszOleQueryObjPos);
  298. if (hMciOle && fp)
  299. OleQueryObjPos = fp; // Avoid cast on LVALUE!!
  300. else
  301. OleQueryObjPos = (OQOPROC)NullOleQueryObjPos;
  302. #ifdef OLE1_HACK
  303. InitOle1Server(hwnd, hInst);
  304. #endif
  305. return TRUE;
  306. }
  307. void DestroyServer (LPSRVR lpsrvr)
  308. {
  309. lpsrvr->fEmbedding = FALSE;
  310. }
  311. /**************************************************************************
  312. * InitNewDocObj:
  313. * Initializes the the lpdoc structure.
  314. **************************************************************************/
  315. BOOL InitNewDocObj(LPDOC lpdoc)
  316. { DPFI("*INITNEWDOCOBJ*");
  317. // Fill the fields in the object structure.
  318. if(gfOle2IPEditing)
  319. return TRUE;
  320. lpdoc->cRef = 1;
  321. lpdoc->doctype = doctypeNew;
  322. lpdoc->m_Ole.lpVtbl = &oleVtbl;
  323. lpdoc->m_Ole.lpdoc = lpdoc;
  324. lpdoc->m_Data.lpVtbl = &dataVtbl;
  325. lpdoc->m_Data.lpdoc = lpdoc;
  326. lpdoc->m_PersistStorage.lpVtbl = &persistStorageVtbl;
  327. lpdoc->m_PersistStorage.lpdoc = lpdoc;
  328. lpdoc->lpIpData = NULL;
  329. lpdoc->m_InPlace.lpVtbl = &ipVtbl;
  330. lpdoc->m_InPlace.lpdoc = lpdoc;
  331. lpdoc->m_IPActive.lpVtbl = &ipActiveVtbl;
  332. lpdoc->m_IPActive.lpdoc = lpdoc;
  333. lpdoc->m_PersistFile.lpVtbl = &persistFileVtbl;
  334. lpdoc->m_PersistFile.lpdoc = lpdoc;
  335. lpdoc->aDocName = GlobalAddAtom (TEXT("(Untitled)"));
  336. lpdoc->lpoleclient = NULL;
  337. lpdoc->lpdaholder = NULL;
  338. lpdoc->hwnd = ghwndApp;
  339. lpdoc->hwndParent = NULL;
  340. #ifdef OLE1_HACK
  341. SetDocVersion( DOC_VERSION_OLE2 );
  342. #endif /* OLE1_HACK */
  343. return TRUE;
  344. }
  345. /**************************************************************************
  346. * DestroyDoc:
  347. * This function Releases the references we hold. This function is called
  348. * at the termination of our operation as a server.
  349. **************************************************************************/
  350. void DestroyDoc (LPDOC lpdoc)
  351. {
  352. if (lpdoc->lpoleclient) {
  353. /******************************************************************
  354. ** OLE2NOTE: we no longer need the ClientSite ptr, so release it **
  355. ******************************************************************/
  356. IOleClientSite_Release(lpdoc->lpoleclient);
  357. lpdoc->lpoleclient = NULL;
  358. }
  359. if (lpdoc->lpoaholder)
  360. {
  361. IOleAdviseHolder_Release(lpdoc->lpoaholder);
  362. lpdoc->lpoaholder = NULL;
  363. }
  364. if (lpdoc->lpdaholder)
  365. {
  366. IDataAdviseHolder_Release(lpdoc->lpdaholder);
  367. lpdoc->lpdaholder = NULL;
  368. }
  369. if (lpdoc->aDocName)
  370. {
  371. GlobalDeleteAtom (lpdoc->aDocName);
  372. lpdoc->aDocName = (ATOM)0;
  373. }
  374. #ifdef OLE1_HACK
  375. SetDocVersion( DOC_VERSION_NONE );
  376. #endif /* OLE1_HACK */
  377. }
  378. /* SendDocMsg
  379. * ----------
  380. *
  381. * This function sends a message to a specific doc object.
  382. *
  383. * LPOBJ lpobj - The object
  384. * WORD wMessage - The message to send
  385. *
  386. *
  387. */
  388. SCODE SendDocMsg (LPDOC lpdoc, WORD wMessage)
  389. {
  390. HRESULT status = S_OK;
  391. // if no clients connected, no message.
  392. if (lpdoc->cRef == 0)
  393. {
  394. DPFI("*OLE_NOMSG");
  395. return S_OK;
  396. }
  397. switch (wMessage) {
  398. case OLE_CLOSED:
  399. // tell the clients that the UI is shutting down for this obj
  400. DPFI("*OLE_CLOSED");
  401. #if 0
  402. //NOTE: We have to SendOnCLose for all clients even OLE1. But
  403. //OLE2 has bug (or by design flaw) that causes the OLE1 client
  404. //doc. to be marked as changed because OLE2 always resaves
  405. //the object even if the object has not changed. So may be we
  406. //should not send the SendOnClose if we just Played in the OLE1 client.
  407. if (gfPlayingInPlace || gfOle1Client)
  408. break;
  409. #endif
  410. DPFI("*SENDING ONCLOSE");
  411. if (lpdoc->lpoaholder)
  412. status = IOleAdviseHolder_SendOnClose(lpdoc->lpoaholder);
  413. break;
  414. case OLE_SAVED:
  415. // inform clients that the object has been saved
  416. DPFI("*OLE_SAVED");
  417. if (lpdoc->lpoaholder)
  418. status = IOleAdviseHolder_SendOnSave(lpdoc->lpoaholder);
  419. break;
  420. case OLE_SAVEOBJ:
  421. // ask the embedding client to save the object now
  422. //If we are just playing then don't send this message.
  423. #if 0
  424. // Yes, do, so that broken links can be fixed.
  425. if(gfOle2IPPlaying || gfPlayingInPlace || glCurrentVerb == OLEIVERB_PRIMARY)
  426. break;
  427. #endif
  428. DPFI("*OLE_SAVEOBJ");
  429. if (lpdoc->lpoleclient)
  430. status = IOleClientSite_SaveObject(lpdoc->lpoleclient);
  431. break;
  432. case OLE_SHOWOBJ:
  433. if(lpdoc->lpoleclient)
  434. status = IOleClientSite_ShowObject(lpdoc->lpoleclient);
  435. break;
  436. case OLE_CHANGED:
  437. // send data changed notification if any have registered
  438. //If we are just playing then don't send this message.
  439. #if 0
  440. // Yes, do, so that broken links can be fixed.
  441. if(gfOle2IPPlaying || gfPlayingInPlace)
  442. break;
  443. #endif
  444. DPFI("*OLE_CHANGED");
  445. if (lpdoc->lpdaholder)
  446. status = IDataAdviseHolder_SendOnDataChange
  447. (lpdoc->lpdaholder, (LPDATAOBJECT)&lpdoc->m_Data, 0, 0);
  448. break;
  449. case OLE_SIZECHG:
  450. // Inform clients that the size of the object has changed.
  451. // This is relevant only if we are inplace Editing.
  452. DPFI("*OLE_SIZEOBJ");
  453. if (gfOle2IPEditing)
  454. {
  455. RECT rc = gInPlacePosRect;
  456. if (ghwndMCI && gfInPlaceResize)
  457. {
  458. DPFI("***In OLE_SIZECHG gfACTIVE***");
  459. gfInPlaceResize = FALSE;
  460. }
  461. else if(ghwndMCI)
  462. {
  463. /* gInPlacePosRect contains the size of the in-place window
  464. * including playbar, if there is one.
  465. * Don't include the playbar on the OnPosRectChange:
  466. */
  467. DPFI("***getextent gfNotActive***");
  468. if (gwOptions & OPT_BAR)
  469. rc.bottom -= TITLE_HEIGHT;
  470. }
  471. MapWindowPoints(NULL,ghwndCntr,(POINT FAR *)&rc,(UINT)2);
  472. DPF("IOleInPlaceSite::OnPosRectChange %d, %d, %d, %d\n", rc);
  473. if (!gfInPPViewer)
  474. IOleInPlaceSite_OnPosRectChange(lpdoc->lpIpData->lpSite, (LPRECT)&rc);
  475. }
  476. break;
  477. }
  478. return GetScode(status);
  479. }
  480. BOOL ItsSafeToClose(void);
  481. void FAR PASCAL InitDoc(BOOL fUntitled)
  482. {
  483. if (gfEmbeddedObject && IsObjectDirty())
  484. {
  485. CleanObject();
  486. }
  487. if (ItsSafeToClose())
  488. CloseMCI(TRUE);
  489. if (fUntitled)
  490. {
  491. LOADSTRING(IDS_UNTITLED, gachFileDevice);
  492. }
  493. }
  494. BOOL CreateDocObjFromFile (
  495. LPCTSTR lpszDoc,
  496. LPDOC lpdoc
  497. )
  498. {
  499. lpdoc->doctype = doctypeFromFile;
  500. // set file name atom
  501. if (lpdoc->aDocName)
  502. GlobalDeleteAtom (lpdoc->aDocName);
  503. lpdoc->aDocName = GlobalAddAtom(lpszDoc);
  504. //SetTitle(lpdoc, lpszDoc);
  505. // register as running
  506. return TRUE;
  507. }
  508. //Open a new document (file or media). Subclass the playback window if
  509. // the device has one. This will be used for drag drop operations.
  510. BOOL OpenDoc (UINT wid, LPTSTR lpsz)
  511. {
  512. if (!DoOpen(wid,lpsz))
  513. return FALSE;
  514. /**********************************************************************
  515. ** OLE2NOTE: shut down current doc before openning a new one. this **
  516. ** will send OLE_CLOSED to any clients if they exist. **
  517. **********************************************************************/
  518. CreateDocObjFromFile (lpsz, &docMain);
  519. SubClassMCIWindow();
  520. return TRUE;
  521. }
  522. /* SetTitle
  523. * --------
  524. *
  525. * Sets the main window's title bar. The format of the title bar is as follows
  526. *
  527. * If embedded
  528. * <Server App name> - <object type> in <client doc name>
  529. *
  530. * Example: "SNWBOARD.AVI - Media Clip in OLECLI.DOC"
  531. * where OLECLI.DOC is a Winword document
  532. */
  533. BOOL SetTitle (LPDOC lpdoc, LPCTSTR lpszDoc)
  534. {
  535. TCHAR szBuf[cchFilenameMax];
  536. TCHAR szBuf1[cchFilenameMax];
  537. if (lpszDoc && lpszDoc[0])
  538. {
  539. // Change document name.
  540. if (lpdoc->aDocName)
  541. GlobalDeleteAtom (lpdoc->aDocName);
  542. lpdoc->aDocName = GlobalAddAtom (lpszDoc);
  543. }
  544. if (gfEmbeddedObject)
  545. {
  546. if (!(gwDeviceType & DTMCI_FILEDEV) && (gwCurDevice > 0))
  547. {
  548. lstrcpy(gachWindowTitle,garMciDevices[gwCurDevice].szDeviceName);
  549. }
  550. if (lpszDoc && lpszDoc[0])
  551. {
  552. /* Load "Media Clip in %s":
  553. */
  554. if(!LOADSTRING(IDS_FORMATEMBEDDEDTITLE, szBuf))
  555. return FALSE;
  556. if (gachWindowTitle[0])
  557. {
  558. /* Format with server app name:
  559. */
  560. wsprintf (szBuf1, TEXT("%s - %s"), gachWindowTitle, szBuf);
  561. wsprintf (szBuf, szBuf1, gachClassRoot, FileName (lpszDoc));
  562. }
  563. else
  564. {
  565. /* Format without server app name:
  566. */
  567. wsprintf (szBuf1, TEXT("%s"), szBuf);
  568. wsprintf (szBuf, szBuf1, gachClassRoot, FileName (lpszDoc));
  569. }
  570. }
  571. else
  572. {
  573. return FALSE;
  574. }
  575. SetWindowText (ghwndApp, szBuf);
  576. }
  577. return TRUE;
  578. }
  579.