1 // =================================
   2 // Copyright (c) 2024 Seppo Laakko
   3 // Distributed under the MIT license
   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(88);
  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 = 0mouseInClient = 1 << 0lbuttonPressed = 1 << 1menuWantsKeys = 1 << 2keyDownHandled = 1 << 3focused = 1 << 4
 192             caretCreated = 1 << 5caretShown = 1 << 6disabled = 1 << 7hidden = 1 << 8tabStop = 1 << 9baseOnCreatedCalled = 1 << 10
 193             mouseHoverTimerStarted = 1 << 11doubleBuffered = 1 << 12scrollSubject = 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(00)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(00)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(1010);
 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()styleexStylelocationsizeparentControl);
 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()windowClassStylewindowClassBackgroundColor);
 331                 if (windowClassResult.Error())
 332                 {
 333                     return Result<bool>(ErrorId(windowClassResult.GetErrorId()));
 334                 }
 335                 ushort windowClass = windowClassResult.Value();
 336                 auto handleResult = CreateWindowByClassAtom(windowClasstext.Chars()styleexStylelocationsizeparentControl);
 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(handleparentWindow->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(handleenable);
 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(handleshowCommand);
 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(handletext);
 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(handlelocationsizetrue);
 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& szuint 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(sizesz);
 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(szSIZE_RESTORED);
 760                 if (result.Error()) return result;
 761                 if (handle != null)
 762                 {
 763                     result = MoveWindow(handlelocationsizetrue);
 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_SETFONTcast<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<intint> GetScrollUnits() const
 899         {
 900             return MakePair(verticalScrollUnithorizontalScrollUnit);
 901         }
 902         [nodiscard]
 903         protected virtual Result<bool> SetCaretLocation()
 904         {
 905             return SetCaretPos(Point(00));
 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.wparentLoc.y);
 954                     parentRect.size = Size(parentSize.w - size.wparentSize.h);
 955                     if (Debug.Docking())
 956                     {
 957                         if (logView != null)
 958                         {
 959                             auto result = logView->WriteLine("Dock.left " + text + ": [" + Rect(newLocationnewSize).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.xparentLoc.y + size.h);
 970                     parentRect.size = Size(parentSize.wparentSize.h - size.h);
 971                     if (Debug.Docking())
 972                     {
 973                         if (logView != null)
 974                         {
 975                             auto result = logView->WriteLine("Dock.top " + text + ": [" + Rect(newLocationnewSize).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.wparentLoc.y);
 984                     newSize.h = parentSize.h;
 985                     parentRect.size = Size(parentSize.w - size.wparentSize.h);
 986                     if (Debug.Docking())
 987                     {
 988                         if (logView != null)
 989                         {
 990                             auto result = logView->WriteLine("Dock.right " + text + ": [" + Rect(newLocationnewSize).ToString() + "], [" + parentRect.ToString() + "]");
 991                             if (result.Error()) return result;
 992                         }
 993                     }
 994                     break;
 995                 }
 996                 case Dock.bottom:
 997                 {
 998                     newLocation = Point(parentLoc.xparentLoc.y + parentSize.h - size.h);
 999                     newSize.w = parentSize.w;
1000                     parentRect.size = Size(parentSize.wparentSize.h - size.h);
1001                     if (Debug.Docking())
1002                     {
1003                         if (logView != null)
1004                         {
1005                             auto result = logView->WriteLine("Dock.bottom " + text + ": [" + Rect(newLocationnewSize).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(newLocationnewSize).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(handlelocationsizetrue);
1035                 if (result.Error()) return result;
1036             }
1037             return Result<bool>(true);
1038         }
1039         [nodiscard]
1040         internal Result<bool> MoveWindow(int dxint 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(handlelocationsizetrue);
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(handlepoint);
1101         }
1102         [nodiscard]
1103         public Result<Point> ScreenToClient(const Point& point) const
1104         {
1105             return ScreenToClient(handlepoint);
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                 // If this control has subclassed a standard Windows control for receiving WM_COMMAND notifications, first set address of original window procedure in the message:
1183                 // Currently only GroupBox does this.
1184                 if (message.originalWndProc == null)
1185                 {
1186                     message.originalWndProc = originalWndProc;
1187                 }
1188                 // If this message is not a WM_COMMAND and not a WM_DESTROY message, return without processing the message.
1189                 // Original window procedure will be called in all cases after returning from Application.ProcessMessage.
1190                 if (message.msg != WM_COMMAND && message.msg != WM_DESTROY)
1191                 {
1192                     return Result<bool>(false);
1193                 }
1194                 // otherwise proceed to process the WM_COMMAND notification or WM_DESTROY message...
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.wparammessage.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(newSizewindowState);
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(handleoriginalWndProc);
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 wparamlong 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(accessKeyKeys.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 accessKeyKeys 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(accessKeykeyCodemenuWantsKeys);
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(handlepaintStruct);
2088             if (hdcResult.Error())
2089             {
2090                 return Result<bool>(ErrorId(hdcResult.GetErrorId()));
2091             }
2092             void* hdc = hdcResult.Value();
2093             Rect clipRect;
2094             WinGetClipRect(paintStructclipRect.location.xclipRect.location.yclipRect.size.wclipRect.size.h);
2095             PaintGuard paintGuard(hdcpaintStruct);
2096             Graphics graphics(hdc);
2097             if (graphics.Error())
2098             {
2099                 return Result<bool>(ErrorId(graphics.GetErrorId()));
2100             }
2101             PaintEventArgs args(graphicsclipRect);
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& argsbool 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()null115);
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(handleTME_LEAVEHOVER_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(mouseHoverTimerIdmouseHoverMs);
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.xpt.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 timerIduint elapseMs)
2448         {
2449             auto result = SetTimer(Handle()timerIdelapseMs);
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(handlenullfalse);
2630         }
2631         [nodiscard]
2632         public Result<bool> Invalidate(const WinRect& rect)
2633         {
2634             return InvalidateRect(handle&rectfalse);
2635         }
2636         [nodiscard]
2637         public Result<bool> Invalidate(const WinRect& rectbool eraseBackground)
2638         {
2639             return InvalidateRect(handle&recteraseBackground);
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& rectbool 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<PaintEventHandlerPaintEventArgs>& PaintEvent()
2728         {
2729             return paintEvent;
2730         }
2731         public Event<MouseEnterEventHandlerEnterLeaveEventArgs>& MouseEnterEvent() const
2732         {
2733             return mouseEnterEvent;
2734         }
2735         public Event<MouseEventHandlerMouseEventArgs>& MouseMoveEvent() const
2736         {
2737             return mouseMoveEvent;
2738         }
2739         public Event<MouseEventHandlerMouseEventArgs>& MouseHoverEvent() const
2740         {
2741             return mouseHoverEvent;
2742         }
2743         public Event<MouseLeaveEventHandlerEnterLeaveEventArgs>& MouseLeaveEvent() const
2744         {
2745             return mouseLeaveEvent;
2746         }
2747         public Event<MouseEventHandlerMouseEventArgs>& MouseDownEvent() const
2748         {
2749             return mouseDownEvent;
2750         }
2751         public Event<MouseEventHandlerMouseEventArgs>& MouseUpEvent() const
2752         {
2753             return mouseUpEvent;
2754         }
2755         public Event<MouseEventHandlerMouseEventArgs>& MouseDoubleClickEvent() const
2756         {
2757             return mouseDoubleClickEvent;
2758         }
2759         public Event<KeyPressEventHandlerKeyPressEventArgs>& KeyPressEvent() const
2760         {
2761             return keyPressEvent;
2762         }
2763         public Event<KeyEventHandlerKeyEventArgs>& KeyDownEvent() const
2764         {
2765             return keyDownEvent;
2766         }
2767         public Event<KeyEventHandlerKeyEventArgs>& 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<ClickEventHandlerClickEventArgs>& ClickEvent() const
2792         {
2793             return clickEvent;
2794         }
2795         public Event<SizeChangedEventHandlerSizeChangedEventArgs>& SizeChangedEvent() const
2796         {
2797             return sizeChangedEvent;
2798         }
2799         public Event<SizeChangingEventHandlerSizeChangingEventArgs> SizeChangingEvent() const
2800         {
2801             return sizeChangingEvent;
2802         }
2803         public Event<ChildSizeChangedEventHandlerControlEventArgs>& 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<ChildContentChangedEventHandlerControlEventArgs>& ChildContentChangedEvent() const
2816         {
2817             return childContentChangedEvent;
2818         }
2819         public Event<ContentLocationChangedEventHandler>& ContentLocationChangedEvent() const
2820         {
2821             return contentLocationChangedEvent;
2822         }
2823         public Event<ChildContentLocationChangedEventHandlerControlEventArgs>& ChildContentLocationChangedEvent() const
2824         {
2825             return childContentLocationChangedEvent;
2826         }
2827         public Event<ContentSizeChangedEventHandler>& ContentSizeChangedEvent() const
2828         {
2829             return contentSizeChangedEvent;
2830         }
2831         public Event<ChildContentSizeChangedEventHandlerControlEventArgs>& ChildContentSizeChangedEvent() const
2832         {
2833             return childContentSizeChangedEvent;
2834         }
2835         public Event<TextChangedEventHandler>& TextChangedEvent() const
2836         {
2837             return textChangedEvent;
2838         }
2839         public Event<HScrollEventHandlerScrollEventArgs>& HScrollEvent() const
2840         {
2841             return hscrollEvent;
2842         }
2843         public Event<VScrollEventHandlerScrollEventArgs>& VScrollEvent() const
2844         {
2845             return vscrollEvent;
2846         }
2847         public Event<MouseWheelEventHandlerMouseWheelEventArgs>& MouseWheelEvent() const
2848         {
2849             return mouseWheelEvent;
2850         }
2851         public Event<TimerEventHandlerTimerEventArgs>& 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<ControlEventHandlerControlEventArgs>& ControlAddedEvent() const
2864         {
2865             return controlAddedEvent;
2866         }
2867         public Event<ControlEventHandlerControlEventArgs>& ControlRemovedEvent() const
2868         {
2869             return controlRemovedEvent;
2870         }
2871         public Event<RightClickEventHandlerRightClickEventArgs>& 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<PaintEventHandlerPaintEventArgs> paintEvent;
3076         private Event<MouseEnterEventHandlerEnterLeaveEventArgs> mouseEnterEvent;
3077         private Event<MouseEventHandlerMouseEventArgs> mouseMoveEvent;
3078         private Event<MouseEventHandlerMouseEventArgs> mouseHoverEvent;
3079         private Event<MouseLeaveEventHandlerEnterLeaveEventArgs> mouseLeaveEvent;
3080         private Event<MouseEventHandlerMouseEventArgs> mouseDownEvent;
3081         private Event<MouseEventHandlerMouseEventArgs> mouseUpEvent;
3082         private Event<MouseEventHandlerMouseEventArgs> mouseDoubleClickEvent;
3083         private Event<KeyPressEventHandlerKeyPressEventArgs> keyPressEvent;
3084         private Event<KeyEventHandlerKeyEventArgs> keyDownEvent;
3085         private Event<KeyEventHandlerKeyEventArgs> keyUpEvent;
3086         private Event<ClickEventHandlerClickEventArgs> 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<SizeChangedEventHandlerSizeChangedEventArgs> sizeChangedEvent;
3093         private Event<SizeChangingEventHandlerSizeChangingEventArgs> sizeChangingEvent;
3094         private Event<ChildSizeChangedEventHandlerControlEventArgs> childSizeChangedEvent;
3095         private Event<LocationChangedEventHandler> locationChangedEvent;
3096         private Event<ContentChangedEventHandler> contentChangedEvent;
3097         private Event<ChildContentChangedEventHandlerControlEventArgs> childContentChangedEvent;
3098         private Event<ContentLocationChangedEventHandler> contentLocationChangedEvent;
3099         private Event<ChildContentLocationChangedEventHandlerControlEventArgs> childContentLocationChangedEvent;
3100         private Event<ContentSizeChangedEventHandler> contentSizeChangedEvent;
3101         private Event<ChildContentSizeChangedEventHandlerControlEventArgs> childContentSizeChangedEvent;
3102         private Event<TextChangedEventHandler> textChangedEvent;
3103         private Event<HScrollEventHandlerScrollEventArgs> hscrollEvent;
3104         private Event<VScrollEventHandlerScrollEventArgs> vscrollEvent;
3105         private Event<MouseWheelEventHandlerMouseWheelEventArgs> mouseWheelEvent;
3106         private Event<TimerEventHandlerTimerEventArgs> timerEvent;
3107         private Event<GotFocusEventHandler> gotFocusEvent;
3108         private Event<LostFocusEventHandler> lostFocusEvent;
3109         private Event<ChildGotFocusEventHandlerControlEventArgs> childGotFocusEvent;
3110         private Event<ChildLostFocusEventHandlerControlEventArgs> childLostFocusEvent;
3111         private Event<ControlEventHandlerControlEventArgs> controlAddedEvent;
3112         private Event<ControlEventHandlerControlEventArgs> controlRemovedEvent;
3113         private Event<RightClickEventHandlerRightClickEventArgs> rightClickEvent;
3114         private Event<ClipboardUpdateEventHandler> clipboardUpdateEvent;
3115     }