【问题标题】:How to read the data from lParam (the pointers value)如何从 lParam 读取数据(指针值)
【发布时间】:2013-07-05 09:58:21
【问题描述】:

我做了一个小应用程序,通过 SendMessage 和 EM_REPLACESEL 将文本发送到记事本。

现在我正在尝试使用记事本获取 EM_REPLACESEL 值(lParam 值,在本例中为“GET THIS TEXT”文本)。

编辑:看这张照片:http://i.stack.imgur.com/8scNL.jpg

钩子工作正常,我的问题是监听 EM_REPLACESEL 消息并从 lParam 中获取值。

当消息发送到记事本时,此代码工作正常:

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    Beep (2000,100);
    return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}

所以现在我想拦截 EM_REPLACESEL 消息。这工作:

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    if (nCode == EM_REPLACESEL)
    {
        Beep (2000,100);
    }
    return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}

1) 如何监听 EM_REPLACESEL 消息?

2) 当我收到消息时,如何获取 lParam 值,例如在 MessageBox 中显示它。像这样的:

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    if (nCode == EM_REPLACESEL)
    {
        MSG *lpMsg;
        lpMsg = (MSG *) lParam;
        MessageBox(NULL,(LPCWSTR)lpMsg,NULL,NULL);
    }
    return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}

谢谢

【问题讨论】:

    标签: winapi callback


    【解决方案1】:

    EM_REPLACESEL 是已发送消息,而不是已发布消息,因此您需要使用WH_CALLWNDPROC 挂钩而不是WH_GETMESSAGE 挂钩,例如:

    LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) 
    {
        if (nCode == HC_ACTION) {
            CWPSTRUCT* cwps = (CWPSTRUCT*)lParam;
            if (cwps->message == EM_REPLACESEL) {
                Beep (2000,100);
                // etc..
            }
        }
        return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }
    
    ... = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, ...), 
    

    【讨论】:

    • 太好了,雷米。有用。谢谢。然后如何在消息框中显示该值?这只是给垃圾: MessageBox(NULL,(LPCWSTR)cwps,NULL,NULL); ?
    • CWPSTRUCT 是一个结构,而不是一个字符串。您不能将其类型转换为 LPCWSTR。要从 EM_REPLACESEL 消息中提取文本,您需要改为类型转换 CWPSTRUCT::lParam 字段:if (IsUnicodeWindow(cwps->hwnd)) MessageBoxW(NULL, (LPWSTR)cwps->lParam, ...); else MessageBoxA(NULL, (LPSTR)cwps->lParam, ...);
    【解决方案2】:

    您的GetMsgProc() callback 编码错误。仔细阅读链接的 MSDN 页面,了解回调参数的含义。 nCode 参数是不是 消息编号,它指定您是否应该处理该消息。您想使用传递的 lParam 来恢复您截获的消息。让它看起来与此类似:

    LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
    {
        if (nCode == HC_ACTION) {
            MSG* pmsg = (MSG*)lParam;
            if (pmsg->message == WM_LBUTTONDOWN) {
                Beep (2000,100);
                // etc..
            }
        }
        return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }
    

    请注意,您似乎使用了 WH_GETMESSAGE 挂钩。它仅适用于使用 PostMessage() 发布到消息队列的消息。但是 EM_REPLACESEL 是使用 SendMessage() 发送的消息。这需要一个不同的钩子,WH_CALLWNDPROC 或 WH_CALLWNDPROCRET。

    【讨论】:

    • 谢谢,汉斯。我猜你的意思是 MSG* pmsg = (MSG*)lParam,对吧?但它不起作用,“哔”永远不会被调用。如果我在“if (pmsg->message == EM_REPLACESEL)”之前移动“哔”,它就可以工作。但是 Spy++ 显示 EM_REPLACESEL 作为消息进来,所以我应该在你的例子中被调用。有什么问题的提示吗?
    • 对。想想看,你似乎用错了钩子。答案已更新。
    • 将其更改为 CallWndProc CALLBACK 函数(并将 SetWindowsHook 更改为 g_hHook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstDll, npThreadId),但我有同样的问题 = 没有蜂鸣声(也用 CallWndRetProc 尝试过)
    • @TheisKristensen:CallWndProc 钩子的lParam 不是MSG*,而是CWPSTRUCT*。您在更改代码时是否考虑到了这一点? CWPSTRUCT *cwps = (CWPSTRUCT*)lParam; if (cwps->message == EM_REPLACESEL) { ... }MSGCWPSTRUCT 在不同的字段偏移处包含消息 ID。
    【解决方案3】:

    这是我通常的做法。

    LRESULT CALLBACK GetMsgProc(MSG nCode, WPARAM wParam, LPARAM lParam) 
    {
       while(GetMessage(&nCode, NULL, 0, 0) > 0)
       {
          if(nCode.message == EM_REPLACESEL)
          {
             //Do something
          }
          else
             DispatchMessage(&nCode);
       }
       return 0;
    }
    

    【讨论】:

    • 谢谢艾莎。但是我这个兼容一个 SetWindowsHook (HOOKPROC),那么 CALLBACK 函数中的 CallNextHookEx 函数呢?
    猜你喜欢
    • 1970-01-01
    • 2020-10-16
    • 2020-10-24
    • 2022-11-30
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多