diff --git a/AboutDlg.c b/AboutDlg.c new file mode 100644 index 0000000..437d7ae --- /dev/null +++ b/AboutDlg.c @@ -0,0 +1,43 @@ +#include "aboutdlg.h" +#include "resource.h" +#include "globals.h" + +/* Dialog procedure for our "about" dialog */ +BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_COMMAND: + { + WORD id = wParam; + + switch (id) + { + case IDOK: + case IDCANCEL: + { + EndDialog(hwndDlg, id); + return TRUE; + } + } + break; + } + + case WM_INITDIALOG: + return TRUE; + } + + return FALSE; +} + +/* Show our "about" dialog */ +void ShowAboutDialog(HWND owner) +{ + /* Create dialog callback thunk */ + FARPROC aboutProc = MakeProcInstance(&AboutDialogProc, g_hInstance); + + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), owner, aboutProc); + + /* Free dialog callback thunk */ + FreeProcInstance(aboutProc); +} diff --git a/AboutDlg.h b/AboutDlg.h new file mode 100644 index 0000000..a326bb6 --- /dev/null +++ b/AboutDlg.h @@ -0,0 +1,12 @@ +#ifndef ABOUTDLG_H +#define ABOUTDLG_H + +#include + +/* Dialog procedure for our "about" dialog */ +BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* Show our "about" dialog */ +void ShowAboutDialog(HWND owner); + +#endif diff --git a/Globals.h b/Globals.h new file mode 100644 index 0000000..cfc8d20 --- /dev/null +++ b/Globals.h @@ -0,0 +1,9 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include + +/* Global instance handle */ +extern HINSTANCE g_hInstance; + +#endif diff --git a/MainWnd.c b/MainWnd.c new file mode 100644 index 0000000..f07c0a0 --- /dev/null +++ b/MainWnd.c @@ -0,0 +1,116 @@ +#include "mainwnd.h" +#include "aboutdlg.h" +#include "resource.h" +#include "globals.h" + +/* Main window class and title */ +static const char MainWndClass[] = "Win16 Example Application"; + +/* Window procedure for our main window */ +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_COMMAND: + { + WORD id = wParam; + + switch (id) + { + case ID_HELP_ABOUT: + { + ShowAboutDialog(hWnd); + break; + } + + case ID_FILE_EXIT: + { + DestroyWindow(hWnd); + break; + } + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + break; + } + + case WM_GETMINMAXINFO: + { + /* Prevent our window from being sized too small */ + MINMAXINFO *minMax = (MINMAXINFO*) lParam; + minMax->ptMinTrackSize.x = 220; + minMax->ptMinTrackSize.y = 110; + + break; + } + + /* Item from system menu has been invoked */ + case WM_SYSCOMMAND: + { + WORD id = wParam; + + switch (id) + { + case ID_HELP_ABOUT: + { + ShowAboutDialog(hWnd); + break; + } + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + break; + } + + case WM_DESTROY: + { + PostQuitMessage(0); + break; + } + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + return 0; +} + +/* Register a class for our main window */ +BOOL RegisterMainWindowClass() +{ + WNDCLASS wc = {0}; + + wc.lpfnWndProc = &MainWndProc; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_APPICON)); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = MainWndClass; + + return (RegisterClass(&wc)) ? TRUE : FALSE; +} + +/* Create an instance of our main window */ +HWND CreateMainWindow() +{ + HWND hWnd; + HMENU hSysMenu; + + hWnd = CreateWindowEx(0, MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, + 320, 200, NULL, NULL, g_hInstance, NULL); + + if (hWnd) + { + /* Add "about" to the system menu */ + hSysMenu = GetSystemMenu(hWnd, FALSE); + InsertMenu(hSysMenu, 5, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); + InsertMenu(hSysMenu, 6, MF_BYPOSITION, (UINT) ID_HELP_ABOUT, "About"); + } + + return hWnd; +} diff --git a/MainWnd.h b/MainWnd.h new file mode 100644 index 0000000..e3daa00 --- /dev/null +++ b/MainWnd.h @@ -0,0 +1,15 @@ +#ifndef MAINWND_H +#define MAINWND_H + +#include + +/* Window procedure for our main window */ +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +/* Register a class for our main window */ +BOOL RegisterMainWindowClass(); + +/* Create an instance of our main window */ +HWND CreateMainWindow(); + +#endif diff --git a/Makefile b/Makefile index 3201305..3483f50 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,31 @@ -# This Makefile will build the Win16 test application. +# This Makefile will build the Win16 Example application -HEADERS = Resource.h Callback.h -OBJS = WinMain.obj Callback.obj -RES = Resource.res - -CC = cl16.exe +CC = cl CFLAGS = /nologo /c /D NDEBUG /D WINVER=0x0300 /G3swf /Os /W3 /Zp /FPi87 -LINK = link16.exe -RC = rc16.exe -EXE = Win16App.exe -DEF = Win16App.def +LINK = link +RC = rc + +OBJS = WinMain.obj MainWnd.obj AboutDlg.obj +# Rules all: Win16App.exe -Win16App.exe: $(OBJS) $(RES) $(DEF) - $(LINK) /nologo /align:16 $(OBJS),$(EXE),,libw.lib slibcew.lib,$(DEF) - $(RC) /nologo /30 $(RES) $(EXE) +Win16App.exe: + $(LINK) /nologo /align:16 $(OBJS),Win16App.exe,,libw.lib slibcew.lib,Win16App.def + $(RC) /nologo /30 Resource.res Win16App.exe clean: - del $(OBJS) $(RES) $(EXE) Win16App.map + @del *.obj *.res *.map Win16App.exe 2> NUL -%.obj: %.c $(HEADERS) +%.obj: $(CC) $(CFLAGS) $< +Resource.res: + $(RC) /nologo /r Resource.rc + +# Dependencies +Win16App.exe: $(OBJS) Resource.res Win16App.def +AboutDlg.obj: AboutDlg.c AboutDlg.h Resource.h Globals.h +MainWnd.obj: MainWnd.c MainWnd.h AboutDlg.h Resource.h Globals.h +WinMain.obj: WinMain.c MainWnd.h Resource.h Globals.h Resource.res: Resource.rc App.ico Resource.h - $(RC) /nologo /r resource.rc \ No newline at end of file diff --git a/Readme.txt b/Readme.txt index 2e1d0cb..9719e37 100644 --- a/Readme.txt +++ b/Readme.txt @@ -1,17 +1,22 @@ -Win16 Test Application +Win16 Example Application This application is an example 16 bit Windows application written in C. It accompanies an article from my web site, located at http://www.transmissionzero.co.uk/computing/win16-apps-in-c/. -To build the application with Microsoft’s Visual C++ compilers, simply open a -command prompt, change to the directory containing the Makefile, and run -“nmake”. Note that you will need the 16 bit C compiler, linker, and resource -compiler—it won’t work with 32 bit compilers! Also note that the Makefile may -require some small modifications if you use a make utility other than “nmake”. +To build the application with Microsoft’s Visual C++ compilers, open a command +prompt, change to the directory containing the Makefile, and run “nmake”. Note +that you will need the 16 bit C compiler, linker, and resource compiler—it won’t +work with 32 bit compilers! Also note that the Makefile may require some small +modifications if you use a make utility other than “nmake”. -To build the application in Open Watcom, simply open the project up in the IDE, -and choose the “Make” option from the “Targets” menu. +To build the application with the Microsoft Visual C++ GUI, open the +“Win16App.mak” file and build the application. You will need a version of Visual +C++ which supports building Win16 apps, for example Visual C++ 1.52 (available +from MSDN if you have a subscription). + +To build the application in Open Watcom, open the project up in the IDE, and +choose the “Make” option from the “Targets” menu. Disclaimer @@ -33,9 +38,22 @@ entirely up to you. Of course, you must still comply with the licensing conditions of the tools you are using to build the application. -Problems? +Known Problems + +If you try to launch this application while the Windows 1 version of the +application is already running, you get a second instance of the Windows 1 +application instead! I can’t find any reason why this would happen, but I’ve +tested the application on Windows 3.0 to Windows 8.1, and it behaves the same +across all of them. -If you have any problems or questions, please get in contact via +The Open Watcom build of the application doesn’t work correctly under Windows +3.0 when running in real mode. The application will start but the menu is +missing and the about dialog won’t display. I’ve found Open Watcom to be a bit +hit and miss, where certain seemingly harmless changes of compiler option result +in an application which crashes, so it may be possible to fix this by changing +the compiler options. + +If you have any other problems or questions, please get in contact via http://www.transmissionzero.co.uk/contact/. Please ensure that you read the article at http://www.transmissionzero.co.uk/computing/win16-apps-in-c/ before sending any questions. @@ -43,6 +61,10 @@ sending any questions. Changelog +2014-11-09: Version 1.3 + • Added a Makefile project for use with the Visual C++ GUI. + • Refactored some of the code to split the source code files by functionality. + 2013–09-07: Version 1.2 • Removed superfluous LOWORD() macros which had been applied to WPARAMs. @@ -52,11 +74,11 @@ Changelog • Added a VERSIONINFO resource to the executable, so that version information can be viewed in File Manager or Windows Explorer. • Open Watcom build now runs in Windows 3.0 (but not in real mode). - • Ensured all source files are 8.3 characters long. + • Ensured all source files are no more than 8.3 characters long. 2011–07–06: Version 1.0 • First release. -Martin Payne -2013–09-07 +Transmission Zero +2014-11-09 diff --git a/Resource.h b/Resource.h new file mode 100644 index 0000000..ccf5fa2 --- /dev/null +++ b/Resource.h @@ -0,0 +1,15 @@ +#ifndef RESOURCE_H +#define RESOURCE_H + +#define IDI_APPICON 101 +#define IDR_MAINMENU 102 +#define IDR_ACCELERATOR 103 +#define IDD_ABOUTDIALOG 104 +#define ID_FILE_EXIT 40001 +#define ID_HELP_ABOUT 40002 + +#ifndef IDC_STATIC + #define IDC_STATIC -1 +#endif + +#endif diff --git a/resource.rc b/Resource.rc similarity index 57% rename from resource.rc rename to Resource.rc index 583e1f9..47d5c98 100644 --- a/resource.rc +++ b/Resource.rc @@ -2,10 +2,10 @@ #include #include "resource.h" -// Win16 application icon. +/* Win16 application icon */ IDI_APPICON ICON DISCARDABLE "App.ico" -// Our main menu. +/* Our main menu */ IDR_MAINMENU MENU DISCARDABLE BEGIN POPUP "&File" @@ -18,8 +18,8 @@ BEGIN END END -// Executable version information. -VS_VERSION_INFO VERSIONINFO +/* Executable version information */ +VS_VERSION_INFO VERSIONINFO DISCARDABLE FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK @@ -35,36 +35,36 @@ BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" - BEGIN - VALUE "CompanyName", "Transmission Zero\0" - VALUE "FileDescription", "Win16 Test Application\0" - VALUE "FileVersion", "1.0.0.0\0" - VALUE "InternalName", "Win16App\0" - VALUE "LegalCopyright", "©2013 Transmission Zero\0" - VALUE "OriginalFilename","Win16App.exe\0" - VALUE "ProductName", "Win16 Test Application\0" - VALUE "ProductVersion", "1.0.0.0\0" + BEGIN + VALUE "CompanyName", "Transmission Zero\0" + VALUE "FileDescription", "Win16 Example application\0" + VALUE "FileVersion", "1.0.0.0\0" + VALUE "InternalName", "Win16App\0" + VALUE "LegalCopyright", "©2014 Transmission Zero\0" + VALUE "OriginalFilename", "Win16App.exe\0" + VALUE "ProductName", "Win16 Test application\0" + VALUE "ProductVersion", "1.0.0.0\0" END END - BLOCK "VarFileInfo" - BEGIN + BLOCK "VarFileInfo" + BEGIN VALUE "Translation", 0x809, 1252 END END -// Our "about" dialog. +/* Our "about" dialog */ IDD_ABOUTDIALOG DIALOG DISCARDABLE 0, 0, 147, 67 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "MS Sans Serif" BEGIN ICON IDI_APPICON,IDC_STATIC,7,7,20,20 - LTEXT "Win16 Test Application.",IDC_STATIC,34,7,86,8 - LTEXT "©2013 Transmission Zero",IDC_STATIC,34,17,86,8 + LTEXT "Win16 Example application.",IDC_STATIC,34,7,91,8 + LTEXT "©2014 Transmission Zero",IDC_STATIC,34,17,86,8 DEFPUSHBUTTON "OK",IDOK,90,46,50,14,WS_GROUP END -// Our accelerators. +/* Our accelerators */ IDR_ACCELERATOR ACCELERATORS DISCARDABLE BEGIN "A", ID_HELP_ABOUT, VIRTKEY, ALT, NOINVERT diff --git a/WIN16APP.MAK b/WIN16APP.MAK new file mode 100644 index 0000000..113ecc9 --- /dev/null +++ b/WIN16APP.MAK @@ -0,0 +1,118 @@ +# Microsoft Visual C++ generated build script - Do not modify + +PROJ = WIN16APP +DEBUG = 0 +PROGTYPE = 0 +CALLER = +ARGS = +DLLS = +D_RCDEFINES = /d_DEBUG +R_RCDEFINES = /dNDEBUG +ORIGIN = MSVC +ORIGIN_VER = 1.00 +USEMFC = 0 +CC = cl +CPP = cl +CXX = cl +CCREATEPCHFLAG = +CPPCREATEPCHFLAG = +CUSEPCHFLAG = +CPPUSEPCHFLAG = +FIRSTC = ABOUTDLG.C +FIRSTCPP = +RC = rc +CFLAGS_D_WEXE = /nologo /W3 /Zi /Od /D "_DEBUG" /FR /GA /Fd"WIN16APP.PDB" +CFLAGS_R_WEXE = /nologo /W3 /O1 /D "NDEBUG" /FR /GA +LFLAGS_D_WEXE = /NOLOGO /NOD /PACKC:61440 /ALIGN:16 /ONERROR:NOEXE /CO +LFLAGS_R_WEXE = /NOLOGO /NOD /PACKC:61440 /ALIGN:16 /ONERROR:NOEXE +LIBS_D_WEXE = oldnames libw slibcew commdlg.lib olecli.lib olesvr.lib shell.lib +LIBS_R_WEXE = oldnames libw slibcew commdlg.lib olecli.lib olesvr.lib shell.lib +RCFLAGS = /nologo +RESFLAGS = /nologo /30 +RUNFLAGS = +DEFFILE = WIN16APP.DEF +OBJS_EXT = +LIBS_EXT = +!if "$(DEBUG)" == "1" +CFLAGS = $(CFLAGS_D_WEXE) +LFLAGS = $(LFLAGS_D_WEXE) +LIBS = $(LIBS_D_WEXE) +MAPFILE = nul +RCDEFINES = $(D_RCDEFINES) +!else +CFLAGS = $(CFLAGS_R_WEXE) +LFLAGS = $(LFLAGS_R_WEXE) +LIBS = $(LIBS_R_WEXE) +MAPFILE = nul +RCDEFINES = $(R_RCDEFINES) +!endif +!if [if exist MSVC.BND del MSVC.BND] +!endif +SBRS = ABOUTDLG.SBR \ + MAINWND.SBR \ + WINMAIN.SBR + + +ABOUTDLG_DEP = aboutdlg.h \ + resource.h \ + globals.h + + +MAINWND_DEP = mainwnd.h \ + aboutdlg.h \ + resource.h \ + globals.h + + +RESOURCE_RCDEP = resource.h \ + app.ico + + +WINMAIN_DEP = mainwnd.h \ + resource.h \ + globals.h + + +all: $(PROJ).EXE $(PROJ).BSC + +ABOUTDLG.OBJ: ABOUTDLG.C $(ABOUTDLG_DEP) + $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c ABOUTDLG.C + +MAINWND.OBJ: MAINWND.C $(MAINWND_DEP) + $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MAINWND.C + +RESOURCE.RES: RESOURCE.RC $(RESOURCE_RCDEP) + $(RC) $(RCFLAGS) $(RCDEFINES) -r RESOURCE.RC + +WINMAIN.OBJ: WINMAIN.C $(WINMAIN_DEP) + $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c WINMAIN.C + + +$(PROJ).EXE:: RESOURCE.RES + +$(PROJ).EXE:: ABOUTDLG.OBJ MAINWND.OBJ WINMAIN.OBJ $(OBJS_EXT) $(DEFFILE) + echo >NUL @<<$(PROJ).CRF +ABOUTDLG.OBJ + +MAINWND.OBJ + +WINMAIN.OBJ + +$(OBJS_EXT) +$(PROJ).EXE +$(MAPFILE) +$(LIBS) +$(DEFFILE); +<< + link $(LFLAGS) @$(PROJ).CRF + $(RC) $(RESFLAGS) RESOURCE.RES $@ + @copy $(PROJ).CRF MSVC.BND + +$(PROJ).EXE:: RESOURCE.RES + if not exist MSVC.BND $(RC) $(RESFLAGS) RESOURCE.RES $@ + +run: $(PROJ).EXE + $(PROJ) $(RUNFLAGS) + + +$(PROJ).BSC: $(SBRS) + bscmake @<< +/o$@ $(SBRS) +<< diff --git a/WIN16APP.VCW b/WIN16APP.VCW new file mode 100644 index 0000000..c0553ca --- /dev/null +++ b/WIN16APP.VCW @@ -0,0 +1,6 @@ +[MSVC Status File] +Version=1.00 +ProjectType=0 +External=0 +BrkptCount=0 +WatchCount=0 diff --git a/WIN16APP.WSP b/WIN16APP.WSP new file mode 100644 index 0000000..6f896bf Binary files /dev/null and b/WIN16APP.WSP differ diff --git a/Win16App.def b/Win16App.def index 04b03de..02aa658 100644 --- a/Win16App.def +++ b/Win16App.def @@ -1,9 +1,10 @@ NAME Win16App -DESCRIPTION "Win16 Test Application" -STUB "WINSTUB.EXE" +DESCRIPTION 'Win16 Example Application' +STUB 'WINSTUB.EXE' CODE MOVEABLE PRELOAD DISCARDABLE DATA MOVEABLE PRELOAD MULTIPLE HEAPSIZE 1024 STACKSIZE 4096 EXPORTS MainWndProc - AboutDialogProc \ No newline at end of file + AboutDialogProc + \ No newline at end of file diff --git a/Win16App.tgt b/Win16App.tgt index 88bb8e8..318ff77 100644 --- a/Win16App.tgt +++ b/Win16App.tgt @@ -43,7 +43,7 @@ WINLINK WString 21 w????Export names(,): -1 +0 12 WString 27 @@ -59,7 +59,7 @@ WINLINK WString 21 w????Export names(,): -0 +1 16 WString 27 @@ -67,215 +67,323 @@ MainWndProc,AboutDialogProc 0 17 WVList +2 +18 +ActionStates +19 +WString +7 +Sam&ple +20 +WVList +0 +21 +ActionStates +22 +WString +5 +&Make +23 +WVList 0 -1 1 1 0 -18 +24 WPickList -10 -19 +11 +25 MItem 3 *.c -20 +26 WString 4 COBJ -21 +27 WVList -2 -22 +8 +28 MRState -23 +29 WString 3 WCC -24 +30 WString -24 -?????Space optimizations +21 +?????Compiler default +1 0 +31 +MRState +32 +WString +3 +WCC +33 +WString +25 +?????Inline with emulator +1 +1 +34 +MRState +35 +WString +3 +WCC +36 +WString +16 +??6??Small model 1 +1 +37 +MRState +38 +WString +3 +WCC +39 +WString +16 +??6??Large model +1 +0 +40 +MRState +41 +WString +3 +WCC +42 +WString +21 +?????Compiler default +0 +0 +43 +MRState +44 +WString +3 +WCC +45 +WString 25 +?????Inline with emulator +0 +1 +46 MRState -26 +47 WString 3 WCC -27 +48 WString -26 -?????Fastest possible code +16 +??6??Small model +0 +1 +49 +MRState +50 +WString +3 +WCC +51 +WString +16 +??6??Large model 0 0 -28 +52 WVList 0 -1 1 1 0 -29 +53 MItem 10 -callback.c -30 +AboutDlg.c +54 WString 4 COBJ -31 +55 WVList 0 -32 +56 WVList 0 -19 +25 1 1 0 -33 +57 MItem 9 -winmain.c -34 +MainWnd.c +58 WString 4 COBJ -35 +59 WVList 0 -36 +60 WVList 0 -19 +25 1 1 0 -37 +61 +MItem +9 +WinMain.c +62 +WString +4 +COBJ +63 +WVList +0 +64 +WVList +0 +25 +1 +1 +0 +65 MItem 3 *.h -38 +66 WString 3 NIL -39 +67 WVList 0 -40 +68 WVList 0 -1 1 1 0 -41 +69 MItem 10 -callback.h -42 +AboutDlg.h +70 WString 3 NIL -43 +71 WVList 0 -44 +72 WVList 0 -37 +65 1 1 0 -45 +73 MItem -10 -resource.h -46 +9 +Globals.h +74 WString 3 NIL -47 +75 WVList 0 -48 +76 WVList 0 -37 +65 1 1 0 -49 +77 MItem -5 -*.ico -50 +9 +MainWnd.h +78 WString 3 NIL -51 +79 WVList 0 -52 +80 WVList 0 --1 +65 1 1 0 -53 +81 MItem -7 -App.ico -54 +10 +Resource.h +82 WString 3 NIL -55 +83 WVList 0 -56 +84 WVList 0 -49 +65 1 1 0 -57 +85 MItem 4 *.rc -58 +86 WString 5 WRESC -59 +87 WVList 0 -60 +88 WVList 0 -1 1 1 0 -61 +89 MItem 11 -resource.rc -62 +Resource.rc +90 WString 5 WRESC -63 +91 WVList 0 -64 +92 WVList 0 -57 +85 1 1 0 diff --git a/Win16App.wpj b/Win16App.wpj index b4b6490..d1676a3 100644 --- a/Win16App.wpj +++ b/Win16App.wpj @@ -6,8 +6,8 @@ VpeMain WRect 0 0 -7680 -9134 +10276 +9979 2 MProject 3 @@ -30,8 +30,8 @@ VComponent WRect 0 0 -2499 -7379 +1737 +8798 0 0 9 @@ -39,5 +39,5 @@ WFileName 12 Win16App.tgt 0 -0 +10 7 diff --git a/WinMain.c b/WinMain.c new file mode 100644 index 0000000..1dbb0cc --- /dev/null +++ b/WinMain.c @@ -0,0 +1,54 @@ +#include +#include "mainwnd.h" +#include "resource.h" +#include "globals.h" + +/* Global instance handle */ +HINSTANCE g_hInstance = NULL; + +/* Our application entry point */ +int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + HWND hWnd; + HACCEL hAccelerators; + MSG msg; + + /* Assign global HINSTANCE */ + g_hInstance = hInstance; + + /* Register our main window class */ + if (! hPrevInstance) + { + if (! RegisterMainWindowClass()) + { + MessageBox(NULL, "Error registering main window class.", "Error", MB_ICONHAND | MB_OK); + return 0; + } + } + + /* Create our main window */ + if (! (hWnd = CreateMainWindow())) + { + MessageBox(NULL, "Error creating main window.", "Error", MB_ICONHAND | MB_OK); + return 0; + } + + /* Load accelerators */ + hAccelerators = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); + + /* Show main window and force a paint */ + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + /* Main message loop */ + while(GetMessage(&msg, NULL, 0, 0) > 0) + { + if (! TranslateAccelerator(msg.hwnd, hAccelerators, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return (int) msg.wParam; +} diff --git a/callback.c b/callback.c deleted file mode 100644 index 9f6bbbf..0000000 --- a/callback.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "callback.h" -#include "resource.h" - -// Window procedure for our main window. -LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HINSTANCE hInstance; - static FARPROC aboutProc; - - switch (msg) - { - case WM_COMMAND: - { - switch (wParam) - { - case ID_HELP_ABOUT: - { - DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWnd, aboutProc); - return 0; - } - - case ID_FILE_EXIT: - { - DestroyWindow(hWnd); - return 0; - } - } - break; - } - - case WM_GETMINMAXINFO: - { - MINMAXINFO *minMax = (MINMAXINFO*) lParam; - minMax->ptMinTrackSize.x = 220; - minMax->ptMinTrackSize.y = 110; - - return 0; - } - - case WM_SYSCOMMAND: - { - switch (wParam) - { - case ID_HELP_ABOUT: - { - DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWnd, aboutProc); - return 0; - } - } - break; - } - - case WM_CREATE: - { - hInstance = ((LPCREATESTRUCT) lParam)->hInstance; - - // Make about dialog procedure thunk. - aboutProc = MakeProcInstance(AboutDialogProc, hInstance); - - return 0; - } - - case WM_DESTROY: - { - // Free about dialog procedure thunk. - FreeProcInstance(aboutProc); - - PostQuitMessage(0); - return 0; - } - } - - return DefWindowProc(hWnd, msg, wParam, lParam); -} - - -// Dialog procedure for our "about" dialog. -BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_COMMAND: - { - switch (wParam) - { - case IDOK: - case IDCANCEL: - { - EndDialog(hwndDlg, wParam); - return TRUE; - } - } - break; - } - - case WM_INITDIALOG: - return TRUE; - } - - return FALSE; -} diff --git a/callback.h b/callback.h deleted file mode 100644 index 926821a..0000000 --- a/callback.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef CALLBACKS_H -#define CALLBACKS_H - -#include - -// Window procedure for our main window. -LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - -// Dialog procedure for our "about" dialog. -BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -#endif diff --git a/resource.h b/resource.h deleted file mode 100644 index 7187ee7..0000000 --- a/resource.h +++ /dev/null @@ -1,8 +0,0 @@ -#define IDI_APPICON 101 -#define IDR_MAINMENU 102 -#define IDD_ABOUTDIALOG 103 -#define IDR_ACCELERATOR 104 -#define ID_HELP_ABOUT 40001 -#define ID_FILE_EXIT 40002 - -#define IDC_STATIC -1 diff --git a/winmain.c b/winmain.c deleted file mode 100644 index 6d0e80d..0000000 --- a/winmain.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include "resource.h" -#include "callback.h" - -// Our application entry point. -int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - WNDCLASS wc; - LPCSTR MainWndClass = "Win16 Test Application"; - HWND hWnd; - HACCEL hAccelerators; - HMENU hSysMenu; - MSG msg; - - if (! hPrevInstance) - { - // Class for our main window. - wc.style = 0; - wc.lpfnWndProc = &MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); - wc.lpszClassName = MainWndClass; - - // Register our window classes, or error. - if (! RegisterClass(&wc)) - { - MessageBox(NULL, "Error registering window class.", "Error", MB_ICONHAND | MB_OK); - return 0; - } - } - - // Create instance of main window. - hWnd = CreateWindowEx(0, MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, - 320, 200, NULL, NULL, hInstance, NULL); - - // Error if window creation failed. - if (! hWnd) - { - MessageBox(NULL, "Error creating main window.", "Error", MB_ICONHAND | MB_OK); - return 0; - } - - // Load accelerators. - hAccelerators = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); - - // Add "about" to the system menu. - hSysMenu = GetSystemMenu(hWnd, FALSE); - InsertMenu(hSysMenu, 5, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); - InsertMenu(hSysMenu, 6, MF_BYPOSITION, ID_HELP_ABOUT, "About"); - - // Show window and force a paint. - ShowWindow(hWnd, nCmdShow); - UpdateWindow(hWnd); - - // Main message loop. - while(GetMessage(&msg, NULL, 0, 0) > 0) - { - if (! TranslateAccelerator(msg.hwnd, hAccelerators, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - return (int) msg.wParam; -}