2024年11月XP系统中如何屏蔽Ctrl+Esc键序列(4)

发布时间:

  ⑴LRESULT CALLBACK MyTaskKeyHookLL(...)

  ⑵if (/* 任务键*)

  ⑶return ; // 立即返回

  ⑷return CallNextHookEx(...);

  ⑸TaskKeyHook的大部分实现都很简单。只有一个地方用到了一点小技巧:既使用#pragma data_seg 命名包含全程数据的数据段,并且用#pragma ment (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 {

  ⒆CMyDialog(CWnd* pParent = NULL) : CDialog(IDD_MYDIALOG, pParent) { }

  ⒇protected:

  ⒈HICON m_hIcon;

  ⒉CStaticLink m_wndLink;

  ⒊CStaticLink m_wndLink;

  ⒋CStaticLink m_wndLink;

  ⒌virtual BOOL OnInitDialog();

  ⒍// 命令/UI 的更新处理

  ⒎afx_msg void OnDisableTaskMgr();

  ⒏afx_msg void OnDisableTaskKeys();

  ⒐afx_msg void OnDisableTaskbar();

  ⒑afx_msg void OnUpdateDisableTaskMgr(mdUI* pCmdUI);

  ⒒afx_msg void OnUpdateDisableTaskKeys(mdUI* pCmdUI);

  ⒓afx_msg void OnUpdateDisableTaskbar(mdUI* pCmdUI);

  ⒔afx_msg LRESULT OnKickIdle(WPARAM,LPARAM);

  ⒕DECLARE_MESSAGE_MAP()

  ⒖///////////////////////////////////////////////////////

  ⒗// 标准的MFC 对话框应用类代码。

  ⒘class CMyApp : public CWinApp {

  ⒙virtual BOOL InitInstance() {

  ⒚// 初始化app:运行对话框

  ⒛CMyDialog dlg;

  ①m_pMainWnd = &dlg;

  ②dlg.DoModal();

  ③return FALSE;

  ④virtual int ExitInstance() {

  ⑤// 为了按全起见,在退出程序的时候,将所有禁用的项目复原

  ⑥CTaskKeyMgr::Disable(CTaskKeyMgr::ALL, FALSE);

  ⑦return ;

  ⑧} theApp;

  ⑨BEGIN_MESSAGE_MAP(CMyDialog, CDialog)

  ⑩ON_MAND(IDC_DISABLE_TASKKEYS,OnDisableTaskKeys)

  ⅠON_MAND(IDC_DISABLE_TASKBAR, OnDisableTaskbar)

  ⅡON_MAND(IDC_DISABLE_TASKMGR, OnDisableTaskMgr)

  ⅢON_UPDATE_MAND_UI(IDC_DISABLE_TASKKEYS, OnUpdateDisableTaskKeys)

  ⅣON_UPDATE_MAND_UI(IDC_DISABLE_TASKBAR, OnUpdateDisableTaskbar)

  ⅤON_UPDATE_MAND_UI(IDC_DISABLE_TASKMGR, OnUpdateDisableTaskMgr)

  ⅥON_MESSAGE(WM_KICKIDLE,OnKickIdle)

  ⅦEND_MESSAGE_MAP()

  Ⅷ///////////////////////////////////////////////

  Ⅸ// 初始化对话框:子类化超链接柄加栽图标

  ⅩBOOL CMyDialog::OnInitDialog()

  ㈠CDialog::OnInitDialog();

  ㈡// 初始化超链接

  ㈢m_wndLink.SubclassDlgItem(IDC_EMAIL,this);

  ㈣m_wndLink.SubclassDlgItem(IDC_VCKBASEURL,this);

  ㈤m_wndLink.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(mdUI* pCmdUI)

  pCmdUI->SetCheck(CTaskKeyMgr::AreTaskKeysDisabled());

  void CMyDialog::OnDisableTaskbar()

  CTaskKeyMgr::Disable(CTaskKeyMgr::TASKBAR,

  !CTaskKeyMgr::IsTaskBarDisabled());

  void CMyDialog::OnUpdateDisableTaskbar(mdUI* pCmdUI)

  pCmdUI->SetCheck(CTaskKeyMgr::IsTaskBarDisabled());

  void CMyDialog::OnDisableTaskMgr()

  CTaskKeyMgr::Disable(CTaskKeyMgr::TASKMGR,

  !CTaskKeyMgr::IsTaskMgrDisabled());

  void CMyDialog::OnUpdateDisableTaskMgr(mdUI* pCmdUI)

  pCmdUI->SetCheck(CTaskKeyMgr::IsTaskMgrDisabled());

  ////////////////////////////////////////////////////////

  // 要想让ON_UPDATE_MAND_UI正常工作,这是必需的。

  LRESULT CMyDialog::OnKickIdle(WPARAM wp, LPARAM lCount)

  UpdateDialogControls(this, TRUE);

  return ;

  按上述方法尽管禁用了任务栏,但是还有一个机关没有处理,那就是按下Windows键仍然可以弹出“开始”菜单。显然在处理VK_LWIN之前,任务栏不会检查是否被启用。一般来讲,如果某个窗口被屏蔽掉,那么它就不再会处理用户在这个窗口的输入——这就是所谓的禁用(Disable)的含义。通常调用EnableWindow(FALSE)后自然就达到了这个目的。但是处理VK_LWIN/VK_RWIN按键的代码决不会去检查任务栏启用/禁用状态。对此,本文的处理办法仍然是利用键盘钩子。修改一下TaskKeyHook实现,增加对Windows键的捕获。这样按下“开始”菜单键之后什么也不会发生。希望没有漏掉其它的按键。如果哪位读者发现漏掉了什么键,请和我联系,以便把它加到键盘钩子中去。为了简单起见,我在类CTaskKeyMgr中封装了所有禁用的函数。下面是这个类的定义击实现文件: