700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 使用GDI绘制一个类似进度条的控件(1)

使用GDI绘制一个类似进度条的控件(1)

时间:2023-08-30 06:09:23

相关推荐

使用GDI绘制一个类似进度条的控件(1)

最近我像学习下图形的绘制,自己是学C/C++的,所以我就把目光放在了GDI上面。基本的win32编程和基本的GDI绘制我已经了解,接下来就进行实践环节。

最简单的GDI绘制图形那就是矩形了,所以我用基本的矩形来绘制进度条,今天写的是最基本的,之后我会把相关操作写成类,代码如下(代码里面有很详细的注释,所以我就不过多介绍了)

#include <windows.h>#include <atlstr.h> //因为wsprintf不能进行浮点型转换,所以加上这个用CString//自绘一个进度条//定义一个定时器宏#define ID_TIMER 1LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int cxClient, cyClient; //客户区的高和宽RECT rect;int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd){static TCHAR szAppName[] = TEXT("ProgressBar");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.style = CS_HREDRAW | CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hInstance;wndclass.hIcon = LoadIcon(NULL, IDI_INFORMATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = szAppName;RegisterClass(&wndclass);hwnd = CreateWindow(szAppName, L"自绘一个进度条",WS_OVERLAPPEDWINDOW,100, 200, 800, 600, NULL, NULL, hInstance, NULL);ShowWindow(hwnd, nShowCmd);UpdateWindow(hwnd);while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}void RenderProgressBar(HWND hwnd) //重绘进度条{RECT RenderRect;RenderRect.left = rect.left;RenderRect.top = rect.top;RenderRect.right = cxClient;RenderRect.bottom = rect.bottom;InvalidateRect(hwnd, &RenderRect, TRUE); //只是让进度条和显示文字的矩形无效就行了}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hdcClient;PAINTSTRUCT ps;//画笔画刷HBRUSH hBrush;HPEN hPen,hOldPen;TCHAR temp[40];static float right;float tempD;CString str;int x;switch (message){case WM_TIMER: //定时器消息RenderProgressBar(hwnd);return 0;case WM_CREATE:SetTimer(hwnd, ID_TIMER, 100, NULL); //每隔10秒触发return 0;case WM_SIZE:cxClient = LOWORD(lParam); //获取客户区的大小cyClient = HIWORD(lParam);rect.left = cxClient / 2 - 300;rect.top = cyClient / 2;rect.right = cxClient / 2 - 300;rect.bottom = cyClient / 2 + 50;right = cxClient / 2 + 300;return 0;case WM_PAINT:hPen = CreatePen(PS_NULL, 0, 0); //创建一个新画笔(这个画笔在绘制矩形的时候是没有边框的)hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); //取得黑色的画刷hdcClient = BeginPaint(hwnd, &ps);hOldPen = (HPEN)SelectObject(hdcClient, hPen); //取得原来的画笔并将自己创建的画笔放入hdc中//创建一个长600,宽50的矩形,位置在客户区中央Rectangle(hdcClient, cxClient / 2-300, cyClient / 2, cxClient / 2 + 300, cyClient / 2 + 50);if (rect.right <= right) //如果还没到头{FillRect(hdcClient, &rect, hBrush);tempD = (float)(rect.right - rect.left) / 600.0;str.Format(TEXT("进度:%.2f%%"), tempD*100.0);TextOut(hdcClient, right, rect.top + 25, temp, wsprintf(temp, L"%s", str.GetBuffer(str.GetLength())));rect.right++;}if (rect.right > right)//已经100%了{RECT tempRect;tempRect.left = rect.left;tempRect.top = rect.top;tempRect.right = rect.right-1;tempRect.bottom = rect.bottom;FillRect(hdcClient, &tempRect, hBrush);TextOut(hdcClient, right, rect.top + 25, temp, wsprintf(temp, L"进度:%d.00%%", 100));}DeleteObject(hPen);SelectObject(hdcClient, hOldPen);//将原来的画笔还回去DeleteObject(hBrush);EndPaint(hwnd, &ps);return 0;case WM_DESTROY:KillTimer(hwnd, ID_TIMER);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);}

运行如下:

基本的进度条就这样了,之后我会将它进行改进,改成类的样子,这样的话可以自己设置宽高和进度条的值。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。