├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── README.md
├── Rebld
└── Rebld.dsp
├── Rebuilder.dsw
├── Rebuilder
└── Rebuilder.dsp
├── cmn
├── combo.h
├── path.cpp
└── path.h
├── ext
└── PropertyGrid
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── CustomItem.h
│ ├── DynDialogEx.cpp
│ ├── DynDialogEx.h
│ ├── DynDialogItemEx.cpp
│ ├── DynDialogItemEx.h
│ ├── ListDynDialogEx.cpp
│ ├── ListDynDialogEx.h
│ ├── PropertyGrid.cpp
│ ├── PropertyGrid.h
│ ├── PropertyGridCombo.cpp
│ ├── PropertyGridCombo.h
│ ├── PropertyGridDirectoryPicker.cpp
│ ├── PropertyGridDirectoryPicker.h
│ ├── PropertyGridInPlaceEdit.cpp
│ ├── PropertyGridInPlaceEdit.h
│ ├── PropertyGridMonthCalCtrl.cpp
│ ├── PropertyGridMonthCalCtrl.h
│ ├── README.md
│ ├── stdafx.cpp
│ ├── stdafx.h
│ └── test
│ ├── CMakeLists.txt
│ ├── CustomTreeCtrl.cpp
│ ├── CustomTreeCtrl.h
│ ├── GradientItem.cpp
│ ├── GradientItem.h
│ ├── PropGrid.cpp
│ ├── PropGrid.h
│ ├── PropGrid.rc
│ ├── PropGridDlg.cpp
│ ├── PropGridDlg.h
│ ├── RectEditDlg.cpp
│ ├── RectEditDlg.h
│ ├── RectItem.cpp
│ ├── RectItem.h
│ ├── SerialItem.cpp
│ ├── SerialItem.h
│ ├── TreeItem.cpp
│ ├── TreeItem.h
│ ├── res
│ ├── PropGrid.ico
│ ├── PropGrid.manifest
│ └── PropGrid.rc2
│ └── resource.h
├── lib
├── config.cpp
├── config.h
├── dllmain.cpp
├── hooks.cpp
├── hooks.h
├── util.cpp
└── util.h
├── pkg
└── fade.gif
├── res
├── mama.ico
├── res.manifest
├── res.rc
└── resource.h
└── src
├── app.cpp
├── app.h
├── clinkstatic.cpp
├── clinkstatic.h
├── launcher.cpp
├── launcher.h
├── patchgrid.cpp
├── patchgrid.h
├── tabs.cpp
├── tabs.h
├── window.cpp
└── window.h
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths-ignore:
8 | - 'README.md'
9 | pull_request:
10 | branches:
11 | - master
12 | paths-ignore:
13 | - 'README.md'
14 |
15 | jobs:
16 |
17 | build:
18 |
19 | runs-on: windows-latest
20 |
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v2
24 | with:
25 | fetch-depth: 0
26 |
27 | - name: Install Visual C++ 6.0
28 | run: |
29 | git clone --depth 1 https://github.com/itsmattkc/MSVC600
30 |
31 | - name: Build
32 | shell: cmd
33 | run: |
34 | call MSVC600/VC98/Bin/vcvars32.bat
35 | msdev Rebuilder.dsw /make
36 |
37 | - name: Upload a Build Artifact
38 | uses: actions/upload-artifact@v2.2.1
39 | with:
40 | path:
41 | Rebuilder/Release/Rebuilder.exe
42 |
43 | - name: Upload to Releases
44 | shell: bash
45 | if: github.event_name == 'push'
46 | env:
47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48 | TRAVIS_REPO_SLUG: isledecomp/LEGOIslandRebuilder
49 | TRAVIS_COMMIT: ${{ github.sha }}
50 | run: |
51 | curl -fLOSs --retry 2 --retry-delay 60 https://github.com/probonopd/uploadtool/raw/master/upload.sh
52 | ./upload.sh Rebuilder/Release/Rebuilder.exe
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build*
2 | Debug/
3 | Release/
4 | *.user
5 | *.obj
6 | *.dll
7 | *.exp
8 | *.lib
9 | *.exe
10 | *.res
11 | *.plg
12 | *.ncb
13 | *.opt
14 | *.aps
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LEGO Island Rebuilder
6 |
7 |
8 |
9 | A launcher and modification/patching tool for the 1997 video game LEGO Island
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Homepage •
22 | Info •
23 | Download •
24 | Building •
25 | Usage •
26 | Contributing
27 |
28 |
29 |
30 |
31 |
32 |
33 | Supports Windows 95 - Windows 11 (Linux and macOS through Wine)
34 |
35 | ## Info
36 |
37 | LEGO Island Rebuilder is a launcher and modification tool for Mindscape's 1997 video game LEGO Island. It is the product of in-depth research done on the game; the bulk of which is documented on the [LEGO Island Wiki](https://www.legoisland.org/).
38 |
39 | It includes fixes to numerous bugs in the original game and multiple quality of life patches while making no permanent changes to the game installation. Additionally, Rebuilder acts as a full replacement for the original configuration tool.
40 |
41 | Rebuilder currently supports [all known versions of LEGO Island](https://www.legoisland.org/wiki/index.php/LEGO_Island_Versions).
42 |
43 | ## Download
44 |
45 | The latest binaries are available on the [releases page](https://github.com/itsmattkc/LEGOIslandRebuilder/releases/tag/continuous).
46 |
47 | ## Building
48 |
49 | LEGO Island Rebuilder specifically targets Microsoft Visual C++ 6.0 in order to retain compatibility with Windows 95. It is highly recommended to use this compiler at all times, as code written for newer compilers may not be compatible with this version.
50 |
51 | Rebuilder can be built with the standard Visual C++ 6.0 IDE. Since the MSVC 6.0 installer is known to have issues on newer versions of Windows, a portable version of MSVC 6.0 is available [here](https://github.com/itsmattkc/MSVC600).
52 |
53 | Since the IDE is old and somewhat archaic, you may wish to use a more modern IDE/code editor. This can be done by using the following commands as your build step in the IDE of your choice:
54 |
55 | ```
56 | # Enter Visual C++ 6.0 build environment
57 | /VC98/bin/VCVARS32.BAT
58 |
59 | # Build the project
60 | msdev Rebuilder.dsw /make
61 | ```
62 |
63 | (Replace `` with the directory you installed/cloned MSVC 6.0 to)
64 |
65 | Rebuilder can only be built in "Release" mode. This is because it utilizes DLL injection to modify LEGO Island in memory, and with MSVC, "Debug" code is incompatible with "Release" code (which is what LEGO Island was naturally compiled as).
66 |
67 | ## Usage
68 |
69 | By default, Rebuilder opens a graphical interface which can be used to set the patch configuration and to launch the game. However, command line arguments are also supported:
70 |
71 | * `-r/--run`: Runs LEGO Island with the currently saved configuration, bypassing Rebuilder's interface entirely.
72 | * `-h/--help`: Shows a help screen with usage details.
73 |
74 | ### Linux and macOS
75 |
76 | Rebuilder works on non-Windows platforms using Wine. Ensure LEGO Island is installed into the same prefix you're running Rebuilder in, and it should work identically to Windows.
77 |
78 | ## Contributing
79 |
80 | Contributions like code changes, documentation, or findings and research about the game are welcome. The best way of contributing code to Rebuilder is to open a [pull request](https://github.com/itsmattkc/LEGOIslandRebuilder/pulls).
81 |
--------------------------------------------------------------------------------
/Rebld/Rebld.dsp:
--------------------------------------------------------------------------------
1 | # Microsoft Developer Studio Project File - Name="Rebld" - Package Owner=<4>
2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00
3 | # ** DO NOT EDIT **
4 |
5 | # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
6 |
7 | CFG=REBLD - WIN32 RELEASE
8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9 | !MESSAGE use the Export Makefile command and run
10 | !MESSAGE
11 | !MESSAGE NMAKE /f "Rebld.mak".
12 | !MESSAGE
13 | !MESSAGE You can specify a configuration when running NMAKE
14 | !MESSAGE by defining the macro CFG on the command line. For example:
15 | !MESSAGE
16 | !MESSAGE NMAKE /f "Rebld.mak" CFG="REBLD - WIN32 RELEASE"
17 | !MESSAGE
18 | !MESSAGE Possible choices for configuration are:
19 | !MESSAGE
20 | !MESSAGE "Rebld - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
21 | !MESSAGE
22 |
23 | # Begin Project
24 | # PROP AllowPerConfigDependencies 0
25 | # PROP Scc_ProjName ""
26 | # PROP Scc_LocalPath ""
27 | CPP=cl.exe
28 | MTL=midl.exe
29 | RSC=rc.exe
30 | # PROP BASE Use_MFC 0
31 | # PROP BASE Use_Debug_Libraries 0
32 | # PROP BASE Output_Dir "Release"
33 | # PROP BASE Intermediate_Dir "Release"
34 | # PROP BASE Target_Dir ""
35 | # PROP Use_MFC 0
36 | # PROP Use_Debug_Libraries 0
37 | # PROP Output_Dir "Release"
38 | # PROP Intermediate_Dir "Release"
39 | # PROP Ignore_Export_Lib 0
40 | # PROP Target_Dir ""
41 | # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "REBLD_EXPORTS" /YX /FD /c
42 | # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "REBLD_EXPORTS" /YX /FD /c
43 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
44 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
45 | # ADD BASE RSC /l 0x409 /d "NDEBUG"
46 | # ADD RSC /l 0x409 /d "NDEBUG"
47 | BSC32=bscmake.exe
48 | # ADD BASE BSC32 /nologo
49 | # ADD BSC32 /nologo
50 | LINK32=link.exe
51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
52 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib shlwapi.lib winmm.lib dxguid.lib /nologo /dll /machine:I386
53 | # Begin Target
54 |
55 | # Name "Rebld - Win32 Release"
56 | # Begin Group "Source Files"
57 |
58 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
59 | # Begin Source File
60 |
61 | SOURCE=..\lib\config.cpp
62 | # End Source File
63 | # Begin Source File
64 |
65 | SOURCE=..\lib\dllmain.cpp
66 | # End Source File
67 | # Begin Source File
68 |
69 | SOURCE=..\lib\hooks.cpp
70 | # End Source File
71 | # Begin Source File
72 |
73 | SOURCE=..\cmn\path.cpp
74 | # End Source File
75 | # Begin Source File
76 |
77 | SOURCE=..\lib\util.cpp
78 | # End Source File
79 | # End Group
80 | # Begin Group "Header Files"
81 |
82 | # PROP Default_Filter "h;hpp;hxx;hm;inl"
83 | # Begin Source File
84 |
85 | SOURCE=..\cmn\combo.h
86 | # End Source File
87 | # Begin Source File
88 |
89 | SOURCE=..\lib\config.h
90 | # End Source File
91 | # Begin Source File
92 |
93 | SOURCE=..\lib\hooks.h
94 | # End Source File
95 | # Begin Source File
96 |
97 | SOURCE=..\cmn\path.h
98 | # End Source File
99 | # Begin Source File
100 |
101 | SOURCE=..\lib\util.h
102 | # End Source File
103 | # End Group
104 | # Begin Group "Resource Files"
105 |
106 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
107 | # End Group
108 | # End Target
109 | # End Project
110 |
--------------------------------------------------------------------------------
/Rebuilder.dsw:
--------------------------------------------------------------------------------
1 | Microsoft Developer Studio Workspace File, Format Version 6.00
2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
3 |
4 | ###############################################################################
5 |
6 | Project: "Rebld"=.\Rebld\Rebld.dsp - Package Owner=<4>
7 |
8 | Package=<5>
9 | {{{
10 | }}}
11 |
12 | Package=<4>
13 | {{{
14 | }}}
15 |
16 | ###############################################################################
17 |
18 | Project: "Rebuilder"=.\Rebuilder\Rebuilder.dsp - Package Owner=<4>
19 |
20 | Package=<5>
21 | {{{
22 | }}}
23 |
24 | Package=<4>
25 | {{{
26 | Begin Project Dependency
27 | Project_Dep_Name Rebld
28 | End Project Dependency
29 | }}}
30 |
31 | ###############################################################################
32 |
33 | Global:
34 |
35 | Package=<5>
36 | {{{
37 | }}}
38 |
39 | Package=<3>
40 | {{{
41 | }}}
42 |
43 | ###############################################################################
44 |
45 |
--------------------------------------------------------------------------------
/Rebuilder/Rebuilder.dsp:
--------------------------------------------------------------------------------
1 | # Microsoft Developer Studio Project File - Name="Rebuilder" - Package Owner=<4>
2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00
3 | # ** DO NOT EDIT **
4 |
5 | # TARGTYPE "Win32 (x86) Application" 0x0101
6 |
7 | CFG=REBUILDER - WIN32 RELEASE
8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9 | !MESSAGE use the Export Makefile command and run
10 | !MESSAGE
11 | !MESSAGE NMAKE /f "Rebuilder.mak".
12 | !MESSAGE
13 | !MESSAGE You can specify a configuration when running NMAKE
14 | !MESSAGE by defining the macro CFG on the command line. For example:
15 | !MESSAGE
16 | !MESSAGE NMAKE /f "Rebuilder.mak" CFG="REBUILDER - WIN32 RELEASE"
17 | !MESSAGE
18 | !MESSAGE Possible choices for configuration are:
19 | !MESSAGE
20 | !MESSAGE "Rebuilder - Win32 Release" (based on "Win32 (x86) Application")
21 | !MESSAGE
22 |
23 | # Begin Project
24 | # PROP AllowPerConfigDependencies 0
25 | # PROP Scc_ProjName ""
26 | # PROP Scc_LocalPath ""
27 | CPP=cl.exe
28 | MTL=midl.exe
29 | RSC=rc.exe
30 | # PROP BASE Use_MFC 0
31 | # PROP BASE Use_Debug_Libraries 0
32 | # PROP BASE Output_Dir "Release"
33 | # PROP BASE Intermediate_Dir "Release"
34 | # PROP BASE Target_Dir ""
35 | # PROP Use_MFC 1
36 | # PROP Use_Debug_Libraries 0
37 | # PROP Output_Dir "Release"
38 | # PROP Intermediate_Dir "Release"
39 | # PROP Ignore_Export_Lib 0
40 | # PROP Target_Dir ""
41 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
42 | # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
43 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
44 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
45 | # ADD BASE RSC /l 0x409 /d "NDEBUG"
46 | # ADD RSC /l 0x409 /d "NDEBUG"
47 | BSC32=bscmake.exe
48 | # ADD BASE BSC32 /nologo
49 | # ADD BSC32 /nologo
50 | LINK32=link.exe
51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
52 | # ADD LINK32 shlwapi.lib ddraw.lib dxguid.lib /nologo /subsystem:windows /machine:I386
53 | # Begin Target
54 |
55 | # Name "Rebuilder - Win32 Release"
56 | # Begin Group "Source Files"
57 |
58 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
59 | # Begin Source File
60 |
61 | SOURCE=..\src\app.cpp
62 | # End Source File
63 | # Begin Source File
64 |
65 | SOURCE=..\src\clinkstatic.cpp
66 | # End Source File
67 | # Begin Source File
68 |
69 | SOURCE=..\ext\PropertyGrid\DynDialogEx.cpp
70 | # End Source File
71 | # Begin Source File
72 |
73 | SOURCE=..\ext\PropertyGrid\DynDialogItemEx.cpp
74 | # End Source File
75 | # Begin Source File
76 |
77 | SOURCE=..\src\launcher.cpp
78 | # End Source File
79 | # Begin Source File
80 |
81 | SOURCE=..\ext\PropertyGrid\ListDynDialogEx.cpp
82 | # End Source File
83 | # Begin Source File
84 |
85 | SOURCE=..\src\patchgrid.cpp
86 | # End Source File
87 | # Begin Source File
88 |
89 | SOURCE=..\cmn\path.cpp
90 | # End Source File
91 | # Begin Source File
92 |
93 | SOURCE=..\ext\PropertyGrid\PropertyGrid.cpp
94 | # End Source File
95 | # Begin Source File
96 |
97 | SOURCE=..\ext\PropertyGrid\PropertyGridCombo.cpp
98 | # End Source File
99 | # Begin Source File
100 |
101 | SOURCE=..\ext\PropertyGrid\PropertyGridDirectoryPicker.cpp
102 | # End Source File
103 | # Begin Source File
104 |
105 | SOURCE=..\ext\PropertyGrid\PropertyGridInPlaceEdit.cpp
106 | # End Source File
107 | # Begin Source File
108 |
109 | SOURCE=..\ext\PropertyGrid\PropertyGridMonthCalCtrl.cpp
110 | # End Source File
111 | # Begin Source File
112 |
113 | SOURCE=..\res\res.rc
114 | # End Source File
115 | # Begin Source File
116 |
117 | SOURCE=..\ext\PropertyGrid\stdafx.cpp
118 | # End Source File
119 | # Begin Source File
120 |
121 | SOURCE=..\src\tabs.cpp
122 | # End Source File
123 | # Begin Source File
124 |
125 | SOURCE=..\src\window.cpp
126 | # End Source File
127 | # End Group
128 | # Begin Group "Header Files"
129 |
130 | # PROP Default_Filter "h;hpp;hxx;hm;inl"
131 | # Begin Source File
132 |
133 | SOURCE=..\src\app.h
134 | # End Source File
135 | # Begin Source File
136 |
137 | SOURCE=..\src\clinkstatic.h
138 | # End Source File
139 | # Begin Source File
140 |
141 | SOURCE=..\cmn\combo.h
142 | # End Source File
143 | # Begin Source File
144 |
145 | SOURCE=..\ext\PropertyGrid\CustomItem.h
146 | # End Source File
147 | # Begin Source File
148 |
149 | SOURCE=..\ext\PropertyGrid\DynDialogEx.h
150 | # End Source File
151 | # Begin Source File
152 |
153 | SOURCE=..\ext\PropertyGrid\DynDialogItemEx.h
154 | # End Source File
155 | # Begin Source File
156 |
157 | SOURCE=..\src\launcher.h
158 | # End Source File
159 | # Begin Source File
160 |
161 | SOURCE=..\ext\PropertyGrid\ListDynDialogEx.h
162 | # End Source File
163 | # Begin Source File
164 |
165 | SOURCE=..\src\patchgrid.h
166 | # End Source File
167 | # Begin Source File
168 |
169 | SOURCE=..\cmn\path.h
170 | # End Source File
171 | # Begin Source File
172 |
173 | SOURCE=..\ext\PropertyGrid\PropertyGrid.h
174 | # End Source File
175 | # Begin Source File
176 |
177 | SOURCE=..\ext\PropertyGrid\PropertyGridCombo.h
178 | # End Source File
179 | # Begin Source File
180 |
181 | SOURCE=..\ext\PropertyGrid\PropertyGridDirectoryPicker.h
182 | # End Source File
183 | # Begin Source File
184 |
185 | SOURCE=..\ext\PropertyGrid\PropertyGridInPlaceEdit.h
186 | # End Source File
187 | # Begin Source File
188 |
189 | SOURCE=..\ext\PropertyGrid\PropertyGridMonthCalCtrl.h
190 | # End Source File
191 | # Begin Source File
192 |
193 | SOURCE=..\res\resource.h
194 | # End Source File
195 | # Begin Source File
196 |
197 | SOURCE=..\ext\PropertyGrid\stdafx.h
198 | # End Source File
199 | # Begin Source File
200 |
201 | SOURCE=..\src\tabs.h
202 | # End Source File
203 | # Begin Source File
204 |
205 | SOURCE=..\src\window.h
206 | # End Source File
207 | # End Group
208 | # Begin Group "Resource Files"
209 |
210 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
211 | # Begin Source File
212 |
213 | SOURCE=..\res\mama.ico
214 | # End Source File
215 | # End Group
216 | # Begin Source File
217 |
218 | SOURCE=..\res\res.manifest
219 | # End Source File
220 | # End Target
221 | # End Project
222 |
--------------------------------------------------------------------------------
/cmn/combo.h:
--------------------------------------------------------------------------------
1 | #ifndef COMBO_H
2 | #define COMBO_H
3 |
4 | enum ModelQuality {
5 | kModelQualityInfinite,
6 | kModelQualityHigh,
7 | kModelQualityMedium,
8 | kModelQualityLow
9 | };
10 |
11 | #endif // COMBO_H
12 |
--------------------------------------------------------------------------------
/cmn/path.cpp:
--------------------------------------------------------------------------------
1 | #include "path.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | LPCTSTR appName = TEXT("Rebuilder");
9 |
10 | BOOL DirectoryExists(LPCTSTR szPath)
11 | {
12 | return PathFileExists(szPath) && PathIsDirectory(szPath);
13 | }
14 |
15 | BOOL RecursivelyCreateDirectory(LPCTSTR directory)
16 | {
17 | if (DirectoryExists(directory)) {
18 | // Directory already exists, do nothing
19 | return TRUE;
20 | } else {
21 | // Determine directory of this directory
22 | std::basic_string copy = directory;
23 | PathRemoveFileSpec(©[0]);
24 |
25 | // Create if necessary
26 | if (RecursivelyCreateDirectory(copy.c_str())) {
27 | return CreateDirectory(directory, NULL);
28 | } else {
29 | return FALSE;
30 | }
31 | }
32 | }
33 |
34 | #ifdef UNICODE
35 | typedef BOOL (WINAPI *SHGetSpecialFolderPath_t)(HWND hwndOwner, LPWSTR lpszPath, int nFolder, BOOL fCreate);
36 | #else
37 | typedef BOOL (WINAPI *SHGetSpecialFolderPath_t)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
38 | #endif
39 | BOOL GetAppDataPath(LPTSTR s)
40 | {
41 | // Dynamically link to SHGetSpecialFolderPath because not all versions of Windows have it
42 | #ifdef UNICODE
43 | LPCSTR functionName = "SHGetSpecialFolderPathW";
44 | #else
45 | LPCSTR functionName = "SHGetSpecialFolderPathA";
46 | #endif
47 |
48 | SHGetSpecialFolderPath_t getSpecialFolderPath = (SHGetSpecialFolderPath_t)GetProcAddress(LoadLibrary(_T("SHELL32.DLL")), functionName);
49 | BOOL haveDir = FALSE;
50 | BOOL usedShell = FALSE;
51 | if (getSpecialFolderPath) {
52 | haveDir = getSpecialFolderPath(NULL, s, CSIDL_APPDATA, TRUE);
53 | usedShell = TRUE;
54 | } else {
55 | // Assume we're on Windows 95 which has no application data folder, we bodge it to write to
56 | // "C:\Windows\Application Data" which is roughly where 98/Me would do it
57 | GetWindowsDirectory(s, MAX_PATH);
58 | _tcscat(s, _T("\\Application Data"));
59 | haveDir = TRUE;
60 | }
61 |
62 | return haveDir;
63 | }
64 |
65 | BOOL GetConfigFilename(LPTSTR s)
66 | {
67 | if (GetAppDataPath(s)) {
68 | _tcscat(s, _T("\\LEGOIslandRebuilder"));
69 | if (RecursivelyCreateDirectory(s)) {
70 | _tcscat(s, _T("\\settings.ini"));
71 | return TRUE;
72 | }
73 | }
74 |
75 | return FALSE;
76 | }
77 |
78 | BOOL GetSafeLEGOIslandSavePath(LPTSTR s)
79 | {
80 | if (GetAppDataPath(s)) {
81 | _tcscat(s, _T("\\LEGO Island"));
82 | if (RecursivelyCreateDirectory(s)) {
83 | return TRUE;
84 | }
85 | }
86 |
87 | return FALSE;
88 | }
89 |
--------------------------------------------------------------------------------
/cmn/path.h:
--------------------------------------------------------------------------------
1 | #ifndef PATH_H
2 | #define PATH_H
3 |
4 | #include
5 |
6 | BOOL GetSafeLEGOIslandSavePath(LPTSTR s);
7 |
8 | BOOL GetConfigFilename(LPTSTR s);
9 |
10 | extern LPCTSTR appName;
11 |
12 | #endif // PATH_H
13 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/.gitignore:
--------------------------------------------------------------------------------
1 | build*/
2 | *.user
3 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 |
3 | project(PropertyGrid LANGUAGES CXX)
4 |
5 | set(CMAKE_MFC_FLAG 2)
6 | add_compile_definitions(_AFXDLL)
7 |
8 | option(PROPERTYGRID_BUILD_APP "Build with test application" ON)
9 |
10 | add_library(PropertyGrid STATIC
11 | CustomItem.h
12 | DynDialogEx.cpp
13 | DynDialogEx.h
14 | DynDialogItemEx.cpp
15 | DynDialogItemEx.h
16 | ListDynDialogEx.cpp
17 | ListDynDialogEx.h
18 | PropertyGrid.cpp
19 | PropertyGrid.h
20 | PropertyGridCombo.cpp
21 | PropertyGridCombo.h
22 | PropertyGridDirectoryPicker.cpp
23 | PropertyGridDirectoryPicker.h
24 | PropertyGridInPlaceEdit.cpp
25 | PropertyGridInPlaceEdit.h
26 | PropertyGridMonthCalCtrl.cpp
27 | PropertyGridMonthCalCtrl.h
28 | stdafx.cpp
29 | stdafx.h
30 | )
31 |
32 | target_link_libraries(PropertyGrid PRIVATE shlwapi.lib)
33 |
34 | if (PROPERTYGRID_BUILD_APP)
35 | add_subdirectory(test)
36 | endif()
37 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/CustomItem.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "PropertyGrid.h"
3 |
4 | class ICustomItem
5 | {
6 | public:
7 | // basic required stuff
8 | virtual CPropertyGrid::EEditMode GetEditMode() = 0;
9 | virtual void DrawItem(CDC& dc, CRect rc, bool focused) = 0;
10 |
11 | // validation
12 | virtual void ValidateChanges() {}
13 |
14 | // mouse stuff
15 | virtual bool OnLButtonDown(CRect rc, CPoint pt) { return false; }
16 | virtual void OnMouseMove(CRect rc, CPoint pt) {}
17 | virtual void OnLButtonUp(CRect rc, CPoint pt) {}
18 |
19 | // in-place edit
20 | virtual string GetStringForInPlaceEdit() { return ""; }
21 | virtual bool OnItemEdited(string strNewValue) { return false; }
22 |
23 | // dropdown edit
24 | virtual void ShowDropDown(CRect rc) {}
25 |
26 | // modal edit
27 | virtual bool OnEditItem() { return false; }
28 |
29 | protected:
30 | friend class CPropertyGrid;
31 | CPropertyGrid* m_pGrid;
32 | };
33 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/DynDialogEx.cpp:
--------------------------------------------------------------------------------
1 | // DynDialogItemEx.cpp: implementation of the CDynDialogItemEx class.
2 | //
3 | // Written by Marcel Scherpenisse
4 | // mailto:Marcel_Scherpenisse@insad.nl
5 | //
6 | // This code may be used in compiled form in any way you desire. This
7 | // file may be redistributed unmodified by any means PROVIDING it is
8 | // not sold for profit without the authors written consent, and
9 | // providing that this notice and the authors name and all copyright
10 | // notices remains intact. If the source code in this file is used in
11 | // any commercial application then a statement along the lines of
12 | // "Portions copyright (c) Marcel Scherpenisse, 2002" must be included in
13 | // the startup banner, "About" box or printed documentation. An email
14 | // letting me know that you are using it would be nice as well.
15 | //
16 | // This file is provided "as is" with no expressed or implied warranty.
17 | // The author accepts no liability for any damage/loss of business that
18 | // this product may cause.
19 | //
20 | // Expect bugs!
21 | //////////////////////////////////////////////////////////////////////
22 |
23 |
24 | #include "stdafx.h"
25 | #include "DynDialogEx.h"
26 |
27 | #ifdef _DEBUG
28 | #define new DEBUG_NEW
29 | #undef THIS_FILE
30 | static char THIS_FILE[] = __FILE__;
31 | #endif
32 |
33 | /////////////////////////////////////////////////////////////////////////////
34 | // CDynDialogEx dialog
35 |
36 |
37 | CDynDialogEx::CDynDialogEx(CWnd* pParent /*=NULL*/)
38 | : CDialog()
39 | {
40 | //{{AFX_DATA_INIT(CDynDialogEx)
41 | // NOTE: the ClassWizard will add member initialization here
42 | //}}AFX_DATA_INIT
43 |
44 | m_DialogTemplate.style = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_SETFONT;
45 | m_DialogTemplate.dwExtendedStyle = WS_EX_DLGMODALFRAME;
46 | m_DialogTemplate.x = 0;
47 | m_DialogTemplate.y = 0;
48 | m_DialogTemplate.cx = 0; // 4 horizontal units are the width of one character
49 | m_DialogTemplate.cy = 0; // 8 vertical units are the height of one character
50 | m_DialogTemplate.cdit = 0; // nr of dialog items in the dialog
51 |
52 | m_pParentWnd = pParent;
53 | m_strCaption = _T("");
54 | m_pFont = NULL;
55 | m_wFontSize = 0;
56 | m_nCurRow = FIRSTROW1;
57 | m_bAddSystemButtons = TRUE;
58 |
59 | m_bIsFontCreated = FALSE;
60 | m_bModelessDlg = FALSE;
61 | }
62 |
63 | CDynDialogEx::~CDynDialogEx()
64 | {
65 | CDynDialogItemEx *pDynDialogItemEx = NULL;
66 | for (INT_PTR i = m_arrDlgItemPtr.size() - 1; i >= 0; i--) {
67 | pDynDialogItemEx = m_arrDlgItemPtr[i];
68 | if (pDynDialogItemEx != NULL) {
69 | delete pDynDialogItemEx;
70 | pDynDialogItemEx = NULL;
71 | }
72 | }
73 |
74 | if (m_bIsFontCreated) {
75 | delete m_pFont;
76 | }
77 | }
78 |
79 | CWnd *CDynDialogEx::GetParent()
80 | {
81 | return m_pParentWnd;
82 | }
83 |
84 | void CDynDialogEx::AddStyles(DWORD dwStyles)
85 | {
86 | m_DialogTemplate.style |= dwStyles;
87 | }
88 |
89 | void CDynDialogEx::RemoveStyles(DWORD dwStyles)
90 | {
91 | m_DialogTemplate.style &= (~dwStyles);
92 | }
93 |
94 | void CDynDialogEx::DoDataExchange(CDataExchange* pDX)
95 | {
96 | CDialog::DoDataExchange(pDX);
97 | //{{AFX_DATA_MAP(CDynDialogEx)
98 | // NOTE: the ClassWizard will add DDX and DDV calls here
99 | //}}AFX_DATA_MAP
100 |
101 | CDynDialogItemEx *pDynDialogItemEx = NULL;
102 | for (INT_PTR i = m_arrDlgItemPtr.size() - 1; i >= 0; i--) {
103 | pDynDialogItemEx = m_arrDlgItemPtr[i];
104 | if (pDynDialogItemEx != NULL) {
105 | pDynDialogItemEx->DoDataExchange(pDX);
106 | }
107 | }
108 | }
109 |
110 | BEGIN_MESSAGE_MAP(CDynDialogEx, CDialog)
111 | //{{AFX_MSG_MAP(CDynDialogEx)
112 | ON_WM_CREATE()
113 | //}}AFX_MSG_MAP
114 | ON_MESSAGE(WM_HELP, OnHelpMsg)
115 | ON_WM_MEASUREITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
116 | ON_WM_DRAWITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
117 | END_MESSAGE_MAP()
118 |
119 | /////////////////////////////////////////////////////////////////////////////
120 | // CDynDialogEx message handlers
121 |
122 | int CDynDialogEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
123 | {
124 | if (CDialog::OnCreate(lpCreateStruct) == -1)
125 | return -1;
126 |
127 | //if we have no font, create one here
128 | if (m_pFont == NULL) {
129 | LOGFONT LogFont;
130 |
131 | // Can do better???
132 | memset(&LogFont, 0x00, sizeof(LogFont));
133 | strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
134 | LogFont.lfHeight = 8;
135 |
136 | m_pFont = new CFont;
137 | m_pFont->CreateFontIndirect(&LogFont);
138 | SetFont(m_pFont);
139 | m_bIsFontCreated = TRUE;
140 | }
141 |
142 | //Create all the controls on the dialog
143 | CDynDialogItemEx *pDynDialogItemEx = NULL;
144 | for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
145 | pDynDialogItemEx = m_arrDlgItemPtr[i];
146 | if (pDynDialogItemEx != NULL) {
147 | if (!pDynDialogItemEx->IsDlgItemSubclassed()) {
148 | if (!pDynDialogItemEx->CreateEx(this)) {
149 | AfxMessageBox(_T("Failed to create DlgItem."));
150 | }
151 | else if (pDynDialogItemEx->GetSafeHwnd() != NULL) {
152 | pDynDialogItemEx->SetFont(m_pFont, FALSE);
153 | }
154 | }
155 | }
156 | }
157 |
158 | return 0;
159 | }
160 |
161 | BOOL CDynDialogEx::OnInitDialog()
162 | {
163 | //Reposition all the controls on the dialog...
164 | CDynDialogItemEx *pDynDialogItemEx = NULL;
165 | for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
166 | pDynDialogItemEx = m_arrDlgItemPtr[i];
167 | if (pDynDialogItemEx != NULL) {
168 | if (!pDynDialogItemEx->IsDlgItemSubclassed() && !pDynDialogItemEx->SetWindowPos(this)) {
169 | CString strMessage;
170 | strMessage.Format(_T("Failed SetWindowPos for control %s."), pDynDialogItemEx->GetClassName());
171 | AfxMessageBox(strMessage);
172 | }
173 | }
174 | }
175 |
176 | CDialog::OnInitDialog();
177 |
178 | CenterWindow();
179 |
180 | return TRUE; // return TRUE unless you set the focus to a control
181 | // EXCEPTION: OCX Property Pages should return FALSE
182 | }
183 |
184 | int CDynDialogEx::DoModal()
185 | {
186 | //Do we need OK and Cancel buttons??
187 | if (m_bAddSystemButtons) {
188 | AddSystemButtons();
189 | }
190 |
191 | //
192 | // Get font info from mainwindow of the application
193 | //
194 | CFont* pParentFont = m_pFont;
195 | if (pParentFont == NULL && m_pParentWnd != NULL) {
196 | pParentFont = m_pParentWnd->GetFont();
197 | }
198 | if (pParentFont == NULL && AfxGetApp()->m_pActiveWnd != NULL) {
199 | pParentFont = AfxGetApp()->m_pActiveWnd->GetFont();
200 | }
201 | LOGFONT LogFont;
202 | memset(&LogFont, 0x00, sizeof(LogFont));
203 | if (pParentFont != NULL) {
204 | pParentFont->GetLogFont(&LogFont);
205 | }
206 | else {
207 | // Can do better???
208 | strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
209 | LogFont.lfHeight = 8;
210 | }
211 |
212 | //Prework for setting font in dialog...
213 | int cWC = MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, NULL, 0);
214 | int nFontNameLen = cWC + 1;
215 | WCHAR *szFontName = new WCHAR[nFontNameLen];
216 | // Copy the string
217 | MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, (LPWSTR) szFontName, cWC);
218 | szFontName[cWC] = 0;
219 | nFontNameLen = (cWC) * sizeof(WCHAR);
220 |
221 | if (m_wFontSize == 0) {
222 | m_wFontSize = (unsigned short)LogFont.lfHeight;
223 | }
224 |
225 | //Prework for setting caption in dialog...
226 | cWC = MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, NULL, 0);
227 | int szBoxLen = cWC + 1;
228 | WCHAR *szBoxCaption = new WCHAR[szBoxLen];
229 | // Copy the string
230 | MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, (LPWSTR) szBoxCaption, cWC);
231 | szBoxCaption[cWC] = 0;
232 | szBoxLen = (cWC) * sizeof(WCHAR);
233 |
234 | INT_PTR iRet = -1;
235 | //Here 's the stuff to build the dialog template in memory
236 | //without the controls being in the template
237 | //(Our first try, was this same template with some additional code
238 | //for each control placed on it, that's why this class is cold Ex :)
239 | //This gave some problems on WIN9x systems, where EDIT boxes
240 | //were not shown with 3D-look, but as flat controls)
241 | int nBufferSize = sizeof(DLGTEMPLATE) + (2 * sizeof(WORD)) /*menu and class*/ + szBoxLen /*size of caption*/
242 | + sizeof(WORD) /*fontsize*/ + nFontNameLen /*size of fontname*/;
243 |
244 | //Are there any subclassed controls...
245 | if (m_DialogTemplate.cdit > 0) {
246 | nBufferSize = (nBufferSize + 3) & ~3; // adjust size to make first control DWORD aligned
247 |
248 | CDynDialogItemEx *pDynDialogItemEx = NULL;
249 | for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
250 | pDynDialogItemEx = m_arrDlgItemPtr[i];
251 | if (pDynDialogItemEx != NULL) {
252 | if (pDynDialogItemEx->IsDlgItemSubclassed()) {
253 | int nItemLength = sizeof(DLGITEMTEMPLATE) + 3 * sizeof(WORD);
254 | nItemLength += (pDynDialogItemEx->GetCaptionLength() + 1) * sizeof(WCHAR);
255 |
256 | if (i != m_DialogTemplate.cdit - 1) { // the last control does not need extra bytes
257 | nItemLength = (nItemLength + 3) & ~3; // take into account gap so next control is DWORD aligned
258 | }
259 | nBufferSize += nItemLength;
260 | }
261 | }
262 | }
263 | }
264 |
265 | HLOCAL hLocal = LocalAlloc(LHND, nBufferSize);
266 | if (hLocal != NULL) {
267 | BYTE* pBuffer = (BYTE*)LocalLock(hLocal);
268 | if (pBuffer == NULL) {
269 | LocalFree(hLocal);
270 | AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalLock Failed"));
271 | }
272 |
273 | BYTE *pdest = pBuffer;
274 | // transfer DLGTEMPLATE structure to the buffer
275 | memcpy(pdest, &m_DialogTemplate, sizeof(DLGTEMPLATE)); // DLGTemplate
276 | pdest += sizeof(DLGTEMPLATE);
277 | *(WORD*)pdest = 0; // no menu -- WORD to say it is 0 bytes
278 | pdest += sizeof(WORD); // Increment
279 | *(WORD*)(pdest + 1) = 0; // use default window class -- WORD to say it is 0 bytes
280 | pdest += sizeof(WORD); // Increment
281 | memcpy(pdest, szBoxCaption, szBoxLen); // Caption
282 | pdest += szBoxLen;
283 |
284 | *(WORD*)pdest = m_wFontSize; // font size
285 | pdest += sizeof(WORD);
286 | memcpy(pdest, szFontName, nFontNameLen); // font name
287 | pdest += nFontNameLen;
288 |
289 | // will now transfer the information for each one of subclassed controls...
290 | if (m_DialogTemplate.cdit > 0) {
291 | CDynDialogItemEx *pDynDialogItemEx = NULL;
292 | for (int i = 0; i < m_arrDlgItemPtr.size(); i++) {
293 | pDynDialogItemEx = m_arrDlgItemPtr[i];
294 | if (pDynDialogItemEx != NULL) {
295 | if (pDynDialogItemEx->IsDlgItemSubclassed()) {
296 | pdest = pDynDialogItemEx->FillBufferWithItemTemplate(pdest);
297 | }
298 | }
299 | }
300 | }
301 | ASSERT(pdest - pBuffer == nBufferSize); // just make sure we did not overrun the heap
302 |
303 | //Next lines to make sure that MFC makes no ASSERTION when PREVIOUS/NEXT is pressed:)
304 | if (m_lpDialogTemplate != NULL) {
305 | m_lpDialogTemplate = NULL;
306 | }
307 |
308 | //These are the MFC functions, which do the job...
309 | if (m_bModelessDlg) {
310 | iRet = CreateIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
311 | }
312 | else {
313 | InitModalIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
314 | iRet = CDialog::DoModal();
315 | }
316 |
317 | LocalUnlock(hLocal);
318 | LocalFree(hLocal);
319 |
320 | delete [] szBoxCaption;
321 | delete [] szFontName;
322 | return iRet;
323 | }
324 | else {
325 | AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalAllock Failed"));
326 | return -1;
327 | }
328 | }
329 |
330 | void CDynDialogEx::SetFont(CFont *pFont)
331 | {
332 | m_pFont = pFont;
333 | }
334 |
335 | CFont *CDynDialogEx::GetFont()
336 | {
337 | return m_pFont;
338 | }
339 |
340 | void CDynDialogEx::SetFontSize(WORD wSize)
341 | {
342 | m_wFontSize = wSize;
343 | }
344 |
345 | WORD CDynDialogEx::GetFontSize()
346 | {
347 | return m_wFontSize;
348 | }
349 |
350 | void CDynDialogEx::SetUseSystemButtons(BOOL bUse /*= TRUE*/)
351 | {
352 | m_bAddSystemButtons = bUse;
353 | }
354 |
355 | void CDynDialogEx::GetDlgRect(LPRECT lpRect)
356 | {
357 | ASSERT(lpRect);
358 | lpRect->left = m_DialogTemplate.x;
359 | lpRect->top = m_DialogTemplate.y;
360 | lpRect->right = lpRect->left + m_DialogTemplate.cx;
361 | lpRect->bottom = lpRect->top + m_DialogTemplate.cy;
362 | }
363 |
364 | void CDynDialogEx::SetDlgRect(LPRECT lpRect)
365 | {
366 | ASSERT(lpRect);
367 | //#pragma warning(disable : 4244)
368 | m_DialogTemplate.cx = (short)(lpRect->right - lpRect->left);
369 | m_DialogTemplate.cy = (short)(lpRect->bottom - lpRect->top);
370 | m_DialogTemplate.x = (short)(lpRect->left);
371 | m_DialogTemplate.y = (short)(lpRect->top);
372 | //#pragma warning(default : 4244)
373 | }
374 |
375 | void CDynDialogEx::SetDlgRectangle(LPRECT pRect)
376 | {
377 | RECT rect;
378 |
379 | GetDlgRect(&rect);
380 | if (rect.left > pRect->left) {
381 | rect.left = pRect->left;
382 | }
383 | if (rect.right < pRect->right) {
384 | rect.right = pRect->right + 5;
385 | }
386 | if (rect.top > pRect->top) {
387 | rect.top = pRect->top;
388 | }
389 | if (rect.bottom < pRect->bottom) {
390 | rect.bottom = pRect->bottom + 5;
391 | }
392 | SetDlgRect(&rect);
393 | }
394 |
395 | UINT CDynDialogEx::AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl,
396 | LPCTSTR lpszCaption,
397 | DWORD dwStyle,
398 | DWORD dwExtendedStyle,
399 | LPRECT pRect /*= NULL*/,
400 | void *pData /*= NULL*/,
401 | UINT nID /*= 0*/)
402 | {
403 | UINT nRet = 0;
404 | //In case no rectangle given create our own...
405 | CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
406 |
407 | //if no rectangle given use our own...
408 | if (pRect == NULL) {
409 | pRect = &Rect;
410 | }
411 | // else {
412 | // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
413 | // }
414 |
415 | m_nCurRow += (ROWSTEPSIZE);
416 |
417 | //Update dialogtemplate boundaries
418 | SetDlgRectangle(pRect);
419 |
420 | //Create control and add to array of controls
421 | CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
422 | if (pDynDialogItemEx != NULL) {
423 | nRet = pDynDialogItemEx->InitDialogItem(TypeControl, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
424 | m_arrDlgItemPtr.push_back(pDynDialogItemEx);
425 | }
426 |
427 | //Return ID of Control we created.
428 | return nRet;
429 | }
430 |
431 | UINT CDynDialogEx::AddDlgControl(LPCSTR lpszClassName,
432 | LPCTSTR lpszCaption,
433 | DWORD dwStyle,
434 | DWORD dwExtendedStyle,
435 | LPRECT pRect /*= NULL*/,
436 | void *pData /*= NULL*/,
437 | UINT nID /*= 0*/)
438 | {
439 | UINT nRet = 0;
440 | //In case no rectangle given create our own...
441 | CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
442 |
443 | //if no rectangle given use our own...
444 | if (pRect == NULL) {
445 | pRect = &Rect;
446 | Rect.right += INPUTCOL;
447 | }
448 | // else {
449 | // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
450 | // }
451 |
452 | m_nCurRow += (ROWSTEPSIZE);
453 |
454 | //Update dialogtemplate boundaries
455 | SetDlgRectangle(pRect);
456 |
457 | //Create control and add to array of controls
458 | CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
459 | if (pDynDialogItemEx != NULL) {
460 | nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
461 | m_arrDlgItemPtr.push_back(pDynDialogItemEx);
462 | }
463 |
464 | //Return ID of Control we created.
465 | return nRet;
466 | }
467 |
468 | UINT CDynDialogEx::AddSubclassedDlgControl(LPCSTR lpszClassName,
469 | LPCTSTR lpszCaption,
470 | DWORD dwStyle,
471 | DWORD dwExtendedStyle,
472 | LPRECT pRect /*= NULL*/,
473 | UINT nID /*= 0*/)
474 | {
475 | UINT nRet = 0;
476 | //In case no rectangle given create our own...
477 | CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
478 |
479 | //if no rectangle given use our own...
480 | if (pRect == NULL) {
481 | pRect = &Rect;
482 | Rect.right += INPUTCOL;
483 | }
484 | // else {
485 | // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
486 | // }
487 |
488 | m_nCurRow += (ROWSTEPSIZE);
489 |
490 | //Update dialogtemplate boundaries
491 | SetDlgRectangle(pRect);
492 |
493 | //Create control and add to array of controls
494 | CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
495 | if (pDynDialogItemEx != NULL) {
496 | nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, TRUE);
497 | m_arrDlgItemPtr.push_back(pDynDialogItemEx);
498 | m_DialogTemplate.cdit++;
499 | }
500 |
501 | //Return ID of Control we created.
502 | return nRet;
503 | }
504 |
505 | void CDynDialogEx::AddSystemButtons()
506 | {
507 | m_nCurRow += 6; // Leave some room!
508 | CRect rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2 - 60, m_nCurRow + (long)(ROWSTEPSIZE * 1.2));
509 |
510 | AddDlgControl(BUTTON, _T("OK"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDOK);
511 |
512 | // This has to be revised later.
513 | rect.left += 55;
514 | rect.right += 55;
515 | AddDlgControl(BUTTON, _T("Annuleren"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDCANCEL);
516 |
517 | }
518 |
519 | void CDynDialogEx::SetWindowTitle(LPCSTR lpszCaption)
520 | {
521 | m_strCaption = lpszCaption;
522 | }
523 |
524 | void CDynDialogEx::SetUseModeless(BOOL bModelessDlg /*= TRUE*/)
525 | {
526 | m_bModelessDlg = bModelessDlg;
527 | }
528 |
529 | void CDynDialogEx::OnCancel()
530 | {
531 | if (m_bModelessDlg) {
532 | DestroyWindow();
533 | }
534 | else {
535 | CDialog::OnCancel();
536 | }
537 | }
538 |
539 | void CDynDialogEx::OnOK()
540 | {
541 | if (m_bModelessDlg) {
542 | DestroyWindow();
543 | }
544 | else {
545 | CDialog::OnOK();
546 | }
547 | }
548 |
549 | BOOL CDynDialogEx::OnCommand(WPARAM wParam, LPARAM lParam)
550 | {
551 | //wParam
552 | //The low-order word of wParam identifies the command ID of the menu item, control, or accelerator.
553 | //The high-order word of wParam specifies the notification message if the message is from a control.
554 | //If the message is from an accelerator, the high-order word is 1.
555 | //If the message is from a menu, the high-order word is 0.
556 |
557 | //lParam
558 | //Identifies the control that sends the message if the message is from a control. Otherwise, lParam is 0.
559 |
560 | WORD wControlID = LOWORD(wParam);
561 | WORD wMessageID = HIWORD(wParam);
562 |
563 | if (wControlID != 0) {
564 | switch (wControlID) {
565 | case IDOK:
566 | OnOK();
567 | return TRUE;
568 | break;
569 | case IDCANCEL:
570 | OnCancel();
571 | return TRUE;
572 | break;
573 | default:
574 | //if we have a parent send the message to the parent, so we can handle the message over there.
575 | if (m_pParentWnd != NULL) {
576 | ::SendMessage(m_pParentWnd->GetSafeHwnd(), WM_COMMAND, wParam, lParam);
577 | }
578 | break;
579 | }
580 | }
581 |
582 | return CDialog::OnCommand(wParam, lParam);
583 | }
584 |
585 | // Hellup!
586 | afx_msg LRESULT CDynDialogEx::OnHelpMsg(WPARAM wParam, LPARAM lParam)
587 | {
588 | //lParam <<-- Contains: (LPHELPINFO)lParam
589 | // >> typedef struct tagHELPINFO {
590 | // UINT cbSize;
591 | // int iContextType
592 | // int iCtrlId;
593 | // HANDLE hItemHandle;
594 | // DWORD dwContextId;
595 | // POINT MousePos;
596 | // } HELPINFO, FAR *LPHELPINFO;
597 |
598 | //
599 | // User pressed F1 in dialog, call the OnHelp() function, this can be overridden...
600 | //
601 | OnHelp();
602 | return TRUE;
603 | }
604 |
605 | // Default implementation of the OnHelp()
606 | // This one is to be overridden by a caller ;)
607 | void CDynDialogEx::OnHelp()
608 | {
609 | CDialog::OnHelp();
610 | }
611 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/DynDialogEx.h:
--------------------------------------------------------------------------------
1 | #if !defined(AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
2 | #define AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_
3 |
4 | #if _MSC_VER > 1000
5 | #pragma once
6 | #endif // _MSC_VER > 1000
7 | // DynDialogEx.h : header file
8 | //
9 |
10 | #include
11 | #include "DynDialogItemEx.h"
12 |
13 | // Control styles
14 | #define STYLE_EDIT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | SS_LEFT)
15 | #define STYLE_MULTIEDIT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | SS_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | ES_WANTRETURN)
16 | #define STYLE_STATIC (WS_VISIBLE | WS_CHILD | SS_LEFT)
17 | #define STYLE_STATIC_CENTER (WS_VISIBLE | WS_CHILD | SS_CENTER)
18 | #define STYLE_STATIC_RIGHT (WS_VISIBLE | WS_CHILD | SS_RIGHT)
19 | #define STYLE_RADIO (WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON)
20 | #define STYLE_RADIO_GROUP (STYLE_RADIO| WS_GROUP | WS_TABSTOP)
21 | #define STYLE_BUTTON (WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON)
22 | #define STYLE_GROUPBOX (WS_VISIBLE | WS_CHILD | BS_GROUPBOX)
23 | #define STYLE_CHECKBOX (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | BS_AUTOCHECKBOX)
24 | #define STYLE_COMBOBOX_DROPDOWN (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
25 | #define STYLE_COMBOBOX_DROPDOWN_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWN | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
26 | #define STYLE_COMBOBOX_SIMPLE (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_SIMPLE | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
27 | #define STYLE_COMBOBOX_SIMPLE_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_SIMPLE | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
28 | #define STYLE_COMBOBOX_DROPDOWNLIST (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_SORT | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
29 | #define STYLE_COMBOBOX_DROPDOWNLIST_NOSORT (WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_AUTOHSCROLL) // | CBS_DISABLENOSCROLL)
30 | #define STYLE_LISTBOX (WS_VISIBLE | WS_CHILD | WS_TABSTOP | LBS_STANDARD)
31 |
32 | #define STYLE_DATETIMEPICKER (WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_RIGHTALIGN)
33 | #define STYLE_TIMEPICKER (WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_RIGHTALIGN | DTS_TIMEFORMAT)
34 | // Default combo-style
35 | #define STYLE_COMBOBOX (STYLE_COMBOBOX_DROPDOWNLIST)
36 | #define STYLE_COMBOBOX_NOSORT (STYLE_COMBOBOX_DROPDOWNLIST_NOSORT)
37 |
38 | // Control Extended styles
39 | #define EXSTYLE_EDIT (WS_EX_CLIENTEDGE)
40 | #define EXSTYLE_MULTIEDIT (WS_EX_CLIENTEDGE)
41 | #define EXSTYLE_LISTBOX (WS_EX_CLIENTEDGE)
42 | #define EXSTYLE_STATIC (0)
43 | #define EXSTYLE_RADIO (0)
44 | #define EXSTYLE_BUTTON (0)
45 | #define EXSTYLE_GROUPBOX (0)
46 | #define EXSTYLE_CHECKBOX (0)
47 | #define EXSTYLE_COMBOBOX (0)
48 | #define EXSTYLE_DATETIMEPICKER (0)
49 | #define EXSTYLE_TIMEPICKER (0)
50 |
51 | #define ROWSTEPSIZE 12
52 | #define FIRSTROW1 10
53 | #define FIRSTROW2 37
54 | #define FIXEDCOL1 10
55 | #define FIXEDCOL2 120
56 | #define INPUTCOL 150
57 | #define GROWLIMIT 6
58 |
59 | #define MAX_COLS_PER_DESCR 25 // Just a number..
60 |
61 | /////////////////////////////////////////////////////////////////////////////
62 | // CDynDialogEx dialog
63 |
64 | class CDynDialogEx : public CDialog
65 | {
66 | // Construction
67 | public:
68 | CDynDialogEx(CWnd* pParent = NULL); // standard constructor
69 | ~CDynDialogEx();
70 |
71 | virtual CWnd *GetParent();
72 |
73 | // Dialog Data
74 | //{{AFX_DATA(CDynDialogEx)
75 | // NOTE: the ClassWizard will add data members here
76 | //}}AFX_DATA
77 |
78 | virtual UINT AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl,
79 | LPCTSTR lpszCaption,
80 | DWORD dwStyle,
81 | DWORD dwExtendedStyle,
82 | LPRECT pRect = NULL,
83 | void *pData = NULL,
84 | UINT nID = 0);
85 | virtual UINT AddDlgControl(LPCSTR lpszClassName,
86 | LPCTSTR lpszCaption,
87 | DWORD dwStyle,
88 | DWORD dwExtendedStyle,
89 | LPRECT pRect = NULL,
90 | void *pData = NULL,
91 | UINT nID = 0);
92 | virtual UINT AddSubclassedDlgControl(LPCSTR lpszClassName,
93 | LPCTSTR lpszCaption,
94 | DWORD dwStyle,
95 | DWORD dwExtendedStyle,
96 | LPRECT pRect = NULL,
97 | UINT nID = 0);
98 | void SetWindowTitle(LPCSTR lpszCaption);
99 | void SetFont(CFont *pFont);
100 | CFont *GetFont();
101 | void SetFontSize(WORD wSize);
102 | WORD GetFontSize();
103 | void SetUseSystemButtons(BOOL bUse = TRUE);
104 | void SetUseModeless(BOOL bModelessDlg = TRUE);
105 | long GetNumberOfConrols() {return long(m_arrDlgItemPtr.size());}
106 |
107 | //Additional functions by Tom Daffin
108 | void AddStyles(DWORD dwStyles);
109 | void RemoveStyles(DWORD dwStyles);
110 |
111 | // Overrides
112 | // ClassWizard generated virtual function overrides
113 | //{{AFX_VIRTUAL(CDynDialogEx)
114 | public:
115 | virtual int DoModal();
116 | protected:
117 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
118 | virtual void OnCancel();
119 | virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
120 | virtual void OnOK();
121 | //}}AFX_VIRTUAL
122 | virtual void OnHelp(); // To be overridden..
123 |
124 | protected:
125 | CWnd *m_pParentWnd;
126 | CString m_strCaption;
127 | CFont *m_pFont;
128 | WORD m_wFontSize;
129 | long m_nCurRow;
130 | BOOL m_bAddSystemButtons;
131 | BOOL m_bIsFontCreated;
132 | BOOL m_bModelessDlg;
133 |
134 | DLGTEMPLATE m_DialogTemplate;
135 |
136 | // DOWNGRADE: Switch from CArray to std::vector because MFC 4.2 doesn't have CArray
137 | std::vector m_arrDlgItemPtr;
138 |
139 | // Implementation
140 | protected:
141 | void AddSystemButtons();
142 | void GetDlgRect(LPRECT lpRect);
143 | void SetDlgRect(LPRECT lpRect);
144 | void SetDlgRectangle(LPRECT pRect);
145 |
146 |
147 | // Generated message map functions
148 | //{{AFX_MSG(CDynDialogEx)
149 | virtual BOOL OnInitDialog();
150 | afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
151 | //}}AFX_MSG
152 | afx_msg LRESULT OnHelpMsg(WPARAM wParam, LPARAM lParam);
153 |
154 | DECLARE_MESSAGE_MAP()
155 | };
156 |
157 | //{{AFX_INSERT_LOCATION}}
158 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
159 |
160 | #endif // !defined(AFX_DYNDIALOGEX_H__CF5AF5E8_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
161 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/DynDialogItemEx.cpp:
--------------------------------------------------------------------------------
1 | // DynDialogItemEx.cpp: implementation of the CDynDialogItemEx class.
2 | //
3 | // Written by Marcel Scherpenisse
4 | // mailto:Marcel_Scherpenisse@insad.nl
5 | //
6 | // This code may be used in compiled form in any way you desire. This
7 | // file may be redistributed unmodified by any means PROVIDING it is
8 | // not sold for profit without the authors written consent, and
9 | // providing that this notice and the authors name and all copyright
10 | // notices remains intact. If the source code in this file is used in
11 | // any commercial application then a statement along the lines of
12 | // "Portions copyright (c) Marcel Scherpenisse, 2002" must be included in
13 | // the startup banner, "About" box or printed documentation. An email
14 | // letting me know that you are using it would be nice as well.
15 | //
16 | // This file is provided "as is" with no expressed or implied warranty.
17 | // The author accepts no liability for any damage/loss of business that
18 | // this product may cause.
19 | //
20 | // Expect bugs!
21 | //////////////////////////////////////////////////////////////////////
22 |
23 |
24 | #include "stdafx.h"
25 | #include "DynDialogItemEx.h"
26 |
27 | #ifdef _DEBUG
28 | #undef THIS_FILE
29 | static char THIS_FILE[]=__FILE__;
30 | #define new DEBUG_NEW
31 | #endif
32 |
33 | struct _RuntimeLicense {
34 | LPCTSTR lpszRegisteredControlName;
35 | WCHAR *wchLicenseKey;
36 | long lLicenseLength;
37 | }_TAGRUNTIMELICENSE;
38 |
39 | /*mgkgtgnnmnmninigthkgogggvmkhinjggnvm*/ //(MS Multimedia MCI Control - mci32.ocx)
40 | WCHAR pwchMCIMMControl1LicenseKey[] =
41 | {
42 | 0x006D, 0x0067, 0x006B, 0x0067, 0x0074, 0x0067,
43 | 0x006E, 0x006E, 0x006D, 0x006E, 0x006D, 0x006E,
44 | 0x0069, 0x006E, 0x0069, 0x0067, 0x0074, 0x0068,
45 | 0x006B, 0x0067, 0x006F, 0x0067, 0x0067, 0x0067,
46 | 0x0076, 0x006D, 0x006B, 0x0068, 0x0069, 0x006E,
47 | 0x006A, 0x0067, 0x0067, 0x006E, 0x0076, 0x006D
48 | };
49 |
50 | /*Copyright (c) 1994 */ //(MS Communications Control - mscomm32.ocx)
51 | WCHAR pwchMSCOMMLibMSComm1LicenseKey[] =
52 | {
53 | 0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
54 | 0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
55 | 0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
56 | 0x0020
57 | };
58 |
59 | /*72E67120-5959-11cf-91F6-C2863C385E30*/ //(MS Flex Grid Control - msflxgrd.ocx)
60 | WCHAR pwchMSFlexGridLibMSFlexGrid1LicenseKey[] =
61 | {
62 | 0x0037, 0x0032, 0x0045, 0x0036, 0x0037, 0x0031,
63 | 0x0032, 0x0030, 0x002D, 0x0035, 0x0039, 0x0035,
64 | 0x0039, 0x002D, 0x0031, 0x0031, 0x0063, 0x0066,
65 | 0x002D, 0x0039, 0x0031, 0x0046, 0x0036, 0x002D,
66 | 0x0043, 0x0032, 0x0038, 0x0036, 0x0033, 0x0043,
67 | 0x0033, 0x0038, 0x0035, 0x0045, 0x0033, 0x0030
68 | };
69 |
70 | /*mgkgtgnnmnmninigthkgogggvmkhinjggnvm*/ //(MS Masked Edit - msmask32.ocx)
71 | WCHAR pwchMSMaskMaskEdBox1LicenseKey[] =
72 | {
73 | 0x006D, 0x0067, 0x006B, 0x0067, 0x0074, 0x0067,
74 | 0x006E, 0x006E, 0x006D, 0x006E, 0x006D, 0x006E,
75 | 0x0069, 0x006E, 0x0069, 0x0067, 0x0074, 0x0068,
76 | 0x006B, 0x0067, 0x006F, 0x0067, 0x0067, 0x0067,
77 | 0x0076, 0x006D, 0x006B, 0x0068, 0x0069, 0x006E,
78 | 0x006A, 0x0067, 0x0067, 0x006E, 0x0076, 0x006D
79 | };
80 |
81 | /*GL........*/ //(MS Grid Control - grid32.ocx)
82 | WCHAR pwchMSDBGridDBGridLicenseKey[] =
83 | {
84 | 0x0047, 0x004C, 0x0005, 0x0008, 0x0001, 0x0005,
85 | 0x0002, 0x0008, 0x0001, 0x0004
86 | };
87 |
88 | /*DB4C0D09-400B-101B-A3C9-08002B2F49FB*/ //(MS Picture Clip Control - picclp32.ocx)
89 | WCHAR pwchPicClipPictureClip1LicenseKey[] =
90 | {
91 | 0x0044, 0x0042, 0x0034, 0x0043, 0x0030, 0x0044,
92 | 0x0030, 0x0039, 0x002D, 0x0034, 0x0030, 0x0030,
93 | 0x0042, 0x002D, 0x0031, 0x0030, 0x0031, 0x0042,
94 | 0x002D, 0x0041, 0x0033, 0x0043, 0x0039, 0x002D,
95 | 0x0030, 0x0038, 0x0030, 0x0030, 0x0032, 0x0042,
96 | 0x0032, 0x0046, 0x0034, 0x0039, 0x0046, 0x0042
97 | };
98 |
99 | /*04746E60CE4F11CDB23C0000C076FE*/ //(MS Tab Control - tabctl32.ocx)
100 | static WCHAR pwchTabDlgSSTab1LicenseKey[] =
101 | {
102 | 0x0030, 0x0034, 0x0037, 0x0034, 0x0036, 0x0045,
103 | 0x0036, 0x0030, 0x0043, 0x0045, 0x0034, 0x0046,
104 | 0x0031, 0x0031, 0x0043, 0x0044, 0x0042, 0x0032,
105 | 0x0033, 0x0043, 0x0030, 0x0030, 0x0030, 0x0030,
106 | 0x0043, 0x0030, 0x0037, 0x0036, 0x0046, 0x0045
107 | };
108 |
109 | static _RuntimeLicense RuntimeLicenses[] =
110 | {
111 | {_T("MCI.MMControl.1"), pwchMCIMMControl1LicenseKey, sizeof(pwchMCIMMControl1LicenseKey)},
112 | {_T("MSCOMMLib.MSComm.1"), pwchMSCOMMLibMSComm1LicenseKey, sizeof(pwchMSCOMMLibMSComm1LicenseKey)},
113 | {_T("MSFlexGridLib.MSFlexGrid.1"), pwchMSFlexGridLibMSFlexGrid1LicenseKey, sizeof(pwchMSFlexGridLibMSFlexGrid1LicenseKey)},
114 | {_T("MSMask.MaskEdBox.1"), pwchMSMaskMaskEdBox1LicenseKey, sizeof(pwchMSMaskMaskEdBox1LicenseKey)},
115 | {_T("MSDBGrid.DBGrid"), pwchMSDBGridDBGridLicenseKey, sizeof(pwchMSDBGridDBGridLicenseKey)},
116 | {_T("PicClip.PictureClip.1"), pwchPicClipPictureClip1LicenseKey, sizeof(pwchPicClipPictureClip1LicenseKey)},
117 | {_T("TabDlg.SSTab.1"), pwchTabDlgSSTab1LicenseKey, sizeof(pwchTabDlgSSTab1LicenseKey)},
118 | {NULL, NULL, 0}
119 | };
120 |
121 | static UINT glb_nNextID = WM_USER; // We have to start somewhere...
122 |
123 | UINT GetNewUniqueID(void)
124 | {
125 | glb_nNextID++;
126 | return glb_nNextID - 1;
127 | }
128 |
129 | //////////////////////////////////////////////////////////////////////
130 | // Construction/Destruction
131 | //////////////////////////////////////////////////////////////////////
132 |
133 | CDynDialogItemEx::CDynDialogItemEx()
134 | : CWnd()
135 | {
136 | m_eTypeControl = NOCONTROL;
137 | m_strClassName = _T("");
138 | m_dwStyle = 0;
139 | m_dwStyleEx = 0;
140 | m_strCaption = _T("");
141 | m_ControlID = 0;
142 | m_pData = NULL;
143 | m_bSubclassed = FALSE;
144 | }
145 |
146 | void CDynDialogItemEx::DoDataExchange(CDataExchange *pDX)
147 | {
148 | if (m_pData != NULL) {
149 | switch(m_eTypeControl) {
150 | case BUTTON:
151 | if ((m_dwStyle & BS_AUTORADIOBUTTON) == BS_AUTORADIOBUTTON) {
152 | DDX_Radio(pDX, m_ControlID, *(int*)m_pData);
153 | }
154 | else if ((m_dwStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX) {
155 | DDX_Check(pDX, m_ControlID, *(int*)m_pData);
156 | }
157 | else {
158 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
159 | }
160 | break;
161 | case EDITCONTROL:
162 | DDX_Text(pDX, m_ControlID, *(CString*)m_pData);
163 | break;
164 | case STATICTEXT:
165 | DDX_Text(pDX, m_ControlID, *(CString*)m_pData);
166 | break;
167 | case LISTBOX:
168 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
169 | break;
170 | case HSCROLL:
171 | DDX_Scroll(pDX, m_ControlID, *(int*)m_pData);
172 | break;
173 | case COMBOBOX:
174 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
175 | break;
176 | case SPIN:
177 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
178 | break;
179 | case PROGRES:
180 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
181 | break;
182 | case SLIDER:
183 | DDX_Slider(pDX, m_ControlID, *(int*)m_pData);
184 | break;
185 | case HOTKEY:
186 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
187 | break;
188 | case LISTCTRL:
189 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
190 | break;
191 | case TREECTRL:
192 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
193 | break;
194 | case TABCTRL:
195 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
196 | break;
197 | case ANIMATE:
198 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
199 | break;
200 | case RICHEDIT:
201 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
202 | break;
203 | case DATETIMEPICKER:
204 | if ((m_dwStyle & DTS_TIMEFORMAT) == DTS_TIMEFORMAT) {
205 | DDX_DateTimeCtrl(pDX, m_ControlID, *(CTime*)m_pData);
206 | }
207 | else {
208 | DDX_DateTimeCtrl(pDX, m_ControlID, *(COleDateTime*)m_pData);
209 | }
210 | break;
211 | case MONTHCALENDER:
212 | DDX_MonthCalCtrl(pDX, m_ControlID, *(COleDateTime*)m_pData);
213 | break;
214 | case IPADRESS:
215 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
216 | break;
217 | case COMBOBOXEX:
218 | DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData);
219 | break;
220 | default:
221 | break;
222 | }
223 | }
224 | CWnd::DoDataExchange(pDX);
225 | }
226 |
227 | BEGIN_MESSAGE_MAP(CDynDialogItemEx, CWnd)
228 | //{{AFX_MSG_MAP(CDynDialogItemEx)
229 | //}}AFX_MSG_MAP
230 | END_MESSAGE_MAP()
231 |
232 | char* CDynDialogItemEx::GetClassNameByType(DLGITEMTEMPLATECONTROLS TypeControl)
233 | {
234 | switch(TypeControl) {
235 | case BUTTON:
236 | return _T("BUTTON");
237 | case EDITCONTROL:
238 | return _T("EDIT");
239 | case STATICTEXT:
240 | return _T("STATIC");
241 | case LISTBOX:
242 | return _T("LISTBOX");
243 | case HSCROLL:
244 | return _T("SCROLLBAR");
245 | case COMBOBOX:
246 | return _T("COMBOBOX");
247 | case SPIN:
248 | return _T("msctls_updown32");
249 | case PROGRES:
250 | return _T("msctls_progress32");
251 | case SLIDER:
252 | return _T("msctls_trackbar32");
253 | case HOTKEY:
254 | return _T("msctls_hotkey32");
255 | case LISTCTRL:
256 | return _T("SysListView32");
257 | case TREECTRL:
258 | return _T("SysTreeView32");
259 | case TABCTRL:
260 | return _T("SysTabControl32");
261 | case ANIMATE:
262 | return _T("SysAnimate32");
263 | case RICHEDIT:
264 | return _T("RICHEDIT");
265 | case DATETIMEPICKER:
266 | return _T("SysDateTimePick32");
267 | case MONTHCALENDER:
268 | return _T("SysMonthCal32");
269 | case IPADRESS:
270 | return _T("SysIPAddress32");
271 | case COMBOBOXEX:
272 | return _T("ComboBoxEx32");
273 | }
274 | return _T("");
275 | }
276 |
277 | DLGITEMTEMPLATECONTROLS CDynDialogItemEx::GetClassTypeByName(LPCSTR lpszClassName)
278 | {
279 | if (memcmp(lpszClassName, _T("BUTTON"), 6) == 0) {
280 | return BUTTON;
281 | }
282 | else if (memcmp(lpszClassName, _T("EDIT"), 4) == 0) {
283 | return EDITCONTROL;
284 | }
285 | else if (memcmp(lpszClassName, _T("STATIC"), 6) == 0) {
286 | return STATICTEXT;
287 | }
288 | else if (memcmp(lpszClassName, _T("LISTBOX"), 7) == 0) {
289 | return LISTBOX;
290 | }
291 | else if (memcmp(lpszClassName, _T("SCROLLBAR"), 9) == 0) {
292 | return HSCROLL;
293 | }
294 | else if (memcmp(lpszClassName, _T("COMBOBOX"), 8) == 0) {
295 | return COMBOBOX;
296 | }
297 | else if (memcmp(lpszClassName, _T("msctls_updown32"), 15) == 0) {
298 | return SPIN;
299 | }
300 | else if (memcmp(lpszClassName, _T("msctls_progress32"), 17) == 0) {
301 | return PROGRES;
302 | }
303 | else if (memcmp(lpszClassName, _T("msctls_trackbar32"), 17) == 0) {
304 | return SLIDER;
305 | }
306 | else if (memcmp(lpszClassName, _T("msctls_hotkey32"), 15) == 0) {
307 | return HOTKEY;
308 | }
309 | else if (memcmp(lpszClassName, _T("SysListView32"), 13) == 0) {
310 | return LISTCTRL;
311 | }
312 | else if (memcmp(lpszClassName, _T("SysTreeView32"), 13) == 0) {
313 | return TREECTRL;
314 | }
315 | else if (memcmp(lpszClassName, _T("SysTabControl32"), 15) == 0) {
316 | return TABCTRL;
317 | }
318 | else if (memcmp(lpszClassName, _T("SysAnimate32"), 12) == 0) {
319 | return ANIMATE;
320 | }
321 | else if (memcmp(lpszClassName, _T("RICHEDIT"), 8) == 0) {
322 | return RICHEDIT;
323 | }
324 | else if (memcmp(lpszClassName, _T("SysDateTimePick32"), 17) == 0) {
325 | return DATETIMEPICKER;
326 | }
327 | else if (memcmp(lpszClassName, _T("SysMonthCal32"), 13) == 0) {
328 | return MONTHCALENDER;
329 | }
330 | else if (memcmp(lpszClassName, _T("SysIPAddress32"), 14) == 0) {
331 | return IPADRESS;
332 | }
333 | else if (memcmp(lpszClassName, _T("ComboBoxEx32"), 12) == 0) {
334 | return COMBOBOXEX;
335 | }
336 |
337 | return NOCONTROL;
338 | }
339 |
340 | UINT CDynDialogItemEx::InitDialogItem(DLGITEMTEMPLATECONTROLS TypeControl,
341 | DWORD dwStyle,
342 | DWORD dwExtendedStyle,
343 | LPRECT pRect,
344 | LPCTSTR lpszCaption,
345 | UINT nID /*= 0*/,
346 | BOOL bSubclassed /*= FALSE*/,
347 | void *pData /*= NULL*/)
348 | {
349 | m_eTypeControl = TypeControl;
350 | m_strClassName = GetClassNameByType(m_eTypeControl);
351 | m_dwStyle = dwStyle;
352 | m_dwStyleEx = dwExtendedStyle;
353 | m_Rect = pRect;
354 | m_strCaption = lpszCaption;
355 | m_bSubclassed = bSubclassed;
356 | m_pData = pData;
357 | if (nID == 0) {
358 | m_ControlID = ::GetNewUniqueID();
359 | }
360 | else {
361 | m_ControlID = nID;
362 | }
363 | return m_ControlID;
364 | }
365 |
366 | UINT CDynDialogItemEx::InitDialogItem(LPCSTR lpszClassName,
367 | DWORD dwStyle,
368 | DWORD dwExtendedStyle,
369 | LPRECT pRect,
370 | LPCTSTR lpszCaption,
371 | UINT nID /*= 0*/,
372 | BOOL bSubclassed /*= FALSE*/,
373 | void *pData /*= NULL*/)
374 | {
375 | m_strClassName = lpszClassName;
376 | m_eTypeControl = GetClassTypeByName(lpszClassName);
377 | m_dwStyle = dwStyle;
378 | m_dwStyleEx = dwExtendedStyle;
379 | m_Rect = pRect;
380 | m_strCaption = lpszCaption;
381 | m_bSubclassed = bSubclassed;
382 | m_pData = pData;
383 | if (nID == 0) {
384 | m_ControlID = ::GetNewUniqueID();
385 | }
386 | else {
387 | m_ControlID = nID;
388 | }
389 | return m_ControlID;
390 | }
391 |
392 | BOOL CDynDialogItemEx::CreateEx(CWnd *pParent)
393 | {
394 | BOOL bRet = FALSE;
395 | if (m_eTypeControl == NOCONTROL) { //It will probably be an OCX...
396 | //
397 | // Create the control later....
398 | // if it's created here then the rectangle is not OK and SetWindowPos doesn't work on OCX's????
399 | //
400 | bRet = TRUE;
401 | }
402 | else if (m_pData != NULL && IsDataMemberPointerToWnd()) {
403 | bRet = ((CWnd*)m_pData)->CreateEx(m_dwStyleEx, m_strClassName, m_strCaption, m_dwStyle, m_Rect, pParent, m_ControlID);
404 | }
405 | else {
406 | bRet = CWnd::CreateEx(m_dwStyleEx, m_strClassName, m_strCaption, m_dwStyle, m_Rect, pParent, m_ControlID);
407 | }
408 |
409 | return bRet;
410 | }
411 |
412 | BOOL CDynDialogItemEx::SetWindowPos(CWnd *pParent)
413 | {
414 | BOOL bRet = FALSE;
415 | //Conversion of Dialog units to screenunits
416 | CRect rect(m_Rect);
417 | ((CDialog *)pParent)->MapDialogRect(&rect);
418 | ASSERT(rect.IsRectEmpty() == FALSE);
419 |
420 | if (m_eTypeControl == NOCONTROL) {
421 | BSTR bstrLicKey = GetRuntimeLicense(m_strClassName);
422 | bRet = CreateControl(m_strClassName, m_strCaption, m_dwStyle, rect, pParent, m_ControlID, NULL, FALSE, bstrLicKey);
423 | if (bstrLicKey != NULL) {
424 | ::SysFreeString(bstrLicKey);
425 | }
426 | }
427 | else if (m_pData != NULL && IsDataMemberPointerToWnd()) {
428 | bRet = ((CWnd*)m_pData)->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
429 | }
430 | else {
431 | bRet = CWnd::SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
432 | }
433 |
434 | return bRet;
435 | }
436 |
437 | void CDynDialogItemEx::SetFont(CFont* pFont, BOOL bRedraw /*= TRUE*/)
438 | {
439 | if (m_pData != NULL && IsDataMemberPointerToWnd()) {
440 | ((CWnd*)m_pData)->SetFont(pFont, bRedraw);
441 | }
442 | else {
443 | CWnd::SetFont(pFont, bRedraw);
444 | }
445 | }
446 |
447 | PBYTE CDynDialogItemEx::FillBufferWithItemTemplate(BYTE *pdest)
448 | {
449 | pdest = (BYTE*)(((DWORD)pdest + 3) & ~3); // make the pointer DWORD aligned
450 |
451 | DLGITEMTEMPLATE dlgItemTemplate;
452 | dlgItemTemplate.x = (short)m_Rect.left;
453 | dlgItemTemplate.y = (short)m_Rect.top;
454 | dlgItemTemplate.cx = (short)m_Rect.Width();
455 | dlgItemTemplate.cy = (short)m_Rect.Height();
456 | dlgItemTemplate.style = m_dwStyle;
457 | dlgItemTemplate.dwExtendedStyle = m_dwStyleEx;
458 | dlgItemTemplate.id = (USHORT)m_ControlID;
459 |
460 | memcpy(pdest, (void *)&dlgItemTemplate, sizeof(DLGITEMTEMPLATE));
461 | pdest += sizeof(DLGITEMTEMPLATE);
462 | *(WORD*)pdest = 0xFFFF; // indicating atom value
463 | pdest += sizeof(WORD);
464 | *(WORD*)pdest = (USHORT)m_eTypeControl; // atom value for the control
465 | pdest += sizeof(WORD);
466 |
467 | // transfer the caption even when it is an empty string
468 | WCHAR* pchCaption;
469 | int nChars, nActualChars;
470 |
471 | nChars = m_strCaption.GetLength() + 1;
472 | pchCaption = new WCHAR[nChars];
473 | nActualChars = MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, pchCaption, nChars);
474 | ASSERT(nActualChars > 0);
475 | memcpy(pdest, pchCaption, nActualChars * sizeof(WCHAR));
476 | pdest += nActualChars * sizeof(WCHAR);
477 | delete pchCaption;
478 |
479 | *(WORD*)pdest = 0; // How many bytes in data for control
480 | pdest += sizeof(WORD);
481 |
482 | return pdest;
483 | }
484 |
485 | BSTR CDynDialogItemEx::GetRuntimeLicense(CString &strControlName)
486 | {
487 | BSTR bstrLicKey = NULL;
488 | int i = 0;
489 | while (RuntimeLicenses[i].lpszRegisteredControlName != NULL) {
490 | if (strControlName.Compare(RuntimeLicenses[i].lpszRegisteredControlName) == 0) {
491 | bstrLicKey = ::SysAllocStringLen(RuntimeLicenses[i].wchLicenseKey, RuntimeLicenses[i].lLicenseLength/sizeof(WCHAR));
492 | break;
493 | }
494 | i++;
495 | }
496 | return bstrLicKey;
497 | }
498 |
499 | BOOL CDynDialogItemEx::IsDataMemberPointerToWnd()
500 | {
501 | BOOL bRet = TRUE;
502 | switch(m_eTypeControl)
503 | {
504 | case BUTTON:
505 | if ((m_dwStyle & BS_AUTORADIOBUTTON) == BS_AUTORADIOBUTTON) {
506 | bRet = FALSE;
507 | }
508 | else if ((m_dwStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX) {
509 | bRet = FALSE;
510 | }
511 | break;
512 | case EDITCONTROL:
513 | bRet = FALSE;
514 | break;
515 | case STATICTEXT:
516 | bRet = FALSE;
517 | break;
518 | case HSCROLL:
519 | bRet = FALSE;
520 | break;
521 | case SLIDER:
522 | bRet = FALSE;
523 | break;
524 | case DATETIMEPICKER:
525 | bRet = FALSE;
526 | break;
527 | case MONTHCALENDER:
528 | bRet = FALSE;
529 | break;
530 | default:
531 | break;
532 | }
533 | return bRet;
534 | }
535 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/DynDialogItemEx.h:
--------------------------------------------------------------------------------
1 | // DynDialogItemEx.h: interface for the CDynDialogItemEx class.
2 | //
3 | //////////////////////////////////////////////////////////////////////
4 |
5 | #if !defined(AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
6 | #define AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_
7 |
8 | #if _MSC_VER > 1000
9 | #pragma once
10 | #endif // _MSC_VER > 1000
11 |
12 | typedef enum {
13 | NOCONTROL = 0,
14 | BUTTON = 0x0080,
15 | EDITCONTROL = 0x0081,
16 | STATICTEXT = 0x0082,
17 | LISTBOX = 0x0083,
18 | HSCROLL = 0x0084,
19 | COMBOBOX = 0x0085,
20 | SPIN,
21 | PROGRES,
22 | SLIDER,
23 | HOTKEY,
24 | LISTCTRL,
25 | TREECTRL,
26 | TABCTRL,
27 | ANIMATE,
28 | RICHEDIT,
29 | DATETIMEPICKER,
30 | MONTHCALENDER,
31 | IPADRESS,
32 | COMBOBOXEX
33 | } DLGITEMTEMPLATECONTROLS;
34 |
35 | class CDynDialogItemEx : public CWnd
36 | {
37 | public:
38 | // Construction
39 | CDynDialogItemEx();
40 | // Operations
41 | public:
42 | UINT InitDialogItem(DLGITEMTEMPLATECONTROLS TypeControl,
43 | DWORD dwStyle,
44 | DWORD dwExtendedStyle,
45 | LPRECT pRect,
46 | LPCTSTR lpszCaption,
47 | UINT nID = 0,
48 | BOOL bSubclassed = FALSE,
49 | void *pData = NULL);
50 | UINT InitDialogItem(LPCSTR lpszClassName,
51 | DWORD dwStyle,
52 | DWORD dwExtendedStyle,
53 | LPRECT pRect,
54 | LPCTSTR lpszCaption,
55 | UINT nID = 0,
56 | BOOL bSubclassed = FALSE,
57 | void *pData = NULL);
58 | BOOL CreateEx(CWnd *pParent);
59 | void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
60 |
61 | // Operations
62 | public:
63 | virtual void DoDataExchange(CDataExchange* pDX);
64 |
65 | // Overrides
66 | // ClassWizard generated virtual function overrides
67 | //{{AFX_VIRTUAL(CDynDialogItemEx)
68 | //}}AFX_VIRTUAL
69 |
70 | // Implementation
71 | public:
72 | //virtual ~CDynDialogItemEx();
73 | BOOL SetWindowPos(CWnd *pParent);
74 | PBYTE FillBufferWithItemTemplate(BYTE* pdest);
75 |
76 | UINT GetControlID() {return m_ControlID;}
77 | DLGITEMTEMPLATECONTROLS GetControlType() {return m_eTypeControl;}
78 | long GetCaptionLength() {return m_strCaption.GetLength();}
79 | BOOL IsDlgItemSubclassed() {return m_bSubclassed;}
80 | CString GetClassName() {return m_strClassName;}
81 |
82 | protected:
83 | DLGITEMTEMPLATECONTROLS GetClassTypeByName(LPCSTR lpszClassName);
84 |
85 | CString m_strClassName;
86 | DLGITEMTEMPLATECONTROLS m_eTypeControl;
87 | UINT m_ControlID;
88 | UINT m_dwStyle;
89 | UINT m_dwStyleEx;
90 | CRect m_Rect;
91 | CString m_strCaption;
92 | void *m_pData;
93 | BOOL m_bSubclassed;
94 |
95 | // Generated message map functions
96 | protected:
97 | BOOL IsDataMemberPointerToWnd();
98 | BSTR GetRuntimeLicense(CString &strControlName);
99 | char* GetClassNameByType(DLGITEMTEMPLATECONTROLS TypeControl);
100 |
101 | //{{AFX_MSG(CDynDialogItemEx)
102 | // NOTE - the ClassWizard will add and remove member functions here.
103 | //}}AFX_MSG
104 | DECLARE_MESSAGE_MAP()
105 | };
106 |
107 | #endif // !defined(AFX_DYNDIALOGITEMEX_H__CF5AF5E9_BD00_11D3_AA7C_0008C7083CA9__INCLUDED_)
108 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/ListDynDialogEx.cpp:
--------------------------------------------------------------------------------
1 | // ListDynDialogEx.cpp: implementation of the CListDynDialogEx class.
2 | //
3 | //////////////////////////////////////////////////////////////////////
4 |
5 | #include "stdafx.h"
6 | #include "ListDynDialogEx.h"
7 |
8 | #ifdef _DEBUG
9 | #undef THIS_FILE
10 | static char THIS_FILE[]=__FILE__;
11 | #define new DEBUG_NEW
12 | #endif
13 |
14 | #define IDC_LIST1 1600
15 | //////////////////////////////////////////////////////////////////////
16 | // Construction/Destruction
17 | //////////////////////////////////////////////////////////////////////
18 |
19 | CListDynDialogEx::CListDynDialogEx(CWnd* pParent /*= NULL*/)
20 | : CDynDialogEx(pParent)
21 | {
22 | m_bAddSystemButtons = FALSE;
23 | }
24 |
25 | CListDynDialogEx::~CListDynDialogEx()
26 | {
27 | }
28 |
29 | BEGIN_MESSAGE_MAP(CListDynDialogEx, CDynDialogEx)
30 | //{{AFX_MSG_MAP(CListDynDialogEx)
31 | ON_LBN_DBLCLK(IDC_LIST1, OnDblclkList)
32 | //}}AFX_MSG_MAP
33 | END_MESSAGE_MAP()
34 |
35 | BOOL CListDynDialogEx::OnInitDialog()
36 | {
37 | BOOL bRet = CDynDialogEx::OnInitDialog();
38 |
39 | m_lstBox.AddString(_T("First String"));
40 | m_lstBox.AddString(_T("Second String"));
41 |
42 | return bRet;
43 | }
44 |
45 | int CListDynDialogEx::DoModal()
46 | {
47 | CRect rect(7,7,150,150);
48 | AddDlgControl(_T("LISTBOX"), _T("ListboxText"), STYLE_LISTBOX, EXSTYLE_LISTBOX, &rect, &m_lstBox, IDC_LIST1);
49 | return CDynDialogEx::DoModal();
50 | }
51 |
52 | void CListDynDialogEx::OnDblclkList()
53 | {
54 | CString strBuf;
55 | int nIndex = m_lstBox.GetCurSel();
56 | m_lstBox.GetText(nIndex, strBuf);
57 | AfxMessageBox(strBuf);
58 | OnOK();
59 | }
60 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/ListDynDialogEx.h:
--------------------------------------------------------------------------------
1 | // ListDynDialogEx.h: interface for the CListDynDialogEx class.
2 | //
3 | //////////////////////////////////////////////////////////////////////
4 |
5 | #if !defined(AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_)
6 | #define AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_
7 |
8 | #if _MSC_VER > 1000
9 | #pragma once
10 | #endif // _MSC_VER > 1000
11 |
12 | #include "dyndialogex.h"
13 |
14 | class CListDynDialogEx : public CDynDialogEx
15 | {
16 | public:
17 | CListDynDialogEx(CWnd* pParent = NULL);
18 | virtual ~CListDynDialogEx();
19 |
20 | CListBox m_lstBox;
21 |
22 | // Overrides
23 | // ClassWizard generated virtual function overrides
24 | //{{AFX_VIRTUAL(CListDynDialogEx)
25 | public:
26 | virtual int DoModal();
27 | //}}AFX_VIRTUAL
28 |
29 | // Implementation
30 | protected:
31 |
32 | // Generated message map functions
33 | //{{AFX_MSG(CListDynDialogEx)
34 | virtual BOOL OnInitDialog();
35 | afx_msg void OnDblclkList();
36 | //}}AFX_MSG
37 | DECLARE_MESSAGE_MAP()
38 | };
39 |
40 | #endif // !defined(AFX_LISTDYNDIALOGEX_H__57BA7AFA_B679_4FAC_B6BE_1AD925E45194__INCLUDED_)
41 |
--------------------------------------------------------------------------------
/ext/PropertyGrid/PropertyGrid.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "PropertyGridCombo.h"
3 | #include "PropertyGridInPlaceEdit.h"
4 |
5 | #include