Click here to Skip to main content
6,293,171 members and growing! (11,367 online)
Email Password   helpLost your password?
Multimedia » GDI » General     Intermediate

Falling Snow on Your Desktop!

By Igor Tolmachev

This article explains how to create an application that makes it snow on the desktop.
VC6, Windows, GDI, Dev
Posted:20 Dec 2006
Views:62,632
Bookmarked:70 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
48 votes for this article.
Popularity: 8.08 Rating: 4.81 out of 5
1 vote, 2.1%
1

2
2 votes, 4.2%
3
3 votes, 6.3%
4
42 votes, 87.5%
5

FallingSnow

Introduction

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.

General Steps

  1. 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:

    BOOL CSnowApp::InitInstance()
    {
        HWND hWnd = ::FindWindow("SnowParentWindow","Snow");
        if(hWnd) 
           return FALSE;
    
        CMainFrame* pFrame = new CMainFrame;
        m_pMainWnd = pFrame;
    
        pFrame->LoadFrame(IDR_TRAYMENU, 
                WS_OVERLAPPEDWINDOW, NULL, NULL);
    
        pFrame->ShowWindow(SW_HIDE);
    ...
    
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    ...
        if(cs.hInstance)
        {
            static const TCHAR szClassName[] = 
                        _T("SnowParentWindow");
            WNDCLASS wc;
            GetClassInfo(cs.hInstance, cs.lpszClass, &wc);
            wc.lpszClassName = szClassName;
            AfxRegisterClass(&wc);
            cs.lpszClass = szClassName;
        }
    ...
  2. 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;
    
        NOTIFYICONDATA tnd;
    
        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; 
    
        if(pszTip) 
           lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
        else
           tnd.szTip[0] = '\0'; 
    
        bResult = Shell_NotifyIcon(dwMessage, &tnd); 
    
        return bResult;
    }
    
  3. 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.

    CRect rcWorkArea;
    SystemParametersInfo(SPI_GETWORKAREA,0,(LPVOID)&rcWorkArea,0);
    int nScreenWidth = rcWorkArea.Width();
    
    int nTimer = 5;
    int nPosX = 0;
    
    srand((unsigned)time(NULL));
    for(int i=0;i<10;i++) // 10 snow flakes
    
    {
        nTimer = abs(rand()*50/RAND_MAX);
        nPosX = abs(rand()*nScreenWidth/RAND_MAX);
        CFlakeDlg* fd = new CFlakeDlg(nTimer,nPosX,this);
        if(fd->Create(IDD_FLAKE,this))
        m_arSnowFlakes.Add(fd);
    }
  4. 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.

  5. 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)
        {
            KillTimer(1);
    
            m_nCurrentY += 5;
            m_nCounter++;
    
            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;
    
            if(m_nCurrentY>m_nScreenHeight)
            {
                m_nCurrentY = 0;
                m_nCurrentX = abs(rand()*m_nScreenWidth/RAND_MAX);
                m_nTimer = abs(rand()*50/RAND_MAX);
            }
    
            MoveWindow(m_nCurrentX,m_nCurrentY,17,17);
            SetTimer(1,m_nTimer,0);
        }
    
        CDialog::OnTimer(nIDEvent);
    }
    

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.

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

About the Author

Igor Tolmachev


Member

Occupation: Software Developer (Senior)
Location: Ukraine Ukraine

Other popular GDI articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 49 (Total in Forum: 49) (Refresh)FirstPrevNext
GeneralCPU %100 Pinmembercsf3lih17:42 20 May '07  
GeneralFlicker problem with Java window Pinmemberx-bay7:46 2 Jan '07  
GeneralRe: Flicker problem with Java window PinmemberIgor Tolmachev5:56 3 Jan '07  
Generalfeature PinmemberNick Alexeev12:56 30 Dec '06  
GeneralRe: feature PinmemberIgor Tolmachev6:00 3 Jan '07  
GeneralGood PinmemberA.N.Zayed5:54 28 Dec '06  
GeneralRe: Good PinmemberIgor Tolmachev6:01 3 Jan '07  
GeneralMy C# Article is here PinmemberIgor Tolmachev7:39 27 Dec '06  
GeneralFlicker problem with Active desktop Pinmemberdustin_5:36 26 Dec '06  
GeneralAlso Happy Eid:) PinmemberMuammar©4:52 26 Dec '06  
GeneralMerry X-Mas!! PinmemberMuammar©20:53 25 Dec '06  
GeneralVery nice snow :) PinmemberEzz Khayyat15:37 25 Dec '06  
GeneralRe: Very nice snow :) PinmemberIgor Tolmachev6:02 3 Jan '07  
GeneralIts snowing on a sunny day. PinmemberMr.Prakash3:06 25 Dec '06  
GeneralVery Nice Work (and one Suggestion) PinmemberJeffrey Walton13:11 24 Dec '06  
GeneralRe: Very Nice Work (and one Suggestion) PinmemberIgor Tolmachev3:00 25 Dec '06  
GeneralRe: Very Nice Work (and one Suggestion) PinmemberJeffrey Walton19:17 25 Dec '06  
GeneralCool Pinmembertruongcongda23:40 22 Dec '06  
GeneralRe: Cool PinmemberIgor Tolmachev3:01 25 Dec '06  
GeneralC# code is here [modified] PinmemberIgor Tolmachev10:36 22 Dec '06  
QuestionTerrific snowflakes! :) PinmemberRaven#3778:46 22 Dec '06  
AnswerRe: Terrific snowflakes! :) PinmemberIgor Tolmachev10:33 22 Dec '06  
QuestionGood job! Pinmembersb_summer7:17 22 Dec '06  
GeneralFalling Snow PinmemberTigrisan11:23 21 Dec '06  
GeneralRe: Falling Snow PinmemberIgor Tolmachev23:44 21 Dec '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 20 Dec 2006
Editor: Smitha Vijayan
Copyright 2006 by Igor Tolmachev
Everything else Copyright © CodeProject, 1999-2009
Web12 | Advertise on the Code Project