Click here to Skip to main content
15,905,233 members
Articles / Programming Languages / Javascript
Article

DayMon - See whose birthday is coming next

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
6 Apr 20075 min read 44.4K   685   18   8
Small Windows Vista Sidebar Gadget that helps those who want to be reminded of upcoming birthdays

Screenshot - daymon.jpg

Introduction

Let's start with personal history of mine.

Once upon a time, I wrote a small application, strictly for personal use, that will notify me whenever time gets close to someone's birthday. Nice way to let your friends know that you think of them. They don't need to know that your computer is keeping an eye on it.

When I first installed Windows Vista, I noticed the Sidebar (yes, I know, it is hard not to notice it) and I noticed how lots of things were based on XML - most noticeably Contacts. I saw lots of gadgets related to them (Address book style and similar), but there was nothing that would pull up an upcoming birthday and/or anniversary and remind me of that.

That is what this gadget will be about.

Downloads

You will notice that there are two downloads here. One is the source of the whole thing and other is just the gadget.

JavaScript

There are few limitations to Windows Vista Sidebar gadget. One that I find most disturbing for a .NET developer is lack of support for using it's objects. It is annoying to hear how Microsoft is all .NET about when new operating system component knows only COM. I needed some way to call my own .NET code.

There are a few ways, most notably using .NET interop to allow COM usage, but the problem with that is that you need to register it somehow. That just doesn't fit with install-free nature of gadgets. And manual entering of registering information in the registry is also something I don't like.

Only other way is to use the possibility of reading data from standard output and placing it in some tag.

JavaScript
var shell = new ActiveXObject("WScript.Shell");
var exec = shell.Exec("file.exe /arg1 /arg2");
document.getElementById('Output').innerHTML = exec.StdOut.ReadAll();

The downside of that choice was fact that I must use some HTML coding in my program to achieve this.

Since configuration also uses HTML/JavaScript programming style, one downside of this decision was that we need to send every configurable parameter down the path of command line argument.

C#

It was quite obvious to me that I need to create a Console project. However, it proved the wrong choice as when you call a Console application, the Console Window was always shown which is annoying. The right path was to build a normal Windows Application. You still get Console output just without the black box. Just what we need.

Parsing of command line arguments was a necessity and I took liberty to reuse one of my classes for that purpose so the only thing to notice here is that it works.

Once we got everything loaded, parsing could start. It just goes recursively into each subdirectory and puts each file in the array. I know that this wastes a small amount of memory since not all Contact files will have been date defined, but it makes it easier to debug and definitely easier to follow.

Birthdays and anniversaries are retrieved next. They all go through a small state machine that does parsing of XML via XmlTextReader. A class is created out of that data and within it calculates the next birthday date.

C#
try {
    thisYearDate = new System.DateTime(System.DateTime.Today.Year, 
                       this._date.Month, this._date.Day);
} catch (System.ArgumentOutOfRangeException) {
    thisYearDate = new System.DateTime(System.DateTime.Today.Year, 
                       this._date.Month, this._date.Day - 1);
}
if (thisYearDate >= System.DateTime.Today) {
    this._nextDate = thisYearDate;
} else {
    try {
        this._nextDate = new System.DateTime(System.DateTime.Today.Year + 1,
                                    this._date.Month, this._date.Day);
    } catch (System.ArgumentOutOfRangeException) {
        this._nextDate = new System.DateTime(System.DateTime.Today.Year + 1,
                                    this._date.Month, this._date.Day - 1);
    }
}

Some exception handling is needed for those who were born on 28th of February.

All elements of that array are sorted using that date.

C#
int IComparable<OneDay>.CompareTo(OneDay other) {
    return System.DateTime.Compare(this.NextDate, other.NextDate);
}

It is good to have generics.

Everything to do after that is to output the first few dates in HTML format (remember that we are directly filling 'Output' tag). That is all about HTML tags. The only difference you will notice is that it goes to XmlTagWriter which provides an easier way of filling XML data. Since it internally uses the well known XmlTextWriter, I don't think that there will be any problems.

Gadget

After everything is done, packing must follow. Since I used all files as content, Visual Studio was "forced" to output everything into the same directory. Just delete .pdb files and ZIP everything else. Zipped file must be renamed to .gadget extension and there you have it.

Possible improvements

Memory usage

Memory usage could be improved by not loading all birthdays at once and then sorting them later. One just needs to make one small list and compare every date with threshold for this list (calculated by all previous dates in it). Why I didn't do this? Well, it is easier to debug this way - you see exactly what the order of upcoming birthdays is, and, at least for me, there are only a limited number of birthdays that I enter in contacts. Memory consumption should be pretty low this way too.

Not calling exe

Parsing of XML files could be done from JavaScript itself. That way, one could avoid calling a separate executable. Why I didn't do it that way? It would take me much more effort to do it and not much would change for the end user. Moreover, this way I get all the benefits of modern programming language procedures and there is nothing I can't do.

Faster updates

It would be nice to have some FileWatcher to update the birthday list whenever a change is detected. But this timeout based refresh is quite OK. Once you enter all birthdays, they tend to be static in nature. There is no need to burden our system with real-time watching.

History

2007-04-06

  • Fixed bug with date parsing
  • Repacked source in order to remove Read-only attribute

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Siemens
Croatia Croatia
.NET programmer with MCSD and MCPD status. Loves chevapi...
Medo's Home Page

Comments and Discussions

 
QuestionCan I use this gadget in XP Pin
Hariohm13-Apr-09 21:03
Hariohm13-Apr-09 21:03 
AnswerRe: Can I use this gadget in XP Pin
Josip Medved13-Apr-09 21:53
Josip Medved13-Apr-09 21:53 
GeneralCan't install Pin
Hariohm8-Apr-09 22:04
Hariohm8-Apr-09 22:04 
AnswerRe: Can't install Pin
Josip Medved9-Apr-09 9:43
Josip Medved9-Apr-09 9:43 
GeneralProblem with installing daymon Pin
dermanu19-Jun-08 3:40
dermanu19-Jun-08 3:40 
QuestionRe: Problem with installing daymon Pin
Josip Medved21-Jul-08 9:52
Josip Medved21-Jul-08 9:52 
QuestionHow to add birthdays to the Vista Gadget ? Pin
DaMayor4-Jul-07 11:35
DaMayor4-Jul-07 11:35 
AnswerRe: How to add birthdays to the Vista Gadget ? Pin
Josip Medved4-Jul-07 20:23
Josip Medved4-Jul-07 20:23 

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.