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.

1230 lines
54 KiB

  1. /*
  2. * Element
  3. */
  4. #ifndef DUI_CORE_ELEMENT_H_INCLUDED
  5. #define DUI_CORE_ELEMENT_H_INCLUDED
  6. #pragma once
  7. #include "duivalue.h"
  8. #include "duievent.h"
  9. #include "duisheet.h"
  10. #include "duilayout.h"
  11. struct IAccessible;
  12. namespace DirectUI
  13. {
  14. #if DBG
  15. extern UINT g_cGetDep;
  16. extern UINT g_cGetVal;
  17. extern UINT g_cOnPropChg;
  18. #endif
  19. class DuiAccessible;
  20. // TODO: Switch DUI listeners to use DirectUser MessageHandlers
  21. /*
  22. * Element Properties
  23. *
  24. * Element provides default behavior for Get/SetValue based on the flags used in PropertyInfo.
  25. * The Flags also define what indicies are available during property operations.
  26. *
  27. * Get/SetValue cannot be overridden. Rather, a default implemention is supplied for GetValue's
  28. * on all properties. By default, Get's on the Specified and Computed index are handled by a
  29. * built-in Value Expression (VE) while Get's on Local query a local store (see below for exact
  30. * default behavior). However, various system properties override this default behavior with
  31. * different unchangable Value Expressions (implicit VEs) in the Local and Computed indicies.
  32. *
  33. * End users will use Normal properties and may occasionally use LocalOnly properties. Although
  34. * available to derived classes, TriLevel property functionaly is only useful by the system.
  35. *
  36. * All property value must be available generically through GetValue.
  37. *
  38. * Flags supported (default behavior):
  39. *
  40. * "LocalOnly"
  41. * Indicies: Local
  42. * Get: Retrieve local value from Element. If none is set, 'Unset' returned.
  43. * Set: Stores value locally on the Element.
  44. * Dependents: None
  45. * Modifiers: Readonly: Disallow Set
  46. *
  47. * "Normal"
  48. * Indicies: Local, Specified (implicit VE)
  49. * Get: Local: Retrieve local value from Element. If none is set, 'Unset' returned.
  50. * Specified: Does a Get on the Local value. If 'Unset', return Property Sheet value
  51. * if Cascade modifier is set. If 'Unset', return parent's value if Inherit
  52. * modifier is set. If 'Unset' return property's Default value.
  53. * Automatically evaulate value expressions before return.
  54. * Set: Local: Stores value locally on the Element.
  55. * Specified: Unsupported.
  56. * Dependents: Specified is dependent on Local.
  57. * Modifiers: Readonly: Disallow Set for Local.
  58. * Cascade: Used with Specified Get (see Get description).
  59. * Inherit: Used with Specified Get (see Get description).
  60. *
  61. * "TriLevel"
  62. * Indicies: Local, Specified (implicit VE), Computed (implicit VE)
  63. * Get: Local: Retrieve local value from Element. If none is set, 'Unset' returned.
  64. * Specified: Does a Get on the Local value. If 'Unset', return Property Sheet value
  65. * if Cascade modifier is set. If 'Unset', return parent's value if Inherit
  66. * modifier is set. If 'Unset' return property's Default value.
  67. * Automatically evaulate value expressions before return.
  68. * Computed: Does a get of the Specified value.
  69. * Set: Local: Stores value locally on the Element.
  70. * Specified: Unsupported.
  71. * Computed: Unsupported.
  72. * Dependents: Computed is dependent on Specified. Specified is dependent on Local.
  73. * Modifiers: Readonly: Disallow Set for Local.
  74. * Cascade: Used with Specified Get (see Get description).
  75. * Inherit: Used with Specified Get (see Get description).
  76. *
  77. * SetValue must always be used by derived classes. However, SetValue is sometimes bypassed and
  78. * Pre/PostSourceChange is called directly in the case of LocalOnly properties that are ReadOnly
  79. * and are cached directly on the Element (optimization). All other ReadOnly sets use
  80. * _SetValue since generic storage (of Values) is used. SetValue is used in all other cases.
  81. *
  82. * For ReadOnly values, if storing the value is cheap (i.e. bools) and interit and style sheet
  83. * functionality is not required, it is best to not use generic storage (_SetValue). Rather,
  84. * write the value directly and call Pre/PostSourceChange directly ("LocalOnly property).
  85. * Otherwise, if a ReadOnly value requires inheritance and/or sheet lookups, or the value is
  86. * seldom different than a default value, use _SetValue (generic storage, "Normal" property).
  87. *
  88. * For Normal/ReadOnly, use SetValue, For LocalOnly/ReadOnly, use _SetValue,
  89. * For internal LocalOnly/ReadOnly, set and store manually (no generic storage)
  90. *
  91. * All property values must be settable generically via SetValue except ReadOnly properties.
  92. * Any "LocalOnly" property that doesn't use generic storage must initialize their members
  93. * at construction to the property's default value. "Normal" properties will choose the
  94. * default value automatically when queried. All derived classes (external) will use "Normal"
  95. * properties.
  96. *
  97. * SetValue only accepts the PI_Local index. ReadOnly sets do not fire OnPropertyChanging.
  98. * All value sets must result in a PreSourceChange, followed by the store update (in which GetValue
  99. * will retrieve values from), followed by a PostSourceChange. OnPropertyChange and old value
  100. * compare are optional.
  101. *
  102. * Set values are updated immediately (i.e. an immediate GetValue after will produce the updated
  103. * result). Location and Extent are updated after the defer cycle ends (EndDefer, SetValues are internal).
  104. */
  105. /*
  106. * Element Multithreading
  107. *
  108. * Elements have context affinity. A single thread is allowed per context. This thread
  109. * is owned by the context. Only that thread may be allowed to access objects in its
  110. * context. This requirement is not enforced in this library. The caller application
  111. * must ensure access to objects in a context happens via the owned thread.
  112. *
  113. * A Proxy class is provided to invoke methods on objects from an out-of-context thread.
  114. *
  115. * The library supports multiple instances in the same process. This would happen by
  116. * linking the library to multiple process modules. The only restriction is a thread
  117. * must access a set of objects consistantly with the same instance of the library code.
  118. *
  119. */
  120. /*
  121. * Error Reporting
  122. *
  123. * Conditions that would affect the stability of DirectUI are reported. Some conditions are
  124. * only reported in Debug builds, and other in both Release and Debug
  125. *
  126. * Debug time reporting:
  127. * Erroneous states are reported in Debug (checked) builds. An erroneous state arises
  128. * when a programming error is found or when invalid arguments are passed to a method.
  129. * Erroneous states cause raising of asserts
  130. *
  131. * Release time reporting:
  132. * Abnormal states (such as out of memory or resources) that result in a serious condition
  133. * (crash or very irregular state) are reported via HRESULTs. Any DUI API that can fail due to
  134. * these types of abnormal states returns an HRESULT. If a method fails, it will recover.
  135. * Some methods (such as object creation methods) will recover by freeing any memory or
  136. * resources allocated within that method (resulting of a complete undo of all the work it
  137. * accomplished up to the point of the failure). Other methods (such as rendering and the defer
  138. * cycle) will do as much work as possible. Upon a failure, they will return an 'incomplete'
  139. * error, however, they would have not completed. Failures do not result in crashes or irregular
  140. * state. Failures are ignored in callbacks
  141. */
  142. typedef int (__cdecl *CompareCallback)(const void*, const void*);
  143. // Property indicies
  144. #define PI_Local 1
  145. #define PI_Specified 2
  146. #define PI_Computed 3
  147. // Property flags
  148. #define PF_LocalOnly 0x01
  149. #define PF_Normal 0x02
  150. #define PF_TriLevel 0x03
  151. #define PF_Cascade 0x04
  152. #define PF_Inherit 0x08
  153. #define PF_ReadOnly 0x10
  154. #define PF_TypeBits 0x03 // Map out for LocalOnly, Normal, or Trilevel
  155. // For use in OnPropertyChanged, mask out non-retrieval index property changes
  156. #define IsProp(p) ((p##Prop == ppi) && ((ppi->fFlags&PF_TypeBits) == iIndex))
  157. #define RetIdx(p) (p->fFlags&PF_TypeBits)
  158. // Property groups
  159. #define PG_AffectsDesiredSize 0x00000001 // Normal priority
  160. #define PG_AffectsParentDesiredSize 0x00000002
  161. #define PG_AffectsLayout 0x00000004
  162. #define PG_AffectsParentLayout 0x00000008
  163. #define PG_AffectsBounds 0x00010000 // Low priority
  164. #define PG_AffectsDisplay 0x00020000
  165. #define PG_NormalPriMask 0x0000FFFF
  166. #define PG_LowPriMask 0xFFFF0000
  167. // Layout cycle queue modes
  168. #define LC_Pass 0
  169. #define LC_Normal 1
  170. #define LC_Optimize 2
  171. // todo: get these from accessibility
  172. #define GA_NOTHANDLED ((Element*) -1)
  173. // to be internal
  174. #define NAV_LOGICAL 0x00000001 // unset == directional
  175. #define NAV_FORWARD 0x00000002 // unset == backward
  176. #define NAV_VERTICAL 0x00000004 // unset == horizontal
  177. #define NAV_RELATIVE 0x00000008 // unset == absolute
  178. // to be exposed
  179. #define NAV_FIRST (NAV_FORWARD | NAV_LOGICAL)
  180. #define NAV_LAST (NAV_LOGICAL)
  181. #define NAV_UP (NAV_RELATIVE | NAV_VERTICAL)
  182. #define NAV_DOWN (NAV_RELATIVE | NAV_VERTICAL | NAV_FORWARD)
  183. #define NAV_LEFT (NAV_RELATIVE)
  184. #define NAV_RIGHT (NAV_RELATIVE | NAV_FORWARD)
  185. #define NAV_NEXT (NAV_RELATIVE | NAV_FORWARD | NAV_LOGICAL)
  186. #define NAV_PREV (NAV_RELATIVE | NAV_LOGICAL)
  187. // to be exposed
  188. #define DIRECTION_LTR 0
  189. #define DIRECTION_RTL 1
  190. // Asynchronous destroy message (must be async to ensure outstanding
  191. // defer pointers are cleared)
  192. #define GM_DUIASYNCDESTROY GM_USER - 1
  193. ////////////////////////////////////////////////////////
  194. // PropertyInfo
  195. struct IClassInfo;
  196. struct EnumMap
  197. {
  198. LPCWSTR pszEnum;
  199. int nEnum;
  200. };
  201. struct PropertyInfo
  202. {
  203. WCHAR szName[81];
  204. int fFlags;
  205. int fGroups;
  206. int* pValidValues;
  207. EnumMap* pEnumMaps;
  208. Value* pvDefault;
  209. int _iIndex; // Class-wide unique id (zero-based consecutive, set by ClassInfo)
  210. int _iGlobalIndex; // Process-wide unique id (zero-based consecutive, set by ClassInfo (manually set for Element))
  211. IClassInfo* _pciOwner; // Class that this property is defined on (direct owner, not inherited-by)
  212. };
  213. class Element;
  214. ////////////////////////////////////////////////////////
  215. // UpdateCache
  216. struct UpdateCache
  217. {
  218. Element* peSrc;
  219. PropertyInfo* ppiSrc;
  220. int iIndexSrc;
  221. Value* pvOldSrc;
  222. Value* pvNewSrc;
  223. };
  224. ////////////////////////////////////////////////////////
  225. // Dependencies
  226. struct Dependency
  227. {
  228. Element* pe;
  229. PropertyInfo* ppi;
  230. int iIndex;
  231. };
  232. // Track dependency records in PC list
  233. struct DepRecs
  234. {
  235. int iDepPos;
  236. int cDepCnt;
  237. };
  238. struct NavReference
  239. {
  240. void Init(Element* pe, RECT* prc);
  241. UINT cbSize;
  242. Element* pe;
  243. RECT* prc;
  244. };
  245. ////////////////////////////////////////////////////////
  246. // Class information interface
  247. // Used so that a class will not be linked out if a class is not referred to
  248. // (and is only referred by the parser)
  249. #define UsingDUIClass(classn) static IClassInfo* _DUI__pCI##classn = ##classn::Class
  250. struct IClassInfo
  251. {
  252. virtual HRESULT CreateInstance(OUT Element** ppElement) = 0;
  253. virtual PropertyInfo* EnumPropertyInfo(UINT nEnum) = 0; // Includes base classes
  254. virtual UINT GetPICount() = 0; // Includes base classes
  255. virtual UINT GetGlobalIndex() = 0;
  256. virtual IClassInfo* GetBaseClass() = 0;
  257. virtual LPCWSTR GetName() = 0;
  258. virtual bool IsValidProperty(PropertyInfo* ppi) = 0;
  259. virtual bool IsSubclassOf(IClassInfo* pci) = 0;
  260. virtual void Destroy() = 0;
  261. };
  262. ////////////////////////////////////////////////////////
  263. // Element Listener interface
  264. struct IElementListener
  265. {
  266. virtual void OnListenerAttach(Element* peFrom) = 0;
  267. virtual void OnListenerDetach(Element* peFrom) = 0;
  268. virtual bool OnListenedPropertyChanging(Element* peFrom, PropertyInfo* ppi, int iIndex, Value* pvOld, Value* pvNew) = 0;
  269. virtual void OnListenedPropertyChanged(Element* peFrom, PropertyInfo* ppi, int iIndex, Value* pvOld, Value* pvNew) = 0;
  270. virtual void OnListenedInput(Element* peFrom, InputEvent* pInput) = 0;
  271. virtual void OnListenedEvent(Element* peFrom, Event* pEvent) = 0;
  272. };
  273. #if DBG
  274. ////////////////////////////////////////////////////////
  275. // Track "owner" context of this instance to validation that threads that don't
  276. // belong to the context don't access the object.
  277. //
  278. // For side-by-side library support, also store the TLS slot of the instance
  279. // of the library in the process that created this object. This will ensure the
  280. // thread is using the correct library instance to access the object.
  281. struct Owner
  282. {
  283. HDCONTEXT hCtx;
  284. DWORD dwTLSSlot;
  285. };
  286. #endif
  287. ////////////////////////////////////////////////////////
  288. // Element
  289. typedef DynamicArray<Element*> ElementList;
  290. class DeferCycle;
  291. struct PCRecord;
  292. #define EC_NoGadgetCreate 0x1 // Do not create DisplayNode, must be created within constructor override
  293. #define EC_SelfLayout 0x2 // Element will lay out children (via self layout callbacks)
  294. class Element
  295. {
  296. public:
  297. ////////////////////////////////////////////////////////
  298. // Construction / destruction
  299. static HRESULT Create(UINT nCreate, OUT Element** ppe);
  300. HRESULT Destroy(bool fDelayed = true); // Destroy self
  301. HRESULT DestroyAll(); // Destroy all children
  302. Element() { }
  303. virtual ~Element();
  304. HRESULT Initialize(UINT nCreate);
  305. ////////////////////////////////////////////////////////
  306. // Properties (impl in property.cpp)
  307. // Accessors
  308. Value* GetValue(PropertyInfo* ppi, int iIndex, UpdateCache* puc = NULL);
  309. HRESULT SetValue(PropertyInfo* ppi, int iIndex, Value* pv);
  310. // Additional property methods
  311. HRESULT RemoveLocalValue(PropertyInfo* ppi);
  312. // Deferring
  313. static void StartDefer();
  314. static void EndDefer();
  315. // Checks
  316. inline bool IsValidAccessor(PropertyInfo* ppi, int iIndex, bool bSetting);
  317. static bool IsValidValue(PropertyInfo* ppi, Value* pv);
  318. bool IsRTL() { return (GetDirection() == DIRECTION_RTL);}
  319. // System event callbacks
  320. virtual bool OnPropertyChanging(PropertyInfo* ppi, int iIndex, Value* pvOld, Value* pvNew); // Direct
  321. virtual void OnPropertyChanged(PropertyInfo* ppi, int iIndex, Value* pvOld, Value* pvNew); // Direct
  322. virtual void OnGroupChanged(int fGroups, bool bLowPri); // Direct
  323. virtual void OnInput(InputEvent* pInput); // Direct and bubbled
  324. virtual void OnKeyFocusMoved(Element* peFrom, Element* peTo); // Direct and bubbled
  325. virtual void OnMouseFocusMoved(Element* peFrom, Element* peTo); // Direct and bubbled
  326. virtual void OnDestroy(); // Direct
  327. // ContainerCleanup: OnLoadedFromResource(dictionary)
  328. // Generic eventing and callback (pointer is only guaranteed good for the lifetime of the call)
  329. void FireEvent(Event* pEvent, bool fFull = true);
  330. virtual void OnEvent(Event* pEvent);
  331. // Rendering callbacks
  332. virtual void Paint(HDC hDC, const RECT* prcBounds, const RECT* prcInvalid, RECT* prcSkipBorder, RECT* prcSkipContent);
  333. #ifdef GADGET_ENABLE_GDIPLUS
  334. virtual void Paint(Gdiplus::Graphics* pgpgr, const Gdiplus::RectF* prcBounds, const Gdiplus::RectF* prcInvalid, Gdiplus::RectF* prSkipBorder, Gdiplus::RectF* prSkipContent);
  335. #endif
  336. virtual SIZE GetContentSize(int dConstW, int dConstH, Surface* psrf);
  337. float GetTreeAlphaLevel();
  338. // Hierarchy
  339. HRESULT Add(Element* pe);
  340. virtual HRESULT Add(Element** ppe, UINT cCount);
  341. HRESULT Insert(Element* pe, UINT iInsertIdx);
  342. virtual HRESULT Insert(Element** ppe, UINT cCount, UINT iInsertIdx);
  343. HRESULT Add(Element* pe, CompareCallback lpfnCompare);
  344. HRESULT SortChildren(CompareCallback lpfnCompare);
  345. HRESULT Remove(Element* peFrom);
  346. HRESULT RemoveAll();
  347. virtual HRESULT Remove(Element** ppe, UINT cCount);
  348. // Mapping and navigation
  349. Element* FindDescendent(ATOM atomID);
  350. void MapElementPoint(Element* peFrom, const POINT* pptFrom, POINT* pptTo);
  351. Element* GetImmediateChild(Element* peFrom);
  352. bool IsDescendent(Element* pe);
  353. virtual Element* GetAdjacent(Element* peFrom, int iNavDir, NavReference const* pnr, bool bKeyable);
  354. Element* GetKeyWithinChild();
  355. Element* GetMouseWithinChild();
  356. bool EnsureVisible();
  357. bool EnsureVisible(UINT uChild);
  358. virtual bool EnsureVisible(int x, int y, int cx, int cy);
  359. virtual void SetKeyFocus();
  360. // Element Listeners
  361. HRESULT AddListener(IElementListener* pel);
  362. void RemoveListener(IElementListener* pel);
  363. // Effects, animate display node to match current Element state
  364. void InvokeAnimation(int dAni, UINT nTypeMask);
  365. void InvokeAnimation(UINT nTypes, UINT nInterpol, float flDuration, float flDelay, bool fPushToChildren = false);
  366. void StopAnimation(UINT nTypes);
  367. // Display node callback extension
  368. virtual UINT MessageCallback(GMSG* pGMsg);
  369. // Internal defer cycle and Layout-only callbacks
  370. SIZE _UpdateDesiredSize(int dConstW, int dConstH, Surface* psrf);
  371. void _UpdateLayoutPosition(int dX, int dY);
  372. void _UpdateLayoutSize(int dWidth, int dHeight);
  373. // Use in DoLayout on children where one or more properties will be changed which will
  374. // cause a Layout GPC to be queued. This will cancel the layout GPCs and force the child
  375. // to be included in the current layout cycle
  376. void _StartOptimizedLayoutQ() { DUIAssertNoMsg(_fBit.fNeedsLayout != LC_Optimize); _fBit.fNeedsLayout = LC_Optimize; }
  377. void _EndOptimizedLayoutQ() { _fBit.fNeedsLayout = LC_Normal; }
  378. // Internal defer cycle and PropertySheet-only callbacks
  379. static void _AddDependency(Element* pe, PropertyInfo* ppi, int iIndex, DepRecs* pdr, DeferCycle* pdc, HRESULT* phr);
  380. // Internal DirectUser interop
  381. static HRESULT CALLBACK _DisplayNodeCallback(HGADGET hgadCur, void * pvCur, EventMsg * pGMsg);
  382. // Internal IUnknown interface impl
  383. long __stdcall QueryInterface(REFIID iid, void** pvObj) { UNREFERENCED_PARAMETER(iid); UNREFERENCED_PARAMETER(pvObj); return E_NOTIMPL; }
  384. ULONG __stdcall AddRef() { return 1; }
  385. ULONG __stdcall Release() { return 1; }
  386. private:
  387. // Value update
  388. HRESULT _GetDependencies(PropertyInfo* ppi, int iIndex, DepRecs* pdr, int iPCSrcRoot, DeferCycle* pdc);
  389. static void _VoidPCNotifyTree(int iPCPos, DeferCycle* pdc);
  390. // Defer cycle
  391. static void _FlushDS(Element* pe, DeferCycle* pdc);
  392. static void _FlushLayout(Element* pe, DeferCycle* pdc);
  393. // Value Update
  394. HRESULT _PreSourceChange(PropertyInfo* ppi, int iIndex, Value* pvOld, Value* pvNew);
  395. HRESULT _PostSourceChange();
  396. protected:
  397. // EC_SelfLayout flag at creation activates these methods. No external layouts are used for layout,
  398. // rather, Element is responsible for layout (use when layout is specific and hierarchy is known)
  399. virtual void _SelfLayoutDoLayout(int dWidth, int dHeight);
  400. virtual SIZE _SelfLayoutUpdateDesiredSize(int dConstW, int dConstH, Surface* psrf);
  401. // Internal Set and Remove
  402. HRESULT _SetValue(PropertyInfo* ppi, int iIndex, Value* pv, bool fInternalCall = true);
  403. HRESULT _RemoveLocalValue(PropertyInfo* ppi, bool fInternalCall = true);
  404. // Natvie hosting system event callbacks and retrieval
  405. virtual void OnHosted(Element* peNewHost); // Direct
  406. virtual void OnUnHosted(Element* peOldHost); // Direct
  407. void MarkHosted() { _fBit.bHosted = true; }
  408. public:
  409. inline void DoubleBuffered(bool fEnabled = true)
  410. {
  411. if (_hgDisplayNode)
  412. SetGadgetStyle(_hgDisplayNode, (fEnabled) ? GS_BUFFERED : 0, GS_BUFFERED);
  413. }
  414. inline BOOL IsRoot()
  415. {
  416. return IsHosted() && (GetParent() == NULL);
  417. }
  418. // Return if being hosted by a native root
  419. inline Element* GetRoot()
  420. {
  421. if (!IsHosted())
  422. return NULL;
  423. Element * peCur = this;
  424. while (peCur->GetParent() != NULL)
  425. {
  426. peCur = peCur->GetParent();
  427. }
  428. return peCur;
  429. }
  430. static BTreeLookup<IClassInfo*>* pciMap;
  431. // Event types
  432. static UID KeyboardNavigate;
  433. // Property definitions
  434. static PropertyInfo* ParentProp; // 00
  435. static PropertyInfo* ChildrenProp; // 01
  436. static PropertyInfo* VisibleProp; // 02
  437. static PropertyInfo* WidthProp; // 03
  438. static PropertyInfo* HeightProp; // 04
  439. static PropertyInfo* LocationProp; // 05
  440. static PropertyInfo* ExtentProp; // 06
  441. static PropertyInfo* XProp; // 07
  442. static PropertyInfo* YProp; // 08
  443. static PropertyInfo* PosInLayoutProp; // 09
  444. static PropertyInfo* SizeInLayoutProp; // 10
  445. static PropertyInfo* DesiredSizeProp; // 11
  446. static PropertyInfo* LastDSConstProp; // 12
  447. static PropertyInfo* LayoutProp; // 13
  448. static PropertyInfo* LayoutPosProp; // 14
  449. static PropertyInfo* BorderThicknessProp; // 15
  450. static PropertyInfo* BorderStyleProp; // 16
  451. static PropertyInfo* BorderColorProp; // 17
  452. static PropertyInfo* PaddingProp; // 18
  453. static PropertyInfo* MarginProp; // 19
  454. static PropertyInfo* ForegroundProp; // 20
  455. static PropertyInfo* BackgroundProp; // 21
  456. static PropertyInfo* ContentProp; // 22
  457. static PropertyInfo* FontFaceProp; // 23
  458. static PropertyInfo* FontSizeProp; // 24
  459. static PropertyInfo* FontWeightProp; // 25
  460. static PropertyInfo* FontStyleProp; // 26
  461. static PropertyInfo* ActiveProp; // 27
  462. static PropertyInfo* ContentAlignProp; // 28
  463. static PropertyInfo* KeyFocusedProp; // 29
  464. static PropertyInfo* KeyWithinProp; // 30
  465. static PropertyInfo* MouseFocusedProp; // 31
  466. static PropertyInfo* MouseWithinProp; // 32
  467. static PropertyInfo* ClassProp; // 33
  468. static PropertyInfo* IDProp; // 34
  469. static PropertyInfo* SheetProp; // 35
  470. static PropertyInfo* SelectedProp; // 36
  471. static PropertyInfo* AlphaProp; // 37
  472. static PropertyInfo* AnimationProp; // 38
  473. static PropertyInfo* CursorProp; // 39
  474. static PropertyInfo* DirectionProp; // 40
  475. static PropertyInfo* AccessibleProp; // 41
  476. static PropertyInfo* AccRoleProp; // 42
  477. static PropertyInfo* AccStateProp; // 43
  478. static PropertyInfo* AccNameProp; // 44
  479. static PropertyInfo* AccDescProp; // 45
  480. static PropertyInfo* AccValueProp; // 46
  481. static PropertyInfo* AccDefActionProp; // 47
  482. static PropertyInfo* ShortcutProp; // 48
  483. static PropertyInfo* EnabledProp; // 49
  484. #if DBG
  485. Owner owner;
  486. #endif
  487. protected:
  488. HGADGET _hgDisplayNode;
  489. private:
  490. int _iIndex;
  491. BTreeLookup<Value*>* _pvmLocal;
  492. int _iGCSlot;
  493. int _iGCLPSlot;
  494. int _iPCTail;
  495. IElementListener** _ppel;
  496. // All "cached" values are caching resulting values from the Specified and Computed IVEs.
  497. // All local (loc) values are for ReadOnly properties. These values are updated directly
  498. // since it is not required to go generically through SetValue because they are ReadOnly.
  499. // They are used often or are cheap to store (bools), so they do not use generic
  500. // storage (via _SetValue).
  501. // Cached and local values
  502. Element* _peLocParent; // Parent local
  503. POINT _ptLocPosInLayt; // Position in layout local
  504. SIZE _sizeLocSizeInLayt; // Size in layout local
  505. SIZE _sizeLocLastDSConst; // Last desired size constraint local
  506. SIZE _sizeLocDesiredSize; // Desired size local
  507. int _dSpecLayoutPos; // Cached layout position
  508. Value* _pvSpecSheet; // Cached property sheet specified (Value cached due to destruction)
  509. ATOM _atomSpecID; // Cached id specified
  510. int _dSpecAlpha; // Cached alpha value
  511. struct _BitMap
  512. {
  513. // Local values
  514. bool bLocKeyWithin : 1; // 0 Keyboard within local
  515. bool bLocMouseWithin : 1; // 1 Mouse within local
  516. // Direct VE cache
  517. bool bCmpVisible : 1; // 2 Cached visible computed
  518. bool bSpecVisible : 1; // 3 Cached visible specified
  519. UINT fSpecActive : 2; // 4 Cached active state specified
  520. bool bSpecSelected : 1; // 5 Cached selected state specified
  521. bool bSpecKeyFocused : 1; // 6 Cached keyboard focused state specified
  522. bool bSpecMouseFocused : 1; // 7 Cached mouse focused state specified
  523. UINT nSpecDirection : 1; // 8 Cached direction specified
  524. bool bSpecAccessible : 1; // 9 Cached accessible specified
  525. bool bSpecEnabled : 1; // 10 Cached enabled specified
  526. // Indirect VE cache (cache if default value)
  527. bool bHasChildren : 1; // 11 Cached children state (likely to be default value, no full cache)
  528. bool bHasLayout : 1; // 12 Cached layout state (likely to be default value, no full cache)
  529. bool bHasBorder : 1; // 13 Cached border state (likely to be default value, no full cache)
  530. bool bHasPadding : 1; // 14 Cached padding state (likely to be default value, no full cache)
  531. bool bHasMargin : 1; // 15 Cached margin state (likely to be default value, no full cache)
  532. bool bHasContent : 1; // 16 Cached content state (likely to be default value, no full cache)
  533. bool bDefaultCAlign : 1; // 17 Cached content align state (likely to be default value, no full cache)
  534. bool bWordWrap : 1; // 18 Cached content align state (likely to be default value, no full cache)
  535. bool bHasAnimation : 1; // 19 Cached animation state (likely to be default value, no full cache)
  536. bool bDefaultCursor : 1; // 20 Cached cursor state (likely to be default value, no full cache)
  537. bool bDefaultBorderColor : 1; // 21 Cached border color state (likely to be default value, no full cache)
  538. bool bDefaultForeground : 1; // 22 Cached foreground state (likely to be default value, no full cache)
  539. bool bDefaultFontWeight : 1; // 23 Cached font weight state (likely to be default value, no full cache)
  540. bool bDefaultFontStyle : 1; // 24 Cached font style state (likely to be default value, no full cache)
  541. // Layout and UDS flags
  542. bool bSelfLayout : 1; // 25 Element is laying out itself (callbacks active, external layout set is undefined)
  543. bool bNeedsDSUpdate : 1; // 26
  544. UINT fNeedsLayout : 2; // 27
  545. // Lifetime flags
  546. bool bDestroyed : 1; // 28
  547. // Hosting flags
  548. bool bHosted : 1; // 29 Initially set by host Element directly
  549. } _fBit;
  550. public:
  551. // Element DisplayNode and Index access
  552. HGADGET GetDisplayNode() { return _hgDisplayNode; }
  553. int GetIndex() { return _iIndex; }
  554. bool IsDestroyed() { return _fBit.bDestroyed; }
  555. bool IsHosted() { return _fBit.bHosted; }
  556. // Cache state for faster property value lookup
  557. bool IsSelfLayout() { return _fBit.bSelfLayout; }
  558. bool HasChildren() { return _fBit.bHasChildren; } // Quick check before doing lookup
  559. bool HasLayout() { return _fBit.bHasLayout; } // Quick check before doing lookup
  560. bool HasBorder() { return _fBit.bHasBorder; } // Quick check before doing lookup
  561. bool HasPadding() { return _fBit.bHasPadding; } // Quick check before doing lookup
  562. bool HasMargin() { return _fBit.bHasMargin; } // Quick check before doing lookup
  563. bool HasContent() { return _fBit.bHasContent; } // Quick check before doing lookup
  564. bool IsDefaultCAlign() { return _fBit.bDefaultCAlign; } // Quick check before doing lookup
  565. bool IsWordWrap() { return _fBit.bWordWrap; } // Quick check before doing lookup
  566. bool HasAnimation() { return _fBit.bHasAnimation; } // Quick check before doing lookup
  567. bool IsDefaultCursor() { return _fBit.bDefaultCursor; } // Quick check before doing lookup
  568. // Quick property accessors (since system has knowledge of its unchangable value expressions, use cached values
  569. // directly were possible to bypass GetValue value lookup). Quick accessors are only used during non-cache
  570. // gets. (PostSourceChange requires GetValue directly (with update-cache flag) for cache updates.)
  571. // All derived classes do accessors normally (no direct cache lookups)
  572. #define DUIQuickGetter(t, gv, p, i) { Value* pv; t v = (pv = GetValue(p##Prop, PI_##i))->gv; pv->Release(); return v; }
  573. #define DUIQuickGetterInd(gv, p, i) { return (*ppv = GetValue(p##Prop, PI_##i))->gv; }
  574. #define DUIQuickSetter(cv, p) { Value* pv = Value::cv; if (!pv) return E_OUTOFMEMORY; HRESULT hr = SetValue(p##Prop, PI_Local, pv); pv->Release(); return hr; }
  575. Element* GetParent() { return _peLocParent; }
  576. bool GetVisible() { return _fBit.bCmpVisible; }
  577. int GetWidth() DUIQuickGetter(int, GetInt(), Width, Specified)
  578. int GetHeight() DUIQuickGetter(int, GetInt(), Height, Specified)
  579. ElementList* GetChildren(Value** ppv) { return (*ppv = (HasChildren() ? GetValue(ChildrenProp, PI_Specified) : ChildrenProp->pvDefault))->GetElementList(); }
  580. int GetX() DUIQuickGetter(int, GetInt(), X, Specified)
  581. int GetY() DUIQuickGetter(int, GetInt(), Y, Specified)
  582. Layout* GetLayout(Value** ppv) { return (*ppv = (HasLayout() ? GetValue(LayoutProp, PI_Specified) : LayoutProp->pvDefault))->GetLayout(); }
  583. int GetLayoutPos() { return _dSpecLayoutPos; }
  584. const RECT* GetBorderThickness(Value** ppv) { return (*ppv = (HasBorder() ? GetValue(BorderThicknessProp, PI_Specified) : BorderThicknessProp->pvDefault))->GetRect(); }
  585. int GetBorderStyle() DUIQuickGetter(int, GetInt(), BorderStyle, Specified)
  586. int GetBorderStdColor() DUIQuickGetter(int, GetInt(), BorderColor, Specified)
  587. const Fill* GetBorderColor(Value** ppv) DUIQuickGetterInd(GetFill(), BorderColor, Specified)
  588. const RECT* GetPadding(Value** ppv) { return (*ppv = (HasPadding() ? GetValue(PaddingProp, PI_Specified) : PaddingProp->pvDefault))->GetRect(); }
  589. const RECT* GetMargin(Value** ppv) { return (*ppv = (HasMargin() ? GetValue(MarginProp, PI_Specified) : MarginProp->pvDefault))->GetRect(); }
  590. const POINT* GetLocation(Value** ppv) DUIQuickGetterInd(GetPoint(), Location, Local)
  591. const SIZE* GetExtent(Value** ppv) DUIQuickGetterInd(GetSize(), Extent, Local)
  592. const SIZE* GetDesiredSize() { return &_sizeLocDesiredSize; }
  593. int GetForegroundStdColor() DUIQuickGetter(int, GetInt(), Foreground, Specified)
  594. const Fill* GetForegroundColor(Value** ppv) DUIQuickGetterInd(GetFill(), Foreground, Specified)
  595. int GetBackgroundStdColor() DUIQuickGetter(int, GetInt(), Background, Specified)
  596. const LPWSTR GetContentString(Value** ppv) { return (*ppv = (HasContent() ? GetValue(ContentProp, PI_Specified) : Value::pvStringNull))->GetString(); }
  597. const LPWSTR GetFontFace(Value** ppv) DUIQuickGetterInd(GetString(), FontFace, Specified)
  598. int GetFontSize() DUIQuickGetter(int, GetInt(), FontSize, Specified)
  599. int GetFontWeight() DUIQuickGetter(int, GetInt(), FontWeight, Specified)
  600. int GetFontStyle() DUIQuickGetter(int, GetInt(), FontStyle, Specified)
  601. int GetActive() { return _fBit.fSpecActive; }
  602. int GetContentAlign() { Value* pv; int v = (pv = (!IsDefaultCAlign() ? GetValue(ContentAlignProp, PI_Specified) : Value::pvIntZero))->GetInt(); pv->Release(); return v; }
  603. bool GetKeyFocused() { return _fBit.bSpecKeyFocused; }
  604. bool GetKeyWithin() { return _fBit.bLocKeyWithin; }
  605. bool GetMouseFocused() { return _fBit.bSpecMouseFocused; }
  606. bool GetMouseWithin() { return _fBit.bLocMouseWithin; }
  607. const LPWSTR GetClass(Value** ppv) DUIQuickGetterInd(GetString(), Class, Specified)
  608. ATOM GetID() { return _atomSpecID; }
  609. PropertySheet* GetSheet() { return _pvSpecSheet->GetPropertySheet(); }
  610. bool GetSelected() { return _fBit.bSpecSelected; }
  611. int GetAlpha() { return _dSpecAlpha; }
  612. int GetAnimation() DUIQuickGetter(int, GetInt(), Animation, Specified)
  613. int GetDirection() DUIQuickGetter(int, GetInt(), Direction, Specified)
  614. bool GetAccessible() { return _fBit.bSpecAccessible; }
  615. int GetAccRole() DUIQuickGetter(int, GetInt(), AccRole, Specified)
  616. int GetAccState() DUIQuickGetter(int, GetInt(), AccState, Specified)
  617. const LPWSTR GetAccName(Value** ppv) DUIQuickGetterInd(GetString(), AccName, Specified)
  618. const LPWSTR GetAccDesc(Value** ppv) DUIQuickGetterInd(GetString(), AccDesc, Specified)
  619. const LPWSTR GetAccValue(Value** ppv) DUIQuickGetterInd(GetString(), AccValue, Specified)
  620. const LPWSTR GetAccDefAction(Value** ppv) DUIQuickGetterInd(GetString(), AccDefAction, Specified)
  621. int GetShortcut() DUIQuickGetter(int, GetInt(), Shortcut, Specified)
  622. bool GetEnabled() { return _fBit.bSpecEnabled; }
  623. HRESULT SetVisible(bool v) DUIQuickSetter(CreateBool(v), Visible)
  624. HRESULT SetWidth(int v) DUIQuickSetter(CreateInt(v), Width)
  625. HRESULT SetHeight(int v) DUIQuickSetter(CreateInt(v), Height)
  626. HRESULT SetX(int v) DUIQuickSetter(CreateInt(v), X)
  627. HRESULT SetY(int v) DUIQuickSetter(CreateInt(v), Y)
  628. HRESULT SetLayout(Layout* v) DUIQuickSetter(CreateLayout(v), Layout)
  629. HRESULT SetLayoutPos(int v) DUIQuickSetter(CreateInt(v), LayoutPos)
  630. HRESULT SetBorderThickness(int l, int t, int r, int b) DUIQuickSetter(CreateRect(l, t, r, b), BorderThickness)
  631. HRESULT SetBorderStyle(int v) DUIQuickSetter(CreateInt(v), BorderStyle)
  632. HRESULT SetBorderStdColor(int v) DUIQuickSetter(CreateInt(v), BorderColor)
  633. HRESULT SetBorderColor(COLORREF cr) DUIQuickSetter(CreateColor(cr), BorderColor)
  634. HRESULT SetBorderGradientColor(COLORREF cr0,
  635. COLORREF cr1, BYTE dType = FILLTYPE_HGradient) DUIQuickSetter(CreateColor(cr0, cr1, dType), BorderColor)
  636. HRESULT SetPadding(int l, int t, int r, int b) DUIQuickSetter(CreateRect(l, t, r, b), Padding)
  637. HRESULT SetMargin(int l, int t, int r, int b) DUIQuickSetter(CreateRect(l, t, r, b), Margin)
  638. HRESULT SetForegroundStdColor(int v) DUIQuickSetter(CreateInt(v), Foreground)
  639. HRESULT SetForegroundColor(COLORREF cr) DUIQuickSetter(CreateColor(cr), Foreground)
  640. HRESULT SetForegroundColor(COLORREF cr0, COLORREF cr1,
  641. BYTE dType = FILLTYPE_HGradient) DUIQuickSetter(CreateColor(cr0, cr1, dType), Foreground)
  642. HRESULT SetForegroundColor(COLORREF cr0, COLORREF cr1, COLORREF cr2,
  643. BYTE dType = FILLTYPE_TriHGradient) DUIQuickSetter(CreateColor(cr0, cr1, cr2, dType), Foreground)
  644. HRESULT SetBackgroundStdColor(int v) DUIQuickSetter(CreateInt(v), Background)
  645. HRESULT SetBackgroundColor(COLORREF cr) DUIQuickSetter(CreateColor(cr), Background)
  646. HRESULT SetBackgroundColor(COLORREF cr0, COLORREF cr1,
  647. BYTE dType = FILLTYPE_HGradient) DUIQuickSetter(CreateColor(cr0, cr1, dType), Background)
  648. HRESULT SetBackgroundColor(COLORREF cr0, COLORREF cr1, COLORREF cr2,
  649. BYTE dType = FILLTYPE_TriHGradient) DUIQuickSetter(CreateColor(cr0, cr1, cr2, dType), Background)
  650. HRESULT SetContentString(LPCWSTR v) DUIQuickSetter(CreateString(v), Content)
  651. HRESULT SetContentGraphic(LPCWSTR v,
  652. BYTE dBlendMode = GRAPHIC_NoBlend,
  653. UINT dBlendValue = 0) DUIQuickSetter(CreateGraphic(v, dBlendMode, dBlendValue), Content)
  654. HRESULT SetContentGraphic(LPCWSTR v, USHORT cxDesired,
  655. USHORT cyDesired) DUIQuickSetter(CreateGraphic(v, cxDesired, cyDesired), Content)
  656. HRESULT SetFontFace(LPCWSTR v) DUIQuickSetter(CreateString(v), FontFace)
  657. HRESULT SetFontSize(int v) DUIQuickSetter(CreateInt(v), FontSize)
  658. HRESULT SetFontWeight(int v) DUIQuickSetter(CreateInt(v), FontWeight)
  659. HRESULT SetFontStyle(int v) DUIQuickSetter(CreateInt(v), FontStyle)
  660. HRESULT SetActive(int v) DUIQuickSetter(CreateInt(v), Active)
  661. HRESULT SetContentAlign(int v) DUIQuickSetter(CreateInt(v), ContentAlign)
  662. HRESULT SetClass(LPCWSTR v) DUIQuickSetter(CreateString(v), Class)
  663. HRESULT SetID(LPCWSTR v) DUIQuickSetter(CreateAtom(v), ID)
  664. HRESULT SetSheet(PropertySheet* v) DUIQuickSetter(CreatePropertySheet(v), Sheet)
  665. HRESULT SetSelected(bool v) DUIQuickSetter(CreateBool(v), Selected)
  666. HRESULT SetAlpha(int v) DUIQuickSetter(CreateInt(v), Alpha)
  667. HRESULT SetAnimation(int v) DUIQuickSetter(CreateInt(v), Animation)
  668. HRESULT SetStdCursor(int v) DUIQuickSetter(CreateInt(v), Cursor)
  669. HRESULT SetCursor(LPCWSTR v) DUIQuickSetter(CreateCursor(v), Cursor)
  670. HRESULT SetDirection(int v) DUIQuickSetter(CreateInt(v), Direction)
  671. HRESULT SetAccessible(bool v) DUIQuickSetter(CreateBool(v), Accessible)
  672. HRESULT SetAccRole(int v) DUIQuickSetter(CreateInt(v), AccRole)
  673. HRESULT SetAccState(int v) DUIQuickSetter(CreateInt(v), AccState)
  674. HRESULT SetAccName(LPCWSTR v) DUIQuickSetter(CreateString(v), AccName)
  675. HRESULT SetAccDesc(LPCWSTR v) DUIQuickSetter(CreateString(v), AccDesc)
  676. HRESULT SetAccValue(LPCWSTR v) DUIQuickSetter(CreateString(v), AccValue)
  677. HRESULT SetAccDefAction(LPCWSTR v) DUIQuickSetter(CreateString(v), AccDefAction)
  678. HRESULT SetShortcut(int v) DUIQuickSetter(CreateInt(v), Shortcut)
  679. HRESULT SetEnabled(bool v) DUIQuickSetter(CreateBool(v), Enabled)
  680. ////////////////////////////////////////////////////////
  681. // ClassInfo accessors (static and virtual instance-based)
  682. static IClassInfo* Class;
  683. virtual IClassInfo* GetClassInfo() { return Class; }
  684. static HRESULT Register();
  685. ///////////////////////////////////////////////////////
  686. // Accessibility support
  687. DuiAccessible * _pDuiAccessible;
  688. virtual HRESULT GetAccessibleImpl(IAccessible ** ppAccessible);
  689. HRESULT QueueDefaultAction();
  690. virtual HRESULT DefaultAction();
  691. };
  692. ////////////////////////////////////////////////////////
  693. // Element helpers
  694. Element* ElementFromGadget(HGADGET hGadget);
  695. void QueryDetails(Element* pe, HWND hParent);
  696. ////////////////////////////////////////////////////////
  697. // DeferCycle: Per-thread deferring information
  698. // Group notifications: deferred until EndDefer and coalesced
  699. struct GCRecord
  700. {
  701. Element* pe;
  702. int fGroups;
  703. };
  704. // Property notifications: deferred until source's dependency
  705. // graph is searched (within SetValue call), not coalesced
  706. struct PCRecord
  707. {
  708. bool fVoid;
  709. Element* pe;
  710. PropertyInfo* ppi;
  711. int iIndex;
  712. Value* pvOld;
  713. Value* pvNew;
  714. DepRecs dr;
  715. int iPrevElRec;
  716. };
  717. class DeferCycle
  718. {
  719. public:
  720. static HRESULT Create(DeferCycle** ppDC);
  721. void Destroy() { HDelete<DeferCycle>(this); }
  722. void Reset();
  723. DynamicArray<GCRecord>* pdaGC; // Group changed database
  724. DynamicArray<GCRecord>* pdaGCLP; // Low priority group changed database
  725. DynamicArray<PCRecord>* pdaPC; // Property changed database
  726. ValueMap<Element*,BYTE>* pvmLayoutRoot; // Layout trees pending
  727. ValueMap<Element*,BYTE>* pvmUpdateDSRoot; // Update desired size trees pending
  728. int cEnter;
  729. bool fFiring;
  730. int iGCPtr;
  731. int iGCLPPtr;
  732. int iPCPtr;
  733. int iPCSSUpdate;
  734. int cPCEnter;
  735. DeferCycle() { }
  736. HRESULT Initialize();
  737. virtual ~DeferCycle();
  738. };
  739. #if DBG
  740. // Process-wide element count
  741. extern LONG g_cElement;
  742. #endif
  743. // Per-thread Element slot
  744. extern DWORD g_dwElSlot;
  745. struct ElTls
  746. {
  747. HDCONTEXT hCtx; // DirectUser thread context
  748. int cRef;
  749. SBAlloc* psba;
  750. DeferCycle* pdc;
  751. FontCache* pfc;
  752. bool fCoInitialized;
  753. int dEnableAnimations;
  754. #if DBG
  755. int cDNCBEnter; // Track when _DisplayNodeCallback is entered
  756. #endif
  757. };
  758. /////////////////////////////////////////////////////////////////////////////
  759. // Per-Context object access
  760. inline bool IsAnimationsEnabled()
  761. {
  762. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  763. if (!petls)
  764. return false;
  765. return (petls->dEnableAnimations == 0);
  766. }
  767. inline void EnableAnimations()
  768. {
  769. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  770. if (!petls)
  771. return;
  772. petls->dEnableAnimations++;
  773. }
  774. inline void DisableAnimations()
  775. {
  776. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  777. if (!petls)
  778. return;
  779. petls->dEnableAnimations--;
  780. }
  781. inline HDCONTEXT GetContext()
  782. {
  783. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  784. if (!petls)
  785. return NULL;
  786. return petls->hCtx;
  787. }
  788. inline DeferCycle* GetDeferObject()
  789. {
  790. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  791. if (!petls)
  792. return NULL;
  793. return petls->pdc;
  794. }
  795. inline FontCache* GetFontCache()
  796. {
  797. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  798. if (!petls)
  799. return NULL;
  800. return petls->pfc;
  801. }
  802. inline SBAlloc* GetSBAllocator()
  803. {
  804. #if 0
  805. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  806. if (!petls)
  807. return NULL;
  808. return petls->psba;
  809. #else
  810. ElTls* petls = (ElTls*)TlsGetValue(g_dwElSlot);
  811. DUIAssert(petls != NULL, "Must have valid SBAllocator");
  812. return petls->psba;
  813. #endif
  814. }
  815. // Use to check if Element may be accessed via the current thread
  816. #if DBG
  817. inline void ContextCheck(Element* pe)
  818. {
  819. DUIAssert(pe->owner.dwTLSSlot == g_dwElSlot, "Element being accessed out of side-by-side instance");
  820. DUIAssert(pe->owner.hCtx == GetContext(), "Element being accessed out of context");
  821. }
  822. #define DUIContextAssert(pe) ContextCheck(pe)
  823. #else
  824. #define DUIContextAssert(pe)
  825. #endif
  826. ////////////////////////////////////////////////////////
  827. // Property enumerations
  828. // ActiveProp
  829. #define AE_Inactive 0x00000000
  830. #define AE_Mouse 0x00000001
  831. #define AE_Keyboard 0x00000002
  832. #define AE_MouseAndKeyboard (AE_Mouse | AE_Keyboard)
  833. // BorderStyleProp
  834. #define BDS_Solid 0
  835. #define BDS_Raised 1
  836. #define BDS_Sunken 2
  837. #define BDS_Rounded 3
  838. // FontStyleProp
  839. #define FS_None 0x00000000
  840. #define FS_Italic 0x00000001
  841. #define FS_Underline 0x00000002
  842. #define FS_StrikeOut 0x00000004
  843. #define FS_Shadow 0x00000008
  844. // FontWeightProp
  845. #define FW_DontCare 0
  846. #define FW_Thin 100
  847. #define FW_ExtraLight 200
  848. #define FW_Light 300
  849. #define FW_Normal 400
  850. #define FW_Medium 500
  851. #define FW_SemiBold 600
  852. #define FW_Bold 700
  853. #define FW_ExtraBold 800
  854. #define FW_Heavy 900
  855. // ContentAlignProp (CAE_XY, Y=bits 0-1, X=bits 2-3)
  856. #define CA_TopLeft 0x00000000 // (0,0)
  857. #define CA_TopCenter 0x00000001 // (0,1)
  858. #define CA_TopRight 0x00000002 // (0,2)
  859. #define CA_MiddleLeft 0x00000004 // (1,0)
  860. #define CA_MiddleCenter 0x00000005 // (1,1)
  861. #define CA_MiddleRight 0x00000006 // (1,2)
  862. #define CA_BottomLeft 0x00000008 // (2,0)
  863. #define CA_BottomCenter 0x00000009 // (2,1)
  864. #define CA_BottomRight 0x0000000A // (2,2)
  865. #define CA_WrapLeft 0x0000000C // (3,0)
  866. #define CA_WrapCenter 0x0000000D // (3,1)
  867. #define CA_WrapRight 0x0000000E // (3,2)
  868. #define CA_EndEllipsis 0x00000010
  869. #define CA_FocusRect 0x00000020
  870. // AnimationProp (Interpolation | CatType [ | CatType | ... ] | Speed)
  871. #define ANI_InterpolMask 0x0000000F
  872. #define ANI_DelayMask 0x000000F0
  873. #define ANI_TypeMask 0x0FFFFF00
  874. #define ANI_SpeedMask 0xF0000000
  875. #define ANI_DefaultInterpol 0x00000000
  876. #define ANI_Linear 0x00000001 // INTERPOLATION_LINEAR
  877. #define ANI_Log 0x00000002 // INTERPOLATION_LOG
  878. #define ANI_Exp 0x00000003 // INTERPOLATION_EXP
  879. #define ANI_S 0x00000004 // INTERPOLATION_S
  880. #define ANI_DelayNone 0x00000000
  881. #define ANI_DelayShort 0x00000010
  882. #define ANI_DelayMedium 0x00000020
  883. #define ANI_DelayLong 0x00000030
  884. #define ANI_AlphaType 0x00000F00
  885. #define ANI_BoundsType 0x0000F000
  886. #define ANI_XFormType 0x000F0000
  887. #define ANI_None 0x00000000
  888. #define ANI_Alpha 0x00000100
  889. #define ANI_Position 0x00001000
  890. #define ANI_Size 0x00002000
  891. #define ANI_SizeH 0x00003000
  892. #define ANI_SizeV 0x00004000
  893. #define ANI_Rect 0x00005000
  894. #define ANI_RectH 0x00006000
  895. #define ANI_RectV 0x00007000
  896. #define ANI_Scale 0x00010000
  897. #define ANI_DefaultSpeed 0x00000000
  898. #define ANI_VeryFast 0x10000000
  899. #define ANI_Fast 0x20000000
  900. #define ANI_MediumFast 0x30000000
  901. #define ANI_Medium 0x40000000
  902. #define ANI_MediumSlow 0x50000000
  903. #define ANI_Slow 0x60000000
  904. #define ANI_VerySlow 0x70000000
  905. // CursorProp
  906. #define CUR_Arrow 0
  907. #define CUR_Hand 1
  908. #define CUR_Help 2
  909. #define CUR_No 3
  910. #define CUR_Wait 4
  911. #define CUR_SizeAll 5
  912. #define CUR_SizeNESW 6
  913. #define CUR_SizeNS 7
  914. #define CUR_SizeNWSE 8
  915. #define CUR_SizeWE 9
  916. #define CUR_Total 10
  917. // Internal property indicies for property compares. Must match up one to one
  918. // with Element property definitions
  919. #define _PIDX_Parent 0
  920. #define _PIDX_PosInLayout 1
  921. #define _PIDX_SizeInLayout 2
  922. #define _PIDX_DesiredSize 3
  923. #define _PIDX_LastDSConst 4
  924. #define _PIDX_Location 5
  925. #define _PIDX_Extent 6
  926. #define _PIDX_LayoutPos 7
  927. #define _PIDX_Active 8
  928. #define _PIDX_Children 9
  929. #define _PIDX_Layout 10
  930. #define _PIDX_BorderThickness 11
  931. #define _PIDX_Padding 12
  932. #define _PIDX_Margin 13
  933. #define _PIDX_Visible 14
  934. #define _PIDX_X 15
  935. #define _PIDX_Y 16
  936. #define _PIDX_ContentAlign 17
  937. #define _PIDX_KeyFocused 18
  938. #define _PIDX_KeyWithin 19
  939. #define _PIDX_MouseFocused 20
  940. #define _PIDX_MouseWithin 21
  941. #define _PIDX_Content 22
  942. #define _PIDX_Sheet 23
  943. #define _PIDX_Width 24
  944. #define _PIDX_Height 25
  945. #define _PIDX_BorderStyle 26
  946. #define _PIDX_BorderColor 27
  947. #define _PIDX_Foreground 28
  948. #define _PIDX_Background 29
  949. #define _PIDX_FontFace 30
  950. #define _PIDX_FontSize 31
  951. #define _PIDX_FontWeight 32
  952. #define _PIDX_FontStyle 33
  953. #define _PIDX_Class 34
  954. #define _PIDX_ID 35
  955. #define _PIDX_Selected 36
  956. #define _PIDX_Alpha 37
  957. #define _PIDX_Animation 38
  958. #define _PIDX_Cursor 39
  959. #define _PIDX_Direction 40
  960. #define _PIDX_Accessible 41
  961. #define _PIDX_AccRole 42
  962. #define _PIDX_AccState 43
  963. #define _PIDX_AccName 44
  964. #define _PIDX_AccDesc 45
  965. #define _PIDX_AccValue 46
  966. #define _PIDX_AccDefAction 47
  967. #define _PIDX_Shortcut 48
  968. #define _PIDX_Enabled 49
  969. #define _PIDX_TOTAL 50
  970. ////////////////////////////////////////////////////////
  971. // Class information template
  972. // All classes that derive from Element must create a global instance of this class.
  973. // It maintains a list of the class properties (provides enumeration) and creation method
  974. // C = Class, B = Base class
  975. // Defined in Element.cpp
  976. extern UINT g_iGlobalCI;
  977. extern UINT g_iGlobalPI;
  978. template <typename C, typename B> class ClassInfo : public IClassInfo
  979. {
  980. public:
  981. // Registration (cannot unregister -- will be registered until UnInitProcess is called)
  982. static HRESULT Register(LPCWSTR pszName, PropertyInfo** ppPI, UINT cPI)
  983. {
  984. HRESULT hr;
  985. // If class mapping doesn't exist, registration fails
  986. if (!Element::pciMap)
  987. return E_FAIL;
  988. // Check for entry in mapping, if exists, ignore registration
  989. if (!Element::pciMap->GetItem((void*)pszName))
  990. {
  991. // Never been registered, create class info entry
  992. hr = Create(pszName, ppPI, cPI, &C::Class);
  993. if (FAILED(hr))
  994. return hr;
  995. hr = Element::pciMap->SetItem((void*)pszName, C::Class);
  996. if (FAILED(hr))
  997. return hr;
  998. }
  999. return S_OK;
  1000. }
  1001. // Construction
  1002. static HRESULT Create(LPCWSTR pszName, PropertyInfo** ppPI, UINT cPI, IClassInfo** ppCI)
  1003. {
  1004. *ppCI = NULL;
  1005. // Element map must already exist
  1006. if (!Element::pciMap)
  1007. return E_FAIL;
  1008. ClassInfo* pci = HNew<ClassInfo>();
  1009. if (!pci)
  1010. return E_OUTOFMEMORY;
  1011. // Setup state
  1012. pci->_ppPI = ppPI;
  1013. pci->_cPI = cPI;
  1014. pci->_pszName = pszName;
  1015. // Set global index
  1016. pci->_iGlobalIndex = g_iGlobalCI++;
  1017. // Setup property ownership
  1018. for (UINT i = 0; i < cPI; i++)
  1019. {
  1020. ppPI[i]->_iIndex = i;
  1021. ppPI[i]->_iGlobalIndex = g_iGlobalPI++;
  1022. ppPI[i]->_pciOwner = pci;
  1023. }
  1024. #if DBG
  1025. // Call string conversion method directly since can't assume Util library is available for header
  1026. CHAR szNameA[101];
  1027. ZeroMemory(szNameA, sizeof(szNameA));
  1028. WideCharToMultiByte(CP_ACP, 0, pszName, -1, szNameA, (sizeof(szNameA) / sizeof(CHAR)) - 1, NULL, NULL);
  1029. //DUITrace("RegDUIClass[%d]: '%s', %d ClassProps\n", pci->_iGlobalIndex, szNameA, cPI);
  1030. #endif
  1031. *ppCI = pci;
  1032. return S_OK;
  1033. }
  1034. void Destroy() { HDelete<ClassInfo>(this); }
  1035. public:
  1036. HRESULT CreateInstance(OUT Element** ppElement) { return C::Create(ppElement); }
  1037. PropertyInfo* EnumPropertyInfo(UINT nEnum) { return (nEnum < _cPI) ? _ppPI[nEnum] : B::Class->EnumPropertyInfo(nEnum - _cPI); }
  1038. UINT GetPICount() { return _cPI + B::Class->GetPICount(); }
  1039. UINT GetGlobalIndex() { return _iGlobalIndex; }
  1040. IClassInfo* GetBaseClass() { return B::Class; }
  1041. LPCWSTR GetName() { return _pszName; }
  1042. bool IsValidProperty(PropertyInfo* ppi) { return (ppi->_pciOwner == this) ? true : B::Class->IsValidProperty(ppi); }
  1043. bool IsSubclassOf(IClassInfo* pci) { return (pci == this) ? true : B::Class->IsSubclassOf(pci); }
  1044. ClassInfo() { }
  1045. virtual ~ClassInfo() { }
  1046. private:
  1047. PropertyInfo** _ppPI; // Array of properties for this class (C)
  1048. UINT _cPI; // Count of properties for this class (C)
  1049. UINT _iGlobalIndex; // Zero-based unique contiguous class id
  1050. LPCWSTR _pszName; // Class name
  1051. };
  1052. } // namespace DirectUI
  1053. #endif // DUI_CORE_ELEMENT_H_INCLUDED