Re: wh_callwndProc hook problem
This is a multi-part message in MIME format.
------=_NextPart_000_0062_01CA3086.2740F5C0
Content-Type: text/plain;
format=flowed;
charset="UTF-8";
reply-type=original
Content-Transfer-Encoding: 7bit
The hookdll.cpp is a sample I wrote to log WM_MENUSELECT:
1) This sample log WM_MENUSELECT, no matter whether the menuitem is clicked (WM_COMMAND) or not.
2) This sample can only log MIIM_STRING (not MF_OWNERDRAW) type menu.
3) This sample can not log Internet Explorer-style menu bar.
4) This sample is designed to log only one process, if you want to log multi-processes in one log file, you need to share and
synchronize logging.
"Sridhar" <Sridhar@discussions.microsoft.com> wrote:
Thank you for your valuable suggestions xiaosi ,
i modified the code..according to your suggestions..
by using spy++(visual studio6.0) i monitor the messages and i came to know
that when i click on the "File" menu of the notepad it generating WM_CREATE
message and if i move cursor to File->New then it generating WM_MENUSELECT
and when i click the new menuitem it generating WH_COMMAND.
i changed my code to monitor WM_MENUSELECT. but now what problem i am
getting is when i open the notepad it is not giving error..if i click on the
menu..notepad is asking to close. if i see in the text file it showing the
following output(this is happening only after closing of notepad).
START RECORDING....
ClassName==Notepad
MenuHandle==
really i am not understanding what is going on...if the message is not
WM_MENUSELELCT it should not do any thing right..but why notepad encountering
the problem(i tried with mspaint also..same problem).
i am posting the modified code of my filter funtion here.
DECLDIR LRESULT CALLBACK MsgHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
char window_class_name[250]={0};
CWPSTRUCT *msg_str = NULL;
if(nCode<0)
return CallNextHookEx(ghKeyHook,nCode,wParam,lParam);
if(HC_ACTION==nCode)
{
msg_str = (CWPSTRUCT *) lParam;
HWND hWndMenu= msg_str->hwnd;
HMENU hMenuHandle=GetMenu(hWndMenu);
if (msg_str->message == WM_MENUSELECT)
{
GetClassName(msg_str->hwnd, window_class_name, sizeof(window_class_name) -
1);
}
FILE *fp;
fp=fopen("C:\\Logdll.txt","ab");
if (strcmp(window_class_name, "Notepad") == 0)
{
fprintf(fp,"\nSTART RECORDING....\n ");
fprintf(fp,"\nClassName==%s\n ",window_class_name);
fprintf(fp,"\nMenuHandle==%s\n ",hMenuHandle);
}
fclose(fp);
}
if(ghKeyHook)
return CallNextHookEx(ghKeyHook,nCode,wParam,lParam);
else
return (LRESULT)NULL;
}
My motive is to know which menu item is selected...like "File" is
selected.."New" is selected..like that.
Please help me on this...
--
--------------------------------------------
At last i learned something for today...:)
------=_NextPart_000_0062_01CA3086.2740F5C0
Content-Type: text/plain;
format=flowed;
name="hook.cpp";
reply-type=original
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="hook.cpp"
#include <stdio.h>
#include <conio.h>
#pragma warning(disable:4996) //_cgets
__declspec(dllimport) bool __stdcall InstallMsgHookProc();
int __cdecl main() {
if (!InstallMsgHookProc()) {
printf("InstallMsgHookProc fail\n");
return 1;
}
printf("InstallMsgHookProc ok, press enter to unhook\n");
char buffer[16] = {10};
_cgets(buffer); //keep main running, if main exit, the hook installed =
by main (call InstallMsgHookProc) will be removed immediately by system.
return 0;
}
------=_NextPart_000_0062_01CA3086.2740F5C0
Content-Type: text/plain;
format=flowed;
name="hookdll.cpp";
reply-type=original
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="hookdll.cpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h> //fprintf, _snprintf
#pragma warning(disable:4996) //fopen
HINSTANCE ghInstance;
HHOOK ghKeyHook;
FILE *gfp;
int __stdcall PrintErr(char *sz, UINT sizeofsz) {
DWORD er = GetLastError(); char bue[128]; *bue = 0;
if (er && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, er, 0, bue, sizeof(bue), 0))
*(DWORD*) bue = '*!*';
return _snprintf(sz, sizeofsz, "ErrorCode %#x(%d) %s", er, er, bue);
}
void __cdecl WriteLog(const char *format, ...) {
SYSTEMTIME t;
GetSystemTime(&t);
SystemTimeToTzSpecificLocalTime(0, &t, &t);
char sztime[64];
_snprintf(sztime, sizeof(sztime), "%04u-%02u-%02u %02u:%02u:%02u.%03u",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
char buf[1024];
_vsnprintf(buf, sizeof(buf), format, (char*)&format + sizeof(format));
fprintf(gfp, "%s %s\r\n", sztime, buf);
return;
}
void __stdcall LogMemuSelect(CWPSTRUCT *cwp) {
HMENU hmenu = (HMENU) cwp->lParam;
WORD flag = HIWORD(cwp->wParam);
if (hmenu && (MF_HILITE & flag) && !(MF_OWNERDRAW & flag)) {
//when click menubar and no menuitem selected, hmenu is null
//SEPARATOR menuitem is not MF_HILITE
//MF_OWNERDRAW menuitem string can not directly get string with GetMenuItemInfo or GetMenuString.
MENUITEMINFO info = {sizeof(MENUITEMINFO)};
char szmenu[250]; szmenu[0] = 0;
info.fMask = MIIM_STRING;
info.dwTypeData = szmenu;
info.cch = sizeof(szmenu)/sizeof(*szmenu);
UINT item = LOWORD(cwp->wParam);
BOOL byPosition = FALSE;
if (MF_POPUP & flag)
byPosition = TRUE;
int result = GetMenuItemInfo(hmenu, item, byPosition, &info);
if (!result)
PrintErr(szmenu, sizeof(szmenu));
char buf[1024];
_snprintf(buf, sizeof(buf), "hmenu\t%x\nitem\t%x\nflag\t%x\nresult\t%x\nszmenu\t%s\n",
hmenu, item, flag, result, szmenu);
OutputDebugStringA(buf);
if (*szmenu) //not log null string
WriteLog(szmenu);
}
return;
}
LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
CWPSTRUCT *cwp = (CWPSTRUCT*) lParam;
if (HC_ACTION == nCode && WM_MENUSELECT == cwp->message) {
LogMemuSelect(cwp);
}
return CallNextHookEx(ghKeyHook, nCode, wParam, lParam);
}
__declspec(dllexport) bool __stdcall InstallMsgHookProc() {
if (ghKeyHook)
return false;
HWND hWnd = FindWindow("NotePad" , NULL);
//HWND hWnd = FindWindow("OpusApp" , NULL); //Miceosoft Word
//HWND hWnd = FindWindow("AdobeAcrobat" , NULL);
if (!hWnd)
return false;
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(hWnd, &processId);
ghKeyHook = SetWindowsHookEx(WH_CALLWNDPROC, MsgHookProc, ghInstance, threadId);
if (!ghKeyHook)
return false;
return true;
}
void __stdcall LogProcess(DWORD reason) {
char szapp[MAX_PATH*2];
GetModuleFileName(0, szapp, sizeof(szapp));
if (DLL_PROCESS_ATTACH == reason) {
WriteLog("PROCESS_ATTACH %s", szapp);
WriteLog("fopen gfp %x", gfp);
} else if (DLL_PROCESS_DETACH == reason) {
WriteLog("PROCESS_DETACH %s", szapp);
WriteLog("fclose gfp %x", gfp);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
if (DLL_PROCESS_ATTACH == reason) {
ghInstance = hModule;
gfp = fopen("J:\\Logdll.txt","ab");
if (!gfp) {
OutputDebugStringA("fopen fail");
return FALSE;
}
LogProcess(reason);
} else if (DLL_PROCESS_DETACH == reason) {
if (gfp) {
LogProcess(reason);
fclose(gfp);
}
}
return TRUE;
}
------=_NextPart_000_0062_01CA3086.2740F5C0--