主頁 >  其他 > C++用桌面圖示系列之三【整理-時鐘】

C++用桌面圖示系列之三【整理-時鐘】

2021-01-02 14:42:21 其他

他來了,他來了,桌面圖示一百種玩法第三種,桌面時鐘,

學會了就發給女朋友玩吧,效果炫酷,學不了吃虧,學不了上當,走過路過不要錯過,

老規矩,先看看視頻效果,

<iframe id="BsN7cagM-1609482050205" src="https://live.csdn.net/v/embed/140603" allowfullscreen="true" data-mediaembed="csdn"></iframe>

C++用桌面圖示系列之三【整理-時鐘】

核心代碼

除了基本的時間展示之外,還包含了初始影片,

int nScreenWith;
int nScreenHeigh;
typedef struct tagMovingIcon
{
	int index;
	int targetX;
	int targetY;
	int startX;
	int startY;
	int aniDelay;                           //影片延遲時間,隨機的,打造一種亂中有序的氛圍

}MovingIcon, *PMovingIcon;

vector<MovingIcon> 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<int(*)[COL]> 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<int> ranX(0, nScreenWith);
			uniform_int_distribution<int> 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() <= 0)
			{

				int hour1 = p->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<int> 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://www.uj5u.com/qita/243656.html

標籤:其他

上一篇:C++小游戲數字炸彈

下一篇:C語言編程>第九周 ⑦ 請撰寫一個函式fun,它的功能是:求出一個2×M整型二維陣列中最小元素的值,并將最小值回傳呼叫函式。

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more