zoukankan      html  css  js  c++  java
  • C++------流星雨

    用C++实现模拟数字、字母流星雨,其主要用到链表、win32编程基础。

    demo实例:

      1 // DataRainDemo.cpp : 定义应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "DataRainDemo.h"
      6 #include<time.h>
      7 #include<stdlib.h>
      8 #include<windows.h>
      9 #define STRMINLEN   8
     10 #define STRMAXLEN    25
     11 
     12 
     13 
     14 //双向链表的每一个节点
     15 typedef struct MyList
     16 {
     17     struct MyList *prev;                //前一节点
     18     struct MyList *pNext;                //下一节点
     19     char ch;                                    //数据保存
     20 } MyList,*pMyList;
     21 //处理数据
     22 typedef struct MyListColum
     23 {
     24     MyList *phead;                        //整个链表的头
     25     MyList *pCurent;                        //链表所在当前的位置
     26     MyList *pTemp;                        //临时变量
     27     int listStrLen;                            //整个链表的长度    
     28     int x, y;                                    //链表的位置
     29     int iStopTimes;
     30     int iMusStopTimes;
     31 }StrColum,*pStrColum;
     32 
     33 
     34 #define MAX_LOADSTRING 100
     35 
     36 // 全局变量: 
     37 HINSTANCE hInst;                                // 当前实例
     38 WCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
     39 WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
     40 
     41 // 此代码模块中包含的函数的前向声明: 
     42 ATOM                MyRegisterClass(HINSTANCE hInstance);
     43 BOOL                InitInstance(HINSTANCE, int);
     44 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
     45 INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
     46 
     47 int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
     48                      _In_opt_ HINSTANCE hPrevInstance,
     49                      _In_ LPWSTR    lpCmdLine,
     50                      _In_ int       nCmdShow)
     51 {
     52     UNREFERENCED_PARAMETER(hPrevInstance);
     53     UNREFERENCED_PARAMETER(lpCmdLine);
     54 
     55     // TODO: 在此放置代码。
     56 
     57     // 初始化全局字符串
     58     LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
     59     LoadStringW(hInstance, IDC_DATARAINDEMO, szWindowClass, MAX_LOADSTRING);
     60     MyRegisterClass(hInstance);
     61 
     62     // 执行应用程序初始化: 
     63     if (!InitInstance (hInstance, nCmdShow))
     64     {
     65         return FALSE;
     66     }
     67     srand(time(NULL));//以时间为种子
     68     HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DATARAINDEMO));
     69 
     70     MSG msg;
     71 
     72     // 主消息循环: 
     73     while (GetMessage(&msg, nullptr, 0, 0))
     74     {
     75         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
     76         {
     77             TranslateMessage(&msg);
     78             DispatchMessage(&msg);
     79         }
     80     }
     81 
     82     return (int) msg.wParam;
     83 }
     84 //宽字节 两个字节代表一个字符
     85 TCHAR randomChar()
     86 {
     87     return (rand() % 10 + 98);//0-9的ASCII
     88 }
     89 
     90 //
     91 //  函数: MyRegisterClass()
     92 //
     93 //  目的: 注册窗口类。
     94 //
     95 ATOM MyRegisterClass(HINSTANCE hInstance)
     96 {
     97     WNDCLASSEXW wcex;
     98 
     99     wcex.cbSize = sizeof(WNDCLASSEX);
    100 
    101     wcex.style          = CS_HREDRAW | CS_VREDRAW;
    102     wcex.lpfnWndProc    = WndProc;
    103     wcex.cbClsExtra     = 0;
    104     wcex.cbWndExtra     = 0;
    105     wcex.hInstance      = hInstance;
    106     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DATARAINDEMO));
    107     wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    108     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    109     wcex.lpszMenuName = NULL;//MAKEINTRESOURCEW(IDC_DATARAINDEMO);
    110     wcex.lpszClassName  = szWindowClass;
    111     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    112 
    113     return RegisterClassExW(&wcex);
    114 }
    115 
    116 //
    117 //   函数: InitInstance(HINSTANCE, int)
    118 //
    119 //   目的: 保存实例句柄并创建主窗口
    120 //
    121 //   注释: 
    122 //
    123 //        在此函数中,我们在全局变量中保存实例句柄并
    124 //        创建和显示主程序窗口。
    125 //
    126 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    127 {
    128    hInst = hInstance; // 将实例句柄存储在全局变量中
    129 
    130    /*HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    131       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);*/
    132    /*
    133        API 函数原型:
    134     HWND WINAPI CreateWindow(
    135       _In_opt_  LPCTSTR lpClassName,      // 窗口类名称
    136       _In_opt_  LPCTSTR lpWindowName,  // 窗口标题
    137       _In_      DWORD dwStyle,                     // 窗口风格,或称窗口格式
    138       _In_      int x,                                         // 初始 x 坐标
    139       _In_      int y,                                         // 初始 y 坐标
    140       _In_      int nWidth,                                 // 初始 x 方向尺寸
    141       _In_      int nHeight,                             // 初始 y 方向尺寸
    142       _In_opt_  HWND hWndParent,             // 父窗口句柄
    143       _In_opt_  HMENU hMenu,                     // 窗口菜单句柄
    144       _In_opt_  HINSTANCE hInstance,          // 程序实例句柄
    145       _In_opt_  LPVOID lpParam                      // 创建参数
    146     );
    147 
    148     注:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数(不是说没有参数,而是可以利用宏搭配参数)。
    149    */
    150    HWND hWnd = CreateWindowW(szWindowClass, NULL, WS_DLGFRAME|WS_THICKFRAME|WS_POPUP,
    151        0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), nullptr, nullptr, hInstance, nullptr);
    152 
    153    if (!hWnd)
    154    {
    155       return FALSE;
    156    }
    157 
    158    ShowWindow(hWnd, nCmdShow);
    159    UpdateWindow(hWnd);
    160 
    161    return TRUE;
    162 }
    163 
    164 //
    165 //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    166 //
    167 //  目的:    处理主窗口的消息。
    168 //
    169 //  WM_COMMAND  - 处理应用程序菜单
    170 //  WM_PAINT    - 绘制主窗口
    171 //  WM_DESTROY  - 发送退出消息并返回
    172 //
    173 //
    174 //初始化每个链表
    175 void init(StrColum *cc, int cyScreen, int x)
    176 {
    177     int j;
    178     cc->listStrLen = rand() % (STRMAXLEN - STRMINLEN) + STRMINLEN;
    179     cc->x = x+3;
    180     cc->y = rand() % 3 ? rand() % cyScreen : 0;
    181     cc->iMusStopTimes = rand() % 6;
    182     cc->iStopTimes = 0;
    183     cc->phead = cc->pCurent = (pMyList)calloc(cc->listStrLen,sizeof(MyList));
    184     for ( j = 0; j < cc->listStrLen-1; j++)
    185     {
    186         cc->pCurent->prev = cc->pTemp;
    187         cc->pCurent->ch = '';
    188         cc->pCurent->pNext = cc->pCurent + 1;
    189         cc->pTemp = cc->pCurent++;
    190     }
    191     cc->pCurent->prev = cc->pTemp;
    192     cc->pCurent->ch = '';
    193     cc->pCurent->pNext = cc->phead;
    194     cc->phead->prev = cc->pCurent;
    195     cc->pCurent = cc->pTemp = cc->phead;
    196     cc->phead->ch = randomChar();
    197 }
    198 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    199 {
    200     HDC hdc;
    201     int i, j, temp, ctn;
    202     static HDC hdcMem;
    203     HFONT hFont;
    204     static HBITMAP hBimtmap;
    205     static int cxScreen, cyScreen;
    206     static int iFontWidth = 10, iFontHeight = 15, iColumCount;
    207     static StrColum *ccChain;
    208     switch (message)
    209     {
    210         case WM_CREATE:
    211         {
    212             cxScreen = GetSystemMetrics(SM_CXSCREEN);
    213             cyScreen = GetSystemMetrics(SM_CYSCREEN);
    214             SetTimer(hWnd, 1, 10, NULL);
    215             hdc = GetDC(hWnd);
    216             hdcMem = CreateCompatibleDC(hdc);
    217             hBimtmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);
    218             SelectObject(hdcMem, hBimtmap);
    219             ReleaseDC(hWnd, hdc); 
    220 
    221             hFont = CreateFont(iFontHeight, iFontWidth - 5, 0, 0, 
    222                 FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, 
    223                 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    224                 DRAFT_QUALITY, FIXED_PITCH | FF_SWISS, 
    225                 TEXT("Fixedsys"));
    226             SelectObject(hdcMem,hFont);
    227             DeleteObject(hFont);
    228             SetBkMode(hdcMem,TRANSPARENT);
    229             //设置显示的列数
    230             iColumCount = cxScreen / (iFontWidth * 3 / 2);
    231             ccChain = (pStrColum)calloc(iColumCount,sizeof(StrColum));
    232             for (int i = 0; i < iColumCount; i++)
    233             {
    234                 init(ccChain + i,cyScreen,(iFontWidth*3/2)*i);
    235             }
    236             return 0;
    237         }
    238         break;
    239     case WM_COMMAND:
    240         {
    241             int wmId = LOWORD(wParam);
    242             // 分析菜单选择: 
    243             switch (wmId)
    244             {
    245             case IDM_ABOUT:
    246                 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    247                 break;
    248             case IDM_EXIT:
    249                 DestroyWindow(hWnd);
    250                 break;
    251             default:
    252                 return DefWindowProc(hWnd, message, wParam, lParam);
    253             }
    254         }
    255         break;
    256     case WM_PAINT:
    257         {
    258             PAINTSTRUCT ps;
    259             HDC hdc = BeginPaint(hWnd, &ps);
    260             // TODO: 在此处添加使用 hdc 的任何绘图代码...
    261             EndPaint(hWnd, &ps);
    262         }
    263         break;
    264     
    265     case WM_DESTROY:
    266         KillTimer(hWnd,1);
    267         DeleteObject(hBimtmap);
    268         DeleteDC(hdcMem);
    269         for ( i = 0; i < iColumCount; i++)
    270         {
    271             free((ccChain+i)->pCurent);
    272         }
    273         free(ccChain);
    274         PostQuitMessage(0);
    275         break;
    276     default:
    277         return DefWindowProc(hWnd, message, wParam, lParam);
    278     case WM_TIMER:
    279     {
    280         hdc = GetDC(hWnd);
    281         PatBlt(hdcMem, 0, 0, cxScreen, cyScreen, BLACKNESS);
    282         for (int i = 0; i < iColumCount; i++)
    283         {
    284             ctn = (ccChain + i)->iStopTimes++ >(ccChain + i)->iMusStopTimes;
    285             (ccChain + i)->pTemp = (ccChain + i)->phead;
    286             SetTextColor(hdcMem,RGB(255,255,255));
    287             TextOut(hdcMem,(ccChain+i)->x,(ccChain+i)->y,&((ccChain+i)->pTemp->ch),1);
    288             j = (ccChain + i)->y;
    289             (ccChain + i)->pTemp = (ccChain + i)->pTemp->pNext;
    290             temp = 0;
    291             //temp 绿色过度到黑色
    292             while ((ccChain+i)->pTemp!=(ccChain+i)->phead
    293                 &&(ccChain+i)->pTemp->ch)
    294             {
    295                 SetTextColor(hdcMem,RGB(0,255-(255*(temp++)
    296                     /(ccChain+i)->listStrLen),0));
    297                 TextOut(hdcMem,(ccChain+i)->x,j-=iFontHeight,
    298                     &((ccChain+i)->pTemp->ch),1);
    299                 (ccChain + i)->pTemp = (ccChain + i)->pTemp->pNext;
    300             }
    301             if (ctn)
    302                 (ccChain + i)->iStopTimes = 0;
    303             else
    304                 continue;
    305             (ccChain + i)->y += iFontHeight;//下次开始显示的地方
    306             if ((ccChain+i)->y-(ccChain+i)->listStrLen*iFontHeight>cyScreen)
    307             {
    308                 free((ccChain+i)->pCurent);
    309                 init(ccChain+i,cyScreen,(iFontWidth*3/2)*i);
    310             }
    311             (ccChain + i)->phead = (ccChain + i)->phead->prev;
    312             (ccChain + i)->phead->ch = randomChar();
    313         }
    314 
    315         BitBlt(hdc,0,0,cxScreen,cyScreen,hdcMem,0,0,SRCCOPY);
    316         ReleaseDC(hWnd,hdc);
    317     }
    318     //case WM_RBUTTONDOWN:
    319     //    KillTimer(hWnd,1);
    320     //    return 0;
    321     //case WM_RBUTTONUP:
    322     //    SetTimer(hWnd,1,10,NULL);
    323     //    return 0;
    324         
    325     }
    326     return 0;
    327 }
    328 
    329 
    330 
    331 
    332 
    333 
    334 // “关于”框的消息处理程序。
    335 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    336 {
    337     UNREFERENCED_PARAMETER(lParam);
    338     switch (message)
    339     {
    340     case WM_INITDIALOG:
    341         return (INT_PTR)TRUE;
    342 
    343     case WM_COMMAND:
    344         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    345         {
    346             EndDialog(hDlg, LOWORD(wParam));
    347             return (INT_PTR)TRUE;
    348         }
    349         break;
    350     }
    351     return (INT_PTR)FALSE;
    352 }

    实现效果展示

  • 相关阅读:
    Unity 执行命令行
    c#中的特性,以及一些思考
    miniui禁用combobox
    给textarea赋值并可编辑
    js不允许input输入空格
    使用OPENROWSET函数连接并访问远程数据库数据
    miniui 换页符点击无效
    AJAX基本结构及使用
    SQL Server查询数据库中包含某个值的表和字段
    js实现input输入框只能输入数字的功能
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/11439296.html
Copyright © 2011-2022 走看看