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.

652 lines
16 KiB

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