Exemple #1
0
 private void UpdateKeyboard()
 {
     for (int index1 = 0; index1 < 256; ++index1)
     {
         VirtualKeys index2 = (VirtualKeys)index1;
         bool        flag   = (int)Functions.GetAsyncKeyState(index2) >> 8 != 0;
         if (this.KeyMap.ContainsKey(index2))
         {
             this.keyboard[this.KeyMap[index2]] = flag;
         }
     }
 }
Exemple #2
0
 void UpdateKeyboard()
 {
     for (int i = 0; i < 256; i++)
     {
         VirtualKeys key     = (VirtualKeys)i;
         bool        pressed = (Functions.GetAsyncKeyState(key) >> 8) != 0;
         if (KeyMap.ContainsKey(key))
         {
             keyboard[KeyMap[key]] = pressed;
         }
     }
 }
Exemple #3
0
 internal static extern uint MapVirtualKey(VirtualKeys vkey, MapVirtualKeyType uMapType);
Exemple #4
0
        public Key TranslateKey(short scancode, VirtualKeys vkey, bool extended0, bool extended1, out bool is_valid)
        {
            is_valid = true;

            Key key;

            ScanMap.TryGetValue(scancode, out key);

            if (!extended0)
            {
                switch (key)
                {
                case Key.Insert: key = Key.Keypad0; break;

                case Key.End: key = Key.Keypad1; break;

                case Key.Down: key = Key.Keypad2; break;

                case Key.PageDown: key = Key.Keypad3; break;

                case Key.Left: key = Key.Keypad4; break;

                case Key.Right: key = Key.Keypad6; break;

                case Key.Home: key = Key.Keypad7; break;

                case Key.Up: key = Key.Keypad8; break;

                case Key.PageUp: key = Key.Keypad9; break;

                case Key.PrintScreen: key = Key.KeypadMultiply; break;

                case Key.Delete: key = Key.KeypadDecimal; break;

                case Key.NumLock:
                    if (vkey == VirtualKeys.Last)
                    {
                        is_valid = false;
                    }
                    else if (vkey == VirtualKeys.PAUSE)
                    {
                        key = Key.Pause;
                    }
                    break;
                }
            }
            else
            {
                switch (key)
                {
                case Key.Enter: key = Key.KeypadEnter; break;

                case Key.AltLeft: key = Key.AltRight; break;

                case Key.AltRight: key = Key.AltLeft; break;

                case Key.ControlLeft: key = Key.ControlRight; break;

                case Key.ControlRight: key = Key.ControlLeft; break;

                case Key.ShiftLeft: is_valid = false; break;
                }
            }

            if (extended1)
            {
                switch (key)
                {
                case Key.ControlLeft: key = Key.Pause; break;
                }
            }

            return(key);
        }
Exemple #5
0
 internal static short GetKeyState(VirtualKeys vKey);
Exemple #6
0
        public static Key TranslateKey(uint scancode, VirtualKeys vkey, bool extended, out bool is_valid)
        {
            //is_valid = true;


            switch (vkey)
            {
            case VirtualKeys.VK_CONTROL:
                vkey = (extended ? VirtualKeys.VK_RCONTROL : VirtualKeys.VK_LCONTROL);
                break;

            case VirtualKeys.VK_SHIFT:
                vkey = (VirtualKeys)Functions.MapVirtualKey(scancode, MapVirtualKeyType.ScanCodeToVirtualKeyExtended);
                break;

            case VirtualKeys.VK_MENU:
                vkey = (extended ? VirtualKeys.VK_RMENU : VirtualKeys.VK_LMENU);
                break;
            }
            var key = GetKey(vkey);

            is_valid = (key != Key.Unknown);

            //var virtualKey =
            //    (VirtualKeys)(
            //        Functions.MapVirtualKey((uint)scancode, MapVirtualKeyType.ScanCodeToVirtualKeyExtended)
            //    );


            //if (!extended0)
            //{
            //    switch (key)
            //    {
            //        case Key.Insert: key = Key.Keypad0; break;
            //        case Key.End: key = Key.Keypad1; break;
            //        case Key.Down: key = Key.Keypad2; break;
            //        case Key.PageDown: key = Key.Keypad3; break;
            //        case Key.Left: key = Key.Keypad4; break;
            //        case Key.Right: key = Key.Keypad6; break;
            //        case Key.Home: key = Key.Keypad7; break;
            //        case Key.Up: key = Key.Keypad8; break;
            //        case Key.PageUp: key = Key.Keypad9; break;
            //        case Key.PrintScreen: key = Key.KeypadMultiply; break;
            //        case Key.Delete: key = Key.KeypadDecimal; break;
            //        case Key.NumLock:
            //            if (vkey == VirtualKeys.Invalid)
            //            {
            //                is_valid = false;
            //            }
            //            else if (vkey == VirtualKeys.VK_PAUSE)
            //            {
            //                key = Key.Pause;
            //            }
            //            break;
            //    }
            //}
            //else
            //{
            //    switch (key)
            //    {
            //        case Key.Slash: key = Key.KeypadDivide; break;
            //        case Key.Enter: key = Key.KeypadEnter; break;
            //        case Key.AltLeft: key = Key.AltRight; break;
            //        case Key.AltRight: key = Key.AltLeft; break;
            //        case Key.ControlLeft: key = Key.ControlRight; break;
            //        case Key.ControlRight: key = Key.ControlLeft; break;
            //        case Key.ShiftLeft: is_valid = false; break;
            //    }
            //}

            //if (extended1)
            //{
            //    switch (key)
            //    {
            //        case Key.ControlLeft: key = Key.Pause; break;
            //    }
            //}

            return(key);
        }
Exemple #7
0
        public static Key GetKey(VirtualKeys vkey)
        {
            switch (vkey)
            {
            case VirtualKeys.QS_EVENT: return(Key.Unknown);

            case VirtualKeys.VK_CANCEL: return(Key.Unknown);

            case VirtualKeys.VK_BACK: return(Key.BackSpace);

            case VirtualKeys.VK_CLEAR: return(Key.Unknown);

            case VirtualKeys.VK_RETURN: return(Key.Enter);

            case VirtualKeys.VK_PAUSE: return(Key.Pause);

            case VirtualKeys.VK_CAPITAL: return(Key.CapsLock);

            case VirtualKeys.VK_KANA: return(Key.Unknown);

            case VirtualKeys.VK_JUNJA: return(Key.Unknown);

            case VirtualKeys.VK_FINAL: return(Key.Unknown);

            case VirtualKeys.VK_HANJA: return(Key.Unknown);

            case VirtualKeys.VK_ESCAPE: return(Key.Escape);

            case VirtualKeys.VK_CONVERT: return(Key.Unknown);

            case VirtualKeys.VK_NONCONVERT: return(Key.Unknown);

            case VirtualKeys.VK_ACCEPT: return(Key.Unknown);

            case VirtualKeys.VK_MODECHANGE: return(Key.Unknown);

            case VirtualKeys.VK_SPACE: return(Key.Space);

            case VirtualKeys.VK_PRIOR: return(Key.PageUp);

            case VirtualKeys.VK_NEXT: return(Key.PageDown);

            case VirtualKeys.VK_END: return(Key.End);

            case VirtualKeys.VK_HOME: return(Key.Home);

            case VirtualKeys.VK_LEFT: return(Key.Left);

            case VirtualKeys.VK_UP: return(Key.Up);

            case VirtualKeys.VK_RIGHT: return(Key.Right);

            case VirtualKeys.VK_DOWN: return(Key.Down);

            case VirtualKeys.VK_SELECT: return(Key.Unknown);

            case VirtualKeys.VK_PRINT: return(Key.PrintScreen);

            case VirtualKeys.VK_EXECUTE: return(Key.Unknown);

            case VirtualKeys.VK_SNAPSHOT: return(Key.PrintScreen);

            case VirtualKeys.VK_INSERT: return(Key.Insert);

            case VirtualKeys.VK_DELETE: return(Key.Delete);

            case VirtualKeys.VK_HELP: return(Key.Unknown);

            case VirtualKeys.VK_0: return(Key.Number0);

            case VirtualKeys.VK_1: return(Key.Number1);

            case VirtualKeys.VK_2: return(Key.Number2);

            case VirtualKeys.VK_3: return(Key.Number3);

            case VirtualKeys.VK_4: return(Key.Number4);

            case VirtualKeys.VK_5: return(Key.Number5);

            case VirtualKeys.VK_6: return(Key.Number6);

            case VirtualKeys.VK_7: return(Key.Number7);

            case VirtualKeys.VK_8: return(Key.Number8);

            case VirtualKeys.VK_9: return(Key.Number9);

            case VirtualKeys.VK_A: return(Key.A);

            case VirtualKeys.VK_B: return(Key.B);

            case VirtualKeys.VK_C: return(Key.C);

            case VirtualKeys.VK_D: return(Key.D);

            case VirtualKeys.VK_E: return(Key.E);

            case VirtualKeys.VK_F: return(Key.F);

            case VirtualKeys.VK_G: return(Key.G);

            case VirtualKeys.VK_H: return(Key.H);

            case VirtualKeys.VK_I: return(Key.I);

            case VirtualKeys.VK_J: return(Key.J);

            case VirtualKeys.VK_K: return(Key.K);

            case VirtualKeys.VK_L: return(Key.L);

            case VirtualKeys.VK_M: return(Key.M);

            case VirtualKeys.VK_N: return(Key.N);

            case VirtualKeys.VK_O: return(Key.O);

            case VirtualKeys.VK_P: return(Key.P);

            case VirtualKeys.VK_Q: return(Key.Q);

            case VirtualKeys.VK_R: return(Key.R);

            case VirtualKeys.VK_S: return(Key.S);

            case VirtualKeys.VK_T: return(Key.T);

            case VirtualKeys.VK_U: return(Key.U);

            case VirtualKeys.VK_V: return(Key.V);

            case VirtualKeys.VK_W: return(Key.W);

            case VirtualKeys.VK_X: return(Key.X);

            case VirtualKeys.VK_Y: return(Key.Y);

            case VirtualKeys.VK_Z: return(Key.Z);

            case VirtualKeys.VK_LWIN: return(Key.WinLeft);

            case VirtualKeys.VK_RWIN: return(Key.WinRight);

            case VirtualKeys.VK_APPS: return(Key.Menu);

            case VirtualKeys.VK_POWER: return(Key.Unknown);

            case VirtualKeys.VK_SLEEP: return(Key.Sleep);

            case VirtualKeys.VK_NUMPAD0: return(Key.Keypad0);

            case VirtualKeys.VK_NUMPAD1: return(Key.Keypad1);

            case VirtualKeys.VK_NUMPAD2: return(Key.Keypad2);

            case VirtualKeys.VK_NUMPAD3: return(Key.Keypad3);

            case VirtualKeys.VK_NUMPAD4: return(Key.Keypad4);

            case VirtualKeys.VK_NUMPAD5: return(Key.Keypad5);

            case VirtualKeys.VK_NUMPAD6: return(Key.Keypad6);

            case VirtualKeys.VK_NUMPAD7: return(Key.Keypad7);

            case VirtualKeys.VK_NUMPAD8: return(Key.Keypad8);

            case VirtualKeys.VK_NUMPAD9: return(Key.Keypad9);

            case VirtualKeys.VK_MULTIPLY: return(Key.KeypadMultiply);

            case VirtualKeys.VK_ADD: return(Key.KeypadAdd);

            case VirtualKeys.VK_SEPARATOR: return(Key.Unknown);

            case VirtualKeys.VK_SUBTRACT: return(Key.KeypadSubtract);

            case VirtualKeys.VK_DECIMAL: return(Key.KeypadDecimal);

            case VirtualKeys.VK_DIVIDE: return(Key.KeypadDivide);

            case VirtualKeys.VK_F1: return(Key.F1);

            case VirtualKeys.VK_F2: return(Key.F2);

            case VirtualKeys.VK_F3: return(Key.F3);

            case VirtualKeys.VK_F4: return(Key.F4);

            case VirtualKeys.VK_F5: return(Key.F5);

            case VirtualKeys.VK_F6: return(Key.F6);

            case VirtualKeys.VK_F7: return(Key.F7);

            case VirtualKeys.VK_F8: return(Key.F8);

            case VirtualKeys.VK_F9: return(Key.F9);

            case VirtualKeys.VK_F10: return(Key.F10);

            case VirtualKeys.VK_F11: return(Key.F11);

            case VirtualKeys.VK_F12: return(Key.F12);

            case VirtualKeys.VK_F13: return(Key.F13);

            case VirtualKeys.VK_F14: return(Key.F14);

            case VirtualKeys.VK_F15: return(Key.F15);

            case VirtualKeys.VK_F16: return(Key.F16);

            case VirtualKeys.VK_F17: return(Key.F17);

            case VirtualKeys.VK_F18: return(Key.F18);

            case VirtualKeys.VK_F19: return(Key.F19);

            case VirtualKeys.VK_F20: return(Key.F20);

            case VirtualKeys.VK_F21: return(Key.F21);

            case VirtualKeys.VK_F22: return(Key.F22);

            case VirtualKeys.VK_F23: return(Key.F23);

            case VirtualKeys.VK_F24: return(Key.F24);

            case VirtualKeys.VK_NUMLOCK: return(Key.NumLock);

            case VirtualKeys.VK_SCROLL: return(Key.ScrollLock);

            case VirtualKeys.VK_RSHIFT: return(Key.ShiftRight);

            case VirtualKeys.VK_BROWSER_BACK: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_FORWARD: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_REFRESH: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_STOP: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_SEARCH: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_FAVORITES: return(Key.Unknown);

            case VirtualKeys.VK_BROWSER_HOME: return(Key.Unknown);

            case VirtualKeys.VK_VOLUME_MUTE: return(Key.Unknown);

            case VirtualKeys.VK_VOLUME_DOWN: return(Key.Unknown);

            case VirtualKeys.VK_VOLUME_UP: return(Key.Unknown);

            case VirtualKeys.VK_MEDIA_NEXT_TRACK: return(Key.Unknown);

            case VirtualKeys.VK_MEDIA_PREV_TRACK: return(Key.Unknown);

            case VirtualKeys.VK_MEDIA_STOP: return(Key.Unknown);

            case VirtualKeys.VK_MEDIA_PLAY_PAUSE: return(Key.Unknown);

            case VirtualKeys.VK_LAUNCH_MAIL: return(Key.Unknown);

            case VirtualKeys.VK_LAUNCH_MEDIA_SELECT: return(Key.Unknown);

            case VirtualKeys.VK_LAUNCH_APP1: return(Key.Unknown);

            case VirtualKeys.VK_LAUNCH_APP2: return(Key.Unknown);

            case VirtualKeys.VK_PROCESSKEY: return(Key.Unknown);

            case VirtualKeys.VK_PACKET: return(Key.Unknown);

            case VirtualKeys.VK_ATTN: return(Key.Unknown);

            case VirtualKeys.VK_CRSEL: return(Key.Unknown);

            case VirtualKeys.VK_EXSEL: return(Key.Unknown);

            case VirtualKeys.VK_EREOF: return(Key.Unknown);

            case VirtualKeys.VK_PLAY: return(Key.Unknown);

            case VirtualKeys.VK_ZOOM: return(Key.Unknown);

            case VirtualKeys.VK_NONAME: return(Key.Unknown);

            case VirtualKeys.VK_PA1: return(Key.Unknown);

            case VirtualKeys.VK_OEM_CLEAR: return(Key.Clear);

            case VirtualKeys.VK_TAB: return(Key.Tab);

            case VirtualKeys.VK_SHIFT: return(Key.ShiftLeft);

            case VirtualKeys.VK_CONTROL: return(Key.ControlLeft);

            case VirtualKeys.VK_MENU: return(Key.AltLeft);

            case VirtualKeys.WS_EX_NOACTIVATE: return(Key.Unknown);

            case VirtualKeys.VK_LSHIFT: return(Key.ShiftLeft);

            case VirtualKeys.VK_RMENU: return(Key.AltRight);

            case VirtualKeys.VK_LMENU: return(Key.AltLeft);

            case VirtualKeys.VK_LCONTROL: return(Key.ControlLeft);

            case VirtualKeys.VK_RCONTROL: return(Key.ControlRight);

            case VirtualKeys.VK_LBUTTON: return(Key.Unknown);

            case VirtualKeys.VK_RBUTTON: return(Key.Unknown);

            case VirtualKeys.VK_MBUTTON: return(Key.Unknown);

            case VirtualKeys.VK_XBUTTON1: return(Key.Unknown);

            case VirtualKeys.VK_XBUTTON2: return(Key.Unknown);

            case VirtualKeys.VK_OEM_1: return(Key.Unknown);

            case VirtualKeys.VK_OEM_PLUS: return(Key.Plus);

            case VirtualKeys.VK_OEM_COMMA: return(Key.Comma);

            case VirtualKeys.VK_OEM_MINUS: return(Key.Minus);

            case VirtualKeys.VK_OEM_PERIOD: return(Key.Period);

            case VirtualKeys.VK_OEM_2: return(Key.Unknown);

            case VirtualKeys.VK_OEM_3: return(Key.Unknown);

            case VirtualKeys.VK_C1: return(Key.Unknown);

            case VirtualKeys.VK_C2: return(Key.Unknown);

            case VirtualKeys.VK_OEM_4: return(Key.Unknown);

            case VirtualKeys.VK_OEM_5: return(Key.Unknown);

            case VirtualKeys.VK_OEM_6: return(Key.Unknown);

            case VirtualKeys.VK_OEM_7: return(Key.Unknown);

            case VirtualKeys.VK_OEM_8: return(Key.Unknown);

            case VirtualKeys.VK_OEM_AX: return(Key.Unknown);

            case VirtualKeys.VK_OEM_102: return(Key.Unknown);

            case VirtualKeys.VK_OEM_RESET: return(Key.Unknown);

            case VirtualKeys.VK_OEM_JUMP: return(Key.Unknown);

            case VirtualKeys.VK_OEM_PA1: return(Key.Unknown);

            case VirtualKeys.VK_OEM_PA2: return(Key.Unknown);

            case VirtualKeys.VK_OEM_PA3: return(Key.Unknown);

            case VirtualKeys.VK_OEM_WSCTRL: return(Key.Unknown);

            case VirtualKeys.VK_OEM_CUSEL: return(Key.Unknown);

            case VirtualKeys.VK_OEM_ATTN: return(Key.Unknown);

            case VirtualKeys.VK_OEM_FINISH: return(Key.Unknown);

            case VirtualKeys.VK_OEM_COPY: return(Key.Unknown);

            case VirtualKeys.VK_OEM_AUTO: return(Key.Unknown);

            case VirtualKeys.VK_OEM_ENLW: return(Key.Unknown);

            case VirtualKeys.VK_OEM_BACKTAB: return(Key.Unknown);

            case VirtualKeys.Invalid: return(Key.Unknown);

            default: return(Key.Unknown);
            }
        }
Exemple #8
0
 public bool TryGetMappedKey(VirtualKeys vKey, out Key key)
 {
     return(TryGetValue((int)vKey, out key));
 }
Exemple #9
0
 void AddKey(VirtualKeys vKey, Key key)
 {
     Add((int)vKey, key);
 }
        IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
        {
            switch (message)
            {
                #region Size / Move / Style events

            case WindowMessage.ACTIVATE:
                // See http://msdn.microsoft.com/en-us/library/ms646274(VS.85).aspx (WM_ACTIVATE notification):
                // wParam: The low-order word specifies whether the window is being activated or deactivated.
                bool new_focused_state = Focused;
                if (IntPtr.Size == 4)
                {
                    focused = (wParam.ToInt32() & 0xFFFF) != 0;
                }
                else
                {
                    focused = (wParam.ToInt64() & 0xFFFF) != 0;
                }

                if (new_focused_state != Focused)
                {
                    FocusedChanged(this, EventArgs.Empty);
                }
                break;

            case WindowMessage.ENTERMENULOOP:
            case WindowMessage.ENTERSIZEMOVE:
                // Entering the modal size/move loop: we don't want rendering to
                // stop during this time, so we register a timer callback to continue
                // processing from time to time.
                is_in_modal_loop = true;
                StartTimer(handle);

                if (!CursorVisible)
                {
                    UngrabCursor();
                }
                break;

            case WindowMessage.EXITMENULOOP:
            case WindowMessage.EXITSIZEMOVE:
                // Exiting from Modal size/move loop: the timer callback is no longer
                // necessary.
                is_in_modal_loop = false;
                StopTimer(handle);

                // Ensure cursor remains grabbed
                if (!CursorVisible)
                {
                    GrabCursor();
                }
                break;

            case WindowMessage.ERASEBKGND:
                return(new IntPtr(1));

            case WindowMessage.WINDOWPOSCHANGED:
                unsafe
                {
                    WindowPosition *pos = (WindowPosition *)lParam;
                    if (window != null && pos->hwnd == window.Handle)
                    {
                        Point new_location = new Point(pos->x, pos->y);
                        if (Location != new_location)
                        {
                            bounds.Location = new_location;
                            Move(this, EventArgs.Empty);
                        }

                        Size new_size = new Size(pos->cx, pos->cy);
                        if (Size != new_size)
                        {
                            bounds.Width  = pos->cx;
                            bounds.Height = pos->cy;

                            Win32Rectangle rect;
                            Functions.GetClientRect(handle, out rect);
                            client_rectangle = rect.ToRectangle();

                            Functions.SetWindowPos(child_window.Handle, IntPtr.Zero, 0, 0, ClientRectangle.Width, ClientRectangle.Height,
                                                   SetWindowPosFlags.NOZORDER | SetWindowPosFlags.NOOWNERZORDER |
                                                   SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING);

                            if (suppress_resize <= 0)
                            {
                                Resize(this, EventArgs.Empty);
                            }
                        }

                        if (!is_in_modal_loop)
                        {
                            // If we are in a modal resize/move loop, cursor grabbing is
                            // handled inside [ENTER|EXIT]SIZEMOVE case above.
                            // If not, then we have to handle cursor grabbing here.
                            if (!CursorVisible)
                            {
                                GrabCursor();
                            }
                        }
                    }
                }
                break;

            case WindowMessage.STYLECHANGED:
                unsafe
                {
                    if (wParam.ToInt64() == (long)GWL.STYLE)
                    {
                        WindowStyle style = ((StyleStruct *)lParam)->New;
                        if ((style & WindowStyle.Popup) != 0)
                        {
                            windowBorder = WindowBorder.Hidden;
                        }
                        else if ((style & WindowStyle.ThickFrame) != 0)
                        {
                            windowBorder = WindowBorder.Resizable;
                        }
                        else if ((style & ~(WindowStyle.ThickFrame | WindowStyle.MaximizeBox)) != 0)
                        {
                            windowBorder = WindowBorder.Fixed;
                        }
                    }
                }

                // Ensure cursor remains grabbed
                if (!CursorVisible)
                {
                    GrabCursor();
                }

                break;

            case WindowMessage.SIZE:
                SizeMessage state     = (SizeMessage)wParam.ToInt64();
                WindowState new_state = windowState;
                switch (state)
                {
                case SizeMessage.RESTORED: new_state = borderless_maximized_window_state ?
                                                       WindowState.Maximized : WindowState.Normal; break;

                case SizeMessage.MINIMIZED: new_state = WindowState.Minimized; break;

                case SizeMessage.MAXIMIZED: new_state = WindowBorder == WindowBorder.Hidden ?
                                                        WindowState.Fullscreen : WindowState.Maximized;
                    break;
                }

                if (new_state != windowState)
                {
                    windowState = new_state;
                    WindowStateChanged(this, EventArgs.Empty);

                    // Ensure cursor remains grabbed
                    if (!CursorVisible)
                    {
                        GrabCursor();
                    }
                }

                break;

                #endregion

                #region Input events

            case WindowMessage.CHAR:
                if (IntPtr.Size == 4)
                {
                    key_press.KeyChar = (char)wParam.ToInt32();
                }
                else
                {
                    key_press.KeyChar = (char)wParam.ToInt64();
                }

                KeyPress(this, key_press);
                break;

            case WindowMessage.MOUSEMOVE:
                Point point = new Point(
                    (short)((uint)lParam.ToInt32() & 0x0000FFFF),
                    (short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));
                mouse.Position = point;

                if (mouse_outside_window)
                {
                    // Once we receive a mouse move event, it means that the mouse has
                    // re-entered the window.
                    mouse_outside_window = false;
                    EnableMouseTracking();

                    MouseEnter(this, EventArgs.Empty);
                }
                break;

            case WindowMessage.MOUSELEAVE:
                mouse_outside_window = true;
                // Mouse tracking is disabled automatically by the OS

                MouseLeave(this, EventArgs.Empty);
                break;

            case WindowMessage.MOUSEWHEEL:
                // This is due to inconsistent behavior of the WParam value on 64bit arch, whese
                // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
                mouse.WheelPrecise += ((long)wParam << 32 >> 48) / 120.0f;
                break;

            case WindowMessage.LBUTTONDOWN:
                Functions.SetCapture(window.Handle);
                mouse[MouseButton.Left] = true;
                break;

            case WindowMessage.MBUTTONDOWN:
                Functions.SetCapture(window.Handle);
                mouse[MouseButton.Middle] = true;
                break;

            case WindowMessage.RBUTTONDOWN:
                Functions.SetCapture(window.Handle);
                mouse[MouseButton.Right] = true;
                break;

            case WindowMessage.XBUTTONDOWN:
                Functions.SetCapture(window.Handle);
                mouse[((wParam.ToInt32() & 0xFFFF0000) >> 16) !=
                      (int)MouseKeys.XButton1 ? MouseButton.Button1 : MouseButton.Button2] = true;
                break;

            case WindowMessage.LBUTTONUP:
                Functions.ReleaseCapture();
                mouse[MouseButton.Left] = false;
                break;

            case WindowMessage.MBUTTONUP:
                Functions.ReleaseCapture();
                mouse[MouseButton.Middle] = false;
                break;

            case WindowMessage.RBUTTONUP:
                Functions.ReleaseCapture();
                mouse[MouseButton.Right] = false;
                break;

            case WindowMessage.XBUTTONUP:
                Functions.ReleaseCapture();
                mouse[((wParam.ToInt32() & 0xFFFF0000) >> 16) !=
                      (int)MouseKeys.XButton1 ? MouseButton.Button1 : MouseButton.Button2] = false;
                break;

            // Keyboard events:
            case WindowMessage.KEYDOWN:
            case WindowMessage.KEYUP:
            case WindowMessage.SYSKEYDOWN:
            case WindowMessage.SYSKEYUP:
                bool pressed =
                    message == WindowMessage.KEYDOWN ||
                    message == WindowMessage.SYSKEYDOWN;

                // Shift/Control/Alt behave strangely when e.g. ShiftRight is held down and ShiftLeft is pressed
                // and released. It looks like neither key is released in this case, or that the wrong key is
                // released in the case of Control and Alt.
                // To combat this, we are going to release both keys when either is released. Hacky, but should work.
                // Win95 does not distinguish left/right key constants (GetAsyncKeyState returns 0).
                // In this case, both keys will be reported as pressed.

                bool        extended = (lParam.ToInt64() & ExtendedBit) != 0;
                short       scancode = (short)((lParam.ToInt64() >> 16) & 0xFF);
                VirtualKeys vkey     = (VirtualKeys)wParam;
                bool        is_valid;
                Key         key = KeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);

                if (is_valid)
                {
                    keyboard.SetKey(key, (byte)scancode, pressed);
                }

                return(IntPtr.Zero);

            case WindowMessage.SYSCHAR:
                return(IntPtr.Zero);

            case WindowMessage.KILLFOCUS:
                keyboard.ClearKeys();
                break;

                #endregion

                #region Creation / Destruction events

            case WindowMessage.CREATE:
                CreateStruct cs = (CreateStruct)Marshal.PtrToStructure(lParam, typeof(CreateStruct));
                if (cs.hwndParent == IntPtr.Zero)
                {
                    bounds.X      = cs.x;
                    bounds.Y      = cs.y;
                    bounds.Width  = cs.cx;
                    bounds.Height = cs.cy;

                    Win32Rectangle rect;
                    Functions.GetClientRect(handle, out rect);
                    client_rectangle = rect.ToRectangle();

                    invisible_since_creation = true;
                }
                break;

            case WindowMessage.CLOSE:
                System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs();

                Closing(this, e);

                if (!e.Cancel)
                {
                    DestroyWindow();
                    break;
                }

                return(IntPtr.Zero);

            case WindowMessage.DESTROY:
                exists = false;

                Functions.UnregisterClass(ClassName, Instance);
                window.Dispose();
                child_window.Dispose();

                Closed(this, EventArgs.Empty);

                break;

                #endregion
            }

            return(Functions.DefWindowProc(handle, message, wParam, lParam));
        }