SetWindowsHookEx用于监视Windows的打开和关闭

时间:2018-05-28 10:13:33

标签: windows hook setwindowshookex

我从here获取了这个示例代码,该代码挂钩函数来拦截键盘事件,并且它可以工作:

#include <Windows.h>

// variable to store the HANDLE to the hook. Don't declare it anywhere else then globally
// or you will get problems since every function uses this variable.
HHOOK _hook;

// This struct contains the data received by the hook callback. As you see in the callback function
// it contains the thing you will need: vkCode = virtual key code.
KBDLLHOOKSTRUCT kbdStruct;

// This is the callback function. Consider it the event that is raised when, in this case, 
// a key is pressed.
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
        // the action is valid: HC_ACTION.
        if (wParam == WM_KEYDOWN)
        {
            // lParam is the pointer to the struct containing the data needed, so cast and assign it to kdbStruct.
            kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
            // a key (non-system) is pressed.
            if (kbdStruct.vkCode == VK_F1)
            {
                // F1 is pressed!
                MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION);
            }
        }
    }

    // call the next hook in the hook chain. This is nessecary or your hook chain will break and the hook stops
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

void SetHook()
{
    // Set the hook and set it to use the callback function above
    // WH_KEYBOARD_LL means it will set a low level keyboard hook. More information about it at MSDN.
    // The last 2 parameters are NULL, 0 because the callback function is in the same thread and window as the
    // function that sets and releases the hook. If you create a hack you will not need the callback function 
    // in another place then your own code file anyway. Read more about it at MSDN.
    if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)))
    {
        MessageBox(NULL, "Failed to install hook!", "Error", MB_ICONERROR);
    }
}

void ReleaseHook()
{
    UnhookWindowsHookEx(_hook);
}

void main()
{
    // Set the hook
    SetHook();

    // Don't mind this, it is a meaningless loop to keep a console application running.
    // I used this to test the keyboard hook functionality. If you want to test it, keep it in ;)
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {

    }
}

我正在努力使类似的代码适用于WH_GETMESSAGE拦截WH_CREATEWH_DESTROY消息,但它没有起作用:

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
#include <iostream>

HHOOK _hook;

LRESULT CALLBACK  GetMsgProc(_In_ int nCode,    _In_ WPARAM wParam, _In_ LPARAM lParam)
{
    std::cout << "Enter hook\n";
    if (nCode >= 0)
    {
        // the action is valid: HC_ACTION.
        std::cout << "HC_ACtION\n";
        if (wParam != PM_REMOVE) return NULL;
        MSG m = *((MSG*)lParam);
        std::cout << "Message received\n";
        TCHAR Buffer[MAX_PATH];
        if (GetModuleFileNameEx(m.hwnd, 0, Buffer, MAX_PATH))
        {
            // At this point, buffer contains the full path to the executable
            MessageBox(NULL, Buffer, L"key pressed", MB_ICONINFORMATION);
        }
        else
        {
            // You better call GetLastError() here
        }
        //CloseHandle(Hand);
    }

    // call the next hook in the hook chain. This is nessecary or your hook chain will break and the hook stops
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

void SetHook()
{       
    if (!(_hook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, NULL, 0)))
    {
        MessageBox(NULL, L"Failed to install hook!", L"Error", MB_ICONERROR);
    }
}

void ReleaseHook()
{
    UnhookWindowsHookEx(_hook);
}

void main()
{
    // Set the hook
    SetHook();

    // Don't mind this, it is a meaningless loop to keep a console application running.
    // I used this to test the keyboard hook functionality. If you want to test it, keep it in ;)
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {

    }
}

MSDN指定将函数GetMsgProc与预定义签名一起使用,但我看不到它做了什么。

0 个答案:

没有答案