From debe52c1e0fbbe68a944a00e287318294aefd1fc Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Tue, 9 Feb 2021 18:09:44 +0300 Subject: [PATCH] Added scalable window, mouse controls. --- SpaceCadetPinball/SpaceCadetPinball.rc | 4 ++ SpaceCadetPinball/fullscrn.cpp | 59 ++++++++++++++++--- SpaceCadetPinball/fullscrn.h | 5 ++ SpaceCadetPinball/gdrv.cpp | 78 ++++++++++++++++++++------ SpaceCadetPinball/gdrv.h | 8 ++- SpaceCadetPinball/options.cpp | 18 ++++-- SpaceCadetPinball/options.h | 1 + SpaceCadetPinball/render.cpp | 40 +++++-------- SpaceCadetPinball/resource.h | 3 +- SpaceCadetPinball/winmain.cpp | 55 +++++++++++++----- SpaceCadetPinball/winmain.h | 2 + 11 files changed, 200 insertions(+), 73 deletions(-) diff --git a/SpaceCadetPinball/SpaceCadetPinball.rc b/SpaceCadetPinball/SpaceCadetPinball.rc index 18b9fc2..93754b9 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.rc +++ b/SpaceCadetPinball/SpaceCadetPinball.rc @@ -95,6 +95,10 @@ BEGIN MENUITEM "&800 x 600", Menu1_800x600 MENUITEM "&1024 x 768", Menu1_1024x768 END + POPUP "&Window" + BEGIN + MENUITEM "&Uniform Scaling", Menu1_WindowUniformScale + END END POPUP "&Help" BEGIN diff --git a/SpaceCadetPinball/fullscrn.cpp b/SpaceCadetPinball/fullscrn.cpp index 367f7e7..6d4aa6f 100644 --- a/SpaceCadetPinball/fullscrn.cpp +++ b/SpaceCadetPinball/fullscrn.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "fullscrn.h" + +#include "options.h" #include "pb.h" #include "render.h" #include "winmain.h" @@ -24,6 +26,10 @@ const resolution_info fullscrn::resolution_array[3] = {800, 600, 752, 520, 502}, {1024, 768, 960, 666, 503}, }; +float fullscrn::ScaleX = 1; +float fullscrn::ScaleY = 1; +float fullscrn::OffsetX = 0; +float fullscrn::OffsetY = 0; void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay) { @@ -46,15 +52,21 @@ void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HME WindowRect2.right = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2 + widht2 + 4; WindowRect2.left = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2; WindowRect2.top = borderHeight / 2 - (captionHeight + menuHeight) - 2; + + /*RECT client{0,0,width,height}; + AdjustWindowRect(&client, winmain::WndStyle, true);*/ MoveWindow( hWnd, (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2, WindowRect2.top, - widht2 + 4 + 10, + WindowRect2.right - WindowRect2.left + 10, WindowRect2.bottom - WindowRect2.top + 10, 0); // Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480 fullscrn_flag1 = 0; + + window_size_changed(); + assertm(ScaleX == 1 && ScaleY == 1, "Wrong default client size"); } void fullscrn::shutdown() @@ -94,13 +106,13 @@ int fullscrn::set_screen_mode(int isFullscreen) int fullscrn::disableWindowFlagsDisDlg() { long style = GetWindowLongA(hWnd, -16); - return SetWindowLongA(hWnd, -16, style & 0xFF3FFFFF); + return SetWindowLongA(hWnd, -16, style & ~(WS_CAPTION | WS_THICKFRAME)); } int fullscrn::setWindowFlagsDisDlg() { int style = GetWindowLongA(hWnd, -16); - return SetWindowLongA(hWnd, -16, style | 0xC00000); + return SetWindowLongA(hWnd, -16, style | WS_CAPTION | WS_THICKFRAME); } int fullscrn::enableFullscreen() @@ -339,10 +351,12 @@ unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY) void fullscrn::getminmaxinfo(MINMAXINFO* maxMin) { - maxMin->ptMaxSize.x = WindowRect2.right - WindowRect2.left; - maxMin->ptMaxSize.y = WindowRect2.bottom - WindowRect2.top; - maxMin->ptMaxPosition.x = WindowRect2.left; - maxMin->ptMaxPosition.y = WindowRect2.top; + /*Block down-scaling lower than min resolution*/ + maxMin->ptMinTrackSize = POINT + { + resolution_array[0].ScreenWidth / 2, + resolution_array[0].ScreenHeight / 2 + }; } void fullscrn::paint() @@ -419,3 +433,34 @@ int fullscrn::get_screen_resolution() auto height = static_cast(GetSystemMetrics(SM_CYSCREEN)); return static_cast(GetSystemMetrics(SM_CXSCREEN)) | (height << 16); } + +void fullscrn::window_size_changed() +{ + /*No scaling in fullscreen mode*/ + if (display_changed) + { + ScaleY = ScaleX = 1; + OffsetX = OffsetY = 0; + return; + } + + RECT client{}; + GetClientRect(hWnd, &client); + auto res = &resolution_array[resolution]; + ScaleX = static_cast(client.right) / res->TableWidth; + ScaleY = static_cast(client.bottom) / res->TableHeight; + OffsetX = OffsetY = 0; + + if (options::Options.UniformScaling) + { + ScaleY = ScaleX = min(ScaleX, ScaleY); + OffsetX = floor((client.right - res->TableWidth * ScaleX) / 2); + OffsetY = floor((client.bottom - res->TableHeight * ScaleY) / 2); + auto dc = GetDC(hWnd); + if (dc) + { + BitBlt(dc, 0, 0, client.right, client.bottom, dc, 0, 0, BLACKNESS); + ReleaseDC(hWnd, dc); + } + } +} diff --git a/SpaceCadetPinball/fullscrn.h b/SpaceCadetPinball/fullscrn.h index 4be2643..4f924a7 100644 --- a/SpaceCadetPinball/fullscrn.h +++ b/SpaceCadetPinball/fullscrn.h @@ -28,6 +28,10 @@ public: static int ChangeDisplay, SmthFullScrnFlag2; static int trick; static const resolution_info resolution_array[3]; + static float ScaleX; + static float ScaleY; + static float OffsetX; + static float OffsetY; static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay); static void shutdown(); @@ -46,6 +50,7 @@ public: static void SetMaxResolution(int resolution); static int get_max_supported_resolution(); static int get_screen_resolution(); + static void window_size_changed(); private : static int MenuEnabled; static HMENU MenuHandle; diff --git a/SpaceCadetPinball/gdrv.cpp b/SpaceCadetPinball/gdrv.cpp index 8820e64..a3b20da 100644 --- a/SpaceCadetPinball/gdrv.cpp +++ b/SpaceCadetPinball/gdrv.cpp @@ -1,5 +1,7 @@ #include "pch.h" #include "gdrv.h" + +#include "fullscrn.h" #include "memory.h" #include "pinball.h" #include "winmain.h" @@ -252,19 +254,20 @@ int gdrv::destroy_bitmap(gdrv_bitmap8* bmp) return 0; } -UINT gdrv::start_blit_sequence() +void gdrv::start_blit_sequence() { HDC dc = winmain::_GetDC(hwnd); sequence_handle = 0; sequence_hdc = dc; SelectPalette(dc, palette_handle, 0); - return RealizePalette(sequence_hdc); + RealizePalette(sequence_hdc); + SetStretchBltMode(dc, stretchMode); } void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight) { if (!use_wing) - StretchDIBits( + StretchDIBitsScaled( sequence_hdc, xDest, yDest, @@ -274,10 +277,10 @@ void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, in bmp->Height - ySrcOff - DestHeight, DestWidth, DestHeight, - bmp->BmpBufPtr1, - bmp->Dib, - 1u, - SRCCOPY); + bmp, + DIB_PAL_COLORS, + SRCCOPY + ); } @@ -289,12 +292,13 @@ void gdrv::end_blit_sequence() void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight) { HDC dc = winmain::_GetDC(hwnd); + SetStretchBltMode(dc, stretchMode); if (dc) { SelectPalette(dc, palette_handle, 0); RealizePalette(dc); if (!use_wing) - StretchDIBits( + StretchDIBitsScaled( dc, xDest, yDest, @@ -304,10 +308,10 @@ void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, bmp->Height - ySrcOff - DestHeight, DestWidth, DestHeight, - bmp->BmpBufPtr1, - bmp->Dib, - 1u, - SRCCOPY); + bmp, + DIB_PAL_COLORS, + SRCCOPY + ); ReleaseDC(hwnd, dc); } } @@ -317,8 +321,9 @@ void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest) HDC dc = winmain::_GetDC(hwnd); SelectPalette(dc, palette_handle, 0); RealizePalette(dc); + SetStretchBltMode(dc, stretchMode); if (!use_wing) - StretchDIBits( + StretchDIBitsScaled( dc, xDest, yDest, @@ -328,10 +333,10 @@ void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest) 0, bmp->Width, bmp->Height, - bmp->BmpBufPtr1, - bmp->Dib, - 1u, - SRCCOPY); + bmp, + DIB_PAL_COLORS, + SRCCOPY + ); ReleaseDC(hwnd, dc); } @@ -416,3 +421,42 @@ void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, SetTextColor(dc, color); ReleaseDC(hwnd, dc); } + +int gdrv::StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, + int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage, + DWORD rop) +{ + /*Scaled partial updates may leave 1px border artifacts around update area. + * Pad update area to compensate.*/ + const int pad = 1, padX2 = pad * 2; + if (fullscrn::ScaleX > 1 && xSrc > pad && xSrc + pad < bmp->Width) + { + xSrc -= pad; + xDest -= pad; + SrcWidth += padX2; + DestWidth += padX2; + } + + if (fullscrn::ScaleY > 1 && ySrc > pad && ySrc + pad < bmp->Height) + { + ySrc -= pad; + yDest -= pad; + SrcHeight += padX2; + DestHeight += padX2; + } + + return StretchDIBits( + hdc, + static_cast(round(xDest * fullscrn::ScaleX + fullscrn::OffsetX)), + static_cast(round(yDest * fullscrn::ScaleY + fullscrn::OffsetY)), + static_cast(round(DestWidth * fullscrn::ScaleX)), + static_cast(round(DestHeight * fullscrn::ScaleY)), + xSrc, + ySrc, + SrcWidth, + SrcHeight, + bmp->BmpBufPtr1, + bmp->Dib, + iUsage, + rop); +} diff --git a/SpaceCadetPinball/gdrv.h b/SpaceCadetPinball/gdrv.h index 8cf5416..11892f7 100644 --- a/SpaceCadetPinball/gdrv.h +++ b/SpaceCadetPinball/gdrv.h @@ -53,7 +53,7 @@ public: static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size); static int destroy_bitmap(gdrv_bitmap8* bmp); static int display_palette(PALETTEENTRY* plt); - static UINT start_blit_sequence(); + static void start_blit_sequence(); static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight); static void end_blit_sequence(); @@ -66,9 +66,15 @@ public: gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff); static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6); private: + /*COLORONCOLOR or HALFTONE*/ + static const int stretchMode = COLORONCOLOR; static HWND hwnd; static HINSTANCE hinst; static int grtext_blue; static int grtext_green; static int grtext_red; + + static int StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, + int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage, + DWORD rop); }; diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index df508b1..5d2da3c 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -12,7 +12,7 @@ LPCSTR options::OptionsRegPath; LPSTR options::OptionsRegPathCur; HMENU options::MenuHandle; -optionsStruct options::Options; +optionsStruct options::Options{}; winhelp_entry options::keymap_help[18] { @@ -107,6 +107,7 @@ void options::init(HMENU menuHandle) Options.LeftTableBumpKey = get_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey); Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey); Options.BottomTableBumpKey = get_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey); + Options.UniformScaling = get_int(nullptr, "Uniform scaling", true); menu_check(Menu1_Sounds, Options.Sounds); Sound::Enable(0, 7, Options.Sounds); menu_check(Menu1_Music, Options.Music); @@ -115,6 +116,7 @@ void options::init(HMENU menuHandle) menu_check(Menu1_2Players, Options.Players == 2); menu_check(Menu1_3Players, Options.Players == 3); menu_check(Menu1_4Players, Options.Players == 4); + menu_check(Menu1_WindowUniformScale, Options.UniformScaling); auto tmpBuf = memory::allocate(0x1F4u); if (tmpBuf) { @@ -146,6 +148,7 @@ void options::uninit() set_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey); set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey); set_int(nullptr, "Screen Resolution", Options.Resolution); + set_int(nullptr, "Uniform scaling", Options.UniformScaling); } void options::path_init(LPCSTR regPath) @@ -315,10 +318,9 @@ void options::toggle(UINT uIDCheckItem) case Menu1_800x600: case Menu1_1024x768: { - menu_check(500u, uIDCheckItem == 500); - menu_check(501u, uIDCheckItem == 501); - menu_check(502u, uIDCheckItem == 502); - menu_check(503u, uIDCheckItem == 503); + for (unsigned i = Menu1_MaximumResolution; i <= Menu1_1024x768; ++i) + menu_check(i, i == uIDCheckItem); + int newResolution = uIDCheckItem - Menu1_640x480; if (uIDCheckItem == Menu1_MaximumResolution) { @@ -333,6 +335,12 @@ void options::toggle(UINT uIDCheckItem) } break; } + case Menu1_WindowUniformScale: + Options.UniformScaling ^= true; + menu_check(Menu1_WindowUniformScale, Options.UniformScaling); + fullscrn::window_size_changed(); + fullscrn::paint(); + break; default: break; } diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index 8e4a17f..c7c94da 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -22,6 +22,7 @@ struct optionsStruct int RightTableBumpKeyDft; int BottomTableBumpKeyDft; int Resolution; + bool UniformScaling; }; diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp index 8cf21fb..61eeb7b 100644 --- a/SpaceCadetPinball/render.cpp +++ b/SpaceCadetPinball/render.cpp @@ -473,35 +473,21 @@ void render::paint_balls() void render::unpaint_balls() { - auto ballPtr = &ball_list[many_balls - 1]; - if (many_balls - 1 >= 0) + for (int index = many_balls-1; index >= 0; index--) { - gdrv_bitmap8* bitmapPtr = &ball_bitmap[many_balls - 1]; - for (int index = many_balls; index > 0; index--) - { - struct render_sprite_type_struct* curBall = *ballPtr; - rectangle_type* rect2 = &(*ballPtr)->DirtyRect; - int width = (*ballPtr)->DirtyRect.Width; - if (width > 0) - gdrv::copy_bitmap( - &vscreen, - width, - (*ballPtr)->DirtyRect.Height, - (*ballPtr)->DirtyRect.XPosition, - (*ballPtr)->DirtyRect.YPosition, - bitmapPtr, - 0, - 0); + auto curBall = ball_list[index]; + if (curBall->DirtyRect.Width > 0) + gdrv::copy_bitmap( + &vscreen, + curBall->DirtyRect.Width, + curBall->DirtyRect.Height, + curBall->DirtyRect.XPosition, + curBall->DirtyRect.YPosition, + &ball_bitmap[index], + 0, + 0); - rectangle_type* rectCopy = &curBall->BmpRectCopy; - rectCopy->XPosition = rect2->XPosition; - rectCopy->YPosition = rect2->YPosition; - rectCopy->Width = rect2->Width; - rectCopy->Height = rect2->Height; - - --ballPtr; - --bitmapPtr; - } + curBall->BmpRectCopy = curBall->DirtyRect; } } diff --git a/SpaceCadetPinball/resource.h b/SpaceCadetPinball/resource.h index 7b93141..5ba7890 100644 --- a/SpaceCadetPinball/resource.h +++ b/SpaceCadetPinball/resource.h @@ -234,6 +234,7 @@ #define Menu1_1024x768 503 #define DLG_HIGHSCORES_Score4 504 #define DLG_HIGHSCORES_Score5 505 +#define Menu1_WindowUniformScale 600 #define DLG_HIGHSCORES_EditName1 601 #define DLG_HIGHSCORES_EditName2 602 #define DLG_HIGHSCORES_EditName3 603 @@ -245,7 +246,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 204 -#define _APS_NEXT_COMMAND_VALUE 40004 +#define _APS_NEXT_COMMAND_VALUE 40006 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 104 #endif diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 5023fe5..1c15267 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -146,26 +146,27 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi picce.dwICC = 5885; InitCommonControlsEx(&picce); - WNDCLASSA WndClass{}; - WndClass.style = 4104; - WndClass.lpfnWndProc = message_handler; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = hInstance; - WndClass.hIcon = LoadIconA(hInstance, "ICON_1"); - WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); - WndClass.hbrBackground = (HBRUSH)16; - WndClass.lpszMenuName = "MENU_1"; - WndClass.lpszClassName = windowClass; + WNDCLASSEXA wndClass{}; + wndClass.cbSize = sizeof wndClass; + wndClass.style = CS_DBLCLKS | CS_BYTEALIGNCLIENT; + wndClass.lpfnWndProc = message_handler; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = hInstance; + wndClass.hIcon = LoadIconA(hInstance, "ICON_1"); + wndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); + wndClass.hbrBackground = (HBRUSH)16; + wndClass.lpszMenuName = "MENU_1"; + wndClass.lpszClassName = windowClass; auto splash = splash::splash_screen(hInstance, "splash_bitmap", "splash_bitmap"); - RegisterClassA(&WndClass); + RegisterClassExA(&wndClass); pinball::FindShiftKeys(); options::init_resolution(); char windowName[40]; - lstrcpyA(windowName, pinball::get_rc_string(38, 0)); - windowHandle = CreateWindowExA(0, windowClass, windowName, 0x3CA0000u, 0, 0, 640, 480, nullptr, nullptr, hInstance, + lstrcpyA(windowName, pinball::get_rc_string(38, 0)); + windowHandle = CreateWindowExA(0, windowClass, windowName, WndStyle, 0, 0, 640, 480, nullptr, nullptr, hInstance, nullptr); hwnd_frame = windowHandle; if (!windowHandle) @@ -437,6 +438,11 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP return DefWindowProcA(hWnd, Msg, wParam, lParam); case WM_ERASEBKGND: break; + case WM_SIZE: + fullscrn::window_size_changed(); + fullscrn::force_redraw(); + pb::paint(); + return DefWindowProcA(hWnd, Msg, wParam, lParam); default: return DefWindowProcA(hWnd, Msg, wParam, lParam); } @@ -595,6 +601,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP case Menu1_640x480: case Menu1_800x600: case Menu1_1024x768: + case Menu1_WindowUniformScale: options::toggle(wParam); break; case Menu1_Help_Topics: @@ -653,6 +660,9 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP last_mouse_y = mouseXY >> 16; SetCapture(hWnd); } + else + pb::keydown(options::Options.LeftFlipperKey); + return DefWindowProcA(hWnd, Msg, wParam, lParam); } break; @@ -663,12 +673,27 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP SetCursor(mouse_hsave); ReleaseCapture(); } + if (!pb::cheat_mode) + pb::keyup(options::Options.LeftFlipperKey); return DefWindowProcA(hWnd, Msg, wParam, lParam); case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: + if (!pb::cheat_mode) + pb::keydown(options::Options.RightFlipperKey); if (pb::game_mode) return DefWindowProcA(hWnd, Msg, wParam, lParam); break; + case WM_RBUTTONUP: + if (!pb::cheat_mode) + pb::keyup(options::Options.RightFlipperKey); + return DefWindowProcA(hWnd, Msg, wParam, lParam); + case WM_MBUTTONDOWN: + pb::keydown(options::Options.PlungerKey); + if (pb::game_mode) + return DefWindowProcA(hWnd, Msg, wParam, lParam); + break; + case WM_MBUTTONUP: + pb::keyup(options::Options.PlungerKey); + return DefWindowProcA(hWnd, Msg, wParam, lParam); case WM_POWERBROADCAST: if (wParam == 4 && options::Options.FullScreen) { diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h index 6914745..ff49949 100644 --- a/SpaceCadetPinball/winmain.h +++ b/SpaceCadetPinball/winmain.h @@ -4,6 +4,8 @@ class winmain { public: + static const DWORD WndStyle = WS_GROUP | WS_SYSMENU | WS_DLGFRAME | WS_BORDER | WS_MAXIMIZE | WS_CLIPCHILDREN | + WS_THICKFRAME | WS_MAXIMIZEBOX; static char DatFileName[300]; static int single_step; static HINSTANCE hinst;