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实现类酷狗安装的进度条显示相关推荐

  1. Mac开发之重写NSSlider(比酷狗的播放进度条好看)

    Mac开发如果觉得系统自带Slider不好看,可以通过重绘让自己软件的Slider变得好看一点.与iOS开发不同的是,Mac开发控件重绘没有那么直接,但也不算复杂.下面说一下怎么通过继承NSSlide ...

  2. windows安装MongoDB进度条卡住,window安装mongo系统错误 2,系统错误5的解决办法(转载)...

    windows安装MongoDB进度条卡住,window安装mongo系统错误 2,系统错误5的解决办法 转自:https://www.cnblogs.com/sufferingStriver/p/m ...

  3. python 酷炫效果_六种酷炫Python运行进度条效果的实现代码

    六种酷炫Python运行进度条效果的实现代码,进度条,代码,六种,效果,酷炫 六种酷炫Python运行进度条效果的实现代码 易采站长站,站长之家为您整理了六种酷炫Python运行进度条效果的实现代码的 ...

  4. android第三方开源音频播放器,Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用...

     Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用 Android平台原生的SeekBar设计简单,然而,比如现在流行的一些音乐播放器的播放进度控制条,如果直接使 ...

  5. 安装MSDE进度条不动

    安装MSDE进度条走到某个地方不动 结束setupre.exe进程

  6. Android自定义View,Android炫酷的音乐频谱进度条,变化自如的音乐进度条

    前段时间,公司项目有个UI需求,要做一个这么的东西 : 一个仿音乐频率谱线进度条(这是什么鬼?),那好,就先将这个控件命名为:音乐频谱进度条:) 废话不多说,先来看一下效果图: 附上在GitHub上的 ...

  7. 利用curl下载文件(进度条显示) 代码片段

    在项目中需要用到程序更新的功能,同事介绍说是curl中的开发库很不错,于是下载这个包测试了一下,确实不错.准备正式用到项目中,以下一个例子用于从互联网上抓取一个文件下载到本地,并加上进度条显示,做得挺 ...

  8. jquery PHP大文件上传,Jquery和BigFileUpload实现大文件上传及进度条显示

    实现方法:用到了高山来客 的bigfileupload组件,用高山来客的方法,弹出一个模式窗口,然后不停刷新获取进度,始终觉得体验感不好,于是想到用jquery来实现无刷新进度显示,因为提交页面后, ...

  9. python tkinter进度条_在python tkinter中Canvas实现进度条显示的方法

    如下所示: from tkinter import * import time #更新进度条函数 def change_schedule(now_schedule,all_schedule): can ...

最新文章

  1. 明日召开!ICLR 2021中国预讲会明天开启,为期3天,5大专题,39场报告
  2. 40岁学python有前途吗-西安新城区学python人工智能少儿编程哪家机构好
  3. 为最快动脉线诊断 铁科院联合第四范式完成高铁智能化巡检应用
  4. 成为明星程序员的独特秘密|极客原创
  5. LeetCode—210. 课程表 II
  6. ASP.NET Core on K8S深入学习(6)Health Check
  7. mysql duplicate key与replace into对比
  8. Linux vi 编辑器常见命令的使用
  9. JS之模板技术(aui / artTemplate)
  10. 看懂这些代码,我哭着笑了
  11. mysql linux压缩包官网下载_mysql for linux 压缩包下载
  12. ZK UserGuide(一)理解/userguide/index.zul导航原理
  13. FeedingBottle 3.2另一个无线破解GUI
  14. pandas 学习task08文本数据
  15. [教程]安装系统解码器 - 指导教程
  16. 日记侠:你的第一桶金可能就是个关键词
  17. matlab生成word文档
  18. MySQL安装后默认密码的问题
  19. 如何利用RTK通过CORS进行测量?
  20. 库卡机器人C2更换系统操作步骤

热门文章

  1. composer安装laravel步骤
  2. 防止异地登录的解决思路
  3. python基础——类(面向对象的特征)
  4. Android Dialog 普通对话框 单选对话框 多选对话框
  5. 选择大于努力,创业项目!总有一个适合你,想赚钱的别犹豫啦!
  6. 利用注册表来去除桌面底纹
  7. Day08 列表 集合字典的相关函数
  8. 分享88个ASP主机域名源码,总有一款适合您
  9. Tech Ed游记(一)
  10. Mac 虚拟打印机PDFWriter on Sierra