c语言按键监听函数 c语言监听键盘事件

C语言控制台程序实时监听键盘按键事件输入焦点不在控制台窗口上, 键盘消息不会被控制台窗口接收, 这种情况只有用全局键盘钩子或低级键盘钩子, 全局钩子要写在动态链接库中(DLL文件), 低级键盘钩子可写在本线程中.
c语言能否监听键盘某个按键按了多久你好?。?
能监听键按下,那就在按下的同时,启动定时器,键抬起来的时候,定时器停止,计算定时时间
c语言怎么监听键盘按键在Microsoft Windows 中c语言按键监听函数,键盘和鼠标是两个标准的用户输入源c语言按键监听函数,在一些交叠的操作中通常相互补充使用 。当然,鼠标在今天的应用程序中比10年前使用得更为广泛 。甚至在一些应用程序中 , c语言按键监听函数我们更习惯于使用鼠标,例如在游戏、画图程序、音乐程序,以及Web创览器等程序中就是这样 。然而,我们可以不使用鼠标 , 但绝对不能从一般的PC中拆掉键盘 。
Windows程序获得键盘输入的方式:键盘输入以消息的形式传递给程序的窗口过程 。实际上,第一次学习消息时,键盘就是一个明显的例子:消息应该传递给应用程序的信息类型 。
Windows用8种不同的消息来传递不同的键盘事件 。这好像太多c语言按键监听函数了,但是(就像我们所看到的一样)程序可以忽略其中至少一半的消息而不会有任何问题 。并且,在大多数情况下,这些消息中包含的键盘信息会多于程序所需要的 。处理键盘的部分工作就是识别出哪些消息是重要的,哪些是不重要的 。
键盘基础知识
虽然应用程序在很多情况下可以通过鼠标实现信息的输入,但到现在为止键盘仍然是PC机中不可替代的重要输入设备 。
用键盘当作输入设备,每当用户按下或释放某一个键时,会产生一个中断,该中断激活键盘驱动程序KEYBOARD.DRV来对键盘中断进行处理 。KEYBOARD.DRV程序会根据用户的不同操作进行编码,然后调用Windows用户模块USER.EXE生成键盘消息 , 并将该消息发送到消息队列中等候处理 。
1.扫描码和虚拟码
扫描码对应着键盘上的不同键 , 每一个键被按下或释放时,都会产生一个唯一的扫描码作为本身的标识 。扫描码依赖于具体的硬件设备,即当相同的键被按下或释放时,在不同的机器上可能产生不同的扫描码 。在程序中通常使用由Windows系统定义的与具体设备无关的虚拟码 。在击键产生扫描码的同时,键盘驱动程序KEYBOARD.DRV截取键的扫描码,然后将其翻译成对应的虚拟码 , 再将扫描码和虚拟码一齐编码形成键盘消息 。所以,最后发送到消息队列的键盘消息中 , 既包含了扫描码又包含了虚拟码 。
经常使用的虚拟码在WINDOWS.H文件中定义,常用虚拟码的数值、常量符号和含义如表所示 。
取值(16进制) 常量符号 含义
01 VK_LBUTTON 鼠标左键
02 VK_RBUTTON 鼠标右键
03 VK_CANCEL Break中断键
04 VK_MBUTTON 鼠标中键
05-07 -- 未定义
08 VK_BACK (BackSpace)键
09 VK_TAB Tab键
0A-0B -- 未定义
0C VK_CLEAR Clear键
0D VK_RETURN Enter键
0E-0F -- 未定义
10 VK_SHIFT Shift键
11 VK_CONTROL Ctrl键
12 VK_MENU Alt键
13 VK_PAUSE Pause键
14 VK_CAPTIAL CapsLock键
15-19 -- 汉字系统保留
1A -- 未定义
1B VK_ESCAPE Esc键
1C-1F -- 汉字系统保留
20 VK_SPACE 空格键
21 VK_PRIOR PageUp键
22 VK_NEXT PageDown键
23 VK_END End键
24 VK_HOME Home键
25 VK_LEFT ←(Left Arrow)键
26 VK_UP ↑(Up Arrow)键
27 VK_RIGHT →(Right Arrow)键
28 VK_DOWN ↓(Down Arrow)键
29 VK_SELECT Select键
2A -- OEM保留
2B VK_EXECUTE Execute键
2C VK_SNAPSHOT Print Screen键
2D VK_INSERT Insert键
2E VK_DELETE Delete键
2F VK_HELP Help键
30-39 VK_0-VK_9 数字键0-9
3A-40 -- 未定义
41-5A VK_A-VK_Z 字母键A-Z
5B-5F -- 未定义
60-69 VK_NUMPAD0-VK_NUMPAD9 小键盘数字键0-9
6A VK_MULTIPLY *(乘号)键
6B VK_ADD(加号)键
6C VK_SEPAPATOR 分隔符键
6E VK_SUBTRACT -(减号)键
6F VK_DECIMAL .(小数点)键
70-87 VK_DIVIDE /(除号)键
88-8F VK_F1-VK_F24 F1-F24功能键
90 VK_NUMBERLOCK Number lock键
91 VK_SCROLL Scroll lock键
92-B9 -- 未定义
BA-C0 -- OEM保留
C1-DA -- 未定义
DB_E4 -- OEM保留
E5 -- 未定义
E6 -- OEM保留
E7-E8 -- 未定义
E9-F5 -- OEM保留
F6-FE -- 未定义
2.输入焦点
同一时刻 , Windows中可能有多个不同的程序在运行,也就是说有多个窗口同时存在 。这时,键盘由多个窗口共享,但只有一个窗口能够接收到键盘消息 , 这个能够接收键盘消息的窗口被称为拥有输入焦点的窗口 。
拥有输入焦点的窗口应该是当前的活动窗口,或者是活动窗口的子窗口,其标题和边框会以高亮度显示,以区别于其c语言按键监听函数他窗口 。拥有输入焦点的也可以是图标而不是窗口,此时,Windows也将消息发送给图标,只是消息的格式略有不同 。
窗口过程可以通过发送WM_SETFOCUS和 WM_KILLFOCUS消息使窗体获得或失去输入焦点 。程序也可以通过捕获WM_SETFOCUS和WM_KILLFOCUS消息来判断窗体何时获得或失去输入焦点 。其中WM_SETFOCUS消息表示窗口正获得输入焦点,WM_ KILLFOCUS消息表示窗口正失去输入焦点 。
3.键盘消息
键盘消息分为系统键消息和非系统键消息 。系统键消息是指由Aft键和其他键组合而产生的按键消息 。当系统键被按下时产生WM_ SYSKEYDOWN消息 , 当系统键被释放时产生WM_SYSKEYUP消息 。Aft键与其他键形成的组合键通常用于对程序菜单和系统菜单进行选择,或用于在不同的程序之间进行切换 。因此,系统键消息应该交由Windows进行处理,用户所编制的程序一般不处理系统键消息,而是将这些消息交由DefWindowProc函数进行处理 。如果用户想对系统键消息进行处理,应该在处理完这些消息后,再将其发送给DefWindowProc函数 , 使得Windows系统能够正常工作 。
某些击键消息可以被转换成字符消息 , 例如字母键、数字键等 。而有些键只能产生按键消息而没有字符消息,例如 Shift键、Insert键等 。消息循环中的 TranslateMessage函数可以实现从击键消息向字符消息的转化 。当GetMessage函数捕获一个WM_SYSKEYDOWN消息或 WM_KEYDOWN消息后,TranslateMessage函数判断产生该消息的键是否能够被转换成字符消息,如果能,就将该消息转换成字符消息 , 再通过DispatchMessape函数将转换后的字符消息发送到消息队列中去 。字符消息共有以下四种,如表所示 。
字符 系统字符 非系统字符
普通字符 WM_SYSCHAR WM_CHAR
死字符 WM_SYSDEADCHAR WM_DEADCHAR
其中死字符是由某些特殊键盘上的按键所造成的,Windows一般忽略死字符所产生的消息 。
Windows的消息一般是通过一个MSG结构体变量传送给消息处理函数的 。对于键盘消息 , MSG结构体变量的各个域中较重要的是lParam域和 wParam域 。wParam域用于保存按键的虚拟键代码或字符的ASCII码 。对于非字符消息,wParam域保存按键的虚拟健代码;对于字符消息,wParam域不保存字符的ASCII码 。lParam域则用于保存击键时产生的附加信息,实际上一个32位的lParam变量被分为六部分,记录了以下相关信息:重复次数、OEM扫描码、扩展键标志、关联键标志、前一击键状态和转换状态 。lParam域各位的含义如表所示 。
位数 含义
0-15 击键重复次数累加
16-23 OEM扫描码
24 是否为扩展键
25-28 未定义
29 是否便用关联键,及Alt键是否同时按下 。
30 前一次击键状态,0表示该键前一次状态为抬起,1表示前一次状态为按下
31 转换状态
按键的次序不同,产生的消息也不相同 。例如,按下并释放1键,读过程依次产生如表所示三条消息 。按下1键所产生的消息和wParam的取值
消息 wParam变量取值
WM_KEYDOWN 虚拟码1
WM_CHAR ASCII码“1”
WM_KEYUP 虚拟码1
如果按下Shift键后再按下1键并释放,则依次产生如表所示的消息 。按下 Shift键后按 1健所产生的消息和 wParam的取值
消息 wParam变量取值
WM_KEYDOWN 虚拟码 VK_SHIFT
WM_KEYDOWN 虚拟码 VK_1
WM_CHAR ASCII码 “1”
WM_KEYUP 虚拟码 VK_1
WM_KEYUP 虚拟码 VK_SHIF
键盘应用实例
下面通过一个应用程序实例来说明在实际编程中如何处理键盘消息 。
#include windows.h
#include stdio.h
// 全局变量
RECT rc; //记录滚屏的矩形区域
?
int xChar, yChar; //文本输入点坐标
WNDCLASSEX wnd; //窗口类结构变量
char szAppName[] = "键盘消息监视程序"; //窗口类名
//函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow);
//函数:WinMain
//作用:入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
MSG msg;
if(!MyRegisterClass(hInstance))
{
return FALSE;
}
if(!InitInstance(hInstance,iCmdShow))
{
return FALSE;
}
while (GetMessage (msg, NULL, 0, 0))
{
TranslateMessage (msg);
DispatchMessage (msg);
}
return msg.wParam;
}
//函数:ShowKey
//作用:实现在窗口中显示按键信息
void ShowKey (HWND hwnd, int iType,char *szMessage,WPARAM wParam,LPARAM lParam)
{
static char *szFormat[2] ={"%-14s = %c %6u M %5s %5s %6s %6s",
"%-14s = %c %6u M %5s %5s %6s %6s" };
char szBuffer[80];
HDC hdc;
ScrollWindowEx(hwnd, 0, -yChar, rc,rc,NULL,NULL,SW_INVALIDATE);
hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
TextOut (hdc,
xChar,
rc.bottom - yChar,
szBuffer,
wsprintf szBuffer,
szFormat[iType],
szMessage, //消息
wParam, //虚拟键代码
(BYTE) (iType ? wParam :‘ ’),//显示字符值
LOWORD (lParam), // 重复次数
HIWORD (lParam)0xFF, // OEM键盘扫描码
//判断是否为增强键盘的扩展键
(PSTR) (0x01000000lParam ? “是” : “否”),
//判断是否同时使用了ALT键
(PSTR) (0x20000000lParam ? “是” : “否”),
(PSTR) (0x40000000lParam ? “按下” : “抬”),
//判断前一次击键状
(PSTR)(0x80000000lParam ? “按下” : “抬起”))
//判断转换状态?
);
ReleaseDC (hwnd, hdc); ?
ValidateRect (hwnd, NULL); ?
}
//函数:WndProc
//作用:处理主窗口的消息
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static char szTop[] ="消息键 字符 重复数 扫描码 扩展码 ALT 前一状态 转换状态";
static char szUnd[] ="_______ __ ____ _____ ______ ______ ___ _______ ______";
//在窗口中输出文字作为信息标题
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
switch (iMsg)
{
case WM_CREATE://处理窗口创建的消息
hdc = GetDC (hwnd); //设定字体
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); //检取当前字体的度量数据
GetTextMetrics (hdc, tm);
xChar = tm.tmAveCharWidth;//保存字体平均宽度
yChar = tm.tmHeight; //保存字体高度
ReleaseDC (hwnd, hdc);
rc.top = 3 * yChar / 2;
return 0;
case WM_SIZE://处理窗口大小改变的消息
//窗体改变后保存新的滚屏区域右下角坐标
rc.right = LOWORD (lParam);
rc.bottom = HIWORD (lParam);
UpdateWindow (hwnd);
return 0;
case WM_PAINT: //处理窗口重绘消息
InvalidateRect (hwnd, NULL, TRUE);
hdc = BeginPaint (hwnd, ps);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
SetBkMode (hdc, TRANSPARENT) ;
TextOut (hdc, xChar, yChar / 2, szTop, (sizeof szTop) - 1) ;
TextOut (hdc, xChar, yChar / 2, szUnd, (sizeof szUnd) - 1) ;
EndPaint (hwnd, ps);
return 0;
case WM_KEYDOWN:
//处理键盘上某一键按下的消息
ShowKey (hwnd, 0, "WM_KEYDOWN",wParam, lParam);
return 0;
case WM_KEYUP:
//处理键盘上某一按下键被释放的消息
ShowKey (hwnd, 0, "WM_KEYUP", wParam, lParam);
return 0;
case WM_CHAR:
//处理击键过程中产生的非系统键的可见字符消息
howKey (hwnd, 1, "WM_CHAR", wParam, lParam);
return 0;
case WM_DEADCHAR:
//处理击键过程中产生的非系统键"死字符"消息
ShowKey (hwnd, 1, "WM_DEADCHAR", wParam, lParam);
return 0;
case WM_SYSKEYDOWN:
//处理系统键按下的消息
ShowKey (hwnd, 0, "WM_SYSKEYDOWN",wParam, lParam);
break;
case WM_SYSKEYUP:
//处理系统键抬起的消息
ShowKey (hwnd, 0, "WM_SYSKEYUP", wParam, lParam);
break;
case WM_SYSCHAR://处理系统键可见字符消息
ShowKey (hwnd, 1, "WM_SYSCHAR", wParam, lParam);
break;
case WM_SYSDEADCHAR://处理系统键"死字符"消息
ShowKey (hwnd, 1, "WM_SYSDEADCHAR", wParam, lParam);
break;
case WM_DESTROY:
//处理结束应用程序的消息
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
//函数:MyRegisterClass
//作用:注册窗口类
BOOL MyRegisterClass(HINSTANCE hInstance)
{
wnd.cbSize= sizeof (wnd);
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.lpfnWndProc = WndProc;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon (NULL, IDI_APPLICATION);?
wnd.hCursor = LoadCursor (NULL, IDC_ARROW);
wnd.hbrBackground = (HBRUSH)
GetStockObject (WHITE_BRUSH);
wnd.lpszMenuName = NULL;
wnd.lpszClassName = szAppName;
wnd.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
return RegisterClassEx (wnd);
}
//函数:InitInstance
//作用:创建主窗口
BOOL InitInstance(HINSTANCE hInstance,int iCmdShow)
{
HWND hwnd;
hwnd = CreateWindow (szAppName,
"键盘消息监视程序",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL
);
if(!hwnd)
{
return FALSE;
}
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
return TRUE;
}
c语言键盘监听问题#include stdio.h
#include conio.h
void main() {
while(1) {
printf("\rhello world!");
if(_kbhit()) {
if(_getch() == '\r')
break;
}
}
printf("\n");
}
c语言编写键盘监控器方法键控程序简单事例:#include string.h
#include conio.h
#include stdlib.h
#include dos.h
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
/*======== ALL VAR==============*/
int bleft=10;
int width=52;
int height=20;
/*=========About Location===========*/
typedef struct
{
int x, y;
int xv, yv;
}Location;/*=============About Welcome=============*/
void menu()
{printf("welcom to coming\n");
printf("=======================================================\n");
printf("!In the game please pressESc to quit!!\n");
printf("!Enter the game?(Y/N)!\n");
printf("=======================================================\n");
}
/*=========About border==========*/
void bianjie()
{
int i;
for(i=0;ibleft;i)
printf(" ");
for(i=0;iwidth;i)
{ printf("=");
}
for(i=0;iheight;i)
{ gotoxy(bleft,i);
printf("!");
}
for(i=0;iheight;i)
{ gotoxy(width bleft,i);
printf("!");
}
for(i=1;iwidth;i)
{ gotoxy(bleft i,height-1);
printf("=");
}
}
/*==========About pro things===========
void things()
{
}*/
/*===========About Oprtion=============*/
void zhixing()
{
int i,key;
Location shili;
shili.x=bleft 1;
shili.y=1;
shili.xv=5;
shili.yv=5;
while(1)
{
key=bioskey(0);
if(key==ESC)/**/
break;
else if(key==UP)
{
for(i=0;ishili.yv;i)
{
if(shili.y-shili.yv1)
{
shili.y--;
gotoxy(shili.x,shili.y 1);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {
if(shili.y1)
{
shili.y--;
gotoxy(shili.x,shili.y 1);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {shili.y;
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
gotoxy(shili.x,shili.y-1);
printf(" ");
}
}
}
}
else if(key==DOWN)
{
for(i=0;ishili.yv;i)
{
if(shili.y shili.yvheight)
{
shili.y;
gotoxy(shili.x,shili.y-1);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {
if(shili.yheight)
{
shili.y;
gotoxy(shili.x,shili.y-1);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {shili.y--;
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
gotoxy(shili.x,shili.y 1);
printf(" ");
}
}
}
}
else if(key==LEFT)
{
for(i=0;ishili.xv;i)
{
if(shili.x-shili.xvbleft)
{
shili.x--;
gotoxy(shili.x 1,shili.y);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {
if(shili.xbleft)
{
shili.x--;
gotoxy(shili.x 1,shili.y);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {shili.x;
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
gotoxy(shili.x-1,shili.y);
printf(" ");
}
}
}
}
else if(key==RIGHT)
{
for(i=0;ishili.xv;i)
{
if(shili.x shili.xvwidth bleft)
{
shili.x;
gotoxy(shili.x-1,shili.y);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {
if(shili.xwidth bleft)
{
shili.x;
gotoxy(shili.x-1,shili.y);
printf(" ");
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
}
else {shili.x--;
gotoxy(shili.x,shili.y);
printf("%c\b", 2);
gotoxy(shili.x 1,shili.y);
printf(" ");
}
}
}
}
}}
/**********************************/
void main()
{ char ch;
clrscr();
menu();
ch=getch();
if(ch=='N'||ch=='n')
return;
else if(ch=='Y'||ch=='y')
{ clrscr();
bianjie();
zhixing();
}
}C语言获取键值函数事例:/*函数名称:bioskey
函数原型:int bioskey(int cmd)
函数功能:读取键盘值
函数返回:cmd=0:返回一个键盘值(ascii值放在低位,扫描码放在高位),若无按键,一直等
cmd=1:查询键盘是否按下:0-无键按下 , 非0-有键按下
cmd=2:返回控制键状态,返回值保存在低8位中
0-右边的shift键按下 5-已打开Scroll_Lock
1-左边的shift键按下 6-已打开Num_Lock
3-Ctrl键按下 7-已打开Caps_Lock
4-Alt键按下 8-已打开Insert
【c语言按键监听函数 c语言监听键盘事件】参数说明:
所属文件:bios.h*/
#include stdio.h
#include bios.h
#include ctype.h
int main()
{
int key, shift;
int lastshift;
while (1)
{
shift=bioskey(2);
if(shift!=lastshift)
printf("Shift=0x% 02x\n",shift);
if(bioskey(1))
{
key=bioskey(0);
if((key0xFF)=='q')
break;
printf("Key=0x% 04x",key);
}
lastshift=shift;
}
return 0;
}文件存在性判断事例:#include stdio.h
#include io.h
int file_exists(char *filename);
int main()
{
printf("Does myfile.FIL exist: %s",file_exists("myfile.FIL") ? "YES" : "NO");
getch();
return 0;
}
int file_exists(char *filename)
{
return (access(filename,0)==0);
} 如还有疑问 , 请追加!
如何在linux下用c语言实现对键盘的监听自己写函数
#include stdio.h
#include termios.h
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard(void);
void close_keyboard(void);
int kbhit(void);
int readch(void);
void init_keyboard()
{
tcgetattr(0,initial_settings);
new_settings = initial_settings;
new_settings.c_lflag |= ICANON;
new_settings.c_lflag |= ECHO;
new_settings.c_lflag |= ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, initial_settings);
}
int kbhit()
{
unsigned char ch;
int nread;
if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, new_settings);
nread = read(0,ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int readch()
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,ch,1);
return ch;
}
int main()
{
init_keyboard();
while(1)
{
kbhit();
printf("\n%d\n", readch());
}
close_keyboard();
return 0;
}
关于c语言按键监听函数和c语言监听键盘事件的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读