通过hook实现禁止shift+delete快捷键

实现全局hook必须要将hook代码封装在dll里,所以此程序有两个文件:noShiftDeleteHook.dll和noShiftDelete.exe

noShiftDeleteHook.dll

//noShiftDeleteHook.h

#ifdef NOSHIFTDELETEHOOK_EXPORTS
#define NOSHIFTDELETEHOOKDLL_API __declspec(dllexport)
#else
#define NOSHIFTDELETEHOOKDLL_API __declspec(dllimport)
#endif

NOSHIFTDELETEHOOKDLL_API void InstallHook(HINSTANCE);
NOSHIFTDELETEHOOKDLL_API void UnInstallHook();
// noShiftDeleteHook.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "noShiftDeleteHook.h"

HHOOK hook=NULL;

LRESULT CALLBACK keyHookCallback (int nCode,WPARAM wParam,LPARAM lParam)
{
    char ch;
    LRESULT result=::CallNextHookEx(hook,nCode,wParam,lParam);
    KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *)lParam;
    BOOL bShiftKeyDown = 0;
    if (wParam==WM_KEYDOWN && nCode == HC_ACTION)
    {
        bShiftKeyDown=GetAsyncKeyState (VK_SHIFT) >> ((sizeof(SHORT) * 8) - 1);
        if (pkbhs->vkCode == VK_DELETE && bShiftKeyDown)
        {
            MessageBox(0,L"拒绝手贱,养成良好习惯,从你做起!",L"不准使用Shift+Delete",MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
            return TRUE;
        }
    }
    return result;
}
NOSHIFTDELETEHOOKDLL_API void InstallHook(HINSTANCE _hinstance)
{
    hook=(HHOOK)::SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)keyHookCallback,_hinstance,NULL);
    if(hook==NULL)
    {
        MessageBox(0,L"安装全局系统钩子失败!",L"提示",MB_OK);
    }
}

NOSHIFTDELETEHOOKDLL_API void UnInstallHook()
{
    BOOL result=UnhookWindowsHookEx(hook);
}

noShiftDelete.exe

// noShiftDelete.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "noShiftDelete.h"
#include <shellapi.h>
#include "../noShiftDeleteHook/noShiftDeleteHook.h"
#pragma comment(lib,"../Release/noShiftDeleteHook.lib")

#define MAX_LOADSTRING 100
#define WM_TRAY (WM_USER + 100)
#define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))

// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名

HMENU hMenu;
NOTIFYICONDATA nid;

// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

//实例化托盘 
void InitTray(HINSTANCE hInstance, HWND hWnd) 
{ 
    nid.cbSize = sizeof(NOTIFYICONDATA); 
    nid.hWnd = hWnd; 
    nid.uID = WM_TRAY; 
    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; 
    nid.uCallbackMessage = WM_TRAY; 
    nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL)); 
    lstrcpy(nid.szTip, L"noShiftDelete v1.0"); 
   
    hMenu = CreatePopupMenu();//生成托盘菜单 
    //为托盘菜单添加两个选项 
    AppendMenu(hMenu, MF_STRING,ID_ABOUT, TEXT("关于...")); 
    AppendMenu(hMenu, MF_SEPARATOR,ID_TITLE , TEXT("分割线")); 
    AppendMenu(hMenu, MF_STRING, ID_EXIT, TEXT("退出")); 
   
    Shell_NotifyIcon(NIM_ADD, &nid); 
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

        //互斥量阻止程序多次运行
    HANDLE m_hMutex = CreateMutex(NULL,FALSE, L"noShiftDelete");
    if (GetLastError() ==ERROR_ALREADY_EXISTS)
    {
        // 如果已有互斥量存在则释放句柄并复位互斥量
        CloseHandle(m_hMutex);
        m_hMutex=NULL;
        return FALSE;
    }
     // TODO: 在此放置代码。
    MSG msg;
    HACCEL hAccelTable;

    // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_NOSHIFTDELETE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_NOSHIFTDELETE));

    // 主消息循环:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释:
//
//    仅当希望
//    此代码与添加到 Windows 95 中的“RegisterClassEx”
//    函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
//    这样应用程序就可以获得关联的
//    “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NOSHIFTDELETE));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_NOSHIFTDELETE);
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // 将实例句柄存储在全局变量中

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX,
      CW_USEDEFAULT, 0, 400, 200, NULL, NULL, hInstance, NULL);
   //安装钩子
   HINSTANCE hinstance=GetModuleHandle(L"noShiftDeleteHook.dll");
   InstallHook(hinstance);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, SW_HIDE);
   UpdateWindow(hWnd);
   //实例化托盘
   InitTray(hInstance, hWnd);
   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND    - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY    - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
        case WM_TRAY: 
        switch(lParam) 
        { 
        case WM_RBUTTONDOWN: 
            { 
                //获取鼠标坐标 
                POINT pt; GetCursorPos(&pt); 
   
                //解决在菜单外单击左键菜单不消失的问题 
                SetForegroundWindow(hWnd); 
   
                //使菜单某项变灰 
                //EnableMenuItem(hMenu, ID_SHOW, MF_GRAYED);     
   
                //显示并获取选中的菜单 
                int cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd, 
                     NULL); 
                if(cmd == ID_EXIT)  
                    PostMessage(hWnd, WM_DESTROY, NULL, NULL);
                if(cmd == ID_ABOUT)  
                    MessageBox(0,L"Email: rophie123@foxmail.com",L"noShiftDelete v1.0",MB_OK); 
            } 
            break; 

        } 
        break; 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        UnInstallHook();
        Shell_NotifyIcon(NIM_DELETE, &nid); 
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    if (message == WM_TASKBAR_CREATED) 
    { 
        //系统Explorer崩溃重启时,重新加载托盘 
        Shell_NotifyIcon(NIM_ADD, &nid); 
    }
    return 0;
}

启动后窗体隐藏最小化到托盘,使用shift+delete时会提示并阻止

编译后文件:点击下载

原文地址:https://www.cnblogs.com/rophie/p/4857527.html