自定义今日项目窗口类

在开发过程中,经常需要编写大量重复且不够"用户友好"的代码。为了解决这个问题,尝试将标准的今日项目封装到一个类中,这个类可以被重用,并且对开发者来说更加舒适。

创建这个类的目的,是编写一个类似于MFCCWnd类的类。这个类封装了今日项目的基本功能,并定义了可以由开发者重写的基本行为。

摘要

定义的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);

这个方法处理一些基本消息,并且定义了一些可以覆盖的虚拟方法。在看来,最常用的消息是:

  • WM_CREATE
  • WM_DESTROY
  • WM_PAINT
  • WM_ERASEBKGND
  • WM_LBUTTONDOWN
  • WM_LBUTTONUP
  • WM_TODAYCUSTOM_CLEARCACHE
  • WM_TODAYCUSTOM_QUERYREFRESHCACHE
  • WM_SETTINGCHANGE

这些消息都有自己的消息处理程序。特殊行为的处理器有:

  • WM_PAINT,首先尝试绘制分配给窗口的图标。这个图标必须通过SetIcon方法设置。
  • WM_TODAYCUSTOM_QUERYREFRESHCACHE,识别今日自定义项的初始化,并设置正确的项目高度存储在m_nHeight中,并由SetItemHeight方法设置。
  • WM_ERASEBKGND消息处理程序OnEraseBkgnd绘制项目的透明背景。这个标准行为可以被开发者覆盖。

创建今日自定义项窗口的处理在:

BOOL Create(HWND hWndParent, DWORD dwStyle = WS_VISIBLE | WS_CHILD)

这个方法创建一个窗口,具有以下属性:

  • dwStyle参数中传递的风格
  • hWndParent参数中传递的父窗口
  • 矩形最初设置为左=0,顶部=0,宽度=屏幕宽度,高度=0
  • 类和窗口名称作为属性在构造函数中传递或通过SetClassInfo方法设置

这个类还提供了今日自定义项窗口类(取消)注册。

类注册由:

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); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485