Win32 API 光标隐藏定位和键盘读取等常用函数
- 一、Win32 API
- 二、控制台程序指令
- mode
- title
- pause
- cls
- 三、控制台屏幕上坐标的结构体COORD
- 四、句柄获取函数GetStdHandle
- 五、控制台光标操作
- 1.控制台光标信息结构体CONSOLE_CURSOR_INFO
- 2.得到光标信息函数GetConsoleCursorInfo
- 3. 设置光标信息函数SetConsoleCursorInfo
- 4. 设置光标位置函数SetConsoleCursorPosition
- 六、键盘读取函数GetAsyncKeyState
以下代码使用的是 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 |