#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 ;
}