ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 콘솔 입력 - DirectX
    GUI/컨트롤 2009. 1. 18. 03:27
    #include <windows.h>
    #include <windowsx.h>
    #include <dinput.h>

    #define KEYDOWN(State,KeyID)    (State[KeyID] & 0x80)

    char                    c_szClassName[] = "마우스입력" ;

    HINSTANCE                g_hInst ;
    BOOL                    g_bPaused = TRUE ;

    LPDIRECTINPUT            g_lpDirectInput ;

    LPDIRECTINPUTDEVICE        g_lpMouse ;
    LPDIRECTINPUTDEVICE        g_lpKeyboard ;

    char                    g_szText[1024] ;

    int                        X_pos, Y_pos ;
    BOOL                    bLeftButton, bRightButton ;

    #define LEFTBUTTON(State)    (State.rgbButtons[0] & 0x80)
    #define RIGHTBUTTON(State)    (State.rgbButtons[1] & 0x80)

    #define WM_SYNCACQUIRE      (WM_USER)

    BOOL DirectInput_Init (HWND hwnd)
    {
        HRESULT hResult ;

        hResult = DirectInputCreate (g_hInst, DIRECTINPUT_VERSION, &g_lpDirectInput, NULL);
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "DirectInputCreate 에러", "마우스입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpDirectInput->CreateDevice (GUID_SysMouse, &g_lpMouse, NULL) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "CreateDevice 에러", "마우스입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpMouse->SetDataFormat (&c_dfDIMouse) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "SetDataFormat 에러", "마우스입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpMouse->SetCooperativeLevel
                    (hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "SetCooperativeLevel 에러", "마우스입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpDirectInput->CreateDevice (GUID_SysKeyboard, &g_lpKeyboard, NULL) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "CreateDevice 에러", "키보드입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpKeyboard->SetDataFormat (&c_dfDIKeyboard) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "SetDataFormat 에러", "키보드입력", MB_OK) ;
            return FALSE ;
        }

        hResult = g_lpKeyboard->SetCooperativeLevel
                    (hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) ;
        if (hResult != DI_OK)
        {
            MessageBox (hwnd, "SetCooperativeLevel 에러", "키보드입력", MB_OK) ;
            return FALSE ;
        }

        return TRUE ;
    }

    void DirectInput_End (void)
    {
        if (g_lpMouse)
        {
            g_lpMouse->Unacquire () ;
            g_lpMouse->Release () ;
            g_lpMouse = NULL ;
        }

        if (g_lpKeyboard)
        {
            g_lpKeyboard->Unacquire () ;
            g_lpKeyboard->Release () ;
            g_lpKeyboard = NULL ;
        }

        if (g_lpDirectInput)
        {
            g_lpDirectInput->Release () ;
            g_lpDirectInput = NULL ;
        }
    }

    LRESULT OnPaint (HWND hwnd)
    {
        PAINTSTRUCT ps;
       
        HDC hdc = BeginPaint(hwnd, &ps);

        if (hdc)
        {
            ExtTextOut (hdc, X_pos, Y_pos, ETO_OPAQUE, &ps.rcPaint, g_szText,
                        lstrlen (g_szText), NULL) ;

            EndPaint (hwnd, &ps) ;
        }

        return 0 ;
    }

    void CheckRect (HWND hwnd, int *X_pos, int *Y_pos, char *szBuf)
    {
        RECT rect ;

        GetClientRect (hwnd, &rect) ;

        if (*X_pos < 0)
            *X_pos = 0 ;
        if (*Y_pos < 0)
            *Y_pos = 0 ;
        if (*X_pos > rect.right-10)
            *X_pos = rect.right-10 ;
        if (*Y_pos > rect.bottom-10)
            *Y_pos = rect.bottom-10 ;

        lstrcpy (g_szText, szBuf) ;
        InvalidateRect (hwnd, NULL, TRUE) ;
    }

    void UpdateFrame(HWND hwnd)
    {
        HRESULT hResult;

        if (g_lpMouse)
        {
            DIMOUSESTATE MouseState ;
           
            for (;;)
            {
                hResult = g_lpMouse->GetDeviceState (sizeof (DIMOUSESTATE), &MouseState) ;

                if (hResult == DIERR_INPUTLOST)
                {
                    hResult = g_lpMouse->Acquire () ;

                    if (hResult != DI_OK)
                    {
                        break ;
                    }
                }
                else
                    break ;
            }

            if (hResult == DI_OK)
            {
                char szBuf[1024];
                char Button[10] ;

                X_pos += MouseState.lX ;
                Y_pos += MouseState.lY ;

                if (LEFTBUTTON(MouseState))
                {
                    bLeftButton = TRUE ;
                    strcpy (Button, "Left") ;
                }
                else
                {
                    bLeftButton = FALSE ;
                }

                if (RIGHTBUTTON(MouseState))
                {
                    bRightButton = TRUE ;
                    strcpy (Button, "Right") ;
                }
                else
                {
                    bRightButton = FALSE ;
                }

                if (bLeftButton == FALSE && bRightButton == FALSE)
                {
                    Button[0] = '\0' ;
                }
                else if (bLeftButton == TRUE && bRightButton == TRUE)
                {
                    strcpy (Button, "L-R Button") ;
                }

                wsprintf (szBuf, "(%d, %d) %s", X_pos, Y_pos, Button) ;
                CheckRect (hwnd, &X_pos, &Y_pos, szBuf) ;
            }
        }

        if (g_lpKeyboard)
        {
            BYTE KeyState[256] ;

            for (;;)
            {
                hResult = g_lpKeyboard->GetDeviceState (sizeof (KeyState), &KeyState) ;

                if (hResult == DIERR_INPUTLOST)
                {
                    hResult = g_lpKeyboard->Acquire () ;

                    if (hResult != DI_OK)
                    {
                        break ;
                    }
                }
                else
                    break ;
            }

            if (hResult == DI_OK)
            {
                char szBuf[1024] ;

                // 아래 있는 모든 if문을 else if 형태로 묶으면
                // 키보드 동시입력을 지원하지 못하게 된다.
                // 그러므로 동시에 입력되도록 if 문으로
                // 각각의 키를 매순간 모두 비교해야 한다.

                if (KEYDOWN(KeyState, DIK_RIGHT))
                {
                    lstrcpy (szBuf, "Right") ;
                    X_pos+=10 ;

                    CheckRect (hwnd, &X_pos, &Y_pos, szBuf) ;
                }
                else if (KEYDOWN(KeyState, DIK_LEFT))
                {
                    lstrcpy (szBuf, "Left") ;
                    X_pos-=10 ;

                    CheckRect (hwnd, &X_pos, &Y_pos, szBuf) ;
                }

                if (KEYDOWN(KeyState, DIK_UP))
                {
                    lstrcpy (szBuf, "Up") ;
                    Y_pos-=10 ;

                    CheckRect (hwnd, &X_pos, &Y_pos, szBuf) ;
                }
                else if (KEYDOWN(KeyState, DIK_DOWN))
                {
                    lstrcpy (szBuf, "Down") ;
                    Y_pos+=10 ;

                    CheckRect (hwnd, &X_pos, &Y_pos, szBuf) ;
                }

                if (KEYDOWN(KeyState, DIK_ESCAPE))
                {
                    lstrcpy (szBuf, "Esc") ;
                    lstrcpy (g_szText, szBuf) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                }

                if (KEYDOWN(KeyState, DIK_SPACE))
                {
                    lstrcpy (szBuf, "SPACE") ;
                    lstrcpy (g_szText, szBuf) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                }

                if (KEYDOWN(KeyState, DIK_LSHIFT))
                {
                    lstrcpy (szBuf, "LShift") ;
                    lstrcpy (g_szText, szBuf) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                }

                if (KEYDOWN(KeyState, DIK_RSHIFT))
                {
                    lstrcpy (szBuf, "RShift") ;
                    lstrcpy (g_szText, szBuf) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                }
            }
        }
    }

    void SyncAcquire (HWND hwnd)
    {
        if (g_bPaused)
        {
            if (g_lpMouse)
                g_lpMouse->Unacquire () ;

            if (g_lpKeyboard)
                g_lpKeyboard->Unacquire () ;
        }
        else
        {
            if (g_lpMouse)
                g_lpMouse->Acquire () ;
            if (g_lpKeyboard)
                g_lpKeyboard->Acquire () ;
        }
    }

    LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        LRESULT Result ;

        switch (msg)
        {
            case WM_PAINT:
                return OnPaint (hwnd) ;

            case WM_ACTIVATE:
                if (wParam == WA_INACTIVE)
                    g_bPaused = TRUE ;
                else
                    g_bPaused = FALSE ;

                SyncAcquire (hwnd) ;
                break ;

            case WM_ENTERMENULOOP:
            case WM_ENTERSIZEMOVE:
                g_bPaused = TRUE ;
                SyncAcquire (hwnd) ;
                break ;

            case WM_EXITMENULOOP:
            case WM_EXITSIZEMOVE:
                if (GetActiveWindow () != hwnd || IsIconic (hwnd))
                    g_bPaused = TRUE ;
                else
                    g_bPaused = FALSE ;
               
                PostMessage (hwnd, WM_SYNCACQUIRE, 0, 0L) ;
                break ;
           
            case WM_SYNCACQUIRE:
                SyncAcquire (hwnd) ;
                break ;
           
            case WM_SYSCOMMAND:
                Result= DefWindowProc (hwnd, msg, wParam, lParam) ;

                if (IsWindow (hwnd))
                {
                    SyncAcquire (hwnd) ;
                }
                return Result ;
           
            case WM_DESTROY:
                PostQuitMessage (0) ;
                break ;
        }

        return DefWindowProc (hwnd, msg, wParam, lParam) ;
    }

    HWND AppInit (HINSTANCE hinst, int nCmdShow)
    {
        g_hInst = hinst ;

        WNDCLASS wc ;

        wc.hCursor        = LoadCursor (0, IDC_ARROW) ;
        wc.hIcon          = LoadIcon (NULL, MAKEINTRESOURCE(IDI_APPLICATION)) ;
        wc.lpszMenuName   = NULL ;
        wc.lpszClassName  = c_szClassName ;
        wc.hbrBackground  = 0 ;
        wc.hInstance      = hinst ;
        wc.style          = 0 ;
        wc.lpfnWndProc    = WndProc ;
        wc.cbClsExtra     = 0 ;
        wc.cbWndExtra     = 0 ;

        if (!RegisterClass (&wc))
        {
            return NULL ;
        }

        HWND hwnd = CreateWindow (
                        c_szClassName,
                        "마우스입력 - 종료시 Alt+F4",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL,
                        NULL,
                        g_hInst,
                        0
                        ) ;

        if (!DirectInput_Init (hwnd))
        {
            DestroyWindow (hwnd) ;
            return NULL ;
        }

        ShowWindow (hwnd, nCmdShow) ;

        return hwnd ;
    }

    int PASCAL WinMain (HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR szCmdLine, int nCmdShow)
    {
        HWND hwnd = AppInit (hinst, nCmdShow) ;

        MSG msg ;

        if (hwnd)
        {
            for (;;)
            {
                if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
                {
                    if (msg.message == WM_QUIT)
                    {
                        break ;
                    }
                    else
                    {
                        TranslateMessage (&msg) ;
                        DispatchMessage (&msg) ;
                    }
                }
                else if (g_bPaused)
                {
                    WaitMessage () ;
                }
                else
                {
                    UpdateFrame(hwnd) ;
                }
            }
        }

        DirectInput_End () ;

        return msg.wParam ;
    }

Designed by Tistory.