#include "win32.h"
#include "../application/win32.h"
#include "../debug.h"
#include "../win32.h"
#include "../window.h"
#include <stdio.h>
#include <stdlib.h>
void bw_Window_cleanup( bw_Window* window );
void _bw_Window_destroy( bw_Window* window, void* data );
BOOL CALLBACK bw_Window_hideChild( HWND handle, LPARAM lparam );
void _bw_Window_resize( bw_Window* window );
void bw_Window_free( bw_Window* window ) {
window->callbacks.do_cleanup( window );
bw_Application* app = window->app;
app->windows_alive -= 1;
free( window );
if ( app->windows_alive == 0 )
bw_Application_exit( app, 0 );
}
void bw_Window_close( bw_Window* window ) {
if ( window->callbacks.on_close != 0 )
window->callbacks.on_close( window );
ShowWindow( window->handle, SW_HIDE );
EnumChildWindows( window->handle, bw_Window_hideChild, 0 );
window->closed = true;
}
void bw_Window_drop( bw_Window* window ) {
bw_Window_dispatch( window, _bw_Window_destroy, 0 );
}
void _bw_Window_destroy( bw_Window* window, void* data ) {
if ( window->closed ) {
if ( !DestroyWindow( window->handle ) )
BW_WIN32_ASSERT_ERROR;
}
else {
window->destroy_on_close = true;
}
}
void bw_Window_dispatch( bw_Window* window, bw_WindowDispatchFn f, void* data ) {
bw_WindowDispatchData* param = malloc( sizeof( bw_WindowDispatchData ) );
param->func = f;
param->window = window;
param->data = data;
if ( !PostThreadMessageW( window->app->thread_id, WM_APP + 1, 0, (LPARAM)param ) ) {
free( param );
BW_WIN32_ASSERT_ERROR;
}
}
BOOL CALLBACK bw_Window_hideChild( HWND handle, LPARAM _ ) {
ShowWindow( handle, SW_HIDE );
return true;
}
LRESULT CALLBACK bw_Window_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
bw_Window* window = (bw_Window*)GetWindowLongPtrW( hwnd, GWLP_USERDATA );
switch (msg) {
case WM_SIZE:
RECT rect;
GetClientRect( window->handle, &rect );
if ( window->callbacks.on_resize != 0 ) {
unsigned int width = rect.right - rect.left;
unsigned int height = rect.bottom - rect.top;
window->callbacks.on_resize( window, width, height );
}
break;
break;
case WM_CLOSE:
if ( window->destroy_on_close )
DestroyWindow( hwnd );
else
bw_Window_close( window );
break;
case WM_NCDESTROY:
bw_Window_free( window );
break;
default:
return DefWindowProcW(hwnd, msg, wp, lp);
}
return 0;
}
bw_Window* bw_Window_new(
bw_Application* app,
const bw_Window* parent,
bw_CStrSlice _title,
int width, int height,
const bw_WindowOptions* options,
void* user_data
) {
bw_Window* window = (bw_Window*)malloc( sizeof( bw_Window ) );
window->app = app;
window->closed = false;
window->destroy_on_close = false;
window->user_data = user_data;
memset( &window->callbacks, 0, sizeof( bw_WindowCallbacks ) );
DWORD window_style = WS_OVERLAPPEDWINDOW;
if ( !options->borders )
window_style ^= WS_BORDER;
if ( !options->resizable )
window_style ^= WS_SIZEBOX;
if ( !options->minimizable )
window_style ^= WS_MINIMIZEBOX;
if ( !options->maximizable )
window_style ^= WS_MAXIMIZEBOX;
wchar_t* title = bw_win32_copyAsNewWstr( _title );
window->handle = CreateWindowExW( 0,
L"browser_window",
title,
window_style,
0, 0,
width,
height,
(parent == 0 ? HWND_DESKTOP : parent->handle),
NULL,
app->handle,
(void*)window
);
free( title );
if ( window->handle == NULL ) {
BW_WIN32_ASSERT_ERROR;
}
SetWindowLongPtr( window->handle, GWLP_USERDATA, (LONG_PTR)window );
ShowWindow( window->handle, SW_SHOW );
app->windows_alive += 1;
return window;
}