散分:很奇怪的问题,很多高手都解决不了

zhyaaa123 2006-11-07 11:36:27
很少的代码,
就是用hook机制将dll注入进程插入菜单,
插入有的EXE后菜单全是灰的,
有的却不是灰的,
诡异的很!
踏遍祖国大江南北,
寻访无数英雄豪杰,
都没有找到答案,
不知道在这里能否得到解决,
能够给出有用建议的请再进这贴:
http://community.csdn.net/Expert/topic/5128/5128860.xml?temp=.3527796
分全给你,
下面是主要代码,
其实也就这些代码,
要源码的留下email

void StartHook(HWND hWnd)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = 0;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
BOOL bres = CreateProcess(
NULL
//这个是记事本,不灰
,_T("C:\\WINNT\\system32\\notepad.exe")
//这个是写字板,全灰
,_T("C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe")
//很奇怪,不知道在这两个exe上分别插入会有什么区别
,NULL
,NULL
,false
,NORMAL_PRIORITY_CLASS
,NULL
,NULL
,&si
,&pi);
threadId = pi.dwThreadId;
if(bres == false)
{
AfxMessageBox("CreateProcess failed");
}
glhHook=(HWND)SetWindowsHookEx(WH_KEYBOARD, HookProc, AfxGetInstanceHandle(), 0);
}

LRESULT WINAPI HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if(threadId == GetCurrentThreadId())
{
if(!istheMenuCreated)
{
HWND hwnd = GetActiveWindow();
HMENU theMenu = GetMenu(hwnd);

if(theMenu)
{
int ItemCount = GetMenuItemCount(theMenu);
HMENU pop = CreatePopupMenu();
InsertMenu(pop, 0, MF_BYPOSITION, IDM_ITEM0, "ITEM0");
InsertMenu(pop, 1, MF_BYPOSITION, IDM_ITEM1, "ITEM1");
HMENU pop2 = CreatePopupMenu();
InsertMenu(pop2, 0, MF_BYPOSITION, IDM_ITEM20, "ITEM20");
InsertMenu(pop2, 1, MF_BYPOSITION, IDM_ITEM21, "ITEM21");
InsertMenu(pop, 2, MF_BYPOSITION | MF_STRING|MF_POPUP, (UINT)pop2, "ITEM2");
InsertMenu(theMenu, ItemCount-1, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT)pop, "PCP");
/*
((CFrameWnd *)AfxGetMainWnd())->m_bAutoMenuEnable = FALSE;
if(!EnableMenuItem(pop, IDM_ITEM0, MF_BYPOSITION | MF_ENABLED))
{
AfxMessageBox("menu enable failed");
}
*/
DrawMenuBar(hwnd);
lpOldWndFunc=(WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);
SetWindowLong(hwnd,GWL_WNDPROC, (LONG)WinProc);
}
istheMenuCreated=TRUE;
}
}
return CallNextHookEx((HHOOK)glhHook,nCode,wParam,lParam);
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_ITEM0:
AfxMessageBox("ITEM0");
break;
case IDM_ITEM1:
AfxMessageBox("ITEM1");
break;
case IDM_ITEM20:
AfxMessageBox("ITEM20");
break;
case IDM_ITEM21:
AfxMessageBox("ITEM21");
break;
}
break;
}
return CallWindowProc(lpOldWndFunc, hwnd, uMsg, wParam, lParam);
}

void StopHook()
{
UnhookWindowsHookEx((HHOOK)glhHook);
}
...全文
262 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
DentistryDoctor 2006-11-07
  • 打赏
  • 举报
回复
看目标程序是否有UPDATE_COMMAND_UI啦。
baojian88888 2006-11-07
  • 打赏
  • 举报
回复
在菜单弹出的瞬间,窗口会收到 WM_INITMENUPOPUP 消息,程序可以在这个消息中处理菜单变灰等事情。因此有可能是写字板在处理这个消息时把你加入的菜单给灰掉了,你可以在子类化的WinProc函数中,拦截一下WM_INITMENUPOPUP消息试试
myfriend023 2006-11-07
  • 打赏
  • 举报
回复
帮你顶~
zhyaaa123 2006-11-07
  • 打赏
  • 举报
回复
问题解决,
谢谢baojian88888(机器人),
请到上面的那个地址里面up一下,
分全部给你。
aa3000 2006-11-07
  • 打赏
  • 举报
回复
楼上正解就是 去掉 MF_BYPOSITION
baojian88888 2006-11-07
  • 打赏
  • 举报
回复
为了验证,我刚才专门写了个程序测试了一下,证实在写字板中,拦截WM_INITMENUPOPUP消息,并EnableMenuItem是成功的。

在你最后的代码基础上这样改:

if(uMsg == WM_INITMENUPOPUP)
{
HMENU theMenu = GetMenu(hwnd);
int ItemCount = GetMenuItemCount(theMenu);
HMENU hAddSubMenu = GetSubMenu(theMenu, ItemCount - 2); // 倒数第二个菜单

EnableMenuItem(hAddSubMenu, IDM_ITEM0, MF_ENABLED); // 去掉 MF_BYPOSITION
}
zhyaaa123 2006-11-07
  • 打赏
  • 举报
回复
该成下面这样了还是没有反应:

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_ITEM0:
AfxMessageBox("ITEM0");
break;
case IDM_ITEM1:
AfxMessageBox("ITEM1");
break;
case IDM_ITEM20:
AfxMessageBox("ITEM20");
break;
case IDM_ITEM21:
AfxMessageBox("ITEM21");
break;
}
break;
// case WM_INITMENUPOPUP:
// AfxMessageBox("WM_INITMENUPOPUP");
// break;
// case UPDATE_COMMAND_UI:
// AfxMessageBox("UPDATE_COMMAND_UI");
// break;
}
LRESULT ret = CallWindowProc(lpOldWndFunc, hwnd, uMsg, wParam, lParam);
if(uMsg == WM_INITMENUPOPUP)
{
// ((CFrameWnd *)AfxGetMainWnd())->m_bAutoMenuEnable = FALSE;
if(!EnableMenuItem(pop, IDM_ITEM0, MF_BYPOSITION | MF_ENABLED))
{
AfxMessageBox("menu enable failed");
}
}
return ret;

}
yjgx007 2006-11-07
  • 打赏
  • 举报
回复
This problem is easier to me.

既然你能截获到WM_INITMENUPOPUP, 然后钩住消息函数void OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu),如果没有这个消息函数,就注入它.

在这个函数中, pPopupMenu就是你的菜单了, 在这个函数里加入如下代码:

CCmdUI state;
state.m_pMenu = pPopupMenu;
state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // Menu separator or invalid cmd - ignore it.
if (state.m_nID == (UINT)-1)
{
// Possibly a popup menu, route to first item of that popup.
// Tip: to update command UI for this popup menu, also refer to this below
}
else
{
state.DoUpdate(this, FALSE); // Manually update command UI of each item
}
}
baojian88888 2006-11-07
  • 打赏
  • 举报
回复
在原窗口过程处理之后处理吧,

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT Ret = CallWindowProc(lpOldWndFunc, hwnd, uMsg, wParam, lParam);

switch(uMsg)
{
case WM_INITMENUPOPUP:
//...
}

return Ret;
}

在处理过程中EnableMenuItem你的菜单试一下
zhyaaa123 2006-11-07
  • 打赏
  • 举报
回复
WM_INITMENUPOPUP 可以截获到,截到后再应该怎么处理呢?
case WM_INITMENUPOPUP:
AfxMessageBox("WM_INITMENUPOPUP");
break;


UPDATE_COMMAND_UI 截获不到,怎么样才可以截获到呢?
error C2065: 'UPDATE_COMMAND_UI' : undeclared identifier

case UPDATE_COMMAND_UI:
AfxMessageBox("UPDATE_COMMAND_UI");
break;

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧