• 非模态对话框不能响应PreTranslateMessage,用键盘钩子


     

      

     h文件中

    	static CDlgMainPanel* gThis;
    	HHOOK m_hHook;
    	static LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    构造函数

    m_hHook=NULL
    void CDlgMainPanel::ShowUI()
    {
    	ShowWindow(SW_NORMAL);
    
    	if (m_hHook == NULL)
    	{
    		m_hHook = ::SetWindowsHookEx(WH_KEYBOARD, GetMessageProc
    			, AfxGetInstanceHandle(), GetCurrentThreadId());
    	}
    }
    

      

    参考 https://blog.csdn.net/booksyhay/article/details/10146103
    // 键盘钩子函数
    LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if(nCode < 0 || nCode == HC_NOREMOVE)
    		return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
    	
            if(lParam & 0x40000000)	// 消息重复就交给下一个hook链
    	{
    		return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
    	}
    	
    	// 通知主窗口。wParam参数为虚拟键码, lParam参数包含了此键的信息
            ::PostMessage(g_hWndCaller, HM_KEY, wParam, lParam);
    	
            return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }
    

      

    这里写的是

    LRESULT CALLBACK CDlgMainPanel::GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	if(nCode < 0 || nCode == HC_NOREMOVE)
    	{
    		return ::CallNextHookEx(gThis->m_hHook, nCode, wParam, lParam);
    	}
    
    	if(lParam & 0x40000000)	// 消息重复就交给下一个hook链
    	{
    		return ::CallNextHookEx(gThis->m_hHook, nCode, wParam, lParam);
    	}
    
    	if (VK_RETURN == wParam)
    	{
    		if (gThis != NULL && gThis->m_render_list_ != NULL)
    		{
    			gThis->m_render_list_->ReceiveEnter();
    		}
    	}
    
    	return CallNextHookEx(gThis->m_hHook, nCode, wParam, lParam);
    }
    

      

    响应的函数

    void CDlgCameraSel::ReceiveEnter()
    {

    if (GetFocus()->m_hWnd == m_edit_camclip_.GetSafeHwnd())
    {
    ChangeEditClip();
    }
    else if (GetFocus()->m_hWnd == m_edit_camview_.GetSafeHwnd())
    {
    ChangeEditCamView();
    }

      

    }
    
    
    参考
    https://blog.csdn.net/greston/article/details/8243115

    WH_KEYBOARD Hook

      在应用程序中,WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息,这些消息通过GetMessage or PeekMessagefunction返回。可以使用这个Hook来监视输入到消息队列中的键盘消息。

     

     

    转自 https://www.cnblogs.com/DuanLaoYe/p/5984658.html

    // WH_GETMESSAGE
    LRESULT CALLBACK GetMsgProc(int iCode, WPARAM wParam, LPARAM lParam)
    {
        if (iCode < 0 || iCode == HC_NOREMOVE)
        {
            return CallNextHookEx(g_hMsg, iCode, wParam, lParam);
        }
    
        PMSG pMsg = (PMSG)lParam;
        if (g_hGameWnd == pMsg->hwnd)
        {
            switch (pMsg->message)
            {
            case WM_SYSCOMMAND:
                if (SC_MINIMIZE == pMsg->wParam) //截获最小化
                {
                    OutputDebugString(_T("GameTips:    -    截获了最小化消息"));
                    pMsg->message = WM_NULL;    //将消息重置为WM_NULL,就达到截获的目的.
                }
                else if (SC_CLOSE == pMsg->wParam)
                {
                    OutputDebugString(_T("GameTips:    -    截获了关闭消息"));
                    pMsg->message = WM_NULL;    //将消息重置为WM_NULL,就达到截获的目的.
                }
                break;
                
            case WM_NCLBUTTONDOWN:
                if (HTMINBUTTON == pMsg->wParam)
                {
                    OutputDebugString(_T("GameTips:    -    截获了最小化按钮消息"));
                    pMsg->message = WM_NULL;    //将消息重置为WM_NULL,就达到截获的目的.
                }
                else if (HTCLOSE == pMsg->wParam)
                {
                    OutputDebugString(_T("GameTips:    -    截获了关闭按钮消息"));
                    pMsg->message = WM_NULL;    //将消息重置为WM_NULL,就达到截获的目的.
                }
                break;
    
            case WM_KEYDOWN:
                if (VK_F11 == pMsg->wParam)
                {
                    OutputDebugString(_T("GameTips:    -    截获了F11"));
                    pMsg->message = WM_NULL;    //将消息重置为WM_NULL,就达到截获的目的.
                }
            }
        }
        return CallNextHookEx(g_hMsg, iCode, wParam, lParam);
    }
    
    // 安装钩子
    EXPORT void SetHook(HWND hGameWnd)
    {
        if (g_hMsg == NULL)
        {
            g_hGameWnd = hGameWnd;
            g_hMsg = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hInstance, 0);
        }
    }
    
    // 卸载钩子
    EXPORT void UnSetHook(void)
    {
        if (g_hMsg)
        {
            UnhookWindowsHookEx(g_hMsg);
            g_hMsg = NULL;
        }
    }

    WH_GETMESSAGE(3):安装一个挂钩处理过程对寄送至消息队列的消息进行监视,详情参见 GetMsgProc 挂钩处理过程.

     

    WH_GETMESSAGE Hook

      应用程序使用WH_GETMESSAGE Hook来监视从GetMessage orPeekMessage函数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入,以及其他发送到消息队列中的消息

    参考 https://blog.csdn.net/weixin_30810583/article/details/96131634

     

    下面的这个是WM_GETMESSAGE,反应消息会多次,不过这个有窗口句柄

    	//LPMSG lpMsg = (LPMSG)lParam;
    	//if( gThis != NULL && gThis->m_render_list_ != NULL
    	//	&& lpMsg->hwnd == gThis->m_render_list_->m_hWnd)
    	//{
    	//	gThis->m_render_list_->PreTranslateMessage(lpMsg);
    	//}
    

      

    原文地址:http://www.zdexe.com/program/201004/587.html

    方法8  : GetMsgProc Function

    The GetMsgProc function is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever the GetMessage or PeekMessage function has retrieved a message from an application message queue. Before returning the retrieved message to the caller, the system passes the message to the hook procedure.

      GetMsgProc是和SetWindowsHookEx方法一起使用的、程序定义的或者库定义的回调函数。无论什么时候,当GetMessage 或者 PeekMessage方法接收到来自应用程序消息队列的消息时,系统都会调用该方法。在将收到的消息返回给调用者之前,系统将消息传递给钩子子程。

     

    The HOOKPROC type defines a pointer to this callback function.GetMsgProc is a placeholder for the application-defined or library-defined function name.

      HOOKPROC类型定义了指向该回调函数的指针。GetMsgProc是程序定义的或者库定义的方法名字。

    Syntax 语法

    LRESULT CALLBACK GetMsgProc(      
        int code,

        WPARAM wParam,

        LPARAM lParam

    );

    Parameters 参数

    code  : [in] Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

      指定钩子子程是否必须处理消息。如果nCode是HC_ACTION,钩子子程就必须处理该消息。如果nCode小于0,钩子子程就必须将该消息传递给CallNextHookEx方法,自己对消息不做进一步处理,并且应该返回由CallNextHookEx方法返回的返回值。

     

    wParam  :[in] Specifies whether the message has been removed from the queue. This parameter can be one of the following values. 

      指定消息是否已经被从队列中移除了。该参数可以是下列值中的一个:

    1.PM_NOREMOVE :Specifies that the message has not been removed from the queue. (An application called the function, specifying the PM_NOREMOVE flag.)

      指定消息尚未从队列中移出。(应用程序在调用该方法的同时指定PM_NOREMOVE标志)

    2.PM_REMOVE Specifies that the message has been removed from the queue. (An application called GetMessage, or it called the PeekMessagefunction, specifying the PM_REMOVE flag.) 

      指定消息已经被从队列中移除了。(程序调用GetMessage 或者PeekMessage方法的同时指定PM_REMOVE标志)

     

    lParam :[in] Pointer to an MSG structure that contains details about the message. 

      指向MSG结构的指针,结构中包含和消息相关的细节。

     

    Return Value 返回值

    If code is less than zero, the hook procedure must return the value returned by CallNextHookEx. If code is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_GETMESSAGE hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.

      如果参数code小于0,钩子子程必须返回由CallNextHookEx返回的返回值。

      如果参数code大于等于0,强烈要求调用CallNextHookEx方法,并返回由该方法返回的返回值;否则,其他已经安装了WH_GETMESSAGE钩子的程序将收不到钩子通知,可能导致行为的错误。如果钩子子程没有调用CallNextHookEx方法,返回值应该是0

     

    Remarks 备注

    The GetMsgProc hook procedure can examine or modify the message. After the hook procedure returns control to the system, the GetMessage orPeekMessage function returns the message, along with any modifications, to the application that originally called it.

      GetMsgProc钩子子程能够检查或者修改消息。在钩子子程将控制权交还给系统之后,GetMessage 或者PeekMessage方法将该消息以及任何修改都一起返回给最初调用它的应用程序。

    An application installs this hook procedure by specifying theWH_GETMESSAGE hook type and a pointer to the hook procedure in a call to the SetWindowsHookEx function.

      应用程序通过下面方式安装该钩子子程:指定WH_ GETMESSAGE钩子类型;指定在调用SetWindowsHookEx方法的函数中指向钩子子程的指针。

  • 相关阅读:
    回调函数仿360开机
    封装运动框架基本函数(多个属性包括透明度和zIndex)
    封装运动框架基本函数(单个属性)
    返回当前样式的函数
    MacOs High Sierra 升级失败解决办法
    Easy-RSA 3 Quickstart README
    Easily use UUIDs in Laravel
    OAuth2.0 原理流程及其单点登录和权限控制
    细说SSO单点登录
    单点登录
  • 原文地址:https://www.cnblogs.com/XiHua/p/16364934.html
Copyright © 2020-2023  润新知