locked
Menu item disabled

    Question

  • Hi all:
     I've received a task to insert a menu to a specified process by inject a dll to target process, after inject my dll to target process succssfully and  the menu displayed, but here comes the question, the submenu always gray(disabled). The problem is mainly on FrameWnd::m_bAutomMenuEnable filed, MFC CMainFrame class set this filed TRUE in default, that means any menu item without add a message handler will automatically disabled. I try to use following code:

    CWnd* pMainWnd=CWnd::FromHandle(g_hWnd);
    pFrameWnd=(CFrameWnd*)(pMainWnd);
    pFrameWnd->m_bAutoMenuEnable=FALSE;

    try to set the m_bAutoMenuEnable=FALSE. but it seemed does't worked well(the pFrameWnd is not NULL but all fields are not valid through debug). Is there any way to modify this filed or another way to add(register) a command handler in order to enable my menu item?
    How can I Enable the sub menu item, Please help me. Also I want someone explain why CWnd* pMainWnd=CWnd::FromHandle(g_hWnd) can not work. Thanks
    All code:

    DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
    {
    	// Remove this if you use lpReserved
    	UNREFERENCED_PARAMETER(lpReserved);
    
    	if (dwReason == DLL_PROCESS_ATTACH)
    	{
    		TRACE0("IMenuMfc.DLL Initializing!\n");
    		
    		// Extension DLL one-time initialization
    		if (!AfxInitExtensionModule(IMenuMfcDLL, hInstance))
    			return 0;
    
    		// Insert this DLL into the resource chain
    		// NOTE: If this Extension DLL is being implicitly linked to by
    		// an MFC Regular DLL (such as an ActiveX Control)
    		// instead of an MFC application, then you will want to
    		// remove this line from DllMain and put it in a separate
    		// function exported from this Extension DLL. The Regular DLL
    		// that uses this Extension DLL should then explicitly call that
    		// function to initialize this Extension DLL. Otherwise,
    		// the CDynLinkLibrary object will not be attached to the
    		// Regular DLL's resource chain, and serious problems will
    		// result.
    
    		new CDynLinkLibrary(IMenuMfcDLL);
    
    
    		HMENU hMenu=NULL;
    		HMENU hMyMenu=NULL;
    		HMENU hSubMenu=NULL;
    		DWORD dwPid=0;
    
    		CFrameWnd* pFrameWnd=NULL;
    		
    
    		dwPid=GetCurrentProcessId();
    		g_hWnd=GetWndFromProcID(dwPid);
    		hMenu=::GetMenu(g_hWnd);
    
    		CWnd* pMainWnd=CWnd::FromHandle(g_hWnd);
    		pFrameWnd=(CFrameWnd*)(pMainWnd);
    		pFrameWnd->m_bAutoMenuEnable=FALSE;
    
    		hMenu=GetMenu(g_hWnd);
    		hMyMenu=LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU_OPTION));
    		hSubMenu=GetSubMenu(hMyMenu,0);
    		InsertMenu(hMenu,2,MF_STRING|MF_BYPOSITION|MF_POPUP|MF_ENABLED,(UINT)hSubMenu,L"Option");
    		hSubMenu=GetSubMenu(hMyMenu,1);
    		EnableMenuItem(hMyMenu,(UINT)hSubMenu,MF_BYCOMMAND|MF_ENABLED);
    		//DrawMenuBar(g_hWnd);
    
    		g_oldProc=(WNDPROC)SetWindowLong(g_hWnd,GWL_WNDPROC,(LONG)MyWndProc);
    		
    
    	}
    	else if (dwReason == DLL_PROCESS_DETACH)
    	{
    		TRACE0("IMenuMfc.DLL Terminating!\n");
    
    		// Terminate the library before destructors are called
    		AfxTermExtensionModule(IMenuMfcDLL);
    
    		SetWindowLong(g_hWnd,GWL_WNDPROC,(LONG)g_oldProc);
    	}
    	return 1;  // ok
    }

    I want to learn more
    Friday, June 25, 2010 7:20 AM

All replies

  • You will need to set up a message hander function for the ID for the menu.  The function will be called when the menu is selected.  Otherwise, the MFC framework will disable the menu assuming that there is nothing for it to do.  You can also add an handler to update the GUI based on conditions.

    http://msdn.microsoft.com/en-us/library/a5f1bcxd(VS.80).aspx

    http://msdn.microsoft.com/en-us/library/b8c866kb(v=VS.80).aspx

    You can add these using the wizards and selecting and "event" for the menu.

    Tom

    Friday, June 25, 2010 4:50 PM
  • BTW, I would have an ON_COMMAND_UI handler and just set a flag for whether or not the DLL is available and loaded and set the menu item to disable or enabled based on the bool flag.

    Tom

    Friday, June 25, 2010 4:52 PM
  • BTW, I would have an ON_COMMAND_UI handler and just set a flag for whether or not the DLL is available and loaded and set the menu item to disable or enabled based on the bool flag.

    Tom


    Hey Tom:

     Thanks for your reply first. I considered to add OM_COMMAND_UI and ON_COMMAND manually. but it seemed still can not work. May be problem on merge my resource and event handler together with the target process.


    I want to learn more
    Monday, June 28, 2010 2:40 AM
  • You will need to set up a message hander function for the ID for the menu.  The function will be called when the menu is selected.  Otherwise, the MFC framework will disable the menu assuming that there is nothing for it to do.  You can also add an handler to update the GUI based on conditions.

    http://msdn.microsoft.com/en-us/library/a5f1bcxd(VS.80).aspx

    http://msdn.microsoft.com/en-us/library/b8c866kb(v=VS.80).aspx

    You can add these using the wizards and selecting and "event" for the menu.

    Tom


    The OM_COMMAND and ON_UPDATE_COMMAND_UI macro need using in CMainFrame or a dialog class. But in my dll there is no such class struct and also I can not get the CmainFrame class pointer. So the two macro can not use in my dll. Thanks
    I want to learn more
    Monday, June 28, 2010 3:25 AM