钩子技术、HOOK技术应用(三)


下文是参考
http://blog.csdn.net/jayky/archive/2006/11/16/1388212.aspx
而改写的。。。

钩取输入法的例子

      最近用键盘钩子截获字符输入时是截不到特殊字符的,比方说中文输入法之类的.后来用到了消息钩子去HOOK WM_IME_CHAR,这时候大部分已经能够获取了,但是对于其他一些程序,比方说WORD之类的也就不能截获了.后来到MSDN上查到, 要用到WM_IME_COMPOSITION消息,并且在处理该消息时要用到IMM的一些库函数从输入法数据区中获取.比方说ImmGetContext,ImmGetCompositionString等等.
以下是源代码:

#define HC_IME_COPYDATA WM_USER+100
#define SH_IMMMESSAGE -3

HookProc UserMouseHookCallback = NULL;
HookProc UserKeyboardHookCallback = NULL;
HookProc UseImeMessageHookCallback = NULL;
HookProc SystemHookCallback = NULL;

HHOOK hookMouse = NULL;
HHOOK hookKeyboard = NULL;
HHOOK hookImeMessage = NULL;
HHOOK hookSystem = NULL;

//
// Store the application instance of this module to pass to
// hook initialization. This is set in DLLMain().
//
HINSTANCE g_appInstance = NULL;

MessageFilter mouseFilter;
MessageFilter keyboardFilter;
MessageFilter imeFilter;

static LRESULT CALLBACK InternalKeyboardHookCallback(int code, WPARAM wparam, LPARAM lparam);
static LRESULT CALLBACK InternalMouseHookCallback(int code, WPARAM wparam, LPARAM lparam);
static LRESULT CALLBACK InternalImeMessageHookCallback(int code, WPARAM wparam, LPARAM lparam);

// 仅内部用
static LRESULT CALLBACK privateImeMessageHookCallback(int code, WPARAM wparam, LPARAM lparam);

extern HINSTANCE g_appInstance;

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        //
        // Capture the application instance of this module to pass to
        // hook initialization.
        //
        if (g_appInstance == NULL)
        {
            g_appInstance = hinstDLL;
        }
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        break;

    default:
        OutputDebugString("Not sure what just happened./n");
        break;
    }

    return TRUE;
}

static HANDLE SetSystemHookHandler()
{
    // 在当前进程做一个局部钩子接受其它进程钩子发来的消息
    HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"SystemHookHandler");
    if (hMap == NULL)
    {
        hMap = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,1024,"SystemHookHandler");
    }

    LPVOID lpMapAddr = MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS, 0,0,0);
    DWORD tid = GetCurrentThreadId();//GetCurrentProcessId();
    char data[50];
    sprintf(data,"%ul",tid);
    memcpy(lpMapAddr,data,strlen(data));
    FlushViewOfFile(lpMapAddr,strlen(data)+1);
    UnmapViewOfFile(hMap);

    return hMap;
}

static DWORD GetSystemHookHandler()
{
    HANDLE hMap = OpenFileMapping(FILE_MAP_READ, 0, "SystemHookHandler");
    if (hMap == NULL)return NULL;
    LPVOID lpMapAddr = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
    DWORD tid = atol((char*)lpMapAddr);
    UnmapViewOfFile(hMap);
    return tid;
}


int SetUserHookCallback(HookProc userProc, UINT hookID)
{   

    if (userProc == NULL)
    {
        return HookCoreErrors::SetCallBack::ARGUMENT_ERROR;
    }

    if (hookID == WH_KEYBOARD_LL)//键盘
    {
        if (UserKeyboardHookCallback != NULL)
        {
            return HookCoreErrors::SetCallBack::ALREADY_SET;
        }

        UserKeyboardHookCallback = userProc;
        keyboardFilter.Clear();
        return HookCoreErrors::SetCallBack::SUCCESS;
    }
    else if (hookID == WH_MOUSE_LL)//鼠标
    {
        if (UserMouseHookCallback != NULL)
        {
            return HookCoreErrors::SetCallBack::ALREADY_SET;
        }

        UserMouseHookCallback = userProc;
        mouseFilter.Clear();
        return HookCoreErrors::SetCallBack::SUCCESS;
    }
    else if (hookID == SH_IMMMESSAGE)//输入法
    {
        if (UseImeMessageHookCallback != NULL)
        {
            return HookCoreErrors::SetCallBack::ALREADY_SET;
        }

        if (SetSystemHookHandler() == NULL)
        {
            return HookCoreErrors::SetCallBack::HANDLE_ERROR;
        }

        hookSystem = SetWindowsHookEx(3, (HOOKPROC)privateImeMessageHookCallback, g_appInstance, 0);
        if (hookSystem != NULL)
        {
            UseImeMessageHookCallback = userProc;
            imeFilter.Clear();
            return HookCoreErrors::SetCallBack::SUCCESS;
        }

        return HookCoreErrors::SetCallBack::HANDLE_ERROR;
    }

    return HookCoreErrors::SetCallBack::NOT_IMPLEMENTED;
}

bool InitializeHook(UINT hookID, int threadID)
{
    if (g_appInstance == NULL)
    {
        return false;
    }

    if (hookID == WH_KEYBOARD_LL)
    {
        if (UserKeyboardHookCallback == NULL)
        {
            return false;
        }

        hookKeyboard = SetWindowsHookEx(hookID, (HOOKPROC)InternalKeyboardHookCallback, g_appInstance, threadID);
        return hookKeyboard != NULL;
    }
    else if (hookID == WH_MOUSE_LL)
    {
        if (UserMouseHookCallback == NULL)
        {
            return false;
        }

        hookMouse = SetWindowsHookEx(hookID, (HOOKPROC)InternalMouseHookCallback, g_appInstance, threadID);
        return hookMouse != NULL;
    }
    else if (hookID == SH_IMMMESSAGE)
    {
        if (UseImeMessageHookCallback == NULL)
        {
            return false;
        }

        hookImeMessage = SetWindowsHookEx(3, (HOOKPROC)InternalImeMessageHookCallback, g_appInstance, threadID);
        return hookImeMessage != NULL;
    }

    return false;
}

void UninitializeHook(UINT hookID)
{

    if (hookID == WH_KEYBOARD_LL)
    {
        if (hookKeyboard != NULL)
        {
            UnhookWindowsHookEx(hookKeyboard);
        }
        hookKeyboard = NULL;
    }
    else if (hookID == WH_MOUSE_LL)
    {
        if (hookMouse != NULL)
        {
            UnhookWindowsHookEx(hookMouse);
        }
        hookMouse = NULL;
    }
    else if (hookID == SH_IMMMESSAGE)
    {
        if (hookImeMessage != NULL)
        {
            UnhookWindowsHookEx(hookImeMessage);
        }
        hookImeMessage = NULL;


    }

}

void Dispose(UINT hookID)
{
    if (hookID == WH_KEYBOARD_LL)
    {
        UserKeyboardHookCallback = NULL;
    }
    else if (hookID == WH_MOUSE_LL)
    {
        UserMouseHookCallback = NULL;
    }
    else if (hookID == SH_IMMMESSAGE)
    {
        UseImeMessageHookCallback = NULL;

        // 关闭内部的消息循环
        if (hookSystem != NULL)
        {
            UnhookWindowsHookEx(hookSystem);
        }
        hookSystem = NULL;
    }


}

int FilterMessage(UINT hookID, int message)
{
    if (hookID == WH_KEYBOARD_LL)
    {
        if (keyboardFilter.AddMessage(message))
        {
            return HookCoreErrors::FilterMessage::SUCCESS;
        }
        else
        {
            return HookCoreErrors::FilterMessage::FAILED;
        }
    }
    else if (hookID == WH_MOUSE_LL)
    {
        if(mouseFilter.AddMessage(message))
        {
            return HookCoreErrors::FilterMessage::SUCCESS;
        }
        else
        {
            return HookCoreErrors::FilterMessage::FAILED;
        }
    }
    else if (hookID == SH_IMMMESSAGE)
    {
        if(imeFilter.AddMessage(message))
        {
            return HookCoreErrors::FilterMessage::SUCCESS;
        }
        else
        {
            return HookCoreErrors::FilterMessage::FAILED;
        }
    }

    return HookCoreErrors::FilterMessage::NOT_IMPLEMENTED;
}

static LRESULT CALLBACK InternalMouseHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
    if (code < 0)
    {
        return CallNextHookEx(hookMouse, code, wparam, lparam);
    }

    if (UserMouseHookCallback != NULL && !mouseFilter.IsFiltered((int)wparam))
    {
        UserMouseHookCallback(code, wparam, lparam);
    }

    return CallNextHookEx(hookMouse, code, wparam, lparam);
}

static LRESULT CALLBACK InternalKeyboardHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
    if (code < 0)
    {
        return CallNextHookEx(hookKeyboard, code, wparam, lparam);
    }

    if (UserKeyboardHookCallback != NULL && !keyboardFilter.IsFiltered((int)wparam))
    {
        UserKeyboardHookCallback(code, wparam, lparam);
    }

    return CallNextHookEx(hookKeyboard, code, wparam, lparam);
}

static void IntenralGetMessageReading(LPTSTR msg)
{
    HANDLE m_hMapFile =  OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"InternalImeMessageHookCallback");
    if (m_hMapFile != NULL)
    {
        LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);
        return;
    }
}
static bool isProcess = false;

static LRESULT CALLBACK InternalImeMessageHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
    if (code < 0)
    {
        return CallNextHookEx(hookImeMessage, code, wparam, lparam);
    }

    PMSG pmsg = (PMSG)lparam;
    if (pmsg->message == WM_KEYUP && isProcess)
    {
        //if(pmsg->wParam == VK_SPACE || pmsg->wParam == VK_RETURN){

            // 强制false,
            // 否则有可能在接下来的无WM_KEYDOWN消息情况下产生WM_KEYUP
            isProcess = false;

            // 发送给处理进程处理消息
            DWORD tid = GetSystemHookHandler();

            if (tid != NULL)
            {
                HIMC hIMC;
                HWND hWnd=pmsg->hwnd;
                DWORD dwSize;

                char lpstr[20];
                //先获取当前正在输入的窗口的输入法句柄
                hIMC = ImmGetContext(hWnd);

                // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
                dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

                // 缓冲区大小要加上字符串的NULL结束符大小,
                // 考虑到UNICODE
                dwSize += sizeof(WCHAR);

                memset(lpstr, 0, 20);

                // 再调用一次.ImmGetCompositionString获取字符串
                ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);

                // 现在lpstr里面即是输入的汉字了。你可以处理lpstr,当然也可以保存为文件...
                bool isEmpty = true;
                for(int i=0;i<20;i++)
                {
                    if (lpstr[i] != '/0')
                        isEmpty = false;
                }
                if (!isEmpty)
                {
                    // 保存在共享内存并返回指向共享内存的
                    HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"ImeMessage");
                    if (m_hMapFile == NULL)
                    {
                        //创建共享文件。
                        m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,20,"ImeMessage");
                    }
                    //拷贝数据到共享文件里。
                    LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);
                    memset(lpMapAddr,0,20);
                    memcpy(lpMapAddr, lpstr,strlen(lpstr));
                    FlushViewOfFile(lpMapAddr,strlen(lpstr)+1);
                    UnmapViewOfFile(m_hMapFile);
                    ImmReleaseContext(hWnd, hIMC);

                    // 通知接受
                    PostThreadMessage(tid,HC_IME_COPYDATA,(WPARAM)(&pmsg->hwnd),lparam);
                }
            }
        //}
    }
    else if (pmsg->message == WM_KEYDOWN)
    {
        if(pmsg->wParam == VK_PROCESSKEY)
        {
            isProcess= true;
        }
        else
        {
            isProcess = false;
        }
    }
    else if (pmsg->message == WM_CHAR && !isProcess)
    {
        //if(pmsg->wParam != VK_SPACE && pmsg->wParam != VK_RETURN){

        // 发送给处理进程处理消息
        DWORD tid = GetSystemHookHandler();

        if (tid != NULL)
        {
            // 保存在共享内存并返回指向共享内存的
            HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"ImeMessage");
            if (m_hMapFile == NULL)
            {
                //创建共享文件。
                m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,20,"ImeMessage");
            }
            //拷贝数据到共享文件里。
            LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);
            memset(lpMapAddr,0,20);
            char lpstr[2];
            lpstr[0] = (char)pmsg->wParam;
            lpstr[1] = '/0';
            memcpy(lpMapAddr, lpstr,strlen(lpstr));
            FlushViewOfFile(lpMapAddr,strlen(lpstr)+1);
            UnmapViewOfFile(m_hMapFile);

            // 通知接受
            PostThreadMessage(tid,HC_IME_COPYDATA,(WPARAM)(&pmsg->hwnd),lparam);
        }
        //}
    }

    return CallNextHookEx(hookImeMessage, code, wparam, lparam);

}

static int imeCount = 0;

static LRESULT CALLBACK privateImeMessageHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
    if (code >= 0)
    {
        // 接受挂载进程发到当前进程上的消息
        PMSG pmsg = (PMSG)lparam;
        if (pmsg->message == HC_IME_COPYDATA)
        {
            if (imeCount % 2 != 0)
            {
                imeCount = 0;
            }
            else
            {
                imeCount++;

                if (UseImeMessageHookCallback != NULL && !imeFilter.IsFiltered((int)wparam))
                {
                    UseImeMessageHookCallback(code, pmsg->wParam, lparam);
                }

            }

        }
    }

    return CallNextHookEx(hookImeMessage, code, wparam, lparam);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值