////////////////////////////////////////////////////////////////
// MFC Animation control from afxcmn.h
//
class CAnimateCtrl : public CWnd
{
DECLARE_DYNAMIC(CAnimateCtrl)
// Constructors
public:
CAnimateCtrl();
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
// Operations
BOOL Open(LPCTSTR lpszFileName);
BOOL Open(UINT nID);
BOOL Play(UINT nFrom, UINT nTo, UINT nRep);
BOOL Stop();
BOOL Close();
BOOL Seek(UINT nTo);
// Implementation
public:
virtual ~CAnimateCtrl();
};
TBAnim.h
////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "StatLink.h"
#define DEFAULT_ANIM_STYLE WS_CHILD | WS_VISIBLE | ACS_CENTER
////////////////
// Toolbar animation control that has a hyperlink.
//
class CTBAnim : public CAnimateCtrl {
public:
CTBAnim(LPCTSTR lpszURL=NULL) : m_link(lpszURL) { }
virtual ~CTBAnim() { }
CHyperlink m_link; // go here when clicked
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg UINT OnNcHitTest(CPoint point);
DECLARE_MESSAGE_MAP()
DECLARE_DYNCREATE(CTBAnim)
};
//////////////////
// Derive your toolbar from this if you're not using a rebar.
//
class CAnimToolBar : public CToolBar {
public:
CAnimToolBar(UINT nWidthAnim, UINT nResID) {
m_nWidthAnim = nWidthAnim;
m_nIDAnim = nResID;
}
~CAnimToolBar() { }
CTBAnim m_wndAnim; // animation control
protected:
int m_nWidthAnim; // width of animation
int m_nIDAnim; // resource ID of animation
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_DYNAMIC(CAnimToolBar)
DECLARE_MESSAGE_MAP()
};
TBAnim.cpp
/ ////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "StdAfx.h"
#include "TBAnim.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CTBAnim, CAnimateCtrl)
BEGIN_MESSAGE_MAP(CTBAnim, CAnimateCtrl)
ON_WM_NCHITTEST()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
//////////////////
// Normally, the animation control returns HTTRANSPARENT, which disallows
// mouse clicks; need to return HTCLIENT to get WM_LBUTTONDOWN, etc.
//
UINT CTBAnim::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
//////////////////
// User clicked: launch the hyperlink
// If string is empty, load it from resource.
//
void CTBAnim::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_link.IsEmpty())
m_link.LoadString(GetDlgCtrlID());
m_link.Navigate();
}
////////////////////////////////////////////////////////////////
// CAnimToolBar
IMPLEMENT_DYNAMIC(CAnimToolBar, CToolBar)
BEGIN_MESSAGE_MAP(CAnimToolBar, CToolBar)
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()
//////////////////
// Create handler: create the animation control
//
int CAnimToolBar::OnCreate(LPCREATESTRUCT lpcs)
{
if (CToolBar::OnCreate(lpcs)==-1)
return -1;
m_wndAnim.Create(DEFAULT_ANIM_STYLE, CRect(0,0,0,0), this, m_nIDAnim);
return 0;
}
//////////////////
// Size handler: size the animation control
//
void CAnimToolBar::OnSize(UINT nType, int cx, int cy)
{
CToolBar::OnSize(nType, cx, cy);
CRect rc(cx-m_nWidthAnim, 0, cx, cy); // right edge
m_wndAnim.MoveWindow(&rc); // do it
}
Doc.h
////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
const MAXNUMICONS = 1024;
////////////////
// Document holds an array of small and large icons
//
class CIconsDoc : public CDocument {
public:
CIconsDoc();
virtual ~CIconsDoc();
// public interface
int GetNumIcons() { return m_nIcons; }
const HICON* GetSmallIcons() { return m_pIconsSmall; }
const HICON* GetLargeIcons() { return m_pIconsLarge; }
protected:
int m_nIcons; // total number of icons
HICON m_pIconsSmall[MAXNUMICONS]; // array of small HICONs
HICON m_pIconsLarge[MAXNUMICONS]; // array of large HICONs
// MFC overrides
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
virtual void SetTitle(LPCTSTR lpszTitle);
afx_msg void OnUpdateIconIndicator(CCmdUI* pCmdUI);
DECLARE_MESSAGE_MAP()
DECLARE_DYNCREATE(CIconsDoc)
};
Doc.cpp
/ ////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "stdafx.h"
.
.
.
IMPLEMENT_DYNCREATE(CIconsDoc, CDocument)
BEGIN_MESSAGE_MAP(CIconsDoc, CDocument)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_ICONS, OnUpdateIconIndicator)
END_MESSAGE_MAP()
//////////////////
// Add number of icons to document title
//
void CIconsDoc::SetTitle(LPCTSTR lpszTitle)
{
CString sTitle;
if (m_nIcons>=0) {
sTitle.Format(_T("%s [%d icons]"), lpszTitle, m_nIcons);
lpszTitle = sTitle;
}
CDocument::SetTitle(lpszTitle);
}
//////////////////
// Load all the icons into the array.
// Ignore extra icons if more than MAXNUMICONS (so sorry).
//
void CIconsDoc::Serialize(CArchive& ar)
{
if (!ar.IsStoring()) {
m_nIcons = ::ExtractIconEx(
ar.GetFile()->GetFilePath(), // file name
0, // start index
m_pIconsLarge, // array of HICONs
m_pIconsSmall, // ..ditto
MAXNUMICONS); // max num to get
ASSERT(m_nIcons != -1);
}
}
//////////////////
// Update the status bar indicator for number of icons
//
void CIconsDoc::OnUpdateIconIndicator(CCmdUI* pCmdUI)
{
CString s = _T("No File");
if (m_nIcons>=0)
s.Format(_T("%d Icons"), m_nIcons);
pCmdUI->SetText(s);
}
View.h
////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "doc.h"
const MYWM_GETTOOLBAR = WM_USER;
//////////////////
// Icon view displays all the icons in its window
//
class CIconsView : public CScrollView {
protected:
CIconsView() { }
virtual ~CIconsView() { }
CIconsDoc* GetDocument() { return (CIconsDoc*)m_pDocument; }
protected:
virtual void OnInitialUpdate();
virtual void OnDraw(CDC* pDC);
afx_msg void OnFoo();
DECLARE_MESSAGE_MAP()
DECLARE_DYNCREATE(CIconsView)
};
View.cpp
////////////////////////////////////////////////////////////////
// 1999 Microsoft Systems Journal.
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "stdafx.h"
•
•
•
//////////////////
// Initial update: set scroll sizes and change toolbar bitmap.
//
void CIconsView::OnInitialUpdate()
{
CIconsDoc* pdoc = GetDocument();
ASSERT_VALID(pdoc);
CScrollView::OnInitialUpdate();
// compute width of all icons
int nIcons = pdoc->GetNumIcons();
int cx = nIcons > 0 ? nIcons * GetSystemMetrics(SM_CXICON) : 0;
// ...and height
int cy = GetSystemMetrics(SM_CYICON) + // normal icon
GetSystemMetrics(SM_CYSMICON) + // small icon
GetSystemMetrics(SM_CYHSCROLL); // allow room for scroll bar
// First change window size, height only (leave width alone)
GetParentFrame()->RecalcLayout();
CRect rc;
GetClientRect(&rc);
SetScrollSizes(MM_TEXT, CSize(rc.Width(), cy));
ResizeParentToFit();
// Now that window size is correct, set true scroll sizes
SetScrollSizes(MM_TEXT, CSize(cx, cy));
// load toolbar bitmap
CBitmap bm;
VERIFY(bm.LoadBitmap(IDR_MAINFRAME));
CToolBar* pToolBar = (CToolBar*)GetParent()->SendMessage(MYWM_GETTOOLBAR);
if (nIcons > 0 && pToolBar) {
// If there's a toolbar, change its first button to be the first
// small icon in the currently open EXE or DLL
// create memory DC
CWindowDC dc(this);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
// select toolbar bitmap
CBitmap *poldbm = memdc.SelectObject(&bm);
// draw into the dc/bitmap
CBrush brush;
brush.CreateSysColorBrush(COLOR_BTNFACE);
VERIFY(::DrawIconEx(memdc, 0, 0, // dc, x, y
*pdoc->GetSmallIcons(), // HICON (first small one)
GetSystemMetrics(SM_CXSMICON), // cx
GetSystemMetrics(SM_CYSMICON), // cy
0, brush, DI_NORMAL)); // frame, brush, flags
memdc.SelectObject(poldbm);
}
// Change bitmap in toolbar. This will delete the old one
pToolBar->SetBitmap((HBITMAP)bm.Detach());
pToolBar->Invalidate(TRUE); // repaint
}
//////////////////
// Draw the icons
//
void CIconsView::OnDraw(CDC* pdc)
{
CIconsDoc* pdoc = GetDocument();
ASSERT_VALID(pdoc);
int nIcons = pdoc->GetNumIcons();
if (nIcons > 0) {
const HICON* pIconLarge = pdoc->GetLargeIcons();
const HICON* pIconSmall = pdoc->GetSmallIcons();
int w = GetSystemMetrics(SM_CXICON);
int h = GetSystemMetrics(SM_CYICON);
int wSmall = GetSystemMetrics(SM_CXSMICON);
int hSmall = GetSystemMetrics(SM_CYSMICON);
int x = 0;
for (int i=0; i<nIcons; i++) {
// NOTE: for normal (large) icons, you could also use
// CWnd::DrawIcon, which has fewer args, but for small
// icons, you must use DrawIconEx
CBrush brush;
brush.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
::DrawIconEx(*pdc,x,0,pIconSmall[i],w,h,0,brush,DI_NORMAL);
::DrawIconEx(*pdc,x,h,pIconSmall[i],wSmall,hSmall,0,brush,DI_NORMAL);
x += w;
}
}
}