一、完成版简介
打开即见效,视觉效果炸裂,杀毒软件扫不出~不多废话,开始教学
最终效果视频
二、基本代码
本次用到的基本代码是windows.h库中的DrawIcon()函数,直接上用法
DrawIcon(窗口hdc, x坐标, y坐标, LoadIcon(图标);
三、应用
在屏幕中心绘制一个警告图标
#include<Windows.h>
using namespace std;
int main()
{
HWND hDesktop = GetDesktopWindow();//获取屏幕窗口句柄
HDC hdc = GetWindowDC(hDesktop);//获取屏幕hdc
int x = GetSystemMetrics(SM_CXSCREEN);//获取屏幕边界x
int y = GetSystemMetrics(SM_CYSCREEN);//获取屏幕边界y
x /= 2;
y /= 2;//x,y取一半
while(1) DrawIcon(hdc, x, y, LoadIcon(NULL, IDI_WARNING));
//在屏幕的中心位置绘制'警告'图标
return 0;
}
简单写个循环,绘制图标覆盖全桌面
#include<Windows.h>
using namespace std;
int main()
{
HWND hDesktop = GetDesktopWindow();//获取桌面句柄
HDC hdc = GetWindowDC(hDesktop);//获取桌面hdc
int x = GetSystemMetrics(SM_CXSCREEN);//获取屏幕边界x
int y = GetSystemMetrics(SM_CYSCREEN);//获取屏幕边界y
while(1)
{
for ( int tx = 0 ; tx < x ; tx++ )
{
for ( int ty = 0 ; ty < y ; ty++ )
DrawIcon(hdc, tx, ty, LoadIcon(NULL, IDI_WARNING));
}
}
return 0;
}
只有warning图标太单调,链接一下系统自带的图标
HINSTANCE hShell32 = LoadLibrary("1.dll");
然后在DrawIcon中调用
DrawIcon(hdc, tx, ty, LoadIcon(hShell32,MAKEINTRESOURCE(数字));
调用一下MEMZ的随机函数
#include <Windows.h>
using namespace std;//使用标准名字空间
HCRYPTPROV prov;//随机函数中必要的全局变量
//生成随机数
int random()
{
if (prov == NULL) if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) ExitProcess(1);
int out;
CryptGenRandom(prov, sizeof(out), (BYTE *)(&out));
return out & 0x7fffffff;
}
有了随机函数之后,只需要把DrawIcon中的LoadIcon参数改为随机自带图标即可
DrawIcon(hdc, tx, ty, LoadIcon(hShell32,MAKEINTRESOURCE(random()%28+100)));
//意为取100~128的随机数,似乎只有这几个图标能用
四、最终成果
做了这么多准备工作,最后终于可以放大招了
全屏随机分块+随机铺图标
首先把绘制图标的部分写入函数,主函数改为生成分块
int main()
{
int hasb[130];//存储各自分块是否已经弹出图标过
int fen;//存储分块数量(平方)
while(1)
{
fen=random()%10+2;//随机分成1至121块
memset(hasb, 0, sizeof(hasb));//重置记录
for(int thnum=1;thnum<fen*fen;)//遍历分块次
{
int position=random()%(fen*fen)+1;//每次随机选择一个未被弹出的分块
if(hasb[position] == 0)
{
hasb[position] = 1;
PlayloadIcon(position,fen);//把分块编号发给函数
thnum++;
}
}
}
return 0;
}
函数内容则如下
//绘制错误图标
void PlayloadIcon(int position,int fen)
{
position--;
int tmpp=position%fen;
int startx = x/fen*tmpp;
int endx = startx + x/fen;
tmpp=(position-tmpp)/fen;
int starty = y/fen*tmpp;
int endy = starty + y/fen;
//反向康托展开,取出编号对应的开始与结束x,y坐标
for(int d=7;d<=20;d+=5)
{
int d2=random()%(d-5)+5;//随机产生每块的图标内距
for(int tx=startx;tx<endx;tx+=d2)
{
for(int ty=starty;ty<endy;ty+=d2)
DrawIcon(hdc, tx, ty, LoadIcon(hShell32,MAKEINTRESOURCE(random()%28+100)));
}
}
}
全部源码如下,拿去
#include <Windows.h>
#include<iostream>
using namespace std;//使用标准名字空间
HCRYPTPROV prov;
HINSTANCE hShell32 = LoadLibrary("1.dll");
//生成随机数
int random()
{
if (prov == NULL) if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) ExitProcess(1);
int out;
CryptGenRandom(prov, sizeof(out), (BYTE *)(&out));
return out & 0x7fffffff;
}
int x=GetSystemMetrics(SM_CXSCREEN);//获取屏幕边界x
int y=GetSystemMetrics(SM_CYSCREEN);//获取屏幕边界y
HWND hDesktop = GetDesktopWindow(); //获取窗口句柄
HDC hdc = GetWindowDC(hDesktop); //获取窗口dc
//绘制错误图标
void PlayloadIcon(int position,int fen)
{
position--;
int tmpp=position%fen;
int startx = x/fen*tmpp;
int endx = startx + x/fen;
tmpp=(position-tmpp)/fen;
int starty = y/fen*tmpp;
int endy = starty + y/fen;
//反向康托展开,取出编号对应的开始与结束x,y坐标
for(int d=7;d<=20;d+=5)
{
int d2=random()%(d-5)+5;//随机产生每块的图标内距
for(int tx=startx;tx<endx;tx+=d2)
{
for(int ty=starty;ty<endy;ty+=d2)
DrawIcon(hdc, tx, ty, LoadIcon(hShell32,MAKEINTRESOURCE(random()%28+100)));
}
}
}
int main()
{
ShowWindow(GetForegroundWindow(),0);//获取最前端窗口的句柄,然后通过ShowWindow隐藏
int hasb[130];//存储各自分块是否已经弹出图标过
int fen;//存储分块数量(平方)
while(1)
{
fen=random()%10+2;//随机分成1至121块
memset(hasb, 0, sizeof(hasb));//重置记录
for(int thnum=1;thnum<fen*fen;)//遍历分块次
{
int position=random()%(fen*fen)+1;//每次随机选择一个未被弹出的分块
if(hasb[position] == 0)
{
hasb[position] = 1;
PlayloadIcon(position,fen);//把分块编号发给函数
thnum++;
}
}
}
return 0;
}
就可以实现开头视频中的效果,本文所有代码在win10环境下的Dev-c++通过编译