Win32 API 光标隐藏定位和键盘读取等常用函数

发布于:2024-04-28 ⋅ 阅读:(23) ⋅ 点赞:(0)


以下代码使用的是 VS2022环境的C语言

一、Win32 API

Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是⼀个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows 32位平台的应用程序编程接口。

二、控制台程序指令

平常我们运行起来的黑框程序其实就是控制台程序

mode

可以使用cmd命令来设置控制台窗口的长宽:设置控制台窗口的大小,30行,100列

mode con cols=100 lines=30

参考:mode

title

通过命令设置控制台窗口的名字:

title 贪吃蛇

参考:title

这些能在控制台窗口执行的命令,也可以调用C语言函数system来执行。例如:

#include <stdio.h>
int main()
{
	 //设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列
	 system("mode con cols=100 lines=30");
	 //设置cmd窗⼝名称
	 system("title 贪吃蛇"); 
	 return 0;
}

pause

暂停批处理程序的处理,显示提示,Press any key to continue . . .

pause

参考:pause

cls

可以刷新控制台窗口

cls

参考:cls

三、控制台屏幕上坐标的结构体COORD

COORD 是Windows API中定义的⼀个结构体,表示一个字符在控制台屏幕幕缓冲区上的坐标,坐标系(0,0) 的原点位于缓冲区的顶部左侧单元格。
在这里插入图片描述
COORD类型的声明:

typedef struct _COORD {
 SHORT X;			// x坐标
 SHORT Y;			// y坐标
} COORD, *PCOORD;

给坐标赋值:

COORD pos = { 10, 15 };

参考:COORD

四、句柄获取函数GetStdHandle

GetStdHandle是一个Windows API函数。它用于从一个特定的标准设备(标准输入、标准输出或标准错误)中取得一个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。

HANDLE GetStdHandle(DWORD nStdHandle);		// 标准设备值

参考:GetStdHandle

五、控制台光标操作

1.控制台光标信息结构体CONSOLE_CURSOR_INFO

CONSOLE_CURSOR_INFO 是Windows API中定义的⼀个结构体。表示光标在控制台中的信息。
• dwSize,由光标填充的字符单元格的百分比。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的水平线条。
• bVisible,游标的可见性。 如果光标可见,则此成员为 TRUE。

typedef struct _CONSOLE_CURSOR_INFO {
  DWORD dwSize;				// 光标填充的当前字符单元的百分比
  BOOL  bVisible;			// 光标是否可见
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

参考:CONSOLE_CURSOR_INFO

2.得到光标信息函数GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息

BOOL WINAPI GetConsoleCursorInfo(
 HANDLE hConsoleOutput,							// 获得当前控制台句柄
 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo		// 光标信息结构体的指针
);

参考:GetConsoleCursorInfo

实例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

3. 设置光标信息函数SetConsoleCursorInfo

设置指定控制台屏幕缓冲区的光标的大小和可见性

BOOL WINAPI SetConsoleCursorInfo(
 HANDLE hConsoleOutput,
 const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

参考:SetConsoleCursorInfo

实例:

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

4. 设置光标位置函数SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。

BOOL WINAPI SetConsoleCursorPosition(
 HANDLE hConsoleOutput,
 COORD pos
);

参考:SetConsoleCursorPosition

实例:

 COORD pos = { 10, 5};
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos)

SetPos:封装一个设置光标位置的函数

//设置光标的坐标
void SetPos(short x, short y)
{
	 COORD pos = { x, y };
	 HANDLE hOutput = NULL;
	 //获取标准输出的句柄(⽤来标识不同设备的数值)
	 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	 //设置标准输出上光标的位置为pos
	 SetConsoleCursorPosition(hOutput, pos);
}

六、键盘读取函数GetAsyncKeyState

获取按键情况,GetAsyncKeyState的函数原型如下:

SHORT GetAsyncKeyState(
 int vKey
);

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。

GetAsyncKeyState 的返回值是short类型,在上⼀次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中,最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。

如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1。

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)

参考:虚拟键码(Winuser.h) - Win32 apps

实例:

#include <stdio.h>
#include <windows.h>
int main()
{ 
	 while (1)
	 {
		 if (KEY_PRESS(0x30))
		 {
		 	printf("0\n");	
		 }
		 else if (KEY_PRESS(0x31))
		 {
		 	printf("1\n");
		 }
		 else if (KEY_PRESS(0x32))
		 {
		 	printf("2\n");
		 }
		 else if (KEY_PRESS(0x33))
		 {
		 	printf("3\n");
		 }
		 else if (KEY_PRESS(0x34))
		 {
		 	printf("4\n");
		 }
		 else if (KEY_PRESS(0x35))
		 {
		 	printf("5\n");
		 }
		 else if (KEY_PRESS(0x36))
		 {
		 	printf("6\n");
		 }
		 else if (KEY_PRESS(0x37))
		 {
		 	printf("7\n");
		 }
		 else if (KEY_PRESS(0x38))
		 {
		 	printf("8\n");
		 }
		 else if (KEY_PRESS(0x39))
		 {
		 	printf("9\n");
		 }
	 }
	 return 0;
}

当然,有一些常见的虚拟键码需要留意一下:

常见的虚拟键码 对应define常数
ESC 键 VK_ESCAPE 0x1B
空格键 VK_SPACE 0x20
UP ARROW 键 (上方向键:↑) VK_UP 0x26
DOWN ARROW 键 (下方向键:↓) VK_DOWN 0x28
LEFT ARROW 键 (左方向键:←) VK_LEFT 0x25
RIGHT ARROW 键 (右方向键:→) VK_RIGHT 0x27

网站公告

今日签到

点亮在社区的每一天
去签到