win32实现类酷狗安装的进度条显示
来源:互联网 发布:image lab for mac 编辑:程序博客网 时间:2024/06/07 09:39
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,316 int 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.代码比较简单,也比较随意,打破传统编码从控件继承模式,直接进行图片叠加更直观快捷,仅供参考
0 0
- win32实现类酷狗安装的进度条显示
- win32 进度条实现
- 加载窗体显示一个进度条的实现
- EVC实现带文字显示的进度条
- 通过BackgroundWorker实现进度条的显示,并将进度显示在进度条上
- NeatUpload的安装使用,可传大文件,显示进度条
- 安装tqdm-python的显示程序运行进度条库
- C语言实现的百分比加进度条的显示程序
- 用WebWork实现进度条显示
- 不用Progress实现进度条显示
- ASP.NET实现投票结果的图片进度条显示代码
- ASP.NET实现投票结果的图片进度条显示
- ASP.NET实现投票结果的图片进度条显示
- 利用WinInet和多线程实现实时显示的下载进度条
- ASP.NET实现投票结果的图片进度条显示代码
- ASP.NET实现投票结果的图片进度条显示
- ASP.NET实现投票结果的图片进度条显示
- 基于AJAX的文件上传显示进度条实现
- 软件开发的心得体会(二)
- poj 2456(二分+贪心)(最大化最小值)
- C/C++ 文件操作总结
- 数值分析四次实验
- Tensorflow LSTM分类问题
- win32实现类酷狗安装的进度条显示
- JUnit使用
- 二叉树的中序,前序,后序非递归遍历
- SQLServer(MSSQL)学习笔记
- Java连接MYSQL 数据库的连接步骤
- Firebase系列之---Realtime Database(实时数据库)的使用
- 文章标题
- OS系统下 使用MAMP站点配置详解
- Socket历由来史