CTLPSST.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //=--------------------------------------------------------------------------=
  2. // CtlPsst.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1997 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.     
  221.     return hr;
  222. }
  223. //=--------------------------------------------------------------------------=
  224. // COleControl::Save    [IPersistStreamInit]
  225. //=--------------------------------------------------------------------------=
  226. // saves out our state using streams
  227. //
  228. // Parameters:
  229. //    IStream *        - [in]
  230. //    BOOL             - [in] clear dirty bit?
  231. //
  232. // Output:
  233. //    HRESULT
  234. //
  235. // Notes:
  236. //
  237. STDMETHODIMP COleControl::Save
  238. (
  239.     IStream *pStream,
  240.     BOOL     fClearDirty
  241. )
  242. {
  243.     HRESULT hr;
  244.     // use our helper routine that we share with the IStorage persistence
  245.     // code.
  246.     //
  247.     hr = m_SaveToStream(pStream);
  248.     RETURN_ON_FAILURE(hr);
  249.     // clear out dirty flag [if appropriate] and notify that we're done
  250.     // with save.
  251.     //
  252.     if (fClearDirty)
  253.         m_fDirty = FALSE;
  254.     if (m_pOleAdviseHolder)
  255.         m_pOleAdviseHolder->SendOnSave();
  256.     return S_OK;
  257. }
  258. //=--------------------------------------------------------------------------=
  259. // COleControl::InitNew    [IPersistStorage]
  260. //=--------------------------------------------------------------------------=
  261. // ipersiststorage version of this.  fweee
  262. //
  263. // Parameters:
  264. //    IStorage *    - [in] we don't use this
  265. //
  266. // Output:
  267. //    HRESULT
  268. //
  269. // Notes:
  270. //
  271. STDMETHODIMP COleControl::InitNew
  272. (
  273.     IStorage *pStorage
  274. )
  275. {
  276.     // we already have an implementation of this [for IPersistStreamInit]
  277.     //
  278.     return InitNew();
  279. }
  280. //=--------------------------------------------------------------------------=
  281. // COleControl::Load    [IPersistStorage]
  282. //=--------------------------------------------------------------------------=
  283. // Ipersiststorage version of this
  284. //
  285. // Parameters:
  286. //    IStorage *    - [in] DUH.
  287. //
  288. // Output:
  289. //    HRESULT
  290. //
  291. // Notes:
  292. //
  293. STDMETHODIMP COleControl::Load(IStorage *pStorage)
  294. {
  295.     IStream *pStream;
  296.     HRESULT  hr;
  297.     // we're going to use IPersistStream::Load from the CONTENTS stream.
  298.     //
  299.     hr = pStorage->OpenStream(wszCtlSaveStream, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
  300.     RETURN_ON_FAILURE(hr);
  301.     // IPersistStreamInit::Load
  302.     //
  303.     hr = Load(pStream);
  304.     pStream->Release();
  305.     return hr;
  306. }
  307. //=--------------------------------------------------------------------------=
  308. // COleControl::Save    [IPersistStorage]
  309. //=--------------------------------------------------------------------------=
  310. // save into the contents stream of the given storage object.
  311. //
  312. // Parameters:
  313. //    IStorage *        - [in] 10 points if you figure it out
  314. //    BOOL              - [in] is the storage the same as the load storage?
  315. //
  316. // Output:
  317. //    HRESULT
  318. //
  319. // Notes:
  320. //
  321. STDMETHODIMP COleControl::Save
  322. (
  323.     IStorage *pStorage,
  324.     BOOL      fSameAsLoad
  325. )
  326. {
  327.     IStream *pStream;
  328.     HRESULT  hr;
  329.     // we're just going to save out to the CONTENTES stream.
  330.     //
  331.     hr = pStorage->CreateStream(wszCtlSaveStream, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  332.                                 0, 0, &pStream);
  333.     RETURN_ON_FAILURE(hr);
  334.     // use our helper routine.
  335.     //
  336.     hr = m_SaveToStream(pStream);
  337.     m_fSaveSucceeded = (FAILED(hr)) ? FALSE : TRUE;
  338.     pStream->Release();
  339.     return hr;
  340. }
  341. //=--------------------------------------------------------------------------=
  342. // COleControl::SaveCompleted    [IPersistStorage]
  343. //=--------------------------------------------------------------------------=
  344. // lets us clear out our flags.
  345. //
  346. // Parameters:
  347. //    IStorage *    - ignored
  348. //
  349. // Output:
  350. //    HRESULT
  351. //
  352. // Notes:
  353. //
  354. STDMETHODIMP COleControl::SaveCompleted
  355. (
  356.     IStorage *pStorageNew
  357. )
  358. {
  359.     // if our save succeeded, then we can do our post save work.
  360.     //
  361.     if (m_fSaveSucceeded) {
  362.         m_fDirty = FALSE;
  363.         if (m_pOleAdviseHolder)
  364.             m_pOleAdviseHolder->SendOnSave();
  365.     }
  366.     return S_OK;
  367. }
  368. //=--------------------------------------------------------------------------=
  369. // COleControl::HandsOffStorage    [IPersistStorage]
  370. //=--------------------------------------------------------------------------=
  371. // not interesting
  372. //
  373. // Output:
  374. //    S_OK
  375. //
  376. // Notes:
  377. //
  378. STDMETHODIMP COleControl::HandsOffStorage
  379. (
  380.     void
  381. )
  382. {
  383.     // we don't ever hold on to  a storage pointer, so this is remarkably
  384.     // uninteresting to us.
  385.     //
  386.     return S_OK;
  387. }
  388. //=--------------------------------------------------------------------------=
  389. // COleControl::m_SaveToStream    [helper: IPersistStreamInit/IPersistStorage]
  390. //=--------------------------------------------------------------------------=
  391. // save ourselves to a stream
  392. //
  393. // Parameters:
  394. //    IStream *        - figure it out
  395. //
  396. // Output:
  397. //    HRESULT
  398. //
  399. // Notes:
  400. //
  401. HRESULT COleControl::m_SaveToStream
  402. (
  403.     IStream *pStream
  404. )
  405. {
  406.     HRESULT hr;
  407.     // save out standard state information that the user has no control
  408.     // over
  409.     //
  410.     hr = SaveStandardState(pStream);
  411.     RETURN_ON_FAILURE(hr);
  412.     // save out user-specific satte information.  they MUST implement this
  413.     // function
  414.     //
  415.     hr = SaveBinaryState(pStream);
  416.     return hr;
  417. }
  418. //=--------------------------------------------------------------------------=
  419. // COleControl::LoadStandardState    [ helper ]
  420. //=--------------------------------------------------------------------------=
  421. // reads in standard properties that all controls are going to have, using
  422. // text persistence APIs.  there is another version for streams.
  423. //
  424. // Parameters:
  425. //    IPropertyBag *    - [in]
  426. //    IErrorLog *       - [in]
  427. //
  428. // Output:
  429. //    HRESULT
  430. //
  431. // Notes:
  432. //
  433. HRESULT COleControl::LoadStandardState
  434. (
  435.     IPropertyBag *pPropertyBag,
  436.     IErrorLog    *pErrorLog
  437. )
  438. {
  439.     VARIANT v;
  440.     HRESULT hr;
  441.     SIZEL   slHiMetric = { 100, 50 };
  442.     // currently, our only standard properties are related to size.
  443.     // if we can't find them, then we'll just use some defaults.
  444.     //
  445.     v.vt = VT_I4;
  446.     v.lVal = 0;
  447.     hr = pPropertyBag->Read(L"_ExtentX", &v, pErrorLog);
  448.     if (SUCCEEDED(hr)) slHiMetric.cx = v.lVal;
  449.     v.lVal = 0;
  450.     hr = pPropertyBag->Read(L"_ExtentY", &v, pErrorLog);
  451.     if (SUCCEEDED(hr)) slHiMetric.cy = v.lVal;
  452.     HiMetricToPixel(&slHiMetric, &m_Size);
  453.     return S_OK;
  454. }
  455. //=--------------------------------------------------------------------------=
  456. // COleControl::LoadStandardState    [ helper ]
  457. //=--------------------------------------------------------------------------=
  458. // reads in standard properties that all controls are going to have, using
  459. // stream persistence APIs.  there is another version for text.
  460. //
  461. // Parameters:
  462. //    IStream *         - [in] 
  463. //
  464. // Output:
  465. //    HRESULT
  466. //
  467. // Notes:
  468. //
  469. HRESULT COleControl::LoadStandardState
  470. (
  471.     IStream *pStream
  472. )
  473. {
  474.     STREAMHDR stmhdr;
  475.     HRESULT hr;
  476.     SIZEL   slHiMetric;
  477.     // look for our header structure, so we can verify stream validity.
  478.     //
  479.     hr = pStream->Read(&stmhdr, sizeof(STREAMHDR), NULL);
  480.     RETURN_ON_FAILURE(hr);
  481.     if (stmhdr.dwSignature != STREAMHDR_SIGNATURE)
  482.         return E_UNEXPECTED;
  483.     // currently, the only standard state we're writing out is
  484.     // a SIZEL structure describing the control's size.
  485.     //
  486.     if (stmhdr.cbWritten != sizeof(m_Size))
  487.         return E_UNEXPECTED;
  488.     // we like the stream.  let's go load in our two properties.
  489.     //
  490.     hr = pStream->Read(&slHiMetric, sizeof(slHiMetric), NULL);
  491.     RETURN_ON_FAILURE(hr);
  492.     HiMetricToPixel(&slHiMetric, &m_Size);
  493.     return S_OK;
  494. }
  495. //=--------------------------------------------------------------------------=
  496. // COleControl::SaveStandardState    [ helper ]
  497. //=--------------------------------------------------------------------------=
  498. // saves out standard properties that we're managing for a control using text
  499. // persistence APIs.  there is another version for stream persistence.
  500. //
  501. // Parameters:
  502. //    IPropertyBag *        - [in]
  503. //
  504. // Output:
  505. //    HRESULT
  506. //
  507. // Notes:
  508. //
  509. HRESULT COleControl::SaveStandardState
  510. (
  511.     IPropertyBag *pPropertyBag
  512. )
  513. {
  514.     HRESULT hr;
  515.     VARIANT v;
  516.     SIZEL   slHiMetric;
  517.     // currently, the only standard proprerties we persist are Size related
  518.     //
  519.     PixelToHiMetric(&m_Size, &slHiMetric);
  520.     v.vt = VT_I4;
  521.     v.lVal = slHiMetric.cx;
  522.     hr = pPropertyBag->Write(L"_ExtentX", &v);
  523.     RETURN_ON_FAILURE(hr);
  524.     v.lVal = slHiMetric.cy;
  525.     hr = pPropertyBag->Write(L"_ExtentY", &v);
  526.     return hr;
  527. }
  528. //=--------------------------------------------------------------------------=
  529. // COleControl::SaveStandardState    [ helper ]
  530. //=--------------------------------------------------------------------------=
  531. // saves out standard properties that we're managing for a control using stream
  532. // persistence APIs.  there is another version for text persistence.
  533. //
  534. // Parameters:
  535. //    IStream *            - [in]
  536. //
  537. // Output:
  538. //    HRESULT
  539. //
  540. // Notes:
  541. //
  542. HRESULT COleControl::SaveStandardState
  543. (
  544.     IStream *pStream
  545. )
  546. {
  547.     STREAMHDR streamhdr = { STREAMHDR_SIGNATURE, sizeof(SIZEL) };
  548.     HRESULT hr;
  549.     SIZEL   slHiMetric;
  550.     // first thing to do is write out our stream hdr structure.
  551.     //
  552.     hr = pStream->Write(&streamhdr, sizeof(STREAMHDR), NULL);
  553.     RETURN_ON_FAILURE(hr);
  554.     // the only properties we're currently persisting here are the size
  555.     // properties for this control.  make sure we do that in HiMetric
  556.     //
  557.     PixelToHiMetric(&m_Size, &slHiMetric);
  558.     hr = pStream->Write(&slHiMetric, sizeof(slHiMetric), NULL);
  559.     return hr;
  560. }
  561. //=--------------------------------------------------------------------------=
  562. // COleControl::InitializeNewState    [overridable]
  563. //=--------------------------------------------------------------------------=
  564. // the user can override this to initialize variables
  565. //
  566. // Output:
  567. //    BOOL        - FALSE means couldn't do it.
  568. //
  569. // Notes:
  570. //
  571. BOOL COleControl::InitializeNewState
  572. (
  573.     void
  574. )
  575. {
  576.     // we find this largely uninteresting
  577.     //
  578.     return TRUE;
  579. }