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 = '