Link to home
Start Free TrialLog in
Avatar of mite51
mite51

asked on

Hooking menus

I am writing a windows hook to capture some drawing messages. One problem I am having is with menus, also with scrollbars. These types of windows don't show up as children so I don't know how to access them. Is there anyway to locate HWND handles for menus and scrollbars?

 
Avatar of Axter
Axter
Flag of United States of America image

>>Is there anyway to locate HWND handles for menus and scrollbars?

Yes, use the FindWindow() function.
Actually, the Menu doesn't have a window handle.
You can get a menu handle.
Example:
GetMenu(m_hWnd);
Here's a class that can handle windows and there menus.

//Here's the new ExternalPrgController.h file

#pragma warning(disable:4786)
#include <string>
#include <vector>
#include <map>

class WindowPath
{
public:
       enum WP_SearchMethod{WP_Normal, WP_CaptionStartWithWindowName, WP_CaptionEndWithWindowName, WP_CaptionIncludesWindowName, WP_CaptionNotIncludeWindowName};
     WindowPath(std::string szClassName, std::string m_szWindowName="", int nIndex=0, WP_SearchMethod SearchMethod = WP_Normal)
      :m_szClassName(szClassName),m_szWindowName(m_szWindowName),m_nIndex(nIndex), m_SearchMethod(SearchMethod){};
     std::string m_szClassName;
     std::string m_szWindowName;
     int m_nIndex;
       WP_SearchMethod m_SearchMethod;
};

class Ext_Wnd
{
public:
//      Ext_Wnd(HWND hWnd);
      Ext_Wnd(const std::vector<WindowPath> &windowpath, HWND hwndParent = 0, HWND hwndChildAfter = 0);
      Ext_Wnd(const char* ProgramPath, const char* lpCurrentDirectory, char* lpCommandLine=NULL, LPVOID lpEnvironment=NULL, WORD wShowWindow=SW_NORMAL);
      static HWND FindWindow(const std::vector<WindowPath> &windowpath, int index = 0,
                                          HWND hwndParent = 0, HWND hwndChildAfter = 0);
//  Common Windows Commands;
      operator HWND() const;
      void BringWindowToTop(void);
      BOOL EnableWindow(BOOL bEnable);
      HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
      HWND GetLastActivePopup(void);
      HMENU GetMenu(void);
#ifdef __AFX_H__
// This function gets a compile error in Win32  (non-MFC) apps
      HWND GetNextWindow(UINT nFlag = GW_HWNDNEXT);
#endif //_MSC_VER
      HWND GetParent(void);
      LONG GetWindowLong(int nIndex);
      HMENU GetSystemMenu(BOOL bRevert);
      HWND GetTopWindow(void);
      BOOL GetUpdateRect(LPRECT lpRect,BOOL bErase);
      int GetUpdateRgn(HRGN hRgn,BOOL bErase);
      HWND GetWindow(UINT uCmd);
      BOOL GetWindowRect(LPRECT lpRect);
      int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount);
      int GetWindowTextLength(void);
      BOOL HiliteMenuItem(HMENU hmenu, UINT uItemHilite, UINT uHilite);
      BOOL InvalidateRect(CONST RECT *lpRect, BOOL bErase);
      BOOL InvalidateRgn(HRGN hRgn, BOOL bErase);
      BOOL IsChild(HWND hWnd);
      BOOL IsIconic(void);
      BOOL IsWindowEnabled(void);
      BOOL IsWindowVisible(void);
      BOOL IsZoomed(void);
      BOOL KillTimer(UINT uIDEvent);
      BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE );
      BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
      LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
      BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
      HWND SetActiveWindow(void);
      HWND SetCapture(void);
      HWND SetFocus(void);
      HWND SetParent(HWND hWndNewParent);
      BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags);
      int SetWindowRgn(HRGN hRgn, BOOL bRedraw );
      void SetWindowText(std::string text);
      void ShowWindow(int nCmdShow);
      BOOL UpdateWindow();
      BOOL ValidateRect(CONST RECT *lpRect);
      BOOL ValidateRgn(HRGN hRgn);
      //  Custom Window Commands
      void CloseApp(void);
      static HWND StartPrgViaCreateProcess(PROCESS_INFORMATION &pi, const char* ProgramPath,
                         const char* lpCurrentDirectory, char* lpCommandLine=NULL,
                         LPVOID lpEnvironment=NULL, WORD wShowWindow=SW_NORMAL);
      HWND StartPrgViaCreateProcess(const char* ProgramPath, const char* lpCurrentDirectory, char* lpCommandLine=NULL,
                         LPVOID lpEnvironment=NULL, WORD wShowWindow=SW_NORMAL, PROCESS_INFORMATION *pi=NULL);
      BOOL EnableWindow(int nIDDlgItem, BOOL bEnable);
      void SetWindowEditBoxText(std::string text);
      void SendKey(char Key);
      void SendBnClick(HWND hWnd_Button);
      void SendBnClicked(HWND hWnd_Button);
      void SendBnDBClick(HWND hWnd_Button);
      UINT GetMenuCommandID(HMENU hMenu, int TierIndex, const std::vector<std::string> &SearchItem);
      UINT GetMenuCommandID(const std::vector<std::string> &SearchItem);
      HMENU GetMenu(HMENU hMenu, int TierIndex, const std::vector<std::string> &SearchItem, int ListSize);
      HMENU GetMenu(const std::vector<std::string> &SearchItem, int ListSize = -1);
      HINSTANCE GetAppHinstance(void);
      //Data members
      HWND m_hWnd;
};


class Ext_Menu
{// Class template by David Maisonave (david@axter.com)
public:
      Ext_Menu(HMENU hMenu);
      BOOL CreateMenu();
      BOOL CreatePopupMenu();
//      BOOL LoadMenu(LPCTSTR lpszResourceName);
//      BOOL LoadMenu(UINT nIDResource);
      BOOL LoadMenuIndirect(const void* lpMenuTemplate);
      BOOL DestroyMenu();
// Attributes
      operator HMENU() const;
      BOOL operator==(const Ext_Menu& menu) const;
      BOOL operator!=(const Ext_Menu& menu) const;
      BOOL Attach(HMENU hMenu);
      HMENU Detach();
// Ext_Menu Operations
      BOOL DeleteMenu(UINT nPosition, UINT nFlags);
      BOOL TrackPopupMenu(UINT nFlags, int x, int y,Ext_Wnd* pWnd, LPCRECT lpRect = 0);
// Ext_MenuItem Operations
      BOOL AppendMenu(UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL);
//      BOOL AppendMenu(UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);
      UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck);
      UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable);
      UINT GetMenuItemCount() const;
      UINT GetMenuItemID(int nPos) const;
      UINT GetMenuState(UINT nID, UINT nFlags) const;
      int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount,UINT nFlags) const;
      int GetMenuString(UINT nIDItem, std::string& rString, UINT nFlags) const;
      BOOL GetMenuItemInfo(UINT nIDItem, LPMENUITEMINFO lpMenuItemInfo,BOOL fByPos = FALSE);
      Ext_Menu* GetSubMenu(int nPos) const;
      BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL);
//      BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp);
      BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL);
//      BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp);
      BOOL RemoveMenu(UINT nPosition, UINT nFlags);
//      BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags,const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked);
      BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags);
//      BOOL SetDefaultItem(UINT uItem, BOOL fByPos = FALSE);
//      UINT GetDefaultItem(UINT gmdiFlags, BOOL fByPos = FALSE);
// Context Help Functions
      BOOL SetMenuContextHelpId(DWORD dwContextHelpId);
      DWORD GetMenuContextHelpId() const;
 //Data members
      HMENU m_hMenu;
};


typedef void (*CALLBACK_FUNCTION_TYPE1)(void);
typedef void (*CALLBACK_FUNCTION_TYPE2)(WORD);
typedef void (*CALLBACK_FUNCTION_TYPE3)(WORD, std::string);
typedef LRESULT (*CALLBACK_FUNCTION_TYPE4)(int,WPARAM,LPARAM);
typedef LRESULT (*CALLBACK_FORWARD_FUNC)(HWND, UINT, WPARAM, LPARAM);

class MainApp
{
      Ext_Menu menu;
      Ext_Wnd m_ApplicationMainWnd;
      HINSTANCE m_hiApp;
      bool m_bCloseAppInDestructor;
      static std::string AppName;
      static HHOOK nHook;
      static LRESULT CALLBACK      HookProc(int, WPARAM, LPARAM);
      static LRESULT CALLBACK      WndProc(HWND, UINT, WPARAM, LPARAM);
      static CALLBACK_FORWARD_FUNC pWndProc;
      
      static std::map<UINT, CALLBACK_FUNCTION_TYPE1> FunctionCallbackList1;
      static std::map<UINT, CALLBACK_FUNCTION_TYPE2> FunctionCallbackList2;
      static std::map<UINT, CALLBACK_FUNCTION_TYPE3> FunctionCallbackList3;
      static std::map<UINT, CALLBACK_FUNCTION_TYPE4> FunctionCallbackList4;
public:
      HWND m_hCallAppWnd;
      MainApp(const std::vector<WindowPath> &windowpath, bool bCloseAppInDestructor = false);
      MainApp(const char* ProgramPath, const char* lpCurrentDirectory, char* lpCommandLine=NULL,
            LPVOID lpEnvironment=NULL, WORD wShowWindow=SW_NORMAL, bool bCloseAppInDestructor = false);
      ~MainApp();
      Ext_Wnd * GetApplicationMainWnd(void);
      HINSTANCE GetApplicationHinstance(void);
      bool AddToMainMenu(const std::vector<std::string> &NewMenuItem, CALLBACK_FUNCTION_TYPE1 f1, UINT uFlags, UINT_PTR uIDNewItem);
};
//Here's the new ExternalPrgController.cpp file

#include "stdafx.h"

#include "ExternalPrgController.h"

//#include <AFXRES.H>

//*************************************************************************************
//*************************************************************************************
Ext_Wnd::Ext_Wnd(const char* ProgramPath, const char* lpCurrentDirectory, char* lpCommandLine, LPVOID lpEnvironment, WORD wShowWindow)
:m_hWnd(StartPrgViaCreateProcess(ProgramPath, lpCurrentDirectory, lpCommandLine, lpEnvironment, wShowWindow))
{
}

Ext_Wnd::Ext_Wnd(const std::vector<WindowPath> &windowpath, HWND hwndParent, HWND hwndChildAfter)
:m_hWnd(FindWindow(windowpath,0,hwndParent,hwndChildAfter))
{
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//  Common Windows Commands;
////////////////////////////////////////////////////////////////////////////////////
HWND Ext_Wnd::FindWindow(const std::vector<WindowPath> &windowpath, int index, HWND hwndParent,
                                                         HWND hwndChildAfter)
{
    if (index >= windowpath.size()) return 0;
    HWND retrnValue = NULL;
    HWND hwndNextChild = hwndChildAfter;
    int MemberIndex = windowpath[index].m_nIndex;
    std::string szClassName = windowpath[index].m_szClassName.c_str();
    std::string szWindowName = (windowpath[index].m_SearchMethod == WindowPath::WP_Normal)?
            windowpath[index].m_szWindowName.c_str():"";
      int nLenStr_WindowName = windowpath[index].m_szWindowName.size();
    do
    {
            retrnValue = ::FindWindowEx(hwndParent,hwndNextChild,
                  (szClassName.size()>0)?szClassName.c_str():NULL,  
                  (szWindowName.size()>0)?szWindowName.c_str():NULL);
            if (retrnValue == NULL) return retrnValue;
            hwndNextChild=retrnValue;
            char szCurrentWindowName[1024];
            ::GetWindowText(hwndNextChild,szCurrentWindowName,sizeof(szCurrentWindowName));
            switch(windowpath[index].m_SearchMethod)
            {
            case WindowPath::WP_CaptionStartWithWindowName:
                  if (!strncmp(windowpath[index].m_szWindowName.c_str(),
                        szCurrentWindowName,nLenStr_WindowName))
                  {
                        MemberIndex--;
                  }
                  break;
            case WindowPath::WP_CaptionEndWithWindowName:
                  if (nLenStr_WindowName <= strlen(szCurrentWindowName))
                  {
                        if (!strncmp(windowpath[index].m_szWindowName.c_str(),
                              szCurrentWindowName+strlen(szCurrentWindowName)-nLenStr_WindowName,nLenStr_WindowName))
                        {
                              MemberIndex--;
                        }
                  }
                  break;
            case WindowPath::WP_CaptionIncludesWindowName:
                  if (strstr(szCurrentWindowName,windowpath[index].m_szWindowName.c_str()))
                  {
                        MemberIndex--;
                  }
                  break;
            case WindowPath::WP_CaptionNotIncludeWindowName:
                  if (!strstr(szCurrentWindowName,windowpath[index].m_szWindowName.c_str()))
                  {
                        MemberIndex--;
                  }
                  break;
            case WindowPath::WP_Normal:
            default:
                  MemberIndex--;
                  break;
            }
    }while(MemberIndex>-1);
    index++;
    if (index < windowpath.size())
    {
            return FindWindow(windowpath,index,retrnValue,0);
    }
    return retrnValue;
}
Ext_Wnd::operator HWND() const
{
  return m_hWnd;
}
void Ext_Wnd::BringWindowToTop(void)
{
  ::BringWindowToTop(m_hWnd);
}
BOOL Ext_Wnd::EnableWindow(BOOL bEnable)
{
  return ::EnableWindow(m_hWnd, bEnable);
}
HWND Ext_Wnd::FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)
{
  return ::FindWindow(lpClassName,lpWindowName);
}
HWND Ext_Wnd::GetLastActivePopup(void)
{
  return ::GetLastActivePopup(m_hWnd);
}
HMENU Ext_Wnd::GetMenu(void)
{
  return ::GetMenu(m_hWnd);
}
#ifdef __AFX_H__
// This function gets a compile error in Win32  (non-MFC) apps
HWND Ext_Wnd::GetNextWindow(UINT nFlag)
{
  return ::GetNextWindow(m_hWnd, nFlag);
}
#endif //_MSC_VER
HWND Ext_Wnd::GetParent(void)
{
  return ::GetParent(m_hWnd);
}
LONG Ext_Wnd::GetWindowLong(int nIndex)
{
  return ::GetWindowLong(m_hWnd, nIndex);
}
HMENU Ext_Wnd::GetSystemMenu(BOOL bRevert)
{
  return ::GetSystemMenu(m_hWnd, bRevert);
}
HWND Ext_Wnd::GetTopWindow(void)
{
  return ::GetTopWindow(m_hWnd);
}
BOOL Ext_Wnd::GetUpdateRect(LPRECT lpRect,BOOL bErase)
{
  return ::GetUpdateRect(m_hWnd, lpRect, bErase);
}
int Ext_Wnd::GetUpdateRgn(HRGN hRgn,BOOL bErase)
{
  return ::GetUpdateRgn(m_hWnd, hRgn, bErase);
}
HWND Ext_Wnd::GetWindow(UINT uCmd)
{
  return ::GetWindow(m_hWnd, uCmd);
}
BOOL Ext_Wnd::GetWindowRect(LPRECT lpRect)
{
  return ::GetWindowRect(m_hWnd, lpRect);
}
int Ext_Wnd::GetWindowText(LPTSTR lpszStringBuf, int nMaxCount)
{
  return SendMessage(WM_GETTEXT, (WPARAM)nMaxCount,(LPARAM)lpszStringBuf);
}
int Ext_Wnd::GetWindowTextLength(void)
{
  return SendMessage(WM_GETTEXTLENGTH, 0,0);
}
BOOL Ext_Wnd::HiliteMenuItem(HMENU hmenu, UINT uItemHilite, UINT uHilite)
{
  return ::HiliteMenuItem(m_hWnd, hmenu, uItemHilite, uHilite);
}
BOOL Ext_Wnd::InvalidateRect(CONST RECT *lpRect, BOOL bErase)
{
  return ::InvalidateRect(m_hWnd, lpRect, bErase);
}
BOOL Ext_Wnd::InvalidateRgn(HRGN hRgn, BOOL bErase)
{
  return ::InvalidateRgn(m_hWnd, hRgn, bErase);
}
BOOL Ext_Wnd::IsChild(HWND hWnd)
{
  return ::IsChild(m_hWnd, hWnd);
}
BOOL Ext_Wnd::IsIconic(void)
{
  return ::IsIconic(m_hWnd);
}
BOOL Ext_Wnd::IsWindowEnabled(void)
{
  return ::IsWindowEnabled(m_hWnd);
}
BOOL Ext_Wnd::IsWindowVisible(void)
{
  return ::IsWindowVisible(m_hWnd);
}
BOOL Ext_Wnd::IsZoomed(void)
{
  return ::IsZoomed(m_hWnd);
}
BOOL Ext_Wnd::KillTimer(UINT uIDEvent)
{
  return ::KillTimer(m_hWnd, uIDEvent);
}
BOOL Ext_Wnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint )
{
  return ::MoveWindow(m_hWnd,x,y,nWidth,nHeight,bRepaint);
}
BOOL Ext_Wnd::PostMessage(UINT message, WPARAM wParam , LPARAM lParam )
{
  return ::PostMessage(m_hWnd, message, wParam, lParam);
}
LRESULT Ext_Wnd::SendMessage(UINT message, WPARAM wParam , LPARAM lParam )
{
  return ::SendMessage(m_hWnd, message, wParam, lParam);
}
BOOL Ext_Wnd::SendNotifyMessage(UINT message, WPARAM wParam , LPARAM lParam )
{
  return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
}
HWND Ext_Wnd::SetActiveWindow(void)
{
  return ::SetActiveWindow(m_hWnd);
}
HWND Ext_Wnd::SetCapture(void)
{
  return ::SetCapture(m_hWnd);
}
HWND Ext_Wnd::SetFocus(void)
{
  return ::SetFocus(m_hWnd);
}
HWND Ext_Wnd::SetParent(HWND hWndNewParent)
{
  return ::SetParent(m_hWnd, hWndNewParent);
}
BOOL Ext_Wnd::SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
{
  return ::SetWindowPos(m_hWnd, hWndInsertAfter,x,y,cx,cy,nFlags);
}
int Ext_Wnd::SetWindowRgn(HRGN hRgn, BOOL bRedraw )
{
  return ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
}
void Ext_Wnd::SetWindowText(std::string text)
{
  ::SetWindowText(m_hWnd,text.c_str());
}
void Ext_Wnd::ShowWindow(int nCmdShow)
{
  ::ShowWindow(m_hWnd,nCmdShow);
}
BOOL Ext_Wnd::UpdateWindow()
{
  return ::UpdateWindow(m_hWnd);
}
BOOL Ext_Wnd::ValidateRect(CONST RECT *lpRect)
{
  return ::ValidateRect(m_hWnd, lpRect);
}
BOOL Ext_Wnd::ValidateRgn(HRGN hRgn)
{
  return ::ValidateRgn(m_hWnd, hRgn);
}

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//  Custom Window Commands
////////////////////////////////////////////////////////////////////////////////////
void Ext_Wnd::CloseApp(void)
{
      PostMessage(WM_SYSCOMMAND,(WPARAM)SC_CLOSE,0);
}
BOOL Ext_Wnd::EnableWindow(int nIDDlgItem, BOOL bEnable)
{
      HWND hWnd = ::GetDlgItem(m_hWnd,nIDDlgItem);
      if (hWnd) return ::EnableWindow(hWnd, bEnable);
      return FALSE;
}
void Ext_Wnd::SetWindowEditBoxText(std::string text)
{
      SendMessage(WM_SETTEXT,0,(LPARAM)(LPCTSTR)text.c_str());
}
void Ext_Wnd::SendKey(char Key)
{
      char data[8];
      memset(data,0,sizeof(data));
      PostMessage(WM_CHAR,Key,(LPARAM)data);
}
void Ext_Wnd::SendBnClick(HWND hWnd_Button)
{
      ::SendMessage(hWnd_Button,BM_CLICK,0,0);
}
void Ext_Wnd::SendBnClicked(HWND hWnd_Button)
{
      SendMessage(WM_COMMAND,HIWORD(BN_CLICKED)+LOWORD(1),(LPARAM)hWnd_Button);
}
void Ext_Wnd::SendBnDBClick(HWND hWnd_Button)
{
      SendMessage(WM_COMMAND,HIWORD(BN_DBLCLK)+LOWORD(1),(LPARAM)hWnd_Button);
}
UINT Ext_Wnd::GetMenuCommandID(HMENU hMenu, int TierIndex, const std::vector<std::string> &SearchItem)
{
      if (!hMenu) return 0;
      for (int m = 0;m < GetMenuItemCount(hMenu);m++)
      {
         char mnItem[1024];
         if (GetMenuString(hMenu,m,mnItem,sizeof(mnItem),MF_BYPOSITION))
         {
                  if (SearchItem[TierIndex] == mnItem)
                  {
                         if (SearchItem.size() == (TierIndex+1))
                         {
                                return ::GetMenuItemID(hMenu,m);
                         }
                         HMENU SubHmenu = ::GetSubMenu(hMenu,m);
                         if (SubHmenu)
                         {
                                return GetMenuCommandID(SubHmenu,TierIndex+1,SearchItem);
                         }
                         return 0;
                  }
         }
      }
      return 0;
}
UINT Ext_Wnd::GetMenuCommandID(const std::vector<std::string> &SearchItem)
{
      HMENU hMenu = GetMenu();
      if (!hMenu) return 0;
      return GetMenuCommandID(hMenu, 0, SearchItem);
}
HMENU Ext_Wnd::GetMenu(HMENU hMenu, int TierIndex, const std::vector<std::string> &SearchItem, int ListSize)
{
      if (!hMenu) return 0;
      for (int m = 0;m < GetMenuItemCount(hMenu);m++)
      {
            char mnItem[1024];
            if (GetMenuString(hMenu,m,mnItem,sizeof(mnItem),MF_BYPOSITION))
            {
                  if (SearchItem[TierIndex] == mnItem)
                  {
                        if (ListSize == (TierIndex+1))
                        {
                              return GetSubMenu(hMenu,m);
                        }
                        HMENU SubHmenu = ::GetSubMenu(hMenu,m);
                        if (SubHmenu)
                        {
                              return GetMenu(SubHmenu,TierIndex+1,SearchItem, ListSize);
                        }
                        return 0;
                  }
            }
      }
      return 0;
}
HMENU Ext_Wnd::GetMenu(const std::vector<std::string> &SearchItem, int ListSize)
{
      HMENU hMenu = GetMenu();
      if (!hMenu) return 0;
      if (ListSize == -1) ListSize = SearchItem.size()-1;
      return GetMenu(hMenu, 0, SearchItem, ListSize);
}
HWND Ext_Wnd::StartPrgViaCreateProcess(const char* ProgramPath, const char* lpCurrentDirectory,
                                                                               char* lpCommandLine, LPVOID lpEnvironment, WORD wShowWindow, PROCESS_INFORMATION *pi)
{
      PROCESS_INFORMATION dummy;
      if (pi == NULL)
      {
            pi = &dummy;
      }
    return StartPrgViaCreateProcess(*pi,ProgramPath, lpCurrentDirectory, lpCommandLine, lpEnvironment, wShowWindow);
}

HWND Ext_Wnd::StartPrgViaCreateProcess(PROCESS_INFORMATION &pi, const char* ProgramPath,
                                                                               const char* lpCurrentDirectory, char* lpCommandLine, LPVOID lpEnvironment, WORD wShowWindow)
{
    STARTUPINFO si;
    memset(&si,0,sizeof(si));
    si.wShowWindow = wShowWindow;
    memset(&pi,0,sizeof(pi));
    if (!CreateProcess(ProgramPath,lpCommandLine,NULL,NULL,TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS,lpEnvironment,lpCurrentDirectory,&si,&pi))
      {
            LPVOID lpMsgBuf;
            ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                        NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL);
            ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
            LocalFree(lpMsgBuf);
            return NULL;
      }
      Sleep(500);
    HWND hwndNextChild = NULL;
    do
    {
            hwndNextChild = ::FindWindowEx(0,hwndNextChild,NULL,NULL);
            if (hwndNextChild)
            {
                  DWORD dwProcessId;
                  DWORD dwThread = GetWindowThreadProcessId(hwndNextChild, &dwProcessId) ;
                  if(dwProcessId == pi.dwProcessId || pi.dwThreadId == dwThread )
                  {
                        break;
                  }
                  bool BreakDo = false;
                  HWND hwndNextChildChild = NULL;
                  do
                  {
                        hwndNextChildChild = ::FindWindowEx(hwndNextChild,hwndNextChildChild,NULL,NULL);
                        if (hwndNextChildChild)
                        {
                              dwThread = GetWindowThreadProcessId(hwndNextChildChild, &dwProcessId) ;
                              if(dwProcessId == pi.dwProcessId || pi.dwThreadId == dwThread )
                              {
                                    BreakDo=true;
                                    break;
                              }
                        }
                  }while(hwndNextChildChild);
                  if (BreakDo) break;
            }
    }while(hwndNextChild);
    return hwndNextChild;
}

HINSTANCE Ext_Wnd::GetAppHinstance(void)
{
      return (HINSTANCE)GetClassLong(m_hWnd,GCL_HMODULE);
}


//*************************************************************************************
//*************************************************************************************
Ext_Menu::Ext_Menu(HMENU hMenu):m_hMenu(hMenu)
{
}

BOOL Ext_Menu::CreateMenu()
{
      m_hMenu = ::CreateMenu();
      if (m_hMenu == NULL) return FALSE;
      return TRUE;
}
BOOL Ext_Menu::CreatePopupMenu()
{
      m_hMenu = ::CreatePopupMenu();
      if (m_hMenu == NULL) return FALSE;
      return TRUE;
}
/*
BOOL Ext_Menu::LoadMenu(LPCTSTR lpszResourceName)
{
      return ::LoadMenu(m_hMenu,lpszResourceName)
}

BOOL Ext_Menu::LoadMenu(UINT nIDResource)
{
      return ::LoadMenu(m_hMenu,nIDResource)
}
*/
BOOL Ext_Menu::LoadMenuIndirect(const void* lpMenuTemplate)
{
      m_hMenu = ::LoadMenuIndirect(lpMenuTemplate);
      if (m_hMenu == NULL) return FALSE;
      return TRUE;
}

BOOL Ext_Menu::DestroyMenu()
{
      return ::DestroyMenu(m_hMenu);
}

// Attributes
Ext_Menu::operator HMENU() const
{
      return m_hMenu;
}

BOOL Ext_Menu::operator==(const Ext_Menu& menu) const
{
      return (m_hMenu==menu.m_hMenu)?TRUE:FALSE;
}

BOOL Ext_Menu::operator!=(const Ext_Menu& menu) const
{
      return (m_hMenu!=menu.m_hMenu)?TRUE:FALSE;
}

BOOL Ext_Menu::Attach(HMENU hMenu)
{
      if (m_hMenu!=NULL) return FALSE;
      m_hMenu = hMenu;
      return TRUE;
}

HMENU Ext_Menu::Detach()
{
      HMENU hMenu = m_hMenu;
      m_hMenu = NULL;
      return hMenu;
}

// Ext_Menu Operations
BOOL Ext_Menu::DeleteMenu(UINT nPosition, UINT nFlags)
{
      return ::DeleteMenu(m_hMenu,nPosition,nFlags);
}

BOOL Ext_Menu::TrackPopupMenu(UINT nFlags, int x, int y,Ext_Wnd* pWnd, LPCRECT lpRect)
{
      return ::TrackPopupMenu(m_hMenu,nFlags,x,y,0,pWnd->m_hWnd,lpRect);
}

// Ext_MenuItem Operations
BOOL Ext_Menu::AppendMenu(UINT nFlags, UINT nIDNewItem,LPCTSTR lpszNewItem)
{
      return ::AppendMenu(m_hMenu,nFlags,nIDNewItem,lpszNewItem);
}

/*
BOOL Ext_Menu::AppendMenu(UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp)
{
}
*/      
UINT Ext_Menu::CheckMenuItem(UINT nIDCheckItem, UINT nCheck)
{
      return ::CheckMenuItem(m_hMenu,nIDCheckItem,nCheck);
}

UINT Ext_Menu::EnableMenuItem(UINT nIDEnableItem, UINT nEnable)
{
      return ::EnableMenuItem(m_hMenu,nIDEnableItem,nEnable);
}

UINT Ext_Menu::GetMenuItemCount() const
{
      return ::GetMenuItemCount(m_hMenu);
}

UINT Ext_Menu::GetMenuItemID(int nPos) const
{
      return ::GetMenuItemID(m_hMenu,nPos);
}

UINT Ext_Menu::GetMenuState(UINT nID, UINT nFlags) const
{
      return ::GetMenuState(m_hMenu,nID,nFlags);
}

int Ext_Menu::GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount,UINT nFlags) const
{
      return ::GetMenuString(m_hMenu,nIDItem,lpString,nMaxCount,nFlags);
}

int Ext_Menu::GetMenuString(UINT nIDItem, std::string& rString, UINT nFlags) const
{
      char buffer[2048];
      int nReturnValue = ::GetMenuString(m_hMenu,nIDItem,buffer,sizeof(buffer),nFlags);
      rString = buffer;
      return nReturnValue;
}

BOOL Ext_Menu::GetMenuItemInfo(UINT nIDItem, LPMENUITEMINFO lpMenuItemInfo,BOOL fByPos)
{
      return ::GetMenuItemInfo(m_hMenu,nIDItem,fByPos,lpMenuItemInfo);
}

Ext_Menu* Ext_Menu::GetSubMenu(int nPos) const
{
      return (Ext_Menu*)::GetSubMenu(m_hMenu,nPos); //???????????????????
}

BOOL Ext_Menu::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,LPCTSTR lpszNewItem)
{
      return ::InsertMenu(m_hMenu,nPosition,nFlags,nIDNewItem,lpszNewItem);
}

/*      
BOOL Ext_Menu::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp)
{
}
*/
BOOL Ext_Menu::ModifyMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,LPCTSTR lpszNewItem)
{
      return ::ModifyMenu(m_hMenu,nPosition,nFlags,nIDNewItem,lpszNewItem);
}

/*      
BOOL Ext_Menu::ModifyMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp)
{
}
*/
BOOL Ext_Menu::RemoveMenu(UINT nPosition, UINT nFlags)
{
      return ::RemoveMenu(m_hMenu,nPosition,nFlags);
}

/*      
BOOL Ext_Menu::SetMenuItemBitmaps(UINT nPosition, UINT nFlags,const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked)
{
}
*/
BOOL Ext_Menu::CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags)
{
      return ::CheckMenuRadioItem(m_hMenu,nIDFirst,nIDLast,nIDItem,nFlags);
}

/*      
BOOL Ext_Menu::SetDefaultItem(UINT uItem, BOOL fByPos)
{
}
UINT Ext_Menu::GetDefaultItem(UINT gmdiFlags, BOOL fByPos)
{
}
*/

// Context Help Functions
BOOL Ext_Menu::SetMenuContextHelpId(DWORD dwContextHelpId)
{
      return ::SetMenuContextHelpId(m_hMenu,dwContextHelpId);
}

DWORD Ext_Menu::GetMenuContextHelpId() const
{
      return ::GetMenuContextHelpId(m_hMenu);
}


//*************************************************************************************
//*************************************************************************************
std::map<UINT, CALLBACK_FUNCTION_TYPE1> MainApp::FunctionCallbackList1;
std::map<UINT, CALLBACK_FUNCTION_TYPE2> MainApp::FunctionCallbackList2;
std::map<UINT, CALLBACK_FUNCTION_TYPE3> MainApp::FunctionCallbackList3;
std::map<UINT, CALLBACK_FUNCTION_TYPE4> MainApp::FunctionCallbackList4;

std::string MainApp::AppName = "";

MainApp::MainApp(const std::vector<WindowPath> &windowpath, bool bCloseAppInDestructor)
: m_ApplicationMainWnd(windowpath), menu(m_ApplicationMainWnd.GetMenu()), m_hiApp(m_ApplicationMainWnd.GetAppHinstance()),
m_bCloseAppInDestructor(bCloseAppInDestructor), m_hCallAppWnd(NULL)
{
}
MainApp::MainApp(const char* ProgramPath, const char* lpCurrentDirectory, char* lpCommandLine, LPVOID lpEnvironment, WORD wShowWindow, bool bCloseAppInDestructor)
: m_ApplicationMainWnd(ProgramPath,lpCurrentDirectory,lpCommandLine,lpEnvironment,wShowWindow), menu(m_ApplicationMainWnd.GetMenu()),
m_hiApp(m_ApplicationMainWnd.GetAppHinstance()), m_bCloseAppInDestructor(bCloseAppInDestructor), m_hCallAppWnd(NULL)
{
}

MainApp::~MainApp()
{
      if (nHook !=  NULL)
      {
            UnhookWindowsHookEx(nHook);
      }
      if (pWndProc !=  NULL)
      {
            ::SetClassLong(m_ApplicationMainWnd.m_hWnd,GCL_WNDPROC,(long)pWndProc);
      }
      if (m_bCloseAppInDestructor)
      {
            m_ApplicationMainWnd.CloseApp();
      }
}

Ext_Wnd *MainApp::GetApplicationMainWnd(void)
{
      return &m_ApplicationMainWnd;
}

HINSTANCE MainApp::GetApplicationHinstance(void)
{
      return m_hiApp;
}

bool MainApp::AddToMainMenu(const std::vector<std::string> &NewMenuItem, CALLBACK_FUNCTION_TYPE1 f1, UINT uFlags, UINT_PTR uIDNewItem)
{
      Ext_Menu hParentMenu = m_ApplicationMainWnd.GetMenu(NewMenuItem,NewMenuItem.size()-2);
      if (hParentMenu.m_hMenu == NULL) return false;
      if (!hParentMenu.AppendMenu(uFlags,uIDNewItem,NewMenuItem.at(NewMenuItem.size()-1).c_str())) return false;
      FunctionCallbackList1[uIDNewItem] = f1;
      if (nHook ==  NULL)
      {
            nHook = ::SetWindowsHookEx(WH_CALLWNDPROC, HookProc, 0, 0);
      }
      if (pWndProc ==  NULL)
      {
            pWndProc = (CALLBACK_FORWARD_FUNC)::SetClassLong(m_hCallAppWnd,GCL_WNDPROC,(long)&WndProc);
      }
      return true;
}

HHOOK  MainApp::nHook=NULL;
LRESULT CALLBACK MainApp::HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
      if (wParam)
      {
            WORD x = wParam;
      }
      return ::CallNextHookEx(nHook, nCode, wParam, lParam);
}      
CALLBACK_FORWARD_FUNC MainApp::pWndProc=NULL;
LRESULT CALLBACK MainApp::WndProc(HWND hWnd, UINT uCode,WPARAM wParam,LPARAM lParam)
{
      PMSG pmsg = (PMSG) lParam;
      if (FunctionCallbackList1[wParam] != NULL)
      {
            FunctionCallbackList1[wParam]();
      }
      else if (FunctionCallbackList2[wParam] != NULL)
      {
            FunctionCallbackList2[wParam](wParam);
      }
      else if (FunctionCallbackList3[wParam] != NULL)
      {
            FunctionCallbackList3[wParam](wParam,AppName.c_str());
      }
      else if (FunctionCallbackList4[wParam] != NULL)
      {
            FunctionCallbackList4[wParam](uCode,wParam,lParam);
      }
      if (pWndProc != NULL) return  pWndProc(hWnd,uCode,wParam,lParam);
      return 0;
}
The following is example on how to select a menu item.
This example works on the windows NotePad program.
It selects the Word Wrap menu item, so that the check mark turns on and off.

std::vector<WindowPath> windowpath_list;
windowpath_list.push_back(WindowPath("Notepad"));
Ext_Wnd NotePadApp(windowpath_list);
std::vector<std::string> MenuItem;
MenuItem.push_back("&Edit");
MenuItem.push_back("&Word Wrap");
UINT Cmd = NotePadApp.GetMenuCommandID(MenuItem);
if (Cmd) NotePadApp.PostMessage(WM_COMMAND,Cmd,0);
Disregard the hook functions in MainApp class.  I'm still working on them, and they're not finish.
In fact, you don't have to use MainApp class at all.
Avatar of mite51
mite51

ASKER

thats interesting, looks like you have done a lot of work. It will take me some time to understand exactly what is going on.

Is there a way to hook an the WINPROC for a HMENU?
That's the part I've been stuck at.

I can get the handle to the menu, and I can add a menu item with no problem.  But I can't seem to get a hook on it.
I haven't tried using a system hook, so you might have some luck with that.
Avatar of mite51

ASKER

I am using a system wide hook. It seems that the system has a section reserved for menus scroll bars and dialog boxes. I am not sure whats up with that.

listening......
If this proposed answer has helped you, please accept it, grade it and close this question.  If it is not, reject it and add comments as to your progress and what else is needed.

Thanks,
Moondancer
Community Support Moderator @ Experts Exchange
Avatar of mite51

ASKER

Axter, did you ever manager to hook the menus? I am working on a theory that you actually have to make a kernel hook to hook menu functions, however, I am still working on it.

Jason
>>Axter, did you ever manager to hook the menus?
No.

Please let me know if you have any luck.
SHOULD I FORCE ACCEPT THIS TO CLOSE IT?  Again months later.

Moondancer
Community Support Moderator @ Experts Exchange
ASKER CERTIFIED SOLUTION
Avatar of SpideyMod
SpideyMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial