├── README.md
├── Samples
├── tcptest
│ ├── resource.rc
│ ├── tcpclient.cpp
│ ├── tcpclient.h
│ ├── tcpserver.cpp
│ ├── tcpserver.h
│ ├── tcptest.cbp
│ ├── tcptest.depend
│ ├── tcptest.layout
│ ├── tcptestApp.cpp
│ ├── tcptestApp.h
│ ├── tcptestMain.cpp
│ ├── tcptestMain.h
│ └── wxsmith
│ │ └── tcptestframe.wxs
└── vidplay
│ ├── resource.rc
│ ├── video.avi
│ ├── video.mpg
│ ├── vidplay.cbp
│ ├── vidplay.depend
│ ├── vidplay.layout
│ ├── vidplayApp.cpp
│ ├── vidplayApp.h
│ ├── vidplayMain.cpp
│ ├── vidplayMain.h
│ └── wxsmith
│ └── vidplayframe.wxs
├── SetupCodeBlocks_AllInOne.bat
├── docs
├── idegif.gif
├── real1.jpg
├── real2.jpg
├── sample1.jpg
├── w31.jpg
├── w31vid.jpg
├── w95.jpg
└── wizard1.jpg
└── installers
├── DEPENDENCIES.txt
├── THIRD_PARTY_FILES.txt
├── _install-bcc55.bat
├── _install-djgpp.bat
├── _install-mingw64.bat
├── _install-openwatcom.bat
├── _install-tdmgcc32.bat
├── _install-wxmsw28bcc.bat
├── _install-wxmsw28tdm32.bat
├── _install-wxmsw305tdm32.bat
├── _install-wxmsw321mingw64.bat
├── default.conf
├── dosbox
└── dosbox.conf
├── dosboxw31
├── INSTALLERS
│ ├── CFG
│ │ ├── AUTOEXEC.BAT
│ │ ├── CONFIG.SYS
│ │ ├── WIN32APP.GRP
│ │ └── WINDOWS
│ │ │ ├── ACCESSOR.GRP
│ │ │ ├── CONTROL.INI
│ │ │ ├── DOSPRMPT.PIF
│ │ │ ├── ENTPACK.INI
│ │ │ ├── GAMES.GRP
│ │ │ ├── INDEO.INI
│ │ │ ├── MAIN.GRP
│ │ │ ├── MICROSOF.GRP
│ │ │ ├── MSACM.INI
│ │ │ ├── NCDINFO.INI
│ │ │ ├── NETWORK.GRP
│ │ │ ├── PROGMAN.INI
│ │ │ ├── PROTOCOL.CLN
│ │ │ ├── PROTOCOL.INI
│ │ │ ├── REG.DAT
│ │ │ ├── SERIALNO.INI
│ │ │ ├── SHARES.PWL
│ │ │ ├── STARTUP.GRP
│ │ │ ├── SYSTEM.CLN
│ │ │ ├── SYSTEM.INI
│ │ │ ├── SYSTEM
│ │ │ └── WIN32S.INI
│ │ │ ├── WFWSYS.CFG
│ │ │ ├── WIN.CLN
│ │ │ ├── WIN.INI
│ │ │ ├── WIN311.PWL
│ │ │ ├── WINFILE.INI
│ │ │ ├── WINGSDK.GRP
│ │ │ └── _DEFAULT.PIF
│ ├── INST311
│ │ └── _PLACE_WIN311_FILES_HERE_
│ ├── LINKS.txt
│ ├── dosbox-x.conf
│ ├── mouse
│ │ ├── oemsetup.inf
│ │ └── source.zip
│ ├── msunpak-source.zip
│ └── msunpak.exe
├── _WFW311AUTOINSTALLER_.bat
└── w31launcher.bat
├── dosboxw95
├── CONFIG_SCRIPTS
│ ├── 1024x768_16bpp_DPI-scaled.bat
│ ├── 640x480_16bpp_DPI-scaled.bat
│ ├── 800x600_16bpp_DPI-scaled.bat
│ ├── _NO-MOUSE-INTEGRATION.bat
│ └── _USE-MOUSE-INTEGRATION.bat
├── SHARED_DRIVE
│ └── readme.txt
├── SetupW95DosboxX.bat
├── _startinw95.bat
├── dosbox-x.conf
├── guest_tools
│ ├── alaunchr
│ │ ├── alaunchr.cfg
│ │ ├── launchit.cfg
│ │ ├── readme.txt
│ │ └── src
│ │ │ └── alaunchr.cpp
│ ├── emptycd.iso
│ ├── emptyfdd.IMG
│ ├── guest-scripts
│ │ ├── 1024_16bpp.bat
│ │ ├── 640_16bpp.bat
│ │ ├── 800_16bpp.bat
│ │ ├── mruclear.bat
│ │ ├── nostsnd.bat
│ │ ├── prodid0.bat
│ │ └── prodtyp9.bat
│ └── setmdrv
│ │ └── source
│ │ ├── ini.h
│ │ └── setmdrv.cpp
├── installers
│ ├── WIN95
│ │ └── _PLACE_WIN95_FILES_HERE_
│ └── w95-inst-utils-cfgfiles.7z
├── w95launcher.bat
└── w95launcher_gdbargs.bat
├── dosboxx
├── dosboxx_install.bat
└── installers
│ ├── dbxlauncher.bat
│ └── dosbox-x.conf
├── patch_wx28_win32s
├── INFO_W32SPATCH.txt
├── include
│ └── wx
│ │ └── msw
│ │ ├── mediactrl.h
│ │ └── slider95.h
└── src
│ ├── common
│ └── mediactrlcmn.cpp
│ └── msw
│ ├── mediactrl_am.cpp
│ ├── notebook.cpp
│ ├── ole
│ └── automtn.cpp
│ ├── slider95.cpp
│ └── window.cpp
├── patch_wx305_9x
├── MODIFICATIONS_wx3.0.5.txt
└── src
│ └── msw
│ ├── checklst.cpp
│ ├── toplevel.cpp
│ ├── utils.cpp
│ └── window.cpp
├── utils
└── CWSDSTUB.EXE_and_exe2coff_goes_here
└── wizard
├── config.script
├── console
├── c
│ └── main.c
├── cpp
│ └── main.cpp
├── logo.png
├── wizard.png
└── wizard.script
├── djgpp
├── c
│ └── main.c
├── cpp
│ └── main.cpp
├── logo.png
├── wizard.png
└── wizard.script
├── owcdos
├── c
│ └── main.c
├── cpp
│ └── main.cpp
├── logo.png
├── wizard.png
└── wizard.script
└── wxwidgets
├── common
├── app.cpp
├── app.h
├── main.cpp
└── main.h
├── logo.png
├── pch
└── wx_pch.h
├── rc
└── resource.rc
├── wizard.png
├── wizard.script
├── wizard.xrc
├── wxfb
├── dialog
│ ├── GUIDialog.cpp
│ ├── GUIDialog.h
│ └── WxWizDialog.fbp
└── frame
│ ├── GUIFrame.cpp
│ ├── GUIFrame.h
│ └── WxWizFrame.fbp
└── wxsmith
├── app.cpp
├── main.cpp
├── main.h
├── main_s.cpp
├── main_s.h
├── resource.wxs
└── resource_s.wxs
/README.md:
--------------------------------------------------------------------------------
1 | # cb-legacy-dev: CodeBlocks for Legacy Software Development
2 |
3 | This is an IDE installer which creates a pre-configured environment that allows rapid GUI application development for Windows 3.11/Win32s (!), Windows 9x or modern targets, even with cross-platform capabilities.
4 | It uses a bunch of configuration files, installation scripts, compilers, frameworks, sample C++ projects and wizard templates. This project heavily relies on CodeBlocks and wxWidgets framework.
5 |
6 | The main idea was to simplify the process of making simple applications for legacy systems as much as possible (you can create and run a test application for Windows 3.11 in less than a minute thanks to built-in configuration wizard).
7 | And thanks to wxWidgets, which miraculously can work with Win32s-extended Windows 3.11 allows to avoid writing platform-specific code for an ancient system. The most recent version that works with Win32s is 2.8.12.
8 |
9 | **Video overview and tutorial: https://youtu.be/d6L272OApVg**
10 |
11 | [
](https://youtu.be/d6L272OApVg)
12 |
13 | **Features:**
14 | * Automatic installer (single batch file)
15 | * Pre-configured CodeBlocks IDE
16 | * Windows 3.11 and Windows 95 integrated with IDE (using DOSBox-X): you can build and run the application in Win 3.11/95 with a single mouse click
17 | * Automatic Windows 3.11/95 installation in DOSBox-X: you provide your own genuine installation disks/CD
18 | * Mouse and network integration between Win 3.11/95 guests and host system
19 | * Easy GUI development thanks to wxWidgets and easy-to-use configuration wizards
20 | * wxWidgets modified to work with Win 3.11 targets (version 2.8.12), version 3.0.5 modified to work with Win 95
21 | * Unicode for Win 9x targets thanks to MSLU/Unicows (works with wxWidgets 3.0.5)
22 | * TDM-GCC 4.7.1 for Win9x+ targets, BCC5.5 compiler (needs to be downloaded separately) for Win 3.11/Win32s targets
23 | * MinGW-w64 and wxWidgets 3.2 for modern 64-bit targets
24 | * As a bonus: DJGPP and OpenWatcom compilers for DOS (with DOSBox integration)
25 |
26 | **Prerequisites:**
27 | * Windows for Workgroups 3.11 English version installation disks - for Win 3.11 IDE integration
28 | * Windows 95 OSR2 English installation CD (WIN95 subdirectory) - for Win 95 IDE integration
29 | * free Borland 5.5 C++ compiler - installation script will try to download it automatically
30 | * drivers and updates for Win 3.11/Win 95 - installation script will try to download them automatically
31 |
32 | **Screenshots:**
33 |
34 | 
35 | 
36 | 
37 | 
38 | 
39 |
40 | **Built apps running on real hardware:**
41 | 
42 |
43 | 
44 | Note: currently non-Windows targets need to be built manually on separate machines
45 |
--------------------------------------------------------------------------------
/Samples/tcptest/resource.rc:
--------------------------------------------------------------------------------
1 | aaaa ICON "wx/msw/std.ico"
2 |
3 | #include "wx/msw/wx.rc"
4 |
--------------------------------------------------------------------------------
/Samples/tcptest/tcpclient.cpp:
--------------------------------------------------------------------------------
1 | #include "tcpclient.h"
2 |
3 | #define BUF_SIZE 1024
4 |
5 | const long SimpleTCPClient::SOCKET_ID = wxNewId();
6 |
7 | BEGIN_EVENT_TABLE(SimpleTCPClient, wxEvtHandler)
8 | EVT_SOCKET(SOCKET_ID, SimpleTCPClient::OnSocketEvent)
9 | END_EVENT_TABLE()
10 |
11 |
12 | DEFINE_EVENT_TYPE(EV_CONNECTED);
13 | DEFINE_EVENT_TYPE(EV_CLIENTONDATA);
14 |
15 | SimpleTCPClient::SimpleTCPClient(wxEvtHandler* parent, wxWindowID id)
16 | {
17 |
18 | m_id = id;
19 | m_parent = parent;
20 | logBox = NULL;
21 | Client = NULL;
22 |
23 | }
24 |
25 | SimpleTCPClient::~SimpleTCPClient()
26 | {
27 |
28 | }
29 |
30 | // Read specified number of bytes to specified buffer from socket and return actual number of read bytes
31 | int SimpleTCPClient::Read( void *buffer, unsigned int nbytes )
32 | {
33 |
34 | int result = 0;
35 |
36 | // Read data
37 | if (Client != NULL)
38 | {
39 | if ( Client->IsConnected() && !disconnected)
40 | {
41 | Client->Read(buffer, nbytes);
42 | result = Client->LastCount(); // Set number of actually read bytes as result
43 | }
44 | }
45 |
46 | return result;
47 | }
48 |
49 | // Peek specified number of bytes to specified buffer from socket and return actual number of peeked bytes
50 | // This doesn't remove the data from socket and it can be read afterwards
51 | int SimpleTCPClient::Peek( void *buffer, unsigned int nbytes )
52 | {
53 | int result = 0;
54 | // Peek data
55 | if (Client != NULL && !disconnected)
56 | {
57 | if ( Client->IsConnected() )
58 | {
59 | Client->Peek(buffer, nbytes);
60 | result = Client->LastCount(); // Set number of actually peeked bytes as result
61 | }
62 | }
63 | return result;
64 | }
65 |
66 |
67 | // Read from socket and return a string (this should be mostly used for "human-readable" data)
68 | wxString SimpleTCPClient::ReadStr()
69 | {
70 | wxString readString = "";
71 |
72 | char buff[BUF_SIZE + 1]; // Buffer with byte for zero termination (end of string)
73 | memset(buff, 0, sizeof(buff));
74 |
75 | // Read data
76 | if (Client != NULL) Client->Read(&buff, BUF_SIZE);
77 |
78 | readString = buff;
79 |
80 | return readString;
81 | }
82 |
83 |
84 | // Peek data in socket without clearing the data and return a string (this should be mostly used for "human-readable" data)
85 | wxString SimpleTCPClient::PeekStr()
86 | {
87 | wxString readString = "";
88 |
89 | char buff[BUF_SIZE + 1]; // Buffer with byte for zero termination (end of string)
90 | memset(buff, 0, sizeof(buff));
91 |
92 | // Read data
93 | if (Client != NULL) Client->Peek(&buff, BUF_SIZE);
94 |
95 | readString = buff;
96 |
97 | return readString;
98 | }
99 |
100 | void SimpleTCPClient::LogClient( wxString logText )
101 | {
102 | // Append text to provided wxTextCtrl (if exists)
103 | // "(internal)" is added just to make it easier to understand how the application works
104 | // It will show which messages came from the "inside" of tcpclient.cpp file
105 | if (logBox != NULL) logBox->WriteText("(internal) " + logText + "\n");
106 | }
107 |
108 | void SimpleTCPClient::Connect(wxString hostname, unsigned int port)
109 | {
110 | if (Client == NULL)
111 | {
112 | wxIPV4address ipaddr;
113 | ipaddr.Hostname(hostname);
114 | ipaddr.Service(port);
115 |
116 | LogClient("Opening client");
117 | Client = new wxSocketClient();
118 | Client->SetFlags(wxSOCKET_NOWAIT); // wxSOCKET_NONE is default but produced some segfaults on retry
119 |
120 | Client->SetEventHandler(*this, SOCKET_ID);
121 | Client->SetNotify(wxSOCKET_CONNECTION_FLAG | wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
122 | Client->Notify(true);
123 |
124 | Client->Connect(ipaddr, false);
125 |
126 | }
127 | else
128 | {
129 |
130 | if ( Client->IsConnected() )
131 | {
132 | LogClient( "Already connected" );
133 | }
134 | else if ( !Client->IsConnected() )
135 | {
136 | LogClient( "Connection in progress" );
137 | }
138 |
139 | }
140 | }
141 |
142 |
143 | void SimpleTCPClient::WriteStr( wxString str_in )
144 | {
145 | if (Client != NULL) // No point in trying if client is not active
146 | {
147 | // Send string to server
148 | if ( Client->IsConnected() )
149 | {
150 | Client->Write(str_in.c_str(), str_in.Length());
151 | LogClient("Sent \"" + str_in + "\"");
152 | }
153 | }
154 | }
155 |
156 | void SimpleTCPClient::Write( const void *data, unsigned int dataBytes )
157 | {
158 | if (Client != NULL) // No point in trying if client is not active
159 | {
160 | // Write data
161 | if ( Client->IsConnected() )
162 | {
163 | Client->Write(data, dataBytes);
164 | LogClient("Sent binary data");
165 | }
166 | }
167 | }
168 |
169 | void SimpleTCPClient::WriteWait( const void *data, unsigned int dataBytes )
170 | {
171 | if (Client != NULL) // No point in trying if client is not active
172 | {
173 | // Write data
174 | if ( Client->IsConnected() )
175 | {
176 | //wxSocketFlags tempFlags = Client->GetFlags();
177 |
178 | //Client->SetFlags(wxSOCKET_BLOCK);
179 |
180 | Client->Write(data, dataBytes);
181 | Client->WaitForWrite(0,10);
182 |
183 | //Client->SetFlags(tempFlags);
184 | }
185 | }
186 | }
187 |
188 |
189 | void SimpleTCPClient::OnRecv(wxSocketBase *sock)
190 | {
191 |
192 | LogClient("Incoming data");
193 |
194 | // Put current socket in event data, so main application will be able to read it
195 | wxCommandEvent myevent(EV_CLIENTONDATA, m_id);
196 | myevent.SetClientData( sock );
197 | wxPostEvent(m_parent, myevent);
198 |
199 |
200 | //**** Data must be handled in main application.
201 | //**** If main application will only read partial data,
202 | //**** next events will be fired until all data is read.
203 | //**** But if application does not read any data,
204 | //**** data receive event will get stuck until it is manually read
205 |
206 | //if ( sock->IsData() ) OnRecv( sock ); // Keep receiving if more data is available (this is default behavior anyway)
207 |
208 | }
209 |
210 | void SimpleTCPClient::Disconnect()
211 | {
212 | if (Client != NULL)
213 | {
214 | Client->Destroy();
215 | Client->WaitForLost(0,50);
216 | Client = NULL;
217 | LogClient("Disconnecting from server");
218 | }
219 | }
220 |
221 | void SimpleTCPClient::OnSocketEvent(wxSocketEvent &event)
222 | {
223 |
224 | LogClient("Socket event");
225 |
226 | wxSocketBase *sock = event.GetSocket();
227 |
228 | switch(event.GetSocketEvent())
229 | {
230 | case wxSOCKET_CONNECTION:
231 | {
232 | LogClient("Successfully connected");
233 |
234 |
235 | wxCommandEvent myevent(EV_CONNECTED, m_id);
236 | myevent.SetClientData( sock );
237 | wxPostEvent(m_parent, myevent);
238 | disconnected = false;
239 |
240 | break;
241 | }
242 |
243 | case wxSOCKET_INPUT:
244 | {
245 | // Redirect to OnRecv function
246 | OnRecv(event.GetSocket());
247 | break;
248 | }
249 |
250 | case wxSOCKET_LOST:
251 | {
252 | LogClient("Disconnected");
253 | sock->Close();
254 | sock->Discard();
255 | sock->Destroy();
256 | Client->Close();
257 | Client->Discard();
258 | Client->Destroy();
259 | Client = NULL;
260 | disconnected = true;
261 | break;
262 | }
263 |
264 | default:
265 | {
266 | LogClient("Unknown event");
267 | break;
268 | }
269 | }
270 |
271 | }
272 |
--------------------------------------------------------------------------------
/Samples/tcptest/tcpclient.h:
--------------------------------------------------------------------------------
1 | #ifndef TCPCLIENT_H
2 | #define TCPCLIENT_H
3 |
4 | #include "wx/wx.h"
5 | #include "wx/socket.h"
6 | #include "wx/event.h"
7 | #include
8 |
9 | DECLARE_EVENT_TYPE(EV_CONNECTED, wxCommandEvent);
10 | DECLARE_EVENT_TYPE(EV_CLIENTONDATA, wxCommandEvent);
11 |
12 | class SimpleTCPClient : public wxEvtHandler
13 | {
14 |
15 | public:
16 |
17 |
18 | int maxClients;
19 |
20 | SimpleTCPClient(wxEvtHandler* parent, wxWindowID id); // Constructor
21 | virtual ~SimpleTCPClient(); // Destructor
22 |
23 | void Connect( wxString hostname, unsigned int port ); // This will start listening (address is optional, port can be also set with different function)
24 |
25 | void Disconnect();
26 |
27 | unsigned int Port( unsigned int port = 0 ); // Return current port number (if no arguments) or set new port number (if specified)
28 |
29 | wxTextCtrl *logBox; // Text control to be used as log output (optional)
30 |
31 |
32 | void OnSocketEvent(wxSocketEvent &event);
33 |
34 | void OnRecv(wxSocketBase *sock);
35 |
36 | wxString ReadStr();
37 |
38 | int Read( void *buffer, unsigned int nbytes );
39 |
40 | wxString PeekStr();
41 |
42 | int Peek( void *buffer, unsigned int nbytes );
43 |
44 | void WriteStr( wxString str_in );
45 |
46 | // Write data (for example char array) to socket
47 | void Write( const void *data, unsigned int dataBytes );
48 |
49 | // Write data (for example char array) to socket
50 | void WriteWait( const void *data, unsigned int dataBytes );
51 |
52 | bool isDisconnected()
53 | {
54 | if (Client)
55 | {
56 | if (Client->IsDisconnected()) return true;
57 | else return false;
58 | }
59 | else return true;
60 | };
61 |
62 |
63 | private:
64 |
65 |
66 | bool disconnected;
67 | wxEvtHandler * m_parent; // Parent form
68 | wxWindowID m_id; // ID assigned to current instance of server
69 |
70 | wxSocketClient *Client; // Client things will happen here
71 |
72 | void LogClient( wxString logText ); // Log will be printed with this function if required
73 |
74 |
75 | static const long SOCKET_ID; // For event handling
76 | DECLARE_EVENT_TABLE() // For event handling
77 |
78 | };
79 |
80 | #endif // TCPCLIENT_H
81 |
--------------------------------------------------------------------------------
/Samples/tcptest/tcpserver.h:
--------------------------------------------------------------------------------
1 | #ifndef TCPSERVER_H
2 | #define TCPSERVER_H
3 |
4 | #include "wx/wx.h"
5 | #include "wx/socket.h"
6 | #include "wx/event.h"
7 | #include
8 | #include