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.

806 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1999.
  5. //
  6. // File: propbase.hxx
  7. //
  8. // Contents: Headers for common property handling routines
  9. //
  10. // Classes: CUtlPropInfo,
  11. // CUtlProps
  12. //
  13. // History: 10-28-97 danleg Created from monarch uprops.hpp
  14. //
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. //
  18. // Constants and Static Struct
  19. //
  20. #define DEFAULT_MACHINE L"."
  21. const ULONG DWORDSNEEDEDPERSET = 2;
  22. const ULONG DWORDSNEEDEDTOTAL = DWORDSNEEDEDPERSET * 5;
  23. //
  24. // Macros
  25. //
  26. #define INRANGE(z,zmin,zmax) ( (zmin) <= (z) && (z) <= (zmax) )
  27. //
  28. // Utility functions
  29. //
  30. // Bit array routines.
  31. // Two versions: one for a single DWORD, one for arrays.
  32. // Note that you pass in not a bit mask, but the bit number.
  33. // i.e. dwBit = 0,1,2,3,4...31 instead of 1,2,4,8,0x10,0x20...
  34. inline void SETBIT( DWORD &dwFlags, DWORD dwBit )
  35. {
  36. dwFlags |= 1 << dwBit;
  37. }
  38. inline void CLEARBIT( DWORD &dwFlags, DWORD dwBit )
  39. {
  40. dwFlags &= ~ (1<<dwBit);
  41. }
  42. inline DWORD TESTBIT( DWORD &dwFlags, DWORD dwBit )
  43. {
  44. return (dwFlags & (1<<dwBit)) != 0;
  45. }
  46. // Routines based on array-of-DWORD.
  47. // Use these like a bit array, from 0...n-1.
  48. #define DivDword(dw) (dw >> 5) // dw / 32 = dw / (sizeof(DWORD)*8)
  49. #define ModDword(dw) (dw & (32-1)) // dw % 32
  50. #define DwordSizeofBits(nBits) (nBits/32+1) // Use in array declarations
  51. inline void SETBIT( DWORD rgdwFlags[], const DWORD dwBit )
  52. {
  53. rgdwFlags[DivDword(dwBit)] |= 1 << ModDword(dwBit);
  54. }
  55. inline void CLEARBIT( DWORD rgdwFlags[], const DWORD dwBit )
  56. {
  57. rgdwFlags[DivDword(dwBit)] &= ~( 1 << ModDword(dwBit) );
  58. }
  59. #define CLEARBITARRAY( rgdwFlags ) RtlZeroMemory( rgdwFlags, sizeof(rgdwFlags) )
  60. inline DWORD TESTBIT( const DWORD rgdwFlags[], const DWORD dwBit )
  61. {
  62. //old//Note: Not {0,1}, but from {0...2^32-1}.
  63. // Note: Now returns {0,1}.
  64. return ( rgdwFlags[DivDword(dwBit)] & ( 1 << ModDword(dwBit) ) ) != 0;
  65. }
  66. #undef DivDWord
  67. #undef ModDWord
  68. //
  69. // Forward Declarations
  70. //
  71. class CColumnIds;
  72. //
  73. // Constants and Static Struct
  74. //
  75. // leave plenty of space for localization.
  76. const ULONG CCH_GETPROPERTYINFO_DESCRIP_BUFFER_SIZE = 256;
  77. const DWORD GETPROPINFO_ALLPROPIDS = 0x0001;
  78. const DWORD GETPROPINFO_NOTSUPPORTED = 0x0002;
  79. const DWORD GETPROPINFO_ERRORSOCCURRED = 0x0004;
  80. const DWORD GETPROPINFO_VALIDPROP = 0x0008;
  81. const DWORD GETPROP_ALLPROPIDS = 0x0001;
  82. const DWORD GETPROP_NOTSUPPORTED = 0x0002;
  83. const DWORD GETPROP_ERRORSOCCURRED = 0x0004;
  84. const DWORD GETPROP_VALIDPROP = 0x0008;
  85. const DWORD GETPROP_PROPSINERROR = 0x0010;
  86. const DWORD SETPROP_BADOPTION = 0x0001;
  87. const DWORD SETPROP_NOTSUPPORTED = 0x0002;
  88. const DWORD SETPROP_VALIDPROP = 0x0004;
  89. const DWORD SETPROP_ERRORS = 0x0008;
  90. const DWORD SETPROP_COLUMN_LEVEL = 0x0010;
  91. const DWORD DBINTERNFLAGS_NOCHANGE = 0x00000000;
  92. const DWORD DBINTERNFLAGS_CHANGED = 0x00000001;
  93. const DWORD DBINTERNFLAGS_CHEAPTOREQ = 0x00000002;
  94. const DWORD DBINTERNFLAGS_INERROR = 0x00000004;
  95. const DWORD DBINTERNFLAGS_INERRORSAVED = 0x00000008;
  96. const DWORD DBINTERNFLAGS_TOTRUE = 0x80000000;
  97. // Additional Property Flags needed internally
  98. const DWORD DBPROPFLAGS_CHANGE = 0x80000000;
  99. // Flags for controlling UPROPSETS
  100. const DWORD UPROPSET_HIDDEN = 0x00000001;
  101. const DWORD UPROPSET_PASSTHROUGH = 0x00000002;
  102. // Rules for GetPropertiesArgChk
  103. const DWORD ARGCHK_PROPERTIESINERROR = 0x00000001;
  104. //
  105. // STRUCTURE DEFINITIONS
  106. //
  107. typedef struct tagPropColId* PPROPCOLID;
  108. typedef struct tagUPROPVAL
  109. {
  110. DBPROPOPTIONS dwOption;
  111. DWORD dwFlags;
  112. VARIANT vValue;
  113. } UPROPVAL;
  114. typedef struct tagUPROPINFO
  115. {
  116. DBPROPID dwPropId;
  117. LPCWSTR pwszDesc;
  118. VARTYPE VarType;
  119. DBPROPFLAGS dwFlags;
  120. } UPROPINFO;
  121. typedef struct tagUPROP
  122. {
  123. ULONG cPropIds;
  124. UPROPINFO** rgpUPropInfo;
  125. UPROPVAL* pUPropVal;
  126. } UPROP;
  127. typedef struct tagUPROPSET
  128. {
  129. const GUID* pPropSet;
  130. ULONG cUPropInfo;
  131. const UPROPINFO* pUPropInfo;
  132. DWORD dwFlags;
  133. } UPROPSET;
  134. //+-------------------------------------------------------------------------
  135. //
  136. // Class: CUtlPropInfo
  137. //
  138. // Purpose: Base class for property storage
  139. //
  140. // History: 11-12-97 danleg Created from Monarch
  141. //
  142. //--------------------------------------------------------------------------
  143. class CUtlPropInfo
  144. {
  145. public:
  146. //
  147. // Ctor / Dtor
  148. //
  149. CUtlPropInfo();
  150. virtual ~CUtlPropInfo() { };
  151. SCODE GetPropertyInfo ( ULONG cPropertySets,
  152. const DBPROPIDSET rgPropertySets[],
  153. ULONG * pcPropertyInfoSets,
  154. DBPROPINFOSET ** prgPropertyInfoSets,
  155. WCHAR ** ppDescBuffer );
  156. //
  157. // Get the count of propsets.
  158. //
  159. ULONG GetUPropSetCount() { return _cUPropSet; }
  160. //
  161. // Reset the count of propsets.
  162. //
  163. void SetUPropSetCount( ULONG c ) { _cUPropSet = c; }
  164. //
  165. // Pure Virtual
  166. //
  167. virtual SCODE InitAvailUPropSets(
  168. ULONG * pcUPropSet,
  169. UPROPSET ** ppUPropSet,
  170. ULONG * pcElemPerSupported )=0;
  171. virtual SCODE InitUPropSetsSupported(
  172. DWORD * rgdwSupported )=0;
  173. //
  174. // Load a localized description
  175. //
  176. virtual ULONG LoadDescription ( LPCWSTR pwszDesc,
  177. PWSTR pwszBuff,
  178. ULONG cchBuff )=0;
  179. protected:
  180. //
  181. // Initialization routine called called from constructors of derived
  182. // classes.
  183. //
  184. void FInit();
  185. private:
  186. //
  187. // Count of UPropSet items
  188. //
  189. ULONG _cUPropSet;
  190. //
  191. // Pointer to UPropset items
  192. //
  193. UPROPSET * _pUPropSet;
  194. //
  195. // Count of UPropSet Indexes
  196. //
  197. ULONG _cPropSetDex;
  198. //
  199. // Pointer to Array of UPropSet Index values
  200. //
  201. XArray<ULONG> _xaiPropSetDex;
  202. //
  203. // Number of DWORDS per UPropSet to indicate supported UPropIds
  204. //
  205. ULONG _cElemPerSupported;
  206. //
  207. // Pointer to array of DWORDs indicating supported UPropIds
  208. //
  209. XArray<DWORD> _xadwSupported;
  210. //
  211. // Member functions
  212. //
  213. // Retrieve the property id pointer
  214. SCODE GetUPropInfoPtr ( ULONG iPropSetDex,
  215. DBPROPID dwPropertyId,
  216. UPROPINFO ** ppUPropInfo );
  217. // Retrieve the property set indexes that match this property set.
  218. SCODE GetPropertySetIndex( const GUID * pPropertySet );
  219. // Determine the number of description buffers needed
  220. ULONG CalcDescripBuffers( ULONG cPropInfoSet,
  221. DBPROPINFOSET* pPropInfoSet );
  222. };
  223. //+-------------------------------------------------------------------------
  224. //
  225. // Class: CUtlProps
  226. //
  227. // Purpose: Base class for property storage
  228. //
  229. // History: 11-12-97 danleg Created from Monarch
  230. //
  231. //--------------------------------------------------------------------------
  232. class CUtlProps
  233. {
  234. public:
  235. //
  236. // Ctor / Dtor
  237. //
  238. CUtlProps( DWORD dwFlags = 0 );
  239. virtual ~CUtlProps();
  240. //
  241. // Fill default values again.
  242. //
  243. SCODE FillDefaultValues(ULONG ulPropSetTarget = ULONG_MAX);
  244. //
  245. // Check the arguments for Retrieve Properties
  246. //
  247. void GetPropertiesArgChk( const ULONG cPropertySets,
  248. const DBPROPIDSET rgPropertySets[],
  249. ULONG * pcProperties,
  250. DBPROPSET ** prgProperties );
  251. //
  252. // Check the arguments for Set Properties
  253. //
  254. static void SetPropertiesArgChk( const ULONG cPropertySets,
  255. const DBPROPSET rgPropertySets[] );
  256. //
  257. // Retrieve Properties
  258. //
  259. SCODE GetProperties ( const ULONG cPropertySets,
  260. const DBPROPIDSET rgPropertySets[],
  261. ULONG * pcProperties,
  262. DBPROPSET ** prgProperties );
  263. //
  264. // Set Properties
  265. //
  266. SCODE SetProperties ( const ULONG cPropertySets,
  267. const DBPROPSET rgPropertySets[] );
  268. inline void SetPropertyInError(
  269. const ULONG iPropSet,
  270. const ULONG iPropId );
  271. inline void ClearPropertyInError( ) ;
  272. BOOL IsPropSet ( const GUID * pguidPropSet,
  273. DBPROPID dwPropId );
  274. SCODE GetPropValue ( const GUID * pguidPropSet,
  275. DBPROPID dwPropId,
  276. VARIANT * pvValue );
  277. SCODE SetPropValue ( const GUID * pguidPropSet,
  278. DBPROPID dwPropId,
  279. VARIANT * pvValue );
  280. SCODE CopyUPropVal ( ULONG iPropSet,
  281. UPROPVAL * rgUPropVal );
  282. //
  283. // Virtuals functions
  284. //
  285. virtual SCODE GetIndexofPropSet( const GUID * pPropSet,
  286. ULONG * pulCurSet );
  287. virtual SCODE GetIndexofPropIdinPropSet(
  288. ULONG iCurSet,
  289. DBPROPID dwPropertyId,
  290. ULONG * piCurPropId );
  291. //
  292. // Pure Virtuals
  293. //
  294. virtual SCODE InitAvailUPropSets( ULONG * pcUPropSet,
  295. UPROPSET ** ppUPropSet,
  296. ULONG * pcElemPerSupported )=0;
  297. virtual SCODE GetDefaultValue ( ULONG iPropSet,
  298. DBPROPID dwPropId,
  299. DWORD * dwOption,
  300. VARIANT * pVar )=0;
  301. virtual SCODE IsValidValue ( ULONG iCurSet,
  302. DBPROP * pDBProp )=0;
  303. virtual SCODE InitUPropSetsSupported( DWORD * rgdwSupported) = 0;
  304. //
  305. // Inlined functions
  306. //
  307. inline ULONG GetUPropSetCount() { return _cUPropSet; }
  308. inline void SetUPropSetCount( ULONG c ) { _cUPropSet = c; }
  309. //
  310. // NOTE: The following functions depend on all prior properties in the
  311. // array being writable. This is because the UPROP array contains only
  312. // writable elements, and the UPROPINFO array contains writable and
  313. // read-only elements. If this is a problem, we would need to define
  314. // which one it came from and add the appropriate asserts...
  315. //
  316. // Get DBPROPOPTIONS_xx
  317. inline DWORD GetPropOption ( ULONG iPropSet,
  318. ULONG iProp );
  319. // Set DBPROPOPTIONS_xx
  320. inline void SetPropOption ( ULONG iPropSet,
  321. ULONG iProp,
  322. DWORD dwOption );
  323. //
  324. // Determine if property is required and variant_true
  325. //
  326. inline BOOL IsRequiredTrue ( ULONG iPropSet,
  327. ULONG iProp );
  328. inline DWORD GetInternalFlags( ULONG iPropSet,
  329. ULONG iProp );
  330. inline void AddInternalFlags( ULONG iPropSet,
  331. ULONG iProp,
  332. DWORD dwFlag );
  333. inline void RemoveInternalFlags (
  334. ULONG iPropSet,
  335. ULONG iProp,
  336. DWORD dwFlag );
  337. inline VARIANT * GetVariant ( ULONG iPropSet,
  338. ULONG iProp );
  339. inline SCODE SetVariant ( ULONG iPropSet,
  340. ULONG iProp,
  341. VARIANT * pv );
  342. inline void SetValEmpty ( ULONG iPropSet,
  343. ULONG iProp );
  344. inline BOOL IsEmpty ( ULONG iPropSet,
  345. ULONG iProp );
  346. inline void SetValBool ( ULONG iPropSet,
  347. ULONG iProp,
  348. VARIANT_BOOL bVal );
  349. inline VARIANT_BOOL GetValBool ( ULONG iPropSet,
  350. ULONG iProp );
  351. inline void SetValShort ( ULONG iPropSet,
  352. ULONG iProp,
  353. SHORT iVal );
  354. inline SHORT GetValShort ( ULONG iPropSet,
  355. ULONG iProp );
  356. inline void SetValLong ( ULONG iPropSet,
  357. ULONG iProp,
  358. LONG lVal );
  359. inline LONG GetValLong ( ULONG iPropSet,
  360. ULONG iProp );
  361. inline SCODE SetValString ( ULONG iPropSet,
  362. ULONG iProp,
  363. const WCHAR * pwsz );
  364. inline const WCHAR * GetValString(
  365. ULONG iPropSet,
  366. ULONG iProp );
  367. inline const GUID * GetGuid ( ULONG iPropSet);
  368. inline DWORD GetPropID ( ULONG iPropSet,
  369. ULONG iProp );
  370. inline VARTYPE GetExpectedVarType( ULONG iPropSet,
  371. ULONG iProp );
  372. // Inline Methods
  373. inline void CopyAvailUPropSets( ULONG * pcUPropSet,
  374. UPROPSET ** ppUPropSet,
  375. ULONG * pcElemPerSupported );
  376. inline void CopyUPropSetsSupported(
  377. XArray<DWORD> & xadwSupported );
  378. inline void CopyUPropInfo ( ULONG iPropSet,
  379. XArray<UPROPINFO*> & xapUPropInfo );
  380. protected:
  381. //
  382. // Number of DWORDS per UPropSet to indicate supported UPropIds
  383. //
  384. ULONG _cElemPerSupported;
  385. //
  386. // Pointer to array of DWORDs indicating supported UPropIds
  387. //
  388. XArray<DWORD> _xadwSupported;
  389. //
  390. // Pointer to array of DWORDs indicating if property is in error
  391. //
  392. XArray<DWORD> _xadwPropsInError;
  393. //
  394. // Initialization Method
  395. //
  396. virtual void FInit ( CUtlProps * pCopyMe = NULL );
  397. private:
  398. //
  399. // Count of UPropSet items
  400. //
  401. ULONG _cUPropSet;
  402. //
  403. //Pointer to UPropset items
  404. //
  405. UPROPSET * _pUPropSet;
  406. XArray<UPROP> _xaUProp;
  407. //
  408. // Count of Hidden items
  409. //
  410. ULONG _cUPropSetHidden;
  411. //
  412. // Configuration flags
  413. //
  414. DWORD _dwFlags;
  415. //
  416. // Count of UPropSet Indexes
  417. //
  418. ULONG _cPropSetDex;
  419. //
  420. // Pointer to Array of UPropSet Index values
  421. //
  422. XArray<ULONG> _xaiPropSetDex;
  423. void FreeMemory ( );
  424. ULONG GetCountofWritablePropsInPropSet(
  425. ULONG iPropSet );
  426. ULONG GetUPropValIndex( ULONG iCurset,
  427. DBPROPID dwPropId);
  428. SCODE SetProperty ( ULONG iCurSet,
  429. ULONG iCurProp,
  430. DBPROP * pDBProp);
  431. //
  432. // Retrieve the property set indexes that
  433. // match this property set.
  434. //
  435. SCODE GetPropertySetIndex( GUID * pPropertySet );
  436. };
  437. // --------------------------------------------------------------------------
  438. // -------------------- I N L I N E F U N C T I O N S ----------------------
  439. // --------------------------------------------------------------------------
  440. inline void CUtlProps::CopyAvailUPropSets
  441. (
  442. ULONG* pcUPropSet,
  443. UPROPSET** ppUPropSet,
  444. ULONG* pcElemPerSupported
  445. )
  446. {
  447. Win4Assert( pcUPropSet && ppUPropSet && pcElemPerSupported );
  448. *pcUPropSet = _cUPropSet;
  449. *ppUPropSet = _pUPropSet;
  450. *pcElemPerSupported = _cElemPerSupported;
  451. }
  452. inline void CUtlProps::CopyUPropSetsSupported
  453. (
  454. XArray<DWORD> & xadwSupported
  455. )
  456. {
  457. // if the passed in array already has elements, we will leak
  458. Win4Assert( xadwSupported.IsNull() );
  459. xadwSupported.Init( _xadwSupported );
  460. //RtlCopyMemory( xadwSupported.GetPointer(),
  461. // _xadwSupported.GetPointer(),
  462. // _cUPropSet * _cElemPerSupported * sizeof(DWORD) );
  463. }
  464. inline void CUtlProps::CopyUPropInfo
  465. (
  466. ULONG iPropSet,
  467. XArray<UPROPINFO*> & xapUPropInfo
  468. )
  469. {
  470. Win4Assert( xapUPropInfo.IsNull() );
  471. Win4Assert( iPropSet < _cUPropSet );
  472. xapUPropInfo.Init( _xaUProp[iPropSet].cPropIds );
  473. RtlCopyMemory( xapUPropInfo.GetPointer(),
  474. _xaUProp[iPropSet].rgpUPropInfo,
  475. xapUPropInfo.SizeOf() );
  476. }
  477. inline void CUtlProps::ClearPropertyInError()
  478. {
  479. Win4Assert( !_xadwPropsInError.IsNull() );
  480. RtlZeroMemory( _xadwPropsInError.GetPointer(), _cUPropSet * _cElemPerSupported * sizeof(DWORD) );
  481. };
  482. // Save a few lines by defining a common set of asserts.
  483. #define is_proper_range \
  484. ( (iPropSet < _cUPropSet) \
  485. && (iProp < _pUPropSet[iPropSet].cUPropInfo) \
  486. && (iProp < _xaUProp[iPropSet].cPropIds) )
  487. // Set Property Ids that should be in Error
  488. inline void CUtlProps::SetPropertyInError
  489. (
  490. const ULONG iPropSet,
  491. const ULONG iProp
  492. )
  493. {
  494. SETBIT(&(_xadwPropsInError[iPropSet * _cElemPerSupported]), iProp);
  495. };
  496. // determine if the property is Required and VARIANT_TRUE
  497. inline BOOL CUtlProps::IsRequiredTrue(ULONG iPropSet, ULONG iProp)
  498. {
  499. Win4Assert( is_proper_range );
  500. Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
  501. Win4Assert(V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_TRUE
  502. || V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_FALSE);
  503. return( !(_xaUProp[iPropSet].pUPropVal[iProp].dwFlags & DBINTERNFLAGS_INERROR) &&
  504. (_xaUProp[iPropSet].pUPropVal[iProp].dwOption == DBPROPOPTIONS_REQUIRED) &&
  505. (V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_TRUE) );
  506. };
  507. // Get DBPROPOPTIONS_xx
  508. inline DWORD CUtlProps::GetPropOption(ULONG iPropSet, ULONG iProp)
  509. {
  510. Win4Assert( is_proper_range );
  511. return _xaUProp[iPropSet].pUPropVal[iProp].dwOption;
  512. }
  513. inline void CUtlProps::SetPropOption(ULONG iPropSet, ULONG iProp, DWORD dwOption)
  514. {
  515. Win4Assert( is_proper_range );
  516. _xaUProp[iPropSet].pUPropVal[iProp].dwOption = dwOption;
  517. }
  518. inline DWORD CUtlProps::GetInternalFlags(ULONG iPropSet, ULONG iProp)
  519. {
  520. Win4Assert( is_proper_range );
  521. return _xaUProp[iPropSet].pUPropVal[iProp].dwFlags;
  522. }
  523. inline void CUtlProps::AddInternalFlags(ULONG iPropSet, ULONG iProp, DWORD dwFlags)
  524. {
  525. Win4Assert( is_proper_range );
  526. _xaUProp[iPropSet].pUPropVal[iProp].dwFlags |= dwFlags;
  527. }
  528. inline void CUtlProps::RemoveInternalFlags(ULONG iPropSet, ULONG iProp, DWORD dwFlags)
  529. {
  530. Win4Assert( is_proper_range );
  531. _xaUProp[iPropSet].pUPropVal[iProp].dwFlags &= ~dwFlags;
  532. }
  533. inline VARIANT * CUtlProps::GetVariant(ULONG iPropSet, ULONG iProp)
  534. {
  535. Win4Assert( is_proper_range );
  536. return & _xaUProp[iPropSet].pUPropVal[iProp].vValue;
  537. }
  538. inline SCODE CUtlProps::SetVariant(ULONG iPropSet, ULONG iProp, VARIANT *pv )
  539. {
  540. Win4Assert( is_proper_range );
  541. // Does VariantClear first.
  542. return VariantCopy( &_xaUProp[iPropSet].pUPropVal[iProp].vValue, pv );
  543. }
  544. inline void CUtlProps::SetValEmpty(ULONG iPropSet, ULONG iProp)
  545. {
  546. Win4Assert( is_proper_range );
  547. VariantClear( &_xaUProp[iPropSet].pUPropVal[iProp].vValue );
  548. }
  549. inline BOOL CUtlProps::IsEmpty(ULONG iPropSet, ULONG iProp)
  550. {
  551. Win4Assert( is_proper_range );
  552. return ( _xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_EMPTY);
  553. }
  554. inline void CUtlProps::SetValBool(ULONG iPropSet, ULONG iProp, VARIANT_BOOL bVal )
  555. {
  556. Win4Assert( is_proper_range );
  557. // Note that we accept any "true" value.
  558. VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
  559. _xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_BOOL;
  560. V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue)
  561. = (bVal ? VARIANT_TRUE : VARIANT_FALSE);
  562. }
  563. inline VARIANT_BOOL CUtlProps::GetValBool(ULONG iPropSet, ULONG iProp)
  564. {
  565. Win4Assert( is_proper_range );
  566. Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
  567. return V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
  568. }
  569. inline void CUtlProps::SetValShort(ULONG iPropSet, ULONG iProp, SHORT iVal )
  570. {
  571. Win4Assert( is_proper_range );
  572. VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
  573. _xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I2;
  574. _xaUProp[iPropSet].pUPropVal[iProp].vValue.iVal = iVal;
  575. }
  576. inline SHORT CUtlProps::GetValShort(ULONG iPropSet, ULONG iProp)
  577. {
  578. Win4Assert( is_proper_range );
  579. Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I2);
  580. return _xaUProp[iPropSet].pUPropVal[iProp].vValue.iVal;
  581. }
  582. inline void CUtlProps::SetValLong(ULONG iPropSet, ULONG iProp, LONG lVal )
  583. {
  584. Win4Assert( is_proper_range );
  585. VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
  586. _xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I4;
  587. _xaUProp[iPropSet].pUPropVal[iProp].vValue.lVal = lVal;
  588. }
  589. // Get value as long
  590. inline LONG CUtlProps::GetValLong(ULONG iPropSet, ULONG iProp)
  591. {
  592. Win4Assert( is_proper_range );
  593. Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I4);
  594. return _xaUProp[iPropSet].pUPropVal[iProp].vValue.lVal;
  595. }
  596. // Set value as string
  597. inline SCODE CUtlProps::SetValString(ULONG iPropSet, ULONG iProp, const WCHAR *pwsz )
  598. {
  599. Win4Assert( is_proper_range );
  600. VARIANT *pv = &_xaUProp[iPropSet].pUPropVal[iProp].vValue;
  601. VariantClear(pv);
  602. pv->bstrVal = SysAllocString(pwsz);
  603. if ( pv->bstrVal )
  604. pv->vt = VT_BSTR;
  605. else
  606. return E_FAIL;
  607. // See if this was used for non-string type.
  608. // Typically this is an easy way to pass integer as a string.
  609. if ( GetExpectedVarType(iPropSet,iProp) == VT_BSTR )
  610. return NOERROR;
  611. if ( pwsz[0] != L'\0' )
  612. return VariantChangeType( pv, pv, 0, GetExpectedVarType(iPropSet,iProp) );
  613. // Set to "", which for non-string means empty.
  614. SysFreeString(pv->bstrVal);
  615. pv->vt = VT_EMPTY;
  616. return NOERROR;
  617. }
  618. inline const WCHAR * CUtlProps::GetValString(ULONG iPropSet, ULONG iProp)
  619. {
  620. Win4Assert( is_proper_range );
  621. Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BSTR);
  622. return _xaUProp[iPropSet].pUPropVal[iProp].vValue.bstrVal;
  623. }
  624. inline const GUID * CUtlProps::GetGuid(ULONG iPropSet)
  625. {
  626. Win4Assert(iPropSet < _cUPropSet);
  627. return _pUPropSet[iPropSet].pPropSet;
  628. }
  629. inline DWORD CUtlProps::GetPropID(ULONG iPropSet, ULONG iProp)
  630. {
  631. Win4Assert( is_proper_range );
  632. return _pUPropSet[iPropSet].pUPropInfo[iProp].dwPropId;
  633. }
  634. inline VARTYPE CUtlProps::GetExpectedVarType(ULONG iPropSet, ULONG iProp)
  635. {
  636. Win4Assert( is_proper_range );
  637. return _pUPropSet[iPropSet].pUPropInfo[iProp].VarType;
  638. }
  639. #undef is_proper_range