c語言按鍵監聽,c語言檢測按鍵

本文目錄一覽:

c語言鍵盤監聽問題

#include stdio.h

#include conio.h

void main() {

while(1) {

printf(“\r                   hello world!”);

if(_kbhit()) {

if(_getch() == ‘\r’)

break;

}

}

printf(“\n”);

}

c語言 如何一直監聽某個鍵是否按下?

看這樣能不能達到效果

while (1)

{

    Sleep(100);//防止CPU消耗太多,每100毫秒才檢測一下

    while (kbhit()){

        char ch = getch();

        if (ch==你所說的鍵)

        {

        //…

        }

    }

}

要求Windows環境

要求#include conio.h

#include Windows.h

C語言控制台程序實時監聽鍵盤按鍵事件

輸入焦點不在控制台窗口上, 鍵盤消息不會被控制台窗口接收, 這種情況只有用全局鍵盤鉤子或低級鍵盤鉤子, 全局鉤子要寫在動態鏈接庫中(DLL文件), 低級鍵盤鉤子可寫在本線程中.

c語言怎麼監聽鍵盤按鍵

在Microsoft Windows 中,鍵盤和鼠標是兩個標準的用戶輸入源,在一些交疊的操作中通常相互補充使用。當然,鼠標在今天的應用程序中比10年前使用得更為廣泛。甚至在一些應用程序中,我們更習慣於使用鼠標,例如在遊戲、畫圖程序、音樂程序,以及Web創覽器等程序中就是這樣。然而,我們可以不使用鼠標,但絕對不能從一般的PC中拆掉鍵盤。

Windows程序獲得鍵盤輸入的方式:鍵盤輸入以消息的形式傳遞給程序的窗口過程。實際上,第一次學習消息時,鍵盤就是一個明顯的例子:消息應該傳遞給應用程序的信息類型。

Windows用8種不同的消息來傳遞不同的鍵盤事件。這好像太多了,但是(就像我們所看到的一樣)程序可以忽略其中至少一半的消息而不會有任何問題。並且,在大多數情況下,這些消息中包含的鍵盤信息會多於程序所需要的。處理鍵盤的部分工作就是識別出哪些消息是重要的,哪些是不重要的。

鍵盤基礎知識

雖然應用程序在很多情況下可以通過鼠標實現信息的輸入,但到現在為止鍵盤仍然是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中可能有多個不同的程序在運行,也就是說有多個窗口同時存在。這時,鍵盤由多個窗口共享,但只有一個窗口能夠接收到鍵盤消息,這個能夠接收鍵盤消息的窗口被稱為擁有輸入焦點的窗口。

擁有輸入焦點的窗口應該是當前的活動窗口,或者是活動窗口的子窗口,其標題和邊框會以高亮度顯示,以區別於其他窗口。擁有輸入焦點的也可以是圖標而不是窗口,此時,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 %3d %c %6u %4d %5s %5s %6s %6s”,

  “%-14s %3d %c %6u %4d %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) (0x01000000  lParam ? “是” : “否”),

 //判斷是否同時使用了ALT鍵

 (PSTR) (0x20000000  lParam ? “是” : “否”),

 (PSTR) (0x40000000  lParam ? “按下” : “抬”),

 //判斷前一次擊鍵狀

 (PSTR)(0x80000000  lParam ? “按下” : “抬起”))

 //判斷轉換狀態?

 );

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語言,監聽虛擬鍵的方法為什麼不直接用getchar接收,然後用==判斷是不是某個鍵,這樣不就好

getchar 會阻斷線程.不方便.所謂監聽.一般必須是掛在系統鍵盤消息的響應函數上.在系統分發KEYDOWN消息時,探測當前按下的key的code是不是自己想要的..

所以getchar肯定是不行了.

如何在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;  

}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/295848.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-27 12:57
下一篇 2024-12-27 12:57

相關推薦

  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python語言設計基礎第2版PDF

    Python語言設計基礎第2版PDF是一本介紹Python編程語言的經典教材。本篇文章將從多個方面對該教材進行詳細的闡述和介紹。 一、基礎知識 本教材中介紹了Python編程語言的…

    編程 2025-04-28
  • Python語言實現人名最多數統計

    本文將從幾個方面詳細介紹Python語言實現人名最多數統計的方法和應用。 一、Python實現人名最多數統計的基礎 1、首先,我們需要了解Python語言的一些基礎知識,如列表、字…

    編程 2025-04-28
  • Python作為中心語言,在編程中取代C語言的優勢和挑戰

    Python一直以其簡單易懂的語法和高效的編碼環境而著名。然而,它最近的發展趨勢表明Python的使用範圍已經從腳本語言擴展到了從Web應用到機器學習等廣泛的開發領域。與此同時,C…

    編程 2025-04-28
  • Python基礎語言

    Python作為一種高級編程語言擁有簡潔優雅的語法。在本文中,我們將從多個方面探究Python基礎語言的特點以及使用技巧。 一、數據類型 Python基礎數據類型包括整數、浮點數、…

    編程 2025-04-28

發表回復

登錄後才能評論