Skip to content

Instantly share code, notes, and snippets.

@kinjalkishor
Last active August 26, 2023 13:36
Show Gist options
  • Save kinjalkishor/b7b9d78f4fdd2f003f2cdd7f0aeb3082 to your computer and use it in GitHub Desktop.
Save kinjalkishor/b7b9d78f4fdd2f003f2cdd7f0aeb3082 to your computer and use it in GitHub Desktop.
Simple WinApi window class version
#if defined(_MSC_VER)
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#endif
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
//#include <wtypes.h>
#include <stdio.h>
#include "base_types.h"
#include "base_io.h"
#include "base_console.h"
#include "base_def.h"
inline const wchar_t* APP_CLASS_NAME = L"SAMPLE_APP_CLASS";
//=====================================================
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
class app_vars {
public:
bool app_quit = false;
bool app_active = true;
bool app_minimized = false;
void sys_quit() { app_quit = true; }
};
//extern app_vars g_av;
app_vars g_av;
#include <thread>
#include <chrono>
inline void sys_sleep(u32 dwMilliseconds) {
//Sleep(dwMilliseconds);
std::this_thread::sleep_for(std::chrono::milliseconds(dwMilliseconds));
}
class game_timer_qpc {
public:
float period() {
i64 cnts_per_sec = 0;
QueryPerformanceFrequency((LARGE_INTEGER*)&cnts_per_sec);
// secs_per_cnt_qpc is 0.0000001f, 1e-07;
float secs_per_cnt_qpc = 1.0f / scast<float>(cnts_per_sec);
//println("{}", secs_per_cnt_qpc);
return secs_per_cnt_qpc;
}
i64 get_time() {
// Retrieves the current value of the performance counter,
// which is a high resolution (<1 micro second) time stamp.
i64 prev_time_qpc = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prev_time_qpc);
return prev_time_qpc;
}
};
class game_timer_ch {
public:
float period() {
//using high_resolution_clock = steady_clock;
// secs_per_cnt_ch or period is 0.000000001f, 1e-09;
float secs_per_cnt_ch = scast<float>(std::chrono::high_resolution_clock::period::num)
/ scast<float>(std::chrono::high_resolution_clock::period::den);
//println("{}", secs_per_cnt_ch);
return secs_per_cnt_ch;
}
i64 get_time() {
std::chrono::high_resolution_clock::time_point prev_time_ch = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::duration duration = prev_time_ch.time_since_epoch();
//i64 time_unit = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
i64 time_unit = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
return time_unit;
}
//using high_resolution_clock = steady_clock;
//// secs_per_cnt_ch or period is 0.000000001f, 1e-09;
//float secs_per_cnt_ch = scast<float>(std::chrono::high_resolution_clock::period::num) / scast<float>(std::chrono::high_resolution_clock::period::den);
//println("{}", secs_per_cnt_ch);
//std::chrono::high_resolution_clock::time_point prev_time_ch = std::chrono::high_resolution_clock::now();
//
//std::chrono::high_resolution_clock::time_point curr_time_ch = std::chrono::high_resolution_clock::now();
//std::chrono::duration<i64, std::nano> time_span = curr_time_ch - prev_time_ch;
//float delta_time_ch = scast<float>(time_span.count())*secs_per_cnt_ch;
};
class win_app {
public:
HWND m_hwnd = nullptr;
HINSTANCE m_app_instance = nullptr;
WNDPROC m_wnd_proc = nullptr;
u32 m_win_bg_color = RGB(25, 25, 112);
wchar_t m_app_class_name[64] = {};
MSG m_msg = {};
win_app() {
m_msg.message = WM_NULL;
}
~win_app() {}
bool register_class(HINSTANCE hInstance, WNDPROC wnd_proc) {
m_app_instance = hInstance;
m_wnd_proc = wnd_proc;
wcsncpy(m_app_class_name, APP_CLASS_NAME, 64);
// register window class
WNDCLASSEX wcex = {};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_OWNDC; //must for opengl
//wcex.style = CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc = m_wnd_proc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = m_app_instance;
wcex.hIcon = LoadIconW(nullptr, IDI_APPLICATION);
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
//wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.hbrBackground = CreateSolidBrush(m_win_bg_color);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = m_app_class_name;
wcex.hIconSm = LoadIconW(nullptr, IDI_APPLICATION);
if (!RegisterClassExW(&wcex)) {
println("Cannot Register WinApi Class.");
return false;
}
return true;
}
bool create_window(const char* wnd_title, i32 xpos, i32 ypos, i32 width, i32 height) {
u32 dwStyle = 0;
u32 dwExStyle = 0;
//dwStyle = WS_POPUP|WS_VISIBLE| WS_CLIPSIBLINGS|WS_CLIPCHILDREN; //borderless
dwStyle = WS_OVERLAPPEDWINDOW|WS_VISIBLE| WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
//dwExStyle = WS_EX_APPWINDOW|WS_EX_TOPMOST; //fullscreen
dwExStyle = WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
wchar_t wstr_wnd_title[256] = {};
sdf::multi_byte_to_wide_char(wstr_wnd_title, sdf::ssize(wstr_wnd_title), wnd_title, sdf::strz_length(wnd_title));
i32 x, y, w, h;
RECT window_rect = {0, 0, width, height};
AdjustWindowRectEx(&window_rect, dwStyle, false, dwExStyle);
x = xpos + window_rect.left;
y = ypos + window_rect.top;
w = window_rect.right - window_rect.left;
h = window_rect.bottom - window_rect.top;
HWND handle_wnd = CreateWindowExW(dwExStyle,
m_app_class_name,
wstr_wnd_title,
dwStyle,
x, y, w, h,
nullptr, nullptr, m_app_instance, nullptr);
if (!handle_wnd) {
println("Cannot Create Window.");
//return false;
}
ShowWindow(handle_wnd, SW_SHOW);
UpdateWindow(handle_wnd);
SetForegroundWindow(handle_wnd);
SetFocus(handle_wnd);
m_hwnd = handle_wnd;
return true;
}
void poll_events() {
if(PeekMessageW(&m_msg, nullptr, 0, 0, PM_REMOVE)) {
TranslateMessage(&m_msg);
DispatchMessageW(&m_msg);
}
}
bool is_quit_msg() {
return (m_msg.message == WM_QUIT);
}
int msg_return() {
return scast<int>(m_msg.wParam);
}
void deinit() {
DestroyWindow(m_hwnd);
UnregisterClassW(m_app_class_name, m_app_instance);
}
};
//======================================
// WinMain
//======================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
std_console gconstd;
gconstd.create_window("NexWars Std Console", 864, 0, 640, 640);
printf("SysConsole Initialized.\n");
println("Sample app");
//------------------
// config
i32 xpos = 10;
i32 ypos = 50;
i32 width = 800;
i32 height = 450;
bool fullscreen = false;
bool borderless = false;
const char* wnd_title = "Sample window";
//------------------
win_app nw_app;
nw_app.register_class(hInstance, MainWndProc);
nw_app.create_window(wnd_title, xpos, ypos, width, height);
//----------------------------
game_timer_qpc nw_timer;
i64 prev_time_qpc = nw_timer.get_time();
//game_timer_ch nw_timer2;
//i64 prev_time_ch = nw_timer2.get_time();
// program main loop
while (!g_av.app_quit) {
//poll events
nw_app.poll_events();
if (nw_app.is_quit_msg()) { g_av.sys_quit(); }
if (g_av.app_active) {
i64 curr_time_qpc = nw_timer.get_time();
float delta_time_qpc = (curr_time_qpc - prev_time_qpc)*nw_timer.period();
//i64 curr_time_ch = nw_timer2.get_time();
//float delta_time_ch = (curr_time_ch - prev_time_ch)*nw_timer2.period()*0.001f;
//println("{:6f}, {:6f}, {:6f}", curr_time_qpc*nw_timer.period(), prev_time_qpc*nw_timer.period(), delta_time_qpc);
//println("{:6f}, {:6f}, {:6f}", curr_time_ch*nw_timer2.period(), prev_time_ch*nw_timer2.period(), delta_time_ch);
//process_input();
//rn->render(delta_time);
//rn->swap_buffers();
prev_time_qpc = curr_time_qpc;
} else {
sys_sleep(1);
continue;
}
} // while: not app_quit
nw_app.deinit();
return nw_app.msg_return();
}
//======================================
// Window Procedure
//======================================
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_ACTIVATE:
g_av.app_active = scast<bool>(LOWORD(wParam) != WA_INACTIVE);
g_av.app_minimized = scast<bool>(HIWORD(wParam));
return 0;
case WM_CREATE:
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CLOSE:
//DestroyWindow(hWnd);
PostQuitMessage(0);
return 0;
case WM_QUIT:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch (wParam) {
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
default: break;
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment