Adjusted workflow.
This commit is contained in:
730
src/io/Window_W32.cpp
Normal file
730
src/io/Window_W32.cpp
Normal file
@@ -0,0 +1,730 @@
|
||||
#include "ehs/io/Window_W32.h"
|
||||
#include "ehs/io/hid/Keyboard.h"
|
||||
#include "ehs/io/hid/Mouse.h"
|
||||
#include "ehs/system/Thread.h"
|
||||
|
||||
#include <hidusage.h>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Array<Window*> Window::windows;
|
||||
|
||||
LRESULT Window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
Window* win = nullptr;
|
||||
for (UInt_64 i = 0; i < windows.Size(); ++i)
|
||||
{
|
||||
if (hWnd == windows[i]->hdl)
|
||||
win = windows[i];
|
||||
}
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!win)
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
|
||||
if (uMsg == WM_CLOSE)
|
||||
{
|
||||
for (UInt_64 i = 0; i < windows.Size(); ++i)
|
||||
{
|
||||
if (windows[i]->hdl != hWnd)
|
||||
continue;
|
||||
|
||||
if (windows.Size() > 1)
|
||||
windows.Swap(i, windows.Size() - 1);
|
||||
|
||||
windows.Pop();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
win->hdl = nullptr;
|
||||
win->Close();
|
||||
|
||||
return 0;
|
||||
|
||||
//return DefWindowProcW(hWnd, WM_QUIT, 0, lParam);
|
||||
}
|
||||
else if (uMsg == WM_SIZE)
|
||||
{
|
||||
Vec2<UInt_16> newSize;
|
||||
newSize[0] = static_cast<UInt_16>(lParam);
|
||||
newSize[1] = static_cast<UInt_16>(lParam >> 16);
|
||||
|
||||
win->OnResized(newSize);
|
||||
}
|
||||
else if (uMsg == WM_HIDE)
|
||||
{
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
}
|
||||
else if (uMsg == WM_SHOW)
|
||||
{
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
}
|
||||
else if (uMsg == WM_HIDE_CURSOR)
|
||||
{
|
||||
while (::ShowCursor(false) >= 0);
|
||||
}
|
||||
else if (uMsg == WM_SHOW_CURSOR)
|
||||
{
|
||||
while (::ShowCursor(true) < 0);
|
||||
}
|
||||
else if (uMsg == WM_PAINT)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hWnd, &ps);
|
||||
|
||||
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW));
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
else if (win->HasFocus() && uMsg == WM_INPUT)
|
||||
{
|
||||
UINT dwSize = 0;
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, nullptr, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
|
||||
if (dwSize)
|
||||
{
|
||||
Byte* data = new Byte[dwSize];
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Getting raw input returned incorrect size.");
|
||||
delete[] data;
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
|
||||
if (raw->header.dwType == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
Keyboard* keyboard = (Keyboard*)win->ih.GetDevice((UInt_64)raw->header.hDevice);
|
||||
if (!keyboard)
|
||||
{
|
||||
UInt_32 bufferSize;
|
||||
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, NULL, &bufferSize);
|
||||
Char_16* deviceName = new Char_16[bufferSize];
|
||||
|
||||
if (GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve device name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
keyboard = new Keyboard(UTF::To_8(deviceName, (UInt_64)bufferSize), (UInt_64)raw->header.hDevice);
|
||||
win->ih.AddDevice(keyboard);
|
||||
}
|
||||
|
||||
const Button button = Keyboard::TranslateScanCode(raw->data.keyboard.MakeCode);
|
||||
|
||||
if (raw->data.keyboard.Message == WM_KEYDOWN || raw->data.keyboard.Message == WM_SYSKEYDOWN)
|
||||
keyboard->ButtonDown(button);
|
||||
else if (raw->data.keyboard.Message == WM_KEYUP || raw->data.keyboard.Message == WM_SYSKEYUP)
|
||||
keyboard->ButtonUp(button);
|
||||
}
|
||||
else if (raw->header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
Mouse* mouse = (Mouse*)win->ih.GetDevice((UInt_64)raw->header.hDevice);
|
||||
if (!mouse)
|
||||
{
|
||||
UInt_32 bufferSize;
|
||||
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, nullptr, &bufferSize);
|
||||
Char_16* deviceName = new Char_16[bufferSize];
|
||||
|
||||
if (GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, deviceName, &bufferSize) < 0)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve device name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mouse = new Mouse(UTF::To_8(deviceName, (UInt_64)bufferSize), (UInt_64)raw->header.hDevice);
|
||||
win->ih.AddDevice(mouse);
|
||||
}
|
||||
|
||||
mouse->SetDelta({raw->data.mouse.lLastX, raw->data.mouse.lLastY});
|
||||
|
||||
UInt_16 code = raw->data.mouse.usButtonFlags;
|
||||
|
||||
if (code == RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
mouse->ButtonDown(Mouse::LMB);
|
||||
else if (code == RI_MOUSE_LEFT_BUTTON_UP)
|
||||
mouse->ButtonUp(Mouse::LMB);
|
||||
else if (code == RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
mouse->ButtonDown(Mouse::RMB);
|
||||
else if (code == RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
mouse->ButtonUp(Mouse::RMB);
|
||||
else if (code == RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
mouse->ButtonDown(Mouse::MMB);
|
||||
else if (code == RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
mouse->ButtonUp(Mouse::MMB);
|
||||
else if (code == RI_MOUSE_BUTTON_4_DOWN)
|
||||
mouse->ButtonDown(Mouse::Four);
|
||||
else if (code == RI_MOUSE_BUTTON_4_UP)
|
||||
mouse->ButtonUp(Mouse::Four);
|
||||
else if (code == RI_MOUSE_BUTTON_5_DOWN)
|
||||
mouse->ButtonDown(Mouse::Five);
|
||||
else if (code == RI_MOUSE_BUTTON_5_UP)
|
||||
mouse->ButtonUp(Mouse::Five);
|
||||
else if (code == RI_MOUSE_WHEEL)
|
||||
{
|
||||
if (raw->data.mouse.usButtonData < 0)
|
||||
mouse->ButtonDown(Mouse::ScrollDown);
|
||||
else if (raw->data.mouse.usButtonData > 0)
|
||||
mouse->ButtonDown(Mouse::ScrollUp);
|
||||
}
|
||||
else if (code == RI_MOUSE_HWHEEL)
|
||||
{
|
||||
if (raw->data.mouse.usButtonData < 0)
|
||||
mouse->ButtonDown(Mouse::ScrollLeft);
|
||||
else if (raw->data.mouse.usButtonData > 0)
|
||||
mouse->ButtonDown(Mouse::ScrollRight);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
else if (uMsg == WM_KILLFOCUS)
|
||||
{
|
||||
win->focused = false;
|
||||
|
||||
if (!win->cursorVisible)
|
||||
{
|
||||
win->SendMsg(WM_SHOW_CURSOR, 0, 0);
|
||||
}
|
||||
|
||||
if (win->cursorConstrained)
|
||||
{
|
||||
if (!ClipCursor(nullptr))
|
||||
EHS_LOG_INT("Error", 0, "Failed to free cursor after losing focus with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
win->ih.ResetAllStates();
|
||||
}
|
||||
else if (uMsg == WM_SETFOCUS)
|
||||
{
|
||||
win->focused = true;
|
||||
|
||||
if (!win->cursorVisible)
|
||||
win->SendMsg(WM_HIDE_CURSOR, 0, 0);
|
||||
|
||||
if (win->cursorConstrained)
|
||||
{
|
||||
RECT client = {};
|
||||
|
||||
if (!GetClientRect(win->GetHdl(), &client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
POINT pos = {};
|
||||
|
||||
if (!ClientToScreen(win->GetHdl(), &pos))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
client.left = pos.x;
|
||||
client.top = pos.y;
|
||||
|
||||
POINT scale = {client.right, client.bottom};
|
||||
|
||||
if (!ClientToScreen(win->GetHdl(), &scale))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
client.right = scale.x;
|
||||
client.bottom = scale.y;
|
||||
|
||||
if (!ClipCursor(&client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (uMsg == WM_MOUSEMOVE)
|
||||
{
|
||||
win->cursorPos.x = ((SInt_16*)&lParam)[0];
|
||||
win->cursorPos.y = ((SInt_16*)&lParam)[1];
|
||||
}
|
||||
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
SendMsg(WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
Window::Window()
|
||||
: owner(0), instance(nullptr), hdl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Window::Window(const Window& win)
|
||||
: BaseWindow(win), owner(0), instance(nullptr), hdl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Window& Window::operator=(const Window& win)
|
||||
{
|
||||
if (&win == this)
|
||||
return *this;
|
||||
|
||||
BaseWindow::operator=(win);
|
||||
|
||||
owner = 0;
|
||||
created = false;
|
||||
focused = false;
|
||||
instance = nullptr;
|
||||
hdl = nullptr;
|
||||
|
||||
return* this;
|
||||
}
|
||||
|
||||
bool Window::Poll()
|
||||
{
|
||||
ih.Poll();
|
||||
|
||||
MSG msg = {};
|
||||
|
||||
while (PeekMessageW(&msg, nullptr, 0, 0, PM_NOREMOVE))
|
||||
{
|
||||
if (GetMessageW(&msg, nullptr, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
BaseWindow::Poll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||
{
|
||||
Create_16(UTF::To_16(title), pos, scale);
|
||||
}
|
||||
|
||||
void Window::Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||
{
|
||||
if (created)
|
||||
return;
|
||||
|
||||
owner = Thread::GetCurrentId();
|
||||
|
||||
instance = GetModuleHandleW(nullptr);
|
||||
|
||||
WNDCLASSEXW wcex = {};
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
wcex.lpfnWndProc = &Window::WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = instance;
|
||||
wcex.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hIconSm = LoadIcon(nullptr, IDI_WINLOGO);
|
||||
wcex.hbrBackground = nullptr;
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = title;
|
||||
|
||||
if (!RegisterClassExW(&wcex))
|
||||
EHS_LOG_INT("Error", 0, "Failed to register window.");
|
||||
|
||||
hdl = CreateWindowExW(
|
||||
0,
|
||||
title,
|
||||
title,
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
pos.x, pos.y, scale.x, scale.y,
|
||||
nullptr, nullptr,
|
||||
instance,
|
||||
nullptr
|
||||
);
|
||||
|
||||
if (!hdl)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to create window.");
|
||||
return;
|
||||
}
|
||||
|
||||
RECT tmp = {
|
||||
0,
|
||||
0,
|
||||
static_cast<LONG>(scale.x),
|
||||
static_cast<LONG>(scale.y)
|
||||
};
|
||||
|
||||
AdjustWindowRectEx(&tmp, WS_OVERLAPPEDWINDOW, false, 0);
|
||||
|
||||
SetWindowPos(hdl, nullptr, 0, 0, tmp.right - tmp.left, tmp.bottom - tmp.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
RAWINPUTDEVICE rid[2];
|
||||
|
||||
rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
|
||||
rid[0].dwFlags = RIDEV_INPUTSINK;
|
||||
rid[0].hwndTarget = hdl;
|
||||
|
||||
rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
|
||||
rid[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
|
||||
rid[1].dwFlags = 0;
|
||||
rid[1].hwndTarget = hdl;
|
||||
|
||||
if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == false)
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to register raw input devices.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
windows.Push(this);
|
||||
|
||||
created = true;
|
||||
|
||||
OnCreated();
|
||||
}
|
||||
|
||||
void Window::Create_8(const Str_8& title, const Vec2_s32& pos, const Vec2_u32 scale)
|
||||
{
|
||||
Create_16(UTF::To_16(title), pos, scale);
|
||||
}
|
||||
|
||||
void Window::Use(HWND windowHdl)
|
||||
{
|
||||
hdl = windowHdl;
|
||||
}
|
||||
|
||||
void Window::Close()
|
||||
{
|
||||
if (hdl)
|
||||
SendMsg(WM_CLOSE, 0, 0);
|
||||
|
||||
created = false;
|
||||
}
|
||||
|
||||
void Window::Show()
|
||||
{
|
||||
SendMsg(WM_SHOW, 0, 0);
|
||||
}
|
||||
|
||||
void Window::Hide()
|
||||
{
|
||||
SendMsg(WM_HIDE, 0, 0);
|
||||
}
|
||||
|
||||
void Window::SetTitle_32(const Str_32& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_32 Window::GetTitle_32()
|
||||
{
|
||||
int size = GetWindowTextLengthW(hdl);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Char_16* buffer = new Char_16[size];
|
||||
|
||||
size = GetWindowTextW(hdl, buffer, size);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return UTF::To_32(buffer, Str_16::Len(buffer));
|
||||
}
|
||||
|
||||
void Window::SetTitle_16(const Str_16& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, title))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_16 Window::GetTitle_16()
|
||||
{
|
||||
int size = GetWindowTextLengthW(hdl);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Char_16* buffer = new Char_16[size];
|
||||
|
||||
size = GetWindowTextW(hdl, buffer, size);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return {buffer};
|
||||
}
|
||||
|
||||
void Window::SetTitle_8(const Str_8& title)
|
||||
{
|
||||
if (!SetWindowTextW(hdl, UTF::To_16(title)))
|
||||
EHS_LOG_INT("Error", 0, "Failed to set window title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
}
|
||||
|
||||
Str_8 Window::GetTitle_8()
|
||||
{
|
||||
int size = GetWindowTextLengthW(hdl);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Char_16* buffer = new Char_16[size];
|
||||
|
||||
size = GetWindowTextW(hdl, buffer, size);
|
||||
if (!size)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err)
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve the window's title length with error #" + Str_8::FromNum(err) + ".");
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return UTF::To_8(buffer, Str_16::Len(buffer));
|
||||
}
|
||||
|
||||
void Window::SetIcon(const Str_8& filePath)
|
||||
{
|
||||
Handle icon = LoadImageW(nullptr, UTF::To_16(filePath), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||
if (!icon)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to load icon at file path, \"" + filePath + "\" with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
SendMsg(WM_SETICON, ICON_SMALL, (LPARAM)icon);
|
||||
SendMsg(WM_SETICON, ICON_BIG, (LPARAM)icon);
|
||||
}
|
||||
|
||||
HWND Window::GetHdl() const
|
||||
{
|
||||
return hdl;
|
||||
}
|
||||
|
||||
HWND Window::GetAvailableHdl()
|
||||
{
|
||||
for (UInt_64 i = 0; i < windows.Size(); ++i)
|
||||
if (windows[i])
|
||||
return windows[i]->hdl;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HINSTANCE Window::GetInst() const
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Window::ToggleEnabled(bool toggle)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
EnableWindow(hdl, toggle);
|
||||
}
|
||||
|
||||
bool Window::IsEnabled()
|
||||
{
|
||||
if (!created)
|
||||
return false;
|
||||
|
||||
return IsWindowEnabled(hdl);
|
||||
}
|
||||
|
||||
void Window::SetPos(int x, int y)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
SetWindowPos(hdl, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
Vec2<Int_32> Window::GetPos()
|
||||
{
|
||||
if (!created)
|
||||
return {};
|
||||
|
||||
RECT tmp = {};
|
||||
GetWindowRect(hdl, &tmp);
|
||||
|
||||
return {(Int_32)tmp.left, (Int_32)tmp.top};
|
||||
}
|
||||
|
||||
void Window::SetClientSize(const Vec2<UInt_32>& size)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
RECT rect = {
|
||||
0,
|
||||
0,
|
||||
static_cast<LONG>(size[0]),
|
||||
static_cast<LONG>(size[1])
|
||||
};
|
||||
|
||||
DWORD exStyle = (DWORD)GetWindowLongPtr(hdl, GWL_EXSTYLE);
|
||||
DWORD style = (DWORD)GetWindowLongPtr(hdl, GWL_STYLE);
|
||||
|
||||
AdjustWindowRectEx(&rect, style, false, exStyle);
|
||||
|
||||
SetWindowPos(hdl, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
Vec2<UInt_32> Window::GetClientSize()
|
||||
{
|
||||
RECT rect = {};
|
||||
|
||||
if (!GetClientRect(hdl, &rect))
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client size with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
|
||||
return {(UInt_32)rect.right, (UInt_32)rect.bottom};
|
||||
}
|
||||
|
||||
void Window::OnResized(const Vec2<UInt_32>& newSize)
|
||||
{
|
||||
}
|
||||
|
||||
void Window::SetSize(int w, int h)
|
||||
{
|
||||
if (!created)
|
||||
return;
|
||||
|
||||
SetWindowPos(hdl, nullptr, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
Vec2<Int_32> Window::GetSize()
|
||||
{
|
||||
if (!created)
|
||||
return {};
|
||||
|
||||
RECT tmp = {};
|
||||
GetWindowRect(hdl, &tmp);
|
||||
|
||||
return {(Int_32)(tmp.right - tmp.left), (Int_32)(tmp.bottom - tmp.top)};
|
||||
}
|
||||
|
||||
void Window::ShowCursor(bool toggle)
|
||||
{
|
||||
SendMsg(toggle ? WM_SHOW_CURSOR : WM_HIDE_CURSOR, 0, 0);
|
||||
|
||||
cursorVisible = toggle;
|
||||
}
|
||||
|
||||
void Window::ConstrainCursor(const bool toggle)
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
RECT client = {};
|
||||
|
||||
if (!GetClientRect(GetHdl(), &client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Failed to retrieve client scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
POINT pos = {};
|
||||
|
||||
if (!ClientToScreen(GetHdl(), &pos))
|
||||
{
|
||||
EHS_LOG_INT("Error", 1, "Failed to retrieve client's absolute position with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
client.left = pos.x;
|
||||
client.top = pos.y;
|
||||
|
||||
POINT scale = {client.right, client.bottom};
|
||||
|
||||
if (!ClientToScreen(GetHdl(), &scale))
|
||||
{
|
||||
EHS_LOG_INT("Error", 2, "Failed to retrieve client's absolute scale with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
client.right = scale.x;
|
||||
client.bottom = scale.y;
|
||||
|
||||
if (!ClipCursor(&client))
|
||||
{
|
||||
EHS_LOG_INT("Error", 3, "Failed to confine cursor with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClipCursor(nullptr);
|
||||
}
|
||||
|
||||
cursorConstrained = toggle;
|
||||
}
|
||||
|
||||
void Window::SendMsg(const UINT msg, const WPARAM wParam, const LPARAM lParam)
|
||||
{
|
||||
if (!hdl)
|
||||
return;
|
||||
|
||||
if (Thread::GetCurrentId() == owner)
|
||||
PostMessageW(hdl, msg, wParam, lParam);
|
||||
else
|
||||
SendMessageW(hdl, msg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user