【C++】禁用/啟用筆記本鍵盤工具(含源碼)


前言

之所以寫這個程序,是因為宿舍桌子太小。有時把外接鍵盤疊在筆記本鍵盤上,容易誤觸到筆記本鍵盤:

fck
從而導致一些莫名其妙的問題困擾自己。
於是找了些資料了解到了如何禁用筆記本鍵盤的方法:

+ 禁用設備法。詳細教程請點擊**[`這里`](https://jingyan.baidu.com/article/77b8dc7fb9aa336175eab674.html)**
+ 修改注冊表法。詳細教程請點擊**[`這里`](https://www.52pojie.cn/thread-1445700-1-2.html)**

可能會有人問:為什么不省事點選用禁用設備法,而是寫代碼再來操作注冊表,來禁用鍵盤這么麻煩的方法呢?原因很簡單,我突然對編程語言操作注冊表很感興趣,就這么做了。

簡單介紹注冊表

**
注冊表結構類似文件目錄:分為根鍵、子鍵和鍵值項三部分,與文件目錄對應的話就是根目錄、子目錄和文件。簡單介紹一下這三部分:**

(1)根鍵

分為5個:HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_USERS和HKEY_CURRENT_CONFIG

(2)子鍵

可以有多個子鍵和鍵值項,就像一個目錄中可以有多個子目錄和多個文件一樣。

(3)鍵值項

**可以理解為文件,它由三部分組成,分別為 :名稱、類型、數據。其中類型主要有:
REG_BINARY 二進制數據
REG_DWORD 32位雙字節數據
REG_SZ 以0結尾的字符串
REG_DWORD_BIG_ENDIAN 高位排在底位的雙字
REG_EXPAND_SZ 擴展字符串,可以加入變量如%PATH%
REG_LINK UNICODE 符號鏈接
REG_RESOURCE_LIST 設備驅動程序資源列表
REG_MULTI_SZ 多字符串
注冊表數據項的數據類型有8種,最常用的是前3種。

操作注冊表的幾個API函數

**需要頭文件:atlbase.h **

(1)打開一個鍵

RegOpenKeyEx
函數定義:LONG RegOpenKeyEx(HKEY hKey,//已經打開的鍵的句柄,或者直接是上述幾個根鍵

                              LPCTSTR lpSubKey,//要打開的子鍵名字的地址

                              DWORD ulOptions,//保留值,必須為0

                              REGSAM samDesired,//打開方式,如讀還是寫

                              PHKEY phkResult//返回的打開的子鍵的句柄

                               );

(2)查詢某一個鍵值

RegQueryValueEx

    函數定義:LONG RegQueryValueEx(HKEY hKey,//要查詢的鍵的句柄

                                   LPCTSTR lpValueName,//要查詢的鍵值的名稱

                                   LPDWORD lpReserved,//保留值

                                   LPDWORD lpType,//要查詢的數據的類型

                                   LPBYTE lpData,//要返回的查詢的數據

                                   LPDWORD lpcbData//預置的數據的長度

                                  );

(3)設置一個鍵值

RegSetValueEx

    函數定義:LONG RegSetValueEx(HKEY hKey,//要設置的鍵的句柄

                                 LPCTSTR lpValueName,//要訪問的鍵值的名稱

                                 LPDWORD lpReserved,//保留值

                                 DWORD dwType,//要設置的數據的類型

                                 const BYTE *lpData,//要設置的健值

                                 DWORD cbData//數據的長度

                                );

(4)新建指定鍵

RegCreateKey

函數定義:LONG RegCreateKey (HKEY  hkey, // 要打開鍵的句柄

LPCTSTR lpsubkey, // 要打開子鍵的名字的地址

PHKEY phkresult // 已打開句柄的緩存區的地址

);

(5)刪除注冊表指定鍵下的值

LONG RegDeleteValue(HKEY hKey,            //子鍵的句柄
LPCTSTR lpValueName  //刪除鍵值的名稱
);

(5.2)刪除注冊表項

LONG RegDeleteKey(HKEY hKey,        //已打開的鍵的句柄

LPCTSTR lpSubKey //要刪除的子鍵或路徑

);

RegDeleteKey 也可用來刪除一個鍵值。在 Win 95/98 平台下,也可用來刪除整個子鍵和鍵值。但是在Windows NT/2000平台下,只能用來刪除沒有子鍵的鍵。

特別聲明

+由於修改注冊表后,需要重啟電腦后才能生效。所以代碼中加入了詢問“是否立刻重啟”的語句
+代碼中的部分函數沒有必要,僅僅是我練習其他注冊表操作功能所寫,與代碼本身目的毫無關聯

無關聯函數如下
read_reg_sz();
write_binary()
write_reg_sz()
delete_value()
delete_key()

**
+之所以附上無關聯函數,一方面為了以后有機會的話自己再次復習,另一方面是給讀者一些啟發。我覺得初學者更能懂初學者哈哈,也許其他函數也能夠被有興趣的讀者拿來開發出更有價值的內容(工具)。
**

成品

運行截圖

2
3

下載

藍奏雲 訪問碼:ocean

源碼

#include <iostream>
#include <atlbase.h>
#include <Windows.h>
using namespace std;
void write_dword();


//測試成功,讀取到start的當前值//讀取操作表,其類型為DWORD
void read_dword(){
    HKEY hKEY;//定義有關的鍵,在查詢結束時關閉
    //打開與路徑data_Set相關的hKEY
    char i,x;


    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");

    //訪問注冊表,hKEY則保存此函數所打開的鍵的句柄
    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_READ, &hKEY)){
        DWORD dwValue;//長整型數據,如果是字符串數據用char數組
        DWORD dwSize = sizeof(DWORD);
        DWORD dwType = REG_DWORD;

        if (::RegQueryValueEx(hKEY, _T("Start"), 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS)
            cout << "錯誤:無法查詢有關的注冊表信息" << endl;

        switch (dwValue){
        case 3:
            cout << "當前筆記本鍵盤狀態為:啟用 " << "(" << hex << dwValue << ")" << endl << endl << "若需要禁用請輸入字母:y或Y" << endl;
            cin >> i;
            if (i == 'y'|| i == 'Y') {
                write_dword();
            }
            break;
        case 4:
            cout << "當前筆記本鍵盤狀態為:禁用 " << "(" << hex << dwValue << ")" << endl << endl << "若需要啟用請輸入字母:y或Y" << endl;
            cin >> x;
            if (x == 'y' || x == 'Y') {
                write_dword();
            }
            break;
        default:
            cout << "當前筆記本鍵盤狀態獲取未知 " << "(" << hex << dwValue << ")" << endl << endl;
            break;
        }
    }
    ::RegCloseKey(hKEY);
}

//測試成功,讀取到start設備名displayname//讀取操作表,其類型為REG_SZ
void read_reg_sz(){
    HKEY hkey;
    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");

    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_READ, &hkey)){
        char dwValue[256];
        DWORD dwSzType = REG_SZ;
        DWORD dwSize = sizeof(dwValue);
        if (::RegQueryValueEx(hkey, _T("DisplayName"), 0, &dwSzType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS){
            cout << "無法查詢有關的注冊表信息" << endl << endl;
        }
        cout << "當前設備名:" << dwValue << endl << endl;
    }
    ::RegCloseKey(hkey);
}

//測試成功,更改(創建)到start鍵值//在SYSTEM\CurrentControlSet\Services\i8042prt文件夾下讀取Start的子鍵,設置其值為dwValue
void write_dword(){
    HKEY hkey;//定義有關的hkey,在查詢結束時要關閉
    HKEY hTempKey;

    char ans;
    int flag;

    DWORD dwValue;
    DWORD dwSize = sizeof(DWORD);
    DWORD dwType = REG_DWORD;

    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");

    cout << "請設置當前筆記本鍵盤狀態,輸入數字:3,表示開啟鍵盤;輸入數字4,表示禁用鍵盤;" << endl;
    cin >> flag;
    switch (flag) {
    case 3:
        dwValue = flag; break;
    case 4:
        dwValue = flag; break;
    default:
        cout << "狀態值輸入錯誤" << endl; break;
    }
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_SET_VALUE, &hkey)){
        //if (ERROR_SUCCESS == ::RegCreateKey(hkey, _T("解開該段落注釋,則可更改為:在SYSTEM\\CurrentControlSet\\Services\\i8042prt下,創建以'該文本內容'為名稱的子健,並創建一個名為“Start”的子健,其值為:dwValue"), &hTempKey)){
            if (ERROR_SUCCESS != ::RegSetValueEx(hkey, _T("Start"), 0, REG_DWORD, (CONST BYTE*) & dwValue, sizeof(DWORD))){
                cout << "寫入注冊表失敗" << endl;
            }
            cout << "修改成功!" << endl << "是否立刻重啟電腦,使設置立即生效?" << endl << "輸入y或Y,以立刻重新啟動電腦;輸入n或N退出程序" << endl;
            cin >> ans;
            if (ans == 'y' || ans == 'Y') {
                cout << "再次確認,要立刻重啟電腦嗎?\n\n輸入y或Y,以立刻重新啟動電腦;輸入n或N退出程序" << endl;
                cin >> ans;
                if (ans == 'y' || ans == 'Y')
                    system("shutdown -r -t 0");
            }
            else
                exit(1);
        //}
    }
    ::RegCloseKey(hkey);
}

//測試成功,更改(創建)子鍵test111及其鍵值項Name到start鍵值
void write_binary(){
    HKEY hkey;
    HKEY hTempKey;
    BYTE m_name[10];
    memset(m_name, 0, sizeof(m_name));
    m_name[0] = 0xff;
    m_name[1] = 0xac;
    m_name[2] = 0x05;
    m_name[3] = 0x4e;

    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");
    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_SET_VALUE, &hkey)){
        if (ERROR_SUCCESS == ::RegCreateKey(hkey, _T("test111"), &hTempKey)){
            if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_BINARY, (unsigned char*)m_name, 5)){
                cout << "寫入錯誤" << endl;
            }
        }
    }
    ::RegCloseKey(hkey);
}

//測試成功,更改(創建)子鍵test111及其鍵值項Name到start鍵值
void write_reg_sz(){
    HKEY hkey;
    HKEY hTempKey;
    char m_name_set[256] = "China";

    DWORD len = strlen(m_name_set) + 1;
    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");
    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_SET_VALUE, &hkey)){
        if (ERROR_SUCCESS == ::RegCreateKey(hkey, _T("test111"), &hTempKey)){
            if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, _T("Name"), 0, REG_SZ, (const BYTE*)m_name_set, len)){
                cout << "寫入錯誤" << endl;
            }
        }
    }
    ::RegCloseKey(hkey);
}

//測試成功,將鍵值項Name刪除
void delete_value()
{
    HKEY hkey;
    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\test111");

    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_SET_VALUE, &hkey))
    {
        if (ERROR_SUCCESS != ::RegDeleteValue(hkey, _T("Name")))
        {
            cout << "刪除錯誤" << endl;
        }
    }
    ::RegCloseKey(hkey);
}

//測試成功,將子鍵test111刪除
void delete_key(){
    HKEY hkey;
    LPCTSTR data_set = _T("SYSTEM\\CurrentControlSet\\Services\\i8042prt");

    if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_set, 0, KEY_SET_VALUE, &hkey)){
        if (ERROR_SUCCESS != ::RegDeleteKey(hkey, "test111")){
            cout << "刪除錯誤" << endl;
        }
    }
    ::RegCloseKey(hkey);
}


void menu(){
    cout << "歡迎使用本工具" << endl << endl;
    read_reg_sz();
    cout << endl << "已為您查詢到該筆記本當前鍵盤狀態為:" ;
    read_dword();
}


int main(){
    menu();
    system("pause");
    return 0;
}

尾聲

**
由於本人剛接觸注冊表操作的相關知識,有大佬能夠指點最好不過。
**


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM