This folder is a modernized port of Microsoft Chat 2.5 beta-1 (the June 1998
"Microsoft Chat" client — the most advanced single-client version in this
repository). The goal of this folder is to be easy to build and run on a
current Windows + Visual Studio machine, while leaving the original
v2.5-beta-1/ tree untouched as the historical reference.
The original 2.5 source built with the Windows NT DDK BUILD.EXE system
(sources / dirs / makefile.def). This folder replaces that with a clean,
self-contained nmake makefile (chat.mak) that uses a modern Visual Studio
C++/MFC toolchain.
From a 32-bit Visual Studio developer prompt (or by calling vcvars32.bat):
call "<VisualStudio>\VC\Auxiliary\Build\vcvars32.bat"
cd v2.5-beta-1-modern
nmake /f chat.mak CFG="chat - Win32 Release" REM optimized, for everyday use
nmake /f chat.mak CFG="chat - Win32 Debug" REM asserts + TRACE for DebugViewTwo configurations are provided:
- Release ->
Release\CChat.exe(optimized/MT//O2,NDEBUG). Use this for normal use. It behaves like the original shipped product. - Debug ->
Debug\CChat.exe(/MTd//Od,_DEBUG). Use this for development: it emitsTRACEoutput (viewable in Sysinternals DebugView) and keeps assertions, which is handy when investigating behavior.
Both link MFC statically. Character/backdrop art lives next to the source in
comicart\ as .avb / .bgb files.
Why two configs? This is a 1996-1998 MFC app. A modern debug build injects assertions (debug-heap validation, MFC teardown-order and CRT range checks) that did not exist in its original MFC 4.0 / old-CRT toolchain. Several of them fire harmlessly during normal use and shutdown; left as modal dialogs they can block
CWinApp::ExitInstance(where settings are saved), which can make settings appear not to persist. The Release build has none of these and runs/saves exactly like the original. The Debug build additionally installs a CRT report hook to suppress those assertion dialogs and saves settings at frame close, so it stays usable too.
The makefile does not track header dependencies. After editing any
.h, delete the matchingDebug\*.obj/Release\*.objand rebuild so the change propagates everywhere.
- New
chat.mak(replaces the NT DDKsources/dirsbuild). Precompiled headers are intentionally disabled for robustness. - Compiler switches that restore legacy behaviour:
/Zc:forScope-(old for-loop scoping),/Zc:strictStrings-(string-literal →char*), plus/FORCE:MULTIPLE /nodefaultlib:"libc"and the spectre-mitigated ATLMFC lib path. MIDLgeneratesicchat.h/icchat_i.cfrombase\icchat.idl.- The delay-load DLL wrappers (
dlylddll.c→..\core\dlylddll.c) are compiled in; they provide themsrating/msconf/wininetthunks.wininet.libis linked. NetMeeting (nmproto) stays excluded (off by default).
- Removed trailing
inlineon declarations/definitions (f() inline;/{). - Added missing return types (e.g. several
splinutlfunctions,SortFunc,GetIndex). - Renamed
DECLARE_OLECMD_MAP/GetCommandMap→MY_*/MyGetCommandMapto avoid a covariant-return clash with modernCCmdTarget::GetCommandMap. - Cast
const-qualifiedstrchr/strstrresults back tochar*. - Renamed
avbfile/avatarINT8/INT16/INT32→AVBINT8/16/32(they collided with the SDK's signedINT8/16/32). mcithrd: localMSGfor the thread pump, 3-argPostThreadMessage.chatsrv::ReattachTonow usesCAsyncSocket::Detach/AttachHandle(the modern MFC socket handle map is internal).- Misc:
CWnd::CreateExqualification,abs→labs((long)),const ints inColorDlg.h.
stdafx.h: removed the 1998#define tagLVITEMA _LV_ITEMA(andLVFINDINFO/TCITEM) remap. It was added to match MFC 4.0's old common-control struct tags; modern MFC and the SDK both use the new tags, so the remap instead broke linking againstCListCtrl/CTabCtrl.stdafx.cpp: added a Common Controls v6 manifest dependency. The 2.5 toolbar is a rebar (CCoolBar), andRB_INSERTBANDfails unless the loadedcomctl32matches the modernREBARBANDINFOsize. Without this the toolbar fails to create → the main frame fails → a debug-heap assertion on cleanup. This is the manifest that makes the app actually start.
resource.h: shifted the 9ID_EM_*emotion IDs out of MFC's reserved0xF006string-table range (they collided withafxres.rc).- Added
chatver.handchatver.rc(the version stamp; these were generated by the original DDK build and were missing from the source drop). - Shared fix in
../artifacts/core/urlutil.cpp(const int+(LPTSTR)casts).
The app runs DPI-unaware: it deliberately does not call
SetProcessDPIAware(), so on a high-DPI display Windows bitmap-scales the whole
window uniformly (toolbar, status bar, menus, every font, and the comic view all
scale together). This avoids the "some surfaces scale, others stay tiny" mess
that results from per-surface scaling in a TWIP + pixel hybrid UI like this one.
A DpiScale() helper (dpiscale.h) and the per-surface scaling
ported from v1.0-pre-modern are still present but become no-ops while DPI-
unaware (the display DPI reads as 96). If you'd rather make the app DPI-aware
and scale every surface yourself, that infrastructure is the starting point —
left as an exercise for the reader.
- Mouse-wheel scrolling in the comic view (
CPageView::OnMouseWheel). - Panels-per-row auto-fit on resize —
CPageViewchooses the largest comfortable column count for the current width, deferred via a postedWM_AUTOFITPANELSmessage to avoidWM_SIZEre-entrancy. - IRC JOIN parsing — modern servers (e.g. Libera) send
JOIN #channelwith the channel as a normal argument rather than a:-trailing parameter; the JOIN handler now recovers the channel fromargs[1]so rooms register correctly. - Text view buffer tracking — modern RichEdit stores a line break as a single
\r, so the oldm_dwBuffSizeaccounting (which counted\r\nas two) drifted and tripped debug assertions; it now resyncs to the control's actual length. - No dead-server downloads — Comic Chat used to fetch custom characters and backdrops from Microsoft's (now-gone) art servers. Both download paths are disabled in favor of the bundled art, with a one-time heads-up dialog.
- Bundled-art lookup — the art is found whether it sits next to the exe
(distribution) or one directory up (the dev
Debug\layout). - On-screen startup window — a stale/oversized saved placement is shrunk to the work area and clamped fully on-screen.
- Safe
is*functions (safectype.h) —isspace/isdigit/ etc. are wrapped to passunsigned char, so high-byte characters no longer trip the modern debug CRT. - Default comic balloon font bumped from 9pt to 12pt for readability on large
high-DPI panels (
IDS_DFLT_COMICSPNTSIZE).
- Native TLS transport is not included. 2.5's
ircsock.cppalready uses SSPI, but for IRC authentication (server auth packages), not SChannel transport encryption. Adding TLS would mean porting theCTlsClientSChannel client fromv1.0-pre-modern/tlssock.cppand wiring a "Use SSL" / port 6697 option into the connect dialog. See../docs/tls.md. - Balloon word-wrap is intentionally left as-is: 2.5 already has a more
advanced international, word-boundary-aware wrapper
(
FindSubStringForINTLThatFits), so the simplerv1.0-pre-modernfix is not needed here.