常用Win32 API的简单介绍

news2025/2/25 18:34:29

目录

前言:

控制控制台程序窗口的指令:

system函数:

COORD函数:

GetStdHandle函数:

GetConsoleCursorInfo函数:

CONSOLE_CURSOR_INFO函数:

SetConsoleCursorInfo函数:

SetConsoleCursorPosition函数:

GetAsyncKeyState函数:

 实例:监控部分键盘按键的使用

小拓展:


前言:

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

本篇介绍的API主要针对下一篇贪吃蛇项目中用到的API

控制控制台程序窗口的指令:

        平常我们win+R输入cmd后运⾏起来的⿊框程序其实就是控制台程序,我们可以通过一些命令实现对控制台程序实现一些简单的更改:
//更改窗⼝的⻓宽
mode con cols= 100 lines= 30
//更改窗⼝的名字
title 改名字
那么我们该怎样在VS2022编译环境下使用这些命令呢?

system函数:

函数原型:int system(const char *command);

command表示要执行的命令,该命令将由操作系统的控制台程序进行分析和执行

包含头文件:<stdlib.h>

作用:在编译器环境下实现对操作系统的控制台程序的相关操作

(先了解,具体使用会在后续的贪吃蛇项目中实现)


COORD函数:

函数原型:

typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD, *PCOORD;

包含头文件:<windows.h>

作用:表示⼀个字符在控制台屏幕上的坐标

//给结构体类型的变量pos赋值:
COORD pos = { 10 , 15 }; //这的确是给结构体类型变量赋值的正确方式哈

GetStdHandle函数:

函数原型:HANDLE GetStdHandle(DWORD nStdHandle);

包含头文件:<windows.h>

作用:从⼀个特定的标准设备中获取(标准输⼊、标准输出或标准错误)中取得⼀个句柄,有了该句柄就有了对该设备输入、输出或错误进行修改的权限

①HANDLE是一个结构体类型的指针

DWORD nStdHandle用于指定要获取的标准设备的类型,常用的标准设备类型包括:

        STD_INPUT_HANDLE:标准输入设备

        STD_OUTPUT_HANDLE:标准输出设备

        STD_ERROR_HANDLE:标准错误设备

③函数的返回值是一个句柄,有了它你就获取了对于以上三种设备的操作权限,至于获取权限后可以干什么就得看你的需求了,我们在下面获得了控制台程序的标准输出设备的权限后可以利用GetConsoleCursorInfo函数对光标信息进行控制

一旦你获得了某个标准设备的权限,就可以根据个人需求选择适当的函数或方法来执行一些操作

有了某个权限后只能用来执行它这个权限规定范围内的操作 

(比如我允许你在我电脑上玩游戏之类的但你不能更改我电脑的相关配置,我没给你这个权限) 

如果你还不懂,往下看后面有对该函数的使用案例

// 获取标准输出的句柄hOutput(有了它你就有了操作修改台光标信息等的权限)
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

GetConsoleCursorInfo函数:

函数原型:
BOOL  WINAPI  GetConsoleCursorInfo {
HANDLE hConsoleOutput ,
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
};
包含头文件:<windows.h>
作用:利用获取的控制台输出句柄hConsoleOutput来控制光标lpConsoleCursorInfo:指向CONSOLE_CURSOR_INFO结构体的指针,用于接收光标的信息)(想要控制还得用下面这个函数)

CONSOLE_CURSOR_INFO函数:

函数原型:

typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize
BOOL bVisible
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

包含头文件:<windows.h>

作用:控制光标的大小dwise(取值范围为1到100之间的百分比)和是否可见vVisible (TRUE表示可见,FALSE表示不可见,默认可见)


//GetConsoleCursorInfo函数需要与CONSOLE_CURSOR_INFO函数配合使用:
hOutput = GetStdHandle (STD_OUTPUT_HANDLE);  //获得标准输出设备的句柄
CONSOLE_CURSOR_INFO CursorInfo;          //定义结构体类型变量     
GetConsoleCursorInfo (hOutput, &CursorInfo); //获取当前光标信息(让系统知道)
CursorInfo.dwSize=50; //然后才能利用CursorInfo修改光标信息

SetConsoleCursorInfo函数:

函数原型:
BOOL WINAPI SetConsoleCursorInfo {
HANDLE hConsoleOutput ,
const CONSOLE_CURSOR_INFO * lpConsoleCursorInfo
};
包含头文件:<windows.h>
作用:显示修改后的光标信息
!!!这里是上面四个函数的整体配合方式:
//操作光标的全部流程
HANDLE hOutput = GetStdHandle (STD_OUTPUT_HANDLE); //获取权限
CONSOLE_CURSOR_INFO CursorInfo; //定义结构体类型变量
GetConsoleCursorInfo (hOutput, &CursorInfo); // 获取控制台光标信息
CursorInfo.bVisible = false ; // 隐藏控制台光标
SetConsoleCursorInfo (hOutput, &CursorInfo); // 设置控制台光标状态

SetConsoleCursorPosition函数:

函数原型:
BOOL WINAPI SetConsoleCursorPosition {
HANDLE hConsoleOutput ,
COORD pos
};

包含头文件:<windows.h>

作用:将光标位置设置到指定的位置

COORD pos = { 10 , 5 };
// 获取标准输出的句柄
HANDLE hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
// 设置标准输出上光标的位置为 pos
SetConsoleCursorPosition (hOutput, pos);
为了便于设置光标的位置我们会 自定义 一个 SetPos函数 ,它的使用方式如下
// 设置光标的坐标
void SetPos ( short x, short y)
{
COORD pos = { x, y };
// 获取标准输出的句柄 ( ⽤来标识不同设备的数值 )
HANDLE hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
// 设置标准输出上光标的位置为 pos
SetConsoleCursorPosition (hOutput, pos);
}
#include <stdio.h>
#include <windows.h>
#include <stdbool.h> 
int main()
{
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//获取权限
	COORD pos = { 5,20 };
	SetConsoleCursorPosition(hOutput, pos);
	int ch = getchar();
	putchar(ch);
	return 0;
}

可以看到初始输入(初始光标)的坐标已经从x=0,y=0变为了x=5,y=20... 


GetAsyncKeyState函数:

函数原型:
SHORT GetAsyncKeyState (
int vKey
);
包含头文件:<windows.h>
作用:监控按键使用(按下/弹起)情况
详细作用:GetAsyncKeyState 的返回值是short类型,在上⼀次调⽤ GetAsyncKeyState 函数后,如果 返回的16位的short数据中,最⾼位是1,说明按键的状态是按下,如果最⾼是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0
//如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1
# define KEY_PRESS(VK)  ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

 实例:监控部分键盘按键的使用

#include <stdio.h>
#include <windows.h>
//PRESS_KET 来检测vk这些虚拟键值对应的按键是否被按过
//如果按过返回1,未按过返回0
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)
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;
}

        注意这里只能对主键盘(有字母的那个)中的数字按键进行监控,对于小键盘中的数字键,该函数并不能直接检测到其按下

小拓展:

        小键盘中的数字键实际上是通过发送键盘消息的方式来模拟的,而不是直接映射为键盘扫描码。因此,GetAsyncKeyState() 函数无法直接检测小键盘中的数字键,如果你想要检测小键盘中的数字键是否被按下,可以使用以下方法之一:

        使用 GetKeyState() 函数:GetKeyState() 函数可以检测指定虚拟键的状态,包括小键盘中的数字键。你可以传递小键盘数字键对应的虚拟键码(如 VK_NUMPAD0VK_NUMPAD1 等)作为参数,然后检查返回值的最高位是否被设置(表示按键被按下)。

#include <stdio.h>
#include <windows.h>
//PRESS_KET 来检测vk这些虚拟键值对应的按键是否被按过
//如果按过返回1,未按过返回0
#define KEY_PRES(VK) ((GetKeyState(VK) & 0x8000) ? 1 : 0)
int main()
{
	while (1)
	{
		if (KEY_PRESS(0x60))
		{
			printf("0\n");
		}
		else if (KEY_PRESS(0x61))
		{
			printf("1\n");
		}
		else if (KEY_PRESS(0x62))
		{
			printf("2\n");
		}
		else if (KEY_PRESS(0x63))
		{
			printf("3\n");
		}
		else if (KEY_PRESS(0x64))
		{
			printf("4\n");
		}
		else if (KEY_PRESS(0x65))
		{
			printf("5\n");
		}
		else if (KEY_PRESS(0x66))
		{
			printf("6\n");
		}
		else if (KEY_PRESS(0x67))
		{
			printf("7\n");
		}
		else if (KEY_PRESS(0x68))
		{
			printf("8\n");
		}
		else if (KEY_PRESS(0x69))
		{
			printf("9\n");
		}
	}
	return 0;
}

~over~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一条监视仪表的小需求,挖掘出定制大市场

作为安防圈内人士&#xff0c;你有没有想过&#xff0c;日常遇到的一条小小客户需求&#xff0c;也许有企业能通过深度定制&#xff0c;在短时间内快速达成且具有极高的性价比&#xff0c;并由此给你带来一个稳定收益的商机&#xff1f;山东的马先生作为一名资深的安防人&#…

【RocketMQ系列十二】RocketMQ集群核心概念之主从复制生产者负载均衡策略消费者负载均衡策略

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

秋季期中考复现xj

flow analysis 1 What is the backdoor file name that comes with the server?( Including file suffix) 服务器自带的后门文件是什么&#xff1f;&#xff08;含文件后缀&#xff09; 题目还要求最后把那个文件名MD5一下&#xff0c;再去提交 开始的前三题是流量分析的&…

操作系统学习——第一类R/W问题和第二类R/W问题

一、First Reader/Writer问题 访问时 结束时 这里因为在第一类读写问题里面Reader可以同时操作&#xff0c;所以在最后一个Reader结束的时刻一定没有其他Reader了 二、Second Reader/Writer问题 第二类问题遵循Writer优先原则&#xff0c;只要存在Writer操作就执行读操作

TTS | 轻量级VITS2的项目实现以及API设置

本文主要是实现了MB-iSTFT-VITS2语音合成模型的训练&#xff0c;相比于VITS模型&#xff0c;MB-iSTFT-VITS模型相对来说会小一点&#xff0c;最重要的是在合成结果来看&#xff0c;MB-iSTFT-VITS模型推理更快&#xff0c;更加自然&#xff08;个人经验&#xff09;.项目地址如下…

冒泡排序:了解原理与实现

目录 原理 实现 性能分析 结论 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单但效率较低的排序算法。它重复地比较相邻的元素并交换位置&#xff0c;直到整个序列有序为止。虽然冒泡排序的时间复杂度较高&#xff0c;但在小规模数据集上仍然具有一定的实际应用价…

Unity 通过jar包形式接入讯飞星火SDK

最近工作上遇到了要接入gpt相关内容的需求&#xff0c;简单实现了一个安卓端接入讯飞星火的UnitySDK。 或者也可以接入WebSocket接口的。本文只讲安卓实现 我使用的Unity版本为2021.3.27f1c2 Android版本为4.2.2 1.下载SDK 登陆讯飞开放平台下载如图所示SDK 2.新建安卓工程…

【Tensorflow 2.12 简单智能商城商品推荐系统搭建】

Tensorflow 2.12 简单智能商城商品推荐系统搭建 前言架构数据召回排序部署调用结尾 前言 基于 Tensorflow 2.12 搭建一个简单的智能商城商品推荐系统demo~ 主要包含6个部分&#xff0c;首先是简单介绍系统架构&#xff0c;接着是训练数据收集、处理&#xff0c;然后是召回模型、…

一个小的图文编辑软件 -- 采用winform开发

本人用winform开发了一款图文编辑软件&#xff0c;实现了图片、文字、图形混合排版; 可以对图元调整大小、设置角度、添加剪切区间等操作。本人以前也写过一款类似的软件《WinForm版图像编辑小程序》&#xff1b; 最近几年&#xff0c;本人一直从事图形处理方面的开发&#xff…

雷达开发的基本概念fft,cfar,以及Clutter, CFAR,AoA

CFAR Constant False-Alarm Rate的缩写。在雷达信号检测中&#xff0c;当外界干扰强度变化时&#xff0c;雷达能自动调整其灵敏度&#xff0c;使雷达的虚警概率保持不变。具有这种特性的接收机称为恒虚警接收机。雷达信号的检测总是在干扰背景下进行的&#xff0c;这些干扰包括…

SAP PO/PI 设置字段或静态参数到URL

文章目录 需求一、字段内容设置到URL中二、使用静态值三、测试总结 需求 通过PO/PI访问第三方接口并把字段或静态参数设置在URL中 一、字段内容设置到URL中 首先我们在MassageMapping中需要把字段内容发送到DynamicConfiguration中去&#xff0c;利用UDF UDF代码 这里面需要…

编译工具链 之一 基本概念、组成部分、编译过程、命名规则

编译工具链将程序源代码翻译成可以在计算机上运行的可执行程序。编译过程是由一系列的步骤组成的&#xff0c;每一个步骤都有一个对应的工具。这些工具紧密地工作在一起&#xff0c;前一个工具的输出是后一个工具的输入&#xff0c;像一根链条一样&#xff0c;我们称这一系列工…

【汇编】第一个汇编程序(学习笔记)

一、程序从编写到执行的过程 1、编写 Notepad / UltraEdit 汇编语言 2、编译、连接 MASM.EXE&#xff1a;编译产生目标文件 LINK.EXE&#xff1a;连接&#xff0c;产生可执行文件 连接作用&#xff1a;源程序分为多个子程序编译后&#xff0c;连接在一起。或程序调用其他…

【JavaEE】网络编程---UDP数据报套接字编程

一、UDP数据报套接字编程 1.1 DatagramSocket API DatagramSocket 是UDP Socket&#xff0c;用于发送和接收UDP数据报。 DatagramSocket 构造方法&#xff1a; DatagramSocket 方法&#xff1a; 1.2 DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。…

SQL查询优化---单表使用索引及常见索引失效优化

如何避免索引失效 1、全值匹配 系统中经常出现的sql语句如下&#xff1a; EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 and deptid4EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 and dept…

美团真题解析

文章目录 &#x1f31f; 美团真题解析&#x1f34a; 美团面试真题-美团招聘简介&#x1f34a; 美团面试真题-介绍一下MyBatis的缓存机制&#x1f389; 一级缓存&#x1f389; 二级缓存 &#x1f34a; 美团面试真题-谈谈jvm的内存模型&#x1f34a; 美团面试真题-谈谈你知道的垃…

手写 Promise(1)核心功能的实现

一&#xff1a;什么是 Promise Promise 是异步编程的一种解决方案&#xff0c;其实是一个构造函数&#xff0c;自己身上有all、reject、resolve这几个方法&#xff0c;原型上有then、catch等方法。 Promise对象有以下两个特点。 &#xff08;1&#xff09;对象的状态不受…

[SQL开发笔记]WHERE子句 : 用于提取满足指定条件的记录

SELECT DISTINCT语句用户返回列表的唯一值&#xff1a;这是一个很特定的条件&#xff0c;假设我需要考虑很多中限制条件进行查询呢&#xff1f;这时我们就可以使用WHERE子句进行条件的限定 一、功能描述&#xff1a; WHERE子句用于提取满足指定条件的记录&#xff1b; 二、WH…

nginx快速部署一个网站服务 + 多域名 + 多端口

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

C#,数值计算——分类与推理Phylo_slc的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_slc : Phylagglom { public override void premin(double[,] d, int[] nextp) { } public override double dminfn(double[…