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.

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