类似“99朵玫瑰”的程序开发
来源:互联网 发布:swisse护肝片 知乎 编辑:程序博客网 时间:2024/04/27 20:33
近几天,逛网站时,发现有个人想要类似“99朵玫瑰花”的程序,要求是程序运行时,显示指定的图片。闲来无事,用C写了以下的程序。
1. 设置一个WIN32窗口属性为全屏透明的,在该全屏透明的窗口上进行图片文件的显示。该窗口负责接收键盘按键和鼠标按键消息。
hwnd = CreateWindow(szAppName, NULL, WS_EX_TRANSPARENT,0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CXSCREEN),NULL, NULL, hInstance, NULL);
WS_EX_TRANSPARENT
这个属性能够使窗口透明,设置了这个属性的窗口的背景使可以被看到的,透明窗口对于鼠标和键盘的消息事件并不是透明的。
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)分别用于获取屏幕的x尺寸和y尺寸,即屏幕的宽度和高度.
(关于Windows窗口层次关系可以参考:http://www.360doc.com/content/10/0415/23/155970_23269174.shtml)
2. 使图片显示在最顶层,首先考虑的是如何显示一张图片
CImage cImg; cImg.Load(“图片名称”)// 加载图片文件 HBITMAP hBmp = HBITMAP(cImg); // 获得bitmap句柄 HDC hDesktopDC = GetDC(NULL); // 获取桌面DC句柄 HDC hMemDC = CreateCompatibleDC(hDesktopDC); // 创建一个适合hDesktopDC的DC句柄 SelectObject(hMemDC, hBmp); // 将hBmp选入该DC SetStretchBltMode(hDesktopDC, COLORONCOLOR); // 清除被消除的像素,因为图片缩放时,可能会失真 // 由于图片的大小有可能很大,而本程序的目的是显示多张图片,并在桌面上随机位置显示,故做了以下处理 // 缩放,并随机位置显示, StretchBlt(hDesktopDC, rand()%(GetSystemMetrics(SM_CXSCREEN)-180), rand()%(GetSystemMetrics(SM_CYSCREEN)-180*cImg.GetHeight()/cImg.GetWidth()), 180, 180*cImg.GetHeight()/cImg.GetWidth(), hMemDC, 0, 0, cImg.GetWidth(), cImg.GetHeight(), SRCCOPY); // rand()%(GetSystemMetrics(SM_CXSCREEN)-180), rand()%(GetSystemMetrics(SM_CYSCREEN)-180*cImg.GetHeight()/cImg.GetWidth()), 是图片显示的位置 // 180,180*cImg.GetHeight()/cImg.GetWidth()是显示的图片最终的大小 // 之后释放相关的设备上下文句柄以及位图资源 ReleaseDC(NULL, hMemDC); ReleaseDC(NULL, hDesktopDC); DeleteObject(hBmp);
3. 需要显示多张图片,将图片都放置到一个文件夹下,接下来要考虑的是如何获取这个文件夹下文件(也就是图片)的名字
这里要用到FindFirstFile和FindNextFile等函数用于获得文件夹下文件的名称,并将文件数量进行计数,然后将图片进行逐一显示。
需要设置字符集,对于VS2008可以进行如下设置:解决方案右击-->属性-->配置属性-->常规-->字符集-->未设置。
获取一个目录下文件名称参考:http://wenwen.soso.com/z/q178975556.htm。
4. 有时候会遇到显示了几张图片后,剩余的图片不显示的问题。
这是由于图片文件夹中存在Thumbs.db文件,是一个用于MicrosoftWindows XP或mac os x缓存Windows Explorer的缩略图的文件。Thumbs.db保存在每一个包含图片或照片的目录中。在显示图片之前进行判断,若是该文件就不显示,否则就进行绘制。
5. 图片显示过程中,似乎不允许打断,即点击键盘或鼠标,图片不会终止显示。
为此,将图片显示函数作为一个子线程。在消息循环中的WM_CREATE消息下,创建该线程
_beginthread (ShowPicToDesktop, 0, NULL) ;其中ShowPicToDesktop就是进行图片显示的函数。这样,就解决了上述问题。
最后附上程序代码:
#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <atlimage.h>#include <mmsystem.h>#define MAX_RESULT 256char** EnumFiles(const char *directory, int *count){WIN32_FIND_DATA FindFileData; // 用于保存查找到的文件的信息HANDLE hFind;char result[MAX_RESULT][MAX_PATH]; // 临时保存查找到的文件的文件名char **returnresult; // 用于返回查找的文件文件名char pattern[MAX_PATH]; // 查找文件的路径int i = 0, j;// 开始查找strcpy(pattern, directory);strcat(pattern, "\\*.*");CString csPattern(pattern);hFind = FindFirstFile(csPattern, &FindFileData);if (hFind == INVALID_HANDLE_VALUE) // 若未查找成功{*count = 0;return NULL;} else {do{strcpy(result[i], directory);strcat(result[i], "\\");strcat(result[i++], FindFileData.cFileName);}while (FindNextFile(hFind, &FindFileData) != 0);}// 查找结束FindClose(hFind);// 复制到结果中returnresult = (char **)calloc(i, sizeof(char *));for (j = 0; j < i; j++){returnresult[j] = (char *)calloc(MAX_PATH, sizeof(char));strcpy(returnresult[j], result[j]);}*count = i;return returnresult;}void ShowPicToDesktop(PVOID pvoid) { int count, i;char ** result;result = EnumFiles("pic", &count);for (i = 2; i < count; i++){CImage cImg;/*Thumbs.db文件是一个数据库,里面保存了这个目录下所有图像文件的缩略图(格式为jpeg)。当以缩略图查看时(展示一幅图片或电影胶片) ,将会生成一个Thumbs.db文件。而这种文件本程序无法绘制,故增加了下面的第一个判断语句*/if(strcmp(result[i], "pic\\Thumbs.db")==0)continue;if(cImg.Load((LPCTSTR)(CString(result[i]))))// 加载图片文件return ; HBITMAP hBmp = HBITMAP(cImg); // 获得bitmap句柄HDC hDesktopDC = GetDC(NULL); // 获取桌面设备上下文句柄HDC hMemDC = CreateCompatibleDC(hDesktopDC); SelectObject(hMemDC, hBmp); SetStretchBltMode(hDesktopDC, COLORONCOLOR); // 清除被消除的像素// 缩放,并随机位置显示StretchBlt(hDesktopDC, rand()%(GetSystemMetrics(SM_CXSCREEN)-180), rand()%(GetSystemMetrics(SM_CYSCREEN)-180*cImg.GetHeight()/cImg.GetWidth()), 180, 180*cImg.GetHeight()/cImg.GetWidth(), hMemDC, 0, 0, cImg.GetWidth(), cImg.GetHeight(), SRCCOPY);ReleaseDC(NULL, hMemDC); ReleaseDC(NULL, hDesktopDC); DeleteObject(hBmp); ::Sleep(700);}}LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { MSG msg;static TCHAR szAppName[] = TEXT("Love");HWND hwnd; WNDCLASS wndclass;wndclass.style = CS_HREDRAW|CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hInstance;wndclass.hIcon = NULL;wndclass.hCursor = NULL;wndclass.hbrBackground = NULL;wndclass.lpszMenuName = NULL;wndclass.lpszClassName = szAppName;if(!RegisterClass(&wndclass)){MessageBox(NULL, TEXT("This program is not created"), szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindow(szAppName, NULL, WS_EX_TRANSPARENT, 0, 0,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 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 hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch(message){case WM_CREATE:PlaySound(TEXT("music//MLH.WAV"), NULL, SND_ASYNC|SND_LOOP); // 异步|循环 播放音频文件_beginthread (ShowPicToDesktop, 0, NULL) ;return 0;case WM_LBUTTONDOWN:case WM_RBUTTONDOWN:case WM_MBUTTONDOWN:case WM_KEYDOWN:case WM_DESTROY:PostQuitMessage(0);return 0; }return DefWindowProc(hwnd, message, wParam, lParam);}
需要建立文件夹pic,在此文件夹中放置要显示的图片;文件夹music中放置要播放的wav格式音频文件。并且该音频文件的名称必须是MLH.wav,当然读者可以在代码中进行更改。
欢迎各位斧正。
- 类似“99朵玫瑰”的程序开发
- 九百九十九朵玫瑰的由来
- 一朵玫瑰
- 这朵玫瑰叫Jenny
- 【javascript】用javascript实现的一朵从含苞到绽放的玫瑰
- WinAPI给女友画朵玫瑰
- [英语阅读]伊朗:吝啬老公被罚买12万朵玫瑰
- 开发那朵花
- 用c#开发一个类似AutoCAD功能的程序
- 程序花花生(1)——熬了10年的一朵程序花
- 玫瑰及玫瑰精油的效用
- 玫瑰下的阿司匹林
- 带刺的玫瑰
- 蓝色玫瑰的传说
- 玫瑰的起源
- 玫瑰精油的作用
- 玫瑰的寓意
- 独一无二的玫瑰
- Android 如何在自定义界面上启用输入法 (How to enable inputmethod for the custom UI)
- ATMEL mXT224电容触摸屏调试笔记
- c/c++语言学习建议
- 通达OA 开发一个按部门查询电话号码的插件
- 数据库在有外键的时候删除
- 类似“99朵玫瑰”的程序开发
- c++ string的简单实现
- bfs+bfs/dfs hdu 1254 推箱子1
- java获取的本机时间比当前时间少8小时的解决方案
- 习题6.6
- Java中逻辑与,逻辑或,按位与,按位或的区分
- windows下守护进程实现
- MYSQL常用命令
- java文件流(File)