//menudll.h
#pragma once
#include "windows.h"
//
//共享数据段
#pragma data_seg(".MYDATA")
#define IDR_MENU 10002 //定义菜单资源
HHOOK hhookWnd=NULL;
HHOOK hhookMsg=NULL;
char mname[MAX_PATH]="";//新增菜单名称
char wname[MAX_PATH]="";//被挂钩子的窗口caption
HWND hrec=NULL;//接受消息的窗口句柄
bool iscname=false;
bool added=false;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.MYDATA,RWS")
//windowname为窗口caption或者窗口类名,classname为true时是窗口类名
//menuname为添加菜单的菜单名字
//hrecieve为接受菜单点击消息的窗口句柄
void __stdcall addMenu(char* windowname,char* menuname,HWND hrecieve,bool classname=false);
// menuhook.cpp : Defines the entry point for the DLL application.
//
#include "menuhook.h"
//
HINSTANCE g_hInstDLL=NULL; //DLL实例句柄
//
//DLL入口 函数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
g_hInstDLL=(HINSTANCE)hModule;
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
{
if(hhookWnd!=NULL)
UnhookWindowsHookEx(hhookWnd);
if(hhookMsg)
UnhookWindowsHookEx(hhookMsg);
break;
}
default:
break;
}
return TRUE;
}
LRESULT CALLBACK MyCallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
HWND hwnd=NULL;
if(iscname)//由类名获取窗口
hwnd=FindWindow(wname,NULL);
else//由窗口class名称获取窗口
hwnd=FindWindow(NULL,wname);
if(nCode>=0&&hwnd!=NULL)
{
PCWPSTRUCT pcwps = (PCWPSTRUCT)lParam;
if(pcwps->hwnd==hwnd)
{
if(pcwps->message ==WM_COMMAND)//是菜单消息
{
SendMessage(hrec, pcwps->message, pcwps->wParam, pcwps->lParam);
// MessageBox(NULL,"ti shi","caidan",MB_OK);
}
}
}
return CallNextHookEx(hhookWnd, nCode, wParam, lParam);
}
LRESULT CALLBACK MyGetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
HWND hwnd=NULL;
if(iscname)//由类名获取窗口
hwnd=FindWindow(wname,NULL);
else//由窗口class名称获取窗口
hwnd=FindWindow(NULL,wname);
PMSG pmsg = (PMSG)lParam;
if(nCode>=0&&hwnd!=NULL&&pmsg->hwnd==hwnd)
{
if(pmsg->message ==WM_COMMAND)//是菜单消息
{
PostMessage(hrec, pmsg->message, pmsg->wParam, pmsg->lParam);
//MessageBox(NULL,"ti shi","caidan",MB_OK);
}
HMENU hMainMenu=::GetMenu(hwnd);
if (hMainMenu != NULL&&!added)//如果有菜单
{
TCHAR szText[MAX_PATH] = "";//菜单名称缓存区
int iCount=GetMenuItemCount(hMainMenu);//获取菜单的item数
for (int i = 0; i < iCount; i ++)
{
GetMenuString(hMainMenu, i, szText, sizeof(szText), MF_BYPOSITION);//获取菜单项的名字
if (!strcmp(szText,mname))//看一下是不是menuname(如"诚信邮")
{
break;
}
}
if (i >= iCount)//如果额外的菜单就加载菜单
{
AppendMenu(hMainMenu,MF_STRING,IDR_MENU,mname);//添加在主菜单中添加菜单
DrawMenuBar(hwnd);
}
added=true;
}
}
return CallNextHookEx(hhookMsg, nCode, wParam, lParam);
}
//
// 挂接钩子函数
void __stdcall addMenu(char* windowname,char* menuname,HWND hrecieve,bool classname)
{
strcpy(wname,windowname);
strcpy(mname,menuname);
iscname=classname;
hrec=hrecieve;
// 挂接钩子
hhookWnd = SetWindowsHookEx(WH_CALLWNDPROC, MyCallWndProc,g_hInstDLL, 0);
hhookMsg = SetWindowsHookEx(WH_GETMESSAGE, MyGetMsgProc,g_hInstDLL, 0);
}
输出函数def的定义
LIBRARY getmsg
EXPORTS
addMenu @2
把dll、lib文件拷贝到应用程序下,添加到应用程序,应用程序调用dll模块窗口代码
typedef (__stdcall *hook)(char* windowname,char* menuname,HWND hrecieve,bool classname);
void CMenuDlg::OnButton1()
{
HINSTANCE hDll= LoadLibrary("menuhook.dll");
if (hDll != NULL)
{
hook fun= (hook)GetProcAddress(hDll,"addMenu");
if(fun!=NULL)
{
int result = fun("Notepad","菜单",m_hWnd,true);
result = fun("Notepad","菜单",m_hWnd,true); //两次才能不出错,为什么,我也不知道,谁知道告诉我
}
}
}