当前位置:C++技术网 > 精选软件 > win32使用计时器实现动态的等待提示字符效果大全(组图)

win32使用计时器实现动态的等待提示字符效果大全(组图)

更新时间:2015-12-26 17:49:54浏览次数:1+次

    各种动态提示的效果,只是做一个简单的展示而已。涵盖了常用的提示。你也可以自己创造属于你的一个个性提示哦。我们首先来看看一系列效果:

1.最常见的点号提示等待的动态效果图:

最常见的点号提示等待的动态效果图


2.横杠原地旋转的等待动态效果图:

横杠原地旋转的等待动态效果图1

横杠原地旋转的等待动态效果图2


3.数字序号的不断提示循环的步骤动态效果图:
数字序号的不断提示循环的步骤动态效果图
4.一个半十字的旋转提示的动态效果图:
一个半十字的旋转提示的动态效果图
5.佛教的卍和卐符号的循环提示动态效果图:
佛教的卍和卐符号的循环提示动态效果图

    动态等待的效果图,是用于提高用户体验而产生的。如果一个提示始终不变,会让人感觉程序是不是卡死了。毕竟windows中这种卡死是很常见的,用动态循环提示用户,表示“我还活着!千万不要以为我死了哦!”。这样用户就心里有底,即使等待的时间长点也是可以的,因为用户知道,程序正在运行。
    现在各种等待提示层出不穷,基本都是用图片的循环播放形式实现的。那么这样就需要图片显示和循环播放的支持。如果只是一个可选的提示,而你的环境下实现图片循环播放提示比较难的话,更多偏向于实用字符的循环输出实现动态等待提示效果。而且在DOS环境下,更别想用图片输出提示了。
    即使是现在软件开发中,图片的动态提示很常见,然而字符的循环输出提示更简单更方便实现,效果也挺好,占用的资源也少。
    我们这里是在Win32环境下实现的动态循环提示,所以是用TextOut来输出文字,用wsprintf来格式化文字到字符数组中,通过取模来实现循环输出不同的字符来实现动态的效果。
    我们在WM_PAINT中来模拟实现。也就是说,我们要保证不停的触发WM_PAINT消息。当然我们会想到用计时器来不停的触发,这是很合适的。在计时器消息WM_TIMER中,我们只需要调用如下代码即可:
InvalidateRect(hwnd,NULL,TRUE);//让客户区重绘,并且要先擦除背景
    擦除背景就是因为之前的输出不能还在本次输出中出现,因为那样留下的痕迹,会干扰本次输出的效果。点的输出方式是不断的增加点数,然而之前如果都输出了所有的点,然后后面的循环就始终看不到动态的增加点的效果。因为背景没有被擦除,你看到的点是之前已经输出来的。所以需要重绘将之前输出的东西都擦掉。
    对于InvalidateRect的背景擦除的详细讲述,请阅读《InvalidateRect无效矩形的图文分析和在字符串中移动光标》和《InvalidateRect是否删除背景效果分析以及实现下划线删除线》。
    那么我们在WM_CREATE消息就开始启动计时器,这样计时器可以不断的产生WM_PAINT消息,输出的次数不断的累加,然后通过取模不断的循环,进而就选择了输出字符数组的不同的字符串,从而达到动态输出的效果。
    你要实现自己的动态变化的效果,可以自己改变字符串数组的字符串,同时改变定义的COUNT宏,字符串数和宏的数字要一致哦。
    下面是完整的计时器实现的完整代码:
#include "windows.h"
#include <tchar.h>
// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_CREATE:
        SetTimer(hwnd,0,100,NULL);
        return 0;
    case WM_PAINT:
        {
            #define COUNT 9
            static int iCount=0;
            static TCHAR Dot[COUNT][10]={_T("."),_T(".."),_T("..."),_T("...."),_T("....."),_T("......"),_T("......."),_T("........"),_T("........")};
            //static TCHAR Dot[COUNT][10]={_T("-"),_T("/"),_T("|"),_T("\\")};
            //static TCHAR Dot[COUNT][10]={_T("╱"),_T("┊"),_T("╲"),_T("┈")};
            //static TCHAR Dot[COUNT][10]={_T("①"),_T("②"),_T("③"),_T("④"),_T("⑤"),_T("⑥")};
            //static TCHAR Dot[COUNT][10]={_T("┹"),_T("┩"),_T("┱"),_T("┢")};
            //static TCHAR Dot[COUNT][10]={_T("卍"),_T("卐")};

            //输出提示
            HDC hdc = BeginPaint(hwnd,&ps);
            SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
            TCHAR Tip[100]=_T("");
            wsprintf(Tip,_T("正在扫描病毒%s"),Dot[iCount++%COUNT]);
            TextOut(hdc,10,20,Tip,lstrlen(Tip));
            EndPaint(hwnd,&ps);
        }
        return 0;
    case WM_TIMER:
        InvalidateRect(hwnd,NULL,TRUE);
        return 0;

     case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
     default:
         return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClass(&wndClass)) return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,600,500,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (TRUE)
    {
        if(GetMessage(&msg,NULL,0,0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
}