Visual C# Developer Center > Visual C# Forums > Visual C# General > DataGridView: horizontal scrolling using mousewheel
Ask a questionAsk a question
 

AnswerDataGridView: horizontal scrolling using mousewheel

  • Thursday, October 29, 2009 10:12 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi all,

    I was wondering if it is possible to scroll horizontally in a datagridview using the scrollwheel.
    Not by using the Ctrl+wheel, but just by pushing the mousewheel to the left or to the right.

    Regards,
    TakeItEasy

Answers

  • Friday, November 20, 2009 8:57 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi Harry,

    I found my mistake :(

    I need to set the Result of the message to (IntPtr)1

    Following code works for me :
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.HWnd != this.Handle)
                {
                    return;
                }
                else
                {
                    if (m.Msg == WM_MOUSEHWHEEL)
                    {
                        if (m.WParam.ToInt32() < 0)
                        {
                            if (this.HorizontalScrollingOffset > 14)
                            {
                                this.HorizontalScrollingOffset -= 15;
                            }
                            else
                            {
                                this.HorizontalScrollingOffset = 0;
                            }
                            m.Result = (IntPtr)1;
                        }
                        if (m.WParam.ToInt32() > 0)
                        {
                            this.HorizontalScrollingOffset += 15;
                            m.Result = (IntPtr)1;
                        }
                        Debug.WriteLine("WM_MOUSEHWHEEL : " + m.ToString() + "  " + this.HorizontalScrollingOffset.ToString());
                    }
                }
            }
    <br/>
    
    I don't fully understand, but I suppose that this m.Result indicates that the message is processed and makes it possible to fire again.

    Regards,
    TakeItEasy
    • Marked As Answer byTakeItEasy Friday, November 20, 2009 8:58 AM
    •  

All Replies

  • Wednesday, November 04, 2009 3:03 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi,

    If you want to use mousewheel to scroll horizontally, please try to set the HorizontalScrollingOffset property of the control within mousewheel event handler.

            private void Form1_Load(object sender, EventArgs e)
            {
                this.dataGridView1.ScrollBars = ScrollBars.Horizontal;
                this.dataGridView1.MouseWheel += new MouseEventHandler(dataGridView1_MouseWheel);
            }

            void dataGridView1_MouseWheel(object sender, MouseEventArgs e)
            {
             
                if (e.Delta > 0)
                    this.dataGridView1.HorizontalScrollingOffset += 15;
                else
                    if (this.dataGridView1.HorizontalScrollingOffset > 15)
                        this.dataGridView1.HorizontalScrollingOffset -= 15;
                    else
                        this.dataGridView1.HorizontalScrollingOffset = 0;          
            }

    Harry


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Sunday, November 08, 2009 6:49 PMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Harry,

    Sorry for my late response (Have been really busy lately :$) :(
    Thx for your answer :)

    Regards,
    TakeItEasy
  • Monday, November 09, 2009 1:38 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi,

    I'm glad I could help :)

    Harry


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Tuesday, November 10, 2009 9:24 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Harry,

    I'm sorry to unmark your reply as an answer to my question.
    I guess I wasn't clear enough in my question :$

    If I'm correct, you change the scrolling of the mousewheel to work on the horizontal scrollbar instead of the vertical. I want the scrolling of my mousewheel to work the way it does now.

    What I want is to catch the pushing of the mousewheel to the left or the right, so the e.delta is zero (I don't scroll the mousewheel, I push it to a side).
    I haven't found an event that fires when I push the mousewheel :( (I tried the Mousewheel event, but nothing happens).

    I know that not all mouses have this function, but when you're used to it, it really is handy :)


    Regards,
    TakeItEasy
  • Tuesday, November 10, 2009 9:49 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    Then you have to see what the message is when you push mousewheel , then handle these messages via overriding WndProc method.

    Harry
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Tuesday, November 10, 2009 2:18 PMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Harry,

    euh ... there I lost you :(

    How can I see which messages are fired? (I hope this question isn't too stupid :$).
    I looked up the WndProc method and this looks idd what I need.

    I searched the net and found an article that explains a lot:
    http://www.philosophicalgeek.com/2007/07/27/mouse-tilt-wheel-horizontal-scrolling-in-c/
    This article was written by Ben Watson.

      On http://stackoverflow.com/questions/199178/is-there-a-net-namespace-where-i-can-find-the-win32-api-message-related-defines
    I found 2 windowsmessages that seemed relevant:
    <
    ...
    private const UInt32 WM_MOUSEWHEEL         = 0x020A;
    private const UInt32 WM_MOUSEHWHEEL        = 0x020E;
    ...
    >
    The first is the tilt wheel scrolling (vertical srolling), the second is the tilt wheel pushing aside (left or right).
    I had to change the UInt32 to int32 (I guess this is ok, but not really my cup of tea these windows messages ... yet :D (I hope ;))).

    I 've tested these messages in my grid and seems to be correct.
    The values in m.WParam are (in my case at least) 7864320 (push right) and -7864320 (push left).
    When I push the tilt wheel down I get the same as when I push it left (could be my thick fingers that aren't so accurate :D), could someone confirm this?

    The value in WParam is an IntPtr, I'm (again) not used to working with them :(
    Is it safe to look at the value of this pointer (so is it always 7864320 and -7864320 )? I guess not.

    I'll look in to it when I'm feeling better  (and have some more time :$).

    Any help would be appreciated although I guess (hope) that I will come to a good result in the end (with more searching and testing and reading).

    Regards,
    TakeItEasy.
  • Wednesday, November 11, 2009 9:32 PMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Not that simple as I hoped for :(

    I have currently 2 problems:
    a) How do I know whether I pushed my mousewheel (tiltwheel or whatever you call it) left or right.
    b) The WM_MOUSEHWHEEL fires, but only once (when I keep pushing left/right I want to keep on moving left/right). So is there another message that fires so I know the tiltwheel is still pushed or is there a messages that fires indicating I stopped pushing? If there is an easy way to detect this myself, I would be very glad to know :)  (I'm using VS 2008 Express edition).

    I still think it's strange that this isn't supported in the datagridview by default (just like the vertical scrolling with the tiltwheel).


    Regards,
    TakeItEasy

  • Friday, November 13, 2009 12:34 PMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Problem a)
    Someone @ work told me that it should be safe to check on the value of the WParam. So left or right should be solved.

    Problem b)
    Problem remains. I'm trying to get there using WinSpector, but I'm drowning in messages :(


    Regards,
    TakeItEasy

  • Monday, November 16, 2009 2:07 PMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Couldn't find any message via Spy++ that could help me.
    So I compared the messages from notepad (where the horizontal scrolling via the mousewheel does work).

    The message WM_HSCROLL (0x0114) seems to be the message that does the trick (in notepad).
    This message doesn't get caught the WndProc :(
    I checked the richtextbox and here it arrives at the WndProc function (the control doesn't scroll, but at least it arrives :) ).
    Hoped to catch the message in the PreProcessMessage (in my inherited grid), but this message doesn't arrive there :'(
    Is there some other way to catch this WM_HSCROLL message (in a class that is inherited from DataGridView)?

    I suppose the WM_HSCROLL message gets send, or not?

    Regards,
    TakeItEasy

  • Tuesday, November 17, 2009 2:06 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    The WM_HSCROLL message is sent to a window when a scroll event occurs in the window's standard horizontal scroll bar.
    Is there a horizontal scroll bar on the control?

    Harry
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Tuesday, November 17, 2009 8:25 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Harry,

    (welcome back, started to feel lonely  :) :) ).

    Yes, there sure is.
    Btw, easy to verify.
    Create a class which inherits from DataGridView, put some columns on it with a big width. Place it on a small panel (for the scrollbar).
    Link WinSpector or Spy++ (or something else that does the same) and push the mousewheel to the left or right, no such message gets fired.
    Link WinSpector or Spy++ to notepad (idd, when it has a horizontal scrollbar) and push the mousewheel to the left or right. Th message fires.
    I tried the same with a class which inherits from RichTextBox and then the message also gets fired.

    My hope for a sollution is getting smaller :(

    Regards,
    TakeItEasy
  • Wednesday, November 18, 2009 2:20 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    My mouse do not have this kind of wheel , so I can not test it for you .
    But are you checking messages on the panel instead of datagridview?

    Harry
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Friday, November 20, 2009 8:25 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hello Harry,

    I'm checking the overriden funtion WndProc of my control which inherits from DataGridView.
    The following code :
        public class BaseGrid : DataGridView
        {
            private const Int32 WM_MOUSEWHEEL = 0x020A; 
            private const Int32 WM_MOUSEHWHEEL = 0x020E;
            private const Int32 WM_HSCROLL = 0x0114;
    
    ....
    
    
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.HWnd != this.Handle)
                {
                    return;
                }
                else
                {
                    if (m.Msg == WM_MOUSEHWHEEL)
                    {
                        Debug.WriteLine("WM_MOUSEHWHEEL : " + m.ToString());
                        this.HorizontalScrollingOffset += 15;
                    }
                    if (m.Msg == WM_HSCROLL)
                    {
                        Debug.WriteLine("WM_HSCROLL : " + m.ToString());
                    }
                }
            }
    
    gives me the following output:

    WM_MOUSEHWHEEL : msg=0x20e hwnd=0x3113a wparam=0x780000 lparam=0x0 result=0x0

    WM_MOUSEHWHEEL : msg=0x20e hwnd=0x3113a wparam=0xffffffffff880000 lparam=0x0 result=0x0

    But as I said before: this message fires only once each time I push the wheel, so not really usefull :(
    The WM_HSCROLL only fires when I'm clicking (or sliding) the scrollbar itself.


    Regards,
    TakeItEasy

  • Friday, November 20, 2009 8:57 AMTakeItEasy Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi Harry,

    I found my mistake :(

    I need to set the Result of the message to (IntPtr)1

    Following code works for me :
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.HWnd != this.Handle)
                {
                    return;
                }
                else
                {
                    if (m.Msg == WM_MOUSEHWHEEL)
                    {
                        if (m.WParam.ToInt32() < 0)
                        {
                            if (this.HorizontalScrollingOffset > 14)
                            {
                                this.HorizontalScrollingOffset -= 15;
                            }
                            else
                            {
                                this.HorizontalScrollingOffset = 0;
                            }
                            m.Result = (IntPtr)1;
                        }
                        if (m.WParam.ToInt32() > 0)
                        {
                            this.HorizontalScrollingOffset += 15;
                            m.Result = (IntPtr)1;
                        }
                        Debug.WriteLine("WM_MOUSEHWHEEL : " + m.ToString() + "  " + this.HorizontalScrollingOffset.ToString());
                    }
                }
            }
    <br/>
    
    I don't fully understand, but I suppose that this m.Result indicates that the message is processed and makes it possible to fire again.

    Regards,
    TakeItEasy
    • Marked As Answer byTakeItEasy Friday, November 20, 2009 8:58 AM
    •  
  • Friday, November 20, 2009 9:01 AMHarry ZhuMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi,

    Glad to know you have sovled the problem!

    Harry


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.