mudgangster

Log | Files | Refs

commit 7a03a1ff4d2684f6d104f8693850bcf3c7b1ff73
parent 6e126f8e3b25c50d3d829a2cec9138458bd3dc29
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Thu,  6 Sep 2018 13:18:45 +0300

Proper painting and double buffering

Diffstat:
src/win32.cc | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 54 insertions(+), 14 deletions(-)

diff --git a/src/win32.cc b/src/win32.cc @@ -16,10 +16,14 @@ struct { HWND hwnd; HDC hdc; + HDC back_buffer; + HBITMAP back_buffer_bitmap; + TextBox main_text; TextBox chat_text; int width, height; + int max_width, max_height; bool has_focus; } UI; @@ -151,11 +155,17 @@ static COLORREF get_colour( Colour colour, bool bold ) { return Style.colours[ bold ][ colour ]; } +static void make_dirty( int left, int top, int width, int height ) { + RECT r = { left, top, left + width, top + height }; + InvalidateRect( UI.hwnd, &r, FALSE ); +} + void ui_fill_rect( int left, int top, int width, int height, Colour colour, bool bold ) { HBRUSH brush = CreateSolidBrush( get_colour( colour, bold ) ); RECT r = { left, top, left + width, top + height }; - FillRect( UI.hdc, &r, brush ); + FillRect( UI.back_buffer, &r, brush ); DeleteObject( brush ); + make_dirty( left, top, width, height ); } void ui_draw_char( int left, int top, char c, Colour colour, bool bold, bool force_bold_font ) { @@ -312,9 +322,11 @@ void ui_draw_char( int left, int top, char c, Colour colour, bool bold, bool for return; } - SelectObject( UI.hdc, ( bold || force_bold_font ? Style.bold_font : Style.font ).font ); - SetTextColor( UI.hdc, get_colour( colour, bold ) ); - TextOutA( UI.hdc, left, top + SPACING, &c, 1 ); + SelectObject( UI.back_buffer, ( bold || force_bold_font ? Style.bold_font : Style.font ).font ); + SetTextColor( UI.back_buffer, get_colour( colour, bold ) ); + TextOutA( UI.back_buffer, left, top + SPACING, &c, 1 ); + + make_dirty( left, top, Style.font.width, Style.font.height + SPACING ); } typedef struct { @@ -427,7 +439,9 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_CREATE: { UI.hdc = GetDC( hwnd ); - SetBkMode( UI.hdc, TRANSPARENT ); + UI.back_buffer = CreateCompatibleDC( UI.hdc ); + + SetBkMode( UI.back_buffer, TRANSPARENT ); Style.font.font = CreateFont( 14, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, DEFAULT_CHARSET, @@ -481,6 +495,20 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { if( UI.width == old_width && UI.height == old_height ) break; + int old_max_width = UI.max_width; + int old_max_height = UI.max_height; + + UI.max_width = max( UI.max_width, UI.width ); + UI.max_height = max( UI.max_height, UI.height ); + + if( UI.max_width != old_max_width || UI.max_height != old_max_height ) { + if( old_width != -1 ) { + DeleteObject( UI.back_buffer_bitmap ); + } + UI.back_buffer_bitmap = CreateCompatibleBitmap( UI.hdc, UI.max_width, UI.max_height ); + SelectObject( UI.back_buffer, UI.back_buffer_bitmap ); + } + textbox_set_pos( &UI.chat_text, PADDING, PADDING ); textbox_set_size( &UI.chat_text, UI.width - ( 2 * PADDING ), ( Style.font.height + SPACING ) * CHAT_ROWS ); @@ -493,6 +521,18 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { ui_draw(); } break; + case WM_PAINT: { + RECT r; + GetUpdateRect( UI.hwnd, &r, FALSE ); + PAINTSTRUCT ps; + HDC hdc = BeginPaint( UI.hwnd, &ps ); + BitBlt( UI.hdc, r.left, r.top, r.right - r.left, r.bottom - r.top, UI.back_buffer, r.left, r.top, SRCCOPY ); + EndPaint( UI.hwnd, &ps ); + } break; + + case WM_ERASEBKGND: + return TRUE; + case WM_LBUTTONDOWN: { // char szFileName[MAX_PATH]; // HINSTANCE hInstance = GetModuleHandle(NULL); @@ -522,10 +562,10 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { } break; case WM_CHAR: { - if( wParam >= ' ' && wParam < 128 ) { + if( wParam >= ' ' && wParam < 127 ) { char c = wParam; input_add( &c, 1 ); - ui_draw(); + draw_input(); } } break; @@ -543,37 +583,37 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( wParam ) { case VK_BACK: input_backspace(); - ui_draw(); + draw_input(); break; case VK_DELETE: input_delete(); - ui_draw(); + draw_input(); break; case VK_RETURN: input_return(); - ui_draw(); + draw_input(); break; case VK_LEFT: input_left(); - ui_draw(); + draw_input(); break; case VK_RIGHT: input_right(); - ui_draw(); + draw_input(); break; case VK_UP: input_up(); - ui_draw(); + draw_input(); break; case VK_DOWN: input_down(); - ui_draw(); + draw_input(); break; case VK_PRIOR: