이전 단계인 "7. Mouse Input (마우스 입력)" 에서는 Mouse 이벤트를 처리했습니다.
이번 단계에서는 마우스의 상대적 좌표를 나타내보려고 합니다.
MouseClass.h
#pragma once
#include "MouseEvent.h"
#include <queue>
using namespace std;
class MouseClass
{
public:
/* 각 타입에 따라 mouseBuffer에 마우스 이벤트 타입, x, y 좌표 저장 */
/* 동일 */
void OnMouseMoveRaw(int x, int y);
/* 동일 */
};
MouseClass.cpp
#include "MouseClass.h"
/* 마우스를 움직였을 때 (상대적 좌표) */
void MouseClass::OnMouseMoveRaw(int x, int y)
{
this->mouseBuffer.push(MouseEvent(MouseEvent::EventType::RAW_MOVE, x, y));
}
WindowContainer.h
#pragma once
#include "RenderWindow.h"
#include "Keyboard/KeyboardClass.h"
#include "Mouse/MouseClass.h"
class WindowContainer
{
public:
WindowContainer(); // 추가
LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
RenderWindow render_window;
KeyboardClass keyboard;
MouseClass mouse;
private:
};
WindowContainer.cpp
#include <memory>
#include "WindowContainer.h"
/* RAW INPUT에 대한 구조체 생성 및 등록 */
WindowContainer::WindowContainer()
{
static bool raw_input_initialized = false;
if (raw_input_initialized == false)
{
/* 구조체 생성 */
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01; // 원시 데스크탑 컨트롤
rid.usUsage = 0x02; // 마우스
rid.dwFlags = 0;
rid.hwndTarget = NULL;
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)) == FALSE)
{
ErrorLogger::Log(GetLastError(), "Failed to register raw input devices.");
exit(-1);
}
raw_input_initialized = true;
}
}
LRESULT WindowContainer::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
/* -- 키보드 메시지 -- */
/* 동일 */
/* -- 마우스 메시지 -- */
/* 동일 */
/* RAW_INPUT을 가져옴 */
case WM_INPUT:
{
UINT dataSize;
/* dataSize를 얻어냄 */
GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER));
if (dataSize > 0)
{
unique_ptr<BYTE[]> rawdata = make_unique<BYTE[]>(dataSize); // 크기 재조정
if (GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, rawdata.get(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
{
RAWINPUT* raw = reinterpret_cast<RAWINPUT*>(rawdata.get());
if (raw->header.dwType == RIM_TYPEMOUSE)
{
// x, y방향의 동작
mouse.OnMouseMoveRaw(raw->data.mouse.lLastX, raw->data.mouse.lLastY);
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam); // WM_INPUT 메시지 처리
}
default:
/* 처리되지 않은 모든 메시지의 디폴트 처리를 수행 */
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
GetRawInputData 함수
- 매개변수
- HRAWINPUT : RAWINPUT 구조체에 대한 핸들
- UINT : 명령 플래그
- RID_HEADER : RAWINPUT 구조체에서 헤더 정보를 가져옴
- RID_INPUT : RAW INPUT 구조체에서 RAW DATA를 가져옴
- LPVOID : RAWINPUT 구조체에서 오는 데이터에 대한 포인터
- pData가 NULL이면 필요한 버퍼 크기가 *pcbSize에 반환됨
- PUINT : pData에 있는 데이터의 크기(바이트)
- UINT : RAWINPUTHEADER 구조체의 크기(바이트)
- 반환값
- pData가 NULL이고 함수가 성공하면 반환 값은 0
- pData가 NULL이 아니고 함수가 성공하면 반환 값은 pData에 복사된 바이트 수
- 오류가 있는 경우 반환 값은 (UINT)-1
- 참고자료 : GetRawInputData 함수
void Engine::Update()
{
/* RAW INPUT 테스트 */
while (!mouse.MouseBufferIsEmpty())
{
MouseEvent me = mouse.ReadEvent();
if (me.GetType() == MouseEvent::EventType::RAW_MOVE)
{
string outmsg = "X : ";
outmsg += to_string(me.GetPosX());
outmsg += ", Y : ";
outmsg += to_string(me.GetPosY());
outmsg += "\n";
OutputDebugStringA(outmsg.c_str());
}
}
}