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