C ++:尝试挂钩消息框并更改其位置

时间:2014-02-25 05:44:03

标签: c++ windows winapi hook

我最近开始用C ++编写代码,我对它很新。 (我经常使用Javascript,PHP,Java和Obj-C编写代码)

我正在练习如何挂钩消息框并改变其位置。这就是我在.cpp文件中的内容(阅读this SO post后)。

#include <iostream>
#pragma comment(lib,"User32.lib")
#include <windows.h>

HHOOK hhookCBTProc = 0;

LRESULT CALLBACK pfnCBTMsgBoxHook(int nCode, WPARAM wParam, LPARAM lParam){
  if (nCode == HCBT_CREATEWND)
  {
    CREATESTRUCT *pcs = ((CBT_CREATEWND *)lParam)->lpcs;
    if ((pcs->style & WS_DLGFRAME) || (pcs->style & WS_POPUP))
    {
      HWND hwnd = (HWND)wParam;
      SetWindowPos(hwnd, HWND_TOP,130,122, 0, 0,SWP_NOSIZE); 
    }
  }
  return (CallNextHookEx(hhookCBTProc, nCode, wParam, lParam));
}

int main(void)
{
  hhookCBTProc = SetWindowsHookEx(WH_CBT,pfnCBTMsgBoxHook, 
                                0, GetCurrentThreadId());
  int sResult = MessageBox ( NULL, "Hooked!", "oh my", MB_OK );
  UnhookWindowsHookEx(hhookCBTProc);
  return 0;

}

由于某种原因,消息框的位置没有改变。它出了什么问题?

(我知道我可以创建一个自定义窗口或对话框。但我这样做是因为我想学习如何挂钩消息框以及我做错了。)

2 个答案:

答案 0 :(得分:1)

来自docs

  

在HCBT_CREATEWND通知时,窗口已经过了   已创建,但其最终大小和位置可能尚未确定   并且可能尚未建立其父窗口。

也许尝试挂钩到CBT_ACTIVATE。

答案 1 :(得分:1)

首先,你应该在调试器中检查你的钩子是否实际被调用,如果你还没有。

其次,在触发HCBT_CREATEWND挂钩事件时,刚刚创建了窗口 - 系统尚未调整大小并定位它。它将使用挂钩返回后的CREATESTRUCT 中的值<覆盖您的SetWindowPos来覆盖{<1}}。

有关此特定挂钩事件的lParam值,请参阅MSDN中的docs

  

指定指向包含的CBT_CREATEWND结构的长指针   窗口的初始化参数。参数包括   窗口的坐标和尺寸。通过改变这些   参数,CBTProc挂钩程序可以设置初始大小和   窗口的位置。

因此,使用此挂钩更改窗口位置的正确方法是直接修改CREATESTRUCT中的值。

另请注意,对话管理器很可能会在创建之后调整窗口的大小和位置,所以如果您发现这仍然不适合您,您可能需要尝试观察而是HCBT_MOVESIZE事件。