C language realizes the digital rain effect
- 2020-06-03 07:31:22
- OfStack
Examples of this paper share the C language to achieve the digital rain effect display specific code for your reference, the specific content is as follows
#include <windows.h>
#include <windowsx.h>
#define ID_TIMER 1
#define STRMAXLEN 25 //1 The maximum length of the columns displayed
#define STRMINLEN 8 //1 The minimum length of the displayed columns
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
typedef struct tagCharChain // The whole thing ACTS as a screen 1 A display list , It's a two-way list
{
struct tagCharChain *prev; // The first element of a linked list
TCHAR ch; //1 Of the display columns 1 A character
struct tagCharChain *next; // The last element of the list
}CharChain, *pCharChain;
typedef struct tagCharColumn
{
CharChain *head, *current, *point;
int x, y, iStrLen; // Displays the beginning of the column x,y coordinates ,iStrLen Is the length of this column
int iStopTimes, iMustStopTimes; // The number of times it has stopped and the number of times it has to stop , The number of times you have to stop is random
}CharColumn, *pCharColumn;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("matrix") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ; // class style
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if(!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT (" This program must be run in NT Under the !"), szAppName, MB_ICONERROR) ;
return 0;
}
hwnd = CreateWindow (szAppName, NULL,
WS_DLGFRAME | WS_THICKFRAME | WS_POPUP, // windows style
0, 0,
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
NULL, NULL, hInstance,
NULL) ;
ShowWindow (hwnd, SW_SHOWMAXIMIZED) ; // Maximized display show windows
UpdateWindow (hwnd) ;
ShowCursor(FALSE); // Hide the mouse cursor
srand ((int) GetCurrentTime ()) ; // Initialize the random number generator
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
ShowCursor(TRUE); // Display mouse cursor
return msg.wParam ;
}
TCHAR randomChar() // Random character generation function
{
return (TCHAR)(rand()%(126-33)+33); //33 to 126 between
}
int init(CharColumn *cc, int cyScreen, int x) // Initialize the
{
int j;
cc->iStrLen = rand()%(STRMAXLEN-STRMINLEN) + STRMINLEN; // Displays the length of the column
cc->x = x+3 ; // Displays the beginning of the column x coordinates
cc->y =rand()%3?rand()%cyScreen:0; // Displays the beginning of the column y coordinates
cc->iMustStopTimes = rand()%6 ;
cc->iStopTimes = 0 ;
cc->head = cc->current =
(pCharChain)calloc(cc->iStrLen, sizeof(CharChain)); // Generate display columns
for(j=0; j<cc->iStrLen-1; j++)
{
cc->current->prev = cc->point; //cc->point1 The first element of the display column
cc->current->ch = '\0';
cc->current->next = cc->current+1; //cc->current+11 The last element of a column
cc->point = cc->current++; //cc->point = cc->current; cc->current++;
}
cc->current->prev = cc->point; // The last 1 A node
cc->current->ch = '\0';
cc->current->next = cc->head;
cc->head->prev = cc->current; // The front of the head node 1 The end of this chain 1 An element
cc->current = cc->point = cc->head; //free The requested memory is to be used current When the parameter
cc->head->ch = randomChar(); // On the head of the chain Element filling
return 0;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
//ctn Used to determine the 1 A display chain whether Move down , If you wait more than you have to wait ,ctn It's going to go down
int i, j, temp, ctn; //j for 1 The number of display chains other than the head of the chain displayed on the screen y coordinates ,temp Excessive green to black
static HDC hdcMem;
HFONT hFont;
static HBITMAP hBitmap;
static int cxScreen, cyScreen; // Screen width highly .
static int iFontWidth=10, iFontHeight=15, iColumnCount; // Font width highly , The number of columns
static CharColumn *ccChain;
switch (message)
{
case WM_CREATE:
cxScreen = GetSystemMetrics(SM_CXSCREEN) ; // The width of the screen
cyScreen = GetSystemMetrics(SM_CYSCREEN) ;
SetTimer (hwnd, ID_TIMER, 10, NULL) ;
hdc = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdc);
hBitmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);
SelectObject(hdcMem, hBitmap);
ReleaseDC(hwnd, hdc);
// Create a font
hFont = CreateFont(iFontHeight, iFontWidth-5, 0, 0, FW_BOLD, 0, 0, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DRAFT_QUALITY, FIXED_PITCH | FF_SWISS, TEXT("Fixedsys"));
SelectObject(hdcMem, hFont);
DeleteObject (hFont) ;
SetBkMode(hdcMem, TRANSPARENT); // Set the background mode to transparent
iColumnCount = cxScreen/(iFontWidth*3/2); // The number of columns of letter rain displayed on the screen
ccChain = (pCharColumn)calloc(iColumnCount, sizeof(CharColumn));
for(i=0; i<iColumnCount; i++)
{
init(ccChain+i, cyScreen, (iFontWidth*3/2)*i);
}
return 0 ;
case WM_TIMER:
hdc = GetDC(hwnd);
PatBlt (hdcMem, 0, 0, cxScreen, cyScreen, BLACKNESS) ; // Paint the memory device image black
for(i=0; i<iColumnCount; i++)
{
ctn = (ccChain+i)->iStopTimes++ > (ccChain+i)->iMustStopTimes;
//
(ccChain+i)->point = (ccChain+i)->head; //point Used to traverse the entire display column
// The first 1 Three characters are displayed as white
SetTextColor(hdcMem, RGB(255, 255, 255));
TextOut(hdcMem, (ccChain+i)->x, (ccChain+i)->y, &((ccChain+i)->point->ch), 1);
j = (ccChain+i)->y;
(ccChain+i)->point = (ccChain+i)->point->next;
// Traverse the entire display column , Display the characters in the display column from bottom to top
temp = 0 ; //temp Excessive green to black
while((ccChain+i)->point != (ccChain+i)->head && (ccChain+i)->point->ch)
{
SetTextColor(hdcMem, RGB(0, 255-(255*(temp++)/(ccChain+i)->iStrLen), 0));
TextOut(hdcMem, (ccChain+i)->x, j-=iFontHeight, &((ccChain+i)->point->ch), 1);
(ccChain+i)->point = (ccChain+i)->point->next;
}
if(ctn)
(ccChain+i)->iStopTimes = 0 ;
else continue;
(ccChain+i)->y += iFontHeight; // I'll show it next time y coordinates For the current y Coordinate with 1 The height of two characters
// If it starts to show y Coordinate minus The length of the entire display column exceeds the height of the screen
if( (ccChain+i)->y-(ccChain+i)->iStrLen*iFontHeight > cyScreen)
{
free( (ccChain+i)->current );
init(ccChain+i, cyScreen, (iFontWidth*3/2)*i);
}
// The head of the list The first element of this linked list , Because the next time I start showing it This is equivalent to adding an element to the beginning of the entire display column , And then it goes up at the beginning
(ccChain+i)->head = (ccChain+i)->head->prev;
(ccChain+i)->head->ch = randomChar();
}
BitBlt(hdc, 0, 0, cxScreen, cyScreen, hdcMem, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hdc);
return 0;
case WM_RBUTTONDOWN:
KillTimer (hwnd, ID_TIMER) ;
return 0;
case WM_RBUTTONUP:
SetTimer (hwnd, ID_TIMER, 10, NULL) ;
return 0;
// Deal with the aftermath
case WM_KEYDOWN:
case WM_LBUTTONDOWN:
case WM_DESTROY:
KillTimer (hwnd, ID_TIMER) ;
DeleteObject(hBitmap);
DeleteDC(hdcMem);
for(i=0; i<iColumnCount; i++)
{
free( (ccChain+i)->current );
}
free(ccChain);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}