Introduction
When writing a custom today item, we always spend a lot of time on writing code that is repeatable and even less "user-friendly". I've tried to wrap standard today custom item into a class which could be reused and is more comfortable for developers.
Background
The purpose of doing this was to write a class which would be similar to MFC CWnd
class. This class wraps basic functionality of today custom item and defines basic behavior overridable by the developer.
Abstract
Class CTodayWindow
is defined as follows:

class CTodayWindow
{
public:
// Member Variables
HWND m_hWnd;
// Methods
CTodayWindow();
CTodayWindow(HINSTANCE hInstance,
LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
virtual ~CTodayWindow();
// Main Create method
BOOL Create(HWND hWndParent,
DWORD dwStyle = WS_VISIBLE | WS_CHILD);
// Update Window
void RefreshWindow(BOOL bShow = FALSE);
// Set Methods
BOOL SetIcon(UINT uID, int xDrawAt = 2, int yDrawAt = 0);
void SetItemHeight(int nHeight);
void SetClassInfo(LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
void SetInstance(HINSTANCE hInstance);
// Get Methods
HWND GetParent() {return m_hParentHwnd;};
int GetItemHeight() {return m_nHeight;};
HINSTANCE GetInstance() {return m_hInstance;};
HICON GetIcon() {return m_hIcon;};
LPCTSTR GetClassName() {return m_lpszClassName;};
LPCTSTR GetWindowName() {return m_lpszWindowName;};
// Register/Unregister TodayWindow
void RegisterTodayClass(WNDPROC wndProc);
void UnregisterTodayClass();
// TodayWndProc - main message loop
virtual LRESULT CALLBACK TodayWndProc(UINT uMsg,
WPARAM wParam, LPARAM lParam);
protected:
BOOL m_bInitialRefresh;
int m_nHeight;
POINT m_pointIconPos;
HWND m_hParentHwnd;
HICON m_hIcon;
HINSTANCE m_hInstance;
LPCTSTR m_lpszClassName;
LPCTSTR m_lpszWindowName;
COLORREF m_crTodayText;
HFONT m_hNormalTodayFont;
HFONT m_hBoldTodayFont;
virtual void DrawTodayIcon(HDC hDC, int xPos, int yPos);
virtual void GetTodayDefaults();
// Message handlers
virtual int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual void OnDestroy();
virtual void OnPaint(HDC hDC);
virtual void OnEraseBkgnd(HDC hDC);
virtual void OnTodayCustomQueryRefreshCache
(TODAYLISTITEM *pTodayListItem, BOOL *pResult);
virtual BOOL OnTodayCustomClearCache(TODAYLISTITEM *pTodayListItem);
virtual void OnLButtonUp(UINT nFlags, POINT point);
virtual void OnLButtonDown(UINT nFlags, POINT point);
virtual void OnSettingChange(UINT nFlags, LPCTSTR lpszSection);
virtual LRESULT OnNotify(UINT nID, NMHDR* pNMHDR);
virtual LRESULT OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
};
Basic class information
As you can see I've pre-defined recently used messages into message handlers which are easy-to-use in derived classes. You don't need write anymore huge code in WndProc
and do the same stuff again and again. The main message loop is defined in:
LRESULT CALLBACK TodayWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
This method handles some basic messages and I've defined some virtual methods you can override. From my point of view the most used message are:
WM_CREATE
WM_DESTROY
WM_PAINT
WM_ERASEBKGND
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_TODAYCUSTOM_CLEARCACHE
WM_TODAYCUSTOM_QUERYREFRESHCACHE
WM_SETTINGCHANGE
These messages have their own message handlers. Special behavior has following handlers:
WM_PAINT
which firstly tries to draw icon assigned to window. This icon has to be set bySetIcon
methodWM_TODAYCUSTOM_QUERYREFRESHCACHE
which recognizes initialization of today custom item and sets correct item height stored inm_nHeight
and set bySetItemHeight
methodWM_ERASEBKGND
message handlerOnEraseBkgnd
draws transparent background for item. This standard behavior can be overridden by the developer.
Creation of today custom item window is handled in:
BOOL Create(HWND hWndParent, DWORD dwStyle = WS_VISIBLE | WS_CHILD)
method. This method creates a window with following attributes:
- style passed in
dwStyle
parameter - parent window passed in
hWndParent
parameter - rectangle initially set to left = 0, top = 0, width = screen width, height = 0
- class and window name passed as attributes in constructor or set by
SetClassInfo
method
This class provides today custom item window class (un)registration as well.
- Class registration is provided by
void RegisterTodayClass(WNDPROC wndProc)
method. Parameter is main window procedure defined in your today custom item application. - Class unregistration is provided by
void UnregisterTodayClass()
Using the code
Usage of this class is very simple. Just derive your own class from CTodayWindow
class and define your today custom item behavior. Then write main application logic as generally known (for example from MSDN). In DLLMain
function create instance of your class when attaching library to process. Set common attributes like item height, item icon etc. In InitializeCustomItem
function, register your class and create today custom item window by calling Create
method. And that's all. Here is the sample code:

// Your derived class
static CMyToday* myToday;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH :
myToday = new CMyToday((HINSTANCE)hModule,
_T("MyTodayClass"), _T("MyTodayWnd"));
myToday->SetItemHeight(40);
myToday->SetIcon(IDI_APP_ICON);
break;
case DLL_PROCESS_DETACH :
myToday->UnregisterTodayClass();
delete myToday;
break;
}
return TRUE;
}
HWND InitializeCustomItem(TODAYLISTITEM *ptli, HWND hWndParent)
{
myToday->RegisterTodayClass((WNDPROC)WndProc);
myToday->Create(hWndParent, WS_VISIBLE | WS_CHILD);
myToday->RefreshWindow(TRUE);
return myToday->m_hWnd;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return myToday->TodayWndProc(uMsg, wParam, lParam);
}
eXEden
'컴퓨터/IT' 카테고리의 다른 글
삼성 애니콜 SPH-P9000 (0) | 2006.11.24 |
---|---|
간단한 로또 프로그램 c# (0) | 2006.11.03 |
CTodayOptionsDialog (0) | 2006.10.25 |
CTodayOptionsDialog (0) | 2006.10.25 |
Using the Today API (0) | 2006.10.25 |