locked
Single WindowProc for all events with Win32 API. RRS feed

  • Question

  • Hi!

    I am building a wrapper for some window controls and it would be handy, for what I'm doing, to have a single window procedure, called for all events.

    One solution may seem to manage the events directly in the events loop, but that cannot work for messages sent through SendMessage.

    Is there any way to do that, other than manually set the same window procedure for all controls?


    • Edited by Aspie96 Saturday, November 5, 2016 4:09 PM
    Saturday, November 5, 2016 4:09 PM

Answers

  • I hoped there was a standard way to do it, but I guess there isn't, so thank you!
    Usel hooks to intercept all events.

    • Edited by Castorix31 Saturday, November 5, 2016 5:41 PM
    • Marked as answer by Aspie96 Sunday, November 6, 2016 9:28 PM
    Saturday, November 5, 2016 5:40 PM

All replies

  • Are you talking about your own custom controls or wrapping standard window controls (e.g., edit, listbox, etc.)?
    Saturday, November 5, 2016 4:30 PM
  • I am wrapping standard controls.
    Saturday, November 5, 2016 4:51 PM
  • Subclass them ?
    Saturday, November 5, 2016 4:57 PM
  • I am wrapping standard controls.

    See About Window ProceduresSuperclassing is a technique that allows an application to create a new window class with the basic functionality of the existing class, plus enhancements provided by the application. A superclass is based on an existing window class called the base class. Frequently, the base class is a system global window class such as an edit control, but it can be any window class.

    So if you used superclassing to wrap an edit control every wrapped control that you create would share the same window procedure that you defined when you registered the superclass for edit controls.  You wouldn't have to manually set a window procedure each time a control was created.

    If you are talking about having all standard controls share a common window procedure then that doesn't make sense to me.

    .



    • Edited by RLWA32 Saturday, November 5, 2016 5:14 PM
    Saturday, November 5, 2016 5:11 PM
  • If you are talking about having all standard controls share a common window procedure then that doesn't make sense to me.

    Basically, what I do is I create a list of events to handle and each time an event occours I check what listener can handle it, if any.

    Checking for all the events in a single place allows me to have only one list.

    But I could do it by superclassing all classes.

    I hoped there was a standard way to do it, but I guess there isn't, so thank you!

    Saturday, November 5, 2016 5:31 PM
  • I hoped there was a standard way to do it, but I guess there isn't, so thank you!
    Usel hooks to intercept all events.

    • Edited by Castorix31 Saturday, November 5, 2016 5:41 PM
    • Marked as answer by Aspie96 Sunday, November 6, 2016 9:28 PM
    Saturday, November 5, 2016 5:40 PM
  • The problem with using a hook is that if I do I will not have the 4 event parameters (hwnd, message, wParam and lParam).
    Saturday, November 5, 2016 7:50 PM
  • The problem with using a hook is that if I do I will not have the 4 event parameters (hwnd, message, wParam and lParam).

     For example, the CWPRETSTRUCT structure has all pameters...


    • Marked as answer by Aspie96 Sunday, November 6, 2016 9:27 PM
    • Unmarked as answer by Aspie96 Sunday, November 6, 2016 9:27 PM
    Saturday, November 5, 2016 7:59 PM
  • Ok, thank you really very much for your help.

    So, what I did was: in my WinMain procedure I modified the loop as follows (myFunc is the function handling the events):

    MSG message;
    while(GetMessage(&message, NULL, 0, 0)) {
    	TranslateMessage(&message);
    	if(!myFunc(message.hwnd, message.message, message.wParam, message.lParam)) {
    		DispatchMessage(&message);
    	}
    }

    And I created a WH_CALLWNDPROCRET hook:

    SetWindowsHookEx(WH_CALLWNDPROCRET, HookProc, NULL, GetWindowThreadProcessId(myHwnd, NULL));

    As for the hook procedure, I defined it as:

    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    	CWPRETSTRUCT *event = (CWPRETSTRUCT*)lParam;
    	if(myFunc(event->hwnd, event->message, event->wParam, event->lParam)) {
    		return FALSE;
    	}
    	return CallNextHookEx(NULL,nCode,wParam,lParam);
    }

    The reason I need to call myFunc twice in the code is that the loop only sees events called through PostMessage and the hook only those sent by SendMessage.

    It seems to work well so far, so thank you very much!

    Saturday, November 5, 2016 9:18 PM