Files
2025-05-13 02:46:21 +03:00

548 lines
13 KiB
C++

#include "WindowWin.h"
#define L_WIN32
#include <windows.h>
#include "log/NLog.h"
namespace LifeCore {
LRESULT __stdcall WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
WindowWin::WindowWin() {
bFullscreen = false;
bActive = true;
bModeSwitching = false;
bCursorVisible = true;
bAltEnterLocked = false;
width = 256;
height = 256;
g_hInst = GetModuleHandle(NULL);
g_hwnd = NULL;
//memset(&g_wndClass,0,sizeof(WNDCLASSEX));
WNDCLASSEX g_wndClass = { NULL };
g_wndClass.cbSize = sizeof(WNDCLASSEX);
g_wndClass.cbClsExtra = NULL;
g_wndClass.cbWndExtra = NULL;
g_wndClass.hbrBackground = (HBRUSH)GetStockObject(1);
g_wndClass.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
g_wndClass.hIcon = LoadIcon(g_hInst, IDI_APPLICATION);
g_wndClass.hIconSm = LoadIcon(g_hInst, IDI_APPLICATION);
g_wndClass.hInstance = g_hInst;
g_wndClass.lpfnWndProc = WndProc;
g_wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
g_wndClass.lpszMenuName = NULL;
g_wndClass.lpszClassName = _text("Onotole");
if(!RegisterClassEx(&g_wndClass)) {
MessageBox(g_hwnd, _text("Can not create window class! We all gonna die!!"), _text("OH SHIT!"), MB_OK);
}
//calculate window size
RECT NewWindowSize;
NewWindowSize.top = 30;
NewWindowSize.left = 300;
NewWindowSize.bottom = NewWindowSize.top + height;
NewWindowSize.right = NewWindowSize.left + width;
AdjustWindowRect(&NewWindowSize, WS_OVERLAPPEDWINDOW, false);
/*WS_MINIMIZEBOX
WS_MAXIMIZEBOX*/
if(!(g_hwnd = CreateWindowEx(NULL, _text("Onotole"), _text("LifeEngine render window"), WS_THICKFRAME,
NewWindowSize.left, NewWindowSize.top, NewWindowSize.right - NewWindowSize.left, NewWindowSize.bottom - NewWindowSize.top, NULL, NULL, g_hInst, NULL))) {
MessageBox(g_hwnd, _text("Can not create window! We all gonna die!!"), _text("HOLY SHIT!"), MB_OK);
}
ShowWindow(g_hwnd, SW_SHOWNORMAL);
SetForegroundWindow(g_hwnd);
SetFocus(g_hwnd);
ZeroMemory(&mode, sizeof(DEVMODE));
mode.dmSize = sizeof(DEVMODE);
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode);
WindowWin* ptr = this;
long val = (long)ptr;
SetWindowLongPtr(g_hwnd, GWLP_USERDATA, val);
fsMode.width = 640;
fsMode.height = 480;
fsMode.refreshRate = 60;
fsMode.bpp = 4;
CenterWindow();
}
bool WindowWin::IsKeyPressed(KeyCodes::Key key) {
return false;
}
void WindowWin::Update() {
#ifdef L_WIN32
MSG msg = { 0 };
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
switch(msg.message) {
case WM_QUIT:
{
Event_Quit.Invoke();
//exit(0);
}
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#endif
}
void WindowWin::SetCaption(const String& val) {
caption = val;
SetWindowText(g_hwnd, caption.c_str());
}
void WindowWin::SetFullScreen(bool state) {
bFullscreen = state;
}
bool WindowWin::IsFullScreen() {
return bFullscreen;
}
WindowWin::~WindowWin(void) {
ChangeDisplaySettings(&mode, 0);
}
void WindowWin::OnActivate() {
bActive = true;
Event_Activate.Invoke(this);
}
void WindowWin::OnDeactivate() {
bActive = false;
Event_Deactivate.Invoke(this);
}
void WindowWin::OnResize() {
if(!IsFullScreen() || !bModeSwitching) {
RECT r;
::GetClientRect(g_hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
}
Event_Resize.Invoke(this);
}
bool WindowWin::IsActive() {
return bActive;
}
bool WindowWin::IsModeSwitching() {
return bModeSwitching;
}
void WindowWin::SetCursorVisible(bool state) {
bCursorVisible = state;
}
bool WindowWin::IsCursorVisible() {
return bCursorVisible;
}
bool WindowWin::SwitchMode(bool fullscreen) {
bFullscreen = fullscreen;
if(bFullscreen) {
bModeSwitching = true;
DEVMODE fmode;
ZeroMemory(&fmode, sizeof(DEVMODE));
fmode.dmSize = sizeof(DEVMODE);
fmode.dmPelsWidth = fsMode.width;
fmode.dmPelsHeight = fsMode.height;
fmode.dmBitsPerPel = mode.dmBitsPerPel;
fmode.dmDisplayFrequency = fsMode.refreshRate;
fmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
//if(ChangeDisplaySettings(&fmode,0)!= DISP_CHANGE_SUCCESSFUL)
// return false;
SetWindowLong(g_hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST);
SetWindowLong(g_hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(g_hwnd, HWND_TOPMOST, 0, 0, fsMode.width, fsMode.height, SWP_SHOWWINDOW | SWP_FRAMECHANGED);
bModeSwitching = false;
} else {
//if(ChangeDisplaySettings(&mode_window,0)!= DISP_CHANGE_SUCCESSFUL)
// return false;
SetWindowLong(g_hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
SetWindowLong(g_hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetSize(width, height);
CenterWindow();
}
Event_SwitchFullscreen.Invoke(this);
return true;
}
void WindowWin::CenterWindow() {
int mx = GetSystemMetrics(SM_CXSCREEN);
int my = GetSystemMetrics(SM_CYSCREEN);
int nx = (mx - width) / 2;
int ny = (my - height) / 2;
SetWindowPos(g_hwnd, NULL, nx, ny, -1, -1,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
void WindowWin::SetFullscreenMode(LifeCore::DisplayMode mode) {
fsMode = mode;
}
void WindowWin::SetSize(int w, int h) {
if(!IsFullScreen()) {
width = w;
height = h;
RECT NewWindowSize;
NewWindowSize.top = 50;
NewWindowSize.left = 50;
NewWindowSize.bottom = NewWindowSize.top + h;
NewWindowSize.right = NewWindowSize.left + w;
AdjustWindowRect(&NewWindowSize, WS_OVERLAPPEDWINDOW, false);
SetWindowPos(g_hwnd, HWND_TOP, NewWindowSize.left, NewWindowSize.top, NewWindowSize.right - NewWindowSize.left, NewWindowSize.bottom - NewWindowSize.top, SWP_SHOWWINDOW | SWP_FRAMECHANGED);
//::MoveWindow(g_hwnd,NewWindowSize.left, NewWindowSize.top, NewWindowSize.right - NewWindowSize.left, NewWindowSize.bottom - NewWindowSize.top, true);
CenterWindow();
}
}
KeyCodes::Key WindowWin::ConvertKeyCode(unsigned long key_code) {
switch(key_code) {
case VK_ESCAPE:
return KeyCodes::KEY_ESCAPE;
case VK_F1:
return KeyCodes::KEY_F1;
case VK_F2:
return KeyCodes::KEY_F2;
case VK_F3:
return KeyCodes::KEY_F3;
case VK_F4:
return KeyCodes::KEY_F4;
case VK_F5:
return KeyCodes::KEY_F5;
case VK_F6:
return KeyCodes::KEY_F6;
case VK_F7:
return KeyCodes::KEY_F7;
case VK_F8:
return KeyCodes::KEY_F8;
case VK_F9:
return KeyCodes::KEY_F9;
case VK_F10:
return KeyCodes::KEY_F10;
case VK_F11:
return KeyCodes::KEY_F11;
case VK_F12:
return KeyCodes::KEY_F12;
case VK_SNAPSHOT:
return KeyCodes::KEY_PRINT_SCREEN;
case VK_SCROLL:
return KeyCodes::KEY_SCROLL_LOCK;
case VK_PAUSE:
return KeyCodes::KEY_PAUSE;
case VK_OEM_3:
return KeyCodes::KEY_TILDE;
case 0x30:
return KeyCodes::KEY_1;
case 0x31:
return KeyCodes::KEY_2;
case 0x32:
return KeyCodes::KEY_3;
case 0x33:
return KeyCodes::KEY_4;
case 0x34:
return KeyCodes::KEY_5;
case 0x35:
return KeyCodes::KEY_6;
case 0x36:
return KeyCodes::KEY_7;
case 0x37:
return KeyCodes::KEY_8;
case 0x38:
return KeyCodes::KEY_9;
case 0x39:
return KeyCodes::KEY_0;
case 0xBD:
return KeyCodes::KEY_MINUS;
case 0xBB:
return KeyCodes::KEY_EQUAL;
case VK_BACK:
return KeyCodes::KEY_BACKSPACE;
case VK_TAB:
return KeyCodes::KEY_TAB;
case VK_CAPITAL:
return KeyCodes::KEY_CAPS_LOCK;
case VK_SHIFT:
return KeyCodes::KEY_SHIFT;
case VK_CONTROL:
return KeyCodes::KEY_CONTROL;
case VK_LWIN:
return KeyCodes::KEY_META_LEFT;
case VK_RWIN:
return KeyCodes::KEY_META_RIGHT;
case VK_MENU:
return KeyCodes::KEY_ALT;
case VK_SPACE:
return KeyCodes::KEY_SPACE;
case VK_APPS:
return KeyCodes::KEY_MENU;
case VK_RETURN:
return KeyCodes::KEY_ENTER;
case 0x41:
return KeyCodes::KEY_A;
case 0x42:
return KeyCodes::KEY_B;
case 0x43:
return KeyCodes::KEY_C;
case 0x44:
return KeyCodes::KEY_D;
case 0x45:
return KeyCodes::KEY_E;
case 0x46:
return KeyCodes::KEY_F;
case 0x47:
return KeyCodes::KEY_G;
case 0x48:
return KeyCodes::KEY_H;
case 0x49:
return KeyCodes::KEY_I;
case 0x4A:
return KeyCodes::KEY_J;
case 0x4B:
return KeyCodes::KEY_K;
case 0x4C:
return KeyCodes::KEY_L;
case 0x4D:
return KeyCodes::KEY_M;
case 0x4E:
return KeyCodes::KEY_N;
case 0x4F:
return KeyCodes::KEY_O;
case 0x50:
return KeyCodes::KEY_P;
case 0x51:
return KeyCodes::KEY_Q;
case 0x52:
return KeyCodes::KEY_R;
case 0x53:
return KeyCodes::KEY_S;
case 0x54:
return KeyCodes::KEY_T;
case 0x55:
return KeyCodes::KEY_U;
case 0x56:
return KeyCodes::KEY_V;
case 0x57:
return KeyCodes::KEY_W;
case 0x58:
return KeyCodes::KEY_X;
case 0x59:
return KeyCodes::KEY_Y;
case 0x5A:
return KeyCodes::KEY_Z;
case VK_OEM_4:
return KeyCodes::KEY_BRACKET_LEFT;
case VK_OEM_6:
return KeyCodes::KEY_BRACKET_RIGHT;
case VK_OEM_5:
return KeyCodes::KEY_BACKSLASH;
case VK_OEM_1:
return KeyCodes::KEY_SEMICOLON;
case VK_OEM_7:
return KeyCodes::KEY_APOSTROPHE;
case 0xBC:
return KeyCodes::KEY_COMMA;
case 0xBE:
return KeyCodes::KEY_DOT;
case VK_OEM_2:
return KeyCodes::KEY_SLASH;
case VK_INSERT:
return KeyCodes::KEY_INSERT;
case VK_DELETE:
return KeyCodes::KEY_DELETE;
case VK_HOME:
return KeyCodes::KEY_HOME;
case VK_END:
return KeyCodes::KEY_END;
case VK_PRIOR:
return KeyCodes::KEY_PAGE_UP;
case VK_NEXT:
return KeyCodes::KEY_PAGE_DOWN;
case VK_UP:
return KeyCodes::KEY_UP;
case VK_LEFT:
return KeyCodes::KEY_LEFT;
case VK_DOWN:
return KeyCodes::KEY_DOWN;
case VK_RIGHT:
return KeyCodes::KEY_RIGHT;
case VK_NUMLOCK:
return KeyCodes::KEY_NUM_LOCK;
case VK_ADD:
return KeyCodes::KEY_NUM_ADD;
case VK_SUBTRACT:
return KeyCodes::KEY_NUM_SUBTRACT;
case VK_MULTIPLY:
return KeyCodes::KEY_NUM_MULTIPLY;
case VK_DIVIDE:
return KeyCodes::KEY_NUM_DIVIDE;
case VK_NUMPAD0:
return KeyCodes::KEY_NUM_0;
case VK_NUMPAD1:
return KeyCodes::KEY_NUM_1;
case VK_NUMPAD2:
return KeyCodes::KEY_NUM_2;
case VK_NUMPAD3:
return KeyCodes::KEY_NUM_3;
case VK_NUMPAD4:
return KeyCodes::KEY_NUM_4;
case VK_NUMPAD5:
return KeyCodes::KEY_NUM_5;
case VK_CLEAR:
return KeyCodes::KEY_NUM_SPECIAL;
case VK_NUMPAD6:
return KeyCodes::KEY_NUM_6;
case VK_NUMPAD7:
return KeyCodes::KEY_NUM_7;
case VK_NUMPAD8:
return KeyCodes::KEY_NUM_8;
case VK_NUMPAD9:
return KeyCodes::KEY_NUM_9;
case VK_DECIMAL:
return KeyCodes::KEY_NUM_DECIMAL;
default:
return KeyCodes::UNKNOWN_KEY;
}
}
LRESULT __stdcall WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch(message) {
case WM_SIZE:
{
//íå ðåñàéçèì äåâàéñ åñëè îêíî ñâ¸ðíóòî
if(wparam != SIZE_MINIMIZED) {
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
wnd->OnResize();
}
}
}
break;
case WM_SETCURSOR:
{
static bool hiddencursor = false;
WORD ht = LOWORD(lparam);
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
if(wnd->IsCursorVisible()) {
ShowCursor(true);
} else {
if(HTCLIENT == ht && !hiddencursor) {
hiddencursor = true;
ShowCursor(false);
} else if(HTCLIENT != ht && hiddencursor) {
hiddencursor = false;
ShowCursor(true);
}
}
}
}
break;
case WM_ACTIVATEAPP:
{
//if(wparam == TRUE)
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
if(wparam!= 0) {
wnd->OnActivate();
} else {
wnd->OnDeactivate();
}
}
}
break;
case WM_ACTIVATE: //Catch Alt + Tab
{
switch(wparam) {
case WA_ACTIVE:
{
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
wnd->OnActivate();
}
}
break;
case WA_INACTIVE:
{
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
wnd->OnDeactivate();
}
}
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
DestroyWindow(hwnd);
break;
case WM_SYSKEYDOWN:
switch(wparam) {
case VK_RETURN:
{
if(GetKeyState(VK_MENU)) //Alt + Enter
{
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
if(!wnd->IsAltEnterLocked()) {
wnd->SetAltEnterLocked(true);
wnd->SwitchMode(!wnd->IsFullScreen());
}
}
}
}
break;
}
break;
case WM_SYSKEYUP:
{
switch(wparam) {
case VK_RETURN:
{
long val = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(val) {
WindowWin* wnd = (WindowWin*)val;
wnd->SetAltEnterLocked(false);
}
}
break;
}
}
break;
case WM_KEYDOWN:
switch(wparam) {
case VK_ESCAPE:
//PostQuitMessage(0);
exit(0);
break;
}
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
}