• 通过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时会提示并阻止

    编译后文件:点击下载

  • 相关阅读:
    windows live writer backup
    SQL SERVER单独安装
    VS异常--未找到与约束 ContractName Microsoft.VisualStudio.Language.Intellisense.IGlyphService RequiredTypeIdentity
    ASP.NET之报表--RDLC(一)---附源码
    尚未指定报表“Report1”的报表定义
    人月神话
    [LeetCode]Reverse Nodes in k-Group
    [LeetCode]Divide Two Integer
    [LeetCode]Minimum Path Sum
    [LeetCode]Regular Expression Matching
  • 原文地址:https://www.cnblogs.com/rophie/p/4857527.html
Copyright © 2020-2023  润新知