CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Apr 2013
    Posts
    9

    Intercept messages sent to controls on a dialog

    If it is possible, I'd like to know how to intercept messages sent to controls on a dialog.

    I'm working on a large application with a large number of dialogs, each with a number of controls on the dialog. I need to be able to intercept messages sent to these controls so that I can determine if the controls really need to take action on these messages. I could subclass each control and override the specific event handlers but due to the volume of controls in the application this could take a very long time, will introduce risk if controls are missed, and will increase maintenance costs. What I want to do is create a class which is derived from CDialog and each of the dialogs in the application would then be derived from this new dialog class. The new dialog class would intercept messages sent to any control on the dialog and if the dialog decides that the control should do something then the dialog will pass the message on to the control.

    example:
    CExistingDialog is derived from CNewDialog is derived from CDialog
    CExistingDialog has a number of controls. When the code in CExistingDialog calls CWnd::EnableWindow on one of these controls I want CNewDialog to intercept the message, determine what should be done with the message, and then pass it on to the control.

    I'm not very familiar with the messaging framework. I've tried overriding a few of the methods of CNewDialog but none of them ever receive the message to enable the window. I assume this is because the message is sent directly to the child window (the control).

    Is there any way to intercept these messages? I don't know much about hooks either but is this a possible option?

    Thank you in advance for your help!

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Intercept messages sent to controls on a dialog

    Well, you can, of course implement a hook (like WH_CALLWNDPROC one). Search with Google for examples.

    Another possibility would be implement base classes for all the control types you are using. Note that there is not so many control types! Very few: edit, static, button, tree, listview, listbox, combobox, spin, progress, slider, IP, ... What else?
    Victor Nijegorodov

  3. #3
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Intercept messages sent to controls on a dialog

    There's PreTranslateMessage too.

  4. #4
    Join Date
    Apr 2013
    Posts
    9

    Re: Intercept messages sent to controls on a dialog

    GCDEF - I tried overriding PreTranslateMessage in the base dialog class (and in the derived dialog class) and the WM_ENABLE messages are not received.

    VictorN - My goal is to avoid implementing classes for each of the control types due to the volume of control instances in the application. I implemented the WH_CALLWNDPROC hook but the messages are not received (or I do not understand how they are received) in the CallWndProc. I verified that the hook is set based on return value of SetWindowsHookEx.

    Below is my code. Am I doing something incorrect here? In HookProc(), should I expect to see WM_ENABLE messages sent to controls on the dialog?

    Code:
    HHOOK g_hMsgHook;
    
    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if(nCode < 0)
            return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
    
        if(nCode == HC_ACTION)
        {
            // Check message
            if(wParam == WM_ENABLE)
            {
                // Do something
    			TRACE("WM_ENABLE\n");
            }
        }    
    
        return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
    }
    
    
    BOOL CBaseDialog::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// TODO:  Add extra initialization here
    	DWORD dwThreadID = GetCurrentThreadId();
    	if((g_hMsgHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, NULL, dwThreadID)) == NULL)
    	{
    		TRACE("CBaseDialog::OnInitDialog - Unable to create hook");
    	}
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    	// EXCEPTION: OCX Property Pages should return FALSE
    }

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Intercept messages sent to controls on a dialog

    Quote Originally Posted by mjh75 View Post
    (or I do not understand how they are received) in the CallWndProc.
    You definitely don't, considering your code. Please read carefully the article CallWndProc callback function, especially about wParam and lParam precise meanings.
    Last edited by Igor Vartanov; April 10th, 2013 at 04:28 AM.
    Best regards,
    Igor

  6. #6
    Join Date
    Apr 2013
    Posts
    9

    Resolved Re: Intercept messages sent to controls on a dialog

    Ah, yes. I definitely missed that part. I've updated the callback function and am now getting the messages. Thank you!!

    Code:
    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	// Doesn't concern us
    	if(nCode < 0)
    		return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
    
    	if(nCode == HC_ACTION)
    	{
    		// message was sent by the current thread
    		CWPSTRUCT *pCWP = (CWPSTRUCT*)lParam;
    		if(pCWP->message == WM_ENABLE)
    		{
    			TRACE("WM_ENABLE\n");
    		}
    	}    
    
    	return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
    }

  7. #7
    Join Date
    Apr 2013
    Posts
    9

    Re: Intercept messages sent to controls on a dialog

    One last question...

    Is it possible to modify the parameters of the CWPSTRUCT pointer in the callback function's lParam parameter and have it affect the parameter passed to the control with the message?

    With the WM_ENABLE message the lParam value of CWPSTRUCT represents the enable/disable flag. I'd like to change it to 0 (disable) so the control is never enabled. It isn't working in my test. I can call EnableWindow on the control and this works but I'd prefer to just change the parameters if possible.

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Intercept messages sent to controls on a dialog

    Quote Originally Posted by mjh75 View Post
    Is it possible to modify the parameters of the CWPSTRUCT pointer in the callback function's lParam parameter and have it affect the parameter passed to the control with the message?
    The article clearly says it's not possible to modify the message in the hook.
    Remarks

    The CallWndProc hook procedure can examine the message, but it cannot modify it. After the hook procedure returns control to the system, the message is passed to the window procedure.
    Best regards,
    Igor

  9. #9
    Join Date
    Apr 2013
    Posts
    9

    Re: Intercept messages sent to controls on a dialog

    Wow, not sure how I missed that! Thank you again!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured