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.

664 lines
17 KiB

  1. //=--------------------------------------------------------------------------=
  2. // ControlPersistence.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of persistence interfaces for COleControl.
  13. //
  14. #include "pch.h"
  15. #include "CtrlObj.H"
  16. #include "CtlHelp.H"
  17. // for ASSERT and FAIL
  18. //
  19. SZTHISFILE
  20. // this is the name of the stream we'll save our ole controls to.
  21. //
  22. const WCHAR wszCtlSaveStream [] = L"Contents";
  23. //=--------------------------------------------------------------------------=
  24. // to help with out stream save implementation ...
  25. //
  26. #define STREAMHDR_SIGNATURE 0x12344321 // Signature to identify our format (avoid crashes!)
  27. #define IPROP_END 0xFF // Marker at end of property list
  28. #define MAXAUTOBUF 3800 // Best if < 1 page.
  29. typedef struct tagSTREAMHDR {
  30. DWORD dwSignature; // Signature.
  31. size_t cbWritten; // Number of bytes written
  32. } STREAMHDR;
  33. //=--------------------------------------------------------------------------=
  34. // COleControl persistence interfaces
  35. //=--------------------------------------------------------------------------=
  36. //=--------------------------------------------------------------------------=
  37. // COleControl::Load [IPersistPropertyBag]
  38. //=--------------------------------------------------------------------------=
  39. // IPersistPropertyBag. we've got a property bag, so let's load our properties
  40. // from it.
  41. //
  42. // Parameters:
  43. // IPropertyBag * - [in] pbag from which to read props.
  44. // IErrorLog * - [in] error log to write to
  45. //
  46. // Output:
  47. // HRESULT
  48. //
  49. // Notes:
  50. //
  51. STDMETHODIMP COleControl::Load
  52. (
  53. IPropertyBag *pPropertyBag,
  54. IErrorLog *pErrorLog
  55. )
  56. {
  57. HRESULT hr;
  58. // load in our standard state first. nothing serious here ... currently,
  59. // we've just got two properties, for cx and cy.
  60. //
  61. hr = LoadStandardState(pPropertyBag, pErrorLog);
  62. RETURN_ON_FAILURE(hr);
  63. // now call the user text load function, and get them to load in whatever
  64. // they're interested in.
  65. //
  66. hr = LoadTextState(pPropertyBag, pErrorLog);
  67. return hr;
  68. }
  69. //=--------------------------------------------------------------------------=
  70. // COleControl::Save [IPersistPropertyBag]
  71. //=--------------------------------------------------------------------------=
  72. // given a property bag, save out all the relevant state information.
  73. //
  74. // Parameters:
  75. // IPropertyBag * - [in] property to write to
  76. // BOOL - [in] do we clear the dirty bit?
  77. // BOOL - [in] do we write out default values anyhoo?
  78. //
  79. // Output:
  80. // HRESULT
  81. //
  82. // Notes:
  83. //
  84. STDMETHODIMP COleControl::Save
  85. (
  86. IPropertyBag *pPropertyBag,
  87. BOOL fClearDirty,
  88. BOOL fWriteDefault
  89. )
  90. {
  91. HRESULT hr;
  92. // save out standard state information
  93. //
  94. hr = SaveStandardState(pPropertyBag);
  95. RETURN_ON_FAILURE(hr);
  96. // now call the user function and get them to save out
  97. // all of their properties.
  98. //
  99. hr = SaveTextState(pPropertyBag, fWriteDefault);
  100. RETURN_ON_FAILURE(hr);
  101. // now clear the dirty flag and send out notification that we're
  102. // done.
  103. //
  104. if (fClearDirty)
  105. m_fDirty = FALSE;
  106. if (m_pOleAdviseHolder)
  107. m_pOleAdviseHolder->SendOnSave();
  108. return S_OK;
  109. }
  110. //=--------------------------------------------------------------------------=
  111. // COleControl::GetClassID [IPersistStreamInit]
  112. //=--------------------------------------------------------------------------=
  113. // returns the classid of this mamma
  114. //
  115. // Parameters:
  116. // CLSID * - [out] where to put the clsid
  117. //
  118. // Output:
  119. // HRESULT
  120. //
  121. // Notes:
  122. //
  123. STDMETHODIMP COleControl::GetClassID
  124. (
  125. CLSID *pclsid
  126. )
  127. {
  128. CHECK_POINTER(pclsid);
  129. // copy the thing over
  130. //
  131. *pclsid = CLSIDOFOBJECT(m_ObjectType);
  132. return S_OK;
  133. }
  134. //=--------------------------------------------------------------------------=
  135. // COleControl::IsDirty [IPersistStreamInit]
  136. //=--------------------------------------------------------------------------=
  137. // asks if we're dirty or not. duh.
  138. //
  139. // Output:
  140. // HRESULT - S_OK: dirty, S_FALSE: not dirty
  141. //
  142. // Notes:
  143. //
  144. STDMETHODIMP COleControl::IsDirty
  145. (
  146. void
  147. )
  148. {
  149. return (m_fDirty) ? S_OK : S_FALSE;
  150. }
  151. //=--------------------------------------------------------------------------=
  152. // COleControl::InitNew [IPersistStreamInit]
  153. //=--------------------------------------------------------------------------=
  154. // causes the control to intialize itself with a new bunch of state information
  155. //
  156. // Output:
  157. // HRESULT
  158. //
  159. // Notes:
  160. //
  161. STDMETHODIMP COleControl::InitNew
  162. (
  163. void
  164. )
  165. {
  166. BOOL f;
  167. // call the overridable function to do this work
  168. //
  169. f = InitializeNewState();
  170. // make sure we mark ourselves as dirty
  171. //
  172. m_fDirty = TRUE;
  173. return (f) ? S_OK : E_FAIL;
  174. }
  175. //=--------------------------------------------------------------------------=
  176. // COleControl::GetSizeMax [IPersistStreamInit]
  177. //=--------------------------------------------------------------------------=
  178. //
  179. // Parameters:
  180. // ULARGE_INTEGER * - [out]
  181. //
  182. // Output:
  183. // HRESULT
  184. //
  185. // Notes:
  186. //
  187. STDMETHODIMP COleControl::GetSizeMax
  188. (
  189. ULARGE_INTEGER *pulMaxSize
  190. )
  191. {
  192. return E_NOTIMPL;
  193. }
  194. //=--------------------------------------------------------------------------=
  195. // COleControl::Load [IPersistStreamInit]
  196. //=--------------------------------------------------------------------------=
  197. // load from an IStream
  198. //
  199. // Parameters:
  200. // IStream * - [in] stream from which to load
  201. //
  202. // Output:
  203. // HRESULT
  204. //
  205. // Notes:
  206. //
  207. STDMETHODIMP COleControl::Load
  208. (
  209. IStream *pStream
  210. )
  211. {
  212. HRESULT hr;
  213. // first thing to do is read in standard properties the user don't
  214. // persist themselves.
  215. //
  216. hr = LoadStandardState(pStream);
  217. RETURN_ON_FAILURE(hr);
  218. // load in the user properties. this method is one they -have- to implement
  219. // themselves.
  220. //
  221. hr = LoadBinaryState(pStream);
  222. return hr;
  223. }
  224. //=--------------------------------------------------------------------------=
  225. // COleControl::Save [IPersistStreamInit]
  226. //=--------------------------------------------------------------------------=
  227. // saves out our state using streams
  228. //
  229. // Parameters:
  230. // IStream * - [in]
  231. // BOOL - [in] clear dirty bit?
  232. //
  233. // Output:
  234. // HRESULT
  235. //
  236. // Notes:
  237. //
  238. STDMETHODIMP COleControl::Save
  239. (
  240. IStream *pStream,
  241. BOOL fClearDirty
  242. )
  243. {
  244. HRESULT hr;
  245. // use our helper routine that we share with the IStorage persistence
  246. // code.
  247. //
  248. hr = m_SaveToStream(pStream);
  249. RETURN_ON_FAILURE(hr);
  250. // clear out dirty flag [if appropriate] and notify that we're done
  251. // with save.
  252. //
  253. if (fClearDirty)
  254. m_fDirty = FALSE;
  255. if (m_pOleAdviseHolder)
  256. m_pOleAdviseHolder->SendOnSave();
  257. return S_OK;
  258. }
  259. //=--------------------------------------------------------------------------=
  260. // COleControl::InitNew [IPersistStorage]
  261. //=--------------------------------------------------------------------------=
  262. // ipersiststorage version of this. fweee
  263. //
  264. // Parameters:
  265. // IStorage * - [in] we don't use this
  266. //
  267. // Output:
  268. // HRESULT
  269. //
  270. // Notes:
  271. //
  272. STDMETHODIMP COleControl::InitNew
  273. (
  274. IStorage *pStorage
  275. )
  276. {
  277. // we already have an implementation of this [for IPersistStreamInit]
  278. //
  279. return InitNew();
  280. }
  281. //=--------------------------------------------------------------------------=
  282. // COleControl::Load [IPersistStorage]
  283. //=--------------------------------------------------------------------------=
  284. // Ipersiststorage version of this
  285. //
  286. // Parameters:
  287. // IStorage * - [in] DUH.
  288. //
  289. // Output:
  290. // HRESULT
  291. //
  292. // Notes:
  293. //
  294. STDMETHODIMP COleControl::Load(IStorage *pStorage)
  295. {
  296. IStream *pStream;
  297. HRESULT hr;
  298. // we're going to use IPersistStream::Load from the CONTENTS stream.
  299. //
  300. hr = pStorage->OpenStream(wszCtlSaveStream, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
  301. RETURN_ON_FAILURE(hr);
  302. // IPersistStreamInit::Load
  303. //
  304. hr = Load(pStream);
  305. pStream->Release();
  306. return hr;
  307. }
  308. //=--------------------------------------------------------------------------=
  309. // COleControl::Save [IPersistStorage]
  310. //=--------------------------------------------------------------------------=
  311. // save into the contents stream of the given storage object.
  312. //
  313. // Parameters:
  314. // IStorage * - [in] 10 points if you figure it out
  315. // BOOL - [in] is the storage the same as the load storage?
  316. //
  317. // Output:
  318. // HRESULT
  319. //
  320. // Notes:
  321. //
  322. STDMETHODIMP COleControl::Save
  323. (
  324. IStorage *pStorage,
  325. BOOL fSameAsLoad
  326. )
  327. {
  328. IStream *pStream;
  329. HRESULT hr;
  330. // we're just going to save out to the CONTENTES stream.
  331. //
  332. hr = pStorage->CreateStream(wszCtlSaveStream, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  333. 0, 0, &pStream);
  334. RETURN_ON_FAILURE(hr);
  335. // use our helper routine.
  336. //
  337. hr = m_SaveToStream(pStream);
  338. m_fSaveSucceeded = (FAILED(hr)) ? FALSE : TRUE;
  339. pStream->Release();
  340. return hr;
  341. }
  342. //=--------------------------------------------------------------------------=
  343. // COleControl::SaveCompleted [IPersistStorage]
  344. //=--------------------------------------------------------------------------=
  345. // lets us clear out our flags.
  346. //
  347. // Parameters:
  348. // IStorage * - ignored
  349. //
  350. // Output:
  351. // HRESULT
  352. //
  353. // Notes:
  354. //
  355. STDMETHODIMP COleControl::SaveCompleted
  356. (
  357. IStorage *pStorageNew
  358. )
  359. {
  360. // if our save succeeded, then we can do our post save work.
  361. //
  362. if (m_fSaveSucceeded) {
  363. m_fDirty = FALSE;
  364. if (m_pOleAdviseHolder)
  365. m_pOleAdviseHolder->SendOnSave();
  366. }
  367. return S_OK;
  368. }
  369. //=--------------------------------------------------------------------------=
  370. // COleControl::HandsOffStorage [IPersistStorage]
  371. //=--------------------------------------------------------------------------=
  372. // not interesting
  373. //
  374. // Output:
  375. // S_OK
  376. //
  377. // Notes:
  378. //
  379. STDMETHODIMP COleControl::HandsOffStorage
  380. (
  381. void
  382. )
  383. {
  384. // we don't ever hold on to a storage pointer, so this is remarkably
  385. // uninteresting to us.
  386. //
  387. return S_OK;
  388. }
  389. //=--------------------------------------------------------------------------=
  390. // COleControl::m_SaveToStream [helper: IPersistStreamInit/IPersistStorage]
  391. //=--------------------------------------------------------------------------=
  392. // save ourselves to a stream
  393. //
  394. // Parameters:
  395. // IStream * - figure it out
  396. //
  397. // Output:
  398. // HRESULT
  399. //
  400. // Notes:
  401. //
  402. HRESULT COleControl::m_SaveToStream
  403. (
  404. IStream *pStream
  405. )
  406. {
  407. HRESULT hr;
  408. // save out standard state information that the user has no control
  409. // over
  410. //
  411. hr = SaveStandardState(pStream);
  412. RETURN_ON_FAILURE(hr);
  413. // save out user-specific satte information. they MUST implement this
  414. // function
  415. //
  416. hr = SaveBinaryState(pStream);
  417. return hr;
  418. }
  419. //=--------------------------------------------------------------------------=
  420. // COleControl::LoadStandardState [ helper ]
  421. //=--------------------------------------------------------------------------=
  422. // reads in standard properties that all controls are going to have, using
  423. // text persistence APIs. there is another version for streams.
  424. //
  425. // Parameters:
  426. // IPropertyBag * - [in]
  427. // IErrorLog * - [in]
  428. //
  429. // Output:
  430. // HRESULT
  431. //
  432. // Notes:
  433. //
  434. HRESULT COleControl::LoadStandardState
  435. (
  436. IPropertyBag *pPropertyBag,
  437. IErrorLog *pErrorLog
  438. )
  439. {
  440. VARIANT v;
  441. HRESULT hr;
  442. SIZEL slHiMetric = { 100, 50 };
  443. // currently, our only standard properties are related to size.
  444. // if we can't find them, then we'll just use some defaults.
  445. //
  446. v.vt = VT_I4;
  447. v.lVal = 0;
  448. hr = pPropertyBag->Read(L"_ExtentX", &v, pErrorLog);
  449. if (FAILED(hr)) goto DefaultSize;
  450. slHiMetric.cx = v.lVal;
  451. v.lVal = 0;
  452. hr = pPropertyBag->Read(L"_ExtentY", &v, pErrorLog);
  453. if (FAILED(hr)) goto DefaultSize;
  454. slHiMetric.cy = v.lVal;
  455. HiMetricToPixel(&slHiMetric, &m_Size);
  456. return S_OK;
  457. DefaultSize:
  458. m_Size.cx = 100;
  459. m_Size.cy = 50;
  460. return S_OK;
  461. }
  462. //=--------------------------------------------------------------------------=
  463. // COleControl::LoadStandardState [ helper ]
  464. //=--------------------------------------------------------------------------=
  465. // reads in standard properties that all controls are going to have, using
  466. // stream persistence APIs. there is another version for text.
  467. //
  468. // Parameters:
  469. // IStream * - [in]
  470. //
  471. // Output:
  472. // HRESULT
  473. //
  474. // Notes:
  475. //
  476. HRESULT COleControl::LoadStandardState
  477. (
  478. IStream *pStream
  479. )
  480. {
  481. STREAMHDR stmhdr;
  482. HRESULT hr;
  483. SIZEL slHiMetric;
  484. // look for our header structure, so we can verify stream validity.
  485. //
  486. hr = pStream->Read(&stmhdr, sizeof(STREAMHDR), NULL);
  487. RETURN_ON_FAILURE(hr);
  488. if (stmhdr.dwSignature != STREAMHDR_SIGNATURE)
  489. return E_UNEXPECTED;
  490. // currently, the only standard state we're writing out is
  491. // a SIZEL structure describing the control's size.
  492. //
  493. if (stmhdr.cbWritten != sizeof(m_Size))
  494. return E_UNEXPECTED;
  495. // we like the stream. let's go load in our two properties.
  496. //
  497. hr = pStream->Read(&slHiMetric, sizeof(slHiMetric), NULL);
  498. RETURN_ON_FAILURE(hr);
  499. HiMetricToPixel(&slHiMetric, &m_Size);
  500. return S_OK;
  501. }
  502. //=--------------------------------------------------------------------------=
  503. // COleControl::SaveStandardState [ helper ]
  504. //=--------------------------------------------------------------------------=
  505. // saves out standard properties that we're managing for a control using text
  506. // persistence APIs. there is another version for stream persistence.
  507. //
  508. // Parameters:
  509. // IPropertyBag * - [in]
  510. //
  511. // Output:
  512. // HRESULT
  513. //
  514. // Notes:
  515. //
  516. HRESULT COleControl::SaveStandardState
  517. (
  518. IPropertyBag *pPropertyBag
  519. )
  520. {
  521. HRESULT hr;
  522. VARIANT v;
  523. SIZEL slHiMetric;
  524. // currently, the only standard proprerties we persist are Size related
  525. //
  526. PixelToHiMetric(&m_Size, &slHiMetric);
  527. v.vt = VT_I4;
  528. v.lVal = slHiMetric.cx;
  529. hr = pPropertyBag->Write(L"_ExtentX", &v);
  530. RETURN_ON_FAILURE(hr);
  531. v.lVal = slHiMetric.cy;
  532. hr = pPropertyBag->Write(L"_ExtentY", &v);
  533. return hr;
  534. }
  535. //=--------------------------------------------------------------------------=
  536. // COleControl::SaveStandardState [ helper ]
  537. //=--------------------------------------------------------------------------=
  538. // saves out standard properties that we're managing for a control using stream
  539. // persistence APIs. there is another version for text persistence.
  540. //
  541. // Parameters:
  542. // IStream * - [in]
  543. //
  544. // Output:
  545. // HRESULT
  546. //
  547. // Notes:
  548. //
  549. HRESULT COleControl::SaveStandardState
  550. (
  551. IStream *pStream
  552. )
  553. {
  554. STREAMHDR streamhdr = { STREAMHDR_SIGNATURE, sizeof(SIZEL) };
  555. HRESULT hr;
  556. SIZEL slHiMetric;
  557. // first thing to do is write out our stream hdr structure.
  558. //
  559. hr = pStream->Write(&streamhdr, sizeof(STREAMHDR), NULL);
  560. RETURN_ON_FAILURE(hr);
  561. // the only properties we're currently persisting here are the size
  562. // properties for this control. make sure we do that in HiMetric
  563. //
  564. PixelToHiMetric(&m_Size, &slHiMetric);
  565. hr = pStream->Write(&slHiMetric, sizeof(slHiMetric), NULL);
  566. return hr;
  567. }
  568. //=--------------------------------------------------------------------------=
  569. // COleControl::InitializeNewState [overridable]
  570. //=--------------------------------------------------------------------------=
  571. // the user can override this to initialize variables
  572. //
  573. // Output:
  574. // BOOL - FALSE means couldn't do it.
  575. //
  576. // Notes:
  577. //
  578. BOOL COleControl::InitializeNewState
  579. (
  580. void
  581. )
  582. {
  583. // we find this largely uninteresting
  584. //
  585. return TRUE;
  586. }