A small Win32 program. Use vc6.0.
- # Include "stdafx. H"
- # Include <windows. h>
- # Include <math. h>
- # Include <stdlib. h>
- # Define id_timer 1
- # Define snownum 500 // snowflake count
- # Define contrast 50 // contrast
- # Define ystart 5 // determines the Y coordinate at the beginning of the snowflake.
- # Define snowcr RGB (0xff, 0xff, 0xff) // snowflake color-white
- # Define snowgathercr RGB (0xdb, 0xdb, 0xff) // stacked snowflake color
- Typedef struct tagsnow
- {
- Point ptsnowspos [snownum]; // used to save the coordinates of each snowflake
- Colorref crorg [snownum]; // used to draw the original color of the screen before snowflake
- Int ivx, Ivy, iallvx, iallvy;
- } Snow;
- Void initsnow (HDC, snow * sn, int isnow, int cxscreen );
- Int getcontrast (HDC, snow * sn, int isnow );
- Void drawsnow (HDC, snow * sn, int cxscreen );
- Lresult callback wndproc (hwnd, uint, wparam, lparam );
- Int winapi winmain (hinstance, hinstance hprevinstance,
- Pstr szcmdline, int icmdshow)
- {
- Static tchar szappname [] = text ("cls1_snow ");
- Hwnd;
- MSG;
- Wndclass;
- Wndclass. Style = cs_hredraw | cs_vredraw;
- Wndclass. lpfnwndproc = wndproc;
- Wndclass. cbclsextra = 0;
- Wndclass. cbwndextra = 0;
- Wndclass. hinstance = hinstance;
- Wndclass. hicon = loadicon (null, idi_application );
- Wndclass. hcursor = loadcursor (null, idc_arrow );
- Wndclass. hbrbackground = (hbrush) getstockobject (white_brush );
- Wndclass. lpszmenuname = NULL;
- Wndclass. lpszclassname = szappname;
- If (! Registerclass (& wndclass ))
- {
- MessageBox (null, text ("this program requires Windows NT! "), Szappname, mb_iconerror );
- Return 0;
- }
- Hwnd = createwindow (szappname, text ("desktop snow "),
- Ws_minimizebox | ws_sysmenu,
- Cw_usedefault, cw_usedefault,
- 240,120,
- Null, null, hinstance, null );
- Showwindow (hwnd, icmdshow );
- Updatewindow (hwnd );
- While (getmessage (& MSG, null, 0, 0 ))
- {
- Translatemessage (& MSG );
- Dispatchmessage (& MSG );
- }
- Return msg. wparam;
- }
- Lresult callback wndproc (hwnd, uint message, wparam, lparam)
- {
- HDC;
- Paintstruct pS;
- Rect;
- Static int cxscreen, cyscreen; // screen width and height (unit: pixels)
- Static int itimes, ilooptimes = 100;
- Static snow snowdream;
- Int I;
- Switch (Message)
- {
- Case wm_create:
- Cxscreen = getsystemmetrics (sm_cxscreen );
- Cyscreen = getsystemmetrics (sm_cyscreen );
- Srand (INT) getcurrenttime (); // initialize the random number generator
- Snowdream. iallvx = (unsigned) rand () % 3-1; // snowflake overall horizontal floating speed (-, 1)
- Snowdream. iallvy = (unsigned) rand () % 2 + 1; // The overall vertical falling speed of snowflake (1, 2)
- HDC = getdc (null); // retrieves the context of the entire screen.
- For (I = 0; I <snownum; I ++)
- {
- Snowdream. ptsnowspos [I]. x = rand () % cxscreen; // X coordinate of a snowflake that begins to fall
- Snowdream. ptsnowspos [I]. Y = rand () % ystart; // y coordinate of a snowflake that begins to fall
- Snowdream. crorg [I] = getpixel (HDC, snowdream. ptsnowspos [I]. X,
- Snowdream. ptsnowspos [I]. Y); // obtain the original color value of the specified point.
- }
- Releasedc (null, HDC );
- Settimer (hwnd, id_timer, 10, null); // timer, 10 ms
- Return 0;
- Case wm_displaychange: // when the resolution is changed
- Cxscreen = getsystemmetrics (sm_cxscreen );
- Cyscreen = getsystemmetrics (sm_cyscreen );
- Return 0;
- Case wm_timer:
- HDC = getdc (null); // retrieves the context of the entire screen.
- If (itimes> ilooptimes)
- {
- Itimes = 0;
- Ilooptimes = 50 + (unsigned) rand () % 50;
- If (snowdream. iallvx! = 0)
- Snowdream. iallvx = 0;
- Else
- Snowdream. iallvx = (unsigned) rand () % 3-1; // snowflake overall horizontal floating speed (-, 1)
- Snowdream. iallvy = (unsigned) rand () % 2 + 1; // The overall vertical falling speed of snowflake (1, 2)
- }
- Else
- Itimes ++;
- Drawsnow (HDC, & snowdream, cxscreen );
- Releasedc (null, HDC );
- Return 0;
- Case wm_paint:
- HDC = beginpaint (hwnd, & PS );
- Getclientrect (hwnd, & rect );
- Drawtext (HDC, text ("it's snowing on the desktop! "),-1, & rect,
- Dt_singleline | dt_center | dt_vcenter );
- Endpaint (hwnd, & PS );
- Return 0;
- Case wm_destroy:
- Killtimer (hwnd, id_timer); // stop the timer
- Invalidaterect (null, null, true); // refresh the Desktop
- Postquitmessage (0 );
- Return 0;
- }
- Return defwindowproc (hwnd, message, wparam, lparam );
- }
- Void initsnow (HDC, snow * sn, int isnow, int cxscreen) // initialize the isnow snowflake
- {
- Sn-> ptsnowspos [isnow]. x = (unsigned) rand () % cxscreen; // The Screen width in the X range
- Sn-> ptsnowspos [isnow]. Y = (unsigned) rand () % ystart; // The value of Y is within the ystart pixel on the top of the screen.
- Sn-> crorg [isnow] = getpixel (HDC, Sn-> ptsnowspos [isnow]. X,
- Sn-> ptsnowspos [isnow]. Y); // obtain the original color value for the specified point
- }
- Int getcontrast (HDC, snow * sn, int isnow)
- {
- Int IR, Ig, IB;
- Colorref crcmp;
- If (0 = Sn-> ivx) // If the horizontal speed is 0, the point at the bottom of the pixel is greater than the value.
- Crcmp = getpixel (HDC, Sn-> ptsnowspos [isnow]. X, Sn-> ptsnowspos [isnow]. Y + 1 );
- Else // If the horizontal speed is greater than 0, take the point in the lower right. <0 indicates that the point in the lower left is used.
- Crcmp = getpixel (HDC, Sn-> ptsnowspos [isnow]. x + (Sn-> ivx> 0? 1:-1), Sn-> ptsnowspos [isnow]. Y + 1 );
- If (crcmp = snowcr) // if it is a snowflake color
- Return 0;
- // Obtain the difference between the blue, green, and red parts of the crcmp and the comparison point.
- IB = ABS (crcmp> 16) & 0xff-(Sn-> crorg [isnow]> 16) & 0xff );
- IG = ABS (crcmp> 8) & 0xff-(Sn-> crorg [isnow]> 8) & 0xff );
- IR = ABS (crcmp) & 0xff-(Sn-> crorg [isnow]) & 0xff );
- Return (IR + ig + IB)/3;
- }
- Void drawsnow (HDC, snow * sn, int cxscreen)
- {
- Int I;
- For (I = 0; I <snownum; I ++)
- {
- // If the original color is not the snowflake color
- If (Sn-> crorg [I]! = Snowcr)
- Setpixel (HDC, Sn-> ptsnowspos [I]. X, Sn-> ptsnowspos [I]. y,
- Sn-> crorg [I]); // restores the color of the previous position
- Sn-> ivx = Sn-> iallvx * (I % 3 + 1); // X floating speed of snowflake
- Sn-> Ivy = Sn-> iallvy * (I % 3 + 1); // y floating speed of snowflake
- // Rand () % 5-2 jitter when the snowflake falls
- Sn-> ptsnowspos [I]. x + = Sn-> ivx + rand () % 5-2; // The next X coordinate of snowflake
- Sn-> ptsnowspos [I]. Y + = Sn-> Ivy + 1; // The next y coordinate of snowflake
- // Obtain the original color value for the specified point
- Sn-> crorg [I] = getpixel (HDC, Sn-> ptsnowspos [I]. X, Sn-> ptsnowspos [I]. y );
- If (clr_invalid = Sn-> crorg [I]) // if the color fails to be obtained, the snowflake floats out of the screen.
- {
- Initsnow (HDC, Sn, I, cxscreen); // reinitialize snowflake
- Continue;
- }
- If (Sn-> crorg [I]! = Snowcr) // if the color of the current vertex is not the color of snowflake
- {
- If (snowgathercr = Sn-> crorg [I]) // color of the current vertex = color of accumulated snow
- {// Set to the snowflake color
- Setpixel (HDC, Sn-> ptsnowspos [I]. X, Sn-> ptsnowspos [I]. Y, snowcr );
- Sn-> crorg [I] = snowcr;
- // Initsnow (HDC, Sn, I, cxscreen); // reinitialize snowflake
- }
- Else if (getcontrast (HDC, Sn, I)> 50) // If the contrast is greater than 50
- {// Snow accumulation
- Setpixel (HDC, Sn-> ptsnowspos [I]. X, Sn-> ptsnowspos [I]. Y, snowgathercr );
- Setpixel (HDC, Sn-> ptsnowspos [I]. X-1, Sn-> ptsnowspos [I]. Y + 1, snowgathercr );
- Setpixel (HDC, Sn-> ptsnowspos [I]. x + 1, Sn-> ptsnowspos [I]. Y + 1, snowgathercr );
- Initsnow (HDC, Sn, I, cxscreen); // reinitialize snowflake
- }
- Else // contrast <50, do not accumulate, draw the snowflake frame, and then restore the original color of the point next time to produce the floating Effect
- Setpixel (HDC, Sn-> ptsnowspos [I]. X, Sn-> ptsnowspos [I]. Y, snowcr );
- }
- }
- }