Win32TextBoxFactory.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Text;
  5. using Avalonia.Controls;
  6. using Avalonia.Platform;
  7. using static IntegrationTestApp.Embedding.WinApi;
  8. namespace IntegrationTestApp.Embedding;
  9. internal class Win32TextBoxFactory : INativeTextBoxFactory
  10. {
  11. public INativeTextBoxImpl CreateControl(IPlatformHandle parent)
  12. {
  13. return new Win32TextBox(parent);
  14. }
  15. private class Win32TextBox : INativeTextBoxImpl
  16. {
  17. private readonly IntPtr _oldWndProc;
  18. private readonly WndProcDelegate _wndProc;
  19. private TRACKMOUSEEVENT _trackMouseEvent;
  20. public Win32TextBox(IPlatformHandle parent)
  21. {
  22. var handle = CreateWindowEx(0, "EDIT",
  23. string.Empty,
  24. (uint)(WinApi.WindowStyles.WS_CHILD | WinApi.WindowStyles.WS_VISIBLE | WinApi.WindowStyles.WS_BORDER),
  25. 0, 0, 1, 1,
  26. parent.Handle,
  27. IntPtr.Zero,
  28. GetModuleHandle(null),
  29. IntPtr.Zero);
  30. _wndProc = new(WndProc);
  31. _oldWndProc = SetWindowLongPtr(handle, WinApi.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(_wndProc));
  32. _trackMouseEvent.cbSize = Marshal.SizeOf<TRACKMOUSEEVENT>();
  33. _trackMouseEvent.dwFlags = TME_HOVER | TME_LEAVE;
  34. _trackMouseEvent.hwndTrack = handle;
  35. _trackMouseEvent.dwHoverTime = 400;
  36. Handle = new Win32WindowControlHandle(handle, "HWND");
  37. }
  38. public IPlatformHandle Handle { get; }
  39. public string Text
  40. {
  41. get
  42. {
  43. var sb = new StringBuilder(256);
  44. GetWindowText(Handle.Handle, sb, sb.Capacity);
  45. return sb.ToString();
  46. }
  47. set => SetWindowText(Handle.Handle, value);
  48. }
  49. public event EventHandler? ContextMenuRequested;
  50. public event EventHandler? Hovered;
  51. public event EventHandler? PointerExited;
  52. private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
  53. {
  54. switch (msg)
  55. {
  56. case WM_CONTEXTMENU:
  57. if (ContextMenuRequested is not null)
  58. {
  59. ContextMenuRequested?.Invoke(this, EventArgs.Empty);
  60. return IntPtr.Zero;
  61. }
  62. break;
  63. case WM_MOUSELEAVE:
  64. PointerExited?.Invoke(this, EventArgs.Empty);
  65. break;
  66. case WM_MOUSEHOVER:
  67. Hovered?.Invoke(this, EventArgs.Empty);
  68. break;
  69. case WM_MOUSEMOVE:
  70. TrackMouseEvent(ref _trackMouseEvent);
  71. break;
  72. }
  73. return CallWindowProc(_oldWndProc, hWnd, msg, wParam, lParam);
  74. }
  75. }
  76. }