From bf262a8668bb169ec9e09fda3f520eec38cb680c Mon Sep 17 00:00:00 2001 From: Martin Payne Date: Tue, 15 Aug 2017 14:34:12 +0100 Subject: [PATCH] Prepare for version 1.0. --- .gitattributes | 63 +++++ .gitignore | 261 ++++++++++++++++++ License.txt | 24 ++ MSVC Win32 MDI Application.sln | 28 ++ MSVC Win32 MDI Application/AboutDialog.c | 40 +++ MSVC Win32 MDI Application/AboutDialog.h | 9 + MSVC Win32 MDI Application/Application.ico | Bin 0 -> 23558 bytes .../Application.manifest | 18 ++ MSVC Win32 MDI Application/Globals.h | 12 + MSVC Win32 MDI Application/MDIChildWindow.c | 250 +++++++++++++++++ MSVC Win32 MDI Application/MDIChildWindow.h | 28 ++ .../MSVC Win32 MDI Application.vcxproj | 198 +++++++++++++ ...MSVC Win32 MDI Application.vcxproj.filters | 72 +++++ MSVC Win32 MDI Application/MainWindow.c | 238 ++++++++++++++++ MSVC Win32 MDI Application/MainWindow.h | 18 ++ MSVC Win32 MDI Application/Resource.h | 33 +++ MSVC Win32 MDI Application/Resource.rc | Bin 0 -> 10046 bytes MSVC Win32 MDI Application/WinMain.c | 71 +++++ MSVC Win32 MDI Application/stdafx.c | 5 + MSVC Win32 MDI Application/stdafx.h | 20 ++ MSVC Win32 MDI Application/targetver.h | 6 + Readme.md | 60 ++++ 22 files changed, 1454 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 License.txt create mode 100644 MSVC Win32 MDI Application.sln create mode 100644 MSVC Win32 MDI Application/AboutDialog.c create mode 100644 MSVC Win32 MDI Application/AboutDialog.h create mode 100644 MSVC Win32 MDI Application/Application.ico create mode 100644 MSVC Win32 MDI Application/Application.manifest create mode 100644 MSVC Win32 MDI Application/Globals.h create mode 100644 MSVC Win32 MDI Application/MDIChildWindow.c create mode 100644 MSVC Win32 MDI Application/MDIChildWindow.h create mode 100644 MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj create mode 100644 MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj.filters create mode 100644 MSVC Win32 MDI Application/MainWindow.c create mode 100644 MSVC Win32 MDI Application/MainWindow.h create mode 100644 MSVC Win32 MDI Application/Resource.h create mode 100644 MSVC Win32 MDI Application/Resource.rc create mode 100644 MSVC Win32 MDI Application/WinMain.c create mode 100644 MSVC Win32 MDI Application/stdafx.c create mode 100644 MSVC Win32 MDI Application/stdafx.h create mode 100644 MSVC Win32 MDI Application/targetver.h create mode 100644 Readme.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c4efe2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/License.txt b/License.txt new file mode 100644 index 0000000..6bb8a29 --- /dev/null +++ b/License.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/MSVC Win32 MDI Application.sln b/MSVC Win32 MDI Application.sln new file mode 100644 index 0000000..0a03f0b --- /dev/null +++ b/MSVC Win32 MDI Application.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.6 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSVC Win32 MDI Application", "MSVC Win32 MDI Application\MSVC Win32 MDI Application.vcxproj", "{034B78A2-1C6B-40C9-8822-B1DF413FB9CC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Debug|x64.ActiveCfg = Debug|x64 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Debug|x64.Build.0 = Debug|x64 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Debug|x86.ActiveCfg = Debug|Win32 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Debug|x86.Build.0 = Debug|Win32 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Release|x64.ActiveCfg = Release|x64 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Release|x64.Build.0 = Release|x64 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Release|x86.ActiveCfg = Release|Win32 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MSVC Win32 MDI Application/AboutDialog.c b/MSVC Win32 MDI Application/AboutDialog.c new file mode 100644 index 0000000..d8dd8d2 --- /dev/null +++ b/MSVC Win32 MDI Application/AboutDialog.c @@ -0,0 +1,40 @@ +#include "stdafx.h" +#include "AboutDialog.h" +#include "Resource.h" +#include "Globals.h" + +/* Dialog procedure for our "about" dialog */ +INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_COMMAND: + { + WORD id = LOWORD(wParam); + + switch (id) + { + case IDOK: + case IDCANCEL: + { + EndDialog(hwndDlg, (INT_PTR)id); + return (INT_PTR)TRUE; + } + } + break; + } + + case WM_INITDIALOG: + { + return (INT_PTR)TRUE; + } + } + + return (INT_PTR)FALSE; +} + +/* Show our "about" dialog */ +void ShowAboutDialog(HWND owner) +{ + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), owner, &AboutDialogProc); +} diff --git a/MSVC Win32 MDI Application/AboutDialog.h b/MSVC Win32 MDI Application/AboutDialog.h new file mode 100644 index 0000000..1e865fc --- /dev/null +++ b/MSVC Win32 MDI Application/AboutDialog.h @@ -0,0 +1,9 @@ +#pragma once + +#include "stdafx.h" + +/* Dialog procedure for our "about" dialog */ +INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* Show our "about" dialog */ +void ShowAboutDialog(HWND owner); diff --git a/MSVC Win32 MDI Application/Application.ico b/MSVC Win32 MDI Application/Application.ico new file mode 100644 index 0000000000000000000000000000000000000000..1073447c20ca46dca11c7f8ed0297cdf1188a5e0 GIT binary patch literal 23558 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 S2uFK+=#hr_`y5^6R{sMo*qd?y literal 0 HcmV?d00001 diff --git a/MSVC Win32 MDI Application/Application.manifest b/MSVC Win32 MDI Application/Application.manifest new file mode 100644 index 0000000..0b31020 --- /dev/null +++ b/MSVC Win32 MDI Application/Application.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MSVC Win32 MDI Application/Globals.h b/MSVC Win32 MDI Application/Globals.h new file mode 100644 index 0000000..d1bc4e9 --- /dev/null +++ b/MSVC Win32 MDI Application/Globals.h @@ -0,0 +1,12 @@ +#pragma once + +#include "stdafx.h" + +/* Global instance handle */ +extern HINSTANCE g_hInstance; + +/* Global main window handle */ +extern HWND g_hMainWindow; + +/* Global MDI client window handle */ +extern HWND g_hMDIClient; diff --git a/MSVC Win32 MDI Application/MDIChildWindow.c b/MSVC Win32 MDI Application/MDIChildWindow.c new file mode 100644 index 0000000..437ec05 --- /dev/null +++ b/MSVC Win32 MDI Application/MDIChildWindow.c @@ -0,0 +1,250 @@ +#include "stdafx.h" +#include "MDIChildWindow.h" +#include "MainWindow.h" +#include "Resource.h" +#include "Globals.h" + +/* MDI child window class and title */ +static LPCTSTR MDIChildWndClass = TEXT("Win32 MDI Example Application - Child"); + +/* Window procedure for our MDI child window */ +LRESULT CALLBACK MDIChildWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_COMMAND: + { + WORD id = LOWORD(wParam); + + switch (id) + { + case ID_FILE_SAVE: + { + MDIChildSave(hWnd); + return 0; + } + + case ID_FILE_SAVEAS: + { + MDIChildSaveAS(hWnd); + return 0; + } + } + + break; + } + + /* An MDI child window is being activated */ + case WM_MDIACTIVATE: + { + HMENU hParentMenu, hParentFileMenu; + UINT enableMenu; + HWND hActivatedChild = (HWND)lParam; + + /* If this window is the one being activated, enable its menus. */ + if (hWnd == hActivatedChild) + { + enableMenu = MF_ENABLED; + } + else + { + enableMenu = MF_GRAYED; + } + + /* Get menu of MDI frame window */ + hParentMenu = GetMenu(g_hMainWindow); + + /* Enable / disable the "window" menu */ + EnableMenuItem(hParentMenu, 1, MF_BYPOSITION | enableMenu); + + /* Enable / disable the save and close menu items */ + hParentFileMenu = GetSubMenu(hParentMenu, 0); + EnableMenuItem(hParentFileMenu, ID_FILE_SAVE, MF_BYCOMMAND | enableMenu); + EnableMenuItem(hParentFileMenu, ID_FILE_SAVEAS, MF_BYCOMMAND | enableMenu); + EnableMenuItem(hParentFileMenu, ID_FILE_CLOSE, MF_BYCOMMAND | enableMenu); + EnableMenuItem(hParentFileMenu, ID_FILE_CLOSEALL, MF_BYCOMMAND | enableMenu); + + /* Redraw the updated menu */ + DrawMenuBar(g_hMainWindow); + + return 0; + } + + case WM_CREATE: + { + /* Allocate child window data */ + MdiChildData* childData = calloc(1, sizeof(MdiChildData)); + + /* Fail window creation if allocation failed */ + if (!childData) + return -1; + + /* Associate child window data with window */ + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)childData); + + return 0; + } + + case WM_DESTROY: + { + /* Free child window data */ + MdiChildData* childData = (MdiChildData*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + if (childData) + free(childData); + + return 0; + } + } + + return DefMDIChildProc(hWnd, msg, wParam, lParam); +} + +/* Register a class for our main window */ +BOOL RegisterMDIChildWindowClass() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.style = 0; + wc.lpfnWndProc = &MDIChildWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | + LR_DEFAULTCOLOR | LR_SHARED); + wc.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = MDIChildWndClass; + wc.hIconSm = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + + return (RegisterClassEx(&wc)) ? TRUE : FALSE; +} + +/* Create a new MDI child window */ +void MDIChildNew(HWND hMDIClient) +{ + MDICREATESTRUCT mcs; + static unsigned int counter = 0; + TCHAR title[16]; + HWND hWndChild; + MdiChildData* childData; + + /* Increment counter, but ensure it doesn't become longer than the buffer */ + counter = (counter % 9999) + 1; + + /* Create the window title */ + wsprintf(title, TEXT("Untitled - %u"), counter); + + /* Set MDI child properties */ + mcs.szTitle = title; + mcs.szClass = MDIChildWndClass; + mcs.hOwner = g_hInstance; + mcs.x = mcs.cx = CW_USEDEFAULT; + mcs.y = mcs.cy = CW_USEDEFAULT; + mcs.style = MDIS_ALLCHILDSTYLES; + + /* Create the MDI child */ + hWndChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); + + if (hWndChild) + { + /* Mark document as unsaved */ + childData = (MdiChildData*)GetWindowLongPtr(hWndChild, GWLP_USERDATA); + childData->IsUnSaved = TRUE; + } + else + MessageBox(NULL, TEXT("Error creating new document."), TEXT("Error"), MB_ICONERROR | MB_OK); +} + +/* Open a document in a new MDI child window */ +void MDIChildOpen(HWND hMDIClient) +{ + OPENFILENAME ofn = { 0 }; + TCHAR fileName[MAX_PATH] = TEXT(""); + TCHAR fileTitle[MAX_PATH] = TEXT(""); + MDICREATESTRUCT mcs; + + /* Set open file dialog properties */ + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hMDIClient; + ofn.lpstrFilter = TEXT("Text Documents (*.txt)\0.txt\0All Files (*.*)\0*.*\0"); + ofn.lpstrFile = fileName; + ofn.lpstrFileTitle = fileTitle; + ofn.nMaxFileTitle = MAX_PATH; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_NOTESTFILECREATE | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrDefExt = TEXT("txt"); + + /* Show open file dialog */ + if (GetOpenFileName(&ofn)) + { + HWND hWndChild; + + /* Set MDI child properties */ + mcs.szTitle = fileTitle; + mcs.szClass = MDIChildWndClass; + mcs.hOwner = g_hInstance; + mcs.x = mcs.cx = CW_USEDEFAULT; + mcs.y = mcs.cy = CW_USEDEFAULT; + mcs.style = MDIS_ALLCHILDSTYLES; + + /* Create the MDI child */ + hWndChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); + + if (hWndChild) + { + /* TODO: Add file opening code */ + } + else + MessageBox(NULL, TEXT("Error opening document."), TEXT("Error"), MB_ICONERROR | MB_OK); + } +} + +/* Save a document in an MDI child window */ +void MDIChildSave(HWND hMDIChild) +{ + MdiChildData* childData = (MdiChildData*)GetWindowLongPtr(hMDIChild, GWLP_USERDATA); + + /* If this is an unsaved document, do a save as */ + if (childData->IsUnSaved) + { + MDIChildSaveAS(hMDIChild); + } + else + { + /* TODO: Add file saving code */ + } +} + +/* Save a document in an MDI child window with a filename */ +void MDIChildSaveAS(HWND hMDIChild) +{ + OPENFILENAME ofn = { 0 }; + TCHAR fileName[MAX_PATH] = TEXT(""); + TCHAR fileTitle[MAX_PATH] = TEXT(""); + + /* Set save file dialog properties */ + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hMDIChild; + ofn.lpstrFilter = TEXT("Text Documents (*.txt)\0.txt\0All Files (*.*)\0*.*\0"); + ofn.lpstrFile = fileName; + ofn.lpstrFileTitle = fileTitle; + ofn.nMaxFileTitle = MAX_PATH; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_NOTESTFILECREATE | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + ofn.lpstrDefExt = TEXT("txt"); + + if (GetSaveFileName(&ofn)) + { + /* TODO: Add file saving code */ + + /* Update window title with the filename */ + SetWindowText(hMDIChild, ofn.lpstrFileTitle); + + /* Mark document as saved */ + MdiChildData* childData = (MdiChildData*)GetWindowLongPtr(hMDIChild, GWLP_USERDATA); + childData->IsUnSaved = FALSE; + } +} diff --git a/MSVC Win32 MDI Application/MDIChildWindow.h b/MSVC Win32 MDI Application/MDIChildWindow.h new file mode 100644 index 0000000..b32666a --- /dev/null +++ b/MSVC Win32 MDI Application/MDIChildWindow.h @@ -0,0 +1,28 @@ +#pragma once + +#include "stdafx.h" + +/* Window procedure for our main window */ +LRESULT CALLBACK MDIChildWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +/* Register a class for our main window */ +BOOL RegisterMDIChildWindowClass(void); + +/* Create a new MDI child window */ +void MDIChildNew(HWND hMDIClient); + +/* Open a document in a new MDI child window */ +void MDIChildOpen(HWND hMDIClient); + +/* Save a document in an MDI child window */ +void MDIChildSave(HWND hMDIChild); + +/* Save a document in an MDI child window with a filename */ +void MDIChildSaveAS(HWND hMDIChild); + +/* Instance data for the MDI child window */ +typedef struct tagMdiChildData +{ + /* Flag to determine whether this is a new document which hasn't been saved */ + BOOL IsUnSaved; +} MdiChildData; diff --git a/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj b/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj new file mode 100644 index 0000000..c7b4e51 --- /dev/null +++ b/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj @@ -0,0 +1,198 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {034B78A2-1C6B-40C9-8822-B1DF413FB9CC} + Win32Proj + MSVCWin32MDIApplication + 10.0.15063.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + true + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + "type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'" + + + Application.manifest + + + + + Use + Level3 + Disabled + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + "type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'" + + + Application.manifest + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + "type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'" + + + Application.manifest + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + "type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'" + + + Application.manifest + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj.filters b/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj.filters new file mode 100644 index 0000000..ea7fcbc --- /dev/null +++ b/MSVC Win32 MDI Application/MSVC Win32 MDI Application.vcxproj.filters @@ -0,0 +1,72 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/MSVC Win32 MDI Application/MainWindow.c b/MSVC Win32 MDI Application/MainWindow.c new file mode 100644 index 0000000..4b56424 --- /dev/null +++ b/MSVC Win32 MDI Application/MainWindow.c @@ -0,0 +1,238 @@ +#include "stdafx.h" +#include "MainWindow.h" +#include "MDIChildWindow.h" +#include "AboutDialog.h" +#include "Resource.h" +#include "Globals.h" + +/* Main window class and title */ +static LPCTSTR MainWndClass = TEXT("Win32 MDI Example Application"); + +/* Global MDI client window handle */ +HWND g_hMDIClient = NULL; + +/* Window procedure for our main window */ +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_COMMAND: + { + WORD id = LOWORD(wParam); + + switch (id) + { + /* Create new MDI child with an empty document */ + case ID_FILE_NEW: + { + MDIChildNew(g_hMDIClient); + return 0; + } + + /* Create new MDI child with an existing document */ + case ID_FILE_OPEN: + { + MDIChildOpen(g_hMDIClient); + return 0; + } + + /* Send close message to MDI child on close menu item */ + case ID_FILE_CLOSE: + { + HWND hWndChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE, 0, 0); + + if (hWndChild) + { + SendMessage(hWndChild, WM_CLOSE, 0, 0); + return 0; + } + + break; + } + + /* Close all MDI children on close all menu item */ + case ID_FILE_CLOSEALL: + { + EnumChildWindows(g_hMDIClient, &CloseAllProc, 0); + return 0; + } + + /* Show "about" dialog on about menu item */ + case ID_HELP_ABOUT: + { + ShowAboutDialog(hWnd); + return 0; + } + + case ID_FILE_EXIT: + { + DestroyWindow(hWnd); + return 0; + } + + case ID_WINDOW_TILE: + { + SendMessage(g_hMDIClient, WM_MDITILE, 0, 0); + return 0; + } + + case ID_WINDOW_CASCADE: + { + SendMessage(g_hMDIClient, WM_MDICASCADE, 0, 0); + return 0; + } + + case ID_WINDOW_ARRANGE: + { + SendMessage(g_hMDIClient, WM_MDIICONARRANGE, 0, 0); + return 0; + } + + default: + { + /* If the ID is less than ID_MDI_FIRSTCHILD, it's probably a message for a child window's menu */ + if (id < ID_MDI_FIRSTCHILD) + { + HWND hWndChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE, 0, 0); + + if (hWndChild) + { + SendMessage(hWndChild, WM_COMMAND, wParam, lParam); + return 0; + } + } + + break; + } + } + + break; + } + + case WM_GETMINMAXINFO: + { + /* Prevent our window from being sized too small */ + MINMAXINFO *minMax = (MINMAXINFO*)lParam; + minMax->ptMinTrackSize.x = 220; + minMax->ptMinTrackSize.y = 110; + + return 0; + } + + case WM_SIZE: + { + /* Ensure MDI client fills the whole client area */ + RECT rcClient; + + GetClientRect(hWnd, &rcClient); + SetWindowPos(g_hMDIClient, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER); + + return 0; + } + + /* Item from system menu has been invoked */ + case WM_SYSCOMMAND: + { + WORD id = LOWORD(wParam); + + switch (id) + { + /* Show "about" dialog on about system menu item */ + case ID_HELP_ABOUT: + { + ShowAboutDialog(hWnd); + return 0; + } + } + + break; + } + + case WM_CREATE: + { + /* Create the MDI client window */ + CLIENTCREATESTRUCT ccs; + HWND hMDIClient; + + ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), 1); + ccs.idFirstChild = ID_MDI_FIRSTCHILD; + + hMDIClient = CreateWindowEx(0, TEXT("MDICLIENT"), NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | + WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, + g_hInstance, (LPVOID)&ccs); + + /* Fail the window creation if the MDI client creation failed */ + if (!hMDIClient) + { + MessageBox(NULL, TEXT("Error creating MDI client."), TEXT("Error"), MB_ICONERROR | MB_OK); + return -1; + } + + /* Set global MDI client handle */ + g_hMDIClient = hMDIClient; + + return 0; + } + + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + } + + return DefFrameProc(hWnd, g_hMDIClient, msg, wParam, lParam); +} + +/* Close all child windows */ +BOOL CALLBACK CloseAllProc(HWND hWnd, LPARAM lParam) +{ + if (GetWindow(hWnd, GW_OWNER)) + return TRUE; + + SendMessage(hWnd, WM_CLOSE, 0, 0); + + return TRUE; +} + +/* Register a class for our main window */ +BOOL RegisterMainWindowClass() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.style = 0; + wc.lpfnWndProc = &MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | + LR_DEFAULTCOLOR | LR_SHARED); + wc.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); + wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = MainWndClass; + wc.hIconSm = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + + return (RegisterClassEx(&wc)) ? TRUE : FALSE; +} + +/* Create an instance of our main window */ +HWND CreateMainWindow() +{ + HWND hWnd; + HMENU hSysMenu; + + hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 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, ID_HELP_ABOUT, TEXT("About")); + } + + return hWnd; +} diff --git a/MSVC Win32 MDI Application/MainWindow.h b/MSVC Win32 MDI Application/MainWindow.h new file mode 100644 index 0000000..8df8c8a --- /dev/null +++ b/MSVC Win32 MDI Application/MainWindow.h @@ -0,0 +1,18 @@ +#pragma once + +#include "stdafx.h" + +/* 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(void); + +/* Create an instance of our main window */ +HWND CreateMainWindow(void); + +/* Callback to close all child windows */ +BOOL CALLBACK CloseAllProc(HWND hWnd, LPARAM lParam); + +/* First ID Windows should use for menu items it attaches to the "Window" menu */ +#define ID_MDI_FIRSTCHILD 50000 diff --git a/MSVC Win32 MDI Application/Resource.h b/MSVC Win32 MDI Application/Resource.h new file mode 100644 index 0000000..0df088c --- /dev/null +++ b/MSVC Win32 MDI Application/Resource.h @@ -0,0 +1,33 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Resource.rc +// +#define IDI_APPICON 101 +#define IDR_MAINMENU 102 +#define IDR_ACCELERATOR 103 +#define IDD_ABOUTDIALOG 104 +#define ID_FILE_NEW 40001 +#define ID_FILE_OPEN 40002 +#define ID_FILE_SAVE 40003 +#define ID_FILE_SAVEAS 40004 +#define ID_FILE_CLOSE 40005 +#define ID_FILE_CLOSEALL 40006 +#define ID_FILE_EXIT 40007 +#define ID_WINDOW_TILE 40008 +#define ID_WINDOW_CASCADE 40009 +#define ID_WINDOW_ARRANGE 40010 +#define ID_HELP_ABOUT 40011 +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40012 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/MSVC Win32 MDI Application/Resource.rc b/MSVC Win32 MDI Application/Resource.rc new file mode 100644 index 0000000000000000000000000000000000000000..b50813f56eae86854d094bfb3c105b43b95d5228 GIT binary patch literal 10046 zcmdU#X-^wR7{}*zrGAI4BSnph2$Y;Jjkzp*2_J+il0_g;BnJ>S36c7R`X$@`{xg2q z(>69q4fKqnr6Fj*YsI+Kf9k;<+(4P(0a++0liOs-;z7Xj9+zs zx{~j$kxzWTGe1sqmtD)XUB`9ZmaDp^>ob0v)-9eJuI7$tY4clmo3zw;w)KT!`7T3e zW#o3@N0!HD@bk)jg8mWQ5g$5G{f^%%R9B!={Me@bckZl2X3OA<=WiI7=Ku0>%n$|b zxP@2Jq%-JVOgD`4Ht%wkhAu+7m)PF`Ne$6~$o-1UFR7Uw?t2-Y!wqT5vjROBCamhh zbL^Ltb)7P2+3lcL!K&I=P#62Euy!B)s&Q%Fzqq1_BRkA-fEM=|)u4RlSFO>iT9>78w=r? zcaom1!vYMD)Dol9xO2ImU%Y6Zv`) zSBP?-=%b8c$jE?uNL@%2Lxo3UH0yv%naS7j+fS4sE(&oKZ>8wb;;G^@36pldoZTZm zro_xeG_8(ligO*4LQ+D@^K9s>RNg2q-{y2h96f-ebtsor)O{rA!hd_x9K~L#1@~L{ z_ZGcN?kUme0?B>M_=V!J#&=t#>OEF{JX3>NzTjg#>aR3{=2QgPmBkzRW%2J}Yq!z;&#azawLNv!Fmrb8Hqz{| zy7;w=e9L6n7E$NJBJU~d)AbPk2d|QpfMF? z+>06XWO=I0y$KDE;cARVe3hSj7*F$DjnS0BRr}vLyN$iyVeg{{QxNN2mb2O&$^Mg; z5@$3vF6(U$SzY@HMYO=hNt(Wh2kMM{nQXC5>{M1U!VB%Vmoq31)E#H$V2ddmhDP?JZirg0{8srP_Nx97P$=tJ4GRWfbq9LWM={S$bQ9 zLKZ9=*4`qGVz#vRKrp~Jr*qClBwKbL(3#r>G&j(+2lg8NNLh%^ExHpmH>OH**S$O$ zLKcakvr?x@Iy+L1mdxdhk{}U3?00ShORjloXvcFl-Wx}tmu+ma z((c$!^D~7R*6+tlCly=Lbj2%&{%eW;@>p6mJwkCM^nC$FT`$ICVs3Sa;mRn|7~=O~ zAD-@ID;L{|cI{30D$bNZpiE0X^&AO>Os-1p4EfJvb?I5x+#9HQ>nZxcZ+a&4fyMaj zt(86Gsnav@pagE6om_kW^cB53rl#CeIYtRx37%_6t9BWt$C3NP>vfhUTf@rqTE>qp z#wJfpgKgNFAtG(~{dXO0s)A%2jT18MljK8-_ZP)nnT{oGpN3(bJZ6)D%~4zmdN02o{EV!B-RscW*vAIEG1~Y^K3I1)7A{ZS&{-LwCl_9Oudo|y zRjFI~iFUtnULviM&ukLYG&Zg&=T;;Uzryc2G3T|fzoOK9`gU`~X!+YMYWiBUO`9To zgHor<_NMNmwAR}3Ii9lG@{O(Rkqq zS)Ij;+6wq22i@|8;a4=6<<;mHz9?Bsx-7v#dAY?R(IiY8=tn^H7F%24o)6Q!o_#tF zMF?Sdl|!N|ZU@cj!qYvU&voFJG&XRl#PhzFvUsoO6`!B1K%ZuN>3J?|SQ%@g_La)> zTb|+{+kcdaMf&oqY$SXczM_;Q<@HqR7H4!SSVkN5MM*v&K7COZQ`8>5-xk}4EHYSD zT34;675m65zqgVN=C2+Y50I*=c#voLA z9N|p5!^--mJsZzrr;3vhJs!{W^Tr^jm_K&9_r37+kg!e@WsP|)uye8WX-oRFBRww9 zA9;x?E6mm%!}4+tEOzpfMiD4k1j~=@edL>UCa{YYCeH+tz9+pa&;L&#Sa$LovA$GG zFXcP*R%<9PDPF7CKWY5r+)2_)W>3k;S3F-Vr}*jdUnnQf@U8xFuspeM7Kz0sD}$a) w`$tJ$Q?hd|PhC_Ajg^o6Z_x%CJN>^!#>eI1K^BP+PS*HK_J8_n{16ZEA3?K++5i9m literal 0 HcmV?d00001 diff --git a/MSVC Win32 MDI Application/WinMain.c b/MSVC Win32 MDI Application/WinMain.c new file mode 100644 index 0000000..2ab35e2 --- /dev/null +++ b/MSVC Win32 MDI Application/WinMain.c @@ -0,0 +1,71 @@ +#include "stdafx.h" +#include "MainWindow.h" +#include "MDIChildWindow.h" +#include "Resource.h" +#include "Globals.h" + +/* Global instance handle */ +HINSTANCE g_hInstance = NULL; + +/* Global main window handle so that child windows can access it */ +HWND g_hMainWindow = NULL; + +/* Our application entry point */ +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + INITCOMMONCONTROLSEX icc; + HWND hWnd; + HACCEL hAccelerators; + MSG msg; + + /* Assign global HINSTANCE */ + g_hInstance = hInstance; + + /* Initialise common controls */ + icc.dwSize = sizeof(icc); + icc.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&icc); + + /* Register our main window class */ + if (!RegisterMainWindowClass()) + { + MessageBox(NULL, TEXT("Error registering main window class."), TEXT("Error"), MB_ICONERROR | MB_OK); + return 0; + } + + /* Register our MDI child window class */ + if (!RegisterMDIChildWindowClass()) + { + MessageBox(NULL, TEXT("Error registering MDI child window class."), TEXT("Error"), MB_ICONERROR | MB_OK); + return 0; + } + + /* Create our main window */ + if (!(hWnd = CreateMainWindow())) + { + MessageBox(NULL, TEXT("Error creating main window."), TEXT("Error"), MB_ICONERROR | MB_OK); + return 0; + } + + /* Set global main window handle */ + g_hMainWindow = hWnd; + + /* 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 (!TranslateMDISysAccel(g_hMDIClient, &msg) && !TranslateAccelerator(hWnd, hAccelerators, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return (int)msg.wParam; +} diff --git a/MSVC Win32 MDI Application/stdafx.c b/MSVC Win32 MDI Application/stdafx.c new file mode 100644 index 0000000..33d95b6 --- /dev/null +++ b/MSVC Win32 MDI Application/stdafx.c @@ -0,0 +1,5 @@ +// stdafx.c : source file that includes just the standard includes +// MSVC Win32 MDI Application.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/MSVC Win32 MDI Application/stdafx.h b/MSVC Win32 MDI Application/stdafx.h new file mode 100644 index 0000000..4b9be93 --- /dev/null +++ b/MSVC Win32 MDI Application/stdafx.h @@ -0,0 +1,20 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#include +#include + +// C RunTime Header Files +#include +#include +#include +#include diff --git a/MSVC Win32 MDI Application/targetver.h b/MSVC Win32 MDI Application/targetver.h new file mode 100644 index 0000000..8014de1 --- /dev/null +++ b/MSVC Win32 MDI Application/targetver.h @@ -0,0 +1,6 @@ +#pragma once + +// Target Windows Vista and later +#define _WIN32_WINNT 0x0600 + +#include diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..8a9399f --- /dev/null +++ b/Readme.md @@ -0,0 +1,60 @@ +# MSVC Win32 MDI Application + +## Table of Contents + +- [Introduction](#introduction) +- [Windows Target Version](#windows-target-version) +- [Distributing Your Application](#distributing-your-application) +- [Terms of Use](#terms-of-use) +- [Problems?](#problems) +- [Changelog](#changelog) + +## Introduction + +This application is an example Windows MDI GUI application. The compiled application is a fully functional, with the +exception that opening and saving files does not read or write the files, and the MDI child windows do not have any code +to display documents. However, by adding this functionality you can quickly create a functioning MDI application. + +To build the application, open the solution file in Visual Studio, select the configuration and platform from the +drop-down menu, and use "Build Solution" from the "Build" menu. + +The solution was created in Visual Studio 2017, but it should open in any version of Visual Studio from 2010 SP1 +onwards. + +## Windows Target Version + +The project targets Windows Vista. If you attempt to call Windows API functions in your source code which were +introduced after Windows Vista, you will get a compilation error. If you'd like to use newer API functions (at the +expense of the application not running on older versions of Windows), you will need to change the "_WIN32_WINNT" +preprocessor definition in "targetver.h" to match the version of Windows you are targeting. For example, to target +Windows 7, change it to "0x0601". + +You can also target Windows XP using the above method with the value "0x0501". However, you will also need to go into +your project properties, and set the "Platform Toolset" under "Configuration Properties" to a toolset which supports +Windows XP. + +You can find a complete list of target version numbers in the "SDKDDKVer.h" Windows SDK header file. + +## Distributing Your Application + +The application will depend on the Microsoft Visual C++ Runtime. This will either be in the form of a Visual C++ Runtime +redistributable MSI (or merge module which you can use in your own installer), or DLL(s) which you must redistribute +with the application. Check the product documentation for your version of Visual Studio to see what your options are, +and be careful to ensure that you are allowed to redistribute the DLL(s) if you choose this option. + +## Terms of Use + +Refer to "License.txt" for terms of use. + +## Problems? + +If you have any problems or questions, please ensure you have read this readme. If you are still having trouble, you can +[get in contact](http://www.transmissionzero.co.uk/contact/). + +## Changelog + +1. 2017-08-15: Version 1.0 + - Initial release. + +Transmission Zero +2017-08-15