Click here to Skip to main content
15,868,141 members
Articles / Mobile Apps

CTodayOptionsDialog - let's continue writing today's custom items in sequence to the CTodayWindow class

Rate me:
Please Sign up or sign in to vote.
4.25/5 (17 votes)
11 Aug 2003CPOL3 min read 92.4K   183   35   23
An article on writing custom today items using the CTodayOptionsDialog and CTodayWindow classes.

Sample Image - TodayOptionsDialog.jpg

Introduction

Yesterday, I published an article about a template today custom item class, CTodayWindow. This class provides basic functionality, but without option dialog support. This article gives developers the possibility to use the CTodayWindow class together with CTodayOptionsDialog, one which handles the basic behavior of the option dialog.

Back to CTodayWindow class

The source contains the CTodayWindow class as well. I've made some changes to this class. First of all, message handling in TodayWndProc has been improved as well as getting the default fonts for the text being drawn on the today window. These fonts are stored in the member variables m_hNormalTodayFont and m_hBoldTodayFont. The default color for these two fonts should be one defined for the today custom items, and it's stored in the member variable m_crTodayText. That's all for the CTodayWindow class for now.

Background

The purpose of doing this was to write a class which would be similar to the MFC CDialog class. This class wraps the basic functionality of the option dialog for the today custom items and defines the basic behavior overridable by the developer.

Abstract

The class CTodayOptionsDialog is defined as follows:

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 CheckRadionButton(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);
};

Basic class information

As you can see, I've pre-defined the recently used messages into message handlers which are easy-to-use in the 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 TodayOptionsWndProc(HWND hDlg, 
               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 messages are:

  • WM_INITDIALOG
  • WM_DESTROY
  • WM_PAINT
  • WM_NOTIFY
  • WM_COMMAND
  • WM_ACTIVATE
  • WM_SETTINGCHANGE

These messages have their own message handlers. Special behavior have the following handlers:

  • WM_PAINT which firstly tries to draw the dialog title. This title has to be set by the SetTitle method.

Using the code

Using this class is very simple. Just derive your own class from the CTodayOptionsDialog class and define your own 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 a library to process. In the constructor, pass your CTodayWindow derived class as the parameter and set the dialog title. The class CTodayOptionsDialog has a reference on the current today custom item window stored in the member variable m_pWndTW. This allows the developer to access and work with the today custom item window and change its attributes while setting options. The only thing needed is to cast this variable to correct the today custom item window class derived from the CTodayWindow class, as follows:

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();
}

Initialization of the DLL library and an example of connecting the today custom item window class to its option dialog class is shown here:

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);
}

Remarks

These two classes working together gives developers the possibility of writing today custom items in a style "close to" that of MFC. Someone might find this code useful whereas another might not. For basic working with today custom items, this, I think, is enough.

License

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


Written By
Web Developer
Czech Republic Czech Republic
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAssociateWithOptionsDlg Pin
Jonathan Rosanowski20-Nov-08 9:54
Jonathan Rosanowski20-Nov-08 9:54 
Generalhelp me!!! Pin
Andrew822-Apr-08 2:12
Andrew822-Apr-08 2:12 
QuestionPropertysheet question [modified] Pin
Mark Rekveld5-Aug-07 5:29
Mark Rekveld5-Aug-07 5:29 
QuestionDo you have any sample code for Today plug-in in C# language? Pin
Lukecao9-Jun-07 22:15
Lukecao9-Jun-07 22:15 
GeneralToday Item disapearing Pin
Josh Booth19-May-05 5:13
Josh Booth19-May-05 5:13 
GeneralRe: Today Item disapearing Pin
zz_smith4-Jul-06 0:21
zz_smith4-Jul-06 0:21 
GeneralSomething wrong with Today DLL (MFC) Pin
Member 195646018-May-05 0:25
Member 195646018-May-05 0:25 
GeneralGreat demo and 1 Question Pin
Member 195646018-May-05 0:13
Member 195646018-May-05 0:13 
GeneralI want badly to maken a Today item for myself bud it wont work. Pin
tne7laa16-Apr-05 5:45
tne7laa16-Apr-05 5:45 
GeneralResource Error Pin
Harry Lau12-Dec-04 14:13
Harry Lau12-Dec-04 14:13 
GeneralRe: Resource Error Pin
Sang Yam17-Jan-05 5:02
Sang Yam17-Jan-05 5:02 
GeneralDinamicaly Change Height Pin
Oscar Carrasco A28-Aug-04 4:57
Oscar Carrasco A28-Aug-04 4:57 
GeneralRe: Dinamicaly Change Height Pin
Daniel Jin31-Mar-05 14:53
Daniel Jin31-Mar-05 14:53 
GeneralPlease make it Pocket Facelift compatible (themes for PPC2000 and many enhancements) Pin
_ms_14-Aug-03 3:49
_ms_14-Aug-03 3:49 
GeneralGreat Article but one question Pin
mattfreeman2-May-04 8:17
mattfreeman2-May-04 8:17 
GeneralRe: Great Article but one question Pin
Daniel Jin31-Mar-05 14:51
Daniel Jin31-Mar-05 14:51 
GeneralGood article for CE Pin
sanong12-Aug-03 20:37
sanong12-Aug-03 20:37 
GeneralRe: Good article for CE Pin
eXEden12-Aug-03 21:45
eXEden12-Aug-03 21:45 
GeneralRe: Good article for CE Pin
sanong12-Aug-03 21:50
sanong12-Aug-03 21:50 
GeneralRe: Good article for CE Pin
eXEden12-Aug-03 23:20
eXEden12-Aug-03 23:20 
GeneralRe: Good article for CE Pin
ting66820-Jun-04 5:12
ting66820-Jun-04 5:12 

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.