屏保飘雪.cpp
资源名称:pmbh.rar [点击查看]
上传用户:jxndlwm19
上传日期:2022-02-28
资源大小:1177k
文件大小:6k
源码类别:
屏幕保护
开发平台:
Visual C++
- #include<windows.h>
- #include<time.h>
- #define SnowNum 800
- #define SnowCol 0xFEFFFE
- #define SnowColDown 0xFFDDDD
- #define ID_TIMER 1
- #define WM_CLICKBIT (WM_USER + 1)
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ;
- void Plate(HWND hwnd);
- long Abs(long num) ;
- int Random(int max) ;
- void InitP(int i) ;
- long GetContrast(int i) ;
- void DrawP(void) ;
- const int ScrnWidth = GetSystemMetrics(SM_CXSCREEN);
- const int ScrnHight = GetSystemMetrics(SM_CYSCREEN);
- const char szAppName[] = "WindowClass";
- HDC hDC;
- POINT pData[SnowNum];
- long pColor[SnowNum];
- int timecont;
- int Vx; //雪花总体水平飘行速度
- int Vy; //雪花总体垂直下落速度
- int PVx; //单个雪花实际水平飘行速度
- int PVy; //单个雪花实际垂直飘行速度
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- WNDCLASS wc;
- HWND hwnd;
- MSG Msg;
- wc.style = 0;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE("IDI_XUEHUA"));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = szAppName;
- if(!RegisterClass(&wc))
- {
- MessageBox(NULL,TEXT("窗体注册失败!"),TEXT("错误!"), MB_ICONEXCLAMATION | MB_OK);
- return 0;
- }
- hwnd = CreateWindow(szAppName, TEXT("飘雪"), WS_POPUP,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, SW_SHOWMAXIMIZED);
- UpdateWindow(hwnd);
- while(GetMessage(&Msg, NULL, 0, 0))
- {
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
- return Msg.wParam;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch(msg)
- {
- case WM_CREATE:
- {
- int j;
- hDC = GetDC(0);
- srand(time(NULL));
- //设置风向
- Vx = Random(4) - 2; //(-1,1)
- Vy = Random(2) + 2; //(2, 3)
- for(j = 0; j<SnowNum; j++)
- {
- pData[j].x = Random(ScrnWidth);
- pData[j].y = Random(ScrnHight);
- pColor[j] = GetPixel(hDC, pData[j].x, pData[j].y);
- }
- SetTimer(hwnd, ID_TIMER, 40, NULL); //每隔1/25秒
- }
- break;
- case WM_TIMER: //时钟
- {
- if(timecont>200) //累计超过一定时间改变风向
- {
- Vx = Random(4) - 2;
- Vy = Random(2) + 2;
- timecont = 0;
- }
- else
- {
- timecont += 1;
- }
- DrawP();
- }
- break;
- case WM_LBUTTONDOWN:
- {
- ReleaseDC(0, hDC);
- KillTimer(hwnd, ID_TIMER);
- PostQuitMessage(0);
- }
- break;
- case WM_KEYDOWN://处理键盘消息
- {
- switch(wParam)
- {
- case VK_ESCAPE: //处理Esc键
- {
- ReleaseDC(0, hDC);
- KillTimer(hwnd, ID_TIMER);
- PostQuitMessage(0);
- }
- break;
- }
- }
- break;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- //重画所有雪花位置一次
- void DrawP(void)
- {
- int i;
- for(i=0; i<SnowNum; i++)
- {
- if(pColor[i]!=SnowCol && pColor[i]!=-1)
- {
- SetPixel(hDC, pData[i].x, pData[i].y, pColor[i]);
- }
- PVx = Vx * (i%3);
- PVy = Vy * (i%3 + 1);
- pData[i].x = pData[i].x + PVx;
- pData[i].y = pData[i].y + PVy;
- pColor[i] = GetPixel(hDC, pData[i].x, pData[i].y); //取得新位置原始颜色值,用于下一步雪花飘过时恢复此处颜色
- if(pColor[i] == -1) //如果获取颜色失败,表明雪花已飘出屏幕,重新初始化
- {
- InitP(i);
- }
- else if(pColor[i]!=SnowCol) //若对比度较小(即不能堆积),就画出雪花
- {
- if (Random(16) > 5 || GetContrast(i) < 50)
- {
- SetPixel(hDC, pData[i].x, pData[i].y, SnowCol);
- }
- }
- else //找到明显的边界,在周围画出堆积的雪,并初始化以便画新的雪花
- {
- SetPixel(hDC, pData[i].x, pData[i].y - 1, SnowColDown);
- SetPixel(hDC, pData[i].x, pData[i].y + 1, SnowColDown);
- SetPixel(hDC, pData[i].x - 1, pData[i].y, SnowColDown);
- SetPixel(hDC, pData[i].x + 1, pData[i].y, SnowColDown);
- InitP(i);
- }
- }
- }
- //初始化雪花位置
- void InitP(int i)
- {
- pData[i].x = Random(ScrnWidth);
- pData[i].y = Random(2);
- pColor[i] = GetPixel(hDC, pData[i].x, pData[i].y); //取得屏幕原来的颜色值
- }
- //取得某一点与周围点的对比度,确定是否在此位置堆积雪花
- long GetContrast(int i)
- {
- long ColorCmp;
- long tempR, tempG, tempB;
- int Slope;
- //计算雪花飘落方向
- if(PVy!=0)
- {
- Slope = PVx / PVy;
- }
- else
- {
- Slope = 2;
- }
- //根据雪花飘落方向决定取哪一点作对比点
- if(Slope == 0)//若PVx/PVy在-1到1之间,即0,就取正下面的象素点作对比点
- {
- ColorCmp = GetPixel(hDC, pData[i].x, pData[i].y + 1);
- }
- else if(Slope > 1)//取右下方的点作对比点
- {
- ColorCmp = GetPixel(hDC, pData[i].x + 1, pData[i].y + 1);
- }
- else //取左下方点作对比点
- {
- ColorCmp = GetPixel(hDC, pData[i].x - 1, pData[i].y + 1);
- }
- //确定当前位置没有与另一个雪花重叠,否则返回0,用于防止由于不同雪花重叠造成雪花乱堆
- if(ColorCmp == SnowCol)
- {
- return 0;
- }
- //分别获取ColorCmp与对比点的蓝、绿、红部分的差值
- tempR = Abs((ColorCmp)&0xFF - (pColor[i])&0xFF);
- tempG = Abs((ColorCmp>>8)&0xFF - (pColor[i]>>8)&0xFF);
- tempB = Abs((ColorCmp>>16)&0xFF - (pColor[i]>>16)&0xFF);
- return ((tempR + tempG + tempB) / 3); //返回对比度值
- }
- long Abs(long num)
- {
- if(num>=0)
- {
- return(num);
- }
- else
- {
- return(-num);
- }
- }
- int Random(int max)
- {
- return rand()%max;
- }