1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Windows.API;
9
10 namespace System.Windows
11 {
12 public class delegate void PaintEventHandler(PaintEventArgs& paintEventArgs);
13 public class delegate void MouseEnterEventHandler(EnterLeaveEventArgs& args);
14 public class delegate void MouseEventHandler(MouseEventArgs& mouseEventargs);
15 public class delegate void MouseLeaveEventHandler(EnterLeaveEventArgs& args);
16 public class delegate void MouseWheelEventHandler(MouseWheelEventArgs& mouseWheelEventArgs);
17 public class delegate void KeyPressEventHandler(KeyPressEventArgs& keyPressEventArgs);
18 public class delegate void KeyEventHandler(KeyEventArgs& keyEventArgs);
19 public class delegate void ClickEventHandler(ClickEventArgs& clickEventArgs);
20 public class delegate void CreatedEventHandler();
21 public class delegate void DestroyedEventHandler();
22 public class delegate void ShownEventHandler();
23 public class delegate void EnabledChangedEventHandler();
24 public class delegate void VisibleChangedEventHandler();
25 public class delegate void SizeChangedEventHandler(SizeChangedEventArgs& args);
26 public class delegate void SizeChangingEventHandler(SizeChangingEventArgs& args);
27 public class delegate void ChildSizeChangedEventHandler(ControlEventArgs& controlEventArgs);
28 public class delegate void LocationChangedEventHandler();
29 public class delegate void ContentChangedEventHandler();
30 public class delegate void ChildContentChangedEventHandler(ControlEventArgs& controlEventArgs);
31 public class delegate void ContentLocationChangedEventHandler();
32 public class delegate void ChildContentLocationChangedEventHandler(ControlEventArgs& controlEventArgs);
33 public class delegate void ContentSizeChangedEventHandler();
34 public class delegate void ChildContentSizeChangedEventHandler(ControlEventArgs& controlEventArgs);
35 public class delegate void TextChangedEventHandler();
36 public class delegate void HScrollEventHandler(ScrollEventArgs& scrollEventArgs);
37 public class delegate void VScrollEventHandler(ScrollEventArgs& scrollEventArgs);
38 public class delegate void TimerEventHandler(TimerEventArgs& timerEventArgs);
39 public class delegate void GotFocusEventHandler();
40 public class delegate void LostFocusEventHandler();
41 public class delegate void ChildGotFocusEventHandler(ControlEventArgs& controlEventArgs);
42 public class delegate void ChildLostFocusEventHandler(ControlEventArgs& controlEventArgs);
43 public class delegate void ControlEventHandler(ControlEventArgs& args);
44 public class delegate void RightClickEventHandler(RightClickEventArgs& args);
45 public class delegate void ClipboardUpdateEventHandler();
46
47 public inline WindowClassStyle DefaultWindowClassStyle()
48 {
49 return WindowClassStyle.CS_DEFAULT;
50 }
51
52 public inline WindowClassStyle DoubleClickWindowClassStyle()
53 {
54 return WindowClassStyle.CS_DBLCLKS;
55 }
56
57 public inline WindowStyle DefaultChildWindowStyle()
58 {
59 return cast<WindowStyle>(WindowStyle.WS_CHILD | WindowStyle.WS_VISIBLE | WindowStyle.WS_CLIPSIBLINGS);
60 }
61
62 public inline WindowStyle HiddenChildWindowStyle()
63 {
64 return cast<WindowStyle>(WindowStyle.WS_CHILD | WindowStyle.WS_CLIPSIBLINGS);
65 }
66
67 public inline WindowStyle DialogWindowStyle()
68 {
69 return cast<WindowStyle>(WindowStyle.WS_CAPTION | WindowStyle.WS_DLGFRAME | WindowStyle.WS_CLIPSIBLINGS);
70 }
71
72 public inline ExtendedWindowStyle DefaultExtendedWindowStyle()
73 {
74 return ExtendedWindowStyle.WS_EX_DEFAULT;
75 }
76
77 public inline SystemColor DefaultWindowClassBackgroundColor()
78 {
79 return SystemColor.COLOR_WINDOW;
80 }
81
82 public Color DefaultControlBackgroundColor()
83 {
84 return GetSystemColor(SystemColor.COLOR_MENU);
85 }
86
87 public const uint mouseHoverTimerId = 2u;
88
89 public uint DefaultMouseHoverMs()
90 {
91 return 300u;
92 }
93
94 public Size DefaultMouseHoverRectSize()
95 {
96 return Size(8, 8);
97 }
98
99 public class ControlCreateParams
100 {
101 public ControlCreateParams() :
102 windowClassName(),
103 windowClassStyle(DefaultWindowClassStyle()),
104 windowStyle(DefaultChildWindowStyle()),
105 extendedWindowStyle(DefaultExtendedWindowStyle()),
106 windowClassBackgroundColor(DefaultWindowClassBackgroundColor()),
107 backgroundColor(DefaultControlBackgroundColor()),
108 text(),
109 location(),
110 size(),
111 anchors(cast<Anchors>(Anchors.left | Anchors.top)),
112 dock(Dock.none)
113 {
114 }
115 public ControlCreateParams& Defaults()
116 {
117 return *this;
118 }
119 public ControlCreateParams& SetWindowClassName(const string& windowClassName_)
120 {
121 windowClassName = windowClassName_;
122 return *this;
123 }
124 public ControlCreateParams& SetWindowClassStyle(WindowClassStyle windowClassStyle_)
125 {
126 windowClassStyle = windowClassStyle_;
127 return *this;
128 }
129 public ControlCreateParams& SetWindowStyle(WindowStyle windowStyle_)
130 {
131 windowStyle = windowStyle_;
132 return *this;
133 }
134 public ControlCreateParams& SetExtendedWindowStyle(ExtendedWindowStyle extendedWindowStyle_)
135 {
136 extendedWindowStyle = extendedWindowStyle_;
137 return *this;
138 }
139 public ControlCreateParams& SetWindowClassBackgroundColor(SystemColor systemColor)
140 {
141 windowClassBackgroundColor = systemColor;
142 return *this;
143 }
144 public ControlCreateParams& SetBackgroundColor(const Color& backgroundColor_)
145 {
146 backgroundColor = backgroundColor_;
147 return *this;
148 }
149 public ControlCreateParams& SetText(const string& text_)
150 {
151 text = text_;
152 return *this;
153 }
154 public ControlCreateParams& SetLocation(const Point& location_)
155 {
156 location = location_;
157 return *this;
158 }
159 public ControlCreateParams& SetSize(const Size& size_)
160 {
161 size = size_;
162 return *this;
163 }
164 public ControlCreateParams& SetDock(Dock dock_)
165 {
166 dock = dock_;
167 return *this;
168 }
169 public ControlCreateParams& SetAnchors(Anchors anchors_)
170 {
171 anchors = anchors_;
172 return *this;
173 }
174 public string windowClassName;
175 public WindowClassStyle windowClassStyle;
176 public WindowStyle windowStyle;
177 public ExtendedWindowStyle extendedWindowStyle;
178 public SystemColor windowClassBackgroundColor;
179 public Color backgroundColor;
180 public string text;
181 public Point location;
182 public Size size;
183 public Dock dock;
184 public Anchors anchors;
185 }
186
187 public abstract class Control : Component
188 {
189 private enum Flags : short
190 {
191 none = 0, mouseInClient = 1 << 0, lbuttonPressed = 1 << 1, menuWantsKeys = 1 << 2, keyDownHandled = 1 << 3, focused = 1 << 4,
192 caretCreated = 1 << 5, caretShown = 1 << 6, disabled = 1 << 7, hidden = 1 << 8, tabStop = 1 << 9, baseOnCreatedCalled = 1 << 10,
193 mouseHoverTimerStarted = 1 << 11, doubleBuffered = 1 << 12, scrollSubject = 1 << 13
194 }
195 public Control(const string& windowClassName_, WindowClassStyle windowClassStyle_, WindowStyle style_, ExtendedWindowStyle exStyle_,
196 const Color& backgroundColor_, const string& text_, const Point& location_, const Size& size_, Dock dock_, Anchors anchors_) :
197 windowClassName(windowClassName_), windowClassStyle(windowClassStyle_), style(style_), exStyle(exStyle_),
198 windowClassBackgroundColor(DefaultWindowClassBackgroundColor()), backgroundColor(backgroundColor_), handle(null), text(text_),
199 location(location_), size(size_), contentLocation(0, 0), contentSize(), dock(dock_), anchors(anchors_), flags(Flags.none),
200 arrowCursor(), caretShowCount(0), font(null), fontHandle(null), originalWndProc(null),
201 mouseHoverMs(0u), mouseHoverRectSize(DefaultMouseHoverRectSize())
202 {
203 Init();
204 }
205 public Control(ControlCreateParams& createParams) :
206 windowClassName(createParams.windowClassName), windowClassStyle(createParams.windowClassStyle), style(createParams.windowStyle),
207 exStyle(createParams.extendedWindowStyle), windowClassBackgroundColor(createParams.windowClassBackgroundColor),
208 backgroundColor(createParams.backgroundColor), handle(null), text(createParams.text), location(createParams.location),
209 size(createParams.size), contentLocation(0, 0), contentSize(), dock(createParams.dock), anchors(createParams.anchors), flags(Flags.none),
210 arrowCursor(), caretShowCount(0), font(null), fontHandle(null), originalWndProc(null),
211 mouseHoverMs(0u), mouseHoverRectSize(DefaultMouseHoverRectSize())
212 {
213 Init();
214 }
215 private void Init()
216 {
217 auto cursorResult = LoadStandardCursor(StandardCursorId.IDC_ARROW);
218 if (cursorResult.Error())
219 {
220 SetErrorId(cursorResult.GetErrorId());
221 return;
222 }
223 arrowCursor = Rvalue(cursorResult.Value());
224 if ((style & WindowStyle.WS_DISABLED) != 0)
225 {
226 SetDisabled();
227 }
228 if ((style & WindowStyle.WS_VISIBLE) == 0)
229 {
230 SetHidden();
231 }
232 if ((style & WindowStyle.WS_TABSTOP) != 0)
233 {
234 SetTabStop();
235 }
236 Application.Init();
237 if ((style & WindowStyle.WS_CHILD) == 0)
238 {
239 auto result = CreateWindow();
240 if (result.Error())
241 {
242 SetErrorId(result.GetErrorId());
243 return;
244 }
245 }
246 SetScrollUnits(10, 10);
247 }
248 public ~Control()
249 {
250 if (handle != null)
251 {
252 Application.GetWindowManager().RemoveWindow(this);
253 WinDestroyWindow(handle);
254 }
255 }
256 protected Result<bool> CreateWindow()
257 {
258 return CreateWindowInternal();
259 }
260 public Control* ParentControl() const
261 {
262 Control* parentControl = null;
263 ComponentContainer* container = GetContainer();
264 if (container != null)
265 {
266 Component* parent = container->Parent();
267 if (parent != null && (parent is Control*))
268 {
269 parentControl = cast<Control*>(parent);
270 }
271 }
272 return parentControl;
273 }
274 [nodiscard]
275 public Result<string> ParentText() const
276 {
277 string parentText;
278 Control* parentControl = ParentControl();
279 if (parentControl != null)
280 {
281 auto handleResult = ToHexString(cast<ulong>(parentControl->Handle()));
282 if (handleResult.Error())
283 {
284 return Result<string>(ErrorId(handleResult.GetErrorId()));
285 }
286 const string& handleStr = handleResult.Value();
287 parentText = "parent:" + string(typename(*parentControl)) + "." + parentControl->Text() + ".parentHandle=" + handleStr;
288 }
289 return Result<string>(parentText);
290 }
291 internal void SetWindowCreateStyleFromFlags()
292 {
293 if (IsDisabled())
294 {
295 style = cast<WindowStyle>(style | WindowStyle.WS_DISABLED);
296 }
297 else
298 {
299 style = cast<WindowStyle>(style & ~WindowStyle.WS_DISABLED);
300 }
301 if (Hidden())
302 {
303 style = cast<WindowStyle>(style & ~WindowStyle.WS_VISIBLE);
304 }
305 else
306 {
307 style = cast<WindowStyle>(style | WindowStyle.WS_VISIBLE);
308 }
309 }
310 internal Result<bool> CreateWindowInternal()
311 {
312 if (handle != null) return Result<bool>(true);
313 Control* parentControl = ParentControl();
314 SetWindowCreateStyleFromFlags();
315 if (Application.GetWindowManager().IsSystemClassName(windowClassName.Chars()))
316 {
317 auto handleResult = CreateWindowByClassName(windowClassName.Chars(), text.Chars(), style, exStyle, location, size, parentControl);
318 if (handleResult.Error())
319 {
320 return Result<bool>(ErrorId(handleResult.GetErrorId()));
321 }
322 else
323 {
324 handle = handleResult.Value();
325 }
326 }
327 else
328 {
329 Result<ushort> windowClassResult = Application.GetWindowManager().RegisterWindowClass(
330 windowClassName.Chars(), windowClassStyle, windowClassBackgroundColor);
331 if (windowClassResult.Error())
332 {
333 return Result<bool>(ErrorId(windowClassResult.GetErrorId()));
334 }
335 ushort windowClass = windowClassResult.Value();
336 auto handleResult = CreateWindowByClassAtom(windowClass, text.Chars(), style, exStyle, location, size, parentControl);
337 if (handleResult.Error())
338 {
339 return Result<bool>(ErrorId(handleResult.GetErrorId()));
340 }
341 else
342 {
343 handle = handleResult.Value();
344 }
345 }
346 if (!createList.IsEmpty())
347 {
348 for (Control* childControl : createList)
349 {
350 auto createResult = childControl->CreateWindowInternal();
351 if (createResult.Error())
352 {
353 return Result<bool>(ErrorId(createResult.GetErrorId()));
354 }
355 }
356 createList.Clear();
357 }
358 Application.GetWindowManager().AddWindow(this);
359 auto createResult = OnCreated();
360 if (createResult.Error())
361 {
362 return Result<bool>(ErrorId(createResult.GetErrorId()));
363 }
364 Result<WinRect> clientRectResult = GetClientRect();
365 if (clientRectResult.Error())
366 {
367 return Result<bool>(ErrorId(clientRectResult.GetErrorId()));
368 }
369 else
370 {
371 const WinRect& clientRect = clientRectResult.Value();
372 if ((style & WindowStyle.WS_CHILD) == 0)
373 {
374 Result<WinRect> windowRectResult = GetWindowRect();
375 if (windowRectResult.Error())
376 {
377 return Result<bool>(ErrorId(windowRectResult.GetErrorId()));
378 }
379 else
380 {
381 const WinRect& windowRect = windowRectResult.Value();
382 location.x = windowRect.left;
383 location.y = windowRect.top;
384 }
385 }
386 size.w = clientRect.right - clientRect.left;
387 size.h = clientRect.bottom - clientRect.top;
388 if (parentControl != null && parentControl->createList.IsEmpty())
389 {
390 auto result = DockWindow();
391 if (result.Error()) return result;
392 }
393 }
394 return Result<bool>(true);
395 }
396 internal Result<bool> AddChildVisual(Control* child)
397 {
398 if (handle != null)
399 {
400 if (child->Handle() == null)
401 {
402 auto createResult = child->CreateWindowInternal();
403 if (createResult.Error())
404 {
405 return Result<bool>(ErrorId(createResult.GetErrorId()));
406 }
407 }
408 else
409 {
410 auto result = child->SetParentWindow(this);
411 if (result.Error())
412 {
413 return result;
414 }
415 }
416 if ((child->GetWindowStyle() & WindowStyle.WS_VISIBLE) != 0)
417 {
418 auto result = child->Show();
419 if (result.Error()) return result;
420 child->Update();
421 }
422 }
423 else
424 {
425 createList.Add(child);
426 }
427 return Result<bool>(true);
428 }
429 public virtual ContainerControl* GetContainerControl() const
430 {
431 Control* parentControl = ParentControl();
432 if (parentControl != null)
433 {
434 return parentControl->GetContainerControl();
435 }
436 return null;
437 }
438 public Window* GetWindow() const
439 {
440 Control* thisControl = this;
441 if (thisControl is Window*)
442 {
443 return cast<Window*>(this);
444 }
445 ComponentContainer* container = GetContainer();
446 if (container != null)
447 {
448 Component* parent = container->Parent();
449 if (parent != null)
450 {
451 if (parent is Window*)
452 {
453 return cast<Window*>(parent);
454 }
455 else if (parent is Control*)
456 {
457 Control* control = cast<Control*>(parent);
458 return control->GetWindow();
459 }
460 }
461 }
462 return null;
463 }
464 [nodiscard]
465 internal Result<bool> SetParentWindow(Control* parentWindow)
466 {
467 auto result = SetParentWindow(handle, parentWindow->handle);
468 if (result.Error()) return result;
469 result = DockWindow();
470 if (result.Error()) return result;
471 return Result<bool>(true);
472 }
473 public inline bool IsEnabled() const
474 {
475 return !IsDisabled();
476 }
477 public void Enable()
478 {
479 if (IsDisabled())
480 {
481 ResetDisabled();
482 style = cast<WindowStyle>(style & ~WindowStyle.WS_DISABLED);
483 if (handle != null)
484 {
485 EnableWindow(true);
486 }
487 OnEnabledChanged();
488 }
489 }
490 public void Disable()
491 {
492 if (!IsDisabled())
493 {
494 SetDisabled();
495 style = cast<WindowStyle>(style | WindowStyle.WS_DISABLED);
496 if (handle != null)
497 {
498 EnableWindow(false);
499 }
500 OnEnabledChanged();
501 }
502 }
503 protected virtual void OnEnabledChanged()
504 {
505 enabledChangedEvent.Fire();
506 }
507 internal void EnableWindow(bool enable)
508 {
509 WinEnableWindow(handle, enable);
510 }
511 [nodiscard]
512 public Result<bool> BringToFront()
513 {
514 return BringWindowToTop(handle);
515 }
516 public Control* TopControl() const
517 {
518 void* topWindowHandle = GetTopWindow(handle);
519 if (topWindowHandle != null)
520 {
521 return Application.GetWindowManager().GetWindow(topWindowHandle);
522 }
523 else
524 {
525 return null;
526 }
527 }
528 public inline bool IsVisible() const
529 {
530 return !Hidden();
531 }
532 [nodiscard]
533 public Result<bool> Show()
534 {
535 if (Hidden())
536 {
537 ResetHidden();
538 style = cast<WindowStyle>(style | WindowStyle.WS_VISIBLE);
539 auto result = OnVisibleChanged();
540 if (result.Error()) return result;
541 }
542 if (handle != null)
543 {
544 auto result = ShowWindow(ShowCommand.SW_SHOW);
545 if (result.Error()) return result;
546 }
547 return Result<bool>(true);
548 }
549 [nodiscard]
550 public Result<bool> Hide()
551 {
552 if (handle != null)
553 {
554 auto result = ShowWindow(ShowCommand.SW_HIDE);
555 if (result.Error()) return result;
556 }
557 if (!Hidden())
558 {
559 SetHidden();
560 style = cast<WindowStyle>(style & ~WindowStyle.WS_VISIBLE);
561 auto result = OnVisibleChanged();
562 if (result.Error()) return result;
563 }
564 return Result<bool>(true);
565 }
566 [nodiscard]
567 public Result<bool> ShowWindow(ShowCommand showCommand)
568 {
569 WinShowWindow(handle, showCommand);
570 if (showCommand == ShowCommand.SW_HIDE)
571 {
572 if (!Hidden())
573 {
574 SetHidden();
575 style = cast<WindowStyle>(style & ~WindowStyle.WS_VISIBLE);
576 auto result = OnVisibleChanged();
577 if (result.Error()) return result;
578 }
579 }
580 return Result<bool>(true);
581 }
582 protected virtual Result<bool> OnVisibleChanged()
583 {
584 visibleChangedEvent.Fire();
585 return Result<bool>(true);
586 }
587 public void Update()
588 {
589 WinUpdateWindow(handle);
590 }
591 internal virtual Control* GetFirstEnabledTabStopControl() const
592 {
593 if (IsTabStop() && IsEnabled())
594 {
595 return this;
596 }
597 else
598 {
599 return null;
600 }
601 }
602 internal virtual Control* GetLastEnabledTabStopControl() const
603 {
604 if (IsTabStop() && IsEnabled())
605 {
606 return this;
607 }
608 else
609 {
610 return null;
611 }
612 }
613 public void SetFocus()
614 {
615 Control* focusedControl = Application.GetFocusedControl();
616 if (focusedControl != null)
617 {
618 currentModifierKeys = focusedControl->currentModifierKeys;
619 Keys emptyModifierKeys;
620 focusedControl->currentModifierKeys = emptyModifierKeys;
621 }
622 WinSetFocus(Handle());
623 Window* window = GetWindow();
624 if (window != null)
625 {
626 window->SetFocusedControl(this);
627 }
628 }
629 public const string& Text() const
630 {
631 return text;
632 }
633 [nodiscard]
634 public Result<bool> SetText(const string& text_)
635 {
636 if (text != text_)
637 {
638 text = text_;
639 auto result = SetWindowText(handle, text);
640 if (result.Error())
641 {
642 return Result<bool>(ErrorId(result.GetErrorId()));
643 }
644 result = OnTextChanged();
645 if (result.Error())
646 {
647 return Result<bool>(ErrorId(result.GetErrorId()));
648 }
649 }
650 return Result<bool>(true);
651 }
652 [nodiscard]
653 internal Result<bool> SetTextInternal(const string& text_)
654 {
655 if (text != text_)
656 {
657 text = text_;
658 auto result = OnTextChanged();
659 if (result.Error())
660 {
661 return Result<bool>(ErrorId(result.GetErrorId()));
662 }
663 }
664 return Result<bool>(true);
665 }
666 [nodiscard]
667 public Result<int> GetWindowTextLength() const
668 {
669 return GetWindowTextLength(handle);
670 }
671 [nodiscard]
672 public Result<string> GetWindowText()
673 {
674 return GetWindowText(handle);
675 }
676 [nodiscard]
677 protected virtual Result<bool> OnTextChanged()
678 {
679 textChangedEvent.Fire();
680 return Result<bool>(true);
681 }
682 [nodiscard]
683 public Result<Point> Location()
684 {
685 if ((style & WindowStyle.WS_CHILD) == 0)
686 {
687 Result<WinRect> windowRectResult = GetWindowRect();
688 if (windowRectResult.Error())
689 {
690 return Result<Point>(ErrorId(windowRectResult.GetErrorId()));
691 }
692 const WinRect& windowRect = windowRectResult.Value();
693 location.x = windowRect.left;
694 location.y = windowRect.top;
695 }
696 return Result<Point>(location);
697 }
698 [nodiscard]
699 public Result<bool> SetLocation(const Point& loc)
700 {
701 if (location != loc)
702 {
703 location = loc;
704 if (handle != null)
705 {
706 auto result = MoveWindow(handle, location, size, true);
707 if (result.Error()) return result;
708 }
709 auto result = OnLocationChanged();
710 if (result.Error()) return result;
711 }
712 return Result<bool>(true);
713 }
714 [nodiscard]
715 internal Result<bool> SetLocationInternal(const Point& loc)
716 {
717 if (location != loc)
718 {
719 location = loc;
720 auto result = OnLocationChanged();
721 if (result.Error()) return result;
722 }
723 return Result<bool>(true);
724 }
725 [nodiscard]
726 protected virtual Result<bool> OnLocationChanged()
727 {
728 locationChangedEvent.Fire();
729 return Result<bool>(true);
730 }
731 public const Size& GetSize() const
732 {
733 return size;
734 }
735 [nodiscard]
736 internal Result<bool> SetSizeInternal(const Size& sz, uint windowState)
737 {
738 if (size != sz)
739 {
740 size = sz;
741 SizeChangedEventArgs args(windowState);
742 auto result = OnSizeChanged(args);
743 if (result.Error()) return result;
744 }
745 return Result<bool>(true);
746 }
747 [nodiscard]
748 public Result<bool> SetSize(const Size& sz)
749 {
750 if (size != sz)
751 {
752 SizeChangingEventArgs sizeChangingArgs(size, sz);
753 auto result = OnSizeChanging(sizeChangingArgs);
754 if (result.Error()) return result;
755 if (sizeChangingArgs.errorId != 0)
756 {
757 return Result<bool>(ErrorId(sizeChangingArgs.errorId));
758 }
759 result = SetSizeInternal(sz, SIZE_RESTORED);
760 if (result.Error()) return result;
761 if (handle != null)
762 {
763 result = MoveWindow(handle, location, size, true);
764 if (result.Error()) return result;
765 }
766 if (IsScrollSubject())
767 {
768 Control* parentControl = ParentControl();
769 if (parentControl != null)
770 {
771 ControlEventArgs args(this);
772 result = parentControl->OnChildSizeChanged(args);
773 if (result.Error()) return result;
774 if (args.errorId != 0)
775 {
776 return Result<bool>(ErrorId(args.errorId));
777 }
778 }
779 }
780 }
781 return Result<bool>(true);
782 }
783 public void SendSetFontMessage(const FontHandle& fontHandle)
784 {
785 if (Handle() != null)
786 {
787 WinSendMessage(Handle(), WM_SETFONT, cast<uint>(cast<ulong>(fontHandle.HFont())), 0);
788 }
789 }
790 [nodiscard]
791 protected virtual Result<bool> OnSizeChanged(SizeChangedEventArgs& args)
792 {
793 sizeChangedEvent.Fire(args);
794 return Result<bool>(true);
795 }
796 [nodiscard]
797 protected virtual Result<bool> OnSizeChanging(SizeChangingEventArgs& args)
798 {
799 sizeChangingEvent.Fire(args);
800 return Result<bool>(true);
801 }
802 [nodiscard]
803 public Result<bool> FireChildSizeChanged(ControlEventArgs& args)
804 {
805 return OnChildSizeChanged(args);
806 }
807 [nodiscard]
808 protected virtual Result<bool> OnChildSizeChanged(ControlEventArgs& args)
809 {
810 childSizeChangedEvent.Fire(args);
811 return Result<bool>(true);
812 }
813 public void SetContentChanged()
814 {
815 OnContentChanged();
816 Control* parentControl = ParentControl();
817 if (parentControl != null)
818 {
819 ControlEventArgs args(this);
820 parentControl->OnChildContentChanged(args);
821 }
822 }
823 protected virtual void OnContentChanged()
824 {
825 contentChangedEvent.Fire();
826 }
827 protected virtual void OnChildContentChanged(ControlEventArgs& args)
828 {
829 childContentChangedEvent.Fire(args);
830 }
831 public inline const Point& ContentLocation() const
832 {
833 return contentLocation;
834 }
835 internal virtual void SetContentLocationInternal(const Point& contentLocation_)
836 {
837 contentLocation = contentLocation_;
838 OnContentLocationChanged();
839 }
840 public void SetContentLocation(const Point& contentLocation_)
841 {
842 if (contentLocation != contentLocation_)
843 {
844 contentLocation = contentLocation_;
845 OnContentLocationChanged();
846 Control* parentControl = ParentControl();
847 if (parentControl != null)
848 {
849 ControlEventArgs args(this);
850 parentControl->OnChildContentLocationChanged(args);
851 }
852 }
853 }
854 protected virtual void OnContentLocationChanged()
855 {
856 contentLocationChangedEvent.Fire();
857 }
858 protected virtual void OnChildContentLocationChanged(ControlEventArgs& args)
859 {
860 childContentLocationChangedEvent.Fire(args);
861 }
862 public inline const Size& ContentSize() const
863 {
864 return contentSize;
865 }
866 [nodiscard]
867 public Result<bool> SetContentSize(const Size& contentSize_)
868 {
869 if (contentSize != contentSize_)
870 {
871 contentSize = contentSize_;
872 OnContentSizeChanged();
873 Control* parentControl = ParentControl();
874 if (parentControl != null)
875 {
876 ControlEventArgs args(this);
877 auto result = parentControl->OnChildContentSizeChanged(args);
878 if (result.Error()) return result;
879 }
880 }
881 return Result<bool>(true);
882 }
883 protected virtual void OnContentSizeChanged()
884 {
885 contentSizeChangedEvent.Fire();
886 }
887 [nodiscard]
888 protected virtual Result<bool> OnChildContentSizeChanged(ControlEventArgs& args)
889 {
890 childContentSizeChangedEvent.Fire(args);
891 return Result<bool>(true);
892 }
893 public void SetScrollUnits(int verticalScrollUnit_, int horizontalScrollUnit_)
894 {
895 verticalScrollUnit = verticalScrollUnit_;
896 horizontalScrollUnit = horizontalScrollUnit_;
897 }
898 public Pair<int, int> GetScrollUnits() const
899 {
900 return MakePair(verticalScrollUnit, horizontalScrollUnit);
901 }
902 [nodiscard]
903 protected virtual Result<bool> SetCaretLocation()
904 {
905 return SetCaretPos(Point(0, 0));
906 }
907 public inline Dock GetDock() const
908 {
909 return dock;
910 }
911 [nodiscard]
912 public Result<bool> SetDock(Dock dock_)
913 {
914 dock = dock_;
915 if (dock != Dock.none)
916 {
917 auto result = DockWindow();
918 if (result.Error()) return result;
919 }
920 return Result<bool>(true);
921 }
922 [nodiscard]
923 public Result<bool> DockWindow()
924 {
925 Control* parentControl = ParentControl();
926 if (parentControl != null)
927 {
928 if (parentControl is ContainerControl*)
929 {
930 ContainerControl* containerParent = cast<ContainerControl*>(parentControl);
931 auto result = containerParent->DockChildren();
932 if (result.Error()) return result;
933 }
934 }
935 return Result<bool>(true);
936 }
937 [nodiscard]
938 internal Result<bool> DockWindow(Rect& parentRect)
939 {
940 if (dock == Dock.none) return Result<bool>(true);
941 if (handle == null) return Result<bool>(false);
942 LogView* logView = Application.GetLogView();
943 Point parentLoc = parentRect.location;
944 Size parentSize = parentRect.size;
945 Point newLocation = location;
946 Size newSize = size;
947 switch (dock)
948 {
949 case Dock.left:
950 {
951 newLocation = parentLoc;
952 newSize.h = parentSize.h;
953 parentRect.location = Point(parentLoc.x + size.w, parentLoc.y);
954 parentRect.size = Size(parentSize.w - size.w, parentSize.h);
955 if (Debug.Docking())
956 {
957 if (logView != null)
958 {
959 auto result = logView->WriteLine("Dock.left " + text + ": [" + Rect(newLocation, newSize).ToString() + "], [" + parentRect.ToString() + "]");
960 if (result.Error()) return result;
961 }
962 }
963 break;
964 }
965 case Dock.top:
966 {
967 newLocation = parentLoc;
968 newSize.w = parentSize.w;
969 parentRect.location = Point(parentLoc.x, parentLoc.y + size.h);
970 parentRect.size = Size(parentSize.w, parentSize.h - size.h);
971 if (Debug.Docking())
972 {
973 if (logView != null)
974 {
975 auto result = logView->WriteLine("Dock.top " + text + ": [" + Rect(newLocation, newSize).ToString() + "], [" + parentRect.ToString() + "]");
976 if (result.Error()) return result;
977 }
978 }
979 break;
980 }
981 case Dock.right:
982 {
983 newLocation = Point(parentLoc.x + parentSize.w - size.w, parentLoc.y);
984 newSize.h = parentSize.h;
985 parentRect.size = Size(parentSize.w - size.w, parentSize.h);
986 if (Debug.Docking())
987 {
988 if (logView != null)
989 {
990 auto result = logView->WriteLine("Dock.right " + text + ": [" + Rect(newLocation, newSize).ToString() + "], [" + parentRect.ToString() + "]");
991 if (result.Error()) return result;
992 }
993 }
994 break;
995 }
996 case Dock.bottom:
997 {
998 newLocation = Point(parentLoc.x, parentLoc.y + parentSize.h - size.h);
999 newSize.w = parentSize.w;
1000 parentRect.size = Size(parentSize.w, parentSize.h - size.h);
1001 if (Debug.Docking())
1002 {
1003 if (logView != null)
1004 {
1005 auto result = logView->WriteLine("Dock.bottom " + text + ": [" + Rect(newLocation, newSize).ToString() + "], [" + parentRect.ToString() + "]");
1006 if (result.Error()) return result;
1007 }
1008 }
1009 break;
1010 }
1011 case Dock.fill:
1012 {
1013 newLocation = parentLoc;
1014 newSize = parentSize;
1015 parentRect.location = Point();
1016 parentRect.size = Size();
1017 if (Debug.Docking())
1018 {
1019 if (logView != null)
1020 {
1021 auto result = logView->WriteLine("Dock.fill " + text + ": [" + Rect(newLocation, newSize).ToString() + "], [" + parentRect.ToString() + "]");
1022 if (result.Error()) return result;
1023 }
1024 }
1025 break;
1026 }
1027 }
1028 if (location != newLocation || size != newSize)
1029 {
1030 auto result = SetLocation(newLocation);
1031 if (result.Error()) return result;
1032 result = SetSize(newSize);
1033 if (result.Error()) return result;
1034 result = MoveWindow(handle, location, size, true);
1035 if (result.Error()) return result;
1036 }
1037 return Result<bool>(true);
1038 }
1039 [nodiscard]
1040 internal Result<bool> MoveWindow(int dx, int dy)
1041 {
1042 Point newLocation = location;
1043 Size newSize = size;
1044 bool leftAnchored = cast<Anchors>(anchors & Anchors.left) != Anchors.none;
1045 bool rightAnchored = cast<Anchors>(anchors & Anchors.right) != Anchors.none;
1046 if (!leftAnchored)
1047 {
1048 newLocation.x = newLocation.x + dx;
1049 }
1050 else if (rightAnchored)
1051 {
1052 newSize.w = newSize.w + dx;
1053 }
1054 bool topAnchored = cast<Anchors>(anchors & Anchors.top) != Anchors.none;
1055 bool bottomAnchored = cast<Anchors>(anchors & Anchors.bottom) != Anchors.none;
1056 if (!topAnchored)
1057 {
1058 newLocation.y = newLocation.y + dy;
1059 }
1060 else if (bottomAnchored)
1061 {
1062 newSize.h = newSize.h + dy;
1063 }
1064 if (location != newLocation || size != newSize)
1065 {
1066 auto result = SetLocation(newLocation);
1067 if (result.Error()) return result;
1068 result = SetSize(newSize);
1069 if (result.Error()) return result;
1070 result = MoveWindow(handle, location, size, true);
1071 if (result.Error()) return result;
1072 }
1073 return Result<bool>(true);
1074 }
1075 public inline Anchors GetAnchors() const
1076 {
1077 return anchors;
1078 }
1079 public inline void SetAnchors(Anchors anchors_)
1080 {
1081 anchors = anchors_;
1082 }
1083 public virtual Padding DefaultPadding() const
1084 {
1085 return Padding();
1086 }
1087 [nodiscard]
1088 public Result<WinRect> GetClientRect() const
1089 {
1090 return GetClientRect(handle);
1091 }
1092 [nodiscard]
1093 public Result<WinRect> GetWindowRect() const
1094 {
1095 return GetWindowRect(handle);
1096 }
1097 [nodiscard]
1098 public Result<Point> ClientToScreen(const Point& point) const
1099 {
1100 return ClientToScreen(handle, point);
1101 }
1102 [nodiscard]
1103 public Result<Point> ScreenToClient(const Point& point) const
1104 {
1105 return ScreenToClient(handle, point);
1106 }
1107 [nodiscard]
1108 internal Result<bool> ProcessMessageInternal(Message& message)
1109 {
1110 return ProcessMessage(message);
1111 }
1112 [nodiscard]
1113 public virtual Result<bool> PrintWindowTree(int level)
1114 {
1115 LogView* log = Application.GetLogView();
1116 if (log != null)
1117 {
1118 auto handleResult = ToHexString(cast<ulong>(Handle()));
1119 if (handleResult.Error())
1120 {
1121 return Result<bool>(ErrorId(handleResult.GetErrorId()));
1122 }
1123 else
1124 {
1125 const string& handleStr = handleResult.Value();
1126 auto parentTextResult = ParentText();
1127 if (parentTextResult.Error())
1128 {
1129 return Result<bool>(ErrorId(parentTextResult.GetErrorId()));
1130 }
1131 else
1132 {
1133 const string& parentText = parentTextResult.Value();
1134 auto result = log->WriteLine(string(' ', level) + "Control." + Text() + ".handle=" + handleStr + " " + parentText + "[" +
1135 Rect(Point(), GetSize()).ToString() + "]");
1136 if (result.Error()) return result;
1137 }
1138 }
1139 }
1140 return Result<bool>(true);
1141 }
1142 [nodiscard]
1143 public virtual Result<bool> ScrollLineDown()
1144 {
1145 Control* parent = ParentControl();
1146 if (parent != null)
1147 {
1148 auto result = parent->ScrollLineDown();
1149 if (result.Error())
1150 {
1151 return Result<bool>(ErrorId(result.GetErrorId()));
1152 }
1153 }
1154 return Result<bool>(true);
1155 }
1156 [nodiscard]
1157 public virtual Result<bool> ScrollLineUp()
1158 {
1159 Control* parent = ParentControl();
1160 if (parent != null)
1161 {
1162 auto result = parent->ScrollLineUp();
1163 if (result.Error())
1164 {
1165 return Result<bool>(ErrorId(result.GetErrorId()));
1166 }
1167 }
1168 return Result<bool>(true);
1169 }
1170 protected void SubClassCommandWndProc()
1171 {
1172 if (originalWndProc == null && handle != null)
1173 {
1174 originalWndProc = WinSubClassCommandWndProc(handle);
1175 }
1176 }
1177 [nodiscard]
1178 protected virtual Result<bool> ProcessMessage(Message& message)
1179 {
1180 if (originalWndProc != null)
1181 {
1182
1183
1184 if (message.originalWndProc == null)
1185 {
1186 message.originalWndProc = originalWndProc;
1187 }
1188
1189
1190 if (message.msg != WM_COMMAND && message.msg != WM_DESTROY)
1191 {
1192 return Result<bool>(false);
1193 }
1194
1195 }
1196 switch (message.msg)
1197 {
1198 case WM_PAINT:
1199 {
1200 auto paintResult = DoPaint();
1201 if (paintResult.Error())
1202 {
1203 return Result<bool>(ErrorId(paintResult.GetErrorId()));
1204 }
1205 message.result = 0;
1206 return Result<bool>(true);
1207 }
1208 case WM_MOUSEMOVE:
1209 {
1210 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam), 0);
1211 auto result = DoMouseMove(args);
1212 if (result.Error())
1213 {
1214 return Result<bool>(ErrorId(result.GetErrorId()));
1215 }
1216 if (args.errorId != 0)
1217 {
1218 return Result<bool>(ErrorId(args.errorId));
1219 }
1220 message.result = 0;
1221 return Result<bool>(true);
1222 }
1223 case WM_MOUSELEAVE:
1224 {
1225 auto result = DoMouseLeave();
1226 if (result.Error()) return result;
1227 message.result = 0;
1228 return Result<bool>(true);
1229 }
1230 case WM_LBUTTONDOWN:
1231 {
1232 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam | MouseButtons.lbutton), 1);
1233 auto result = DoMouseDown(args);
1234 if (result.Error())
1235 {
1236 return Result<bool>(ErrorId(result.GetErrorId()));
1237 }
1238 if (args.errorId != 0)
1239 {
1240 return Result<bool>(ErrorId(args.errorId));
1241 }
1242 message.result = 0;
1243 return Result<bool>(true);
1244 }
1245 case WM_LBUTTONUP:
1246 {
1247 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam | MouseButtons.lbutton), 1);
1248 auto result = DoMouseUp(args);
1249 if (result.Error())
1250 {
1251 return Result<bool>(ErrorId(result.GetErrorId()));
1252 }
1253 if (args.errorId != 0)
1254 {
1255 return Result<bool>(ErrorId(args.errorId));
1256 }
1257 message.result = 0;
1258 return Result<bool>(true);
1259 }
1260 case WM_LBUTTONDBLCLK:
1261 {
1262 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam | MouseButtons.lbutton), 2);
1263 auto result = DoMouseDoubleClick(args);
1264 if (result.Error())
1265 {
1266 return Result<bool>(ErrorId(result.GetErrorId()));
1267 }
1268 if (args.errorId != 0)
1269 {
1270 return Result<bool>(ErrorId(args.errorId));
1271 }
1272 message.result = 0;
1273 return Result<bool>(true);
1274 }
1275 case WM_RBUTTONDOWN:
1276 {
1277 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam | MouseButtons.rbutton), 1);
1278 auto result = DoMouseDown(args);
1279 if (result.Error())
1280 {
1281 return Result<bool>(ErrorId(result.GetErrorId()));
1282 }
1283 if (args.errorId != 0)
1284 {
1285 return Result<bool>(ErrorId(args.errorId));
1286 }
1287 message.result = 0;
1288 return Result<bool>(true);
1289 }
1290 case WM_RBUTTONUP:
1291 {
1292 MouseEventArgs args(Point(message.LParamX(), message.LParamY()), cast<MouseButtons>(message.wparam | MouseButtons.rbutton), 1);
1293 auto result = DoMouseUp(args);
1294 if (result.Error())
1295 {
1296 return Result<bool>(ErrorId(result.GetErrorId()));
1297 }
1298 if (args.errorId != 0)
1299 {
1300 return Result<bool>(ErrorId(args.errorId));
1301 }
1302 message.result = 0;
1303 return Result<bool>(true);
1304 }
1305 case WM_CHAR:
1306 {
1307 wchar ch = cast<wchar>(message.wparam);
1308 KeyPressEventArgs args(ch);
1309 auto keyPressResult = DoKeyPress(args);
1310 if (keyPressResult.Error())
1311 {
1312 return Result<bool>(ErrorId(keyPressResult.GetErrorId()));
1313 }
1314 if (args.errorId != 0)
1315 {
1316 return Result<bool>(ErrorId(args.errorId));
1317 }
1318 if (args.handled)
1319 {
1320 message.result = 0;
1321 return Result<bool>(true);
1322 }
1323 break;
1324 }
1325 case WM_KEYDOWN:
1326 {
1327 int virtualKeyCode = cast<int>(message.wparam);
1328 auto doKeyDownResult = DoKeyDown(virtualKeyCode);
1329 if (doKeyDownResult.Error())
1330 {
1331 return Result<bool>(ErrorId(doKeyDownResult.GetErrorId()));
1332 }
1333 bool keyDownHandled = doKeyDownResult.Value();
1334 if (keyDownHandled)
1335 {
1336 message.result = 0;
1337 return Result<bool>(true);
1338 }
1339 break;
1340 }
1341 case WM_KEYUP:
1342 {
1343 int virtualKeyCode = cast<int>(message.wparam);
1344 auto doKeyUpResult = DoKeyUp(virtualKeyCode);
1345 if (doKeyUpResult.Error())
1346 {
1347 return Result<bool>(ErrorId(doKeyUpResult.GetErrorId()));
1348 }
1349 bool keyUpHandled = doKeyUpResult.Value();
1350 if (keyUpHandled)
1351 {
1352 message.result = 0;
1353 return Result<bool>(true);
1354 }
1355 break;
1356 }
1357 case WM_SYSCOMMAND:
1358 {
1359 auto sysCommandResult = DoSysCommand(message.wparam, message.lparam);
1360 if (sysCommandResult.Error())
1361 {
1362 return Result<bool>(ErrorId(sysCommandResult.GetErrorId()));
1363 }
1364 bool sysCommandHandled = sysCommandResult.Value();
1365 if (sysCommandHandled)
1366 {
1367 message.result = 0;
1368 return Result<bool>(true);
1369 }
1370 break;
1371 }
1372 case WM_HSCROLL:
1373 {
1374 ushort request = message.WParamLoWord();
1375 auto result = DoHScroll(request);
1376 if (result.Error())
1377 {
1378 return Result<bool>(ErrorId(result.GetErrorId()));
1379 }
1380 message.result = 0;
1381 return Result<bool>(true);
1382 }
1383 case WM_VSCROLL:
1384 {
1385 ushort request = message.WParamLoWord();
1386 auto result = DoVScroll(request);
1387 if (result.Error())
1388 {
1389 return Result<bool>(ErrorId(result.GetErrorId()));
1390 }
1391 message.result = 0;
1392 return Result<bool>(true);
1393 }
1394 case WM_MOUSEWHEEL:
1395 {
1396 MouseWheelEventArgs args(Point(message.LParamX(), message.LParamY()),
1397 cast<MouseButtons>(cast<ulong>(cast<ushort>(message.wparam))), cast<short>(message.wparam >> 16u));
1398 auto result = DoMouseWheel(args);
1399 if (result.Error()) return result;
1400 if (args.errorId != 0) return Result<bool>(ErrorId(args.errorId));
1401 if (args.handled)
1402 {
1403 message.result = 0;
1404 return Result<bool>(true);
1405 }
1406 break;
1407 }
1408 case WM_SETFOCUS:
1409 {
1410 auto result = DoSetFocus();
1411 if (result.Error()) return result;
1412 message.result = 0;
1413 return Result<bool>(true);
1414 }
1415 case WM_KILLFOCUS:
1416 {
1417 auto result = DoKillFocus();
1418 if (result.Error()) return result;
1419 message.result = 0;
1420 return Result<bool>(true);
1421 }
1422 case WM_SHOWWINDOW:
1423 {
1424 if (message.wparam == 1)
1425 {
1426 auto result = OnShown();
1427 if (result.Error()) return result;
1428 }
1429 message.result = 0;
1430 return Result<bool>(true);
1431 }
1432 case WM_TIMER:
1433 {
1434 auto result = DoTimer(message.wparam);
1435 if (result.Error()) return result;
1436 message.result = 0;
1437 return Result<bool>(true);
1438 }
1439 case WM_DESTROY:
1440 {
1441 DoDestroy();
1442 message.result = 0;
1443 return Result<bool>(true);
1444 }
1445 case WM_CLIPBOARDUPDATE:
1446 {
1447 auto result = DoClipboardUpdate();
1448 if (result.Error()) return result;
1449 message.result = 0;
1450 return Result<bool>(true);
1451 }
1452 case WM_MOVE:
1453 {
1454 Point newLocation = message.LParamLocation();
1455 Result<Point> oldLocationResult = Location();
1456 if (oldLocationResult.Error())
1457 {
1458 return Result<bool>(ErrorId(oldLocationResult.GetErrorId()));
1459 }
1460 const Point& oldLocation = oldLocationResult.Value();
1461 if (newLocation != oldLocation)
1462 {
1463 auto result = SetLocationInternal(newLocation);
1464 if (result.Error()) return result;
1465 }
1466 message.result = 0;
1467 return Result<bool>(true);
1468 }
1469 case WM_SIZE:
1470 {
1471 Size newSize = message.LParamSize();
1472 Size oldSize = GetSize();
1473 uint windowState = cast<uint>(message.wparam);
1474 if (newSize != oldSize)
1475 {
1476 auto result = SetSizeInternal(newSize, windowState);
1477 if (result.Error()) return result;
1478 }
1479 message.result = 0;
1480 return Result<bool>(true);
1481 }
1482 case WM_COMMAND:
1483 {
1484 void* childWindowHandle = message.LParamHandle();
1485 ushort notificationCode = message.WParamHiWord();
1486 ushort controlId = message.WParamLoWord();
1487 Control* child = Application.GetWindowManager().GetWindow(childWindowHandle);
1488 if (child != null)
1489 {
1490 switch (notificationCode)
1491 {
1492 case BN_CLICKED:
1493 {
1494 ClickEventArgs args;
1495 auto result = child->OnClick(args);
1496 if (result.Error()) return result;
1497 if (args.errorId != 0)
1498 {
1499 return Result<bool>(ErrorId(args.errorId));
1500 }
1501 message.result = 0;
1502 return Result<bool>(true);
1503 }
1504 case BN_SETFOCUS:
1505 {
1506 auto result = child->DoGotFocus();
1507 if (result.Error()) return result;
1508 message.result = 0;
1509 return Result<bool>(true);
1510 }
1511 case BN_KILLFOCUS:
1512 {
1513 auto result = child->DoLostFocus();
1514 if (result.Error()) return result;
1515 message.result = 0;
1516 return Result<bool>(true);
1517 }
1518 case EN_CHANGE:
1519 {
1520 auto windowTextResult = child->GetWindowText();
1521 if (windowTextResult.Error())
1522 {
1523 return Result<bool>(ErrorId(windowTextResult.GetErrorId()));
1524 }
1525 const string& windowText = windowTextResult.Value();
1526 auto result = child->SetTextInternal(windowText);
1527 if (result.Error()) return result;
1528 message.result = 0;
1529 return Result<bool>(true);
1530 }
1531 case EN_SETFOCUS:
1532 {
1533 auto result = child->DoGotFocus();
1534 if (result.Error()) return result;
1535 message.result = 0;
1536 return Result<bool>(true);
1537 }
1538 case EN_KILLFOCUS:
1539 {
1540 auto result = child->DoLostFocus();
1541 if (result.Error()) return result;
1542 message.result = 0;
1543 return Result<bool>(true);
1544 }
1545 case LBN_SETFOCUS:
1546 {
1547 auto result = child->DoGotFocus();
1548 if (result.Error()) return result;
1549 message.result = 0;
1550 return Result<bool>(true);
1551 }
1552 case LBN_KILLFOCUS:
1553 {
1554 auto result = child->DoLostFocus();
1555 if (result.Error()) return result;
1556 message.result = 0;
1557 return Result<bool>(true);
1558 }
1559 case LBN_SELCHANGE:
1560 {
1561 if (child is ListBox*)
1562 {
1563 ListBox* listBox = cast<ListBox*>(child);
1564 auto result = listBox->SelectedIndexChangedInternal();
1565 if (result.Error()) return result;
1566 }
1567 message.result = 0;
1568 return Result<bool>(true);
1569 }
1570 }
1571 }
1572 break;
1573 }
1574 }
1575 return Result<bool>(false);
1576 }
1577 private void DoDestroy()
1578 {
1579 OnDestroyed();
1580 if (originalWndProc != null)
1581 {
1582 WinRestoreOriginalWndProc(handle, originalWndProc);
1583 }
1584 }
1585 private Result<bool> DoClipboardUpdate()
1586 {
1587 return OnClipboardUpdate();
1588 }
1589 protected virtual Result<bool> OnClipboardUpdate()
1590 {
1591 clipboardUpdateEvent.Fire();
1592 return Result<bool>(true);
1593 }
1594 [nodiscard]
1595 private Result<bool> DoSysCommand(ulong wparam, long lparam)
1596 {
1597 switch (wparam)
1598 {
1599 case SC_KEYMENU:
1600 {
1601 auto upperResult = ToUpper(cast<uchar>(cast<wchar>(lparam)));
1602 if (upperResult.Error())
1603 {
1604 return Result<bool>(ErrorId(upperResult.GetErrorId()));
1605 }
1606 uchar upper = upperResult.Value();
1607 wchar accessKey = cast<wchar>(upper);
1608 auto doMenuResult = DoMenu(accessKey, Keys.none);
1609 if (doMenuResult.Error())
1610 {
1611 return Result<bool>(ErrorId(doMenuResult.GetErrorId()));
1612 }
1613 bool menuHandled = doMenuResult.Value();
1614 if (menuHandled)
1615 {
1616 return Result<bool>(true);
1617 }
1618 else
1619 {
1620 if (lparam == VK_F10)
1621 {
1622 auto doKeyDownResult = DoKeyDown(cast<int>(lparam));
1623 if (doKeyDownResult.Error())
1624 {
1625 return Result<bool>(ErrorId(doKeyDownResult.GetErrorId()));
1626 }
1627 bool keyDownHandled = doKeyDownResult.Value();
1628 if (keyDownHandled)
1629 {
1630 return Result<bool>(true);
1631 }
1632 }
1633 else
1634 {
1635 currentModifierKeys = cast<Keys>(currentModifierKeys | Keys.altModifier);
1636 }
1637 auto doKeyDownResult = DoKeyDown(cast<int>(accessKey));
1638 if (doKeyDownResult.Error())
1639 {
1640 return Result<bool>(ErrorId(doKeyDownResult.GetErrorId()));
1641 }
1642 bool keyDownHandled = doKeyDownResult.Value();
1643 if (keyDownHandled)
1644 {
1645 currentModifierKeys = cast<Keys>(currentModifierKeys & ~Keys.altModifier);
1646 return Result<bool>(true);
1647 }
1648 currentModifierKeys = cast<Keys>(currentModifierKeys & ~Keys.altModifier);
1649 }
1650 break;
1651 }
1652 case SC_CLOSE:
1653 {
1654 KeyEventArgs args(cast<Keys>(Keys.f4 | Keys.altModifier));
1655 auto result = DoMenu(args);
1656 if (result.Error()) return result;
1657 if (args.errorId != 0)
1658 {
1659 return Result<bool>(ErrorId(args.errorId));
1660 }
1661 if (args.handled)
1662 {
1663 return Result<bool>(true);
1664 }
1665 break;
1666 }
1667 }
1668 return Result<bool>(false);
1669 }
1670 public void ResetModifierKeys()
1671 {
1672 currentModifierKeys = Keys.none;
1673 }
1674 [nodiscard]
1675 private Result<bool> DoKeyDown(int virtualKeyCode)
1676 {
1677 LogView* logView = Application.GetLogView();
1678 if (logView != null)
1679 {
1680 auto hexStringResult = ToHexString(cast<uint>(virtualKeyCode));
1681 if (hexStringResult.Error())
1682 {
1683 return Result<bool>(ErrorId(hexStringResult.GetErrorId()));
1684 }
1685 string s = "DoKeyDown: " + ToString(cast<Keys>(virtualKeyCode)) + " " + hexStringResult.Value();
1686 auto result = logView->WriteLine(s);
1687 if (result.Error()) return result;
1688 }
1689 ResetKeyDownHandled();
1690 if (MenuWantsKeys())
1691 {
1692 auto doMenuResult = DoMenu('\0', cast<Keys>(virtualKeyCode));
1693 if (doMenuResult.Error())
1694 {
1695 return Result<bool>(ErrorId(doMenuResult.GetErrorId()));
1696 }
1697 bool menuHandled = doMenuResult.Value();
1698 if (menuHandled)
1699 {
1700 SetKeyDownHandled();
1701 return Result<bool>(true);
1702 }
1703 }
1704 Keys key = cast<Keys>(virtualKeyCode);
1705 if (WinKeyPressed(VK_SHIFT))
1706 {
1707 key = cast<Keys>(key | Keys.shiftModifier);
1708 }
1709 if (WinKeyPressed(VK_CONTROL))
1710 {
1711 key = cast<Keys>(key | Keys.controlModifier);
1712 }
1713 if (WinKeyPressed(VK_MENU))
1714 {
1715 key = cast<Keys>(key | Keys.altModifier);
1716 }
1717 KeyEventArgs args(key);
1718 auto result = DoMenu(args);
1719 if (result.Error()) return result;
1720 if (args.errorId != 0)
1721 {
1722 return Result<bool>(ErrorId(args.errorId));
1723 }
1724 if (args.handled)
1725 {
1726 SetKeyDownHandled();
1727 return Result<bool>(true);
1728 }
1729 else
1730 {
1731 auto result = DispatchKeyDown(args);
1732 if (result.Error()) return result;
1733 if (args.errorId != 0)
1734 {
1735 return Result<bool>(ErrorId(args.errorId));
1736 }
1737 if (args.handled)
1738 {
1739 SetKeyDownHandled();
1740 return Result<bool>(true);
1741 }
1742 }
1743 return Result<bool>(false);
1744 }
1745 [nodiscard]
1746 private Result<bool> DoKeyUp(int virtualKeyCode)
1747 {
1748 LogView* logView = Application.GetLogView();
1749 if (logView != null)
1750 {
1751 auto hexStringResult = ToHexString(cast<uint>(virtualKeyCode));
1752 if (hexStringResult.Error())
1753 {
1754 return Result<bool>(ErrorId(hexStringResult.GetErrorId()));
1755 }
1756 string s = "DoKeyUp: " + ToString(cast<Keys>(virtualKeyCode)) + " " + hexStringResult.Value();
1757 auto result = logView->WriteLine(s);
1758 if (result.Error()) return result;
1759 }
1760 Keys key = cast<Keys>(virtualKeyCode);
1761 if (KeyDownHandled() || MenuWantsKeys())
1762 {
1763 return Result<bool>(KeyDownHandled());
1764 }
1765 KeyEventArgs args(key);
1766 auto result = DispatchKeyUp(args);
1767 if (result.Error()) return result;
1768 if (args.errorId != 0)
1769 {
1770 return Result<bool>(ErrorId(args.errorId));
1771 }
1772 if (args.handled)
1773 {
1774 return Result<bool>(true);
1775 }
1776 return Result<bool>(false);
1777 }
1778 [nodiscard]
1779 private Result<bool> DoKeyPress(KeyPressEventArgs& args)
1780 {
1781 LogView* logView = Application.GetLogView();
1782 if (logView != null)
1783 {
1784 auto hexStringResult = ToHexString(cast<uint>(args.keyChar));
1785 if (hexStringResult.Error())
1786 {
1787 return Result<bool>(ErrorId(hexStringResult.GetErrorId()));
1788 }
1789 auto keyCharResult = ToString(args.keyChar);
1790 if (keyCharResult.Error())
1791 {
1792 return Result<bool>(ErrorId(keyCharResult.GetErrorId()));
1793 }
1794 const string& keyCharStr = keyCharResult.Value();
1795 string s = "DoKeyPress: " + keyCharStr + " " + hexStringResult.Value();
1796 auto result = logView->WriteLine(s);
1797 if (result.Error()) return result;
1798 }
1799 if (KeyDownHandled() || MenuWantsKeys())
1800 {
1801 args.handled = KeyDownHandled();
1802 return Result<bool>(true);
1803 }
1804 ResetModifierKeys();
1805 auto result = DispatchKeyPress(args);
1806 if (result.Error()) return result;
1807 if (args.errorId != 0)
1808 {
1809 return Result<bool>(ErrorId(args.errorId));
1810 }
1811 return Result<bool>(true);
1812 }
1813 [nodiscard]
1814 private Result<bool> DispatchKeyPress(KeyPressEventArgs& args)
1815 {
1816 auto result = OnKeyPress(args);
1817 if (result.Error()) return result;
1818 if (!args.handled)
1819 {
1820 Control* parent = ParentControl();
1821 if (parent != null)
1822 {
1823 result = parent->DispatchKeyPress(args);
1824 if (result.Error()) return result;
1825 }
1826 }
1827 return Result<bool>(true);
1828 }
1829 [nodiscard]
1830 private Result<bool> DispatchKeyDown(KeyEventArgs& args)
1831 {
1832 auto result = OnKeyDown(args);
1833 if (result.Error()) return result;
1834 if (args.errorId != 0) return Result<bool>(ErrorId(args.errorId));
1835 if (!args.handled)
1836 {
1837 Control* parent = ParentControl();
1838 if (parent != null)
1839 {
1840 result = parent->DispatchKeyDown(args);
1841 if (result.Error()) return result;
1842 }
1843 }
1844 return Result<bool>(true);
1845 }
1846 [nodiscard]
1847 private Result<bool> DispatchKeyUp(KeyEventArgs& args)
1848 {
1849 auto result = OnKeyUp(args);
1850 if (result.Error()) return result;
1851 if (args.errorId != 0) return Result<bool>(ErrorId(args.errorId));
1852 if (!args.handled)
1853 {
1854 Control* parent = ParentControl();
1855 if (parent != null)
1856 {
1857 result = parent->DispatchKeyUp(args);
1858 if (result.Error()) return result;
1859 }
1860 }
1861 return Result<bool>(true);
1862 }
1863 [nodiscard]
1864 private Result<bool> DoMenu(wchar accessKey, Keys keyCode)
1865 {
1866 ResetKeyDownHandled();
1867 LogView* logView = Application.GetLogView();
1868 if (logView != null)
1869 {
1870 auto hexStringResult = ToHexString(cast<ushort>(accessKey));
1871 if (hexStringResult.Error())
1872 {
1873 return Result<bool>(ErrorId(hexStringResult.GetErrorId()));
1874 }
1875 auto accessKeyResult = ToString(accessKey);
1876 if (accessKeyResult.Error())
1877 {
1878 return Result<bool>(ErrorId(accessKeyResult.GetErrorId()));
1879 }
1880 string s = "MENU: " + accessKeyResult.Value() + " " + hexStringResult.Value();
1881 auto result = logView->WriteLine(s);
1882 if (result.Error()) return result;
1883 }
1884 Window* window = GetWindow();
1885 if (window != null)
1886 {
1887 MenuBar* menuBar = window->GetMenuBar();
1888 if (menuBar != null)
1889 {
1890 bool menuWantsKeys = false;
1891 auto handleResult = menuBar->HandleAccessKey(accessKey, keyCode, menuWantsKeys);
1892 if (handleResult.Error())
1893 {
1894 return Result<bool>(ErrorId(handleResult.GetErrorId()));
1895 }
1896 bool handled = handleResult.Value();
1897 if (handled)
1898 {
1899 SetKeyDownHandled();
1900 }
1901 if (menuWantsKeys)
1902 {
1903 SetMenuWantsKeys();
1904 }
1905 else
1906 {
1907 ResetMenuWantsKeys();
1908 }
1909 return Result<bool>(handled);
1910 }
1911 }
1912 return Result<bool>(false);
1913 }
1914 [nodiscard]
1915 private Result<bool> DoMenu(KeyEventArgs& args)
1916 {
1917 Window* window = GetWindow();
1918 if (window != null)
1919 {
1920 MenuBar* menuBar = window->GetMenuBar();
1921 if (menuBar != null)
1922 {
1923 auto result = menuBar->DoKeyDown(args);
1924 if (result.Error()) return result;
1925 }
1926 }
1927 return Result<bool>(true);
1928 }
1929 [nodiscard]
1930 private Result<bool> DoVScroll(ushort request)
1931 {
1932 ScrollEventArgs args(request);
1933 auto result = OnVScroll(args);
1934 if (result.Error()) return result;
1935 if (args.errorId != 0)
1936 {
1937 return Result<bool>(ErrorId(args.errorId));
1938 }
1939 return Result<bool>(true);
1940 }
1941 [nodiscard]
1942 private Result<bool> DoHScroll(ushort request)
1943 {
1944 ScrollEventArgs args(request);
1945 auto result = OnHScroll(args);
1946 if (result.Error()) return result;
1947 if (args.errorId != 0)
1948 {
1949 return Result<bool>(ErrorId(args.errorId));
1950 }
1951 return Result<bool>(true);
1952 }
1953 [nodiscard]
1954 private Result<bool> DoMouseWheel(MouseWheelEventArgs& args)
1955 {
1956 return OnMouseWheel(args);
1957 }
1958 [nodiscard]
1959 private Result<bool> DoSetFocus()
1960 {
1961 if (this is Window*)
1962 {
1963 Window* thisWindow = cast<Window*>(this);
1964 if (thisWindow->IsMainWindow())
1965 {
1966 auto result = OnGotFocus();
1967 if (result.Error()) return result;
1968 return Result<bool>(true);
1969 }
1970 }
1971 SetFocused();
1972 auto result = DoGotFocus();
1973 if (result.Error()) return result;
1974 result = DoCreateAndShowCaret();
1975 if (result.Error()) return result;
1976 return Result<bool>(true);
1977 }
1978 [nodiscard]
1979 private Result<bool> DoGotFocus()
1980 {
1981 auto result = OnGotFocus();
1982 if (result.Error()) return result;
1983 Control* parentControl = ParentControl();
1984 if (parentControl != null)
1985 {
1986 ControlEventArgs args(this);
1987 auto result = parentControl->OnChildGotFocus(args);
1988 if (result.Error()) return result;
1989 if (args.errorId != 0)
1990 {
1991 return Result<bool>(ErrorId(args.errorId));
1992 }
1993 }
1994 return Result<bool>(true);
1995 }
1996 [nodiscard]
1997 protected virtual Result<bool> OnGotFocus()
1998 {
1999 gotFocusEvent.Fire();
2000 return Result<bool>(true);
2001 }
2002 [nodiscard]
2003 protected virtual Result<bool> OnChildGotFocus(ControlEventArgs& args)
2004 {
2005 childGotFocusEvent.Fire(args);
2006 return Result<bool>(true);
2007 }
2008 [nodiscard]
2009 private Result<bool> DoKillFocus()
2010 {
2011 ResetFocused();
2012 auto result = DoLostFocus();
2013 if (result.Error()) return result;
2014 result = DoDestroyCaret();
2015 if (result.Error()) return result;
2016 return Result<bool>(true);
2017 }
2018 [nodiscard]
2019 private Result<bool> DoLostFocus()
2020 {
2021 auto result = OnLostFocus();
2022 if (result.Error()) return result;
2023 Control* parentControl = ParentControl();
2024 if (parentControl != null)
2025 {
2026 ControlEventArgs args(this);
2027 auto result = parentControl->OnChildLostFocus(args);
2028 if (result.Error()) return result;
2029 if (args.errorId != 0)
2030 {
2031 return Result<bool>(ErrorId(args.errorId));
2032 }
2033 }
2034 return Result<bool>(true);
2035 }
2036 [nodiscard]
2037 protected virtual Result<bool> OnLostFocus()
2038 {
2039 lostFocusEvent.Fire();
2040 return Result<bool>(true);
2041 }
2042 [nodiscard]
2043 protected virtual Result<bool> OnChildLostFocus(ControlEventArgs& args)
2044 {
2045 childLostFocusEvent.Fire(args);
2046 return Result<bool>(true);
2047 }
2048 protected virtual bool IsDecoratorControl() const
2049 {
2050 return false;
2051 }
2052 [nodiscard]
2053 protected virtual Result<bool> TranslateChildGraphics(Graphics& graphics)
2054 {
2055 Control* parentControl = ParentControl();
2056 if (parentControl != null)
2057 {
2058 auto result = parentControl->TranslateChildGraphics(graphics);
2059 if (result.Error())
2060 {
2061 return Result<bool>(ErrorId(result.GetErrorId()));
2062 }
2063 }
2064 return Result<bool>(true);
2065 }
2066 protected virtual void TranslateMousePos(Point& location)
2067 {
2068 Control* parentControl = ParentControl();
2069 if (parentControl != null)
2070 {
2071 parentControl->TranslateMousePos(location);
2072 }
2073 }
2074 protected virtual void TranslateContentLocation(Point& location)
2075 {
2076 Control* parentControl = ParentControl();
2077 if (parentControl != null)
2078 {
2079 parentControl->TranslateContentLocation(location);
2080 }
2081 }
2082 [nodiscard]
2083 private Result<bool> DoPaint()
2084 {
2085 if (handle == null) return Result<bool>(false);
2086 void* paintStruct = null;
2087 Result<void*> hdcResult = BeginPaint(handle, paintStruct);
2088 if (hdcResult.Error())
2089 {
2090 return Result<bool>(ErrorId(hdcResult.GetErrorId()));
2091 }
2092 void* hdc = hdcResult.Value();
2093 Rect clipRect;
2094 WinGetClipRect(paintStruct, clipRect.location.x, clipRect.location.y, clipRect.size.w, clipRect.size.h);
2095 PaintGuard paintGuard(hdc, paintStruct);
2096 Graphics graphics(hdc);
2097 if (graphics.Error())
2098 {
2099 return Result<bool>(ErrorId(graphics.GetErrorId()));
2100 }
2101 PaintEventArgs args(graphics, clipRect);
2102 PaintEventArgs* argsPtr = &args;
2103 if (!IsDecoratorControl())
2104 {
2105 auto result = TranslateChildGraphics(graphics);
2106 if (result.Error())
2107 {
2108 return Result<bool>(ErrorId(result.GetErrorId()));
2109 }
2110 }
2111 if (Focused())
2112 {
2113 --caretShowCount;
2114 }
2115 UniquePtr<PaintEventArgs> bufferPaintArgs;
2116 if (IsDoubleBuffered())
2117 {
2118 if (buffer.IsNull() || buffer->GetSize() != GetSize())
2119 {
2120 buffer.Reset(new Buffer(GetSize(), graphics));
2121 if (buffer->Error())
2122 {
2123 return Result<bool>(ErrorId(buffer->GetErrorId()));
2124 }
2125 }
2126 auto clearResult = buffer->BitmapGraphics().Clear(BackgroundColor());
2127 if (clearResult.Error())
2128 {
2129 return Result<bool>(ErrorId(clearResult.GetErrorId()));
2130 }
2131 bufferPaintArgs.Reset(new PaintEventArgs(buffer->BitmapGraphics(), clipRect));
2132 argsPtr = bufferPaintArgs.Get();
2133 Matrix matrix;
2134 auto transformResult = graphics.GetTransform(matrix);
2135 if (transformResult.Error())
2136 {
2137 return Result<bool>(ErrorId(transformResult.GetErrorId()));
2138 }
2139 auto setTransformResult = buffer->BitmapGraphics().SetTransform(matrix);
2140 if (setTransformResult.Error())
2141 {
2142 return Result<bool>(ErrorId(setTransformResult.GetErrorId()));
2143 }
2144 }
2145 auto paintResult = OnPaint(*argsPtr);
2146 if (paintResult.Error())
2147 {
2148 return Result<bool>(ErrorId(paintResult.GetErrorId()));
2149 }
2150 if (argsPtr->errorId != 0)
2151 {
2152 return Result<bool>(ErrorId(argsPtr->errorId));
2153 }
2154 if (IsDoubleBuffered())
2155 {
2156 Graphics windowGraphics(hdc);
2157 if (windowGraphics.Error())
2158 {
2159 return Result<bool>(ErrorId(windowGraphics.GetErrorId()));
2160 }
2161 auto drawResult = buffer->Draw(windowGraphics);
2162 if (drawResult.Error())
2163 {
2164 return Result<bool>(ErrorId(drawResult.GetErrorId()));
2165 }
2166 }
2167 if (Focused() && CaretCreated())
2168 {
2169 auto result = ShowCaret();
2170 if (result.Error()) return result;
2171 }
2172 return Result<bool>(true);
2173 }
2174 [nodiscard]
2175 protected virtual Result<bool> OnPaint(PaintEventArgs& args)
2176 {
2177 paintEvent.Fire(args);
2178 return Result<bool>(true);
2179 }
2180 [nodiscard]
2181 internal virtual Result<bool> PaintAll(PaintEventArgs& args, bool skipMenuBar)
2182 {
2183 auto paintResult = OnPaint(args);
2184 if (paintResult.Error())
2185 {
2186 return Result<bool>(ErrorId(paintResult.GetErrorId()));
2187 }
2188 return Result<bool>(true);
2189 }
2190 [nodiscard]
2191 private Result<bool> DoCreateAndShowCaret()
2192 {
2193 if (Focused())
2194 {
2195 auto result = CreateCaret();
2196 if (result.Error()) return result;
2197 SetCaretCreated();
2198 result = SetCaretLocation();
2199 if (result.Error()) return result;
2200 result = ShowCaret();
2201 if (result.Error()) return result;
2202 }
2203 return Result<bool>(true);
2204 }
2205 [nodiscard]
2206 public virtual Result<bool> CreateCaret()
2207 {
2208 auto result = System.Windows.API.CreateCaret(Handle(), null, 1, 15);
2209 if (result.Error()) return result;
2210 return Result<bool>(true);
2211 }
2212 [nodiscard]
2213 private Result<bool> DoDestroyCaret()
2214 {
2215 if (CaretCreated())
2216 {
2217 auto result = HideCaret();
2218 if (result.Error()) return result;
2219 ResetCaretCreated();
2220 result = DestroyCaret();
2221 if (result.Error()) return result;
2222 }
2223 return Result<bool>(true);
2224 }
2225 [nodiscard]
2226 public virtual Result<bool> DestroyCaret()
2227 {
2228 auto result = System.Windows.API.DestroyCaret();
2229 if (result.Error()) return result;
2230 caretShowCount = 0;
2231 return Result<bool>(true);
2232 }
2233 [nodiscard]
2234 public Result<bool> ShowCaret()
2235 {
2236 auto result = System.Windows.API.ShowCaret(Handle());
2237 if (result.Error()) return result;
2238 ++caretShowCount;
2239 return Result<bool>(true);
2240 }
2241 [nodiscard]
2242 public Result<bool> HideCaret()
2243 {
2244 auto result = System.Windows.API.HideCaret(Handle());
2245 if (result.Error()) return result;
2246 --caretShowCount;
2247 return Result<bool>(true);
2248 }
2249 public inline int CaretShowCount() const
2250 {
2251 return caretShowCount;
2252 }
2253 public Result<Point> GetCaretPos() const
2254 {
2255 return System.Windows.API.GetCaretPos();
2256 }
2257 [nodiscard]
2258 public Result<bool> SetCaretPos(const Point& caretPos)
2259 {
2260 if (CaretCreated())
2261 {
2262 auto result = System.Windows.API.SetCaretPos(caretPos);
2263 if (result.Error()) return result;
2264 }
2265 return Result<bool>(true);
2266 }
2267 [nodiscard]
2268 private Result<bool> DoMouseMove(MouseEventArgs& args)
2269 {
2270 if (!MouseInClient())
2271 {
2272 SetMouseInClient();
2273 auto result = SetCursor();
2274 if (result.Error()) return result;
2275 EnterLeaveEventArgs enterArgs;
2276 result = OnMouseEnter(enterArgs);
2277 if (result.Error()) return result;
2278 if (enterArgs.errorId != 0)
2279 {
2280 return Result<bool>(ErrorId(enterArgs.errorId));
2281 }
2282 if (result.Error()) return result;
2283 WinTrackMouseEvent(handle, TME_LEAVE, HOVER_DEFAULT);
2284 }
2285 else
2286 {
2287 if (!IsDecoratorControl())
2288 {
2289 TranslateMousePos(args.location);
2290 }
2291 auto result = SetCursor();
2292 if (result.Error())
2293 {
2294 return Result<bool>(ErrorId(result.GetErrorId()));
2295 }
2296 result = OnMouseMove(args);
2297 if (result.Error()) return result;
2298 }
2299 if (mouseHoverMs != 0u && !MouseHoverTimerStarted())
2300 {
2301 Point pt = args.location;
2302 int dx = Abs(mouseHoverLocation.x - pt.x);
2303 int dy = Abs(mouseHoverLocation.y - pt.y);
2304 if (dx > mouseHoverRectSize.w || dy > mouseHoverRectSize.h)
2305 {
2306 SetMouseHoverTimerStarted();
2307 mouseHoverLocation = pt;
2308 auto result = SetTimer(mouseHoverTimerId, mouseHoverMs);
2309 if (result.Error()) return result;
2310 }
2311 }
2312 return Result<bool>(true);
2313 }
2314 public void SetMouseHoverMs(uint mouseHoverMs_)
2315 {
2316 mouseHoverMs = mouseHoverMs_;
2317 }
2318 public uint MouseHoverMs() const
2319 {
2320 return mouseHoverMs;
2321 }
2322 public void SetMouseHoverRectSize(const Size& mouseHoverRectSize_)
2323 {
2324 mouseHoverRectSize = mouseHoverRectSize_;
2325 }
2326 public const Size& MouseHoverRectSize() const
2327 {
2328 return mouseHoverRectSize;
2329 }
2330 [nodiscard]
2331 private Result<bool> DoMouseHover()
2332 {
2333 ResetMouseHoverTimerStarted();
2334 auto result = KillTimer(mouseHoverTimerId);
2335 if (result.Error()) return result;
2336 Point pt;
2337 result = GetCursorPos(pt.x, pt.y);
2338 if (result.Error()) return result;
2339 auto ptResult = ScreenToClient(pt);
2340 if (ptResult.Error())
2341 {
2342 return Result<bool>(ErrorId(ptResult.GetErrorId()));
2343 }
2344 pt = ptResult.Value();
2345 if (!IsDecoratorControl())
2346 {
2347 TranslateMousePos(pt);
2348 }
2349 int dx = Abs(mouseHoverLocation.x - pt.x);
2350 int dy = Abs(mouseHoverLocation.y - pt.y);
2351 if (dx <= mouseHoverRectSize.w && dy <= mouseHoverRectSize.h)
2352 {
2353 MouseEventArgs args;
2354 args.location = pt;
2355 OnMouseHover(args);
2356 }
2357 return Result<bool>(true);
2358 }
2359 [nodiscard]
2360 private Result<bool> DoMouseLeave()
2361 {
2362 ResetMouseInClient();
2363 ResetLButtonPressed();
2364 EnterLeaveEventArgs leaveArgs;
2365 auto result = OnMouseLeave(leaveArgs);
2366 if (leaveArgs.errorId != 0)
2367 {
2368 return Result<bool>(ErrorId(leaveArgs.errorId));
2369 }
2370 if (result.Error()) return result;
2371 return Result<bool>(true);
2372 }
2373 [nodiscard]
2374 private Result<bool> DoMouseDown(MouseEventArgs& args)
2375 {
2376 if (!IsDecoratorControl())
2377 {
2378 TranslateMousePos(args.location);
2379 }
2380 auto result = OnMouseDown(args);
2381 if (result.Error()) return result;
2382 if (args.errorId != 0)
2383 {
2384 return Result<bool>(ErrorId(args.errorId));
2385 }
2386 if ((args.buttons & MouseButtons.lbutton) != 0)
2387 {
2388 SetLButtonPressed();
2389 }
2390 if (args.errorId != 0)
2391 {
2392 return Result<bool>(ErrorId(args.errorId));
2393 }
2394 return Result<bool>(true);
2395 }
2396 [nodiscard]
2397 private Result<bool> DoMouseUp(MouseEventArgs& args)
2398 {
2399 if (!IsDecoratorControl())
2400 {
2401 TranslateMousePos(args.location);
2402 }
2403 auto result = OnMouseUp(args);
2404 if (result.Error()) return result;
2405 if ((args.buttons & MouseButtons.lbutton) != 0)
2406 {
2407 if (LButtonPressed())
2408 {
2409 ResetLButtonPressed();
2410 ClickEventArgs args;
2411 result = this->OnClick(args);
2412 if (result.Error()) return result;
2413 if (args.errorId != 0)
2414 {
2415 return Result<bool>(ErrorId(args.errorId));
2416 }
2417 }
2418 }
2419 Window* mainWindow = Application.MainWindow();
2420 if (mainWindow != null)
2421 {
2422 auto result = mainWindow->MouseUpNotificationInternal(args);
2423 if (result.Error()) return result;
2424 }
2425 if (args.errorId != 0)
2426 {
2427 return Result<bool>(ErrorId(args.errorId));
2428 }
2429 return Result<bool>(true);
2430 }
2431 [nodiscard]
2432 private Result<bool> DoMouseDoubleClick(MouseEventArgs& args)
2433 {
2434 if (!IsDecoratorControl())
2435 {
2436 TranslateMousePos(args.location);
2437 }
2438 auto result = OnMouseDoubleClick(args);
2439 if (result.Error()) return result;
2440 if (args.errorId != 0)
2441 {
2442 return Result<bool>(ErrorId(args.errorId));
2443 }
2444 return Result<bool>(true);
2445 }
2446 [nodiscard]
2447 public Result<bool> SetTimer(uint timerId, uint elapseMs)
2448 {
2449 auto result = SetTimer(Handle(), timerId, elapseMs);
2450 if (result.Error()) return result;
2451 return Result<bool>(true);
2452 }
2453 [nodiscard]
2454 public Result<bool> KillTimer(uint timerId)
2455 {
2456 auto result = KillTimer(Handle(), timerId);
2457 if (result.Error()) return result;
2458 return Result<bool>(true);
2459 }
2460 [nodiscard]
2461 private Result<bool> DoTimer(ulong timerId)
2462 {
2463 TimerEventArgs timerEventArgs(timerId);
2464 auto result = OnTimer(timerEventArgs);
2465 if (result.Error()) return result;
2466 if (timerEventArgs.errorId != 0)
2467 {
2468 return Result<bool>(ErrorId(timerEventArgs.errorId));
2469 }
2470 return Result<bool>(true);
2471 }
2472 [nodiscard]
2473 protected virtual Result<bool> OnTimer(TimerEventArgs& args)
2474 {
2475 if (args.timerId == mouseHoverTimerId)
2476 {
2477 auto result = DoMouseHover();
2478 if (result.Error()) return result;
2479 }
2480 else
2481 {
2482 timerEvent.Fire(args);
2483 }
2484 return Result<bool>(true);
2485 }
2486 [nodiscard]
2487 protected virtual Result<bool> SetCursor()
2488 {
2489 SetCursor(&arrowCursor);
2490 return Result<bool>(true);
2491 }
2492 [nodiscard]
2493 protected virtual Result<bool> OnMouseEnter(EnterLeaveEventArgs& args)
2494 {
2495 mouseEnterEvent.Fire(args);
2496 return Result<bool>(true);
2497 }
2498 [nodiscard]
2499 protected virtual Result<bool> OnMouseMove(MouseEventArgs& args)
2500 {
2501 mouseMoveEvent.Fire(args);
2502 return Result<bool>(true);
2503 }
2504 protected virtual void OnMouseHover(MouseEventArgs& args)
2505 {
2506 mouseHoverEvent.Fire(args);
2507 }
2508 [nodiscard]
2509 protected virtual Result<bool> OnMouseLeave(EnterLeaveEventArgs& args)
2510 {
2511 mouseLeaveEvent.Fire(args);
2512 return Result<bool>(true);
2513 }
2514 [nodiscard]
2515 protected virtual Result<bool> OnMouseDown(MouseEventArgs& args)
2516 {
2517 mouseDownEvent.Fire(args);
2518 if (!(this is MenuItem*) && !(this is MenuControl*))
2519 {
2520 Window* window = GetWindow();
2521 if (window != null)
2522 {
2523 MenuBar* menuBar = window->GetMenuBar();
2524 if (menuBar != null)
2525 {
2526 auto result = menuBar->CloseMenu();
2527 if (result.Error()) return result;
2528 }
2529 }
2530 }
2531 return Result<bool>(true);
2532 }
2533 [nodiscard]
2534 protected virtual Result<bool> OnMouseUp(MouseEventArgs& args)
2535 {
2536 mouseUpEvent.Fire(args);
2537 return Result<bool>(true);
2538 }
2539 [nodiscard]
2540 protected virtual Result<bool> OnMouseDoubleClick(MouseEventArgs& args)
2541 {
2542 mouseDoubleClickEvent.Fire(args);
2543 return Result<bool>(true);
2544 }
2545 [nodiscard]
2546 protected virtual Result<bool> OnKeyPress(KeyPressEventArgs& args)
2547 {
2548 keyPressEvent.Fire(args);
2549 return Result<bool>(true);
2550 }
2551 [nodiscard]
2552 protected virtual Result<bool> OnKeyDown(KeyEventArgs& args)
2553 {
2554 keyDownEvent.Fire(args);
2555 return Result<bool>(true);
2556 }
2557 [nodiscard]
2558 protected virtual Result<bool> OnKeyUp(KeyEventArgs& args)
2559 {
2560 keyUpEvent.Fire(args);
2561 return Result<bool>(true);
2562 }
2563 [nodiscard]
2564 protected virtual Result<bool> OnClick(ClickEventArgs& args)
2565 {
2566 clickEvent.Fire(args);
2567 return Result<bool>(true);
2568 }
2569 [nodiscard]
2570 protected virtual Result<bool> OnRightClick(RightClickEventArgs& args)
2571 {
2572 rightClickEvent.Fire(args);
2573 return Result<bool>(true);
2574 }
2575 [nodiscard]
2576 protected virtual Result<bool> OnCreated()
2577 {
2578 SetBaseOnCreatedCalled();
2579 createdEvent.Fire();
2580 return Result<bool>(true);
2581 }
2582 protected virtual void OnDestroyed()
2583 {
2584 destroyedEvent.Fire();
2585 }
2586 [nodiscard]
2587 protected virtual Result<bool> OnShown()
2588 {
2589 shownEvent.Fire();
2590 return Result<bool>(true);
2591 }
2592 [nodiscard]
2593 protected virtual Result<bool> OnHScroll(ScrollEventArgs& args)
2594 {
2595 hscrollEvent.Fire(args);
2596 return Result<bool>(true);
2597 }
2598 [nodiscard]
2599 protected virtual Result<bool> OnVScroll(ScrollEventArgs& args)
2600 {
2601 vscrollEvent.Fire(args);
2602 return Result<bool>(true);
2603 }
2604 [nodiscard]
2605 protected virtual Result<bool> OnMouseWheel(MouseWheelEventArgs& args)
2606 {
2607 mouseWheelEvent.Fire(args);
2608 return Result<bool>(true);
2609 }
2610 [nodiscard]
2611 protected virtual Result<bool> OnControlAdded(ControlEventArgs& args)
2612 {
2613 controlAddedEvent.Fire(args);
2614 return Result<bool>(true);
2615 }
2616 [nodiscard]
2617 public virtual Result<bool> OnControlRemoved(ControlEventArgs& args)
2618 {
2619 controlRemovedEvent.Fire(args);
2620 return Result<bool>(true);
2621 }
2622 public void* GetDC()
2623 {
2624 return GetDC(handle);
2625 }
2626 [nodiscard]
2627 public Result<bool> Invalidate()
2628 {
2629 return InvalidateRect(handle, null, false);
2630 }
2631 [nodiscard]
2632 public Result<bool> Invalidate(const WinRect& rect)
2633 {
2634 return InvalidateRect(handle, &rect, false);
2635 }
2636 [nodiscard]
2637 public Result<bool> Invalidate(const WinRect& rect, bool eraseBackground)
2638 {
2639 return InvalidateRect(handle, &rect, eraseBackground);
2640 }
2641 [nodiscard]
2642 public Result<bool> Invalidate(const Rect& rect)
2643 {
2644 return Invalidate(rect.ToWinRect());
2645 }
2646 [nodiscard]
2647 public Result<bool> Invalidate(const Rect& rect, bool eraseBackground)
2648 {
2649 return Invalidate(rect.ToWinRect(), eraseBackground);
2650 }
2651 public inline const Color& BackgroundColor() const
2652 {
2653 return backgroundColor;
2654 }
2655 [nodiscard]
2656 public Result<bool> SetBackgroundColor(const Color& backgroundColor_)
2657 {
2658 backgroundColor = backgroundColor_;
2659 return Invalidate();
2660 }
2661 public const Font& GetFont() const
2662 {
2663 if (!font.IsNull())
2664 {
2665 return font;
2666 }
2667 else
2668 {
2669 Control* parent = ParentControl();
2670 if (parent != null)
2671 {
2672 return parent->GetFont();
2673 }
2674 else
2675 {
2676 return font;
2677 }
2678 }
2679 }
2680 public void SetFont(const Font& font_)
2681 {
2682 font = font_;
2683 }
2684 public void SetFont(Font&& font_)
2685 {
2686 font = Rvalue(font_);
2687 }
2688 [nodiscard]
2689 public Result<FontHandle*> GetFontHandle(Graphics& graphics)
2690 {
2691 if (!fontHandle.IsNull())
2692 {
2693 return Result<FontHandle*>(&fontHandle);
2694 }
2695 if (!font.IsNull())
2696 {
2697 auto fontHandleResult = font.ToHFont(graphics);
2698 if (fontHandleResult.Error())
2699 {
2700 return Result<FontHandle*>(ErrorId(fontHandleResult.GetErrorId()));
2701 }
2702 fontHandle = Rvalue(fontHandleResult.Value());
2703 return Result<FontHandle*>(&fontHandle);
2704 }
2705 Control* parent = ParentControl();
2706 if (parent != null)
2707 {
2708 return parent->GetFontHandle(graphics);
2709 }
2710 else
2711 {
2712 return Result<FontHandle*>(&fontHandle);
2713 }
2714 }
2715 public inline void* Handle() const
2716 {
2717 return handle;
2718 }
2719 public inline WindowStyle GetWindowStyle() const
2720 {
2721 return style;
2722 }
2723 public inline ExtendedWindowStyle GetExtendedWindowStyle() const
2724 {
2725 return exStyle;
2726 }
2727 public Event<PaintEventHandler, PaintEventArgs>& PaintEvent()
2728 {
2729 return paintEvent;
2730 }
2731 public Event<MouseEnterEventHandler, EnterLeaveEventArgs>& MouseEnterEvent() const
2732 {
2733 return mouseEnterEvent;
2734 }
2735 public Event<MouseEventHandler, MouseEventArgs>& MouseMoveEvent() const
2736 {
2737 return mouseMoveEvent;
2738 }
2739 public Event<MouseEventHandler, MouseEventArgs>& MouseHoverEvent() const
2740 {
2741 return mouseHoverEvent;
2742 }
2743 public Event<MouseLeaveEventHandler, EnterLeaveEventArgs>& MouseLeaveEvent() const
2744 {
2745 return mouseLeaveEvent;
2746 }
2747 public Event<MouseEventHandler, MouseEventArgs>& MouseDownEvent() const
2748 {
2749 return mouseDownEvent;
2750 }
2751 public Event<MouseEventHandler, MouseEventArgs>& MouseUpEvent() const
2752 {
2753 return mouseUpEvent;
2754 }
2755 public Event<MouseEventHandler, MouseEventArgs>& MouseDoubleClickEvent() const
2756 {
2757 return mouseDoubleClickEvent;
2758 }
2759 public Event<KeyPressEventHandler, KeyPressEventArgs>& KeyPressEvent() const
2760 {
2761 return keyPressEvent;
2762 }
2763 public Event<KeyEventHandler, KeyEventArgs>& KeyDownEvent() const
2764 {
2765 return keyDownEvent;
2766 }
2767 public Event<KeyEventHandler, KeyEventArgs>& KeyUpEvent() const
2768 {
2769 return keyUpEvent;
2770 }
2771 public Event<CreatedEventHandler>& CreatedEvent() const
2772 {
2773 return createdEvent;
2774 }
2775 public Event<DestroyedEventHandler>& DestroyedEvent() const
2776 {
2777 return destroyedEvent;
2778 }
2779 public Event<ShownEventHandler>& ShownEvent() const
2780 {
2781 return shownEvent;
2782 }
2783 public Event<EnabledChangedEventHandler>& EnabledChangedEvent() const
2784 {
2785 return enabledChangedEvent;
2786 }
2787 public Event<VisibleChangedEventHandler>& VisibleChangedEvent() const
2788 {
2789 return visibleChangedEvent;
2790 }
2791 public Event<ClickEventHandler, ClickEventArgs>& ClickEvent() const
2792 {
2793 return clickEvent;
2794 }
2795 public Event<SizeChangedEventHandler, SizeChangedEventArgs>& SizeChangedEvent() const
2796 {
2797 return sizeChangedEvent;
2798 }
2799 public Event<SizeChangingEventHandler, SizeChangingEventArgs> SizeChangingEvent() const
2800 {
2801 return sizeChangingEvent;
2802 }
2803 public Event<ChildSizeChangedEventHandler, ControlEventArgs>& ChildSizeChangedEvent() const
2804 {
2805 return childSizeChangedEvent;
2806 }
2807 public Event<LocationChangedEventHandler>& LocationChangedEvent() const
2808 {
2809 return locationChangedEvent;
2810 }
2811 public Event<ContentChangedEventHandler>& ContentChangedEvent() const
2812 {
2813 return contentChangedEvent;
2814 }
2815 public Event<ChildContentChangedEventHandler, ControlEventArgs>& ChildContentChangedEvent() const
2816 {
2817 return childContentChangedEvent;
2818 }
2819 public Event<ContentLocationChangedEventHandler>& ContentLocationChangedEvent() const
2820 {
2821 return contentLocationChangedEvent;
2822 }
2823 public Event<ChildContentLocationChangedEventHandler, ControlEventArgs>& ChildContentLocationChangedEvent() const
2824 {
2825 return childContentLocationChangedEvent;
2826 }
2827 public Event<ContentSizeChangedEventHandler>& ContentSizeChangedEvent() const
2828 {
2829 return contentSizeChangedEvent;
2830 }
2831 public Event<ChildContentSizeChangedEventHandler, ControlEventArgs>& ChildContentSizeChangedEvent() const
2832 {
2833 return childContentSizeChangedEvent;
2834 }
2835 public Event<TextChangedEventHandler>& TextChangedEvent() const
2836 {
2837 return textChangedEvent;
2838 }
2839 public Event<HScrollEventHandler, ScrollEventArgs>& HScrollEvent() const
2840 {
2841 return hscrollEvent;
2842 }
2843 public Event<VScrollEventHandler, ScrollEventArgs>& VScrollEvent() const
2844 {
2845 return vscrollEvent;
2846 }
2847 public Event<MouseWheelEventHandler, MouseWheelEventArgs>& MouseWheelEvent() const
2848 {
2849 return mouseWheelEvent;
2850 }
2851 public Event<TimerEventHandler, TimerEventArgs>& TimerEvent() const
2852 {
2853 return timerEvent;
2854 }
2855 public Event<GotFocusEventHandler>& GotFocusEvent() const
2856 {
2857 return gotFocusEvent;
2858 }
2859 public Event<LostFocusEventHandler>& LostFocusEvent() const
2860 {
2861 return lostFocusEvent;
2862 }
2863 public Event<ControlEventHandler, ControlEventArgs>& ControlAddedEvent() const
2864 {
2865 return controlAddedEvent;
2866 }
2867 public Event<ControlEventHandler, ControlEventArgs>& ControlRemovedEvent() const
2868 {
2869 return controlRemovedEvent;
2870 }
2871 public Event<RightClickEventHandler, RightClickEventArgs>& RightClickEvent() const
2872 {
2873 return rightClickEvent;
2874 }
2875 public Event<ClipboardUpdateEventHandler>& ClipboadUpdateEvent() const
2876 {
2877 return clipboardUpdateEvent;
2878 }
2879 private inline bool MouseInClient() const
2880 {
2881 return (flags & Flags.mouseInClient) != 0;
2882 }
2883 private inline void SetMouseInClient()
2884 {
2885 flags = cast<Flags>(flags | Flags.mouseInClient);
2886 }
2887 private inline void ResetMouseInClient()
2888 {
2889 flags = cast<Flags>(flags & ~Flags.mouseInClient);
2890 }
2891 private inline bool LButtonPressed() const
2892 {
2893 return (flags & flags.lbuttonPressed) != 0;
2894 }
2895 private inline void SetLButtonPressed()
2896 {
2897 flags = cast<Flags>(flags | Flags.lbuttonPressed);
2898 }
2899 private inline void ResetLButtonPressed()
2900 {
2901 flags = cast<Flags>(flags & ~Flags.lbuttonPressed);
2902 }
2903 private inline bool MenuWantsKeys() const
2904 {
2905 return (flags & flags.menuWantsKeys) != 0;
2906 }
2907 private inline void SetMenuWantsKeys()
2908 {
2909 flags = cast<Flags>(flags | Flags.menuWantsKeys);
2910 }
2911 private inline void ResetMenuWantsKeys()
2912 {
2913 flags = cast<Flags>(flags & ~Flags.menuWantsKeys);
2914 }
2915 private inline bool KeyDownHandled() const
2916 {
2917 return (flags & Flags.keyDownHandled) != 0;
2918 }
2919 private inline void SetKeyDownHandled()
2920 {
2921 flags = cast<Flags>(flags | Flags.keyDownHandled);
2922 }
2923 private inline void ResetKeyDownHandled()
2924 {
2925 flags = cast<Flags>(flags & ~Flags.keyDownHandled);
2926 }
2927 public inline bool Focused() const
2928 {
2929 return (flags & Flags.focused) != 0;
2930 }
2931 private inline void SetFocused()
2932 {
2933 flags = cast<Flags>(flags | Flags.focused);
2934 }
2935 private inline void ResetFocused()
2936 {
2937 flags = cast<Flags>(flags & ~Flags.focused);
2938 }
2939 public inline bool CaretCreated() const
2940 {
2941 return (flags & Flags.caretCreated) != 0;
2942 }
2943 private inline void SetCaretCreated()
2944 {
2945 flags = cast<Flags>(flags | Flags.caretCreated);
2946 }
2947 private inline void ResetCaretCreated()
2948 {
2949 flags = cast<Flags>(flags & ~Flags.caretCreated);
2950 }
2951 private inline bool CaretShown() const
2952 {
2953 return (flags & Flags.caretShown) != 0;
2954 }
2955 private inline void SetCaretShown()
2956 {
2957 flags = cast<Flags>(flags | Flags.caretShown);
2958 }
2959 private inline void ResetCaretShown()
2960 {
2961 flags = cast<Flags>(flags & ~Flags.caretShown);
2962 }
2963 public inline bool IsDisabled() const
2964 {
2965 return (flags & Flags.disabled) != 0;
2966 }
2967 private inline void SetDisabled()
2968 {
2969 flags = cast<Flags>(flags | Flags.disabled);
2970 }
2971 private inline void ResetDisabled()
2972 {
2973 flags = cast<Flags>(flags & ~Flags.disabled);
2974 }
2975 private inline bool Hidden() const
2976 {
2977 return (flags & Flags.hidden) != 0;
2978 }
2979 private inline void SetHidden()
2980 {
2981 flags = cast<Flags>(flags | Flags.hidden);
2982 }
2983 private inline void ResetHidden()
2984 {
2985 flags = cast<Flags>(flags & ~Flags.hidden);
2986 }
2987 public inline bool IsTabStop() const
2988 {
2989 return (flags & Flags.tabStop) != Flags.none;
2990 }
2991 public inline void SetTabStop()
2992 {
2993 flags = cast<Flags>(flags | Flags.tabStop);
2994 }
2995 public inline void ResetTabStop()
2996 {
2997 flags = cast<Flags>(flags & ~Flags.tabStop);
2998 }
2999 internal inline bool BaseOnCreatedCalled() const
3000 {
3001 return (flags & Flags.baseOnCreatedCalled) != Flags.none;
3002 }
3003 internal inline void SetBaseOnCreatedCalled()
3004 {
3005 flags = cast<Flags>(flags | Flags.baseOnCreatedCalled);
3006 }
3007 private inline void ResetBaseOnCreatedCalled()
3008 {
3009 flags = cast<Flags>(flags & ~Flags.baseOnCreatedCalled);
3010 }
3011 private inline bool MouseHoverTimerStarted() const
3012 {
3013 return (flags & Flags.mouseHoverTimerStarted) != Flags.none;
3014 }
3015 private inline void SetMouseHoverTimerStarted()
3016 {
3017 flags = cast<Flags>(flags | Flags.mouseHoverTimerStarted);
3018 }
3019 private inline void ResetMouseHoverTimerStarted()
3020 {
3021 flags = cast<Flags>(flags & ~Flags.mouseHoverTimerStarted);
3022 }
3023 public inline bool IsDoubleBuffered() const
3024 {
3025 return (flags & Flags.doubleBuffered) != Flags.none;
3026 }
3027 public inline void SetDoubleBuffered()
3028 {
3029 flags = cast<Flags>(flags | Flags.doubleBuffered);
3030 }
3031 public inline void ResetDoubleBuffered()
3032 {
3033 flags = cast<Flags>(flags & ~Flags.doubleBuffered);
3034 }
3035 public inline bool IsScrollSubject() const
3036 {
3037 return (flags & Flags.scrollSubject) != Flags.none;
3038 }
3039 public inline void SetScrollSubject()
3040 {
3041 flags = cast<Flags>(flags | Flags.scrollSubject);
3042 }
3043 public inline void ResetScrollSubject()
3044 {
3045 flags = cast<Flags>(flags & ~Flags.scrollSubject);
3046 }
3047 private string windowClassName;
3048 private int windowClassBackgroundColor;
3049 private WindowClassStyle windowClassStyle;
3050 private Color backgroundColor;
3051 private WindowStyle style;
3052 private ExtendedWindowStyle exStyle;
3053 private void* handle;
3054 private string text;
3055 private Point location;
3056 private Size size;
3057 private Point contentLocation;
3058 private Size contentSize;
3059 private int verticalScrollUnit;
3060 private int horizontalScrollUnit;
3061 private Dock dock;
3062 private Anchors anchors;
3063 private Flags flags;
3064 private Keys currentModifierKeys;
3065 private List<Control*> createList;
3066 private Cursor arrowCursor;
3067 private int caretShowCount;
3068 private Font font;
3069 private FontHandle fontHandle;
3070 private void* originalWndProc;
3071 private Size mouseHoverRectSize;
3072 private uint mouseHoverMs;
3073 private Point mouseHoverLocation;
3074 private UniquePtr<Buffer> buffer;
3075 private Event<PaintEventHandler, PaintEventArgs> paintEvent;
3076 private Event<MouseEnterEventHandler, EnterLeaveEventArgs> mouseEnterEvent;
3077 private Event<MouseEventHandler, MouseEventArgs> mouseMoveEvent;
3078 private Event<MouseEventHandler, MouseEventArgs> mouseHoverEvent;
3079 private Event<MouseLeaveEventHandler, EnterLeaveEventArgs> mouseLeaveEvent;
3080 private Event<MouseEventHandler, MouseEventArgs> mouseDownEvent;
3081 private Event<MouseEventHandler, MouseEventArgs> mouseUpEvent;
3082 private Event<MouseEventHandler, MouseEventArgs> mouseDoubleClickEvent;
3083 private Event<KeyPressEventHandler, KeyPressEventArgs> keyPressEvent;
3084 private Event<KeyEventHandler, KeyEventArgs> keyDownEvent;
3085 private Event<KeyEventHandler, KeyEventArgs> keyUpEvent;
3086 private Event<ClickEventHandler, ClickEventArgs> clickEvent;
3087 private Event<CreatedEventHandler> createdEvent;
3088 private Event<DestroyedEventHandler> destroyedEvent;
3089 private Event<ShownEventHandler> shownEvent;
3090 private Event<EnabledChangedEventHandler> enabledChangedEvent;
3091 private Event<VisibleChangedEventHandler> visibleChangedEvent;
3092 private Event<SizeChangedEventHandler, SizeChangedEventArgs> sizeChangedEvent;
3093 private Event<SizeChangingEventHandler, SizeChangingEventArgs> sizeChangingEvent;
3094 private Event<ChildSizeChangedEventHandler, ControlEventArgs> childSizeChangedEvent;
3095 private Event<LocationChangedEventHandler> locationChangedEvent;
3096 private Event<ContentChangedEventHandler> contentChangedEvent;
3097 private Event<ChildContentChangedEventHandler, ControlEventArgs> childContentChangedEvent;
3098 private Event<ContentLocationChangedEventHandler> contentLocationChangedEvent;
3099 private Event<ChildContentLocationChangedEventHandler, ControlEventArgs> childContentLocationChangedEvent;
3100 private Event<ContentSizeChangedEventHandler> contentSizeChangedEvent;
3101 private Event<ChildContentSizeChangedEventHandler, ControlEventArgs> childContentSizeChangedEvent;
3102 private Event<TextChangedEventHandler> textChangedEvent;
3103 private Event<HScrollEventHandler, ScrollEventArgs> hscrollEvent;
3104 private Event<VScrollEventHandler, ScrollEventArgs> vscrollEvent;
3105 private Event<MouseWheelEventHandler, MouseWheelEventArgs> mouseWheelEvent;
3106 private Event<TimerEventHandler, TimerEventArgs> timerEvent;
3107 private Event<GotFocusEventHandler> gotFocusEvent;
3108 private Event<LostFocusEventHandler> lostFocusEvent;
3109 private Event<ChildGotFocusEventHandler, ControlEventArgs> childGotFocusEvent;
3110 private Event<ChildLostFocusEventHandler, ControlEventArgs> childLostFocusEvent;
3111 private Event<ControlEventHandler, ControlEventArgs> controlAddedEvent;
3112 private Event<ControlEventHandler, ControlEventArgs> controlRemovedEvent;
3113 private Event<RightClickEventHandler, RightClickEventArgs> rightClickEvent;
3114 private Event<ClipboardUpdateEventHandler> clipboardUpdateEvent;
3115 }