mirror of
				https://gitee.com/csharpui/CPF.git
				synced 2025-11-01 00:46:56 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			1907 lines
		
	
	
		
			76 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1907 lines
		
	
	
		
			76 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | ||
| using System.Collections.Generic;
 | ||
| using System.ComponentModel;
 | ||
| using System.Diagnostics.CodeAnalysis;
 | ||
| using System.Runtime.InteropServices;
 | ||
| using static CPF.Windows.UnmanagedMethods;
 | ||
| using CPF;
 | ||
| using System.Threading;
 | ||
| using System.IO;
 | ||
| using CPF.Threading;
 | ||
| using System.Collections.Concurrent;
 | ||
| using CPF.Drawing;
 | ||
| using CPF.Input;
 | ||
| using System.Linq;
 | ||
| using CPF.Controls;
 | ||
| using CPF.Platform;
 | ||
| using CPF.Shapes;
 | ||
| using CPF.Animation;
 | ||
| using System.Diagnostics;
 | ||
| using System.Text;
 | ||
| using CPF.Design;
 | ||
| using CPF.Windows.OpenGL;
 | ||
| using CPF.OpenGL;
 | ||
| //using System.Runtime.InteropServices.ComTypes;
 | ||
| 
 | ||
| namespace CPF.Windows
 | ||
| {
 | ||
|     public class WindowImpl : IWindowImpl
 | ||
|     {
 | ||
|         internal static int threadCallbackMessage;
 | ||
|         public ConcurrentQueue<SendOrPostData> invokeQueue = new ConcurrentQueue<SendOrPostData>();
 | ||
|         public ConcurrentQueue<SendOrPostData> asyncQueue = new ConcurrentQueue<SendOrPostData>();
 | ||
|         float scaling = 1;
 | ||
|         internal static WindowImpl Window;
 | ||
|         const double wheelDelta = 120.0;
 | ||
|         private bool _trackingMouse;
 | ||
|         DispatcherTimer timer;
 | ||
|         View root;
 | ||
|         public View Root
 | ||
|         {
 | ||
|             get { return root; }
 | ||
|         }
 | ||
|         WindowState windowState = WindowState.Normal;
 | ||
|         WindowState oldwindowState = WindowState.Normal;
 | ||
|         //bool isFirst = true;
 | ||
|         private string _className;
 | ||
| 
 | ||
|         static WindowImpl()
 | ||
|         {
 | ||
|             threadCallbackMessage = RegisterWindowMessage("CPF_ThreadCallbackMessage");
 | ||
|             if (WindowsPlatform.registerForMarshalling)
 | ||
|             {
 | ||
| #if NET5_0_OR_GREATER
 | ||
|                 ComWrappers.RegisterForMarshalling(ComWrapper.CpfComWrappers.Instance);
 | ||
| #endif
 | ||
|             }
 | ||
|             HRESULT res = UnmanagedMethods.OleInitialize(IntPtr.Zero);
 | ||
|             if (res != HRESULT.S_OK &&
 | ||
|                 res != HRESULT.S_FALSE /*already initialized*/)
 | ||
|                 throw new Win32Exception((int)res, "Failed to initialize OLE:必须设置线程STA,Main方法上加[STAThread]");
 | ||
| 
 | ||
|         }
 | ||
|         static IntPtr moduleHandle;
 | ||
|         public static IntPtr ModuleHandle
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 if (moduleHandle == IntPtr.Zero)
 | ||
|                 {
 | ||
|                     moduleHandle = GetModuleHandle(null);
 | ||
|                 }
 | ||
|                 return moduleHandle;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         WNDCLASSEX wc = new WNDCLASSEX();
 | ||
|         public WindowImpl()
 | ||
|         {
 | ||
|             if (Window == null)
 | ||
|             {
 | ||
|                 Window = this;
 | ||
|             }
 | ||
|             posttime = Application.Elapsed;
 | ||
|             var v = System.Environment.OSVersion.Version;
 | ||
|             if (v.Major >= 6 && DwmIsCompositionEnabled() && !Application.DesignMode)
 | ||
|             {
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 isLayered = true;
 | ||
|             }
 | ||
|             _className = "CPFWindow-" + Guid.NewGuid();
 | ||
|             // 初始化窗口类结构  
 | ||
|             wc.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
 | ||
|             //wc.style = (int)ClassStyles.CS_DBLCLKS;
 | ||
|             wc.lpfnWndProc = WndProc;
 | ||
|             wc.hInstance = ModuleHandle;
 | ||
|             wc.hbrBackground = IntPtr.Zero;
 | ||
|             wc.lpszClassName = _className;
 | ||
|             wc.cbClsExtra = 0;
 | ||
|             wc.cbWndExtra = 0;
 | ||
|             wc.hIcon = IntPtr.Zero;
 | ||
|             wc.hCursor = DefaultCursor;
 | ||
|             wc.lpszMenuName = "";
 | ||
|             // 注册窗口类  
 | ||
|             RegisterClassEx(ref wc);
 | ||
|             // 创建并显示窗口  
 | ||
|             handle = CreateWindowEx((int)ExStyle, _className, "窗体标题", (uint)Style,
 | ||
|               CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, IntPtr.Zero, IntPtr.Zero, ModuleHandle, null);
 | ||
| 
 | ||
|             //timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1), IsEnabled = true };
 | ||
|             //timer.Tick += Timer_Tick;
 | ||
| 
 | ||
|             if (UnmanagedMethods.ShCoreAvailable)
 | ||
|             {
 | ||
|                 uint dpix, dpiy;
 | ||
| 
 | ||
|                 var monitor = UnmanagedMethods.MonitorFromWindow(
 | ||
|                     handle,
 | ||
|                     UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST);
 | ||
| 
 | ||
|                 if (UnmanagedMethods.GetDpiForMonitor != null)
 | ||
|                 {
 | ||
|                     if (UnmanagedMethods.GetDpiForMonitor(
 | ||
|                             monitor,
 | ||
|                             UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI,
 | ||
|                             out dpix,
 | ||
|                             out dpiy) == 0)
 | ||
|                     {
 | ||
|                         scaling = (float)(dpix / 96.0);
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             scaling = Application.BaseScale * scaling;
 | ||
|             //scaling = 1;
 | ||
| 
 | ||
|             imeCentext = ImmGetContext(handle);
 | ||
|             if (imeCentext == IntPtr.Zero)
 | ||
|             {
 | ||
|                 imeCentext = ImmCreateContext();
 | ||
|                 //ImmAssociateContext(handle, imeCentext);
 | ||
|                 createimeCentext = true;
 | ||
|             }
 | ||
|             dropTarget = new OleDropTarget(this);
 | ||
| 
 | ||
|             var r = UnmanagedMethods.RegisterDragDrop(handle, dropTarget);
 | ||
| 
 | ||
|             //UnmanagedMethods.RegisterDragDrop(handle, Marshal.GetComInterfaceForObject(dropTarget, typeof(IDropTarget)));
 | ||
|             //UpdateWindow(handle);
 | ||
|             useGPU = Application.GetDrawingFactory().UseGPU;
 | ||
|             if (!isLayered && useGPU)
 | ||
|             {
 | ||
|                 wglContext = new WglContext(handle);
 | ||
|                 if (wglContext.RC == IntPtr.Zero)
 | ||
|                 {
 | ||
|                     //useGPU = false;
 | ||
|                     wglContext.Dispose();
 | ||
|                     wglContext = null;
 | ||
|                     isLayered = true;
 | ||
|                     SetWindowLong(handle, (int)WindowLongParam.GWL_EXSTYLE, (uint)ExStyle);
 | ||
|                 }
 | ||
|             }
 | ||
|             if (!isLayered)
 | ||
|             {
 | ||
|                 DWM_BLURBEHIND dwm = new DWM_BLURBEHIND();
 | ||
|                 dwm.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
 | ||
|                 dwm.fEnable = true;
 | ||
|                 dwm.hRegionBlur = CreateRectRgn(0, 0, -1, -1);
 | ||
|                 DwmEnableBlurBehindWindow(handle, ref dwm);
 | ||
|                 DeleteObject(dwm.hRegionBlur);
 | ||
|                 //MARGINS sRT = new MARGINS();
 | ||
|                 //sRT.Right = sRT.Left = sRT.Top = sRT.Bottom = -1;
 | ||
|                 //DwmExtendFrameIntoClientArea(handle, ref sRT);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         bool useGPU;
 | ||
| 
 | ||
|         CPF.Windows.OpenGL.WglContext wglContext;
 | ||
|         //[DllImport("QCall")]
 | ||
|         //private static extern void SetGlobalInstanceRegisteredForMarshalling(long id);
 | ||
|         OleDropTarget dropTarget;
 | ||
| 
 | ||
|         public static readonly IntPtr DefaultCursor = LoadCursor(IntPtr.Zero, new IntPtr((int)UnmanagedMethods.Cursor.IDC_ARROW));
 | ||
| 
 | ||
|         protected virtual WindowStyles ExStyle
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 var style = WindowStyles.WS_EX_LEFT;
 | ||
|                 if (isLayered)
 | ||
|                 {
 | ||
|                     style |= WindowStyles.WS_EX_LAYERED;
 | ||
|                 }
 | ||
|                 return style;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         protected bool isLayered;
 | ||
| 
 | ||
|         protected virtual WindowStyles Style
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 return WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_POPUP |
 | ||
|                   //WindowStyles.WS_BORDER |
 | ||
|                   //WindowStyles.WS_THICKFRAME |
 | ||
|                   WindowStyles.WS_MINIMIZEBOX
 | ||
|                   ;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         public void DragMove()
 | ||
|         {
 | ||
|             SendMessage(handle, (int)WindowsMessage.WM_SYSCOMMAND, (IntPtr)SystemCommand.SC_MOUSEMOVE, IntPtr.Zero);
 | ||
|             BeginInvoke(a =>
 | ||
|             {
 | ||
|                 SendMessage(handle, (int)WindowsMessage.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
 | ||
|             }, null);
 | ||
|         }
 | ||
| 
 | ||
|         public void Invoke(SendOrPostCallback callback, object data)
 | ||
|         {
 | ||
|             if (Dispatcher.MainThread.CheckAccess())
 | ||
|             {
 | ||
|                 callback(data);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 var invokeMre = new ManualResetEvent(false);
 | ||
|                 invokeQueue.Enqueue(new SendOrPostData { Data = data, SendOrPostCallback = callback, ManualResetEvent = invokeMre });
 | ||
|                 PostMessage(handle, (uint)threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
 | ||
|                 invokeMre.WaitOne();
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         TimeSpan posttime;
 | ||
|         public void BeginInvoke(SendOrPostCallback callback, object data)
 | ||
|         {
 | ||
|             var time = Application.Elapsed;
 | ||
|             asyncQueue.Enqueue(new SendOrPostData { Data = data, SendOrPostCallback = callback });
 | ||
|             if (asyncQueue.Count <= 1 || (time.TotalMilliseconds - posttime.TotalMilliseconds) > 10)
 | ||
|             {
 | ||
|                 PostMessage(handle, (uint)threadCallbackMessage, (IntPtr)1, IntPtr.Zero);
 | ||
|             }
 | ||
|             posttime = time;
 | ||
|         }
 | ||
|         bool canResize;
 | ||
|         public bool CanResize
 | ||
|         {
 | ||
|             get { return canResize; }
 | ||
|             set
 | ||
|             {
 | ||
|                 canResize = value;
 | ||
|                 var ex = GetWindowLong(handle, (int)WindowLongParam.GWL_STYLE);
 | ||
|                 if (value)
 | ||
|                 {
 | ||
|                     SetWindowLong(handle, (int)WindowLongParam.GWL_STYLE, ex | (uint)WindowStyles.WS_MAXIMIZEBOX);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     SetWindowLong(handle, (int)WindowLongParam.GWL_STYLE, ex ^ (uint)WindowStyles.WS_MAXIMIZEBOX);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|         public Action<PixelPoint> PositionChanged { get; set; }
 | ||
|         public event Action Move;
 | ||
|         public Action<Size> Resized { get; set; }
 | ||
|         public Action WindowStateChanged { get; set; }
 | ||
|         public Action ScalingChanged { get; set; }
 | ||
|         public Action Activated { get; set; }
 | ||
| 
 | ||
|         public Func<bool> Closing { get; set; }
 | ||
| 
 | ||
|         public Action Closed { get; set; }
 | ||
| 
 | ||
|         public Action Deactivated { get; set; }
 | ||
| 
 | ||
|         public IntPtr Handle { get { return handle; } }
 | ||
|         IntPtr handle;
 | ||
|         IntPtr hBitmap;
 | ||
|         Size oldSize;
 | ||
|         IntPtr ppvBits;
 | ||
|         /// <summary>
 | ||
|         /// 为了防止多屏幕拖动的时候抖动
 | ||
|         /// </summary>
 | ||
|         PixelPoint? ScalingChangedPosition;
 | ||
|         //bool cc;
 | ||
|         // 窗口过程  
 | ||
|         protected unsafe virtual IntPtr WndProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam)
 | ||
|         {
 | ||
|             if (msg == threadCallbackMessage)
 | ||
|             {
 | ||
|                 if (wParam == IntPtr.Zero)
 | ||
|                 {
 | ||
|                     if (invokeQueue.TryDequeue(out SendOrPostData result))
 | ||
|                     {
 | ||
|                         try
 | ||
|                         {
 | ||
|                             result.SendOrPostCallback(result.Data);
 | ||
|                         }
 | ||
|                         //catch (Exception e)
 | ||
|                         //{
 | ||
|                         //    throw new InvalidOperationException("Invoke操作异常", e);
 | ||
|                         //}
 | ||
|                         finally
 | ||
|                         {
 | ||
|                             result.ManualResetEvent.Set();
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     while (asyncQueue.TryDequeue(out SendOrPostData data))
 | ||
|                     {
 | ||
|                         data.SendOrPostCallback(data.Data);
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             if (WndPro != null)
 | ||
|             {
 | ||
|                 var r = WndPro(hwnd, (WindowsMessage)msg, wParam, lParam);
 | ||
|                 if (r != null)
 | ||
|                 {
 | ||
|                     return r.Value;
 | ||
|                 }
 | ||
|             }
 | ||
|             InputModifiers modifiers;
 | ||
|             switch ((WindowsMessage)msg)
 | ||
|             {
 | ||
|                 case WindowsMessage.WM_ACTIVATEAPP:
 | ||
|                     //Debug.WriteLine(root.ToString() + "Deactivated");
 | ||
|                     //if (!cc)
 | ||
|                     //{
 | ||
|                     //    var s = Bounds;
 | ||
|                     //    InitOpenGLWin((int)s.Width, (int)s.Height, handle);
 | ||
|                     //}
 | ||
|                     //cc = true;
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_CREATE:
 | ||
|                     break;
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
 | ||
|                     //{
 | ||
|                     //}
 | ||
|                     //{
 | ||
|                     //    var s = Bounds;
 | ||
|                     //    ChangeOpenGLWinSize((int)s.Width, (int)s.Height);
 | ||
|                     //}
 | ||
|                     var wa = (UnmanagedMethods.WindowActivate)(ToInt32(wParam) & 0xffff);
 | ||
|                     //Debug.WriteLine(root.ToString() + " " + wa);
 | ||
|                     switch (wa)
 | ||
|                     {
 | ||
|                         case UnmanagedMethods.WindowActivate.WA_ACTIVE:
 | ||
|                         case UnmanagedMethods.WindowActivate.WA_CLICKACTIVE:
 | ||
|                             Activated?.Invoke();
 | ||
|                             break;
 | ||
|                         case UnmanagedMethods.WindowActivate.WA_INACTIVE:
 | ||
|                             Deactivated?.Invoke();
 | ||
|                             //Debug.WriteLine(root.ToString() + "Deactivated");
 | ||
|                             //root.InputManager.KeyboardDevice.ProcessEvent(new KeyEventArgs(root, Keys.None, root.InputManager.KeyboardDevice.Modifiers, root.InputManager.KeyboardDevice), KeyEventType.LostFocus);
 | ||
|                             break;
 | ||
|                     }
 | ||
|                     return IntPtr.Zero;
 | ||
|                 //case WindowsMessage.WM_NCACTIVATE:
 | ||
|                 //    if (!canActivate)
 | ||
|                 //    {
 | ||
|                 //        Debug.WriteLine(root.ToString() + "WM_NCACTIVATE");
 | ||
|                 //        if (((int)wParam & 0xFFFF) != (int)WindowActivate.WA_INACTIVE)
 | ||
|                 //        {
 | ||
|                 //            if (lParam != IntPtr.Zero)
 | ||
|                 //            {
 | ||
|                 //                SetActiveWindow(lParam);
 | ||
|                 //            }
 | ||
|                 //            else
 | ||
|                 //            {
 | ||
|                 //                SetActiveWindow(IntPtr.Zero);
 | ||
|                 //            }
 | ||
|                 //        }
 | ||
|                 //    }
 | ||
|                 //    break;
 | ||
|                 case WindowsMessage.WM_MOUSEACTIVATE:
 | ||
|                     if (!canActivate)
 | ||
|                     {
 | ||
|                         return new IntPtr(3);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_DPICHANGED:
 | ||
|                     var dpi = ToInt32(wParam) & 0xffff;
 | ||
| #if Net4
 | ||
|                     var newDisplayRect = (UnmanagedMethods.RECT)Marshal.PtrToStructure(lParam, typeof(UnmanagedMethods.RECT));
 | ||
| #else
 | ||
|                     var newDisplayRect = Marshal.PtrToStructure<UnmanagedMethods.RECT>(lParam);
 | ||
| #endif
 | ||
|                     scaling = dpi / 96f;
 | ||
|                     //SetWindowPos(hwnd,
 | ||
|                     //    IntPtr.Zero,
 | ||
|                     //    newDisplayRect.left,
 | ||
|                     //    newDisplayRect.top,
 | ||
|                     //    newDisplayRect.right - newDisplayRect.left,
 | ||
|                     //    newDisplayRect.bottom - newDisplayRect.top,
 | ||
|                     //    SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
|                     ScalingChangedPosition = new PixelPoint(newDisplayRect.left, newDisplayRect.top);
 | ||
|                     ScalingChanged?.Invoke();
 | ||
|                     root.LayoutManager.ExecuteLayoutPass();
 | ||
|                     ScalingChangedPosition = null;
 | ||
|                     return IntPtr.Zero;
 | ||
|                 case WindowsMessage.WM_NCHITTEST:
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_NCCALCSIZE:
 | ||
|                     if (wParam != (IntPtr)0)
 | ||
|                     {
 | ||
|                         //var style = GetWindowLong(handle, (int)WindowLongParam.GWL_STYLE);
 | ||
|                         //if ((style & (uint)WindowStyles.WS_THICKFRAME) == 0)
 | ||
|                         //{
 | ||
|                         //    SetWindowLong(handle, (int)WindowLongParam.GWL_STYLE, style | (uint)WindowStyles.WS_THICKFRAME);
 | ||
|                         //}
 | ||
|                     }
 | ||
|                     //break;
 | ||
|                     return (IntPtr)1;
 | ||
|                 case WindowsMessage.WM_GETMINMAXINFO:
 | ||
|                     WmGetMinMaxInfo(hwnd, lParam);
 | ||
|                     //break;
 | ||
|                     return IntPtr.Zero;
 | ||
|                 case WindowsMessage.WM_NCLBUTTONDOWN:
 | ||
|                     int test = (int)wParam;
 | ||
|                     if (test == (int)HitTestValues.HTCLOSE || test == (int)HitTestValues.HTHELP || test == (int)HitTestValues.HTMINBUTTON || test == (int)HitTestValues.HTMAXBUTTON)
 | ||
|                     {
 | ||
|                         return IntPtr.Zero;
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_SYSCOMMAND:
 | ||
|                     //if (wParam.ToInt32() == 61728)
 | ||
|                     //{
 | ||
|                     //    return 0;
 | ||
|                     //}
 | ||
|                     break;
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_SYSKEYDOWN:
 | ||
|                     GetKeyboardState(_keyStates);
 | ||
|                     InputModifiers result = 0;
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftAlt) || IsDown(Keys.RightAlt))
 | ||
|                     {
 | ||
|                         result |= InputModifiers.Alt;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftCtrl) || IsDown(Keys.RightCtrl))
 | ||
|                     {
 | ||
|                         result |= InputModifiers.Control;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftShift) || IsDown(Keys.RightShift))
 | ||
|                     {
 | ||
|                         result |= InputModifiers.Shift;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LWin) || IsDown(Keys.RWin))
 | ||
|                     {
 | ||
|                         result |= InputModifiers.Windows;
 | ||
|                     }
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = result;
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.KeyboardDevice.ProcessEvent(new KeyEventArgs(root, KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), ToInt32(wParam), root.InputManager.KeyboardDevice.Modifiers, root.InputManager.KeyboardDevice), KeyEventType.KeyDown);
 | ||
|                     }
 | ||
|                     //System.Diagnostics.Debug.WriteLine(root.ToString() + wParam + "|" + lParam);
 | ||
|                     break;
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_KEYUP:
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_SYSKEYUP:
 | ||
| 
 | ||
|                     InputModifiers result1 = 0;
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftAlt) || IsDown(Keys.RightAlt))
 | ||
|                     {
 | ||
|                         result1 |= InputModifiers.Alt;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftCtrl) || IsDown(Keys.RightCtrl))
 | ||
|                     {
 | ||
|                         result1 |= InputModifiers.Control;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LeftShift) || IsDown(Keys.RightShift))
 | ||
|                     {
 | ||
|                         result1 |= InputModifiers.Shift;
 | ||
|                     }
 | ||
| 
 | ||
|                     if (IsDown(Keys.LWin) || IsDown(Keys.RWin))
 | ||
|                     {
 | ||
|                         result1 |= InputModifiers.Windows;
 | ||
|                     }
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = result1;
 | ||
|                     //root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.KeyboardDevice.ProcessEvent(new KeyEventArgs(root, KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), ToInt32(wParam), root.InputManager.KeyboardDevice.Modifiers, root.InputManager.KeyboardDevice), KeyEventType.KeyUp);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_CHAR:
 | ||
|                     // Ignore control chars
 | ||
|                     if (ToInt32(wParam) >= 32 && isEnable)
 | ||
|                     {
 | ||
|                         var str = new string((char)ToInt32(wParam), 1);
 | ||
|                         root.InputManager.KeyboardDevice.ProcessEvent(new TextInputEventArgs(root, root.InputManager.KeyboardDevice, str), KeyEventType.TextInput);
 | ||
|                     }
 | ||
| 
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_IME_SETCONTEXT:
 | ||
|                     if (ToInt32(wParam) == 1)
 | ||
|                     {
 | ||
|                         var old = ImmAssociateContext(handle, imeCentext);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_IME_STARTCOMPOSITION:
 | ||
| 
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_IME_ENDCOMPOSITION:
 | ||
| 
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_IME_NOTIFY:
 | ||
| 
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MOUSEMOVE:
 | ||
|                     if (!_trackingMouse)
 | ||
|                     {
 | ||
|                         var tm = new TRACKMOUSEEVENT
 | ||
|                         {
 | ||
| #if Net4
 | ||
|                             cbSize = Marshal.SizeOf(typeof(TRACKMOUSEEVENT)),
 | ||
| #else
 | ||
|                             cbSize = Marshal.SizeOf<TRACKMOUSEEVENT>(),
 | ||
| #endif
 | ||
|                             dwFlags = 2,
 | ||
|                             hwndTrack = hwnd,
 | ||
|                             dwHoverTime = 0,
 | ||
|                         };
 | ||
| 
 | ||
|                         TrackMouseEvent(ref tm);
 | ||
|                     }
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     modifiers = root.InputManager.KeyboardDevice.Modifiers;
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.MouseDevice.ProcessEvent(new MouseEventArgs(root, modifiers.HasFlag(InputModifiers.LeftMouseButton), modifiers.HasFlag(InputModifiers.RightMouseButton), modifiers.HasFlag(InputModifiers.MiddleMouseButton), DipFromLParam(lParam), root.InputManager.MouseDevice, IsTouch()), root.LayoutManager.VisibleUIElements, EventType.MouseMove);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MOUSELEAVE:
 | ||
|                     _trackingMouse = false;
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     modifiers = root.InputManager.KeyboardDevice.Modifiers;
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.MouseDevice.ProcessEvent(new MouseEventArgs(root, modifiers.HasFlag(InputModifiers.LeftMouseButton), modifiers.HasFlag(InputModifiers.RightMouseButton), modifiers.HasFlag(InputModifiers.MiddleMouseButton), DipFromLParam(lParam), root.InputManager.MouseDevice, IsTouch()), root.LayoutManager.VisibleUIElements, EventType.MouseLeave);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MOUSEWHEEL:
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     modifiers = root.InputManager.KeyboardDevice.Modifiers;
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.MouseDevice.ProcessEvent(new MouseWheelEventArgs(root, modifiers.HasFlag(InputModifiers.LeftMouseButton), modifiers.HasFlag(InputModifiers.RightMouseButton), modifiers.HasFlag(InputModifiers.MiddleMouseButton), PointToClient(PointFromLParam(lParam)), root.InputManager.MouseDevice, new Vector(0, (ToInt32(wParam) >> 16))), root.LayoutManager.VisibleUIElements, EventType.MouseWheel);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MBUTTONUP:
 | ||
|                 case WindowsMessage.WM_RBUTTONUP:
 | ||
|                 case WindowsMessage.WM_LBUTTONUP:
 | ||
|                     MouseButton mouseButton = MouseButton.Left;
 | ||
|                     if ((WindowsMessage)msg == WindowsMessage.WM_RBUTTONUP)
 | ||
|                     {
 | ||
|                         mouseButton = MouseButton.Right;
 | ||
|                     }
 | ||
|                     if ((WindowsMessage)msg == WindowsMessage.WM_MBUTTONUP)
 | ||
|                     {
 | ||
|                         mouseButton = MouseButton.Middle;
 | ||
|                     }
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.MouseDevice.ProcessEvent(new MouseButtonEventArgs(root, root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.LeftMouseButton), root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.RightMouseButton), root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.MiddleMouseButton), DipFromLParam(lParam), root.InputManager.MouseDevice, mouseButton, IsTouch()), root.LayoutManager.VisibleUIElements, EventType.MouseUp);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MBUTTONDOWN:
 | ||
|                 case WindowsMessage.WM_LBUTTONDOWN:
 | ||
|                 case WindowsMessage.WM_RBUTTONDOWN:
 | ||
|                     //Debug.WriteLine("触摸点击:" + IsTouch());
 | ||
|                     mouseButton = MouseButton.Left;
 | ||
|                     if ((WindowsMessage)msg == WindowsMessage.WM_RBUTTONDOWN)
 | ||
|                     {
 | ||
|                         mouseButton = MouseButton.Right;
 | ||
|                     }
 | ||
|                     if ((WindowsMessage)msg == WindowsMessage.WM_MBUTTONDOWN)
 | ||
|                     {
 | ||
|                         mouseButton = MouseButton.Middle;
 | ||
|                     }
 | ||
|                     root.InputManager.KeyboardDevice.Modifiers = GetMouseModifiers(wParam);
 | ||
|                     if (isEnable)
 | ||
|                     {
 | ||
|                         root.InputManager.MouseDevice.ProcessEvent(new MouseButtonEventArgs(root, root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.LeftMouseButton), root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.RightMouseButton), root.InputManager.KeyboardDevice.Modifiers.HasFlag(InputModifiers.MiddleMouseButton), DipFromLParam(lParam), root.InputManager.MouseDevice, mouseButton, IsTouch()), root.LayoutManager.VisibleUIElements, EventType.MouseDown);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_LBUTTONDBLCLK:
 | ||
|                 case WindowsMessage.WM_MBUTTONDBLCLK:
 | ||
|                 case WindowsMessage.WM_RBUTTONDBLCLK:
 | ||
|                     //Debug.WriteLine("DBLCLK");
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_MOVE:
 | ||
|                     //var pos = new Point((short)(ToInt32(lParam) & 0xffff) / scaling, (short)(ToInt32(lParam) >> 16) / scaling);
 | ||
|                     //var pos = Bounds.Location;
 | ||
|                     if (Move != null)
 | ||
|                     {
 | ||
|                         Move();
 | ||
|                     }
 | ||
|                     var pos = new PixelPoint((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16));
 | ||
|                     //bounds = Bounds;
 | ||
|                     PositionChanged?.Invoke(pos);
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_SIZE:
 | ||
|                     var size = (SizeCommand)wParam;
 | ||
| 
 | ||
|                     if (Resized != null &&
 | ||
|                         (size == SizeCommand.Restored ||
 | ||
|                          size == SizeCommand.Maximized))
 | ||
|                     {
 | ||
|                         var clientSize = new Size(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16);
 | ||
|                         Resized(clientSize / scaling);
 | ||
|                     }
 | ||
| 
 | ||
|                     var windowState = size == SizeCommand.Maximized ? WindowState.Maximized
 | ||
|                         : (size == SizeCommand.Minimized ? WindowState.Minimized : WindowState.Normal);
 | ||
| 
 | ||
|                     if (windowState != this.oldwindowState || this.windowState == WindowState.FullScreen)
 | ||
|                     {
 | ||
|                         if (this.windowState != WindowState.FullScreen)
 | ||
|                         {
 | ||
|                             this.windowState = windowState;
 | ||
|                             oldwindowState = windowState;
 | ||
|                             WindowStateChanged?.Invoke();
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             if (oldwindowState != WindowState.FullScreen && windowState != WindowState.Normal)
 | ||
|                             {
 | ||
|                                 oldwindowState = WindowState.FullScreen;
 | ||
|                                 WindowStateChanged?.Invoke();
 | ||
|                             }
 | ||
|                         }
 | ||
|                     }
 | ||
|                     if (windowState != WindowState.Minimized)
 | ||
|                     {
 | ||
|                         RECT rr = new RECT(0, 0, LOWORD((int)lParam), HIWORD((int)lParam));
 | ||
|                         //Debug.WriteLine("WM_SIZE:" + rr.Width + "," + rr.Height);
 | ||
|                         //InvalidateRect(handle, ref rr, false);
 | ||
|                         if (root != null)
 | ||
|                         {
 | ||
|                             Invalidate(new Rect(new Point(), root.ActualSize));
 | ||
|                         }
 | ||
|                         //if (root != null)
 | ||
|                         //{
 | ||
|                         //System.Diagnostics.Debug.WriteLine(rr);
 | ||
|                         //root.Width = rr.Width / scaling;
 | ||
|                         //root.Height = rr.Height / scaling;
 | ||
|                         //root.ActualSize = rr;
 | ||
|                         //root.LayoutManager.ExecuteLayoutPass();
 | ||
|                         //}
 | ||
|                         if (!isLayered)
 | ||
|                         {
 | ||
|                             RedrawWindow(handle, ref rr, IntPtr.Zero, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
 | ||
|                             //UpdateWindow(handle);
 | ||
|                             //InvalidateRect(handle, ref rr, false);
 | ||
|                         }
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_NCUAHDRAWCAPTION:
 | ||
|                 case WindowsMessage.WM_NCUAHDRAWFRAME:
 | ||
|                     return IntPtr.Zero;
 | ||
|                 case WindowsMessage.WM_ERASEBKGND:
 | ||
|                     return (IntPtr)1;
 | ||
|                 //case WindowsMessage.WM_NCACTIVATE:
 | ||
|                 case WindowsMessage.WM_NCPAINT:
 | ||
|                     //DrawBoder(hwnd);
 | ||
|                     var _hdc = GetDC(hwnd);
 | ||
|                     OnPaint(_hdc, new Rect(new Point(), Bounds.Size));
 | ||
|                     ReleaseDC(hwnd, _hdc);
 | ||
|                     return (IntPtr)1;
 | ||
|                 case WindowsMessage.WM_PAINT:
 | ||
|                     PAINTSTRUCT ps = new PAINTSTRUCT();
 | ||
|                     IntPtr hdc = BeginPaint(hwnd, out ps);
 | ||
|                     if (ps.rcPaint.Width > 0 && ps.rcPaint.Height > 0)
 | ||
|                     {
 | ||
|                         OnPaint(hdc, new Rect(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.Width, ps.rcPaint.Height));
 | ||
|                     }
 | ||
|                     EndPaint(hwnd, ref ps);
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_SHOWWINDOW:
 | ||
|                     //System.Diagnostics.Debug.WriteLine(wParam);
 | ||
|                     //if (wParam == (IntPtr)1)
 | ||
|                     //{
 | ||
|                     //    root.Visibility = Visibility.Visible;
 | ||
|                     //}
 | ||
|                     //else
 | ||
|                     //{
 | ||
|                     //    root.Visibility = Visibility.Collapsed;
 | ||
|                     //}
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_POINTERDOWN:
 | ||
|                 case WindowsMessage.WM_POINTERUP:
 | ||
|                 case WindowsMessage.WM_POINTERUPDATE:
 | ||
|                     var id = GetPointerId(wParam);
 | ||
|                     var position = GetPointerLocation(lParam);
 | ||
|                     position = PointToClient(position);
 | ||
|                     //Debug.WriteLine("id:" + id + "  " + position);
 | ||
|                     POINTER_INFO pi = new POINTER_INFO();
 | ||
|                     if (GetPointerInfo(id, ref pi))
 | ||
|                     {
 | ||
|                         switch ((WindowsMessage)msg)
 | ||
|                         {
 | ||
|                             case WindowsMessage.WM_POINTERDOWN:
 | ||
|                                 //Debug.WriteLine("down");
 | ||
|                                 root.InputManager.TouchDevice.ProcessEvent(new TouchEventArgs(new TouchPoint { Id = id, Position = position }, root.InputManager.TouchDevice, Root), root.LayoutManager.VisibleUIElements, EventType.TouchDown);
 | ||
|                                 break;
 | ||
|                             case WindowsMessage.WM_POINTERUP:
 | ||
|                                 //Debug.WriteLine("up");
 | ||
|                                 root.InputManager.TouchDevice.ProcessEvent(new TouchEventArgs(new TouchPoint { Id = id, Position = position }, root.InputManager.TouchDevice, Root), root.LayoutManager.VisibleUIElements, EventType.TouchUp);
 | ||
|                                 //root.InputManager.TouchDevice.ProcessEvent(new TouchEventArgs(new TouchPoint { Id = id, Position = position }, root.InputManager.TouchDevice, Root), root.LayoutManager.VisibleUIElements, EventType.TouchLeave);
 | ||
|                                 break;
 | ||
|                             case WindowsMessage.WM_POINTERUPDATE:
 | ||
|                                 //Debug.WriteLine("update");
 | ||
|                                 root.InputManager.TouchDevice.ProcessEvent(new TouchEventArgs(new TouchPoint { Id = id, Position = position }, root.InputManager.TouchDevice, Root), root.LayoutManager.VisibleUIElements, EventType.TouchMove);
 | ||
|                                 break;
 | ||
|                         }
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_POINTERWHEEL:
 | ||
|                     Debug.WriteLine("WM_POINTERWHEEL");
 | ||
|                     break;
 | ||
|                 //case WindowsMessage.WM_TOUCH:
 | ||
|                 //    {
 | ||
|                 //        var touchInputCount = wParam.ToInt32();
 | ||
|                 //        var pTouchInputs = stackalloc TOUCHINPUT[touchInputCount];
 | ||
|                 //        if (GetTouchInputInfo(lParam, (uint)touchInputCount, pTouchInputs, Marshal.SizeOf(typeof(TOUCHINPUT))))
 | ||
|                 //        {
 | ||
|                 //            for (int i = 0; i < touchInputCount; i++)
 | ||
|                 //            {
 | ||
|                 //                var touchInput = pTouchInputs[i];
 | ||
| 
 | ||
|                 //                //Input?.Invoke(new RawTouchEventArgs(_touchDevice, touchInput.Time,
 | ||
|                 //                //    _owner,
 | ||
|                 //                //    touchInput.Flags.HasAllFlags(TouchInputFlags.TOUCHEVENTF_UP) ?
 | ||
|                 //                //        RawPointerEventType.TouchEnd :
 | ||
|                 //                //        touchInput.Flags.HasAllFlags(TouchInputFlags.TOUCHEVENTF_DOWN) ?
 | ||
|                 //                //            RawPointerEventType.TouchBegin :
 | ||
|                 //                //            RawPointerEventType.TouchUpdate,
 | ||
|                 //                //    PointToClient(new PixelPoint(touchInput.X / 100, touchInput.Y / 100)),
 | ||
|                 //                //    WindowsKeyboardDevice.Instance.Modifiers,
 | ||
|                 //                //    touchInput.Id));
 | ||
|                 //            }
 | ||
|                 //            CloseTouchInputHandle(lParam);
 | ||
|                 //            return IntPtr.Zero;
 | ||
|                 //        }
 | ||
|                 //        break;
 | ||
|                 //    }
 | ||
|                 case UnmanagedMethods.WindowsMessage.WM_CLOSE:
 | ||
|                     bool? preventClosing = Closing?.Invoke();
 | ||
|                     if (preventClosing == true)
 | ||
|                     {
 | ||
|                         return IntPtr.Zero;
 | ||
|                     }
 | ||
|                     if (_parent != null)
 | ||
|                     {
 | ||
|                         //EnableWindow(_parent.handle, true);
 | ||
|                         //_parent.SetEnable(true);
 | ||
|                         _parent.Activate();
 | ||
|                         SetFocus(_parent.handle);
 | ||
|                         SetWindowLongPtr(handle, (int)WindowLongParam.GWL_HWNDPARENT, IntPtr.Zero);
 | ||
|                         //_parent.SetVisible(true);
 | ||
|                         _parent = null;
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case WindowsMessage.WM_DESTROY:
 | ||
|                     if (handle != IntPtr.Zero)
 | ||
|                     {
 | ||
|                         try
 | ||
|                         {
 | ||
|                             RevokeDragDrop(handle);
 | ||
|                         }
 | ||
|                         catch (Exception e)
 | ||
|                         {
 | ||
|                             Debug.WriteLine(e.Message);
 | ||
|                         }
 | ||
|                     }
 | ||
|                     if (imeCentext != IntPtr.Zero)
 | ||
|                     {
 | ||
|                         ImmReleaseContext(handle, imeCentext);
 | ||
|                         if (createimeCentext)
 | ||
|                         {
 | ||
|                             ImmDestroyContext(imeCentext);
 | ||
|                         }
 | ||
|                         imeCentext = IntPtr.Zero;
 | ||
|                     }
 | ||
|                     if (ismain)
 | ||
|                     {
 | ||
|                         PostQuitMessage(0);
 | ||
|                     }
 | ||
|                     timer?.Dispose();
 | ||
|                     timer = null;
 | ||
|                     wglContext?.Dispose();
 | ||
|                     wglContext = null;
 | ||
|                     if (hBitmap != IntPtr.Zero)
 | ||
|                     {
 | ||
|                         DeleteObject(hBitmap);
 | ||
|                         hBitmap = IntPtr.Zero;
 | ||
|                     }
 | ||
|                     //Dispose();
 | ||
|                     if (IconHandle != IntPtr.Zero)
 | ||
|                     {
 | ||
|                         DestroyIcon(IconHandle);
 | ||
|                         IconHandle = IntPtr.Zero;
 | ||
|                     }
 | ||
|                     if (_className != null)
 | ||
|                     {
 | ||
|                         UnmanagedMethods.UnregisterClass(_className, ModuleHandle);
 | ||
|                         _className = null;
 | ||
|                     }
 | ||
|                     if (RenderBitmap != null)
 | ||
|                     {
 | ||
|                         RenderBitmap.Dispose();
 | ||
|                         RenderBitmap = null;
 | ||
|                     }
 | ||
|                     handle = IntPtr.Zero;
 | ||
|                     Closed?.Invoke();
 | ||
|                     foreach (var item in invokeQueue)
 | ||
|                     {
 | ||
|                         item.SendOrPostCallback(item.Data);
 | ||
|                         item.ManualResetEvent.Set();
 | ||
|                     }
 | ||
|                     if (ismain)
 | ||
|                     {
 | ||
|                         Window = null;
 | ||
|                     }
 | ||
|                     //GC.Collect();
 | ||
|                     break;
 | ||
|             }
 | ||
|             return DefWindowProc(hwnd, msg, wParam, lParam);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
 | ||
|         public static extern void InitOpenGLWin(int width, int height, IntPtr pwin);
 | ||
| 
 | ||
|         [DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
 | ||
|         public static extern void ChangeOpenGLWinSize(int width, int height);
 | ||
|         /// <summary>
 | ||
|         /// 处理WindowProc
 | ||
|         /// </summary>
 | ||
|         public Func<IntPtr, WindowsMessage, IntPtr, IntPtr, IntPtr?> WndPro { get; set; }
 | ||
| 
 | ||
|         bool rendToBitmap;
 | ||
|         public bool RenderToBitmap
 | ||
|         {
 | ||
|             get { return rendToBitmap; }
 | ||
|             set
 | ||
|             {
 | ||
|                 rendToBitmap = value;
 | ||
|                 //if (value)
 | ||
|                 //{
 | ||
|                 //    if (!isLayered)
 | ||
|                 //    {
 | ||
|                 //        isLayered = true;
 | ||
|                 //        SetWindowLong(handle, (int)WindowLongParam.GWL_EXSTYLE, (uint)ExStyle);
 | ||
|                 //        ShowInTaskbar(false);
 | ||
|                 //    }
 | ||
|                 //}
 | ||
|             }
 | ||
|         }
 | ||
|         /// <summary>
 | ||
|         /// RenderToBitmap=true,图像渲染到这个位图里,界面将不显示
 | ||
|         /// </summary>
 | ||
|         public Bitmap RenderBitmap { get; private set; }
 | ||
|         public Action OnRenderedBitmap { get; set; }
 | ||
|         //int cc = 0;
 | ||
| 
 | ||
|         //void testPaint()
 | ||
|         //{
 | ||
|         //    OpenGl gl = new OpenGl();
 | ||
|         //    gl.Enable(OpenGl.GL_ALPHA_TEST);
 | ||
|         //    gl.Enable(OpenGl.GL_DEPTH_TEST);
 | ||
|         //    gl.Enable(OpenGl.GL_COLOR_MATERIAL);
 | ||
| 
 | ||
|         //    gl.Enable(OpenGl.GL_LIGHTING);
 | ||
|         //    gl.Enable(OpenGl.GL_LIGHT0);
 | ||
| 
 | ||
|         //    gl.Enable(OpenGl.GL_BLEND);
 | ||
|         //    gl.BlendFunc(OpenGl.GL_SRC_ALPHA, OpenGl.GL_ONE_MINUS_SRC_ALPHA);
 | ||
|         //    gl.ClearColor(0, 0, 0, 0);
 | ||
|         //    gl.Clear(OpenGl.GL_COLOR_BUFFER_BIT | OpenGl.GL_DEPTH_BUFFER_BIT);
 | ||
| 
 | ||
|         //    gl.PushMatrix();
 | ||
| 
 | ||
|         //    gl.Color(0, 1, 1);
 | ||
|         //    gl.Begin(OpenGl.GL_TRIANGLES);                              // Drawing Using Triangles
 | ||
|         //    gl.Color(1.0f, 0.0f, 0.0f);                      // Set The Color To Red
 | ||
|         //    gl.Vertex(0.0f, 1.0f, 0.0f);                  // Top
 | ||
|         //    gl.Color(0.0f, 1.0f, 0.0f);                      // Set The Color To Green
 | ||
|         //    gl.Vertex(-1.0f, -1.0f, 0.0f);                  // Bottom Left
 | ||
|         //    gl.Color(0.0f, 0.0f, 1.0f);                      // Set The Color To Blue
 | ||
|         //    gl.Vertex(1.0f, -1.0f, 0.0f);                  // Bottom Right
 | ||
|         //    gl.End();
 | ||
| 
 | ||
|         //    gl.PopMatrix();
 | ||
|         //    gl.Flush();
 | ||
|         //}
 | ||
|         void OnPaint(IntPtr hdc, Rect rect)
 | ||
|         {
 | ||
|             if (handle == IntPtr.Zero)
 | ||
|             {
 | ||
|                 return;
 | ||
|             }
 | ||
|             var r = this.Bounds;
 | ||
| 
 | ||
|             root.LayoutManager.ExecuteLayoutPass();
 | ||
|             if (RenderToBitmap)
 | ||
|             {
 | ||
|                 if (RenderBitmap == null || oldSize != r.Size)
 | ||
|                 {
 | ||
|                     oldSize = r.Size;
 | ||
|                     if (RenderBitmap != null)
 | ||
|                     {
 | ||
|                         RenderBitmap.Dispose();
 | ||
|                     }
 | ||
|                     RenderBitmap = new Bitmap((int)r.Width, (int)r.Height);
 | ||
|                 }
 | ||
|                 if (root.LayoutManager.VisibleUIElements != null)
 | ||
|                 {
 | ||
|                     using (DrawingContext dc = DrawingContext.FromBitmap(RenderBitmap))
 | ||
|                     {
 | ||
|                         root.RenderView(dc, rect);
 | ||
|                         //DrawRenderRectangle(dc);
 | ||
|                     }
 | ||
|                 }
 | ||
|                 if (OnRenderedBitmap != null)
 | ||
|                 {
 | ||
|                     //Debug.WriteLine(r.Size);
 | ||
|                     OnRenderedBitmap();
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 IntPtr screenDC = IntPtr.Zero;
 | ||
|                 IntPtr memDc = IntPtr.Zero;
 | ||
|                 var oldBits = IntPtr.Zero;
 | ||
| 
 | ||
|                 if (isLayered || !useGPU)
 | ||
|                 {
 | ||
|                     screenDC = GetDC(IntPtr.Zero);
 | ||
|                     memDc = CreateCompatibleDC(screenDC);
 | ||
|                     if (oldSize != r.Size || hBitmap == IntPtr.Zero)
 | ||
|                     {
 | ||
|                         oldSize = r.Size;
 | ||
|                         if (hBitmap != IntPtr.Zero)
 | ||
|                         {
 | ||
|                             DeleteObject(hBitmap);
 | ||
|                         }
 | ||
| 
 | ||
|                         BITMAPINFOHEADER info = new BITMAPINFOHEADER();
 | ||
|                         info.biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
 | ||
|                         info.biBitCount = 32;
 | ||
|                         info.biHeight = -(int)r.Height;
 | ||
|                         info.biWidth = (int)r.Width;
 | ||
|                         info.biPlanes = 1;
 | ||
|                         hBitmap = CreateDIBSection(memDc, ref info, 0, out ppvBits, IntPtr.Zero, 0);
 | ||
|                     }
 | ||
|                     oldBits = SelectObject(memDc, hBitmap);
 | ||
|                 }
 | ||
| 
 | ||
|                 //Stopwatch stopwatch = new Stopwatch();
 | ||
|                 //stopwatch.Start();
 | ||
|                 wglContext?.MakeCurrent();
 | ||
|                 if (root.LayoutManager.VisibleUIElements != null)
 | ||
|                 {
 | ||
|                     IRenderTarget rt = new HDCRenderTarget((isLayered || !useGPU) ? memDc : hdc, (int)Bounds.Width, (int)Bounds.Height, !isLayered);
 | ||
|                     if (wglContext != null)
 | ||
|                     {
 | ||
|                         wglContext.GetFramebufferInfo(out var fb, out var sam, out var sten);
 | ||
|                         rt = new OpenGlRenderTarget<IntPtr>(hdc, wglContext, (int)Bounds.Width, (int)Bounds.Height, fb, sam, sten);
 | ||
|                     }
 | ||
|                     //Console.WriteLine(rt + " " + isLayered + "  " + useGPU + "  " + memDc);
 | ||
|                     using (DrawingContext dc = DrawingContext.FromRenderTarget(rt))
 | ||
|                     {
 | ||
|                         root.RenderView(dc, rect);
 | ||
|                         //DrawRenderRectangle(dc);
 | ||
|                     }
 | ||
|                     //testPaint();
 | ||
|                 }
 | ||
|                 wglContext?.SwapBuffers();
 | ||
|                 //stopwatch.Stop();
 | ||
|                 //Debug.WriteLine(stopwatch.ElapsedMilliseconds);
 | ||
| 
 | ||
|                 if (hdc != IntPtr.Zero)
 | ||
|                 {
 | ||
|                     //AlphaBlend(hdc, (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height, memDc, (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height, new BLENDFUNCTION { SourceConstantAlpha = 255, AlphaFormat = 1 });
 | ||
|                     if (!useGPU)
 | ||
|                     {
 | ||
|                         BitBlt(hdc, (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height, memDc, (int)rect.X, (int)rect.Y, TernaryRasterOperations.SRCCOPY);
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     if (isLayered)
 | ||
|                     {
 | ||
|                         if (windowState != WindowState.Minimized)
 | ||
|                         {
 | ||
|                             //Stopwatch stopwatch = new Stopwatch();
 | ||
|                             //stopwatch.Start();
 | ||
|                             BLENDFUNCTION blendFunc = new BLENDFUNCTION();
 | ||
|                             blendFunc.BlendOp = 0;
 | ||
|                             blendFunc.SourceConstantAlpha = 255;
 | ||
|                             blendFunc.AlphaFormat = 1;
 | ||
|                             blendFunc.BlendFlags = 0;
 | ||
|                             POINT topLoc = new POINT((int)r.Left, (int)r.Top);
 | ||
|                             SIZE bitMapSize = new SIZE((int)r.Width, (int)r.Height);
 | ||
|                             POINT srcLoc = new POINT(0, 0);
 | ||
|                             var rr = UpdateLayeredWindow(handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, 2);
 | ||
|                             //stopwatch.Stop();
 | ||
|                             //Debug.WriteLine(stopwatch.ElapsedMilliseconds);
 | ||
|                         }
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         //UpdateWindow(handle);
 | ||
|                     }
 | ||
|                 }
 | ||
|                 if (isLayered || !useGPU)
 | ||
|                 {
 | ||
|                     SelectObject(memDc, oldBits);
 | ||
|                     ReleaseDC(IntPtr.Zero, screenDC);
 | ||
|                     DeleteDC(memDc);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         //private void DrawRenderRectangle(DrawingContext dc)
 | ||
|         //{
 | ||
|         //    if (renderRectElement != null)
 | ||
|         //    {
 | ||
|         //        var rect1 = renderRectElement.GetContentBounds();
 | ||
|         //        var points = new List<Point>();
 | ||
|         //        points.Add(new Point());
 | ||
|         //        points.Add(new Point((float)Math.Round(rect1.Width * scaling) / scaling, 0));
 | ||
|         //        points.Add(new Point((float)Math.Round(rect1.Width * scaling) / scaling, (float)Math.Round(rect1.Height * scaling) / scaling));
 | ||
|         //        points.Add(new Point(0, (float)Math.Round(rect1.Height * scaling) / scaling));
 | ||
|         //        for (int i = 0; i < points.Count; i++)
 | ||
|         //        {
 | ||
|         //            points[i] = renderRectElement.TransformPoint(points[i]);
 | ||
|         //        }
 | ||
|         //        var p = renderRectElement.Parent;
 | ||
|         //        while (p != null && !p.IsRoot)
 | ||
|         //        {
 | ||
|         //            for (int i = 0; i < points.Count; i++)
 | ||
|         //            {
 | ||
|         //                points[i] = p.TransformPoint(points[i]);
 | ||
|         //            }
 | ||
|         //            p = p.Parent;
 | ||
|         //        }
 | ||
| 
 | ||
|         //        using (var brush = new SolidColorBrush(Color.FromRgb(255, 0, 0)))
 | ||
|         //        {
 | ||
|         //            var stroke = new Stroke(1);
 | ||
|         //            for (int i = 0; i < points.Count; i++)
 | ||
|         //            {
 | ||
|         //                dc.DrawLine(stroke, brush, points[i] * scaling, points[i == 3 ? 0 : (i + 1)] * scaling);
 | ||
|         //            }
 | ||
|         //        }
 | ||
|         //    }
 | ||
|         //}
 | ||
| 
 | ||
|         private Point PointFromLParam(IntPtr lParam)
 | ||
|         {
 | ||
|             return new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16));
 | ||
|         }
 | ||
|         public Point PointToClient(Point point)
 | ||
|         {
 | ||
|             var p = new POINT { X = (int)point.X, Y = (int)point.Y };
 | ||
|             UnmanagedMethods.ScreenToClient(handle, ref p);
 | ||
|             return new Point(p.X, p.Y) / scaling;
 | ||
|         }
 | ||
|         //private Point DipFromLParam(IntPtr lParam)
 | ||
|         //{
 | ||
|         //    //var rect = WindowPixelRectangle;
 | ||
|         //    Debug.WriteLine((ToInt32(lParam) & 0xffff));
 | ||
|         //    return new Point((ToInt32(lParam) & 0xffff), (ToInt32(lParam) >> 16)) / scaling;
 | ||
|         //}
 | ||
|         private Point DipFromLParam(IntPtr lParam)
 | ||
|         {
 | ||
|             return new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)) / RenderScaling;
 | ||
|         }
 | ||
|         public static int ToInt32(IntPtr ptr)
 | ||
|         {
 | ||
|             if (IntPtr.Size == 4) return ptr.ToInt32();
 | ||
| 
 | ||
|             return (int)(ptr.ToInt64() & 0xffffffff);
 | ||
|         }
 | ||
|         public static int SignedHIWORD(int n)
 | ||
|         {
 | ||
|             int i = (int)(short)((n >> 16) & 0xffff);
 | ||
| 
 | ||
|             return i;
 | ||
|         }
 | ||
| 
 | ||
|         public static int SignedLOWORD(int n)
 | ||
|         {
 | ||
|             int i = (int)(short)(n & 0xFFFF);
 | ||
| 
 | ||
|             return i;
 | ||
|         }
 | ||
|         public static int SignedHIWORD(IntPtr n)
 | ||
|         {
 | ||
|             return SignedHIWORD(unchecked((int)(long)n));
 | ||
|         }
 | ||
|         public static int SignedLOWORD(IntPtr n)
 | ||
|         {
 | ||
|             return SignedLOWORD(unchecked((int)(long)n));
 | ||
|         }
 | ||
|         public bool IsTouch()
 | ||
|         {
 | ||
|             uint extra = GetMessageExtraInfo();
 | ||
|             bool isTouchOrPen = ((extra & 0xFFFFFF00) == 0xFF515700);
 | ||
|             if (!isTouchOrPen)
 | ||
|                 return false;
 | ||
|             bool isTouch = ((extra & 0x00000080) == 0x00000080);
 | ||
|             return isTouch;
 | ||
|         }
 | ||
|         public static int GetPointerId(IntPtr WParam)
 | ||
|         {
 | ||
|             return (short)WParam;
 | ||
|         }
 | ||
| 
 | ||
|         public static Point GetPointerLocation(IntPtr LParam)
 | ||
|         {
 | ||
|             var lowword = LParam.ToInt32();
 | ||
|             return new Point()
 | ||
|             {
 | ||
|                 X = (short)(lowword),
 | ||
|                 Y = (short)(lowword >> 16),
 | ||
|             };
 | ||
|         }
 | ||
| 
 | ||
|         private bool IsDown(Keys key)
 | ||
|         {
 | ||
|             return (GetKeyStates(key) & KeyStates.Down) != 0;
 | ||
|         }
 | ||
| 
 | ||
|         byte[] _keyStates = new byte[256];
 | ||
|         private KeyStates GetKeyStates(Keys key)
 | ||
|         {
 | ||
|             int vk = KeyInterop.VirtualKeyFromKey(key);
 | ||
|             byte state = _keyStates[vk];
 | ||
|             KeyStates result = 0;
 | ||
| 
 | ||
|             if ((state & 0x80) != 0)
 | ||
|             {
 | ||
|                 result |= KeyStates.Down;
 | ||
|             }
 | ||
| 
 | ||
|             if ((state & 0x01) != 0)
 | ||
|             {
 | ||
|                 result |= KeyStates.Toggled;
 | ||
|             }
 | ||
| 
 | ||
|             return result;
 | ||
|         }
 | ||
|         [Flags]
 | ||
|         public enum KeyStates : byte
 | ||
|         {
 | ||
|             None = 0,
 | ||
|             Down = 1,
 | ||
|             Toggled = 2,
 | ||
|         }
 | ||
|         InputModifiers GetMouseModifiers(IntPtr wParam)
 | ||
|         {
 | ||
|             GetKeyboardState(_keyStates);
 | ||
|             var keys = (ModifierKeys)ToInt32(wParam);
 | ||
|             //var modifiers = InputManager.KeyboardDevice.Modifiers;
 | ||
|             var modifiers = InputModifiers.None;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_LBUTTON))
 | ||
|                 modifiers |= InputModifiers.LeftMouseButton;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_RBUTTON))
 | ||
|                 modifiers |= InputModifiers.RightMouseButton;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_MBUTTON))
 | ||
|                 modifiers |= InputModifiers.MiddleMouseButton;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_CONTROL))
 | ||
|                 modifiers |= InputModifiers.Control;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_SHIFT))
 | ||
|                 modifiers |= InputModifiers.Shift;
 | ||
|             if (keys.HasFlag(ModifierKeys.MK_ALT) || IsDown(Keys.LeftAlt) || IsDown(Keys.RightAlt))
 | ||
|                 modifiers |= InputModifiers.Alt;//因为wParam获取不到alt键
 | ||
|             return modifiers;
 | ||
|         }
 | ||
|         /// <summary>
 | ||
|         /// 窗体位置和尺寸,屏幕像素
 | ||
|         /// </summary>
 | ||
|         public Rect Bounds
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 RECT r = new RECT();
 | ||
|                 GetWindowRect(handle, out r);
 | ||
|                 return new Rect(r.left, r.top, r.Width, r.Height);
 | ||
|             }
 | ||
|             set
 | ||
|             {
 | ||
|                 //bounds = value;
 | ||
|                 if (ScalingChangedPosition.HasValue)
 | ||
|                 {
 | ||
|                     SetWindowPos(handle, IntPtr.Zero, ScalingChangedPosition.Value.X, ScalingChangedPosition.Value.Y, (int)value.Width, (int)value.Height, SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     SetWindowPos(handle, IntPtr.Zero, (int)value.Left, (int)value.Top, (int)value.Width, (int)value.Height, SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
|         }
 | ||
|         //Rect? bounds;
 | ||
| 
 | ||
|         public PixelPoint Position
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 RECT r = new RECT();
 | ||
|                 GetWindowRect(handle, out r);
 | ||
|                 return new PixelPoint(r.left, r.top);
 | ||
|             }
 | ||
|             set
 | ||
|             {
 | ||
|                 RECT r = new RECT();
 | ||
|                 GetWindowRect(handle, out r);
 | ||
|                 //bounds = new Rect(value.X, value.Y, r.Width, r.Height);
 | ||
|                 SetWindowPos(handle, IntPtr.Zero, value.X, value.Y, r.Width, r.Height, SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         public WindowState WindowState
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 var placement = default(UnmanagedMethods.WINDOWPLACEMENT);
 | ||
|                 UnmanagedMethods.GetWindowPlacement(handle, ref placement);
 | ||
| 
 | ||
|                 switch (placement.ShowCmd)
 | ||
|                 {
 | ||
|                     case ShowWindowCommand.ShowMaximized:
 | ||
|                         if (windowState == WindowState.FullScreen)
 | ||
|                         {
 | ||
|                             return windowState;
 | ||
|                         }
 | ||
|                         return WindowState.Maximized;
 | ||
|                     case ShowWindowCommand.ShowMinimized:
 | ||
|                         return WindowState.Minimized;
 | ||
|                     default:
 | ||
|                         return WindowState.Normal;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             set
 | ||
|             {
 | ||
|                 windowState = value;
 | ||
|                 if (UnmanagedMethods.IsWindowVisible(handle))
 | ||
|                 {
 | ||
|                     SetVisible(true);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         private static bool multiMonitorSupport = (GetSystemMetrics(SystemMetric.SM_CMONITORS) != 0);
 | ||
|         private const int PRIMARY_MONITOR = unchecked((int)0xBAADF00D);
 | ||
|         public Screen Screen
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 if (multiMonitorSupport)
 | ||
|                 {
 | ||
|                     var sc = MonitorFromWindow(handle, MONITOR.MONITOR_DEFAULTTONEAREST);
 | ||
|                     return ScreenImpl.FromMonitor(sc, IntPtr.Zero);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     return ScreenImpl.FromMonitor((IntPtr)PRIMARY_MONITOR, IntPtr.Zero);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|         bool canActivate = true;
 | ||
|         public bool CanActivate
 | ||
|         {
 | ||
|             get { return canActivate; }
 | ||
| 
 | ||
|             set
 | ||
|             {
 | ||
|                 if (canActivate != value)
 | ||
|                 {
 | ||
|                     canActivate = value;
 | ||
|                     if (!value)
 | ||
|                     {
 | ||
|                         SetWindowLongPtr(handle, (int)WindowLongParam.GWL_EXSTYLE, (IntPtr)(ExStyle | WindowStyles.WS_EX_NOACTIVATE));
 | ||
|                         SetWindowLongPtr(handle, (int)WindowLongParam.GWL_STYLE, (IntPtr)(Style | WindowStyles.WS_CHILD));
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         SetWindowLongPtr(handle, (int)WindowLongParam.GWL_EXSTYLE, (IntPtr)(ExStyle));
 | ||
|                         SetWindowLongPtr(handle, (int)WindowLongParam.GWL_STYLE, (IntPtr)(Style));
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         private void WmGetMinMaxInfo(IntPtr handle, IntPtr lParam)
 | ||
|         {
 | ||
|             // MINMAXINFO structure  
 | ||
|             MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
 | ||
| 
 | ||
|             // Get handle for nearest monitor to this window  
 | ||
|             //WindowInteropHelper wih = new WindowInteropHelper(this);
 | ||
|             IntPtr hMonitor = MonitorFromWindow(handle, MONITOR.MONITOR_DEFAULTTONEAREST);
 | ||
| 
 | ||
|             // Get monitor info  
 | ||
|             MONITORINFO monitorInfo = new MONITORINFO();
 | ||
|             monitorInfo.cbSize = Marshal.SizeOf(monitorInfo);
 | ||
|             GetMonitorInfo(hMonitor, ref monitorInfo);
 | ||
| 
 | ||
|             //// Get HwndSource  
 | ||
|             //HwndSource source = HwndSource.FromHwnd(wih.Handle);
 | ||
|             //if (source == null)
 | ||
|             //    // Should never be null  
 | ||
|             //    throw new Exception("Cannot get HwndSource instance.");
 | ||
|             //if (source.CompositionTarget == null)
 | ||
|             //    // Should never be null  
 | ||
|             //    throw new Exception("Cannot get HwndTarget instance.");
 | ||
| 
 | ||
|             //// Get transformation matrix  
 | ||
|             //Matrix matrix = source.CompositionTarget.TransformFromDevice;
 | ||
| 
 | ||
|             // Convert working area  
 | ||
|             RECT workingArea = monitorInfo.rcWork;
 | ||
|             //Point dpiIndependentSize =
 | ||
|             //    matrix.Transform(new Point(
 | ||
|             //            workingArea.Right - workingArea.Left,
 | ||
|             //            workingArea.Bottom - workingArea.Top
 | ||
|             //            ));
 | ||
| 
 | ||
|             //// Convert minimum size  
 | ||
|             //Point dpiIndenpendentTrackingSize = matrix.Transform(new Point(
 | ||
|             //    this.MinWidth,
 | ||
|             //    this.MinHeight
 | ||
|             //    ));
 | ||
| 
 | ||
|             // Set the maximized size of the window  
 | ||
|             //mmi.ptMaxSize.x = (int)dpiIndependentSize.X;
 | ||
|             //mmi.ptMaxSize.y = (int)dpiIndependentSize.Y;
 | ||
|             if (windowState == WindowState.FullScreen)
 | ||
|             {
 | ||
|                 mmi.ptMaxSize.X = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
 | ||
|                 mmi.ptMaxSize.Y = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 mmi.ptMaxSize.X = workingArea.right - workingArea.left;
 | ||
|                 mmi.ptMaxSize.Y = workingArea.bottom - workingArea.top;
 | ||
|             }
 | ||
|             ////mmi.ptMaxTrackSize.x = 1370;
 | ||
|             ////mmi.ptMaxTrackSize.y = 772;
 | ||
|             //// Set the position of the maximized window  
 | ||
|             mmi.ptMaxPosition.X = windowState == WindowState.FullScreen ? 0 : workingArea.left - monitorInfo.rcMonitor.left;
 | ||
|             mmi.ptMaxPosition.Y = windowState == WindowState.FullScreen ? 0 : workingArea.top - monitorInfo.rcMonitor.top;
 | ||
| 
 | ||
|             // Set the minimum tracking size  
 | ||
|             //mmi.ptMinTrackSize.X = 1;//(int)dpiIndenpendentTrackingSize.X;
 | ||
|             //mmi.ptMinTrackSize.Y = 1;//(int)dpiIndenpendentTrackingSize.Y;
 | ||
| 
 | ||
|             mmi.ptMinTrackSize.X = 0;
 | ||
|             mmi.ptMinTrackSize.Y = 0;
 | ||
| 
 | ||
|             Marshal.StructureToPtr(mmi, lParam, true);
 | ||
|         }
 | ||
| 
 | ||
|         public void SetCursor(Cursor cursor)
 | ||
|         {
 | ||
|             var hCursor = (IntPtr)cursor.PlatformCursor == IntPtr.Zero ? DefaultCursor : (IntPtr)cursor.PlatformCursor;
 | ||
|             UnmanagedMethods.SetClassLong(handle, UnmanagedMethods.ClassLongIndex.GCLP_HCURSOR, hCursor);
 | ||
| 
 | ||
|             //if (_owner.IsPointerOver)
 | ||
|             //    UnmanagedMethods.SetCursor(hCursor);
 | ||
|         }
 | ||
| 
 | ||
|         public void SetRoot(View view)
 | ||
|         {
 | ||
|             root = view;
 | ||
|             root.LayoutUpdated += Root_LayoutUpdated;
 | ||
|         }
 | ||
| 
 | ||
|         private void Root_LayoutUpdated(object sender, RoutedEventArgs e)
 | ||
|         {
 | ||
|             var b = Bounds;
 | ||
|             var s = root.ActualSize;
 | ||
|             var l = root.ActualOffset;
 | ||
|             var src = root.Screen;
 | ||
|             if ((int)b.Width != (int)Math.Ceiling(s.Width * scaling) || (int)b.Height != (int)Math.Ceiling(s.Height * scaling) || (int)b.X != (int)(l.X * scaling + src.WorkingArea.X) || (int)b.Y != (int)(l.Y * scaling + src.WorkingArea.Y))
 | ||
|             {
 | ||
|                 Bounds = new Rect(l.X * scaling + src.WorkingArea.X, l.Y * scaling + src.WorkingArea.Y, (float)Math.Ceiling(s.Width * scaling), (float)Math.Ceiling(s.Height * scaling));
 | ||
|             }
 | ||
|             //Debug.WriteLine("Root_LayoutUpdated" + s);
 | ||
|         }
 | ||
| 
 | ||
|         public float RenderScaling
 | ||
|         {
 | ||
|             get { return scaling; }
 | ||
|         }
 | ||
| 
 | ||
|         bool createimeCentext = false;
 | ||
|         IntPtr imeCentext;
 | ||
|         //public bool EnabledIME
 | ||
|         //{
 | ||
|         //    get { return ImmGetOpenStatus(imeCentext); }
 | ||
|         //    set
 | ||
|         //    {
 | ||
|         //        ImmSetOpenStatus(imeCentext, value);
 | ||
|         //    }
 | ||
|         //}
 | ||
|         public void SetIMEEnable(bool value)
 | ||
|         {
 | ||
|             ImmSetOpenStatus(imeCentext, value);
 | ||
|             if (IsTouch())
 | ||
|             {
 | ||
|                 string windir = Environment.GetEnvironmentVariable("WINDIR");
 | ||
|                 string osk = null;
 | ||
| 
 | ||
|                 if (osk == null)
 | ||
|                 {
 | ||
|                     osk = System.IO.Path.Combine(System.IO.Path.Combine(windir, "sysnative"), "osk.exe");
 | ||
|                     if (!System.IO.File.Exists(osk))
 | ||
|                         osk = null;
 | ||
|                 }
 | ||
| 
 | ||
|                 if (osk == null)
 | ||
|                 {
 | ||
|                     osk = System.IO.Path.Combine(System.IO.Path.Combine(windir, "system32"), "osk.exe");
 | ||
|                     if (!System.IO.File.Exists(osk))
 | ||
|                     {
 | ||
|                         osk = null;
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
|                 if (osk == null)
 | ||
|                     osk = "osk.exe";
 | ||
|                 Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = osk });
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         bool ismain;
 | ||
|         public bool IsMain
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 return ismain;
 | ||
|             }
 | ||
| 
 | ||
|             set
 | ||
|             {
 | ||
|                 ismain = value;
 | ||
|                 if (value)
 | ||
|                 {
 | ||
|                     Window = this;
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         public void SetIMEPosition(Point point)
 | ||
|         {
 | ||
|             COMPOSITIONFORM cf = new COMPOSITIONFORM();
 | ||
|             cf.dwStyle = 2;
 | ||
|             cf.ptCurrentPos = new POINT((int)(point.X * scaling), (int)(point.Y * scaling));
 | ||
|             ImmSetCompositionWindow(imeCentext, ref cf);
 | ||
|         }
 | ||
| 
 | ||
|         public Point PointToScreen(Point point)
 | ||
|         {
 | ||
|             point *= scaling;
 | ||
|             var p = new POINT { X = (int)point.X, Y = (int)point.Y };
 | ||
|             ClientToScreen(handle, ref p);
 | ||
|             return new Point(p.X, p.Y);
 | ||
|         }
 | ||
| 
 | ||
|         bool paint = false;
 | ||
|         Rect invalidateRect;
 | ||
|         public void Invalidate(in Rect rect)
 | ||
|         {
 | ||
|             Rect all = new Rect(new Point(), root.ActualSize);//控件区域
 | ||
|             if ((all.Contains(rect) || rect.IntersectsWith(all) || all == rect || rect.Contains(all)) && !rect.IsEmpty && !all.IsEmpty)
 | ||
|             {
 | ||
|                 //Debug.WriteLine(invalidateRect);
 | ||
|                 if (invalidateRect.IsEmpty || rect.Contains(invalidateRect) || rect == invalidateRect)//如果更新区域大于原有失效区域,则当前失效区域设为更新区域
 | ||
|                 {
 | ||
|                     invalidateRect = rect;
 | ||
|                 }
 | ||
|                 else if (invalidateRect.Contains(rect))//如果更新区域小于原来的失效区域,则失效区域不变
 | ||
|                 {
 | ||
| 
 | ||
|                 }
 | ||
|                 else if (invalidateRect.IsEmpty)//如果原来的失效区域为空
 | ||
|                 {
 | ||
|                     invalidateRect = rect;
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {//如果两个区域没有关联或者相交
 | ||
|                     var minX = invalidateRect.X < rect.X ? invalidateRect.X : rect.X;//确定包含这两个矩形的最小矩形
 | ||
|                     var minY = invalidateRect.Y < rect.Y ? invalidateRect.Y : rect.Y;
 | ||
|                     var maxW = (invalidateRect.Width + invalidateRect.X - minX) > (rect.Width + rect.X - minX) ? (invalidateRect.Width + invalidateRect.X - minX) : (rect.Width + rect.X - minX);
 | ||
|                     var maxH = (invalidateRect.Height + invalidateRect.Y - minY) > (rect.Height + rect.Y - minY) ? (invalidateRect.Height + invalidateRect.Y - minY) : (rect.Height + rect.Y - minY);
 | ||
|                     Rect min = new Rect(minX, minY, maxW, maxH);
 | ||
| 
 | ||
|                     invalidateRect = min;
 | ||
|                 }
 | ||
|                 invalidateRect.Intersect(all);//最后失效区域为在控件区域里面的相交区域
 | ||
|             }
 | ||
|             if (!paint && (timer == null ))//&& isLayered
 | ||
|             {
 | ||
|                 paint = true;
 | ||
|                 BeginInvoke(a =>
 | ||
|                 {
 | ||
|                     root.LayoutManager.ExecuteLayoutPass();
 | ||
|                     Rect rect1 = new Rect(((invalidateRect.X - 1) * scaling), ((invalidateRect.Y - 1) * scaling), ((invalidateRect.Width + 2) * scaling), ((invalidateRect.Height + 2) * scaling));
 | ||
|                     if (isLayered)
 | ||
|                     {
 | ||
|                         OnPaint(IntPtr.Zero, rect1);
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         RECT r = new RECT(rect1);
 | ||
|                         //InvalidateRect(handle, ref r, false);
 | ||
|                         RedrawWindow(handle, ref r, IntPtr.Zero, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
 | ||
|                     }
 | ||
|                     //System.Diagnostics.Debug.WriteLine(invalidateRect);
 | ||
|                     invalidateRect = new Rect();
 | ||
|                     paint = false;
 | ||
|                 }, null);
 | ||
|             }
 | ||
|             //if (timer == null && !isLayered)
 | ||
|             //{
 | ||
|             //    RECT r = new RECT((int)((rect.X - 1) * scaling), (int)((rect.Y - 1) * scaling), (int)((rect.Right + 2) * scaling), (int)((rect.Bottom + 2) * scaling));
 | ||
|             //    InvalidateRect(handle, ref r, false);
 | ||
|             //}
 | ||
|         }
 | ||
| 
 | ||
|         private void Timer_Tick(object sender, EventArgs e)
 | ||
|         {
 | ||
|             if (handle != IntPtr.Zero && IsWindowVisible(handle) && windowState != WindowState.Minimized && invalidateRect.Width > 0 && invalidateRect.Height > 0)
 | ||
|             {
 | ||
|                 root.LayoutManager.ExecuteLayoutPass();
 | ||
|                 Rect rect1 = new Rect(((invalidateRect.X - 1) * scaling), ((invalidateRect.Y - 1) * scaling), ((invalidateRect.Width + 2) * scaling), ((invalidateRect.Height + 2) * scaling));
 | ||
|                 if (isLayered)
 | ||
|                 {
 | ||
|                     OnPaint(IntPtr.Zero, rect1);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     RECT r = new RECT(rect1);
 | ||
|                     //InvalidateRect(handle, ref r, false);
 | ||
|                     RedrawWindow(handle, ref r, IntPtr.Zero, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
 | ||
|                 }
 | ||
|                 //System.Diagnostics.Debug.WriteLine(invalidateRect);
 | ||
|                 invalidateRect = new Rect();
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         public void Activate()
 | ||
|         {
 | ||
|             UnmanagedMethods.SetActiveWindow(handle);
 | ||
|         }
 | ||
| 
 | ||
|         public void Capture()
 | ||
|         {
 | ||
|             SetCapture(handle);
 | ||
|         }
 | ||
| 
 | ||
|         WindowImpl _parent;
 | ||
|         public void ShowDialog(Window parent)
 | ||
|         {
 | ||
|             _parent = (WindowImpl)parent.ViewImpl;
 | ||
|             Show();
 | ||
|             SetWindowLongPtr(handle, (int)WindowLongParam.GWL_HWNDPARENT, _parent.handle);
 | ||
|         }
 | ||
| 
 | ||
|         public void ReleaseCapture()
 | ||
|         {
 | ||
|             UnmanagedMethods.ReleaseCapture();
 | ||
|         }
 | ||
| 
 | ||
|         public void Show()
 | ||
|         {
 | ||
|             //_parent = null;
 | ||
|             root.Visibility = Visibility.Visible;
 | ||
|             //if (isFirst)
 | ||
|             //{
 | ||
|             //    isFirst = false;
 | ||
|             //root.LayoutManager.ExecuteLayoutPass();
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         public void Hide()
 | ||
|         {
 | ||
|             root.Visibility = Visibility.Collapsed;
 | ||
|         }
 | ||
| 
 | ||
|         public void Close()
 | ||
|         {
 | ||
|             SendMessage(handle, (int)WindowsMessage.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
 | ||
|         }
 | ||
| 
 | ||
|         public void SetTitle(string title)
 | ||
|         {
 | ||
|             UnmanagedMethods.SetWindowText(handle, title);
 | ||
|         }
 | ||
| 
 | ||
|         bool _taskbarIcon = true;
 | ||
|         public void ShowInTaskbar(bool value)
 | ||
|         {
 | ||
|             if (_taskbarIcon == value)
 | ||
|             {
 | ||
|                 return;
 | ||
|             }
 | ||
| 
 | ||
|             _taskbarIcon = value;
 | ||
| 
 | ||
|             var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(handle, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
 | ||
| 
 | ||
|             style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
 | ||
| 
 | ||
|             style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
 | ||
| 
 | ||
|             if (value)
 | ||
|                 style |= UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW;
 | ||
|             else
 | ||
|                 style &= ~(UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW);
 | ||
| 
 | ||
|             WINDOWPLACEMENT windowPlacement = UnmanagedMethods.WINDOWPLACEMENT.Default;
 | ||
|             if (UnmanagedMethods.GetWindowPlacement(handle, ref windowPlacement))
 | ||
|             {
 | ||
|                 //Toggle to make the styles stick
 | ||
|                 UnmanagedMethods.ShowWindow(handle, ShowWindowCommand.Hide);
 | ||
|                 UnmanagedMethods.SetWindowLong(handle, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE, (uint)style);
 | ||
|                 UnmanagedMethods.ShowWindow(handle, windowPlacement.ShowCmd);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         public bool IsTopMost
 | ||
|         {
 | ||
|             get { return _topmost; }
 | ||
|         }
 | ||
| 
 | ||
|         bool _topmost = false;
 | ||
|         public void TopMost(bool value)
 | ||
|         {
 | ||
|             if (value == _topmost)
 | ||
|             {
 | ||
|                 return;
 | ||
|             }
 | ||
| 
 | ||
|             IntPtr hWndInsertAfter = value ? WindowPosZOrder.HWND_TOPMOST : WindowPosZOrder.HWND_NOTOPMOST;
 | ||
|             UnmanagedMethods.SetWindowPos(handle,
 | ||
|                    hWndInsertAfter,
 | ||
|                    0, 0, 0, 0,
 | ||
|                    SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
| 
 | ||
|             _topmost = value;
 | ||
|         }
 | ||
| 
 | ||
|         public void Dispose()
 | ||
|         {
 | ||
|             if (handle != IntPtr.Zero)
 | ||
|             {
 | ||
|                 var h = handle;
 | ||
|                 handle = IntPtr.Zero;
 | ||
|                 UnmanagedMethods.DestroyWindow(h);
 | ||
|             }
 | ||
|             //if (Window == this)
 | ||
|             //{
 | ||
|             //    Window = null;
 | ||
|             //}
 | ||
|         }
 | ||
| 
 | ||
|         public void SetVisible(bool visible)
 | ||
|         {
 | ||
|             //var v = IsWindowVisible(handle);
 | ||
|             root.InputManager.TouchDevice.ClearPoints();
 | ||
|             if (visible)
 | ||
|             {
 | ||
|                 if (windowState == WindowState.Normal)
 | ||
|                 {
 | ||
|                     root.LayoutManager.ExecuteLayoutPass();
 | ||
|                     invalidateRect = new Rect(new Point(), root.ActualSize);
 | ||
|                     if (isLayered)
 | ||
|                     {
 | ||
|                         OnPaint(IntPtr.Zero, new Rect((invalidateRect.X - 1) * scaling, (invalidateRect.Y - 1) * scaling, (invalidateRect.Width + 2) * scaling, (invalidateRect.Height + 2) * scaling));
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         //UpdateWindow(handle);
 | ||
|                     }
 | ||
|                     invalidateRect = new Rect();
 | ||
|                     if (canActivate)
 | ||
|                     {
 | ||
|                         ShowWindow(handle, ShowWindowCommand.Normal);
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         ShowWindow(handle, ShowWindowCommand.ShowNoActivate);
 | ||
|                     }
 | ||
|                     //if (_parent != null)
 | ||
|                     //{
 | ||
|                     //    //EnableWindow(_parent.handle, false);
 | ||
|                     //    _parent.SetEnable(false);
 | ||
|                     //}
 | ||
|                     if (this is PopupImpl)
 | ||
|                     {
 | ||
|                         SetWindowPos(handle, WindowPosZOrder.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE);
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else if (windowState == WindowState.Maximized || windowState == WindowState.FullScreen)
 | ||
|                 {
 | ||
|                     root.LayoutManager.ExecuteLayoutPass();
 | ||
|                     invalidateRect = new Rect(new Point(), root.ActualSize);
 | ||
|                     if (isLayered)
 | ||
|                     {
 | ||
|                         OnPaint(IntPtr.Zero, new Rect((invalidateRect.X - 1) * scaling, (invalidateRect.Y - 1) * scaling, (invalidateRect.Width + 2) * scaling, (invalidateRect.Height + 2) * scaling));
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
| 
 | ||
|                     }
 | ||
|                     invalidateRect = new Rect();
 | ||
|                     if (windowState == WindowState.FullScreen)
 | ||
|                     {
 | ||
|                         var placement = default(UnmanagedMethods.WINDOWPLACEMENT);
 | ||
|                         UnmanagedMethods.GetWindowPlacement(handle, ref placement);
 | ||
|                         if (placement.ShowCmd == ShowWindowCommand.ShowMaximized)
 | ||
|                         {
 | ||
|                             ShowWindow(handle, ShowWindowCommand.Normal);
 | ||
|                         }
 | ||
|                     }
 | ||
|                     ShowWindow(handle, ShowWindowCommand.Maximize);
 | ||
|                     //if (_parent != null)
 | ||
|                     //{
 | ||
|                     //    //EnableWindow(_parent.handle, false);
 | ||
|                     //    _parent.SetEnable(false);
 | ||
|                     //}
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     ShowWindow(handle, ShowWindowCommand.Minimize);
 | ||
|                     //if (_parent != null)
 | ||
|                     //{
 | ||
|                     //    //EnableWindow(_parent.handle, false);
 | ||
|                     //    _parent.SetEnable(false);
 | ||
|                     //}
 | ||
|                 }
 | ||
|                 //if (bounds.HasValue)
 | ||
|                 //{
 | ||
|                 //    Bounds = bounds.Value;
 | ||
|                 //}
 | ||
|                 //Show();
 | ||
|             }
 | ||
|             else if (!visible)
 | ||
|             {
 | ||
|                 //Hide();
 | ||
|                 ShowWindow(handle, ShowWindowCommand.Hide);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         //private static int bitDepth;
 | ||
|         IntPtr IconHandle = IntPtr.Zero;
 | ||
|         public unsafe void SetIcon(Image image)
 | ||
|         {
 | ||
|             var stream = image.SaveToStream(ImageFormat.Png);
 | ||
|             var states = GdipCreateBitmapFromStream(new GPStream(stream), out IntPtr bitmap);
 | ||
|             stream.Dispose();
 | ||
|             GdipCreateHICONFromBitmap(bitmap, out IntPtr hIcon);
 | ||
|             GdipDisposeImage(bitmap);
 | ||
|             if (IconHandle != IntPtr.Zero)
 | ||
|             {
 | ||
|                 DestroyIcon(IconHandle);
 | ||
|             }
 | ||
|             IconHandle = hIcon;
 | ||
|             PostMessage(handle, (int)WindowsMessage.WM_SETICON, new IntPtr((int)Icons.ICON_BIG), hIcon);
 | ||
|         }
 | ||
|         private unsafe short GetShort(byte* pb)
 | ||
|         {
 | ||
|             int retval = 0;
 | ||
|             if (0 != (unchecked((byte)pb) & 1))
 | ||
|             {
 | ||
|                 retval = *pb;
 | ||
|                 pb++;
 | ||
|                 retval = unchecked(retval | (*pb << 8));
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 retval = unchecked((int)(*(short*)pb));
 | ||
|             }
 | ||
|             return unchecked((short)retval);
 | ||
|         }
 | ||
| 
 | ||
|         private unsafe int GetInt(byte* pb)
 | ||
|         {
 | ||
|             int retval = 0;
 | ||
|             if (0 != (unchecked((byte)pb) & 3))
 | ||
|             {
 | ||
|                 retval = *pb; pb++;
 | ||
|                 retval = retval | (*pb << 8); pb++;
 | ||
|                 retval = retval | (*pb << 16); pb++;
 | ||
|                 retval = unchecked(retval | (*pb << 24));
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 retval = *(int*)pb;
 | ||
|             }
 | ||
|             return retval;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         //bool fullscreen;
 | ||
|         //public void SetFullscreen(bool fullscreen)
 | ||
|         //{
 | ||
|         //    this.fullscreen = fullscreen;
 | ||
|         //    if (fullscreen)
 | ||
|         //    {
 | ||
|         //        WindowState = WindowState.Maximized;
 | ||
|         //    }
 | ||
|         //    else
 | ||
|         //    {
 | ||
|         //        if (WindowState == WindowState.Maximized)
 | ||
|         //        {
 | ||
|         //            WindowState = WindowState.Normal;
 | ||
|         //        }
 | ||
|         //    }
 | ||
|         //}
 | ||
| 
 | ||
|         bool isEnable = true;
 | ||
|         public void SetEnable(bool enable)
 | ||
|         {
 | ||
|             isEnable = enable;
 | ||
|             //EnableWindow(handle, enable);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         public float LayoutScaling { get { return scaling; } }
 | ||
|     }
 | ||
|     class PopupImpl : WindowImpl, IPopupImpl
 | ||
|     {
 | ||
|         protected override WindowStyles Style
 | ||
|         {
 | ||
|             get { return WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_POPUP; }// | WindowStyles.WS_MAXIMIZEBOX
 | ||
|         }
 | ||
|         protected override WindowStyles ExStyle
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 var style = WindowStyles.WS_EX_TOOLWINDOW | WindowStyles.WS_EX_TOPMOST;
 | ||
|                 if (isLayered)
 | ||
|                 {
 | ||
|                     style |= WindowStyles.WS_EX_LAYERED;
 | ||
|                 }
 | ||
|                 return style;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         protected override IntPtr WndProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam)
 | ||
|         {
 | ||
|             switch ((WindowsMessage)msg)
 | ||
|             {
 | ||
|                 case WindowsMessage.WM_ACTIVATE:
 | ||
|                     var wa = (WindowActivate)(ToInt32(wParam) & 0xffff);
 | ||
| 
 | ||
|                     switch (wa)
 | ||
|                     {
 | ||
|                         case WindowActivate.WA_INACTIVE:
 | ||
| 
 | ||
|                             break;
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     break;
 | ||
|             }
 | ||
|             return base.WndProc(hwnd, msg, wParam, lParam);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     public class SendOrPostData
 | ||
|     {
 | ||
|         public SendOrPostCallback SendOrPostCallback;
 | ||
| 
 | ||
|         public object Data;
 | ||
| 
 | ||
|         public ManualResetEvent ManualResetEvent;
 | ||
|     }
 | ||
| 
 | ||
| }
 | 
