Every time the Christmas holidays come, I think about making funny toys for my desktop.
Searching through the Internet, you can easily find many wonderful desktop gifts for any occasion, including Christmas time. Unfortunately, I couldn't find any source code or open source samples of such desktop animations.
So, I decided to create my own application that makes it snow on the desktop over other windows. As I can see from the Internet, many authors use different ways to display snow fall on the desktop. I tried to create my application as simple as possible, and decided to develop a system tray application with numerous child flake windows. I think, this method is the simplest, but has a few limitations regarding memory and video usage.
- Creating the main window.
We need to create a hidden frame window and prevent more than one open ‘Snow’ window at the same time. The following code fragment shows how to do this:
HWND hWnd = ::FindWindow("SnowParentWindow","Snow");
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
WS_OVERLAPPEDWINDOW, NULL, NULL);
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
static const TCHAR szClassName =
GetClassInfo(cs.hInstance, cs.lpszClass, &wc);
wc.lpszClassName = szClassName;
cs.lpszClass = szClassName;
- Installing the system tray icon.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
SetTrayIcon(NIM_ADD, m_hIcon, "Desktop Snow");
BOOL CMainFrame::SetTrayIcon(DWORD dwMessage,
HICON hIcon, PSTR pszTip)
BOOL bResult = FALSE;
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = m_hWnd;
tnd.uID = NULL;
tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnd.uCallbackMessage = WM_NOTIFYTRAY;
tnd.hIcon = hIcon;
lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
tnd.szTip = '\0';
bResult = Shell_NotifyIcon(dwMessage, &tnd);
- Creating the array of snow flakes.
In this application, each snow flake has been created as a non-modal dialog window with its own timer-dependent movement function.
int nScreenWidth = rcWorkArea.Width();
int nTimer = 5;
int nPosX = 0;
nTimer = abs(rand()*50/RAND_MAX);
nPosX = abs(rand()*nScreenWidth/RAND_MAX);
CFlakeDlg* fd = new CFlakeDlg(nTimer,nPosX,this);
- Creating a flake shape from the bitmap.
Before running the window, we need to create a flake region that shows the window as a real snow flake. I used the '
BitmapToRegion' function from the article of Jean-Edouard Lachand-Robert, posted here.
- The last step: start the timer and enjoy.
The last thing to do is start the timer and see how the flakes move. I used a very simple algorithm below, but it is sufficient to show snow movement on the desktop.
void CFlakeDlg::OnTimer(UINT nIDEvent)
if(nIDEvent == 1)
m_nCurrentY += 5;
if(m_nCounter == 15)
if(((rand()*10/RAND_MAX)-5)>0) m_nIncrement = 1;
else m_nIncrement = -1;
m_nCounter = 0;
m_nCurrentX += m_nIncrement;
m_nCurrentY = 0;
m_nCurrentX = abs(rand()*m_nScreenWidth/RAND_MAX);
m_nTimer = abs(rand()*50/RAND_MAX);
This example can be extended by drawing snowdrifts on the desktop, displaying Santa, snowman, and other objects. You can experiment with the flakes positioning (top, topmost, bottom), number of flakes, falling speed etc.
Anyway, I hope others find this code useful for the Christmas holidays. Please feel free to report errors, issues, or requests.