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.

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