屏保飘雪.cpp
上传用户:jxndlwm19
上传日期:2022-02-28
资源大小:1177k
文件大小:6k
源码类别:

屏幕保护

开发平台:

Visual C++

  1. #include<windows.h> 
  2. #include<time.h>
  3. #define SnowNum  800
  4. #define SnowCol  0xFEFFFE
  5. #define SnowColDown 0xFFDDDD
  6. #define ID_TIMER 1
  7. #define WM_CLICKBIT (WM_USER + 1)
  8. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ;
  9. void Plate(HWND hwnd);
  10. long Abs(long num) ;
  11. int  Random(int max) ;
  12. void InitP(int i) ;
  13. long GetContrast(int i) ;
  14. void DrawP(void) ;
  15. const int  ScrnWidth = GetSystemMetrics(SM_CXSCREEN);
  16. const int  ScrnHight = GetSystemMetrics(SM_CYSCREEN);
  17. const char szAppName[] = "WindowClass"; 
  18. HDC   hDC; 
  19. POINT pData[SnowNum]; 
  20. long  pColor[SnowNum]; 
  21. int   timecont;
  22. int   Vx; //雪花总体水平飘行速度
  23. int   Vy; //雪花总体垂直下落速度
  24. int   PVx; //单个雪花实际水平飘行速度
  25. int   PVy; //单个雪花实际垂直飘行速度
  26. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
  27. {     
  28. WNDCLASS wc; 
  29.     HWND hwnd; 
  30.     MSG  Msg; 
  31.     wc.style         = 0; 
  32.     wc.lpfnWndProc   = WndProc; 
  33.     wc.cbClsExtra    = 0; 
  34.     wc.cbWndExtra    = 0; 
  35.     wc.hInstance     = hInstance; 
  36.     wc.hIcon         = LoadIcon(NULL, MAKEINTRESOURCE("IDI_XUEHUA")); 
  37.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
  38.     wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); 
  39.     wc.lpszMenuName  = NULL; 
  40.     wc.lpszClassName = szAppName; 
  41.     if(!RegisterClass(&wc)) 
  42.         MessageBox(NULL,TEXT("窗体注册失败!"),TEXT("错误!"), MB_ICONEXCLAMATION | MB_OK); 
  43.         return 0; 
  44.     hwnd = CreateWindow(szAppName, TEXT("飘雪"), WS_POPUP, 
  45.                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,
  46.                   NULL, NULL, hInstance, NULL); 
  47.     ShowWindow(hwnd, SW_SHOWMAXIMIZED); 
  48.     UpdateWindow(hwnd); 
  49.     while(GetMessage(&Msg, NULL, 0, 0)) 
  50.         TranslateMessage(&Msg); 
  51.         DispatchMessage(&Msg); 
  52. return Msg.wParam; 
  53. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
  54. switch(msg) 
  55. {
  56. case WM_CREATE: 
  57. int j; 
  58. hDC = GetDC(0);
  59. srand(time(NULL)); 
  60. //设置风向
  61. Vx = Random(4) - 2; //(-1,1)
  62. Vy = Random(2) + 2; //(2, 3)
  63. for(j = 0; j<SnowNum; j++) 
  64. pData[j].x = Random(ScrnWidth); 
  65. pData[j].y = Random(ScrnHight); 
  66. pColor[j]  = GetPixel(hDC, pData[j].x, pData[j].y); 
  67. SetTimer(hwnd, ID_TIMER, 40, NULL); //每隔1/25秒
  68.         break;
  69. case WM_TIMER: //时钟 
  70. if(timecont>200) //累计超过一定时间改变风向
  71. Vx = Random(4) - 2; 
  72. Vy = Random(2) + 2; 
  73. timecont = 0; 
  74. }
  75. else
  76. {
  77. timecont += 1; 
  78. }
  79.            DrawP(); 
  80.         break; 
  81.   
  82.       case WM_LBUTTONDOWN:
  83.   {
  84.   ReleaseDC(0, hDC); 
  85.   KillTimer(hwnd, ID_TIMER);
  86.   PostQuitMessage(0);
  87.   }
  88.   break;
  89.   case WM_KEYDOWN://处理键盘消息
  90.   {
  91.   switch(wParam)
  92.   {
  93.   case VK_ESCAPE: //处理Esc键
  94.   {
  95.   ReleaseDC(0, hDC); 
  96.   KillTimer(hwnd, ID_TIMER);
  97.   PostQuitMessage(0);
  98.   }
  99.   break;
  100.   }
  101.   }
  102. break;  
  103.     return DefWindowProc(hwnd, msg, wParam, lParam); 
  104. //重画所有雪花位置一次 
  105. void DrawP(void) 
  106. int i; 
  107.     for(i=0; i<SnowNum; i++) 
  108.         if(pColor[i]!=SnowCol && pColor[i]!=-1)
  109. {
  110. SetPixel(hDC, pData[i].x, pData[i].y, pColor[i]); 
  111. }
  112.         PVx = Vx * (i%3); 
  113.         PVy = Vy * (i%3 + 1); 
  114.         pData[i].x = pData[i].x + PVx; 
  115.         pData[i].y = pData[i].y + PVy; 
  116.         pColor[i]  = GetPixel(hDC, pData[i].x, pData[i].y); //取得新位置原始颜色值,用于下一步雪花飘过时恢复此处颜色
  117.         if(pColor[i] == -1) //如果获取颜色失败,表明雪花已飘出屏幕,重新初始化 
  118. {
  119. InitP(i); 
  120.         else if(pColor[i]!=SnowCol) //若对比度较小(即不能堆积),就画出雪花
  121.         {
  122. if (Random(16) > 5 || GetContrast(i) < 50)
  123. {
  124. SetPixel(hDC, pData[i].x, pData[i].y, SnowCol); 
  125. }
  126. }
  127.         else //找到明显的边界,在周围画出堆积的雪,并初始化以便画新的雪花
  128.             SetPixel(hDC, pData[i].x, pData[i].y - 1, SnowColDown); 
  129. SetPixel(hDC, pData[i].x, pData[i].y + 1, SnowColDown);
  130.             SetPixel(hDC, pData[i].x - 1, pData[i].y, SnowColDown); 
  131.             SetPixel(hDC, pData[i].x + 1, pData[i].y, SnowColDown); 
  132.             InitP(i); 
  133. }
  134. //初始化雪花位置
  135. void InitP(int i) 
  136. pData[i].x = Random(ScrnWidth); 
  137. pData[i].y = Random(2); 
  138. pColor[i]  = GetPixel(hDC, pData[i].x, pData[i].y); //取得屏幕原来的颜色值 
  139. //取得某一点与周围点的对比度,确定是否在此位置堆积雪花
  140. long GetContrast(int i) 
  141. long  ColorCmp; 
  142.     long  tempR, tempG, tempB; 
  143.     int   Slope; 
  144. //计算雪花飘落方向 
  145.     if(PVy!=0)
  146. {
  147. Slope = PVx / PVy; 
  148. }
  149.     else
  150. {
  151. Slope = 2; 
  152. }
  153. //根据雪花飘落方向决定取哪一点作对比点
  154.     if(Slope == 0)//若PVx/PVy在-1到1之间,即0,就取正下面的象素点作对比点 
  155. {
  156. ColorCmp = GetPixel(hDC, pData[i].x, pData[i].y + 1); 
  157. }
  158.     else if(Slope > 1)//取右下方的点作对比点
  159. {
  160. ColorCmp = GetPixel(hDC, pData[i].x + 1, pData[i].y + 1); 
  161. }
  162.     else //取左下方点作对比点
  163. {
  164. ColorCmp = GetPixel(hDC, pData[i].x - 1, pData[i].y + 1); 
  165. }
  166. //确定当前位置没有与另一个雪花重叠,否则返回0,用于防止由于不同雪花重叠造成雪花乱堆 
  167.     if(ColorCmp == SnowCol)
  168. {
  169. return 0; 
  170. }
  171. //分别获取ColorCmp与对比点的蓝、绿、红部分的差值
  172. tempR = Abs((ColorCmp)&0xFF - (pColor[i])&0xFF);
  173.     tempG = Abs((ColorCmp>>8)&0xFF - (pColor[i]>>8)&0xFF);  
  174. tempB = Abs((ColorCmp>>16)&0xFF - (pColor[i]>>16)&0xFF); 
  175.     return ((tempR + tempG + tempB) / 3); //返回对比度值 
  176. long Abs(long num) 
  177. if(num>=0)
  178. {
  179. return(num); 
  180. }
  181.     else 
  182. {
  183. return(-num); 
  184. }
  185. int Random(int max) 
  186. return rand()%max;