Click here to Skip to main content
12,395,871 members (64,816 online)
Click here to Skip to main content
Add your own
alternative version

Stats

122.3K views
270 downloads
48 bookmarked
Posted

CTodayWindow - A template class for creating custom today items

, 10 Aug 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
An article on writing custom today items using the CTodayWindow class.

Sample Image - CTodayWindow.jpg

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 the 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 the MFC CWnd class. This class wraps the basic functionality of a today custom item and defines the basic behavior overridable by the developer.

Abstract

The 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 to write anymore 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 commonly 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 the following handlers:

  • WM_PAINT which firstly tries to draw the icon assigned to the window. This icon has to be set by the SetIcon method.
  • WM_TODAYCUSTOM_QUERYREFRESHCACHE which recognizes the initialization of the today custom item and sets the correct item height stored in m_nHeight and set by the SetItemHeight method.
  • WM_ERASEBKGND message handler OnEraseBkgnd draws the transparent background for the item. This standard behavior can be overridden by the developer.

Creation of a today custom item window is handled in the:

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

method. This method creates a window with the following attributes:

  • style passed in the dwStyle parameter
  • parent window passed in the hWndParent parameter
  • rectangle initially set to left = 0, top = 0, width = screen width, height = 0
  • class and window name passed as attributes in the constructor or set by the SetClassInfo method

This class provides a today custom item window class (un)registration as well.

  • Class registration is provided by the void RegisterTodayClass(WNDPROC wndProc) method. The parameter is the main window procedure defined in your today custom item application.
  • Class unregistration is provided by void UnregisterTodayClass()

Using the code

Using this class is very simple. Just derive your own class from the CTodayWindow class and define your today custom item behavior. Then, write the main application logic as generally known (for example, from MSDN). In the DLLMain function, create an instance of your class when attaching the library to process. Set the common attributes like item height, item icon etc. In the InitializeCustomItem function, register your class and create the today custom item window by calling the 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);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

eXEden
Web Developer
Czech Republic Czech Republic
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionCan someone have a Visual Studio 2008 example of this TodayItem Pin
jenga73737319-Dec-09 5:17
memberjenga73737319-Dec-09 5:17 
QuestionHow to get Today Screen's HWND? Pin
lifecat94-Sep-07 20:33
memberlifecat94-Sep-07 20:33 
GeneralSelection of the custom today item - without touchscreen Pin
Mikael Braad Nielsen12-Feb-07 5:14
memberMikael Braad Nielsen12-Feb-07 5:14 
GeneralRe: Selection of the custom today item - without touchscreen Pin
siri_s14-Feb-07 1:23
membersiri_s14-Feb-07 1:23 
GeneralRe: Selection of the custom today item - without touchscreen Pin
Mikael Braad Nielsen15-Feb-07 23:44
memberMikael Braad Nielsen15-Feb-07 23:44 
GeneralRe: Selection of the custom today item - without touchscreen Pin
siri_s19-Feb-07 17:46
membersiri_s19-Feb-07 17:46 
GeneralOther comments from Scott Hunter Pin
siri_s20-Feb-07 17:06
membersiri_s20-Feb-07 17:06 
AnswerProblem solved Pin
Mikael Braad Nielsen6-Jun-07 9:08
memberMikael Braad Nielsen6-Jun-07 9:08 
GeneralThanks for your article. Pin
Iain Clarke8-Feb-07 3:52
memberIain Clarke8-Feb-07 3:52 
GeneralRe: Thanks for your article. Pin
nemanjas30-Mar-08 22:21
membernemanjas30-Mar-08 22:21 
GeneralError in CMyToday::~CMyToday() Pin
isemenov4-Dec-06 4:53
memberisemenov4-Dec-06 4:53 
GeneralWindow Mobile 2005 Pin
bm_masri29-Jan-06 7:10
memberbm_masri29-Jan-06 7:10 
GeneralHandle WM_KILLFOCUS Pin
Bas Spymac4-Jul-05 2:34
sussBas Spymac4-Jul-05 2:34 
QuestionMFC? Pin
cteel043-Apr-05 10:55
membercteel043-Apr-05 10:55 
QuestionDoes it work???? Pin
WaveFront Technologies, Inc.1-Oct-04 18:38
memberWaveFront Technologies, Inc.1-Oct-04 18:38 
AnswerRe: Does it work???? Pin
Daniel Jin31-Mar-05 14:47
memberDaniel Jin31-Mar-05 14:47 
QuestionHow to get Today Item Window Handle ? Pin
smoh23-Jul-04 9:43
membersmoh23-Jul-04 9:43 
AnswerRe: How to get Today Item Window Handle ? Pin
Daniel Jin31-Mar-05 14:31
memberDaniel Jin31-Mar-05 14:31 
GeneralRe: How to get Today Item Window Handle ? Pin
lifecat94-Sep-07 16:52
memberlifecat94-Sep-07 16:52 
AnswerRe: How to get Today Item Window Handle ? Pin
johnwoo92816-Aug-05 15:33
memberjohnwoo92816-Aug-05 15:33 
Generaladd content dynamically Pin
ting66820-Jun-04 1:14
memberting66820-Jun-04 1:14 
GeneralRe: add content dynamically Pin
Daniel Jin31-Mar-05 14:27
memberDaniel Jin31-Mar-05 14:27 
GeneralOnCreate m_hWnd still NULL Pin
R_S14-Jun-04 10:21
memberR_S14-Jun-04 10:21 
GeneralRe: OnCreate m_hWnd still NULL Pin
Daniel Jin31-Mar-05 14:21
memberDaniel Jin31-Mar-05 14:21 
Generalmissing = in if(m_hWnd==NULL) Pin
R_S14-Jun-04 10:16
memberR_S14-Jun-04 10:16 
GeneralMistake in ctor Pin
Bugaboo13-Apr-04 1:21
memberBugaboo13-Apr-04 1:21 
QuestionHow to get it working on eVC++ 4 Pin
Vinnepin18-Feb-04 5:42
memberVinnepin18-Feb-04 5:42 
AnswerRe: How to get it working on eVC++ 4 Pin
Daniel Jin31-Mar-05 14:48
memberDaniel Jin31-Mar-05 14:48 
QuestionHow to use the dll? Pin
mzjun28-Jan-04 1:38
membermzjun28-Jan-04 1:38 
AnswerRe: How to use the dll? Pin
Wes Jones12-Jan-05 15:32
memberWes Jones12-Jan-05 15:32 
GeneralRe: How to use the dll? Pin
Tony Kmoch25-Jan-06 1:35
memberTony Kmoch25-Jan-06 1:35 
Questionhow to see it Pin
ETA6-Dec-03 8:36
memberETA6-Dec-03 8:36 
AnswerRe: how to see it Pin
phenix_teng8-Dec-03 13:46
memberphenix_teng8-Dec-03 13:46 
Generaldebugging Pin
astrid2-Dec-03 23:58
memberastrid2-Dec-03 23:58 
GeneralRe: debugging Pin
Anonymous20-Jan-04 7:45
sussAnonymous20-Jan-04 7:45 
GeneralUsing Timers ... Pin
surrahman25-Oct-03 21:21
susssurrahman25-Oct-03 21:21 
GeneralRe: Using Timers ... Pin
R_S14-Jun-04 10:24
memberR_S14-Jun-04 10:24 
GeneralGood Stuff Pin
bmichael8-Sep-03 16:53
memberbmichael8-Sep-03 16:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 11 Aug 2003
Article Copyright 2003 by eXEden
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid