Source code of Windows XP (NT5)
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.

637 lines
17 KiB

  1. //**********************************************************************
  2. // File name: SITE.CPP
  3. //
  4. // Implementation file for CSimpleSite
  5. //
  6. // Functions:
  7. //
  8. // See SITE.H for class definition
  9. //
  10. // Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved.
  11. //**********************************************************************
  12. #include "pre.h"
  13. #include "iocs.h"
  14. #include "ias.h"
  15. #include "ioipf.h"
  16. #include "ioips.h"
  17. #include "app.h"
  18. #include "site.h"
  19. #include "doc.h"
  20. //**********************************************************************
  21. //
  22. // CSimpleSite::Create
  23. //
  24. // Purpose:
  25. //
  26. // Creation routine for CSimpleSite
  27. //
  28. // Parameters:
  29. //
  30. // CSimpleDoc FAR *lpDoc - Pointer to CSimpleDoc
  31. //
  32. // Return Value:
  33. //
  34. // None
  35. //
  36. // Function Calls:
  37. // Function Location
  38. //
  39. // CSimpleSite::CSimpleSite SITE.CPP
  40. // IStorage::CreateStorage OLE API
  41. // CSimpleSite::AddRef SITE.CPP
  42. // assert C Runtime
  43. //
  44. //
  45. //********************************************************************
  46. CSimpleSite FAR * CSimpleSite::Create(CSimpleDoc FAR *lpDoc)
  47. {
  48. CSimpleSite FAR * lpTemp = new CSimpleSite(lpDoc);
  49. if (!lpTemp)
  50. return NULL;
  51. // create a sub-storage for the object
  52. HRESULT hErr = lpDoc->m_lpStorage->CreateStorage( OLESTR("Object"),
  53. STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE,
  54. 0,
  55. 0,
  56. &lpTemp->m_lpObjStorage);
  57. assert(hErr == NOERROR);
  58. if (hErr != NOERROR)
  59. {
  60. delete lpTemp;
  61. return NULL;
  62. }
  63. // we will add one ref count on our Site. later when we want to destroy
  64. // the Site object we will release this ref count. when the Site's ref
  65. // count goes to 0, it will be deleted.
  66. lpTemp->AddRef();
  67. return lpTemp;
  68. }
  69. //**********************************************************************
  70. //
  71. // CSimpleSite::CSimpleSite
  72. //
  73. // Purpose:
  74. //
  75. // Constructor for CSimpleSite
  76. //
  77. // Parameters:
  78. //
  79. // CSimpleDoc FAR *lpDoc - Pointer to CSimpleDoc
  80. //
  81. // Return Value:
  82. //
  83. // None
  84. //
  85. // Function Calls:
  86. // Function Location
  87. //
  88. //
  89. //********************************************************************
  90. #pragma warning(disable : 4355) // turn off this warning. This warning
  91. // tells us that we are passing this in
  92. // an initializer, before "this" is through
  93. // initializing. This is ok, because
  94. // we just store the ptr in the other
  95. // constructors
  96. CSimpleSite::CSimpleSite (CSimpleDoc FAR *lpDoc) : m_OleClientSite(this),
  97. m_AdviseSink(this),
  98. m_OleInPlaceSite(this)
  99. #pragma warning (default : 4355) // Turn the warning back on
  100. {
  101. TestDebugOut (TEXT("In CSimpleSite's Constructor \r\n"));
  102. // remember the pointer to the doc
  103. m_lpDoc = lpDoc;
  104. // clear the reference count
  105. m_nCount = 0;
  106. m_dwDrawAspect = DVASPECT_CONTENT;
  107. m_lpOleObject = NULL;
  108. m_lpInPlaceObject = NULL;
  109. m_hwndIPObj = NULL;
  110. m_fInPlaceActive = FALSE;
  111. m_fObjectOpen = FALSE;
  112. }
  113. //**********************************************************************
  114. //
  115. // CSimpleSite::~CSimpleSite
  116. //
  117. // Purpose:
  118. //
  119. // Destructor for CSimpleSite
  120. //
  121. // Parameters:
  122. //
  123. // None
  124. //
  125. // Return Value:
  126. //
  127. // None
  128. //
  129. // Function Calls:
  130. // Function Location
  131. //
  132. // TestDebugOut Windows API
  133. // IOleObject::Release Object
  134. // IStorage::Release OLE API
  135. //
  136. //
  137. //********************************************************************
  138. CSimpleSite::~CSimpleSite ()
  139. {
  140. TestDebugOut (TEXT("In CSimpleSite's Destructor \r\n"));
  141. if (m_lpOleObject)
  142. m_lpOleObject->Release();
  143. if (m_lpObjStorage)
  144. m_lpObjStorage->Release();
  145. }
  146. //**********************************************************************
  147. //
  148. // CSimpleSite::CloseOleObject
  149. //
  150. // Purpose:
  151. //
  152. // Call IOleObject::Close on the object of the CSimpleSite
  153. //
  154. // Parameters:
  155. //
  156. // None
  157. //
  158. // Return Value:
  159. //
  160. // None
  161. //
  162. // Function Calls:
  163. // Function Location
  164. //
  165. // TestDebugOut Windows API
  166. // IOleObject::QueryInterface Object
  167. // IOleObject::Close Object
  168. // IOleInPlaceObject::UIDeactivate Object
  169. // IOleInPlaceObject::InPlaceDeactivate Object
  170. // IOleInPlaceObject::Release Object
  171. //
  172. //
  173. //********************************************************************
  174. void CSimpleSite::CloseOleObject (void)
  175. {
  176. LPOLEINPLACEOBJECT lpObject;
  177. LPVIEWOBJECT lpViewObject = NULL;
  178. TestDebugOut (TEXT("In CSimpleSite::CloseOleObject \r\n"));
  179. if (m_lpOleObject)
  180. {
  181. if (m_fInPlaceActive)
  182. {
  183. m_lpOleObject->QueryInterface(IID_IOleInPlaceObject,
  184. (LPVOID FAR *)&lpObject);
  185. lpObject->UIDeactivate();
  186. // don't need to worry about inside-out because the object
  187. // is going away.
  188. lpObject->InPlaceDeactivate();
  189. lpObject->Release();
  190. }
  191. m_lpOleObject->Close(OLECLOSE_NOSAVE);
  192. }
  193. }
  194. //**********************************************************************
  195. //
  196. // CSimpleSite::UnloadOleObject
  197. //
  198. // Purpose:
  199. //
  200. // Close and release all pointers to the object of the CSimpleSite
  201. //
  202. // Parameters:
  203. //
  204. // None
  205. //
  206. // Return Value:
  207. //
  208. // None
  209. //
  210. // Function Calls:
  211. // Function Location
  212. //
  213. // TestDebugOut Windows API
  214. // CSimpleSite::CloseOleObject SITE.CPP
  215. // IOleObject::QueryInterface Object
  216. // IOleObject::Release Object
  217. // IViewObject::SetAdvise Object
  218. // IViewObject::Release Object
  219. //
  220. //
  221. //********************************************************************
  222. void CSimpleSite::UnloadOleObject (void)
  223. {
  224. TestDebugOut (TEXT("In CSimpleSite::UnloadOleObject \r\n"));
  225. if (m_lpOleObject)
  226. {
  227. LPVIEWOBJECT lpViewObject;
  228. CloseOleObject(); // ensure object is closed; NOP if already closed
  229. m_lpOleObject->QueryInterface(IID_IViewObject,
  230. (LPVOID FAR *)&lpViewObject);
  231. if (lpViewObject)
  232. {
  233. // Remove the view advise
  234. lpViewObject->SetAdvise(m_dwDrawAspect, 0, NULL);
  235. lpViewObject->Release();
  236. }
  237. m_lpOleObject->Release();
  238. m_lpOleObject = NULL;
  239. }
  240. }
  241. //**********************************************************************
  242. //
  243. // CSimpleSite::QueryInterface
  244. //
  245. // Purpose:
  246. //
  247. // Used for interface negotiation of the container Site.
  248. //
  249. // Parameters:
  250. //
  251. // REFIID riid - A reference to the interface that is
  252. // being queried.
  253. //
  254. // LPVOID FAR* ppvObj - An out parameter to return a pointer to
  255. // the interface.
  256. //
  257. // Return Value:
  258. //
  259. // S_OK - The interface is supported.
  260. // E_NOINTERFACE - The interface is not supported
  261. //
  262. // Function Calls:
  263. // Function Location
  264. //
  265. // TestDebugOut Windows API
  266. // IsEqualIID OLE API
  267. // ResultFromScode OLE API
  268. // CSimpleSite::AddRef OBJ.CPP
  269. // COleClientSite::AddRef IOCS.CPP
  270. // CAdviseSink::AddRef IAS.CPP
  271. // COleInPlaceSite::AddRef IOIPS.CPP
  272. //
  273. //
  274. //********************************************************************
  275. STDMETHODIMP CSimpleSite::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  276. {
  277. TestDebugOut(TEXT("In CSimpleSite::QueryInterface\r\n"));
  278. *ppvObj = NULL; // must set out pointer parameters to NULL
  279. if ( IsEqualIID(riid, IID_IUnknown))
  280. {
  281. AddRef();
  282. *ppvObj = this;
  283. return ResultFromScode(S_OK);
  284. }
  285. if ( IsEqualIID(riid, IID_IOleClientSite))
  286. {
  287. m_OleClientSite.AddRef();
  288. *ppvObj = &m_OleClientSite;
  289. return ResultFromScode(S_OK);
  290. }
  291. if ( IsEqualIID(riid, IID_IAdviseSink))
  292. {
  293. m_AdviseSink.AddRef();
  294. *ppvObj = &m_AdviseSink;
  295. return ResultFromScode(S_OK);
  296. }
  297. if ( IsEqualIID(riid, IID_IOleInPlaceSite))
  298. {
  299. m_OleInPlaceSite.AddRef();
  300. *ppvObj = &m_OleInPlaceSite;
  301. return ResultFromScode(S_OK);
  302. }
  303. // Not a supported interface
  304. return ResultFromScode(E_NOINTERFACE);
  305. }
  306. //**********************************************************************
  307. //
  308. // CSimpleSite::AddRef
  309. //
  310. // Purpose:
  311. //
  312. // Increments the reference count of the container Site.
  313. //
  314. // Parameters:
  315. //
  316. // None
  317. //
  318. // Return Value:
  319. //
  320. // ULONG - The new reference count of the site.
  321. //
  322. // Function Calls:
  323. // Function Location
  324. //
  325. // TestDebugOut Windows API
  326. //
  327. //
  328. //********************************************************************
  329. STDMETHODIMP_(ULONG) CSimpleSite::AddRef()
  330. {
  331. TestDebugOut(TEXT("In CSimpleSite::AddRef\r\n"));
  332. return ++m_nCount;
  333. }
  334. //**********************************************************************
  335. //
  336. // CSimpleSite::Release
  337. //
  338. // Purpose:
  339. //
  340. // Decrements the reference count of the container Site
  341. //
  342. // Parameters:
  343. //
  344. // None
  345. //
  346. // Return Value:
  347. //
  348. // ULONG - The new reference count of the Site.
  349. //
  350. // Function Calls:
  351. // Function Location
  352. //
  353. // TestDebugOut Windows API
  354. //
  355. //
  356. //********************************************************************
  357. STDMETHODIMP_(ULONG) CSimpleSite::Release()
  358. {
  359. TestDebugOut(TEXT("In CSimpleSite::Release\r\n"));
  360. if (--m_nCount == 0)
  361. {
  362. delete this;
  363. return 0;
  364. }
  365. return m_nCount;
  366. }
  367. //**********************************************************************
  368. //
  369. // CSimpleSite::InitObject
  370. //
  371. // Purpose:
  372. //
  373. // Used to initialize a newly create object (can't be done in the
  374. // constructor).
  375. //
  376. // Parameters:
  377. //
  378. // BOOL fCreateNew - TRUE if insert NEW object
  379. // FALSE if create object FROM FILE
  380. //
  381. // Return Value:
  382. //
  383. // None
  384. //
  385. // Function Calls:
  386. // Function Location
  387. //
  388. // IOleObject::SetHostNames Object
  389. // IOleObject::QueryInterface Object
  390. // IViewObject2::GetExtent Object
  391. // IOleObject::DoVerb Object
  392. // IViewObject2::SetAdvise Object
  393. // IViewObject2::Release Object
  394. // GetClientRect Windows API
  395. // OleSetContainedObject OLE API
  396. //
  397. //
  398. //********************************************************************
  399. void CSimpleSite::InitObject(BOOL fCreateNew)
  400. {
  401. LPVIEWOBJECT2 lpViewObject2;
  402. RECT rect;
  403. TestDebugOut(TEXT("In CSimpleSite::InitObject\r\n"));
  404. // Set a View Advise
  405. m_lpOleObject->QueryInterface(IID_IViewObject2,
  406. (LPVOID FAR *)&lpViewObject2);
  407. lpViewObject2->SetAdvise(m_dwDrawAspect, ADVF_PRIMEFIRST, &m_AdviseSink);
  408. // get the initial size of the object
  409. lpViewObject2->GetExtent(m_dwDrawAspect, -1 /*lindex*/, NULL /*ptd*/,
  410. &m_sizel);
  411. GetObjRect(&rect); // get the rectangle of the object in pixels
  412. lpViewObject2->Release();
  413. // give the object the name of the container app/document
  414. m_lpOleObject->SetHostNames(OLESTR("Simple Application"),
  415. OLESTR("Simple OLE 2.0 In-Place Container"));
  416. // inform object handler/DLL object that it is used in the embedding
  417. // container's context
  418. HRESULT hRes;
  419. if ((hRes = OleSetContainedObject(m_lpOleObject, TRUE))
  420. != ResultFromScode(S_OK) )
  421. {
  422. TestDebugOut(TEXT("Fail in OleSetContainedObject\n"));
  423. }
  424. if (fCreateNew)
  425. {
  426. // force new object to save to guarantee valid object in our storage.
  427. // OLE 1.0 objects may close w/o saving. this is NOT necessary if the
  428. // object is created FROM FILE; its data in storage is already valid.
  429. m_OleClientSite.SaveObject();
  430. // we only want to DoVerb(SHOW) if this is an InsertNew object.
  431. // we should NOT DoVerb(SHOW) if the object is created FromFile.
  432. m_lpOleObject->DoVerb(
  433. OLEIVERB_SHOW,
  434. NULL,
  435. &m_OleClientSite,
  436. -1,
  437. m_lpDoc->m_hDocWnd,
  438. &rect);
  439. }
  440. }
  441. //**********************************************************************
  442. //
  443. // CSimpleSite::PaintObj
  444. //
  445. // Purpose:
  446. //
  447. // Paints the object
  448. //
  449. // Parameters:
  450. //
  451. // HDC hDC - Device context of the document window
  452. //
  453. // Return Value:
  454. // None
  455. //
  456. // Function Calls:
  457. // Function Location
  458. //
  459. // CSimpleSite::GetObjRect SITE.CPP
  460. // IOleObject::QueryInterface Object
  461. // IViewObject::GetColorSet Object
  462. // IViewObject::Release Object
  463. // SetROP2 Windows API
  464. // Rectamgle Windows API
  465. // CreateHatchBrush Windows API
  466. // SelectObject Windows API
  467. // DeleteObject Windows API
  468. // CreatePalette Windows API
  469. // SelectPalette Windows API
  470. // RealizePalette Windows API
  471. // OleStdFree OLE2UI Function
  472. // OleDraw OLE API
  473. //
  474. //
  475. //********************************************************************
  476. void CSimpleSite::PaintObj(HDC hDC)
  477. {
  478. RECT rect;
  479. // need to check to make sure there is a valid object
  480. // available. This is needed if there is a paint msg
  481. // between the time that CSimpleSite is instantiated
  482. // and OleUIInsertObject returns.
  483. if (!m_lpOleObject)
  484. return;
  485. // convert it to pixels
  486. GetObjRect(&rect);
  487. LPLOGPALETTE pColorSet = NULL;
  488. LPVIEWOBJECT lpView = NULL;
  489. // get a pointer to IViewObject
  490. m_lpOleObject->QueryInterface(IID_IViewObject,(LPVOID FAR *) &lpView);
  491. // if the QI succeeds, get the LOGPALETTE for the object
  492. if (lpView)
  493. lpView->GetColorSet(m_dwDrawAspect, -1, NULL, NULL, NULL, &pColorSet);
  494. HPALETTE hPal=NULL;
  495. HPALETTE hOldPal=NULL;
  496. // if a LOGPALETTE was returned (not guarateed), create the palette and
  497. // realize it.NOTE:A smarter application would want to get the LOGPALETTE
  498. // for each of its visible objects, and try to create a palette that
  499. // satisfies all of the visible objects. ALSO: OleStdFree() is use to
  500. // free the returned LOGPALETTE.
  501. if ((pColorSet))
  502. {
  503. hPal = CreatePalette((const LPLOGPALETTE) pColorSet);
  504. hOldPal = SelectPalette(hDC, hPal, FALSE);
  505. RealizePalette(hDC);
  506. OleStdFree(pColorSet);
  507. }
  508. // draw the object
  509. HRESULT hRes;
  510. hRes = OleDraw(m_lpOleObject, m_dwDrawAspect, hDC, &rect);
  511. if ((hRes != ResultFromScode(S_OK)) &&
  512. (hRes != ResultFromScode(OLE_E_BLANK)) &&
  513. (hRes != ResultFromScode(DV_E_NOIVIEWOBJECT)))
  514. {
  515. TestDebugOut(TEXT("Fail in OleDraw\n"));
  516. }
  517. // if the object is open, draw a hatch rect.
  518. if (m_fObjectOpen)
  519. {
  520. HBRUSH hBrush = CreateHatchBrush ( HS_BDIAGONAL, RGB(0,0,0) );
  521. HBRUSH hOldBrush = (HBRUSH) SelectObject (hDC, hBrush);
  522. SetROP2(hDC, R2_MASKPEN);
  523. Rectangle (hDC, rect.left, rect.top, rect.right, rect.bottom);
  524. SelectObject(hDC, hOldBrush);
  525. DeleteObject(hBrush);
  526. }
  527. // if we created a palette, restore the old one, and destroy
  528. // the object.
  529. if (hPal)
  530. {
  531. SelectPalette(hDC,hOldPal,FALSE);
  532. DeleteObject(hPal);
  533. }
  534. // if a view pointer was successfully returned, it needs to be released.
  535. if (lpView)
  536. lpView->Release();
  537. }
  538. //**********************************************************************
  539. //
  540. // CSimpleSite::GetObjRect
  541. //
  542. // Purpose:
  543. //
  544. // Retrieves the rect of the object in pixels
  545. //
  546. // Parameters:
  547. //
  548. // LPRECT lpRect - Rect structure filled with object's rect in pixels
  549. //
  550. // Return Value:
  551. // None
  552. //
  553. // Function Calls:
  554. // Function Location
  555. //
  556. // XformWidthInHimetricToPixels OLE2UI Function
  557. // XformHeightInHimetricToPixels OLE2UI Function
  558. //
  559. //
  560. //********************************************************************
  561. void CSimpleSite::GetObjRect(LPRECT lpRect)
  562. {
  563. // convert it to pixels
  564. lpRect->left = lpRect->top = 0;
  565. lpRect->right = XformWidthInHimetricToPixels(NULL,(int)m_sizel.cx);
  566. lpRect->bottom = XformHeightInHimetricToPixels(NULL,(int)m_sizel.cy);
  567. }