Coding at a lower level for a deeper understanding.
Coding at a lower level might give you
the deeper understanding you're looking for, TonyJeffs,
and, to boot, it's a more stable target, instead of the latest fad.
My hand-rolled newsreader ( X.EXE ), for example,
employs only one WinProc() and one CreateWindow(),
and the WinProc is merely:
long __stdcall WinProc ( HWND Wnd, uint _WM, uint C, long C2 ) {
PostMessage( Win, _WM, C, C2 ); return 1 ; }
I never use ??? member functions ??? and the like.
I cache Unicode glyphs onto DirectDraw surfaces
and, as I employ only one window ( always maximized ),
my buttons don't use WinProc() or CreateWindow().
My glyph-caching routines are too complex to mention here,
but here is a code snippet showing how a Device Context works:
// Monospaced fonts have different width-to-height ratios,
// hence: _CharH( WtoH )
#define _CharH( WtoH ) ( CacheW / ( WtoH ) )
// ScrW is the width of our maximized window, in pixels.
// This give us 123 columns of monospaced glyphs per line:
CharW = ScrW / ( ScrCols = 123 );
CacheW = CharW + 1, ColsDC = ScrW / CacheW ;
CharH = _CharH( 120. / 256 );
CacheH = CharH + 1, ScrRows = ScrH / CharH ;
Fnt = CreateFont(
CharH, 0,0,0,0,0,0,0,0,0,0,0, FIXED_PITCH, L"Consolas");
SymFnt = CreateFont(
_CharH( 128. / 256 ),0,0,0,0,0,0,0,0,0,0,0, FIXED_PITCH, L"MS Mincho");
BassFnt = CreateFont(
_CharH( 1 / 4.5 ),0,0,0,0,0,0,0,0,0,0,0, 0, L"Musical Symbols");
............
// The Double Sharp and Bass glyphs
// are merely examples of Plane One Glyphs.
//
// The code that chaches them is a total hack
// because no other Plane One Glyphs can be cached.
int ColsCh, CacheW, CacheH ;
const int Dub = 2, Highest_Consolas = 0xFFF;
_CacheGlyph( GyP P, int I_Hue, _SurT TheCache, int _X ) {
// 0xD834 Double Sharp: DD2A Bass: DD1E
int Bass = P->Ch >= 0xDC00 && P->Ch <= 0xDFFF ;
static wchar_t B[ 2 ];
wchar_t Ch = B[ Bass ] = P->Blank ? * L"???" : P->Ch ;
if ( Bass ) * B = 0xD834 ;
HDC DC ; Chk( TheCache->GetDC( & DC ) );
SetTextAlign( DC , TA_LEFT | TA_TOP | TA_UPDATECP );
SetPtr( DC, Bass ? BassFnt : Fnt );
if ( ! Bass ) { ushort Good ;
GetGlyphIndices( DC, B, 1, & Good, GGI_MARK_NONEXISTING_GLYPHS );
if ( short( Good ) == -1 ) SetPtr( DC, SymFnt );
GetGlyphIndices( DC, B, 1, & Good, GGI_MARK_NONEXISTING_GLYPHS );
if ( short( Good ) == -1 ) { // Give up, we don't have the font.
Chk( TheCache->ReleaseDC( DC ) ); return 1 ; } }
P->RowsCh = Bass + 1 ;
int WW = CacheW * ( ! P->ColsCh ? Dub : P->ColsCh )
, HH = CacheH * P->RowsCh , X = _X * CacheW ;
RECT CacheR = _R( X, 0, WW, HH ); MvTo( X, 0 ), SetBkColor( DC, 0 );
SetTextColor( DC, * ( ( ulong * ) & Hues + I_Hue ) );
ExtTextOut(
DC, 0, 0, ETO_CLIPPED | ETO_OPAQUE, & CacheR, B, 1 + Bass, 0 );
MvTo( X, 0 ); Chk( TheCache->ReleaseDC( DC ) );
ColsCh = Bass ? Dub : ( WW = XY.x - X + 1 ) > CharW + 3 ? Dub : 1 ;
return WW < CharW ; }