8#include "EventHandlerWrapper.h"
11#include "RoutedEvent.h"
12#include "RoutedEventArgs.h"
16#include <unordered_map>
82 bool _collapseWhenHide =
true;
92 Size _origionalSize{};
97 Size _minSize{-1, -1};
102 Size _maxSize{-1, -1};
127 std::vector<UIElement *> _children{};
132 std::vector<UIElement *> _layoutVisibleChildren{};
137 std::unordered_map<RoutedEventType, RoutedEventHandler> _eventMap{};
157 double _arrangeOffsetX = 0;
162 double _arrangeOffsetY = 0;
167 double _childRightmost = 0;
172 double _childBottommost = 0;
182 bool _tabStop =
false;
197 bool _transparent =
false;
202 bool _inheritTextColor =
false;
207 bool _useDefaultCursor =
true;
217 Size _lastMeasureAvailableSize{};
242 bool _isHitTestVisible =
true;
247 bool _focusedViaTab =
false;
252 std::unordered_map<FieldId, std::unique_ptr<BindingBase>> _bindings{};
390 [[deprecated(
"Use AddHandler instead to avoid overwriting existing event handlers.")]]
1036 void _SetMeasureInvalidated();
1041 void _UpdateLayoutVisibleChildren();
1074 struct _CanAddChild : std::false_type {
1089 template <
typename First,
typename...
Rest>
1090 struct _CanAddChildren
1091 : std::integral_constant<bool, _CanAddChild<First>::value && _CanAddChildren<Rest...>::value> {
1097 template <
typename T>
1098 struct _CanAddChildren<
T> : _CanAddChild<T> {
1105 template <
typename T>
1106 int _AddChildrenImpl(
T &&child)
1108 return this->
AddChild(std::forward<T>(child)) ? 1 : 0;
1115 template <
typename First,
typename... Rest>
1116 int _AddChildrenImpl(First &&first, Rest &&...rest)
1119 if (this->
AddChild(std::forward<First>(first)))
1120 count = 1 + this->_AddChildrenImpl(std::forward<Rest>(rest)...);
1131 template <
typename First,
typename... Rest>
1133 ->
typename std::enable_if<_CanAddChildren<
First,
Rest...>::value,
int>::type
1136 int count = this->_AddChildrenImpl(std::forward<First>(
first), std::forward<Rest>(
rest)...);
1152 template <
typename T>
1153 [[deprecated(
"Use AddHandler instead to avoid overwriting existing event handlers.")]]
1169 template <
typename TEventArgs>
1170 [[deprecated(
"Use AddHandler instead to avoid overwriting existing event handlers.")]]
1189 template <
typename TEventArgs,
typename THandleObj>
1190 [[deprecated(
"Use AddHandler instead to avoid overwriting existing event handlers.")]]
1208 template <
typename T>
1219 template <
typename TEventArgs>
1233 template <
typename TEventArgs,
typename THandleObj>
1246 template <
typename TEventArgs>
1248 ->
typename std::enable_if<
1249 std::is_base_of<RoutedEventArgs, TEventArgs>::value &&
1250 !std::is_same<TEventArgs, RoutedEventArgs>::value &&
1264 template <
typename TEventArgs,
typename THandleObj>
1282 template <
typename T>
1294 template <
typename TEventArgs>
1313 template <
typename TEventArgs,
typename THandleObj>
1331 template <
typename TEventArgs>
1333 ->
typename std::enable_if<
1334 std::is_base_of<RoutedEventArgs, TEventArgs>::value &&
1335 !std::is_same<TEventArgs, RoutedEventArgs>::value &&
1355 template <
typename TEventArgs,
typename THandleObj>
1374 template <
typename T>
1375 struct UIElement::_CanAddChild<
布局接口
Definition ILayout.h:13
Tag接口
Definition ITag.h:12
值转换器接口
Definition IValueConverter.h:14
表示界面中的元素
Definition UIElement.h:69
Color GetRealTextColor() const
获取当前要显示的文本颜色
virtual UIElement * GetParent() const override final
获取父元素
virtual uint64_t GetTag() const override
获取Tag
const Property< HorizontalAlignment > HorizontalAlignment
水平对齐方式
Definition UIElement.h:263
void RaiseRoutedEvent(RoutedEventType eventType)
触发路由事件
UIElement * GetNextElement()
获取当前元素在界面树上的下一个节点,若已是最后一个节点则返回根节点
void RegisterRoutedEvent(RoutedEventType eventType, T &obj, void(T::*handler)(UIElement &, RoutedEventArgs &))
注册成员函数作为路由事件处理函数,当事件已注册时会覆盖已注册的函数
Definition UIElement.h:1154
virtual void SetTag(uint64_t tag) override
设置Tag
void UnregisterRoutedEvent(RoutedEventType eventType)
取消对应类型路由事件的注册,该函数会移除对应事件所有的处理函数
void SetCursor(HCURSOR hCursor)
设置鼠标样式
virtual UIElement * ToUIElement() override final
尝试将对象转换成UIElement
virtual void OnTabStop()
通过tab键将焦点移动到当前元素时调用该函数
bool AddChild(UIElement &element)
添加子元素
virtual bool OnMove(const Point &newClientPosition) override
接收到WM_MOVE时调用该函数
UIElement * GetPreviousElement()
获取当前元素在界面树上的上一个节点,若元素为第一个节点则返回最后一个节点
void UpdateSiblingsZOrder(bool invalidateMeasure=true)
更新兄弟元素的Z轴位置
virtual bool OnClose() override
接收到WM_CLOSE时调用该函数
double GetChildRightmost(bool update)
获取所有子元素在当前元素中最右边的位置(只考虑参与布局的子窗口且忽略悬浮的元素)
const ReadOnlyProperty< bool > IsFocusedViaTab
当前元素是否是通过按下Tab键获得的焦点
Definition UIElement.h:371
const Property< bool > TabStop
表示用户是否可以通过按下Tab键将焦点移动到当前元素
Definition UIElement.h:303
void RegisterRoutedEvent(RoutedEventType eventType, const RoutedEventHandler &handler)
注册路由事件处理函数,当事件已注册时会覆盖已注册的函数
double & GetInternalArrangeOffsetY()
获取布局时子元素的垂直偏移量
virtual void ArrangeOverride(const Size &finalSize)
安排子元素的位置,可重写该函数以实现自定义布局
bool AddChild(UIElement *element)
添加子元素
const Property< double > MinHeight
最小高度,当值为负数或0时表示不限制
Definition UIElement.h:345
bool AddChild(UIElement &element, uint64_t layoutTag)
添加子元素并设置布局标记
virtual UIElement & GetChildAt(int index) const override final
获取指定索引处的子元素
void ResetCursor()
将鼠标样式设置为默认样式
virtual bool OnKeyUp(VirtualKey key, const KeyFlags &flags) override
接收到WM_KEYUP时调用该函数
int IndexOf(UIElement *element)
获取指定元素的索引
virtual void OnRoutedEvent(RoutedEventArgs &eventArgs, const RoutedEventHandler &handler)
路由事件经过当前元素时调用该函数
virtual Size GetDesireSize() const override
获取当前元素所需尺寸
virtual bool OnMouseLeftButtonDown(const Point &mousePosition, MouseKey keyState) override
接收到WM_LBUTTONDOWN时调用该函数
auto RegisterRoutedEvent(THandleObj &obj, void(THandleObj::*handler)(UIElement &, TEventArgs &)) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
根据事件参数类型注册成员函数作为路由事件,当事件已注册时会覆盖已注册的函数
Definition UIElement.h:1191
UIElement * GetRootElement()
获取当前元素所在界面树的根节点
const ReadOnlyProperty< int > ChildCount
子元素数量
Definition UIElement.h:273
virtual bool OnColor(HDC hdc, HBRUSH &hRetBrush) override
父窗口接收到WM_CTLCOLORxxx时调用对应控件的该函数
void ClampDesireSize(sw::Size &size) const
限定指定尺寸在最小和最大尺寸之间
const ReadOnlyProperty< sw::Rect > LogicalRect
元素的逻辑位置和尺寸,即去除布局偏移以及拉伸影响的位置和尺寸
Definition UIElement.h:361
virtual bool OnSetCursor(HWND hwnd, HitTestResult hitTest, int message, bool &result) override
接收到WM_SETCURSOR消息时调用该函数
virtual bool OnKeyDown(VirtualKey key, const KeyFlags &flags) override
接收到WM_KEYDOWN时调用该函数
bool RemoveChildAt(int index)
移除指定索引处的子元素
virtual int GetChildLayoutCount() const override final
获取参与布局的子元素数量
UIElement * GetNextTabStopElement()
获取下一个TabStop属性为true的元素
virtual bool OnDropFiles(HDROP hDrop) override
接收到WM_DROPFILES时调用该函数
virtual bool OnKillFocus(HWND hNextFocus) override
接收到WM_KILLFOCUS时调用该函数
bool RemoveHandler(RoutedEventType eventType, T &obj, void(T::*handler)(UIElement &, RoutedEventArgs &))
移除已添加的类型为成员函数的路由事件处理函数
Definition UIElement.h:1283
auto AddChildren(First &&first, Rest &&...rest) -> typename std::enable_if< _CanAddChildren< First, Rest... >::value, int >::type
添加多个子元素
Definition UIElement.h:1132
bool ShowContextMenu(const Point &point, sw::HorizontalAlignment horz=sw::HorizontalAlignment::Left, sw::VerticalAlignment vert=sw::VerticalAlignment::Top)
弹出当前元素的上下文菜单
virtual bool OnSize(const Size &newClientSize) override
接收到WM_SIZE时调用该函数
virtual bool OnMouseMiddleButtonUp(const Point &mousePosition, MouseKey keyState) override
接收到WM_MBUTTONUP时调用该函数
const Property< uint64_t > LayoutTag
布局标记,对于不同的布局有不同含义
Definition UIElement.h:288
virtual void OnTabMove(bool forward)
通过tab键将焦点从当前元素移出时调用该函数
const ReadOnlyProperty< bool > IsMeasureValid
当前元素的布局状态是否有效
Definition UIElement.h:335
virtual bool OnMouseRightButtonDown(const Point &mousePosition, MouseKey keyState) override
接收到WM_RBUTTONDOWN时调用该函数
void MoveToBottom()
移动到界面底部
virtual bool OnMouseMiddleButtonDown(const Point &mousePosition, MouseKey keyState) override
接收到WM_MBUTTONDOWN时调用该函数
void SetAlignment(sw::HorizontalAlignment horz, sw::VerticalAlignment vert)
设置对齐方式
virtual void OnNcHitTest(const Point &testPoint, HitTestResult &result) override
接收到WM_NCHITTEST后调用该函数
double GetChildBottommost(bool update)
获取所有子元素在当前元素中最底边的位置(只考虑参与布局的子窗口且忽略悬浮的元素)
void AddHandler(RoutedEventType eventType, const RoutedEventHandler &handler)
添加路由事件处理函数
const Property< bool > InheritTextColor
是否继承父元素的文本颜色
Definition UIElement.h:324
virtual void OnTextChanged() override
Text属性更改时调用此函数
void SetCursor(StandardCursor cursor)
设置鼠标样式
virtual uint64_t GetLayoutTag() const override
获取布局标记
const Property< bool > IsHitTestVisible
当前元素是否响应鼠标事件
Definition UIElement.h:366
virtual void ParentChanged(WndBase *newParent) override
父窗口改变时调用此函数
bool QueryAllChildren(const Predicate< UIElement * > &queryFunc)
查询所有子元素,直到queryFunc返回false或所有子元素均被查询
Color GetRealBackColor() const
获取当前要显示的背景颜色
const Property< uint64_t > Tag
储存用户自定义信息的标记
Definition UIElement.h:283
bool IsRootElement() const
判断当前元素是否为根节点
virtual Size MeasureOverride(const Size &availableSize)
测量元素所需尺寸,无需考虑边框和边距
auto AddHandler(const Action< UIElement &, TEventArgs & > &handler) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
根据事件参数类型添加路由事件处理函数
Definition UIElement.h:1220
auto RemoveHandler(RoutedEventType eventType, THandleObj &obj, void(THandleObj::*handler)(UIElement &, TEventArgs &)) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&!std::is_same< TEventArgs, RoutedEventArgs >::value &&!sw::_IsTypedRoutedEventArgs< TEventArgs >::value, bool >::type
移除已添加的类型为成员函数的路由事件处理函数
Definition UIElement.h:1356
const Property< Thickness > Margin
边距
Definition UIElement.h:258
int IndexOf(UIElement &element)
获取指定元素的索引
bool RemoveHandler(RoutedEventType eventType, const RoutedEventHandler &handler)
移除已添加的路由事件处理函数
bool RemoveChild(UIElement *element)
移除子元素
virtual ILayout & GetChildLayoutAt(int index) const override final
获取对应索引处的子元素,只索引参与布局的子元素
virtual bool OnMouseWheel(int wheelDelta, const Point &mousePosition, MouseKey keyState) override
接收到WM_MOUSEWHEEL时调用该函数
virtual bool OnChar(wchar_t ch, const KeyFlags &flags) override
接收到WM_CHAR时调用该函数
auto RemoveHandler(const Action< UIElement &, TEventArgs & > &handler) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value, bool >::type
移除已添加的路由事件处理函数
Definition UIElement.h:1295
const Property< bool > CollapseWhenHide
是否在不可见时不参与布局
Definition UIElement.h:278
void ClearChildren()
移除所有子元素
virtual bool OnSetFocus(HWND hPrevFocus) override
接收到WM_SETFOCUS时调用该函数
auto AddHandler(THandleObj &obj, void(THandleObj::*handler)(UIElement &, TEventArgs &)) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
根据事件参数类型添加成员函数作为路由事件处理函数
Definition UIElement.h:1234
virtual void VisibleChanged(bool newVisible) override
Visible属性改变时调用此函数
const Property< double > MinWidth
最小宽度,当值为负数或0时表示不限制
Definition UIElement.h:340
bool IsLayoutUpdateConditionSet(sw::LayoutUpdateCondition condition)
判断指定的布局更新条件是否已设置
bool RemoveChild(UIElement &element)
移除子元素
virtual bool OnMouseLeftButtonUp(const Point &mousePosition, MouseKey keyState) override
接收到WM_LBUTTONUP时调用该函数
void UpdateChildrenZOrder(bool invalidateMeasure=true)
更新子元素的Z轴位置
auto AddHandler(RoutedEventType eventType, THandleObj &obj, void(THandleObj::*handler)(UIElement &, TEventArgs &)) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&!std::is_same< TEventArgs, RoutedEventArgs >::value &&!sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
添加成员函数作为路由事件处理函数
Definition UIElement.h:1265
void Resize(const Size &size)
调整当前元素的尺寸
void AddHandler(RoutedEventType eventType, T &obj, void(T::*handler)(UIElement &, RoutedEventArgs &))
添加成员函数作为路由事件处理函数
Definition UIElement.h:1209
const Property< double > MaxHeight
最大高度,当值为负数或0时表示不限制
Definition UIElement.h:355
const Property< bool > Transparent
是否使用透明背景
Definition UIElement.h:319
virtual void OnRemovedChild(UIElement &element)
移除子元素后调用该函数
const Property< Color > BackColor
背景颜色,修改该属性会同时将Transparent属性设为false,对于部分控件该属性可能不生效
Definition UIElement.h:308
UIElement * GetPreviousTabStopElement()
获取上一个TabStop属性为true的元素
const Property< sw::LayoutUpdateCondition > LayoutUpdateCondition
触发布局更新的条件
Definition UIElement.h:330
virtual void SetTextColor(Color color, bool redraw)
设置文本颜色
auto AddHandler(RoutedEventType eventType, const Action< UIElement &, TEventArgs & > &handler) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&!std::is_same< TEventArgs, RoutedEventArgs >::value &&!sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
添加路由事件处理函数
Definition UIElement.h:1247
bool QueryAllElements(const Predicate< UIElement * > &queryFunc)
查询自身和所有子元素,直到queryFunc返回false或所有子元素均被查询
auto RegisterRoutedEvent(const Action< UIElement &, TEventArgs & > &handler) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value >::type
根据事件参数类型注册路由事件,当事件已注册时会覆盖已注册的函数
Definition UIElement.h:1171
bool AddChild(UIElement *element, uint64_t layoutTag)
添加子元素并设置布局标记
double & GetInternalArrangeOffsetX()
获取布局时子元素的水平偏移量
const Property< bool > Float
元素是否悬浮,若元素悬浮则该元素不会随滚动条滚动而改变位置
Definition UIElement.h:298
virtual bool RequestBringIntoView(const sw::Rect &screenRect)
尝试将指定的矩形区域移动到可视区域内
virtual bool OnMouseLeave() override
接收到WM_MOUSELEAVE时调用该函数
virtual void Arrange(const sw::Rect &finalPosition) override
安排元素位置
virtual void OnMenuCommand(int id) override
当WM_COMMAND接收到菜单命令时调用该函数
virtual ~UIElement()=0
析构函数,这里用纯虚函数使该类成为抽象类
virtual int GetChildCount() const override final
获取子元素数量
auto RemoveHandler(THandleObj &obj, void(THandleObj::*handler)(UIElement &, TEventArgs &)) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&sw::_IsTypedRoutedEventArgs< TEventArgs >::value, bool >::type
移除已添加的类型为成员函数的路由事件处理函数
Definition UIElement.h:1314
const Property< double > MaxWidth
最大宽度,当值为负数或0时表示不限制
Definition UIElement.h:350
virtual bool SetParent(WndBase *parent) override
设置父窗口
const Property< VerticalAlignment > VerticalAlignment
垂直对齐方式
Definition UIElement.h:268
bool BringIntoView()
尝试将当前元素移动到可视区域内
bool IsRoutedEventRegistered(RoutedEventType eventType)
判断路由事件是否已存在事件处理函数
auto RemoveHandler(RoutedEventType eventType, const Action< UIElement &, TEventArgs & > &handler) -> typename std::enable_if< std::is_base_of< RoutedEventArgs, TEventArgs >::value &&!std::is_same< TEventArgs, RoutedEventArgs >::value &&!sw::_IsTypedRoutedEventArgs< TEventArgs >::value, bool >::type
移除已添加的路由事件处理函数
Definition UIElement.h:1332
virtual bool OnMouseMove(const Point &mousePosition, MouseKey keyState) override
接收到WM_MOUSEMOVE时调用该函数
virtual void OnAddedChild(UIElement &element)
添加子元素后调用该函数
const Property< sw::ContextMenu * > ContextMenu
右键按下时弹出的菜单
Definition UIElement.h:293
virtual void OnMinMaxSizeChanged()
当MinWidth、MinHeight、MaxWidth或MaxHeight属性更改时调用此函数
virtual bool OnMouseRightButtonUp(const Point &mousePosition, MouseKey keyState) override
接收到WM_RBUTTONUP时调用该函数
const Property< Color > TextColor
文本颜色,修改该属性会同时将InheritTextColor属性设为false,对于部分控件该属性可能不生效
Definition UIElement.h:313
virtual void Measure(const Size &availableSize) override
测量元素所需尺寸
virtual bool OnContextMenu(bool isKeyboardMsg, const Point &mousePosition) override
接收到WM_CONTEXTMENU后调用目标控件的该函数
virtual void SetBackColor(Color color, bool redraw)
设置背景颜色
void InvalidateMeasure()
使元素的布局状态失效,并立即触发布局更新
表示一个Windows窗口,是所有窗口和控件的基类
Definition WndBase.h:29
SimpleWindow框架的顶级命名空间,所有公共类型、控件、枚举和工具函数均定义于此。
Definition Alignment.h:4
LayoutUpdateCondition
通知布局更新的条件
Definition UIElement.h:29
@ PositionChanged
位置改变时更新布局
VerticalAlignment
垂直对齐方式
Definition Alignment.h:18
MouseKey
鼠标事件时用于判断按键状态
Definition Keys.h:291
VirtualKey
虚拟按键
Definition Keys.h:65
EventHandler< UIElement, RoutedEventArgs > RoutedEventHandler
路由事件类型
Definition RoutedEvent.h:195
HorizontalAlignment
水平对齐方式
Definition Alignment.h:8
StandardCursor
系统标准鼠标样式
Definition Cursor.h:12
RoutedEventType
路由事件类型枚举
Definition RoutedEvent.h:12
HitTestResult
NcHitTest(WM_NCHITTEST)的返回值
Definition HitTestResult.h:10
https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#keystroke-message-flags
Definition Keys.h:12
表示相对于左上角的点坐标
Definition Point.h:15
表示一个矩形区域
Definition Rect.h:17
路由事件的参数
Definition RoutedEvent.h:154
表示矩形区域周围边框的厚度
Definition Thickness.h:15
结构体模板,用于检测类型T是否包含事件类型信息
Definition RoutedEventArgs.h:58