请选择 进入手机版 | 继续访问电脑版

C++用桌面图标系列之三【整理-时钟】

[复制链接]
林雨宣 发表于 2021-1-3 11:56:32 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
他来了,他来了,桌面图标一百种玩法第三种,桌面时钟。
学会了就发给女朋侪玩吧,效果炫酷,学不了亏损,学不了上当,走过途经不要错过。
老例子,先看看视频效果。
   C++用桌面图标系列之三【整理-时钟】
 
焦点代码
除了根本的时间展示之外,还包罗了初始动画。
  1. int nScreenWith;int nScreenHeigh;typedef struct tagMovingIcon{        int index;        int targetX;        int targetY;        int startX;        int startY;        int aniDelay;                           //动画延迟时间,随机的。打造一种乱中有序的氛围}MovingIcon, *PMovingIcon;vector vMoveAniIcons;           //动画队列的图标索引ULONGLONG startAniTick;                     //记载动画起始时间DWORD dwProcessId = 0;HANDLE hProcess;LPVOID lpvPt;BOOL MoveTo(int numIndex, int posX, int posY, int iconIndex, bool moveAni = false);void WriteNumber(int numIndex, int numberShade[ROW][COL], bool moveAni = false);BOOL CALLBACK EnumWindowsProc(_In_ HWND TopHandle, _In_ LPARAM topparamhandle);void DoMoveAni();//桌面图标层句柄HWND  hwndSysListView32;//逻辑起点void ClockLogic(){        vector vNumberShade;        vNumberShade.push_back(num0);        vNumberShade.push_back(num1);        vNumberShade.push_back(num2);        vNumberShade.push_back(num3);        vNumberShade.push_back(num4);        vNumberShade.push_back(num5);        vNumberShade.push_back(num6);        vNumberShade.push_back(num7);        vNumberShade.push_back(num8);        vNumberShade.push_back(num9);        HWND  hwndParent = ::FindWindow("Progman", "Program Manager");        HWND  hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent, NULL, "SHELLDLL_DefView", NULL);        hwndSysListView32 = ::FindWindowEx(hwndSHELLDLL_DefView, NULL, "SysListView32", "FolderView");        if (hwndSysListView32 == NULL)        {                //***注意,某些情句柄有空的,实验用下面的函数来查找句柄***                //***也可以自行使用vs的工具spy++工具来检察层级是否准确*****                EnumWindows(EnumWindowsProc, (LPARAM)nullptr);                if (hwndSysListView32 == NULL)                        return;        }        int iconCount = ListView_GetItemCount(hwndSysListView32);        if (iconCount < TOTAL_ICON_COUNT)        {                //图标数量不敷啊大佬,多复制几个                return;        }        GetWindowThreadProcessId(hwndSysListView32, &dwProcessId);                        //通过桌面窗口句柄获取此窗口所在进程的PID,实在就是explorer进程        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);                   //打开指定PID进程,取得进程句柄        lpvPt = VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_COMMIT, PAGE_READWRITE);//在指定进程内里申请一个POINI布局巨细的空间.        for (size_t i = 0; i < iconCount; i++)        {                if (i >= TOTAL_ICON_COUNT - 1)                {                        //这里会将所有多余的桌面图标放到接们看不见的位置,反面可以右键桌面设置对齐网格还原图标位置                        SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, i, MAKELPARAM(-100, -100));                }                else                {                        //将图标打乱,这部门只是为了拍视频  可删除                        random_device rd;                        uniform_int_distribution ranX(0, nScreenWith);                        uniform_int_distribution ranY(0, nScreenHeigh);                        SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, i, MAKELPARAM(ranX(rd), ranY(rd)));                }        }        //这部门只是为了拍视频   可删除        Sleep(3000);        time_t currentTime;        struct tm* p;        ULONGLONG nextClockTick = GetTickCount64() + ANI_TOTAL_TIME + ANI_DELAY_TIME;//加上动画需要的时间,动画阶数再开始显示时间        ULONGLONG nextAniTick = GetTickCount64();        startAniTick = GetTickCount64();        int checkHour = -1;        int checkMin = -1;        while (1)        {                if (GetTickCount64() >= nextAniTick)                {                        time(&currentTime);                        p = localtime(&currentTime);                        if (vMoveAniIcons.size() tm_hour / 10;                                int hour2 = p->tm_hour % 10;                                WriteNumber(0, vNumberShade[hour1], true);                                WriteNumber(1, vNumberShade[hour2], true);                                int min1 = p->tm_min / 10;                                int min2 = p->tm_min % 10;                                WriteNumber(2, vNumberShade[min1], true);                                WriteNumber(3, vNumberShade[min2], true);                                int sec1 = p->tm_sec / 10;                                int sec2 = p->tm_sec % 10;                                WriteNumber(4, vNumberShade[sec1], true);                                WriteNumber(5, vNumberShade[sec2], true);                        }                        DoMoveAni();                        nextAniTick += 10;//移动隔断                }                //下面是正式的时钟显示逻辑///                if (GetTickCount64() < nextClockTick)                        continue;                nextClockTick = GetTickCount64() + 1000;                time(&currentTime);                p = localtime(&currentTime);                //小时                if (checkHour == -1 || checkHour != p->tm_hour)                {                        checkHour = p->tm_hour;                        int hour1 = p->tm_hour / 10;//十位数                        int hour2 = p->tm_hour % 10;//个位数                        WriteNumber(0, vNumberShade[hour1]);                        WriteNumber(1, vNumberShade[hour2]);                }                //分钟                if (checkMin == -1 || checkMin != p->tm_min)                {                        checkMin = p->tm_min;                        int min1 = p->tm_min / 10;                        int min2 = p->tm_min % 10;                        WriteNumber(2, vNumberShade[min1]);                        WriteNumber(3, vNumberShade[min2]);                }                //秒的                int sec1 = p->tm_sec / 10;                int sec2 = p->tm_sec % 10;                WriteNumber(4, vNumberShade[sec1]);                WriteNumber(5, vNumberShade[sec2]);        }}void WriteNumber(int numIndex, int numberShade[ROW][COL], bool moveAni){        int nIconIndex = numIndex * (ROW * COL);        for (size_t row = 0; row < ROW; row++)        {                for (size_t col = 0; col < COL; col++)                {                        if (numberShade[row][col] == 1)                                MoveTo(numIndex, row, col, nIconIndex, moveAni);                        else                                MoveTo(numIndex, -1, -1, nIconIndex, moveAni);        //不需要显示的就挪到看不见的地方                        ++nIconIndex;                }        }}//图标iconIndex 移动到目标点BOOL MoveTo(int numIndex, int row, int col, int iconIndex, bool moveAni){        //int numGap = numIndex % 2 == 0 ? (numIndex / 2) * NUM_GAP2 : ((numIndex - 1) / 2) * NUM_GAP2 + NUM_GAP1;//        int targetX = 0, targetY = 0, numGap = 0;        if (row == -1)//需要移出屏幕的图标        {                targetX = -100;                targetY = 0;        }        else if (numIndex == 0 || numIndex == 1)//时        {                numGap = numIndex % 2 == 0 ? 0 : NUM_GAP1;                targetX = nScreenWith / 4 - GRID_WIDTH * COL + numGap + col * GRID_WIDTH;                targetY = nScreenHeigh / 3 + row * GRID_WIDTH - 120;        }        else if (numIndex == 2 || numIndex == 3)//分        {                numGap = numIndex % 2 == 0 ? 0 : NUM_GAP1;                targetX = (3 * nScreenWith / 4) - GRID_WIDTH * COL + numGap + col * GRID_WIDTH;                targetY = nScreenHeigh / 3 + row * GRID_WIDTH - 120;        }        else if (numIndex == 4 || numIndex == 5)//秒        {                numGap = numIndex % 2 == 0 ? 0 : NUM_GAP1;                targetX = nScreenWith / 2 - GRID_WIDTH * COL + numGap + col * GRID_WIDTH;                targetY = nScreenHeigh / 2 + row * GRID_WIDTH + 30;        }        //需要播放动画的        if (moveAni && row != -1)        {                //获取图标初始位置                POINT pIconCurPos;                ListView_GetItemPosition(hwndSysListView32, iconIndex, lpvPt);                ReadProcessMemory(hProcess, lpvPt, &pIconCurPos, sizeof(POINT), NULL);                random_device rd;                //取0 - ANI_DELAY_TIME的随机数                uniform_int_distribution dist(0, ANI_DELAY_TIME);                MovingIcon icon;                icon.index = iconIndex;                icon.targetX = targetX;                icon.targetY = targetY;                icon.startX = pIconCurPos.x;                icon.startY = pIconCurPos.y;                icon.aniDelay = dist(rd);                //放到动画队列里                vMoveAniIcons.push_back(icon);        }        else        {                SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, iconIndex, MAKELPARAM(targetX, targetY));        }        return true;}//做初始动画void DoMoveAni(){        //动画做了多久        ULONGLONG nPassedTime = GetTickCount64() - startAniTick;        if (nPassedTime > ANI_TOTAL_TIME + ANI_DELAY_TIME)                return;        for (auto iter = vMoveAniIcons.begin(); iter != vMoveAniIcons.end(); ++iter)        {                if (nPassedTime < iter->aniDelay)                        continue;                if (nPassedTime - iter->aniDelay >= ANI_TOTAL_TIME)                {                        //校正最后的位置                        SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, iter->index, MAKELPARAM(iter->targetX, iter->targetY));                        continue;                }                //当前所在位置  =  (颠末的时间 / 总时间) * (总旅程)                //按时间比例来算,应该不复杂 = =!                int targetX = 0, targetY = 0;                targetX = ((double)(nPassedTime - iter->aniDelay) / (ANI_TOTAL_TIME)) * (iter->targetX - iter->startX);                targetY = ((double)(nPassedTime - iter->aniDelay) / (ANI_TOTAL_TIME)) * (iter->targetY - iter->startY);                //在vs的输出界面打印信息                char out0[128] = { 0 };                sprintf(out0, "index=%d x=%d y=%d \n", iter->index, targetX, targetY);                //OutputDebugStringA(out0);                targetX += iter->startX;                targetY += iter->startY;                SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, iter->index, MAKELPARAM(targetX, targetY));        }}
复制代码
这里是完整代码和可执行文件。
https://download.csdn.net/download/Yang9325/13999888

来源:https://blog.csdn.net/Yang9325/article/details/112056356
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )