|
@@ -9,33 +9,9 @@
|
|
|
#include "../pltf.h"
|
|
#include "../pltf.h"
|
|
|
#include "DynArray.h"
|
|
#include "DynArray.h"
|
|
|
#include "DynString.h"
|
|
#include "DynString.h"
|
|
|
|
|
+#include "internal.h"
|
|
|
#include "log.h"
|
|
#include "log.h"
|
|
|
-
|
|
|
|
|
-typedef struct {
|
|
|
|
|
- HGLRC gl_ctx;
|
|
|
|
|
-} WinState;
|
|
|
|
|
-
|
|
|
|
|
-HMODULE opengl_module = NULL;
|
|
|
|
|
-
|
|
|
|
|
-static struct {
|
|
|
|
|
- const wchar_t* wc_name;
|
|
|
|
|
- HMODULE exe_module;
|
|
|
|
|
- HWND hwnd;
|
|
|
|
|
- HDC hdc;
|
|
|
|
|
- DynArray_DynString wgl_extensions;
|
|
|
|
|
- WinState window_state;
|
|
|
|
|
-} pltf_state = {
|
|
|
|
|
- .wc_name = L"Sample Window Class",
|
|
|
|
|
- .exe_module = NULL,
|
|
|
|
|
- .hwnd = NULL,
|
|
|
|
|
- .hdc = NULL,
|
|
|
|
|
- .wgl_extensions = { 0 },
|
|
|
|
|
- .window_state = (WinState) {
|
|
|
|
|
- .gl_ctx = NULL
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
|
+#include "win_proc.h"
|
|
|
|
|
|
|
|
void pltf_init() {
|
|
void pltf_init() {
|
|
|
pltf_state.exe_module = GetModuleHandle(NULL);
|
|
pltf_state.exe_module = GetModuleHandle(NULL);
|
|
@@ -62,36 +38,19 @@ void pltf_deinit() {
|
|
|
UnregisterClass(pltf_state.wc_name, pltf_state.exe_module);
|
|
UnregisterClass(pltf_state.wc_name, pltf_state.exe_module);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static bool pltf_has_wgl_extension(const DynString* name) {
|
|
|
|
|
- for (size_t i = 0; i < pltf_state.wgl_extensions.len; i++) {
|
|
|
|
|
- if (DynString_equal(name, DynArray_DynString_at(&pltf_state.wgl_extensions, i))) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return false;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static bool pltf_has_wgl_extension_c_str(const char* name) {
|
|
|
|
|
- DynString name_dstr = DynString_alloc(name, strlen(name));
|
|
|
|
|
- const bool res = pltf_has_wgl_extension(&name_dstr);
|
|
|
|
|
- DynString_free(&name_dstr);
|
|
|
|
|
- return res;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
void pltf_window_create() {
|
|
void pltf_window_create() {
|
|
|
// Create the window
|
|
// Create the window
|
|
|
pltf_state.hwnd = CreateWindowEx(
|
|
pltf_state.hwnd = CreateWindowEx(
|
|
|
0, // Optional window styles
|
|
0, // Optional window styles
|
|
|
- pltf_state.wc_name, // Window class
|
|
|
|
|
|
|
+ pltf_state.wc_name, // Window class
|
|
|
L"Learn to Program Windows", // Window text
|
|
L"Learn to Program Windows", // Window text
|
|
|
WS_OVERLAPPEDWINDOW, // Window style
|
|
WS_OVERLAPPEDWINDOW, // Window style
|
|
|
|
|
|
|
|
// Size and position
|
|
// Size and position
|
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
|
|
|
|
|
|
- NULL, // Parent window
|
|
|
|
|
- NULL, // Menu
|
|
|
|
|
|
|
+ NULL, // Parent window
|
|
|
|
|
+ NULL, // Menu
|
|
|
pltf_state.exe_module, // Instance handle
|
|
pltf_state.exe_module, // Instance handle
|
|
|
&pltf_state.window_state // Additional application data
|
|
&pltf_state.window_state // Additional application data
|
|
|
);
|
|
);
|
|
@@ -108,6 +67,10 @@ void pltf_window_create() {
|
|
|
ShowWindow(pltf_state.hwnd, SW_SHOWDEFAULT);
|
|
ShowWindow(pltf_state.hwnd, SW_SHOWDEFAULT);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void pltf_window_close() {
|
|
|
|
|
+ PostMessage(pltf_state.hwnd, WM_CLOSE, 0, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void pltf_window_destroy() {
|
|
void pltf_window_destroy() {
|
|
|
if (pltf_state.hwnd != NULL) {
|
|
if (pltf_state.hwnd != NULL) {
|
|
|
DestroyWindow(pltf_state.hwnd);
|
|
DestroyWindow(pltf_state.hwnd);
|
|
@@ -288,63 +251,37 @@ void pltf_swap_buffers() {
|
|
|
|
|
|
|
|
PltfWindowEvent pltf_window_event_handle() {
|
|
PltfWindowEvent pltf_window_event_handle() {
|
|
|
MSG msg = { 0 };
|
|
MSG msg = { 0 };
|
|
|
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
|
|
|
+ if (PeekMessage(&msg, pltf_state.hwnd, 0, 0, PM_REMOVE)) {
|
|
|
TranslateMessage(&msg);
|
|
TranslateMessage(&msg);
|
|
|
DispatchMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
|
- if (msg.message == WM_QUIT) {
|
|
|
|
|
- return PLTF_WE_QUIT;
|
|
|
|
|
|
|
+ switch (msg.message) {
|
|
|
|
|
+ case WM_DESTROY:
|
|
|
|
|
+ return PLTF_WE_DESTROY;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return PLTF_WE_NULL;
|
|
return PLTF_WE_NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
|
|
|
|
- WinState* pState = NULL;
|
|
|
|
|
- if (uMsg == WM_CREATE) {
|
|
|
|
|
- CREATESTRUCT* pCreate = (CREATESTRUCT*) lParam;
|
|
|
|
|
- pState = (WinState*) pCreate->lpCreateParams;
|
|
|
|
|
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pState);
|
|
|
|
|
- } else {
|
|
|
|
|
- LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
|
- pState = (WinState*) ptr;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- switch (uMsg) {
|
|
|
|
|
- // case WM_LBUTTONDOWN: {
|
|
|
|
|
- // printf("State: msg: %s, num: %d\n", pState->msg, pState->num);
|
|
|
|
|
- //
|
|
|
|
|
- // printf("lParam: %llx\n", lParam);
|
|
|
|
|
- // int mouse_x = GET_X_LPARAM(lParam);
|
|
|
|
|
- // printf("mouse_x: %x\n", mouse_x);
|
|
|
|
|
- // int mouse_y = GET_Y_LPARAM(lParam);
|
|
|
|
|
- // printf("mouse_y: %x\n", mouse_y);
|
|
|
|
|
- // printf("x: %d y: %d\n", mouse_x, mouse_y);
|
|
|
|
|
- //
|
|
|
|
|
- // return 0;
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- case WM_CREATE: {
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+#define PLTF_KEYS_X(lower, upper) \
|
|
|
|
|
+ case PLTF_KEY_##upper: { \
|
|
|
|
|
+ pltf_state.key_##lower##_cb = cb; \
|
|
|
|
|
+ pltf_state.key_##lower##_cb_user_data = (void*) user_data; \
|
|
|
|
|
+ break; \
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- case WM_KEYDOWN:
|
|
|
|
|
- if (wParam == VK_ESCAPE) {
|
|
|
|
|
- PostMessage(hwnd, WM_DESTROY, 0, 0);
|
|
|
|
|
- }
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+void pltf_key_callback_set(
|
|
|
|
|
+ const PltfKey key,
|
|
|
|
|
+ const PltfKeyCallback cb,
|
|
|
|
|
+ const void* user_data
|
|
|
|
|
+) {
|
|
|
|
|
|
|
|
- case WM_DESTROY:
|
|
|
|
|
- wglDeleteContext(pState->gl_ctx);
|
|
|
|
|
- PostQuitMessage(0);
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ switch (key) {
|
|
|
|
|
+ case PLTF_KEY_NONE:
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- case WM_CLOSE:
|
|
|
|
|
- if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) {
|
|
|
|
|
- DestroyWindow(hwnd);
|
|
|
|
|
- }
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ PLTF_KEYS(PLTF_KEYS_X);
|
|
|
}
|
|
}
|
|
|
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#undef PLTF_KEYS_X
|