钩子 添加额外菜单(dll)

钩子 添加额外菜单(dll)  

2011-01-18 18:04:29|  分类: vc++|字号 订阅

//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);    //两次才能不出错,为什么,我也不知道,谁知道告诉我
   }
  }
 
}

声明:占用各位1个资源分,大家可以在下载后评分,这样就不亏啦~~~多谢支持! 使用工具栏代替原窗口中的菜单(暂不对VB窗口提供支持)。 功能: 1、工具栏替代原来系统默认的菜单栏 2、菜单拥有阴影 3、菜单自绘,不是系统默认的样式 …… …… 使用方法: 编写代码的时候,把 MenuBar.lib 和 MenuBarFunction.h 文件放到代码目录,在需要使用该函数的代码文件头部,声明一下: #pragma comment(lib, "MenuBar.lib") #include "MenuBarFunction.h" 当然啦,也可以用显式声明的方法调用,详细的参数下面有说明,或者看看 MenuBarFunction.h 文件,里面都有注释的了。 所有功能均封装在一个标准DLL里面,导出函数体如下(详情可见 MenuBarFunction.h 文件): 1、BOOL WINAPI MenuBarCreate(HMENU, HWND) 功能:根据菜单句柄创建菜单栏 参数:HMENU-给定菜单句柄、HWND-主窗口句柄 返回:菜单是否创建成功 2、BOOL WINAPI MenuBarCreateByWindow(HWND) 功能:根据窗口中的菜单创建菜单栏 参数:HWND-主窗口句柄 返回:菜单栏是否创建成功 3、BOOL WINAPI MenuBarCreateByResource(UINT, HWND, HINSTANCE) 功能:根据资源文件中的菜单创建菜单栏 参数:UINT-菜单资源符号、HWND-主窗口句柄、HINSTANCE-拥有菜单资源的模块句柄(如为空,则在调用函数的程序中查找) 4、void WINAPI MenuBarDestroy() 功能:移除主窗口中的菜单栏 5、HBITMAP WINAPI MenuBarSetBKBitmap(HBITMAP, BOOL) 功能:设置菜单栏背景图片 参数:HBITMAP-位图句柄、BOOL-是否销毁旧有的位图 返回:旧有位图的句柄(如选择销毁旧有的位图或者函数调用失败,则返回NULL) 6、HMENU WINAPI MenuBarGetBarMenu() 功能:获取菜单栏中的菜单 返回:菜单栏中的菜单句柄 7、HBITMAP WINAPI MenuBarSetLogo(HBITMAP, BOOL) 功能:设置菜单栏右侧图片(类似于文件夹中的菜单栏右侧Logo,不过不是动画) 参数:HBITMAP-位图句柄(注意此位图最好固定尺寸为38*22)、BOOL-是否销毁旧有的位图 返回:旧有位图句柄(如选择销毁旧有的位图或者函数调用失败,则返回NULL) 注意:在不使用菜单栏的时候,请使用MenuBarDestroy()函数移除菜单栏,如果菜单栏是根据主窗口中的菜单创建,则菜单栏移除后将自动把菜单装回主窗口;如果菜单栏是根据资源文件创建,则移除时将自动销毁该菜单。但如果主窗口销毁的情况下,则可不必理会菜单栏是否移除。 因为要出差至外地,暂时没有时间对其进行改进,源代码迟1、2个月就会放出。如在使用过程中遇到什么问题,请发邮件到:SandrerEsa@yahoo.com.cn 下载的资源里有两个程序,一个是Win32、一个是MFC,Win32的程序支持的没那么好(主要表现在菜单阴影部分,在弹出菜单切换的时候会有右边边缘会有一点残影)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值