Windows XP系統中如何屏蔽 Ctrl+Alt+Del、Alt+Tab以及Ctrl+Esc鍵序列

來源:互聯網
上載者:User

Windows XP系統中如何屏蔽 Ctrl+Alt+Del、Alt+Tab以及Ctrl+Esc鍵序列

編譯/northtibet

關鍵字:Ctrl+Alt+Del,Alt+Tab,Ctrl+Esc,VK_LWIN,VK_RWIN,Task bar,Task Manager,工作列,工作管理員。

下載本文原始碼: TrapKeys.zip (95KB)

    對於用過Windows的人,幾乎沒有人不知道Ctrl+Alt+Del按鍵組合,尤其是在使用經常死機的Windows9x時,使用它的頻率更高,這一按鍵組合是專門為了系統安全起見提供的緊急出口。VC知識庫線上雜誌第11期,ac952_z_cn在他的個人專欄中寫過一篇關於這方面的文章:“WINDOWS NT/2000下如何屏蔽CTRL+ALT+DEL”。因此本文側重於介紹在Windows XP中如何?屏蔽CTRL+ALT+DEL按鍵組合,也就是工作管理員,任務切換按鍵組合(Alt+Tab),工作列和“開始”菜單(Ctrl+Esc,VK_LWIN,VK_RWIN)。這個方法也能應用於Windows 2000環境。
    在Windows 9x/Me系統中,屏蔽Ctrl+Alt+Del和各種任務開關鍵的方法是通過下面的方法實現的:

BOOL bOldState;SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &bOldState, 0);      

    MS大佬認為這種方法很業餘,所以在Windows NT/2000/XP中對此進行了修改。在這些較新的Windows版本中使用者登陸使用Winlogon和GINA——Graphical Identification and Authentication,意思是圖形化的身份認證,挺嚇唬人的是不是!其實就那麼回事。Winlogon是Windows系統的一部分,它專門提供互動式登陸支援,而GINA則是Winlogon用來實現認證的一個DLL——這個DLL就是msgina.dll。WlxInitialize、WlxActivateUserShell便是其中輸出,當然不知這兩個,還有別的。前者進行自身的初始化,後者啟用使用者的外殼程式。Windows就是用這個DLL來實現使用者名稱+口令的身份認證的,但是開發人員可以用自己的GINA代替msgina.dll。例如,實現智慧卡、視網膜掃描器、DNA檢查等等認證機制來代替輸入使用者名稱+口令形式的身份檢查。 下面的表格中列出了與GINA有關的全部函數。其中有一個是WlxLoggedOnSAS,當按下Ctrl+Alt+Del 鍵時,Winlogon便調用這個函數。

(表一)GINA 函數一覽表

函數  描述
WlxActivateUserShell 啟用使用者外殼程式
WlxDisplayLockedNotice 允許GINA DLL 顯示鎖定資訊
WlxDisplaySASNotice  當沒有使用者登陸時,Winlogon調用此函數
WlxDisplayStatusMessage Winlogon 用一個狀態資訊調用此函數進行顯示
WlxGetConsoleSwitchCredentials  Winlogon調用此函數讀取當前登陸使用者的信任資訊,並透明地將它們傳到目標會話
WlxGetStatusMessage  Winlogon 調用此函數擷取目前狀態資訊
WlxInitialize  針對指定的視窗位置進行GINA DLL初始化
WlxIsLockOk  驗證工作站正常鎖定
WlxIslogoffOk  驗證登出正常
WlxLoggedOnSAS  使用者已登陸並且工作站沒有被加鎖,如果此時接收到SAS事件,則Winlogon 調用此函數
WlxLoggedOutSAS  沒有使用者登陸,如果此時收到SAS事件,則Winlogon 調用此函數
WlxLogoff  請求登出操作時通知GINA DLL 
WlxNegotiate  表示當前的Winlogon版本是否能使用GINA DLL
WlxNetworkProviderLoad  在載入網路服務提供者收集了身份和認證資訊後,Winlogon 調用此函數
WlxRemoveStatusMessage  Winlogon 調用此函數告訴GINA DLL 停止顯示狀態資訊
WlxScreensaverNotify  允許GINA與螢幕保護裝置操作互動
WlxShutdown  在關閉之前Winlogon 調用此函數,允許GINA實現任何關閉任務,例如從讀卡機中退出智慧卡
WlxStartApplication  當系統需要在使用者的上下文中啟動應用程式時調用此函數
WlxWkstaLockedSAS 當工作站被鎖定,如果接收到一個SAS,則Winlogon 調用此函數

    在預設情況下,GINA顯示登陸對話方塊,使用者輸入使用者名稱及口令。所以要想屏蔽掉Ctrl+Alt+Del,則可以寫一個新的MyGina.dll,其中提供介面調用msgina.dll的函數WlxLoggedOnSAS,從而實現Ctrl+Alt+Del屏蔽。或者編寫一個鍵盤驅動程式來實現。
    難道屏蔽Ctrl+Alt+Del真的象上述所說的那麼麻煩嗎?有沒有更好的方法呢?答案是肯定的。所以忘掉GINA吧,使用作業系統的原則設定完全可以搞掂這個問題。方法是進入"開始"菜單,選擇"運行",然後在運行對話方塊中輸入"gpedit.msc",啟動Windows系統的組策略編輯器。在左邊窗格查看"使用者配置|系統管理範本|系統|登入/登出",則在右邊窗格策略裡不難發現"禁用工作管理員"一項。二所示:


圖一 組策略編輯器

通過對這個策略的設定可以屏蔽掉Ctrl+Alt+Del。如果要通過編寫代碼來實現,則必須操作下面的登錄機碼:

HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr = dword:1

如此設定之後,則在Windows XP中,如果使用者按下Ctrl+Alt+Del,則會彈出一個出錯對話方塊,二所示:


圖二 錯誤資訊

注意這裡假設在控制台中“使用者帳號”管理的“選擇登入和登出選項”設定啟用了“使用歡迎畫面”一項。三所示:


圖三 登入選項

    否則,XP將使用Windows的傳統登入模式,要求使用者輸入帳戶名稱。並且Ctrl+Alt+Del按鍵組合的 行為也和傳統的行為一樣,註冊表中DisableTaskMgr的設定也只是將登入/登出對話方塊中的工作管理員按鈕屏蔽或置灰。 有人可能會問,有關工作管理員的文檔又沒有明確說明,那你是怎麼知道DisableTaskMgr是用來禁用工作管理員的呢?告訴你吧, 我是在使用GPEDIT時發現的。GPEDIT是一個非常有用的工具,不僅可以用它來編輯策略,還可以用它來發現策略。利用這個工具 可以輕鬆控制Windows的許多東西,從許可許可權的存取到是否使用IE的傳統外觀,從是否顯示對話方塊中的Places Bar到是否用Ctrl+Alt+Del 啟動工作管理員。總之用它可以配置上百個介面行為,因此它是一個足以讓系統管理員垂延三尺的工具。 一旦找到了感興趣的策略,那如何知道相應的註冊表位置呢?有兩種方法。第一種是比較粗魯的辦法:在修改策略的前後將註冊表輸出到 一個.reg檔案,然後比較它們有什麼不同。所有的策略無外乎以下的四個註冊表鍵:

// 使用者指定HKEY_CURRENT_USER\Software\PoliciesHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies// 機器指定HKEY_LOCAL_MACHINE\Software\PoliciesHKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies      

    第二種方法是直搗資訊源頭--檢查描述策略的系統管理範本檔案(.adm)。下面是Windows XP的system.adm檔案對 DisableTaskMgr的描述:(Windows 2000對此的描述稍有不同,其細節請參考Windows 2000的資源開發包)

CATEGORY !!CADOptions#if version >= 4EXPLAIN !!CADOptions_Help#endifKEYNAME "Software\Microsoft\Windows\CurrentVersion\Policies\System"POLICY !!DisableTaskMgr#if version >= 4SUPPORTED !!SUPPORTED_Win2k#endifEXPLAIN !!DisableTaskMgr_HelpVALUENAME "DisableTaskMgr"END POLICY;; More Ctrl+Alt+Del policies here...;END CATEGORY ; Ctrl+Alt+Del options…………DisableTaskMgr_Help="防止使用者啟動''工作管理員''(Taskmgr.exe)。\n\n如果該設定被啟用,並且使用者試圖啟動工作管理員,系統會顯示訊息,解釋是一個策略禁止了這個操作。\n\n工作管理員讓使用者啟動或終止程式,監視電腦效能,查看及監視電腦上所有運行中的程式 (包含系統服務), 搜尋程式的執行檔案名稱,及更改程式啟動並執行優先順序。"DisableTaskMgr="刪除工作管理員" 

以上是DisableTaskMgr的描述片斷

    正是在這段描述中KEYNAME 和VALUENAME指定了註冊表的索引值對。利用這種方法,你可以為自己的應用程式建立系統管理範本和策略,但編輯和瀏覽.adm模板檔案的編輯器必須支援Unicode字元。如Notepad或者WordPad等都可以。此外,使用系統管理範本檔案,系統管理員可以用它為整個組織配置需要的策略——由此可以看出,此檔案在系統中的地位舉足輕重!有關範本管理員檔案格式的詳細資料請參考平台SDK。最後需要強調的是DisableTaskMgr只是禁用Ctrl+Alt+Del的功能。下面我們來討論如何捕獲它的按鍵序列。要想截獲Ctrl+Alt+Del,有三種可選擇的方法:

  • 1、 編寫一個GINA代理;此方法我們在以後的文章中介紹。實際上,ac952_z_cn的個人專欄文章:“WINDOWS NT/2000下如何屏蔽CTRL+ALT+DEL”使用的就是這種方法。
  • 2、 編寫一個鍵盤驅動程式;本文例子程式使用的方法。
  • 3、 用自己的程式代替工作管理員程式TaskMgr.exe。

屏蔽Ctrl+Alt+Del解決方案的具體實現細節請參考本文的例子代碼。
    下面讓我們來解決屏蔽任務切換鍵序列的問題,這些鍵序列包括Alt+Tab、Ctrl+Esc、Alt+Esc、VK_LWIN/VK_RWIN以及工作列。在很早以前的Window 3.1年代,處理這個問題的方法是通過WM_SYSKEYDOWN實現。到了Windows 9x時期,本文前面提到過對這個問題的處理方法,使用SPI_SETSCREENSAVERRUNNING。但是進入Windows NT 4.0 (SP3 +),Windows 2000以及Windows XP時代,對這個問題的處理已經有所不同,必須寫一個低級的鍵盤驅動鉤子。不要怕,因為要實現這個鉤子並不是很難。本文下面會介紹如何?這個鍵盤鉤子。一般來講,系統級鉤子必須是一個DLL。下面是本文提供的一個鍵盤鉤子DLL的原始碼片斷(TaskKeyHook.dll):

標頭檔//////////////////////////////////////////////////////////////////TaskKeyHook.h//#define DLLIMPORT __declspec(dllimport)DLLIMPORT BOOL DisableTaskKeys(BOOL bEnable, BOOL bBeep);DLLIMPORT BOOL AreTaskKeysDisabled();實現檔案////////////////////////////////////////////////////////////////// TaskKeyHook.cpp//#define _WIN32_WINNT 0x0500 // for KBDLLHOOKSTRUCT#include <afxwin.h>         // MFC core and standard components#define DLLEXPORT __declspec(dllexport)//////////////////// App (DLL) object//class CTaskKeyHookDll : public CWinApp {public:CTaskKeyHookDll()  { }~CTaskKeyHookDll() { }} MyDll;////////////////////////////////////////////////// 下面的代碼錶示這一部分在此DLL所有執行個體之間共用// 低級鍵盤鉤子一定是系統級的鉤子//#pragma data_seg (".mydata")HHOOK g_hHookKbdLL = NULL; // 鉤子控制代碼BOOL  g_bBeep = FALSE;     // 按下非法鍵時蜂鳴響鈴#pragma data_seg ()#pragma comment(linker, "/SECTION:.mydata,RWS") // 告訴連結器:建立資料共用段//////////////////////////////////// 低級鍵盤鉤子// 截獲任務轉換鍵:不傳遞直接返回//LRESULT CALLBACK MyTaskKeyHookLL(int nCode, WPARAM wp, LPARAM lp){KBDLLHOOKSTRUCT *pkh = (KBDLLHOOKSTRUCT *) lp;if (nCode==HC_ACTION) {BOOL bCtrlKeyDown =GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) * 8) - 1);if ((pkh->vkCode==VK_ESCAPE && bCtrlKeyDown) || // Ctrl+Esc// Alt+TAB(pkh->vkCode==VK_TAB && pkh->flags & LLKHF_ALTDOWN) ||// Alt+Esc(pkh->vkCode==VK_ESCAPE && pkh->flags & LLKHF_ALTDOWN)||(pkh->vkCode==VK_LWIN || pkh->vkCode==VK_RWIN)) { // 開始菜單if (g_bBeep && (wp==WM_SYSKEYDOWN||wp==WM_KEYDOWN))MessageBeep(0); // 蜂鳴return 1; // 不再往CallNextHookEx傳遞,直接返回}}return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);}////////////////////////////////////////////////// 是否屏蔽任務鍵序列——也就是說鍵盤鉤子是否安裝?// 註:這裡假設沒有其它鉤子做同樣的事情//DLLEXPORT BOOL AreTaskKeysDisabled(){return g_hHookKbdLL != NULL;}////////////////////////////////////////////////// 屏蔽任務鍵:安裝低級鍵盤構// 返回當前是否屏蔽標誌(TRUE/FALSE)//DLLEXPORT BOOL DisableTaskKeys(BOOL bDisable, BOOL bBeep){if (bDisable) {if (!g_hHookKbdLL) {g_hHookKbdLL = SetWindowsHookEx(WH_KEYBOARD_LL,MyTaskKeyHookLL, MyDll.m_hInstance, 0);}} else if (g_hHookKbdLL != NULL) {UnhookWindowsHookEx(g_hHookKbdLL);g_hHookKbdLL = NULL;}g_bBeep = bBeep;return AreTaskKeysDisabled();}      

    TaskKeyHook 輸出兩個函數:DisableTaskKeys 和 AreTaskKeysDisabled。前者安裝WH_KEYBOARD_LL 鉤子;後者判斷這個鉤子是否安裝。此鍵盤鉤子的處理思路是截獲Alt+Tab,Ctrl+Esc,Alt+Esc以及Windows 鍵VK_LWIN/VK_RWIN,關於這兩個鍵,稍候會有詳細描述。當鉤子碰到這些鍵時,它直接返回到調用者,而不是將處理傳遞給CallNextHookEx 。

LRESULT CALLBACK MyTaskKeyHookLL(...){if (/* 任務鍵*)return 1; // 立即返回return CallNextHookEx(...);}      

    TaskKeyHook的大部分實現都很簡單。只有一個地方用到了一點小技巧:既使用#pragma data_seg 命名包含全程資料的資料區段,並且用#pragma comment (linker...)告訴連結器讓這個資料區段為共用段。實現細節請參考原始碼。 本文附帶的例子程式(TrapKeys.exe)彙集了上述幾個有關屏蔽鍵盤按鍵序列的功能,除此之外,它還有一個功能就是禁用工作列。因為既然禁用了任務轉換鍵,那麼一般來說,也必然要禁用工作列,否則禁用任務轉換鍵就沒有意義了。禁用工作列的具體方法如下:

HWND hwnd = FindWindow("Shell_traywnd", NULL);//找到工作列EnableWindow(hwnd, FALSE); // 禁用工作列

四是例子程式運行畫面:


圖四 TrapKeys程式運行畫面

以下是TrapKeys程式的實現代碼:

/////////////////////////////////////////////////// TrapKeys.cpp//#include "stdafx.h"#include "resource.h"#include "StatLink.h"#include "TaskKeyMgr.h"////////////////////// 主對話方塊//class CMyDialog : public CDialog {public:CMyDialog(CWnd* pParent = NULL) : CDialog(IDD_MYDIALOG, pParent) { }protected:HICON m_hIcon;CStaticLink m_wndLink1;CStaticLink m_wndLink2;CStaticLink m_wndLink3;virtual BOOL OnInitDialog();// 命令/UI 的更新處理afx_msg void OnDisableTaskMgr();afx_msg void OnDisableTaskKeys();afx_msg void OnDisableTaskbar();afx_msg void OnUpdateDisableTaskMgr(CCmdUI* pCmdUI);afx_msg void OnUpdateDisableTaskKeys(CCmdUI* pCmdUI);afx_msg void OnUpdateDisableTaskbar(CCmdUI* pCmdUI);afx_msg LRESULT OnKickIdle(WPARAM,LPARAM);DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////// 標準的MFC 對話方塊應用類代碼。//class CMyApp : public CWinApp {public:virtual BOOL InitInstance() {// 初始化app:運行對話方塊CMyDialog dlg;m_pMainWnd = &dlg;dlg.DoModal();return FALSE;}virtual int ExitInstance() {// 為了按全起見,在退出程式的時候,將所有禁用的項目複原CTaskKeyMgr::Disable(CTaskKeyMgr::ALL, FALSE);return 0;}} theApp;BEGIN_MESSAGE_MAP(CMyDialog, CDialog)ON_COMMAND(IDC_DISABLE_TASKKEYS,OnDisableTaskKeys)ON_COMMAND(IDC_DISABLE_TASKBAR, OnDisableTaskbar)ON_COMMAND(IDC_DISABLE_TASKMGR, OnDisableTaskMgr)ON_UPDATE_COMMAND_UI(IDC_DISABLE_TASKKEYS, OnUpdateDisableTaskKeys)ON_UPDATE_COMMAND_UI(IDC_DISABLE_TASKBAR, OnUpdateDisableTaskbar)ON_UPDATE_COMMAND_UI(IDC_DISABLE_TASKMGR, OnUpdateDisableTaskMgr)ON_MESSAGE(WM_KICKIDLE,OnKickIdle)END_MESSAGE_MAP()///////////////////////////////////////////////// 初始化對話方塊:子類化超連結柄加栽表徵圖//BOOL CMyDialog::OnInitDialog(){CDialog::OnInitDialog();// 初始化超連結m_wndLink1.SubclassDlgItem(IDC_EMAIL,this);m_wndLink2.SubclassDlgItem(IDC_VCKBASEURL,this);m_wndLink3.SubclassDlgItem(IDC_VCKBASELINK,this);// 自己設定對話方塊表徵圖。MFC不會為對話方塊應用程式設定它m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);SetIcon(m_hIcon, TRUE);       // 打表徵圖SetIcon(m_hIcon, FALSE);      // 小表徵圖return TRUE;}////////////////////////////////////////////////////////// 命令/UI 更新處理:寫這些東西應該很輕鬆。void CMyDialog::OnDisableTaskKeys(){CTaskKeyMgr::Disable(CTaskKeyMgr::TASKKEYS,!CTaskKeyMgr::AreTaskKeysDisabled(), TRUE); // 蜂鳴}void CMyDialog::OnUpdateDisableTaskKeys(CCmdUI* pCmdUI){pCmdUI->SetCheck(CTaskKeyMgr::AreTaskKeysDisabled());}void CMyDialog::OnDisableTaskbar(){CTaskKeyMgr::Disable(CTaskKeyMgr::TASKBAR,!CTaskKeyMgr::IsTaskBarDisabled());}void CMyDialog::OnUpdateDisableTaskbar(CCmdUI* pCmdUI){pCmdUI->SetCheck(CTaskKeyMgr::IsTaskBarDisabled());}void CMyDialog::OnDisableTaskMgr(){CTaskKeyMgr::Disable(CTaskKeyMgr::TASKMGR,!CTaskKeyMgr::IsTaskMgrDisabled());}void CMyDialog::OnUpdateDisableTaskMgr(CCmdUI* pCmdUI){pCmdUI->SetCheck(CTaskKeyMgr::IsTaskMgrDisabled());}////////////////////////////////////////////////////////// 要想讓ON_UPDATE_COMMAND_UI正常工作,這是必需的。//LRESULT CMyDialog::OnKickIdle(WPARAM wp, LPARAM lCount){UpdateDialogControls(this, TRUE);return 0;}      

   按上述方法儘管禁用了工作列,但是還有一個機關沒有處理,那就是按下Windows鍵仍然可以彈出“開始”菜單。顯然在處理VK_LWIN之前,工作列不會檢查是否被啟用。一般來講,如果某個視窗被屏蔽掉,那麼它就不再會處理使用者在這個視窗的輸入——這就是所謂的禁用(Disable)的含義。通常調用EnableWindow(FALSE)後自然就達到了這個目的。但是處理VK_LWIN/VK_RWIN按鍵的代碼決不會去檢查工作列啟用/禁用狀態。對此,本文的處理辦法仍然是利用鍵盤鉤子。修改一下TaskKeyHook實現,增加對Windows鍵的捕獲。這樣按下“開始”菜單鍵之後什麼也不會發生。希望沒有漏掉其它的按鍵。如果哪位讀者發現漏掉了什麼鍵,請和我聯絡,以便把它加到鍵盤鉤子中去。為了簡單起見,我在類CTaskKeyMgr中封裝了所有禁用的函數。下面是這個類的定義擊實現檔案:

TaskKeyMgr////////////////////////////////////////// TaskKeyMgr.h//#pragma once#include "TaskKeyHook.h"/////////////////////////////////////////////////////////////////////// 使用這個類禁用任務鍵,工作管理員或工作列。// 用相應的標誌調用Disable,如:CTaskMgrKeys::Disable(CTaskMgrKeys::ALL);//class CTaskKeyMgr {public:enum {TASKMGR  = 0x01,  // 禁用工作管理員(Ctrl+Alt+Del)TASKKEYS = 0x02,  //禁用任務轉換鍵(Alt-TAB, etc)TASKBAR  = 0x04,  //禁用工作列ALL=0xFFFF        //禁用所有東西L};static void Disable(DWORD dwItem,BOOL bDisable,BOOL bBeep=FALSE);static BOOL IsTaskMgrDisabled();static BOOL IsTaskBarDisabled();static BOOL AreTaskKeysDisabled() {return ::AreTaskKeysDisabled(); // 調用 DLL}};CPP實現////////////////////////////////////////////////////////////////// TaskKeyMgr.cpp//#include "StdAfx.h"#include "TaskKeyMgr.h"#define HKCU HKEY_CURRENT_USER// 用于禁用工作管理員策略的註冊表索引值對LPCTSTR KEY_DisableTaskMgr ="Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";LPCTSTR VAL_DisableTaskMgr = "DisableTaskMgr";///////////////////////////////////////////// 禁用相關的任務鍵//// dwFlags   =  表示禁用什麼// bDisable   = 禁用為 (TRUE) ,否則為啟用 (FALSE)// bBeep    =  按下非法鍵是否蜂鳴(指標對任務鍵)//void CTaskKeyMgr::Disable(DWORD dwFlags, BOOL bDisable, BOOL bBeep){// 工作管理員 (Ctrl+Alt+Del)if (dwFlags & TASKMGR) {HKEY hk;if (RegOpenKey(HKCU, KEY_DisableTaskMgr,&hk)!=ERROR_SUCCESS)RegCreateKey(HKCU, KEY_DisableTaskMgr, &hk);if (bDisable) { // 禁用工作管理員(disable TM): set policy = 1DWORD val=1;RegSetValueEx(hk, VAL_DisableTaskMgr, NULL,REG_DWORD, (BYTE*)&val, sizeof(val));} else { // 啟用工作管理員(enable TM)RegDeleteValue(hk,VAL_DisableTaskMgr);}}// 任務鍵 (Alt-TAB etc)if (dwFlags & TASKKEYS)::DisableTaskKeys(bDisable,bBeep); // 安裝鍵盤鉤// 工作列if (dwFlags & TASKBAR) {HWND hwnd = FindWindow("Shell_traywnd", NULL);EnableWindow(hwnd, !bDisable);}}BOOL CTaskKeyMgr::IsTaskBarDisabled(){HWND hwnd = FindWindow("Shell_traywnd", NULL);return IsWindow(hwnd) ? !IsWindowEnabled(hwnd) : TRUE;}BOOL CTaskKeyMgr::IsTaskMgrDisabled(){HKEY hk;if (RegOpenKey(HKCU, KEY_DisableTaskMgr, &hk)!=ERROR_SUCCESS)return FALSE; // 沒有此鍵,不禁用DWORD val=0;DWORD len=4;return RegQueryValueEx(hk, VAL_DisableTaskMgr,NULL, NULL, (BYTE*)&val, &len)==ERROR_SUCCESS && val==1;}      

    這個類中的函數都是靜態,實際上CTaskKeyMgr完全就是一個名字空間。你可以在自己的程式中隨心所欲地使用它。例如,禁用任務轉換按鍵和工作列,但是不禁用Ctrl+Alt+Del:

CTaskKeyMgr::Disable(CTaskKeyMgr::TASKKEYS |CTaskKeyMgr::TASKBAR, TRUE);      

    此外,還有幾個函數是用來檢查當前禁用了哪些東西,甚至可以在使用者按下禁用鍵時發出蜂鳴聲……自己去享受Paul的原始碼吧!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.