win32实现类酷狗安装的进度条显示
1.前言
项目中需要一个类似酷狗安装的更新进度条显示,用win32实现了下,需要美工做三张图,代码比较简单
2.实现
1.用vs2010创建一个win32项目
2.将三张图片放在res文件夹下面,并将其导入到项目中
3.在stdafx.h中增加对gdi的支持
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//#pragma once#include "targetver.h"#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <locale.h>#include <olectl.h>
#include <assert.h>#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;// TODO: 在此处引用程序需要的其他头文件
4.对变量函数进行声明
void SetBackground(HWND m_hWnd); //实现图片叠加显示
DWORD dw_main = IDB_PNG1; //底图
DWORD dw_process = IDB_PNG2; //部分进度条
DWORD dw_count = 0; //当前显示的进度
DWORD dw_max = 20; //最大刻度值
DWORD dw_x = 20; //进度条在图片上的水平起始坐标
DWORD dw_y = 310; //进度条在图片上的垂直起始坐标
#define ID_PROCESS_TIMER 200 //进度条定时器
ULONG_PTR gdiplusToken = 0; //gdi全局变量
5._tWinMain中对gdi进行初始化
**int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: 在此放置代码。Gdiplus::GdiplusStartupInput gdiplusStartupInput;Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);MSG msg;HACCEL hAccelTable;// 初始化全局字符串LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_LIKEKUGOU, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// 执行应用程序初始化:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LIKEKUGOU));// 主消息循环:while (GetMessage(&msg, NULL, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}Gdiplus::GdiplusShutdown(gdiplusToken);return (int) msg.wParam;
}
6.对窗口属性进行修改
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{HWND hWnd;hInst = hInstance; // 将实例句柄存储在全局变量中//hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,// CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);hWnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, WS_POPUPWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, (HINSTANCE)::GetModuleHandle(NULL), 0);if (!hWnd){return FALSE;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE;
}
7.wndproc中对消息的处理主要是针对定时器的
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;switch (message){case WM_CREATE:{LONG styleValue = ::GetWindowLong(hWnd, GWL_STYLE);styleValue &= ~WS_CAPTION;styleValue &= ~WS_MAXIMIZEBOX; styleValue &= ~WS_MINIMIZEBOX; styleValue &= ~WS_THICKFRAME; styleValue &= ~WS_BORDER; styleValue &= ~WS_CAPTION;::SetWindowLong(hWnd, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);int scrWidth = GetSystemMetrics ( SM_CXSCREEN ); int scrHeight = GetSystemMetrics ( SM_CYSCREEN ); int nleft = (scrWidth - 580) / 2;int ntop = (scrHeight - 380) / 2;SetWindowPos(hWnd, HWND_TOPMOST, nleft, ntop, 580, 380, SWP_SHOWWINDOW);InvalidateRect(hWnd, NULL, TRUE);UpdateWindow(hWnd);//这里开一个定时器测试下效果 看下情况.SetTimer(hWnd, ID_PROCESS_TIMER, 500, NULL);break;}case WM_TIMER:{if (wParam == ID_PROCESS_TIMER){dw_count += (dw_count % 3+1);if (dw_count > dw_max){//dw_count = dw_max;dw_main = IDB_PNG3;KillTimer(hWnd, ID_PROCESS_TIMER);InvalidateRect(hWnd, NULL, TRUE);UpdateWindow(hWnd);Sleep(1000);SendMessage(hWnd, WM_CLOSE, 0, 0);break;}InvalidateRect(hWnd, NULL, TRUE);UpdateWindow(hWnd);}break;}case WM_COMMAND:wmId = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: 在此添加任意绘图代码...SetBackground(hWnd);EndPaint(hWnd, &ps);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}
8.对底图和进度条进行图片叠加显示
void SetBackground(HWND m_hWnd)
{HMODULE hInstance = ::GetModuleHandle(NULL);HRSRC hRsrc = ::FindResource(hInstance, MAKEINTRESOURCE(dw_main), _T("PNG")); DWORD dwSize = ::SizeofResource(hInstance, hRsrc);LPBYTE lpRsrc = (LPBYTE)::LoadResource(hInstance, hRsrc);HGLOBAL hMem = ::GlobalAlloc(GMEM_FIXED, dwSize);LPBYTE pMem = (LPBYTE)::GlobalLock(hMem);memcpy(pMem, lpRsrc, dwSize);IStream* pStream = NULL;::CreateStreamOnHGlobal( hMem, TRUE, &pStream );Gdiplus::Image* pImage = Gdiplus::Image::FromStream(pStream);if (pImage==NULL)assert(false && _T("error in FromStream."));HRSRC hRww = ::FindResource(hInstance, MAKEINTRESOURCE(dw_process), _T("PNG")); DWORD dwWwSize = ::SizeofResource(hInstance, hRww);LPBYTE lpRww = (LPBYTE)::LoadResource(hInstance, hRww);HGLOBAL hWwMem = ::GlobalAlloc(GMEM_FIXED, dwWwSize);LPBYTE pWwMem = (LPBYTE)::GlobalLock(hWwMem);memcpy(pWwMem, lpRww, dwWwSize);IStream* pWwStream = NULL;::CreateStreamOnHGlobal( hWwMem, TRUE, &pWwStream );Gdiplus::Image* pWwImage = Gdiplus::Image::FromStream(pWwStream);if (pWwImage==NULL)assert(false && _T("error in FromStream."));RECT windowRect;GetWindowRect(m_hWnd,&windowRect);SIZE sizeWindow;if (windowRect.left==windowRect.right){sizeWindow.cx=pImage->GetWidth();sizeWindow.cy=pImage->GetHeight();}else{sizeWindow.cx=windowRect.right-windowRect.left;sizeWindow.cy=windowRect.bottom-windowRect.top;}HDC hDC = ::GetDC(m_hWnd);HDC hdcMemory = CreateCompatibleDC(hDC);RECT rcWindow;GetWindowRect(m_hWnd,&rcWindow);BITMAPINFOHEADER stBmpInfoHeader = { 0 }; int nBytesPerLine = ((sizeWindow.cx * 32 + 31) & (~31)) >> 3;stBmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER); stBmpInfoHeader.biWidth = sizeWindow.cx; stBmpInfoHeader.biHeight = sizeWindow.cy; stBmpInfoHeader.biPlanes = 1; stBmpInfoHeader.biBitCount = 32; stBmpInfoHeader.biCompression = BI_RGB; stBmpInfoHeader.biClrUsed = 0; stBmpInfoHeader.biSizeImage = nBytesPerLine * sizeWindow.cy; PVOID pvBits = NULL; HBITMAP hbmpMem = ::CreateDIBSection(NULL, (PBITMAPINFO)&stBmpInfoHeader, DIB_RGB_COLORS, &pvBits, NULL, 0);assert(hbmpMem != NULL);HGDIOBJ hbmpOld = ::SelectObject( hdcMemory, hbmpMem);POINT ptWinPos = { rcWindow.left, rcWindow.top };Gdiplus::Graphics graph(hdcMemory);graph.SetSmoothingMode(Gdiplus::SmoothingModeNone);graph.DrawImage(pImage, 0, 0, sizeWindow.cx, sizeWindow.cy);//20,310,560,316int process_width = pWwImage->GetWidth();int process_height = pWwImage->GetHeight();if (dw_count <= dw_max){for (int nindex = 0; nindex < dw_count; ++nindex)graph.DrawImage(pWwImage, dw_x + nindex * process_width, dw_y, process_width, process_height);}HMODULE hFuncInst = LoadLibrary(_T("User32.DLL"));typedef BOOL (WINAPI *MYFUNC)(HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD); MYFUNC UpdateLayeredWindow;UpdateLayeredWindow = (MYFUNC)::GetProcAddress(hFuncInst, "UpdateLayeredWindow");POINT ptSrc = { 0, 0};BLENDFUNCTION blendFunc;blendFunc.BlendOp = 0;blendFunc.BlendFlags = 0;blendFunc.AlphaFormat = 1;blendFunc.SourceConstantAlpha = 255;if(!UpdateLayeredWindow(m_hWnd, hDC, &ptWinPos, &sizeWindow, hdcMemory, &ptSrc, 0, &blendFunc, ULW_ALPHA))assert(L"UpdateLayeredWindow failed.");SelectObject( hdcMemory, hbmpOld); DeleteObject(hbmpMem); DeleteDC(hdcMemory);ReleaseDC(m_hWnd, hDC);FreeLibrary(hFuncInst);if (pImage != NULL)delete pImage;pStream->Release();::GlobalUnlock(hMem);if (pWwImage != NULL)delete pWwImage;pWwStream->Release();::GlobalUnlock(hWwMem);
}
3.备注
1.http://download.csdn.net/detail/zhang_ruiqiang/9826938
2.代码比较简单,也比较随意,打破传统编码从控件继承模式,直接进行图片叠加更直观快捷,仅供参考
win32实现类酷狗安装的进度条显示相关推荐
- Mac开发之重写NSSlider(比酷狗的播放进度条好看)
Mac开发如果觉得系统自带Slider不好看,可以通过重绘让自己软件的Slider变得好看一点.与iOS开发不同的是,Mac开发控件重绘没有那么直接,但也不算复杂.下面说一下怎么通过继承NSSlide ...
- windows安装MongoDB进度条卡住,window安装mongo系统错误 2,系统错误5的解决办法(转载)...
windows安装MongoDB进度条卡住,window安装mongo系统错误 2,系统错误5的解决办法 转自:https://www.cnblogs.com/sufferingStriver/p/m ...
- python 酷炫效果_六种酷炫Python运行进度条效果的实现代码
六种酷炫Python运行进度条效果的实现代码,进度条,代码,六种,效果,酷炫 六种酷炫Python运行进度条效果的实现代码 易采站长站,站长之家为您整理了六种酷炫Python运行进度条效果的实现代码的 ...
- android第三方开源音频播放器,Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用...
Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用 Android平台原生的SeekBar设计简单,然而,比如现在流行的一些音乐播放器的播放进度控制条,如果直接使 ...
- 安装MSDE进度条不动
安装MSDE进度条走到某个地方不动 结束setupre.exe进程
- Android自定义View,Android炫酷的音乐频谱进度条,变化自如的音乐进度条
前段时间,公司项目有个UI需求,要做一个这么的东西 : 一个仿音乐频率谱线进度条(这是什么鬼?),那好,就先将这个控件命名为:音乐频谱进度条:) 废话不多说,先来看一下效果图: 附上在GitHub上的 ...
- 利用curl下载文件(进度条显示) 代码片段
在项目中需要用到程序更新的功能,同事介绍说是curl中的开发库很不错,于是下载这个包测试了一下,确实不错.准备正式用到项目中,以下一个例子用于从互联网上抓取一个文件下载到本地,并加上进度条显示,做得挺 ...
- jquery PHP大文件上传,Jquery和BigFileUpload实现大文件上传及进度条显示
实现方法:用到了高山来客 的bigfileupload组件,用高山来客的方法,弹出一个模式窗口,然后不停刷新获取进度,始终觉得体验感不好,于是想到用jquery来实现无刷新进度显示,因为提交页面后, ...
- python tkinter进度条_在python tkinter中Canvas实现进度条显示的方法
如下所示: from tkinter import * import time #更新进度条函数 def change_schedule(now_schedule,all_schedule): can ...
最新文章
- 明日召开!ICLR 2021中国预讲会明天开启,为期3天,5大专题,39场报告
- 40岁学python有前途吗-西安新城区学python人工智能少儿编程哪家机构好
- 为最快动脉线诊断 铁科院联合第四范式完成高铁智能化巡检应用
- 成为明星程序员的独特秘密|极客原创
- LeetCode—210. 课程表 II
- ASP.NET Core on K8S深入学习(6)Health Check
- mysql duplicate key与replace into对比
- Linux vi 编辑器常见命令的使用
- JS之模板技术(aui / artTemplate)
- 看懂这些代码,我哭着笑了
- mysql linux压缩包官网下载_mysql for linux 压缩包下载
- ZK UserGuide(一)理解/userguide/index.zul导航原理
- FeedingBottle 3.2另一个无线破解GUI
- pandas 学习task08文本数据
- [教程]安装系统解码器 - 指导教程
- 日记侠:你的第一桶金可能就是个关键词
- matlab生成word文档
- MySQL安装后默认密码的问题
- 如何利用RTK通过CORS进行测量?
- 库卡机器人C2更换系统操作步骤