CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jul 2009
    Posts
    5

    [RESOLVED] Capture click before all children

    My first and most important question is how does one capture a click event before any of the child controls? I have multiple panels that have different controls in them, and whenever I click anywhere in one, I want to change a value that says that that panel is the one selected.

    However, OnClick, OnMouseClick, OnMouseDown all do not get fired before or after the OnClick of the control clicked on. How does one hook into this?

  2. #2
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Capture click before all children

    Why don't you just create a handler for the Click event of all child controls in your panel class?

  3. #3
    Join Date
    Jul 2009
    Posts
    5

    Re: Capture click before all children

    I was hoping to avoid that kind of ugly solution, since it's one more thing to maintain when new things are added down the line. I'll do it if it's the only option, but only then.

  4. #4
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Capture click before all children

    Quote Originally Posted by Ninkazu View Post
    I was hoping to avoid that kind of ugly solution, since it's one more thing to maintain when new things are added down the line. I'll do it if it's the only option, but only then.
    Why would that be an "ugly" solution? That is how you handle events. You do have to actually write code to get a program working correctly. It's not as if you have to define a separate handler for every control. Just loop through the Controls collection and assign a handler to each control's Click event. Pretty simple stuff, can't see how it could be easier than that.

  5. #5
    Join Date
    Jul 2009
    Posts
    5

    Re: Capture click before all children

    Having written a couple widgets libraries myself, I tend to think that the hierarchy should be kept in the framework and that messages should pass from the top down rather than to the one component and only the one component.

    As for a one-stop click event - if a control on the panel has a child control, this whole thing breaks down unless I write new inheriting controls for whatever I need, then fire a message up the line until it hits my parent panel.

    This is far too much to do for simply wanting to know that, in the parent control, something has been clicked inside it. That shouldn't amount to extended everything I would want to use as children.

  6. #6
    Join Date
    May 2007
    Posts
    1,546

    Re: Capture click before all children

    You want the parent to know about mouse clicks before its children do, which is the exact opposite of what every GUI toolkit i've ever used does. So, why do you want to do this? What scenario is that which makes you think you have to do things the exact opposite of what the toolkit enforces?
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  7. #7
    Join Date
    Jul 2009
    Posts
    5

    Re: Capture click before all children

    It looks like there is indeed no easy solution to this then. So be it. Thanks for the help.

  8. #8
    Join Date
    May 2007
    Posts
    1,546

    Re: [RESOLVED] Capture click before all children

    You still haven't said what it is you're trying to accomplish. It's quite possible there is an easy way, but you just haven't thought of it yet. Maybe someone would be able to suggest a not-to-horrible way of doing it that you'll like. Who knows
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  9. #9
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: [RESOLVED] Capture click before all children

    you can create an IMessageFilter that will allow you to preview all windows messages including WM_CLICK. you'll need a way to put those messages into context. One thing I've done in the past (and you can probably search these forums for where I did something similar to this) is to create an IExtenderProvider component that will allow you to subscribe to those messages prior to them being dispatched to the control itself or any child controls. There you can preview the message, and block it if need be...

    good luck.

  10. #10
    Join Date
    Jul 2009
    Posts
    5

    Re: [RESOLVED] Capture click before all children

    Thanks Mad Hatter. I ended up not needing the IExtenderProvider. Here was my solution

    Code:
          // for intercepting clicks to select different plots
          class MessageFilter : IMessageFilter
          {
             private PlotManager parent;
             public MessageFilter(PlotManager parent)
             {
                this.parent = parent;
             }
             public bool PreFilterMessage(ref Message objMessage)
             {
                if (objMessage.Msg == 0x201) // WM_LBUTTONDOWN
                {
                   parent.CheckClick();
                }
                return false;
             }
          }
    
    // ...in the parent
          public PlotManager()
          {
              // other init code
             clickmsgFilter = new MessageFilter(this);
             Application.AddMessageFilter(clickmsgFilter);
          }
    
          public void CheckClick()
          {
             System.Drawing.Rectangle rect = this.Parent.RectangleToScreen(this.Bounds);
             if (!rect.Contains(MousePosition)) return;        
             foreach (PlotPanel p in this.Controls)
             {
                rect = this.RectangleToScreen(p.Bounds);
                if (rect.Contains(MousePosition))
                {
                   SelectPlot(p);
                   break;
                }
             }
          }
    The PlotManager is essentially a singleton in this application, so I don't bother removing the message filter at disposal time.

Tags for this Thread

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