在开发过程中,经常需要编写大量重复且不够"用户友好"的代码。为了解决这个问题,尝试将标准的今日项目封装到一个类中,这个类可以被重用,并且对开发者来说更加舒适。
创建这个类的目的,是编写一个类似于MFC的CWnd类的类。这个类封装了今日项目的基本功能,并定义了可以由开发者重写的基本行为。
定义的CTodayWindow类如下:
class CTodayWindow {
public:
// 成员变量
HWND m_hWnd;
// 方法
CTodayWindow();
CTodayWindow(HINSTANCE hInstance, LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
virtual ~CTodayWindow();
// 主要创建方法
BOOL Create(HWND hWndParent, DWORD dwStyle = WS_VISIBLE | WS_CHILD);
// 更新窗口
void RefreshWindow(BOOL bShow = FALSE);
// 设置方法
BOOL SetIcon(UINT uID, int xDrawAt = 2, int yDrawAt = 0);
void SetItemHeight(int nHeight);
void SetClassInfo(LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
void SetInstance(HINSTANCE hInstance);
// 获取方法
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; };
// 注册/注销TodayWindow
void RegisterTodayClass(WNDPROC wndProc);
void UnregisterTodayClass();
// TodayWndProc - 主消息循环
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();
// 消息处理程序
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);
};
如所见,已经预定义了最近使用的消息到消息处理程序中,这些在派生类中易于使用。不需要在WndProc中重复编写相同的代码。主消息循环定义在:
LRESULT CALLBACK TodayWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
这个方法处理一些基本消息,并且定义了一些可以覆盖的虚拟方法。在看来,最常用的消息是:
这些消息都有自己的消息处理程序。特殊行为的处理器有:
创建今日自定义项窗口的处理在:
BOOL Create(HWND hWndParent, DWORD dwStyle = WS_VISIBLE | WS_CHILD)
这个方法创建一个窗口,具有以下属性:
这个类还提供了今日自定义项窗口类(取消)注册。
类注册由:
void RegisterTodayClass(WNDPROC wndProc)
方法提供。参数是今日自定义项应用程序中定义的主窗口过程。
void UnregisterTodayClass()
// 派生类
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);
}