C++ 高仿超链接

1 篇文章 0 订阅


1.前言

如果你学过HTML,你肯定知道如何写一个超链接,像这样

<a href="http://www.baidu.com/">balabala</a>

点开就能进入链接的网站:

—> balabala

那么C++有没有这样的功能呢?貌似没有…

那么我们就这样放弃了吗?
NO!no!no!no!no!

既然没有,我们就来创造一个。


2.超链接的制作

编译系统:Dev-C++上编译通过
操作系统:Windows10

首先我们先来看一看超链接是怎样构成的

  1. 超链接的名称
  2. 链接的地址
  3. 链接下的下划线(可有可无)
  4. 访问过的链接是紫色的,没有访问过的是蓝色的

完成,现在我们开始写一些初始代码吧:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

HWND hwnd=GetForegroundWindow();		//控制台窗口句柄

void gotoxy(int x, int y) {				//设置光标位置(行,列)
	COORD pos = {y,x};
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
POINT mouse_pos() {					//鼠标位置(行,列) 
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p={y,x};
	return p; 
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

函数原理这里就不多解释了,相关内容可以参考:

C++ 获取鼠标点击位置 https://blog.csdn.net/wangxun20081008/article/details/113915805
C++ 移动光标 https://blog.csdn.net/wangxun20081008/article/details/115560811


完成了这些,我们来编写主函数。

先初始化控制台窗口,用system函数设置窗口的大小、字体颜色,详细内容可以参考:

C++ 设置字体颜色 https://blog.csdn.net/wangxun20081008/article/details/115046817

接下来移除我们的快速编辑模式,在win10环境下将会被默认开启,开启快速编辑模式会使我们无法点击超链接,而是选择。所以我们先将它移除。

int main() {
	//----------初始化窗口----------
	system("mode 80,40");
	system("color f0");

	//----------移除快速编辑模式(对于win10用户)----------
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	SetConsoleMode(hStdin, mode);
}

现在我们开始着手编写超链接了。

先指定一下超链接的名称,emmm…,就选4399好了

在顶上加一些变量:

string str="4399小游戏";					//超链接名称
const int len=str.size()-1;				//超链接的长度
bool b=false;							//是否访问过该超链接

接下来就来打印我们的超链接了:

//----------打印超链接字幕----------
HANDLE hOut;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hOut,
                        FOREGROUND_BLUE |
                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
                        COMMON_LVB_UNDERSCORE);
gotoxy(0,0);
printf(str.c_str());

在这里,我们用SetConsoleTextAttribute函数混合了颜色,

FOREGROUND_BLUE表示前景是蓝色的
BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |表示混合红、蓝、绿这三原色,但是混合结果实际是灰色,所以我们用BACKGROUND_INTENSITY进行高亮,形成白色。所以背景就是白色。

COMMON_LVB_UNDERSCORE表示的是下划线,它的颜色跟随前景色

然后,我们用gotoxy函数指定光标到(0,0)除位置,打印超链接。

整合1

我们的超链接打印就完成了,整合一下代码。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

HWND hwnd=GetForegroundWindow();
string str="4399小游戏";
const int len=str.size()-1;
bool b=false;

void gotoxy(int x, int y) {				//设置光标位置(行,列)
	COORD pos = {y,x};
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
POINT mouse_pos() {					//鼠标位置(行,列) 
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p={y,x};
	return p; 
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

int main() {
	//----------初始化窗口----------
	system("mode 80,40");
	system("color f0");

	//----------移除快速编辑模式(对于win10用户)----------
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	SetConsoleMode(hStdin, mode);

	//----------打印超链接字幕----------
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hOut,
	                        FOREGROUND_BLUE | 
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
	gotoxy(0,0);
	printf(str.c_str());
	return 0;
}

整合1
运行效果良好,然后我们要开始检测鼠标点击事件。


回到我们刚开始写道的三个函数:

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

POINT mouse_pos() {					//鼠标位置(行,列) 
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p={y,x};
	return p; 
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

我们用key_down函数来检测是否有鼠标点击事件;用press函数来检测鼠标是否在超链接上。

将两个函数结合起来,来检测鼠标是否点击超链接。

//----------检测是否有点击事件----------
while(1) {
	if((hwnd == ::GetForegroundWindow())) {
		if(key_down(VK_LBUTTON)) {
			while(key_down(VK_LBUTTON))Sleep(50);
			if(press(0,0,0,len)) {
				balabala
			}
		}
	}
	Sleep(50);
}

在这里,我们用(hwnd == ::GetForegroundWindow())来判断窗口是否在顶层(不在顶层怎么点?隔着窗口点??),(key_down(VK_LBUTTON))用来检测是否有鼠标左键的点击事件

while(key_down(VK_LBUTTON))Sleep(50);

这一行则是为了等鼠标左键抬起,再执行下面的语句。

if(press(0,0,0,len)) 

再看这一行,当鼠标位置在【(第0行,第0列)到(第0行,第len列)】时(超链接的位置),那么再访问4399的网站。


那么点击了超链接会发生什么呢,添加下面的代码:

system("start www.4399.com");
b=true;

system函数打开www.4399.com,然后将b(是否访问过该超链接)的值设为true

整合2

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

HWND hwnd=GetForegroundWindow();
string str="4399小游戏";
const int len=str.size()-1;
bool b=false;

void gotoxy(int x, int y) {				//设置光标位置(行,列)
	COORD pos = {y,x};
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
POINT mouse_pos() {					//鼠标位置(行,列) 
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p={y,x};
	return p; 
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

int main() {
	//----------初始化窗口----------
	system("mode 80,40");
	system("color f0");

	//----------移除快速编辑模式(对于win10用户)----------
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	SetConsoleMode(hStdin, mode);

	//----------打印超链接字幕----------
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hOut,
	                        FOREGROUND_BLUE | 
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
	gotoxy(0,0);
	printf(str.c_str());

	//----------检测是否有点击事件----------
	while(1) {
		if((hwnd == ::GetForegroundWindow())) {
			if(key_down(VK_LBUTTON)) {
				while(key_down(VK_LBUTTON))Sleep(50);
				if(press(0,0,0,len)) {
					system("start www.4399.com");
					b=true;
				}
			}
		}
		Sleep(50);
	}

	return 0;
}

整合2
在这里插入图片描述
链接成功!


之前我们说过访问过超链接后链接的颜色将变为紫色,那么我们开始吧:

if(b==false) {
	SetConsoleTextAttribute(hOut,
	                        FOREGROUND_BLUE | 
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
} else {
	SetConsoleTextAttribute(hOut,
	                        37|
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
}
gotoxy(0,0);
printf(str.c_str());

如果btrue,那么颜色应该变为紫色,也就是37这里就简写好了),如果bfalse,就照原来那些打印就行了。

整合3

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

HWND hwnd=GetForegroundWindow();
string str="4399小游戏";
const int len=str.size()-1;
bool b=false;

void gotoxy(int x, int y) {				//设置光标位置(行,列)
	COORD pos = {y,x};
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
POINT mouse_pos() {					//鼠标位置(行,列)
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p= {y,x};
	return p;
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

int main() {
	//----------初始化窗口----------
	system("mode 80,40");
	system("color f0");

	//----------移除快速编辑模式(对于win10用户)----------
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	SetConsoleMode(hStdin, mode);

	//----------打印超链接字幕----------
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hOut,
	                        FOREGROUND_BLUE |
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
	gotoxy(0,0);
	printf(str.c_str());

	//----------检测是否有点击事件----------
	while(1) {
		if((hwnd == ::GetForegroundWindow())) {
			if(b==false) {
				SetConsoleTextAttribute(hOut,
				                        FOREGROUND_BLUE |
				                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
				                        COMMON_LVB_UNDERSCORE);
			} else {
				SetConsoleTextAttribute(hOut,
				                        37|
				                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
				                        COMMON_LVB_UNDERSCORE);
			}
			gotoxy(0,0);
			printf(str.c_str());
			if(key_down(VK_LBUTTON)) {
				while(key_down(VK_LBUTTON))Sleep(50);
				if(press(0,0,0,len)) {
					system("start www.4399.com");
					b=true;
				}
			}
		}
		Sleep(50);
	}

	return 0;
}

整合3
好了,现在超链接是紫色的了,表示我们已经访问了这个网站,完成!


3.完善超链接

什么,你以为这就结束了?
OH!NO!no!no!no!

我们的超链接完成了,但是还有一个缺陷,当将鼠标放在超链接上时,我们应该让用户知道他的鼠标移到了这个超链接上。

所以,我们应该让字体出现阴影,我们只需要将——不知道你还记不记得,字体的背景色有个高亮值——高亮取消。

if(press(0,0,0,len)) {
	if(b==false) {
		SetConsoleTextAttribute(hOut,
		                        FOREGROUND_BLUE |
		                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN |
		                        COMMON_LVB_UNDERSCORE);
	} else {
		SetConsoleTextAttribute(hOut,
		                        37|
		                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN |
		                        COMMON_LVB_UNDERSCORE);
	}
	gotoxy(0,0);
	printf(str.c_str());
} else {
	if(b==false) {
		SetConsoleTextAttribute(hOut,
		                        FOREGROUND_BLUE | 
		                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
		                        COMMON_LVB_UNDERSCORE);
	} else {
		SetConsoleTextAttribute(hOut,
		                        37|
		                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
		                        COMMON_LVB_UNDERSCORE);
	}
	gotoxy(0,0);
	printf(str.c_str());
}

整合4 - 大功告成

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

#define key_down(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//检测按键按下

HWND hwnd=GetForegroundWindow();
string str="4399小游戏";
const int len=str.size()-1;
bool b=false;

void gotoxy(int x, int y) {				//设置光标位置(行,列)
	COORD pos = {y,x};
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
POINT mouse_pos() {					//鼠标位置(行,列) 
	CONSOLE_FONT_INFO consoleCurrentFont;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	POINT p;
	GetCursorPos(&p);
	ScreenToClient(hwnd,&p);               //获取鼠标在窗口上的位置
	GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
	int x=p.x/=consoleCurrentFont.dwFontSize.X;
	int y=p.y/=consoleCurrentFont.dwFontSize.Y;
	p={y,x};
	return p; 
}
bool press(int x1,int y1,int x2,int y2) {		//鼠标是否在矩形区域内
	POINT p;
	p=mouse_pos();
	if(p.x>=x1&&p.x<=x2&&p.y>=y1&&p.y<=y2)return true;
	return false;
}

int main() {
	//----------初始化窗口----------
	system("mode 80,40");
	system("color f0");

	//----------移除快速编辑模式(对于win10用户)----------
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	SetConsoleMode(hStdin, mode);

	//----------打印超链接字幕----------
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hOut,
	                        FOREGROUND_BLUE | 
	                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
	                        COMMON_LVB_UNDERSCORE);
	gotoxy(0,0);
	printf(str.c_str());

	//----------检测是否有点击事件----------
	while(1) {
		if((hwnd == ::GetForegroundWindow())) {
			if(press(0,0,0,len)) {
				if(b==false) {
					SetConsoleTextAttribute(hOut,
					                        FOREGROUND_BLUE |
					                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN |
					                        COMMON_LVB_UNDERSCORE);
				} else {
					SetConsoleTextAttribute(hOut,
					                        37|
					                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN |
					                        COMMON_LVB_UNDERSCORE);
				}
				gotoxy(0,0);
				printf(str.c_str());
			} else {
				if(b==false) {
					SetConsoleTextAttribute(hOut,
					                        FOREGROUND_BLUE | 
					                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
					                        COMMON_LVB_UNDERSCORE);
				} else {
					SetConsoleTextAttribute(hOut,
					                        37|
					                        BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY |
					                        COMMON_LVB_UNDERSCORE);
				}
				gotoxy(0,0);
				printf(str.c_str());
			}
			if(key_down(VK_LBUTTON)) {
				while(key_down(VK_LBUTTON))Sleep(50);
				if(press(0,0,0,len)) {
					system("start www.4399.com");
					b=true;
				}
			}
		}
		Sleep(50);
	}

	return 0;
}

整合4
完美!

4.小结

现在我们的超链接完成了,这次我们运用了很多C++控制台游戏编程的基本函数,想了解更多就关注我吧。本章到此就告一段落了,再见!
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值