也许有很多人曾和我一样, 对Office XP里面的菜单的阴影效果羡慕不已,它不需要在Windows XP 中就可以在菜单后面显示阴影, 当然在Windows XP中, 已经完全支持菜单阴影了。虽然我们不一定很有必要自己来实现这个较难实现的效果。但是正如有很多人想实现那种IE风格的菜单栏一样,尽管它 们并不能为我们带来更多实用的功能, 却可以使我们的程序看起来与众不同。:)
菜单也是一个窗口, 假如我们能得到它的窗口的句柄, 要实现像添加阴影这样的效果, 就不会很难了。可惜我们根本找不到这个窗口是在哪里被创建的,也没办法很容易地取得它的窗口句柄,甚至几乎难以相信它是一个窗口,因为我实在找不到它的窗口句柄啊。经过对许多别人已经做好的类的源代码的"研究", 我终于找到了一个方法。那就是万能的钩子,如果说在Windows里面抓"人",连钩子也办不到的话,那我就不知道该用什么方法实现了,呵呵。
下面我就一起来看看如何抓到这些"可恶"的家伙吧。为了便于移植,我们就写一个专用的类吧,就取名为CMenuWndHook。添加两个静态成员先:
static CMap m_WndMenuMap;
static HHOOK m_hMenuHook;
被我们抓到的这些家伙肯定不止一个,我们需要一个映射模板类来保存它们的句柄和对应的CMenuWndHook 类对象的指针。m_hMenuHook则为我们将要创建的钩子的钩子句柄。再在CPP文件中初始化它们:
CMap CMenuWndHook::m_WndMenuMap;
下面再添加两个函数来做安装与卸载hook之用, 它们都是静态函数:
HHOOK CMenuWndHook::m_hMenuHook = NULL;void CMenuWndHook::InstallHook()
Windows之下一般用上面的SetWindowsHookEx API函数来安装HOOK,它的函数原型如下:
{
if (m_hMenuHook == NULL)
{
m_hMenuHook = ::SetWindowsHookEx(WH_CALLWNDPROC,
WindowHook,
AfxGetApp()->m_hInstance,
::GetCurrentThreadId());
}
}