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.

643 lines
14 KiB

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