Figure 1   EditCast.cpp
////////////////////////////////////////////////////////////////
// EditCast 1997 Microsoft Systems Journal. 
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// EditCast illustrates why it's not safe to cast the return from
// CWnd::GetDlgItem to a CEdit or other kind of window class.

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include "resource.h"
#include "TraceWin.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////
// Dialog class that alters the TAB sequence and handles
// the RETURN key.
//
class CMyDialog : public CDialog {
public:
    CMyDialog();
    ~CMyDialog();
    virtual BOOL OnInitDialog();
    afx_msg void OnButton();
    DECLARE_MESSAGE_MAP()
};
////////////////////////////////////////////////////////////////
// Application class
//
class CApp : public CWinApp {
public:
    CApp() { }
    virtual BOOL InitInstance();
} the App;

/////////////////
// Initialize: just run the dialog and quit.
//
BOOL CApp::InitInstance()
{
    CMyDialog dlg;
    dlg.DoModal();
    return FALSE;
}
////////////////////////////////////////////////////////////////
// CMyDialog
//
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    ON_BN_CLICKED(IDC_BUTTON1, OnButton)
END_MESSAGE_MAP()

//////////////////
// Construct dialog: set everything to zero or NULL.
//
CMyDialog::CMyDialog() : CDialog(IDD_DIALOG1)
{
}

CMyDialog::~CMyDialog()
{
}
/////////////////
// Initialize dialog: load accelerators and set initial focus.
//
BOOL CMyDialog::OnInitDialog()
{
    return CDialog::OnInitDialog();
}
/////////////////
// Button handler: do demo stuff
//
void CMyDialog::OnButton()
{
    // Get the window
    CWnd*     pWnd  = GetDlgItem(IDC_EDIT1);
    ASSERT(pWnd);
    // Demonstrate that pWnd is not an edit control.
    CEdit*    pEdit = dynamic_cast<CEdit*>(pWnd);
    BOOL      bIsEdit = pWnd->IsKindOf(RUNTIME_CLASS(CEdit));
    TRACE("GetDlgItem(IDC_EDIT1) returns CWnd = %p\n", pWnd);
    TRACE("dynamic_cast to CEdit* = %p\n", pEdit);
    TRACE("pWnd->IsKindOf(RUNTIME_CLASS(CEdit)) returns %d\n", bIsEdit);
    
    // But you can treat it as one! (Do this at your own risk)
    pEdit = (CEdit*)pWnd;
    pEdit->SetSel(0, -1);
    pEdit->ReplaceSel("");
    pEdit->SetFocus();
}


Figure 3   StatLink

StatLink.h


 ////////////////////////////////////////////////////////////////// 
 // CStaticLink 1997 Microsoft Systems Journal. 
 // If this program works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 ////////////////
 // CStaticLink implements a static control that's a hyperlink
 // to any file on your desktop or web. You can use it in dialog boxes
 // to create hyperlinks to web sites. When clicked, opens the file/URL
 //
 class CStaticLink : public CStatic {
 public:
     CStaticLink();
 
     // you can change the Se any time:
     COLORREF     m_colorUnvisited;         // color for unvisited
     COLORREF     m_colorVisited;           // color for visited
     BOOL         m_bVisited;               // whether visited or not
 
     // URL/filename for non-text controls (e.g., icon, bitmap) or when link is
     // different from window text. If you don't set this, CStaticIcon will
     // use GetWindowText to get the link.
     CString     m_link;
 
 protected:
     DECLARE_DYNAMIC(CStaticLink)
     CFont         m_font;                  // underline font for text control
 
     // message handlers
     afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
     afx_msg void    OnClicked();
     DECLARE_MESSAGE_MAP()
 };
StatLink.cpp

 ////////////////////////////////////////////////////////////////// 
 // CStaticLink 1997 Microsoft Systems Journal. 
 // If this program works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // CStaticLink implements a static control that's a hyperlink
 // to any file on your desktop or web. You can use it in dialog boxes
 // to create hyperlinks to web sites. When clicked, opens the file/URL
 //
 #include "StdAfx.h"
 #include "StatLink.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 #endif
 
 IMPLEMENT_DYNAMIC(CStaticLink, CStatic)
 
 BEGIN_MESSAGE_MAP(CStaticLink, CStatic)
     ON_WM_CTLCOLOR_REFLECT()
     ON_CONTROL_REFLECT(STN_CLICKED, OnClicked)
 END_MESSAGE_MAP()
 ///////////////////
 // Constructor sets default colors = blue/purple.
 //
 CStaticLink::CStaticLink()
 {
     m_colorUnvisited = RGB(0,0,255);       // blue
     m_colorVisited   = RGB(128,0,128);     // purple
     m_bVisited       = FALSE;              // not visited yet
 }
 //////////////////// Handle reflected WM_CTLCOLOR to set custom control color.
 // For a text control, use visited/unvisited colors and underline font.
 // For non-text controls, do nothing. Also ensures SS_NOTIFY is on.
 //
 HBRUSH CStaticLink::CtlColor(CDC* pDC, UINT nCtlColor)
 {
     ASSERT(nCtlColor == CTLCOLOR_STATIC);
     DWORD dwStyle = GetStyle();
     if (!(dwStyle & SS_NOTIFY)) {
         // Turn on notify flag to get mouse messages and STN_CLICKED.
         // Otherwise, I'll never get any mouse clicks!
         ::SetWindowLong(m_hWnd, GWL_STYLE, dwStyle | SS_NOTIFY);
     }
     
     HBRUSH hbr = NULL;
     if ((dwStyle & 0xFF) <= SS_RIGHT) {
 
         // this is a text control: set up font and colors
         if (!(HFONT)m_font) {
             // first time init: create font
             LOGFONT lf;
             GetFont()->GetObject(sizeof(lf), &lf);
             lf.lfUnderline = TRUE;
             m_font.CreateFontIndirect(&lf);
         }
 
         // use underline font and visited/unvisited colors
         pDC->SelectObject(&m_font);
         pDC->SetTextColor(m_bVisited ? m_colorVisited : m_colorUnvisited);
         pDC->SetBkMode(TRANSPARENT);
 
         // return hollow brush to preserve parent background color
         hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
     }
     return hbr;
 }
 /////////////////
 // Handle mouse click: open URL/file.
 //
 void CStaticLink::OnClicked()
 {
     if (m_link.IsEmpty())         // if URL/filename not set..
         GetWindowText(m_link);    // ..get it from window text
 
     // Call ShellExecute to run the file.
     // For an URL, this means opening it in the browser.
     //
     HINSTANCE h = ShellExecute(NULL, "open", m_link, NULL, NULL, SW_SHOWNORMAL);
     if ((UINT)h > 32) {
         m_bVisited = TRUE;       // (not really--might not have found link)
         Invalidate();            // repaint to show visited color
     } else {
         MessageBeep(0);          // unable to execute file!
         TRACE(_T("*** WARNING: CStaticLink: unable to execute file %s\n"),
               (LPCTSTR)m_link);
     }
 }


Figure 4   AboutDlg.cpp


 ////////////////////////////////////////////////////////////////
 // ABOUTDLG 1997 Microsoft Systems Journal. 
 // If this program works, it was written by Paul DiLascia.
 // If not, I don't know who wrote it.
 // ABOUTDLG illustrates how to use CStaticLink to implement an About
 // dialog with a web link in it.
 
 #include "StdAfx.h"
 #include "Resource.h"
 #include "StatLink.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 #endif
 //////////////////
 // Standard main frame class
 class CMainFrame : public CFrameWnd {
 protected:
     DECLARE_DYNAMIC(CMainFrame)
     CStatusBar  m_wndStatusBar;
     CToolBar    m_wndToolBar;
     afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
     DECLARE_MESSAGE_MAP()
 };
 /////////////////
 // Standard app class
 class CMyApp : public CWinApp {
 public:
     CMyApp();
 protected:
     DECLARE_DYNAMIC(CMyApp)
     virtual BOOL InitInstance();
     afx_msg void OnAppAbout();
     DECLARE_MESSAGE_MAP()
 };
 ////////////////////////////////////////////////////////////////
 // CMyApp implementation
 CMyApp the App;
 
 IMPLEMENT_DYNAMIC(CMyApp, CWinApp)
 
 BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
     ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
 END_MESSAGE_MAP()
 
 CMyApp::CMyApp()
 {
 }
 //////////////////
 // Standard InitInstance
 BOOL CMyApp::InitInstance()
 {
    // Create main frame window (don't use doc/view stuff)
    // 
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
       return FALSE;
    pMainFrame->ShowWindow(m_nCmdShow);
    pMainFrame->UpdateWindow();
    m_pMainWnd = pMainFrame;
 
     return TRUE;
 }
 //////////////////
 // Custom about dialog uses CStaticLink for hyperlinks.
 //    * for text control, URL is specified as text in dialog editor
 //    * for icon control, URL is specified by setting m_iconLink.m_link
 class CAboutDlg : public CDialog {
 public:
     CAboutDlg() : CDialog(IDD_ABOUTBOX) { }
 protected:
     CStaticLink m_textLink;        // static text
     CStaticLink m_iconLink;        // static icon
 
     //////////////////
     // Initialize dialog: subclass static controls
     virtual BOOL OnInitDialog() {
         m_textLink.SubclassDlgItem(IDC_URLTEXT, this);
         m_iconLink.SubclassDlgItem(IDC_URLICON, this);
         m_iconLink.m_link = _T("http://www.microsoft.com/msj");
         return CDialog::OnInitDialog();
     }
 };
 //////////////////
 // Handle Help | About : run the About dialog
 void CMyApp::OnAppAbout()
 {
     CAboutDlg().DoModal();
 }
 ////////////////////////////////////////////////////////////////
 // CMainFrame implementation
 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
 
 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
     ON_WM_CREATE()
 END_MESSAGE_MAP()
 
 static UINT BASED_CODE indicators[] = {
     ID_SEPARATOR,       // status line indicator
     ID_INDICATOR_CAPS,
     ID_INDICATOR_NUM,
     ID_INDICATOR_SCRL,
 };
 
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
         return -1;
 
     if (!m_wndToolBar.Create(this) ||
         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))    {
         TRACE0("Failed to create toolbar\n");
         return -1;      // fail to create
     }
 
     if (!m_wndStatusBar.Create(this) ||
         !m_wndStatusBar.SetIndicators(indicators,
           sizeof(indicators)/sizeof(UINT))) {
         TRACE("Failed to create status bar\n");
         return -1;      // fail to create
     }
 
     m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
         CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
 
     return 0;
 }