Looks interesting right! Well this is done using plain window’s GDI functions, here is a function which does this!
// Thanks to Charles Petzold!
void CCanvas::DrawOutlineText( CDC& dc, const CString& Text )
{
const int RestorePoint = dc.SaveDC();
// Create new font
CFont NewFont;
NewFont.CreatePointFont( 700, TEXT( "Verdana" ), &dc );
// Use this font
dc.SelectObject( &NewFont );
// Brush for pen
LOGBRUSH lBrushForPen = { 0 };
lBrushForPen.lbColor = RGB( 200, 150, 100 );
lBrushForPen.lbHatch = HS_CROSS;
lBrushForPen.lbStyle = BS_SOLID;
// New pen for drawing outline text
CPen OutlinePen;
OutlinePen.CreatePen( PS_GEOMETRIC | PS_SOLID, 2, &lBrushForPen, 0, 0 );
// Use this pen
dc.SelectObject( &OutlinePen );
dc.SetBkMode( TRANSPARENT );
dc.BeginPath();
// This text is not drawn on screen, but instead each action is being
// recorded and stored internally as a path, since we called BeginPath
dc.TextOut( 20, 20, Text );
// Stop path
dc.EndPath();
// Now draw outline text
dc.StrokePath();
dc.RestoreDC( RestorePoint );
}
Using ExtCreatePen and PS_USERSTYLE you can create funky styled pens instead of the old PS_DOT, PS_DASHDOT, PS_DASHDOTDOT style pens. When using PS_USERSTYLE for creating pens you’ve got specify an array of DWORD which holds dash and space length while drawing a user styled pen!
I’ve created a sample application which demostrates marching ants demo, if you’ve worked in photoshop then you’ve already seen it after selecting a portion of an image…
// Add this to "OnPaint" function to have some fun :smiley:
void CDialogTestDlg::DrawMarchingStuff()
{
CPaintDC dc(this);
const int SavePoint = dc.SaveDC();
// Just for demo, make this a member or whatever but not static !!!
static CFont fnt;
if( !fnt.GetSafeHandle() )
{
fnt.CreatePointFont( 700, _T( "verdana" ), &dc );
}
dc.SelectObject( fnt );
// Create new ext pen
CBrush Brush;
Brush.CreateSolidBrush( RGB( 255, 00, 178 ));
LOGBRUSH lBrush = { 0 };
Brush.GetLogBrush( &lBrush );
dc.SelectStockObject( NULL_BRUSH );
int DashLen = 1;
int SpaceLen = 2;
// Well this is the array that I was talking about, every value at "odd index" denotes dash length and every
// every value at "even index" denotes space length
CPen NewPen;
DWORD Style1[] = { DashLen, SpaceLen };
DWORD Style2[] = { DashLen, SpaceLen + 1 }; // Secret to animation
static int Decider = 0;
int StyleLength = 0;
DWORD* pStyle = NULL;
if( !Decider )
{
StyleLength = sizeof(Style1)/sizeof(Style1[0]);
pStyle = Style1;
Decider = 1;
}
else
{
StyleLength = sizeof(Style2)/sizeof(Style2[0]);
pStyle = Style2;
Decider = 0;
}
NewPen.CreatePen( PS_GEOMETRIC | PS_USERSTYLE, 1, &lBrush, StyleLength, pStyle );
// Hey Mr DC use MY pen
dc.SelectObject( &NewPen );
dc.SetBkMode(TRANSPARENT);
dc.BeginPath();
// This text is not drawn on screen, but instead each action is being
// recorded and stored internally as a path, since we called BeginPath
dc.TextOut( 20, 20, _T( "Hello Nibu" ));
// Stop path
dc.EndPath();
// Draw outlined text
dc.StrokePath();
// Draw a marching rectangle wrapping above text
dc.Rectangle( 20, 30, 500, 130 );
// Restore previous stuff
dc.RestoreDC( SavePoint );
}