views:

225

answers:

2

I've written a grid control and would like to add support for the mouse wheel to it. I thought it would be as simple as overriding the DoMouseWheel virtual method, but there is a bit of a problem with it.

You can set the number of lines to scroll at a time in Control Panel and the default there is three. And this makes perfect sense when scrolling through a document or web page, but on a grid, I think the expectation is rather to scroll a line at a time. But it seems that Delphi's wheel support will call DoMouseWheel three times for every notch that I scroll, meaning that I can only scroll to each third line in the grid (or whatever that global setting is).

How do I go about scrolling a single line at a time for every turn of the mouse wheel?

Update: The short answer here is to simply set Result to True after scrolling - then it doesn't scroll three times, but only once.

+1  A: 

Just copy the code from the TCustomGrid class, which overrides both DoMouseWheelDown() and DoMouseWheelUp() to scroll exactly one line at a time.

mghie
There was nothing about the implementation that stood out. But following your advice I took another look at it. Turns out simply returning True after scrolling (I returned inherited) caused it to only call the function once.
Cobus Kruger
@Cobus: Of course, if you are overriding functionality you need to check whether calling the inherited code is the correct thing to do. That's why I advised to copy the VCL grid implementation - it does the right thing. I didn't see *your* implementation, and I'm not psychic.
mghie
+2  A: 

In general, it is not a very good idea to fight against the system defaults and/or the user preferences. In this case means that you should respect whatever the system or the user has decided to set in the scrolling time.

Having said so, if you really believe that the multiscroll effect is totally wrong and misleading for the kind of component you want to drive, you might envision a way to get rid of this. You could try to set some timer and ignore all but one of the mouseWheel events that happen in a given lapse of time (in the range of milliseconds). One thing you should do is to set a configuration option in your program, to let the user to turn off this behaviour.

PA
+1 for the reminder about respecting the user's settings.
serialhobbyist
The user is probably unaware of the setting. And if he is aware of it, he probably picked it to work well with what the primary use of the scroll wheel is - reading web pages. If you see rolling the wheel as analogous to scrolling up and down by clicking the arrows on the scroll bar, then would you agree that one line at a time makes more sense in a data-bound grid?
Cobus Kruger
in that case, do it, but always leave the user the option to turn it off.
PA
Cobus, please don't second-guess the user. Have any of your users *told* you that they think turning the wheel one notch is analogous to clicking the scroll arrow once? Have they expressed their frustration that no other programs scroll just one line at a time?
Rob Kennedy