Пример #1
0
        private IntPtr WindowProc(IntPtr hwnd, Win32MessageType uMsg, IntPtr wParam, IntPtr lParam)
        {
            if (HandleWindowEvent(hwnd, uMsg, wParam, lParam))
            {
                return(IntPtr.Zero);
            }

            if (uMsg == Win32MessageType.WM_SETCURSOR)
            {
                uint lParam32 = (uint)lParam.ToInt64();
                var  hitTest  = (Win32HitTestResult)(lParam32 & 0xFFFF);
                if (hitTest == Win32HitTestResult.HTCLIENT)
                {
                    IntPtr cursor = Win32API.LoadImageW(
                        IntPtr.Zero,
                        Win32SystemResources.IDC_ARROW,
                        Win32ImageType.IMAGE_CURSOR,
                        0, 0,
                        Win32LoadImageFlags.LR_DEFAULTSIZE | Win32LoadImageFlags.LR_SHARED
                        );
                    if (cursor != IntPtr.Zero)
                    {
                        Win32API.SetCursor(cursor);
                        return(IntPtr.Zero);
                    }
                }
            }

            if (uMsg == Win32MessageType.WM_DESTROY)
            {
                windows.Remove(hwnd);
                Win32API.PostQuitMessage(0);
                return(IntPtr.Zero);
            }

            if (uMsg == Win32MessageType.WM_MOUSEMOVE)
            {
                if (windows.TryGetValue(hwnd, out var window))
                {
                    uint wParam32 = (uint)wParam.ToInt64();
                    uint lParam32 = (uint)lParam.ToInt64();
                    int  x        = (short)(lParam32 & 0xFFFF);
                    int  y        = (short)((lParam32 >> 16) & 0xFFFF);
                    window.StartupInfo.OnMouseMove(new Point(x, y));
                }

                return(IntPtr.Zero);
            }

            if (uMsg == Win32MessageType.WM_CHAR)
            {
                if (windows.TryGetValue(hwnd, out var window))
                {
                    char c = (char)wParam.ToInt64();

                    if (!char.IsControl(c))
                    {
                        window.StartupInfo.OnTextInput(c.ToString());
                    }
                }

                return(IntPtr.Zero);
            }

            if (uMsg == Win32MessageType.WM_PAINT)
            {
                PAINTSTRUCT ps  = new PAINTSTRUCT();
                IntPtr      hdc = Win32API.BeginPaint(hwnd, ref ps);
                try
                {
                    if (windows.TryGetValue(hwnd, out var window))
                    {
                        Rectangle area = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.Width, ps.rcPaint.Height);
                        using (Win32Bitmap bitmap = Win32Bitmap.Create(hdc, area.Width, area.Height))
                        {
                            using (Win32Canvas canvas = graphics.CreateCanvas(bitmap, new Point(-area.X, -area.Y)))
                            {
                                window.StartupInfo.OnPaint(canvas, area);
                            }

                            bitmap.CopyTo(hdc, area.X, area.Y);
                        }
                    }
                }
                finally
                {
                    Win32API.EndPaint(hwnd, ref ps);
                }

                return(IntPtr.Zero);
            }

            if (uMsg == Win32MessageType.WM_SIZE)
            {
                if (windows.TryGetValue(hwnd, out var window))
                {
                    ulong lParam32 = (uint)lParam.ToInt64();
                    int   width    = (short)(lParam32 & 0xFFFF);
                    int   height   = (short)((lParam32 >> 16) & 0xFFFF);
                    window.StartupInfo.OnResize(new Size(width, height));
                }

                return(IntPtr.Zero);
            }

            return(Win32API.DefWindowProcW(hwnd, uMsg, wParam, lParam));
        }
Пример #2
0
        public void Run(INativeWindowStartupInfo startupInfo)
        {
            GdiplusStartupInput gdiPlusStartupInput = GdiplusStartupInput.CreateV1();

            GdiPlusAPI.CheckStatus(GdiPlusAPI.GdiplusStartup(out var gdiPlusToken, ref gdiPlusStartupInput, out _));
            IntPtr hInstance = Win32API.GetModuleHandleW(null);

            var windowClass = new WNDCLASSEXW();

            windowClass.cbSize        = (uint)Marshal.SizeOf <WNDCLASSEXW>();
            windowClass.lpfnWndProc   = WindowProc;
            windowClass.hInstance     = hInstance;
            windowClass.lpszClassName = WindowClassName;
            var atom = Win32API.RegisterClassExW(ref windowClass);

            if (atom == 0)
            {
                throw new InvalidOperationException("Failed to register window class.");
            }

            try
            {
                const int CW_USEDEFAULT = unchecked ((int)0x80000000);
                IntPtr    hwnd          = Win32API.CreateWindowExW(
                    0,
                    WindowClassName,
                    startupInfo.Title,
                    Win32WindowStyle.WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    startupInfo.Width, startupInfo.Height,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    hInstance,
                    IntPtr.Zero
                    );

                if (hwnd == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Failed to create a window.");
                }

                var window = new Win32Window(hwnd, startupInfo);
                windows.Add(hwnd, window);
                startupInfo.OnCreate(window);

                try
                {
                    Win32API.ShowWindow(hwnd, Win32ShowWindowCommand.SW_SHOWNORMAL);

                    MSG msg = new MSG();
                    int mRet;
                    while ((mRet = Win32API.GetMessageW(ref msg, IntPtr.Zero, 0, 0)) != 0)
                    {
                        if (mRet == -1)
                        {
                            throw new InvalidOperationException("Failed to retrieve a message.");
                        }

                        Win32API.TranslateMessage(ref msg);
                        Win32API.DispatchMessageW(ref msg);
                    }
                }
                finally
                {
                    // usually window will be destroyed before this point, unless error occurs
                    if (Win32API.DestroyWindow(hwnd) == 0)
                    {
                        // todo: log warning ?
                    }
                }
            }
            finally
            {
                if (Win32API.UnregisterClassW(WindowClassName, hInstance) == 0)
                {
                    // todo: log warning
                }

                // todo: use separate finally for GDI+
                GdiPlusAPI.GdiplusShutdown(gdiPlusToken);
            }
        }
Пример #3
0
 public void SetTitle(string title)
 {
     Win32API.SetWindowTextW(windowHandle, title);
 }