在软件开发中,创建自定义的今日项(Today Items)可以为用户提供更加个性化的体验。本文将介绍如何使用CTodayWindow和CTodayOptionsDialog类来实现这一功能。这两个类提供了基础的功能,使得开发者能够创建类似于MFC CDialog类的今日项。
CTodayWindow类是今日项的基础类,它提供了基本的功能,但是没有选项对话框的支持。本文将展示如何将CTodayWindow类与CTodayOptionsDialog类结合使用,后者处理选项对话框的基本行为。
在CTodayWindow类的实现中,对TodayWndProc的消息处理进行了改进,并且获取了用于在今日窗口上绘制文本的默认字体。这些字体存储在成员变量m_hNormalTodayFont和m_hBoldTodayFont中。这两种字体的默认颜色应该定义为今日自定义项的颜色,并存储在成员变量m_crTodayText中。
创建这个类的目的,是为了编写一个类似于MFC CDialog类的类。这个类封装了今日自定义项的选项对话框的基本功能,并定义了可以由开发者重写的基本行为。
CTodayOptionsDialog类定义如下:
class CTodayOptionsDialog {
public:
HWND m_hWnd;
CTodayOptionsDialog();
CTodayOptionsDialog(HINSTANCE hInstance, CTodayWindow *pToday, BOOL bFullScreen = TRUE);
virtual ~CTodayOptionsDialog();
// Get methods
HINSTANCE GetInstance() {
return m_hInstance;
};
BOOL GetFullScreen() {
return m_bFullScreen;
};
int GetTitleHeight() {
return m_nTitleHeight;
};
// Set methods
void SetInstance(HINSTANCE hInstance) { m_hInstance = hInstance; };
void SetFullScreen(BOOL bFullScreen) { m_bFullScreen = bFullScreen; };
void SetTitle(LPCTSTR lpszTitle, BOOL bRefresh = FALSE);
void SetTitle(UINT nID, BOOL bRefresh = FALSE);
// Association with option dialog created by system
void AssociateWithOptionsDlg(HWND hWnd);
void RefreshWindow();
virtual LRESULT CALLBACK TodayOptionsWndProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
// Reference to Today plug-in window
CTodayWindow *m_pWndTW;
BOOL m_bFullScreen;
int m_nTitleHeight;
LPCTSTR m_lpszTitle;
HINSTANCE m_hInstance;
HFONT m_hTitleFont;
// Methods for better work with controls
HWND ItemHandleFromID(UINT nID);
BOOL IsButtonChecked(UINT nID);
void CheckButton(UINT nID, BOOL bCheck = TRUE);
void CheckRadioButton(UINT nIDFirst, UINT nIDLast, UINT nIDToCheck);
virtual void DrawDialogTitle(HDC hDC);
virtual void GetDefaultTitleFont();
// Message handlers
virtual BOOL OnInitDialog(TODAYLISTITEM *ptli);
virtual void OnDestroy();
virtual void OnOK();
virtual void OnCancel();
virtual void OnPaint(HDC hDC);
virtual void OnActivate(UINT nState, HWND hWndPrevious, BOOL bMinimized);
virtual void OnCommand(UINT nID, UINT nNotifyCode, HWND hWndCtrl);
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 TodayOptionsWndProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
这个方法处理一些基本的消息,并且定义了一些可以覆盖的虚拟方法。在看来,最常用的消息有:
这些消息都有自己的消息处理程序。特殊行为有以下处理程序:
BOOL CMyOption::OnInitDialog(TODAYLISTITEM *ptli)
{
BOOL bResult = CTodayOptionsDialog::OnInitDialog(ptli);
CMyToday *pToday = (CMyToday*)m_pWndTW;
CheckButton(IDC_CHECK_SHOW_FIRST, pToday->m_bShowFirst);
CheckButton(IDC_CHECK_SHOW_SECOND, pToday->m_bShowSecond);
CheckButton(IDC_CHECK_SHOW_POWER, pToday->m_bShowPower);
return bResult;
}
void CMyOption::OnOK()
{
CMyToday *pToday = (CMyToday*)m_pWndTW;
pToday->m_bShowFirst = IsButtonChecked(IDC_CHECK_SHOW_FIRST);
pToday->m_bShowSecond = IsButtonChecked(IDC_CHECK_SHOW_SECOND);
pToday->m_bShowPower = IsButtonChecked(IDC_CHECK_SHOW_POWER);
CTodayOptionsDialog::OnOK();
}
static CMyToday* myToday;
static CMyOption *myOption;
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);
myToday->UnregisterTodayClass();
myOption = new CMyOption((HINSTANCE)hModule, myToday, TRUE);
myOption->SetTitle(_T("My Today Options"), FALSE);
break;
case DLL_PROCESS_DETACH:
delete myToday;
delete myOption;
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);
}
LRESULT WINAPI CustomItemOptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
return myOption->TodayOptionsWndProc(hDlg, message, wParam, lParam);
}