Thread: Programmatically Activating A Splitter

  1. #1
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273

    Question Programmatically Activating A Splitter

    Hello,

    This is my first foray into C# programming, coming from a strong C background and a reasonable grasp of Java. I thought that for my first trick I would port one of my old applications written in C over to .NET, taking advantage of base classes wherever possible.

    However... my app has an option on its View menu to activate the Splitter "control" (it wasn't in my code, such carefree days ) to allow keyboarders to adjust the view. MSDN makes explicit reference to the Splitter control being mouse controlled only.

    Now to me this seems like one step forward and two steps back, especially from an accessibility perspective.

    Would anyone be able to suggest a way that I can simulate the mouse dragging the splitter in order to allow keyboard control? I have tried invoking SendInput and sending a left button click within its area on the screen and although the splitter correctly draws the "ghost" bar as I move it around it doesn't affect the location of the split. Am I missing some crazy .NET mouse activation thing?

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Perhaps there is a property controlling the location of the splitter? So in your key-event, you do something like:
    Code:
    if(KeyCode.Right) MySplitter.Location += SomeDistance;
    else if(KeyCode.Left) MySplitter.Location -= SomeDistance;
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    That works but I want the behaviour to mimic my original application's splitter exactly. You can see how it works by firing up regedit and selecting "Split" from the View menu. The mouse cursor will move to the middle of the splitter and the splitter will activate. You can then use either the arrow keys or the mouse to move it.

    I think my problem is caused by the fact that I cannot change the state of the mouse as reported by its driver. So although I can simulate pressing the left mouse button, when I then go to move the mouse afterwards it is not reporting that the button is still down.

    The only way I can think of to fix this is to somehow "shim" the splitter's MouseDown event, changing the properties on the MouseEventArgs object and then passing it to the splitter's default MouseDown handler. That way I can make it think that the button is down based on the value of a variable. Anyone know how this is achieved?

  4. #4
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    Well today I've tried implementing a NativeWindow listener class in an attempt to intercept the WM_MOUSEMOVE message and set wParam to 1 (indicating left mouse button down):-
    Code:
    internal class SplitterListener : NativeWindow
    {
        private const int WM_MOUSEMOVE = 0x0200;
        private Splitter parent;
    
        public SplitterListener(Splitter parent)
        {
            parent.HandleCreated += new EventHandler(this.OnHandleCreated);
            parent.HandleDestroyed += new EventHandler(this.OnHandleDestroyed);
            this.parent = parent;
        }
    
        // Listen for the control's window creation and then hook into it.
        internal void OnHandleCreated(object sender, EventArgs e)
        {
            // Window is now created, assign handle to NativeWindow.
            AssignHandle(((Splitter)sender).Handle);
        }
        internal void OnHandleDestroyed(object sender, EventArgs e)
        {
            // Window was destroyed, release hook.
            ReleaseHandle();
        }
    
        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_MOUSEMOVE)
                m.WParam = (System.IntPtr)((int)m.WParam | 1);
    
            this.DefWndProc(ref m);
        }
    
    }
    After instantiating the class in my Form's constructor the message is picked up OK when the mouse moves over the splitter, however if I then check the value of e.Button within the splitter1_MouseMove event it is still "None"?!? I have verified that my listener is fired first and through the call to DefWndProc passes the message onto the event handler, yet the change is not registered?!? AAARRRRGGHH!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. mfc splitter view sizing
    By stanlvw in forum Windows Programming
    Replies: 2
    Last Post: 03-22-2009, 09:56 PM
  2. Program showing splitter
    By Zurswe in forum C++ Programming
    Replies: 1
    Last Post: 01-11-2009, 09:33 AM
  3. Programmatically declare vectors
    By franse in forum C++ Programming
    Replies: 15
    Last Post: 11-10-2008, 03:17 PM
  4. Static Splitter Problem
    By dhrodrigues in forum Windows Programming
    Replies: 0
    Last Post: 05-19-2005, 05:49 AM
  5. Debug error creating splitter bar :: MFC ... PLEASE HELP :(
    By SyntaxBubble in forum Windows Programming
    Replies: 0
    Last Post: 04-15-2003, 12:40 PM