1
\$\begingroup\$

How can I improve it?

#include <iostream>
#include <deque>
#include <string>
#include <stdexcept>

#include <Windows.h>

namespace ms
{
    typedef signed   char Int8;
    typedef unsigned char Uint8;

    typedef signed   short Int16;
    typedef unsigned short Uint16;

    typedef signed   int Int32;
    typedef unsigned int Uint32;

    typedef signed   __int64 Int64;
    typedef unsigned __int64 Uint64;

    struct NonCopyable
    {
        NonCopyable() = default;
        virtual ~NonCopyable() = default;

        NonCopyable(const NonCopyable &) = delete;
        NonCopyable(const NonCopyable &&) = delete;
        NonCopyable& operator = (const NonCopyable&) = delete;
    };

    template <typename T>
    struct Vector2
    {
        Vector2();

        Vector2(T X, T Y);

        T x;
        T y;
    };

    template <typename T>
    bool operator !=(const Vector2<T>& V1, const Vector2<T>& V2);

    template <typename T>
    Vector2<T>::Vector2() : x(), y(){   }

    template <typename T>
    Vector2<T>::Vector2(T X, T Y) : x(X), y(Y){ }

    template <typename T>
    Vector2<T> operator -(const Vector2<T>& V)
    {
        return Vector2<T>(-V.x, -V.y);
    }

    template <typename T>
    Vector2<T>& operator +=(Vector2<T>& V1, const Vector2<T>& V2)
    {
        V1.x += V2.x;
        V1.y += V2.y;

        return V1;
    }

    template <typename T>
    Vector2<T>& operator -=(Vector2<T>& V1, const Vector2<T>& V2)
    {
        V1.x -= V2.x;
        V1.y -= V2.y;

        return V1;
    }

    template <typename T>
    Vector2<T> operator +(const Vector2<T>& V1, const Vector2<T>& V2)
    {
        return Vector2<T>(V1.x + V2.x, V1.y + V2.y);
    }

    template <typename T>
    Vector2<T> operator -(const Vector2<T>& V1, const Vector2<T>& V2)
    {
        return Vector2<T>(V1.x - V2.x, V1.y - V2.y);
    }

    template <typename T>
    Vector2<T> operator *(const Vector2<T>& V, T X)
    {
        return Vector2<T>(V.x * X, V.y * X);
    }

    template <typename T>
    Vector2<T> operator *(T X, const Vector2<T>& V)
    {
        return Vector2<T>(V.x * X, V.y * X);
    }

    template <typename T>
    Vector2<T>& operator *=(Vector2<T>& V, T X)
    {
        V.x *= X;
        V.y *= X;

        return V;
    }

    template <typename T>
    Vector2<T> operator /(const Vector2<T>& V, T X)
    {
        return Vector2<T>(V.x / X, V.y / X);
    }

    template <typename T>
    Vector2<T>& operator /=(Vector2<T>& V, T X)
    {
        V.x /= X;
        V.y /= X;

        return V;
    }

    template <typename T>
    bool operator ==(const Vector2<T>& V1, const Vector2<T>& V2)
    {
        return (V1.x == V2.x) && (V1.y == V2.y);
    }

    template <typename T>
    bool operator !=(const Vector2<T>& V1, const Vector2<T>& V2)
    {
        return (V1.x != V2.x) || (V1.y != V2.y);
    }

    typedef Vector2<int>   Vector2i;
    typedef Vector2<float> Vector2f;
    typedef Vector2<Uint32> Vector2u;

    struct Mouse
    {
        enum Button
        {
            Left,       
            Right,      
            Middle,     
            XButton1,   
            XButton2,   

            ButtonCount 
        };

        static bool isButtonPressed(Button button);

        static Vector2i getPosition();
        static void setPosition(const Vector2i& position);
    };


    struct Keyboard
    {
        enum Key
        {
            Unknown = -1,
            A = 0,        
            B,            
            C,            
            D,            
            E,           
            F,            
            G,            
            H,            
            I,            
            J,            
            K,         
            L,           
            M,            
            N,            
            O,           
            P,           
            Q,           
            R,          
            S,           
            T,            
            U,            
            V,            
            W,           
            X,           
            Y,           
            Z,            
            Num0,         
            Num1,         
            Num2,         
            Num3,         
            Num4,        
            Num5,         
            Num6,        
            Num7,         
            Num8,         
            Num9,         
            Escape,       
            LControl,     
            LShift,       
            LAlt,        
            LSystem,      
            RControl,     
            RShift,      
            RAlt,         
            RSystem,      
            Menu,         
            LBracket,     
            RBracket,     
            SemiColon,    
            Comma,        
            Period,       
            Quote,        
            Slash,        
            BackSlash,    
            Tilde,        
            Equal,        
            Dash,         
            Space,       
            Return,       
            BackSpace,    
            Tab,         
            PageUp,      
            PageDown,    
            End,          
            Home,         
            Insert,       
            Delete,       
            Add,         
            Subtract,     
            Multiply,    
            Divide,       
            Left,        
            Right,        
            Up,        
            Down,       
            Numpad0,     
            Numpad1,      
            Numpad2,     
            Numpad3,     
            Numpad4,    
            Numpad5,    
            Numpad6,    
            Numpad7,      
            Numpad8,     
            Numpad9,     
            F1,         
            F2,           
            F3,         
            F4,          
            F5,          
            F6,           
            F7,           
            F8,        
            F9,           
            F10,         
            F11,         
            F12,          
            F13,          
            F14,          
            F15,          
            Pause,        

            KeyCount      
        };

        static bool isKeyPressed(Key key);
    };

    namespace priv
    {

        struct InputImpl : NonCopyable
        {
            static bool isKeyPressed(Keyboard::Key key);

            static bool isMouseButtonPressed(Mouse::Button button);

            static Vector2i getMousePosition();
            static void setMousePosition(const Vector2i& position);

        };

        bool InputImpl::isKeyPressed(Keyboard::Key key)
        {
            int vkey = 0;
            switch (key)
            {
            default:                   vkey = 0;             break;
            case Keyboard::A:          vkey = 'A';           break;
            case Keyboard::B:          vkey = 'B';           break;
            case Keyboard::C:          vkey = 'C';           break;
            case Keyboard::D:          vkey = 'D';           break;
            case Keyboard::E:          vkey = 'E';           break;
            case Keyboard::F:          vkey = 'F';           break;
            case Keyboard::G:          vkey = 'G';           break;
            case Keyboard::H:          vkey = 'H';           break;
            case Keyboard::I:          vkey = 'I';           break;
            case Keyboard::J:          vkey = 'J';           break;
            case Keyboard::K:          vkey = 'K';           break;
            case Keyboard::L:          vkey = 'L';           break;
            case Keyboard::M:          vkey = 'M';           break;
            case Keyboard::N:          vkey = 'N';           break;
            case Keyboard::O:          vkey = 'O';           break;
            case Keyboard::P:          vkey = 'P';           break;
            case Keyboard::Q:          vkey = 'Q';           break;
            case Keyboard::R:          vkey = 'R';           break;
            case Keyboard::S:          vkey = 'S';           break;
            case Keyboard::T:          vkey = 'T';           break;
            case Keyboard::U:          vkey = 'U';           break;
            case Keyboard::V:          vkey = 'V';           break;
            case Keyboard::W:          vkey = 'W';           break;
            case Keyboard::X:          vkey = 'X';           break;
            case Keyboard::Y:          vkey = 'Y';           break;
            case Keyboard::Z:          vkey = 'Z';           break;
            case Keyboard::Num0:       vkey = '0';           break;
            case Keyboard::Num1:       vkey = '1';           break;
            case Keyboard::Num2:       vkey = '2';           break;
            case Keyboard::Num3:       vkey = '3';           break;
            case Keyboard::Num4:       vkey = '4';           break;
            case Keyboard::Num5:       vkey = '5';           break;
            case Keyboard::Num6:       vkey = '6';           break;
            case Keyboard::Num7:       vkey = '7';           break;
            case Keyboard::Num8:       vkey = '8';           break;
            case Keyboard::Num9:       vkey = '9';           break;
            case Keyboard::Escape:     vkey = VK_ESCAPE;     break;
            case Keyboard::LControl:   vkey = VK_LCONTROL;   break;
            case Keyboard::LShift:     vkey = VK_LSHIFT;     break;
            case Keyboard::LAlt:       vkey = VK_LMENU;      break;
            case Keyboard::LSystem:    vkey = VK_LWIN;       break;
            case Keyboard::RControl:   vkey = VK_RCONTROL;   break;
            case Keyboard::RShift:     vkey = VK_RSHIFT;     break;
            case Keyboard::RAlt:       vkey = VK_RMENU;      break;
            case Keyboard::RSystem:    vkey = VK_RWIN;       break;
            case Keyboard::Menu:       vkey = VK_APPS;       break;
            case Keyboard::LBracket:   vkey = VK_OEM_4;      break;
            case Keyboard::RBracket:   vkey = VK_OEM_6;      break;
            case Keyboard::SemiColon:  vkey = VK_OEM_1;      break;
            case Keyboard::Comma:      vkey = VK_OEM_COMMA;  break;
            case Keyboard::Period:     vkey = VK_OEM_PERIOD; break;
            case Keyboard::Quote:      vkey = VK_OEM_7;      break;
            case Keyboard::Slash:      vkey = VK_OEM_2;      break;
            case Keyboard::BackSlash:  vkey = VK_OEM_5;      break;
            case Keyboard::Tilde:      vkey = VK_OEM_3;      break;
            case Keyboard::Equal:      vkey = VK_OEM_PLUS;   break;
            case Keyboard::Dash:       vkey = VK_OEM_MINUS;  break;
            case Keyboard::Space:      vkey = VK_SPACE;      break;
            case Keyboard::Return:     vkey = VK_RETURN;     break;
            case Keyboard::BackSpace:  vkey = VK_BACK;       break;
            case Keyboard::Tab:        vkey = VK_TAB;        break;
            case Keyboard::PageUp:     vkey = VK_PRIOR;      break;
            case Keyboard::PageDown:   vkey = VK_NEXT;       break;
            case Keyboard::End:        vkey = VK_END;        break;
            case Keyboard::Home:       vkey = VK_HOME;       break;
            case Keyboard::Insert:     vkey = VK_INSERT;     break;
            case Keyboard::Delete:     vkey = VK_DELETE;     break;
            case Keyboard::Add:        vkey = VK_ADD;        break;
            case Keyboard::Subtract:   vkey = VK_SUBTRACT;   break;
            case Keyboard::Multiply:   vkey = VK_MULTIPLY;   break;
            case Keyboard::Divide:     vkey = VK_DIVIDE;     break;
            case Keyboard::Left:       vkey = VK_LEFT;       break;
            case Keyboard::Right:      vkey = VK_RIGHT;      break;
            case Keyboard::Up:         vkey = VK_UP;         break;
            case Keyboard::Down:       vkey = VK_DOWN;       break;
            case Keyboard::Numpad0:    vkey = VK_NUMPAD0;    break;
            case Keyboard::Numpad1:    vkey = VK_NUMPAD1;    break;
            case Keyboard::Numpad2:    vkey = VK_NUMPAD2;    break;
            case Keyboard::Numpad3:    vkey = VK_NUMPAD3;    break;
            case Keyboard::Numpad4:    vkey = VK_NUMPAD4;    break;
            case Keyboard::Numpad5:    vkey = VK_NUMPAD5;    break;
            case Keyboard::Numpad6:    vkey = VK_NUMPAD6;    break;
            case Keyboard::Numpad7:    vkey = VK_NUMPAD7;    break;
            case Keyboard::Numpad8:    vkey = VK_NUMPAD8;    break;
            case Keyboard::Numpad9:    vkey = VK_NUMPAD9;    break;
            case Keyboard::F1:         vkey = VK_F1;         break;
            case Keyboard::F2:         vkey = VK_F2;         break;
            case Keyboard::F3:         vkey = VK_F3;         break;
            case Keyboard::F4:         vkey = VK_F4;         break;
            case Keyboard::F5:         vkey = VK_F5;         break;
            case Keyboard::F6:         vkey = VK_F6;         break;
            case Keyboard::F7:         vkey = VK_F7;         break;
            case Keyboard::F8:         vkey = VK_F8;         break;
            case Keyboard::F9:         vkey = VK_F9;         break;
            case Keyboard::F10:        vkey = VK_F10;        break;
            case Keyboard::F11:        vkey = VK_F11;        break;
            case Keyboard::F12:        vkey = VK_F12;        break;
            case Keyboard::F13:        vkey = VK_F13;        break;
            case Keyboard::F14:        vkey = VK_F14;        break;
            case Keyboard::F15:        vkey = VK_F15;        break;
            case Keyboard::Pause:      vkey = VK_PAUSE;      break;
            }

            return (GetAsyncKeyState(vkey) & 0x8000) != 0;
        }

        bool InputImpl::isMouseButtonPressed(Mouse::Button button)
        {
            int vkey = 0;
            switch (button)
            {
            case Mouse::Left:     vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON; break;
            case Mouse::Right:    vkey = GetSystemMetrics(SM_SWAPBUTTON) ? VK_LBUTTON : VK_RBUTTON; break;
            case Mouse::Middle:   vkey = VK_MBUTTON;  break;
            case Mouse::XButton1: vkey = VK_XBUTTON1; break;
            case Mouse::XButton2: vkey = VK_XBUTTON2; break;
            default:              vkey = 0;           break;
            }

            return (GetAsyncKeyState(vkey) & 0x8000) != 0;
        }

        ////////////////////////////////////////////////////////////
        Vector2i InputImpl::getMousePosition()
        {
            HWND handle = GetConsoleWindow();
            if (handle)
            {
                COORD tempfontsize = { 0, 0 };
                CONSOLE_FONT_INFOEX cfix = { 0 };
                cfix.cbSize = sizeof(CONSOLE_FONT_INFOEX);
                if (GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfix))
                {
                    tempfontsize = GetConsoleFontSize(GetStdHandle(STD_OUTPUT_HANDLE), cfix.nFont);
                }

                POINT pos = { 0, 0 };
                if (!GetCursorPos(&pos) && ScreenToClient(GetConsoleWindow(), &pos))
                {
                    throw "failed to GetCursorPos(&pos)";
                }
                Vector2i delta = { 0, 0 };
                ScreenToClient(GetConsoleWindow(), &pos);
                delta.x = pos.x / tempfontsize.X;
                delta.y = pos.y / tempfontsize.Y;
                return delta;
            }
            else
            {
                return Vector2i();
            }
        }

        void InputImpl::setMousePosition(const Vector2i& position)
        {
            HWND handle = GetConsoleWindow();
            if (handle)
            {
                POINT point = { position.x, position.y };
                ClientToScreen(handle, &point);
                SetCursorPos(point.x, point.y);
            }
        }

    } // namespace priv

    bool Keyboard::isKeyPressed(Key key)
    {
        return priv::InputImpl::isKeyPressed(key);
    }

    bool Mouse::isButtonPressed(Button button)
    {
        return priv::InputImpl::isMouseButtonPressed(button);
    }

    Vector2i Mouse::getPosition()
    {
        return priv::InputImpl::getMousePosition();
    }

    void Mouse::setPosition(const Vector2i& position)
    {
        priv::InputImpl::setMousePosition(position);
    }

    struct Event : NonCopyable
    {
        struct SizeEvent
        {
            unsigned int width;  
            unsigned int height; 
        };

        struct KeyEvent
        {
            Keyboard::Key code;    
            bool          alt;     
            bool          control; 
            bool          shift;   
            bool          system;  
        };

        struct TextEvent
        {
            Uint32 unicode; 
        };

        struct MouseMoveEvent
        {
            int x; 
            int y; 
        };

        struct MouseButtonEvent
        {
            Mouse::Button button; 
            int           x;      
            int           y;      
        };

        struct MouseWheelEvent
        {
            int delta; 
            int x;     
            int y;     
        };

        enum EventType
        {
            Closed,                
            Resized,               
            TextEntered,           
            KeyPressed,            
            KeyReleased,            
            MouseWheelMoved,        
            MouseButtonPressed,     
            MouseButtonReleased,    
            MouseMoved,             
            MouseEntered,           
            MouseLeft,              

            Count                  
        };

        EventType type; 

        union
        {
            SizeEvent            size;    
            KeyEvent             key;       
            TextEvent            text;         
            MouseMoveEvent       mouseMove;    
            MouseButtonEvent     mouseButton;     
            MouseWheelEvent      mouseWheel;      
        };
    };


    namespace priv
    {
        Keyboard::Key KeyConvert(const WORD Key)
        {
            if ((Key >= 'A' && Key <= 'Z') || (Key >= '1' && Key <= '9') || Key == '0')
            {
                return Keyboard::Key(Key);
            }
            if (Key == VK_RETURN) return Keyboard::Return;
            if (Key == VK_ESCAPE) return Keyboard::Escape;
            if (Key == VK_TAB) return Keyboard::Tab;
            return Keyboard::Unknown;
        }
    }

    struct Console : NonCopyable
    {
        Console(short left, short top, short width, short height, const std::string& rStrTitle, short rWidth = 8, short rHeight = 12);

        void setFontSize(short& rWidth, short& rHeight);
        void title(const std::string& rStrTitle);
        void resize(const short width, const short height);

        bool pollEvent(Event& ev);
        POINT getMousePosition() const;

    private:
        COORD getFontSize() const;
        void setPosition(short left, short top);
        std::deque<POINT> mMouseMoveQueue;
    };

    Console::Console(short left, short top, short width, short height, const std::string& rStrTitle, short rWidth, short rHeight)
    {
        if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT))
        {
            throw "failed to SetConsoleMode()";
        }
        setPosition(left, top);
        title(rStrTitle);
        resize(width, height);
        setFontSize(rWidth, rHeight);
    }

    void Console::setFontSize(short& rWidth, short& rHeight)
    {
        CONSOLE_FONT_INFOEX cfix = { 0 };
        COORD cfs1 = { 0, 0 }, cfs2 = { 0, 0 };
        short w = rWidth, h = rHeight;
        cfix.cbSize = sizeof(CONSOLE_FONT_INFOEX);

        rWidth = 0;
        rHeight = 0;

        if (GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfix))
        {
            cfs1 = GetConsoleFontSize(GetStdHandle(STD_OUTPUT_HANDLE), cfix.nFont);

            if (cfs1.X && cfs1.Y)
            {
                cfix.dwFontSize.X = w;
                cfix.dwFontSize.Y = h;

                if (SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfix)
                    && GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfix))
                {
                    cfs2 = GetConsoleFontSize(GetStdHandle(STD_OUTPUT_HANDLE), cfix.nFont);

                    if (cfs2.X && cfs2.Y)
                    {
                        rWidth = cfs2.X;
                        rHeight = cfs2.Y;
                    }
                }
            }
        }
    }

    void Console::setPosition(short left, short top)
    {
        SetWindowPos(GetConsoleWindow(), NULL, left, top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
    }

    COORD Console::getFontSize() const
    {
        COORD tempfontsize = { 0, 0 };

        CONSOLE_FONT_INFOEX cfix = { 0 };

        cfix.cbSize = sizeof(CONSOLE_FONT_INFOEX);

        if (GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfix))
        {
            tempfontsize = GetConsoleFontSize(GetStdHandle(STD_OUTPUT_HANDLE), cfix.nFont);
        }

        return tempfontsize;
    }

    void Console::title(const std::string& rStrTitle) 
    {
        SetConsoleTitleA(rStrTitle.c_str());
    }

    void Console::resize(const short width, const short height)
    {
        long lHeight = 0, lWidth = 0;
        HMONITOR hMonitor = NULL;
        MONITORINFO mi = { 0 };
        CONSOLE_FONT_INFO cfi = { 0 };
        COORD crdfontsize = { 0, 0 };
        COORD coord = { 0, 0 };
        COORD crdbuf = { width, height };

        hMonitor = MonitorFromWindow(GetConsoleWindow(), MONITOR_DEFAULTTONEAREST);
        mi.cbSize = sizeof(MONITORINFO);

        if (!GetMonitorInfo(hMonitor, &mi) || !GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi))
        {
            return;
        }

        crdfontsize = GetConsoleFontSize(GetStdHandle(STD_OUTPUT_HANDLE), cfi.nFont);

        lWidth = width * crdfontsize.X + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXBORDER));
        lHeight = height * crdfontsize.Y + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYBORDER)) + GetSystemMetrics(SM_CYCAPTION);

        if (crdfontsize.X == 0
            || crdfontsize.Y == 0
            || lWidth > (mi.rcWork.right - mi.rcWork.left)
            || lHeight > (mi.rcWork.bottom - mi.rcWork.top)
            || lWidth < GetSystemMetrics(SM_CXMIN)
            || lHeight < GetSystemMetrics(SM_CYMIN))
        {
            return;
        }

        coord.X = static_cast<short>((mi.rcWork.right - mi.rcWork.left) / crdfontsize.X);
        coord.Y = static_cast<short>((mi.rcWork.bottom - mi.rcWork.top) / crdfontsize.Y);

        if (SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord)
            && SetWindowPos(GetConsoleWindow(), NULL, 0, 0, lWidth, lHeight, SWP_NOZORDER | SWP_NOMOVE)
            && SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), crdbuf))
        {
            SetWindowPos(GetConsoleWindow(), NULL, 0, 0, lWidth + 50, lHeight + 50, SWP_NOZORDER | SWP_NOMOVE);
        }

    }

    POINT Console::getMousePosition() const
    {
        POINT pos = { 0, 0 };
        if (!GetCursorPos(&pos) && ScreenToClient(GetConsoleWindow(), &pos))
        {
            throw "failed to GetCursorPos(&pos)";
        }
        POINT delta = { 0, 0 };
        ScreenToClient(GetConsoleWindow(), &pos);
        delta.x = pos.x / getFontSize().X;
        delta.y = pos.y / getFontSize().Y;
        return delta;
    }

    bool Console::pollEvent(Event& ev)
    {
        if (!mMouseMoveQueue.empty())
        {
            ev.type = ms::Event::MouseMoved;
            ev.mouseMove.x = mMouseMoveQueue.front().x;
            ev.mouseMove.y = mMouseMoveQueue.front().y;
            mMouseMoveQueue.pop_front();
            return true;
        }

        INPUT_RECORD record;

        DWORD numEvents;
        if (!GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &numEvents))
        {
            return false;
        }

        while (numEvents > 0)
        {
            DWORD numRead;
            if (!ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &record, 1, &numRead))
            {
                return false;
            }

            if (numRead == 0)
            {
                return false;
            }

            switch (record.EventType)
            {
            case KEY_EVENT:
            {
                Keyboard::Key code = priv::KeyConvert(record.Event.KeyEvent.wVirtualKeyCode);

                if (code == ms::Keyboard::Unknown)
                {
                    break;
                }

                ev.key.code = code;
                ev.type = (record.Event.KeyEvent.bKeyDown) ? ms::Event::KeyPressed : ms::Event::KeyReleased;

                return true;
            }
            case MOUSE_EVENT:
            {
                if (record.Event.MouseEvent.dwEventFlags == 0 || record.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
                {
                    DWORD change = record.Event.MouseEvent.dwButtonState;

                    if (change == FROM_LEFT_1ST_BUTTON_PRESSED)
                    {
                        ev.mouseButton.button = ms::Mouse::Left;
                    }
                    else if (change == RIGHTMOST_BUTTON_PRESSED)
                    {
                        ev.mouseButton.button = ms::Mouse::Right;
                    }
                    else if (change == FROM_LEFT_2ND_BUTTON_PRESSED)
                    {
                        ev.mouseButton.button = ms::Mouse::Middle;
                    }
                    else if (change == FROM_LEFT_3RD_BUTTON_PRESSED)
                    {
                        ev.mouseButton.button = ms::Mouse::XButton1;
                    }
                    else if (change == FROM_LEFT_4TH_BUTTON_PRESSED)
                    {
                        ev.mouseButton.button = ms::Mouse::XButton2;
                    }
                    else
                    {
                        break; //invalid key
                    }

                    ev.type = (change & 0x8000) ? ms::Event::MouseButtonPressed : ms::Event::MouseButtonReleased;
                    return true;
                }
                if (record.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
                {
                    ev.type = ms::Event::MouseWheelMoved;
                    ev.mouseWheel.delta = record.Event.MouseEvent.dwButtonState;
                    return true;
                }
                if (record.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
                {
                    mMouseMoveQueue.push_back(getMousePosition());

                    return true;
                }

            }
            case WINDOW_BUFFER_SIZE_EVENT:
            {
                ev.type = ms::Event::Resized;
                ev.size.width = record.Event.WindowBufferSizeEvent.dwSize.X;
                ev.size.height = record.Event.WindowBufferSizeEvent.dwSize.Y;
                return true;
            }
            case FOCUS_EVENT:
            {
                //should be ignored
                break;
            }
            default:
            {
                //ignored

                break;
            }
            } //switch

            // event was ignored - let's see how many are left.
            if (!GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &numEvents))
            {
                return false;
            }
        }
        return false;
    }
}

int main()
{
    ms::Console window(350, 50, 80, 50, "test console library 0.01", 8, 8);

    bool isRunning = true;
    while (isRunning)
    {
        ms::Event event;
        while (window.pollEvent(event))
        {
            // Window closed or escape key pressed: exit
            if ((event.type == ms::Event::Closed) || ((event.type == ms::Event::KeyPressed) && (event.key.code == ms::Keyboard::Escape)))
            {
                isRunning = false;
            }
            else if (event.type == ms::Event::Resized)
            {
                std::cout << "Resized to " << event.size.width << ", " << event.size.height << std::endl;
            }
            else if (event.type == ms::Event::MouseButtonPressed)
            {
                std::cout << "Mouse button " << event.mouseButton.button << " pressed" << std::endl;
            }
            else if (event.type == ms::Event::MouseButtonReleased)
            {
                std::cout << "Mouse button " << event.mouseButton.button << " released" << std::endl;
            }
            else if (event.type == ms::Event::MouseWheelMoved)
            {
                std::cout << "Mouse wheel moved by " << event.mouseWheel.delta << std::endl;
            }
            else if (event.type == ms::Event::KeyPressed)
            {
                std::cout << "Key " << char(event.key.code) << " pressed" << std::endl;
            }
            else if (event.type == ms::Event::KeyReleased)
            {
                std::cout << "Key " << char(event.key.code) << " released" << std::endl;
            }
            else if (event.type == ms::Event::MouseMoved)
            {
                std::cout << "Mouse moved by " << event.mouseMove.x << ", " << event.mouseMove.y << std::endl;
            }
        }

        if (ms::Keyboard::isKeyPressed(ms::Keyboard::A))
        {
            std::cout << 'A';
        }
        if (ms::Keyboard::isKeyPressed(ms::Keyboard::Left))
        {
            std::cout << " move left ";

        }
        else if (ms::Keyboard::isKeyPressed(ms::Keyboard::Right))
        {
            std::cout << " move right ";
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.