程序猿的酷炫屏保 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时制粘贴 AI 生成的内容
juxiuyu123
V2EX    程序员

程序猿的酷炫屏保

  •  
  • /div>   juxiuyu123 2015-12-13 05:54:36 +08:00 4221 次点击
    这是一个创建于 3592 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include "stdafx.h"
    #include <windows.h>
    #define ID_TIMER 1
    #define STRMAXLEN 25 //一个显示列的最大长度
    #define STRMINLEN 8 //一个显示列的最小长度


    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
    typedef struct tagCharChain //整个当作屏幕的一个显示列,这是个双向列表
    {
    struct tagCharChain *prev; //链表的前个元素
    TCHAR ch; //一个显示列中的一个字符
    struct tagCharChain *next; //链表的后个元素
    }CharChain, *pCharChain;

    typedef struct tagCharColumn
    {
    CharChain *head, *current, *point;
    int x, y, iStrLen; //显示列的开始显示的 x,y 坐标,iStrLen 是这个列的长度
    int iStopTimes, iMustStopTimes; //已经停滞的次数和必须停滞的次数,必须停滞的次数是随机的
    }CharColumn, *pCharColumn;

    int main(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 ;
    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 ("此程序必须运行在 NT 下!"), szAppName, MB_IC ONERROR) ;
    return 0;
    }

    hwnd = CreateWindow (szAppName, NULL,
    WS_DLGFRAME | WS_THICKFRAME | WS_POPUP,
    0, 0,
    GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
    NULL, NULL, hInstance,
    NULL) ;

    ShowWindow (hwnd, SW_SHOWMAXIMIZED) ; //最大化显示
    UpdateWindow (hwnd) ;
    ShowCursor(FALSE); //隐藏鼠标光标

    srand ((int) GetCurrentTime ()) ; //初始化随机数发生器
    while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg) ;
    DispatchMessage (&msg) ;
    }
    ShowCursor(TRUE); //显示鼠标光标
    return msg.wParam ;
    }

    TCHAR randomChar() //随机字符产生函数
    {
    return (TCHAR)(rand()%(126-33)+33); //33 到 126 之间
    }

    int init(CharColumn *cc, int cyScreen, int x) //初始化
    {
    int j;
    cc->iStrLen = rand()%(STRMAXLEN-STRMINLEN) + STRMINLEN; //显示列的长度
    cc->x = x+3 ; //显示列的开始显示的 x 坐标
    cc->y =rand()%3?rand()%cyScreen:0; //显示列的开始显示的 y 坐标
    cc->iMustStopTimes = rand()%6 ;
    cc->iStopTimes = 0 ;
    cc->head = cc->current =
    (pCharChain)calloc(cc->iStrLen, sizeof(CharChain)); //生成显示列
    for(j=0; j<cc->iStrLen-1; j++)
    {
    cc->current->prev = cc->point; //cc->point 一个显示列的前个元素
    cc->current->ch = '\0';
    cc->current->next = cc->current+1; //cc->current+1 一个显示列的后个元素
    cc->point = cc->current++; //cc->point = cc->current; cc->current++;
    }
    cc->current->prev = cc->point; //最后一个节点
    cc->current->ch = '\0';
    cc->current->next = cc->head;
    cc->head->prev = cc->current; //头节点的前一个为此链的最后一个元素

    cc->current = cc->point = cc->head; //free 掉申请的内存要用 current 当参数
    cc->head->ch = randomChar(); // 对链表头的 元素填充
    return 0;
    }

    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HDC hdc ;
    //ctn 用来确定一个显示链是否 向下前进,如果等待次数超过必须等待的次数,ctn 就代表要向下前进
    int i, j, temp, ctn; //j 为一个显示链中除链表头外的在屏幕上显示的 y 坐标,temp 绿色过度到黑色之用
    static HDC hdcMem;
    HFONT hFont;
    static HBITMAP hBitmap;
    static int cxScreen, cyScreen; //屏幕的宽度 高度.
    static int iFOntWidth=10, iFOntHeight=15, iColumnCount; //字体的宽度 高度, 列数
    static CharColumn *ccChain;

    switch (message)
    {
    case WM_CREATE:
    cxScreen = GetSystemMetrics(SM_CXSCREEN) ; //屏幕宽度
    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);
    //创建字体
    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); //设置背景模式为 透明
    iColumnCount = cxScreen/(iFontWidth*3/2); //屏幕所显示字母雨的列数

    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) ; //将内存设备映像刷成黑色
    for(i=0; i<iColumnCount; i++)
    {
    ctn = (ccChain+i)->iStopTimes++ > (ccChain+i)->iMustStopTimes;
    //
    (ccChain+i)->point = (ccChain+i)->head; //point 用于遍历整个显示列

    //第一个字符显示为 白色
    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;
    //遍历整个显示列,将这个显示列里的字符从下往上显示
    temp = 0 ; //temp 绿色过度到黑色之用
    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)->iStopTmes = 0 ;
    else continue;
    (ccChain+i)->y += iFontHeight; //下次开始显示的 y 坐标 为当前的 y 坐标加上 一个字符的高度
    //如果开始显示的 y 坐标减去 整个显示列的长度超过了屏幕的高度
    if( (ccChain+i)->y-(ccChain+i)->iStrLen*iFontHeight > cyScreen)
    {
    free( (ccChain+i)->current );
    init(ccChain+i, cyScreen, (iFontWidth*3/2)*i);
    }
    //链表的头 为此链表的前个元素,因为下次开始显示的时候 就相当与在整个显示列的开头添加个元素,然后在开始往上显示
    (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;

    //处理善后工作
    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) ;
    }
    14 条回复    2015-12-14 00:13:35 +08:00
    vibbow
        1
    vibbow  
       2015-12-13 06:34:06 +08:00
    没看代码
    但是看标题,猜测不会是黑客帝国那种效果把...
    hqs123
        2
    hqs123  
       2015-12-13 08:08:14 +08:00
    楼主是编程高手啊...
    greatghoul
        3
    greatghoul  
       2015-12-13 09:47:43 +08:00
    楼主不如直接给个 gist 链接 ,你这排版一点也不炫。
    wyntau
        4
    wyntau  
       2015-12-13 10:54:20 +08:00
    请使用 cmatrix
    Ouyangan
        5
    Ouyangan  
       2015-12-13 10:55:10 +08:00
    编码风格,我头痛~
    Karblue
        6
    Karblue  
       2015-12-3 11:34:37 +08:00 via Android
    不用看了。字母雨效果
    harry890829
        7
    harry890829  
       2015-12-13 12:03:00 +08:00
    windows 的……
    loading
        8
    loading  
       2015-12-13 12:22:25 +08:00 via Android
    楼主你知道这样贴是没人看的吗?
    tangbao
        9
    tangbao  
       2015-12-13 17:39:31 +08:00
    LZ , stdafx.h 这个头文件是不是只有 vc++才有的啊?
    Barnet
        10
    Barnet  
       2015-12-13 20:27:42 +08:00
    没看评论,我估也是黑客帝国那种效果
    haogefeifei
        11
    haogefeifei  
       2015-12-13 21:50:40 +08:00
    看见 windows.h 。我默默的不说话了。。。
    icedx
        12
    icedx  
       2015-12-13 23:44:30 +08:00
    Windows 还是 MFC 啧啧
    exoticknight
        13
    exoticknight  
       2015-12-13 23:51:11 +08:00
    除了黑客帝国还能怎么酷炫?
    matthewz
        14
    matthewz  
       2015-12-14 00:13:35 +08:00 via iPhone
    看 mfc
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4296 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 05:33 PVG 13:33 LAX 22:33 JFK 01:33
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86