1
2
3
4
5
6 using System;
7 using System.Windows.API;
8
9 namespace System.Windows
10 {
11 public enum LabelStyle : long
12 {
13 SS_BITMAP = 14,
14 SS_BLACKFRAME = 7,
15 SS_BLACKRECT = 4,
16 SS_CENTER = 1,
17 SS_CENTERIMAGE = 512,
18 SS_EDITCONTROL = 8192,
19 SS_ENDELLIPSIS = 16384,
20 SS_ENHMETAFILE = 15,
21 SS_ETCHEDFRAME = 18,
22 SS_ETCHEDHORZ = 16,
23 SS_ETCHEDVERT = 17,
24 SS_GRAYFRAME = 8,
25 SS_GRAYRECT = 5,
26 SS_ICON = 3,
27 SS_LEFT = 0,
28 SS_LEFTNOWORDWRAP = 12,
29 SS_NOPREFIX = 128u,
30 SS_NOTIFY = 256,
31 SS_OWNERDRAW = 13,
32 SS_PATHELLIPSIS = 32768u,
33 SS_REALSIZECONTROL = 64,
34 SS_REALSIZEIMAGE = 2048,
35 SS_RIGHT = 2,
36 SS_RIGHTJUST = 1024,
37 SS_SIMPLE = 11,
38 SS_SUNKEN = 4096,
39 SS_TYPEMASK = 31,
40 SS_WHITEFRAME = 9,
41 SS_WHITERECT = 6,
42 SS_WORDELLIPSIS = 49152u
43 }
44
45 public ControlCreateParams& LabelControlCreateParams(ControlCreateParams& controlCreateParams, LabelStyle labelStyle)
46 {
47 return controlCreateParams.SetWindowClassName("STATIC").SetWindowStyle(cast<WindowStyle>(DefaultChildWindowStyle() | labelStyle));
48 }
49
50 public ControlCreateParams& LabelControlCreateParams(ControlCreateParams& controlCreateParams)
51 {
52 return LabelControlCreateParams(controlCreateParams, LabelStyle.SS_LEFT);
53 }
54
55 public class LabelCreateParams
56 {
57 public LabelCreateParams(ControlCreateParams& controlCreateParams_) : controlCreateParams(controlCreateParams_), autoSize(true)
58 {
59 }
60 public LabelCreateParams& Defaults()
61 {
62 return *this;
63 }
64 public LabelCreateParams& SetAutoSize(bool autoSize_)
65 {
66 autoSize = autoSize_;
67 return *this;
68 }
69 public ControlCreateParams& controlCreateParams;
70 public bool autoSize;
71 }
72
73 public class Label : Control
74 {
75 private enum Flags : sbyte
76 {
77 none = 0, autoSize = 1 << 0, autoSized = 1 << 1
78 }
79
80 public Label(LabelStyle labelStyle, const Color& backgroundColor, const string& text, const Point& location, const Size& size,
81 Dock dock, Anchors anchors, bool autoSize) :
82 base("STATIC", DefaultWindowClassStyle(), cast<WindowStyle>(DefaultChildWindowStyle() | labelStyle), DefaultExtendedWindowStyle(),
83 backgroundColor, text, location, size, dock, anchors), flags(Flags.none)
84 {
85 if (autoSize)
86 {
87 SetAutoSizeFlag();
88 DoAutoSize();
89 }
90 }
91 public Label(const string& text, const Point& location, const Size& size, Dock dock, Anchors anchors, bool autoSize) :
92 this(LabelStyle.SS_LEFT, DefaultControlBackgroundColor(), text, location, size, dock, anchors, autoSize)
93 {
94 }
95 public Label(LabelCreateParams& createParams) : base(createParams.controlCreateParams), flags(Flags.none)
96 {
97 if (createParams.autoSize)
98 {
99 SetAutoSizeFlag();
100 auto result = DoAutoSize();
101 if (result.Error())
102 {
103 SetErrorId(result.GetErrorId());
104 return;
105 }
106 }
107 }
108 protected override Result<bool> OnCreated()
109 {
110 auto result = base->OnCreated();
111 if (result.Error())
112 {
113 return Result<bool>(ErrorId(result.GetErrorId()));
114 }
115 auto graphicsResult = Graphics.FromWindowHandle(Handle());
116 if (graphicsResult.Error())
117 {
118 return Result<bool>(ErrorId(graphicsResult.GetErrorId()));
119 }
120 Graphics& graphics = graphicsResult.Value();
121 auto fontHandleResult = GetFontHandle(graphics);
122 if (fontHandleResult.Error())
123 {
124 return Result<bool>(ErrorId(fontHandleResult.GetErrorId()));
125 }
126 FontHandle* fontHandle = fontHandleResult.Value();
127 if (!fontHandle->IsNull())
128 {
129 SendSetFontMessage(*fontHandle);
130 }
131 if (AutoSize())
132 {
133 auto result = DoAutoSize();
134 if (result.Error())
135 {
136 return Result<bool>(ErrorId(result.GetErrorId()));
137 }
138 }
139 return Result<bool>(true);
140 }
141 [nodiscard]
142 protected override Result<bool> OnTextChanged()
143 {
144 auto baseResult = base->OnTextChanged();
145 if (baseResult.Error())
146 {
147 return Result<bool>(ErrorId(baseResult.GetErrorId()));
148 }
149 if (AutoSize())
150 {
151 ResetAutoSized();
152 auto result = DoAutoSize();
153 if (result.Error())
154 {
155 return Result<bool>(ErrorId(result.GetErrorId()));
156 }
157 }
158 return Result<bool>(true);
159 }
160 public inline bool AutoSize() const
161 {
162 return (flags & Flags.autoSize) != Flags.none;
163 }
164 [nodiscard]
165 public Result<bool> SetAutoSize(bool autoSize)
166 {
167 if (autoSize)
168 {
169 if (!AutoSize())
170 {
171 SetAutoSizeFlag();
172 if (!AutoSized())
173 {
174 auto result = DoAutoSize();
175 if (result.Error())
176 {
177 return Result<bool>(ErrorId(result.GetErrorId()));
178 }
179 }
180 }
181 }
182 else
183 {
184 ResetAutoSizeFlag();
185 ResetAutoSized();
186 }
187 return Result<bool>(true);
188 }
189 private Result<bool> DoAutoSize()
190 {
191 if (AutoSized()) return Result<bool>(true);
192 if (Handle() == null) Result<bool>(false);
193 auto graphicsResult = Graphics.FromWindowHandle(Handle());
194 if (graphicsResult.Error())
195 {
196 return Result<bool>(ErrorId(graphicsResult.GetErrorId()));
197 }
198 Graphics& graphics = graphicsResult.Value();
199 const Font& font = GetFont();
200 StringFormat stringFormat;
201 if (stringFormat.Error())
202 {
203 return Result<bool>(ErrorId(stringFormat.GetErrorId()));
204 }
205 auto measureResult = graphics.MeasureStringRectF(Text(), font, PointF(0, 0), stringFormat);
206 if (measureResult.Error())
207 {
208 return Result<bool>(ErrorId(measureResult.GetErrorId()));
209 }
210 RectF r = measureResult.Value();
211 auto result = SetSize(Size(cast<int>(r.size.w), cast<int>(r.size.h)));
212 if (result.Error()) return result;
213 SetAutoSized();
214 return Result<bool>(true);
215 }
216 private inline void SetAutoSizeFlag()
217 {
218 flags = cast<Flags>(flags | Flags.autoSize);
219 }
220 private inline void ResetAutoSizeFlag()
221 {
222 flags = cast<Flags>(flags & ~Flags.autoSize);
223 }
224 private inline bool AutoSized() const
225 {
226 return (flags & Flags.autoSized) != Flags.none;
227 }
228 private inline void SetAutoSized()
229 {
230 flags = cast<Flags>(flags | Flags.autoSized);
231 }
232 private inline void ResetAutoSized()
233 {
234 flags = cast<Flags>(flags & ~Flags.autoSized);
235 }
236 private Flags flags;
237 }