Note: The most up-to-date version of the code is in post #1. WheelHookAllControls.zip includes MSFlexGrid example
It was brought to my attention that controls that already responded to the MouseWheel (combobox, textbox, etc.), would prevent MouseWheel events passing to form, so even if you were over a grid, it would be the combobox that scrolled, and you would have to remove focus from the control before it would work
I have fixed this so that you can Hook the controls, and if a WM_MOUSEWHEEL event occurs and the mouse is not over the control, it triggers the MouseWheel sub on the form.
The code for scrolling the grid if it's the activecontrol will work fine regardless of other controls responding to scroll events.
EDIT: This was recovered from the original post. The original two attachments are the links WheelHook-NestedControls and WheelHook-AllControls:
These example projects demonstrate enabling the MouseWheel for any control (multiple controls / multiple forms).
Examples
• Enabling MouseWheel Support with any control - attached to post #1 14/03/06: Slight correction to code 20/04/06: Minor modification to code (more info: post #9) 12/01/07:Nested Controls example created allowing the mousewheel to work with controls nested to any depth - incorporates fixes from other posts (1, 2) - attached to post #1
The hooking code was modified from here. Original thread, with suggestions from other members.
Note:
These codes use subclassing which can cause your IDE to crash if your code is incorrectly ended (e.g. via the stop button).
See here for adding in code to detect if your program is running in the IDEWheelHook-NestedControls.zipWheelHook-AllControls.zip
Last edited by Shaggy Hiker; Apr 21st, 2023 at 10:07 AM.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Thanks for pointing that out. Rather than checking there I would recommend checking within the Select Case clause, that way it allows the program to deal with it on a per-control basis. For example, you may want to scroll the grid even though it is disabled.
I would therefore make the below change instead, and indeed have done so to the code in post #1
VB Code:
Case TypeOf ctl Is ListBox, TypeOf ctl Is TextBox, TypeOf ctl Is ComboBox
' These controls already handle the mousewheel themselves, so allow them to:
[B]If ctl.Enabled Then[/B] ctl.SetFocus
Last edited by bushmobile; Apr 20th, 2006 at 05:18 AM.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Great work but...
I do not like individually testing for min and max for each control, so I extracted those lines into a function in the module:
Public Function MouseWheelChange(CurrentValue As Variant, DeltaValue As Variant, MinValue As Variant, MaxValue As Variant) As Variant
Dim newvalue As Variant
newvalue = CurrentValue + DeltaValue
If newvalue < MinValue Then
newvalue = MinValue
ElseIf newvalue > MaxValue Then
newvalue = MaxValue
End If
MouseWheelChange = newvalue
End Function
The MouseWheel() sub now looks like:
Public Sub MouseWheel(ByVal MouseKeys As Long, ByVal Rotation As Long, ByVal Xpos As Long, ByVal Ypos As Long)
On Error Resume Next
If TypeOf Me.ActiveControl Is VScrollBar Then
With VScroll1
.Value = MouseWheelChange(.Value, Sgn(Rotation) * .LargeChange, .Min, .Max)
End With
ElseIf TypeOf Me.ActiveControl Is TextBox Then
Text1.Text = MouseWheelChange(Text1.Text, Rotation, -1000, 1000)
End If
End Sub
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Great code, bushmobile, but is there any way to add support for a tilt wheel (Microsoft IntelliMouse Explorer 5.0). Thanx!
Visit here to learn to make the VB interface fit you!.
"I have not failed 10,000 times. I have successfully identified 10,000 ways that will not work" Thomas Edison
"The day Microsoft makes something that doesn't suck is probably the day they start making vacuum cleaners" -- Ernst Jan Plugge
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Hi, this is great piece of code.(exactly what I have been looking for) That being said I’m having some trouble implementing it into one of my projects. I have a form with a Sstab. On the tab I have a combo box and an MsFlexgrid.
I’m getting an error in the module when ever I use Hook Controls to be ignored: Call WheelHook(Combo1.hWnd) ( if I don’t hook the Combo1 then I don’t get the error. But then the msflexgrid has to have focus for the mouse scroll to work)
I get an Object Variable or with block variable not set Error. And VB highlights this line in the module: GetForm(GetParent(Lwnd)).MouseWheel MouseKeys, Rotation, Xpos, Ypos (I’m not familiar at all with API calls so I’m at a loss)
I get this error when I have used the mouse scroll 1st over the combo box and then use the mouse scroll over the form or over the flexgrid.
Any help would be greatly appreciated.( Just being able to mouse scroll all the controls is great, but you spoiled me with sample using the mouse over)
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
I tried your solution and it crashed, so I went back and looked at the module
And saw there was still a reference to GetParent:
' it's not a form
If Not IsOver(Lwnd, Xpos, Ypos) And IsOver(GetParent(Lwnd), Xpos, Ypos) Then
' it's not over the control and is over the form,
So instead of of Replacing the GetParent API declaration with the GetAncestor API declaration you must keep the GetParent API and
Add the GetAncestor API
Anyway you put me on the right path and it works like a charm. Thanks
so much
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Ok so here's the situation. I have a mdi container with a child form inside of it. The child forms is longer than the mdi container which creates a vertical scroll bar.
Is there any way to scroll the mdi container with the mouse wheel. Can this code accomplish what I want to do??
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Use the same idea, but use the mousewheel movement to change the value of the scrollbar.
The most difficult part of developing a program is understanding the problem.
The second most difficult part is deciding how you're going to solve the problem.
Actually writing the program (translating your solution into some computer language) is the easiest part.
Please indent your code and use [HIGHLIGHT="VB"] [/HIGHLIGHT] tags around it to make it easier to read. Please Help Us To Save Ana
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
I've already follow those suggests without any result.
I uploaded your example with all the controls included in a picturebox.
As you can see, that picturebox is always onfocus.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Hi bushmobile,
I used your mousewheel code in an existing VB6 app and it worked fine. I altered it slightly because I'm using an MSHFlexgrid instead of an MSFlexgrid. I'm running into another problem though. In my MSHFlexgrid I list rows of invoices, some billed and some unbilled. The user has options to list all invoices, only billed invoices or only unbilled invoices. When the user takes the option to list only billed invoices, the program loops through the grid row by row and sets the .rowheight = 0 for those rows that are unbilled and and sets the .rowheight = -1 for rows that are billed. This code works great for hiding rows but for whatever reason, once the routine completes, the mousewheel no longer works on the grid. I tried all kinds of things to figure out where the problem is and everything seems to point to setting the rowheight to 0. I tried setting the rowheight to like 50 and that worked but it looked ugly. Any thoughts?
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Originally Posted by qvqnytowl
everything seems to point to setting the rowheight to 0. I tried setting the rowheight to like 50 and that worked but it looked ugly. Any thoughts?
How about not loading the grid with the records you don't want displayed? Are you loading it from a database? If so, the solution is simple - a Where clause in your select statement.
The most difficult part of developing a program is understanding the problem.
The second most difficult part is deciding how you're going to solve the problem.
Actually writing the program (translating your solution into some computer language) is the easiest part.
Please indent your code and use [HIGHLIGHT="VB"] [/HIGHLIGHT] tags around it to make it easier to read. Please Help Us To Save Ana
VB6 Closes unexpectedly - MouseWheel with MSFlexGrid Scrolling
Unexpected problem:
Running WinHook2 example (project1):
Stick a dummy event on form1
Click Run Tool Button - all okay
Click Stop Tool Button - all okay
Put a breakpoint on the dummy event
Run - VB6 freezes when it hits the breakpoint
ctlBreak has no effect - must be ended with
Task Manager
In my own project:
When WheelHook has been called, and a breakpoint (anywhere
in the project) has been hit, VB6 proceeds normally but
clicking the Stop tool button causes VB6 to close immediately.
Commenting out the WheelHook call results in normal behavior.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Originally Posted by Me in post #1
These codes use subclassing which can cause your IDE to crash if your code is incorrectly ended (e.g. via the stop button).
subclassing works fine in the IDE (and the exe) unless the normal program flow is interrupted - for example, by pressing the stop button or attempting any runtime debugging.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
There appears to be an error with the code that works by hovering over a flexgrid.
You can end up with an invalid row value.
Isn't it easier to just do something like this?
vb Code:
Public Sub FlexGridScroll(ByRef FG As MSFlexGrid, ByVal MouseKeys As Long, ByVal Rotation As Long, ByVal Xpos As Long, ByVal Ypos As Long)
Dim NewValue As Long
Dim Lstep As Single
On Error Resume Next
With FG
' Lstep = .Height / .RowHeight(0)
' Lstep = Int(Lstep)
' If .Rows < Lstep Then Exit Sub
' Do While Not (.RowIsVisible(.TopRow + Lstep))
' Lstep = Lstep - 1
' Loop
' If Rotation > 0 Then
' NewValue = .TopRow - Lstep
' If NewValue < 1 Then
' NewValue = 1
' End If
' Else
' NewValue = .TopRow + Lstep
' If NewValue > .Rows - 1 Then
' NewValue = .Rows - 1
' End If
' End If
If Rotation > 0 Then
NewValue = .TopRow - 5
If NewValue < 1 Then
NewValue = 1
End If
Else
NewValue = .TopRow + 5
If NewValue > .Rows - 1 Then
NewValue = .Rows - 1
End If
End If
.TopRow = NewValue
End With
End Sub
This also doesn't scroll so much either.
I put in 5 as it is my preferred number of rows to scroll.
There is a setting in the control panel which lets you specify number of lines to scroll at a time
It would good if the code could pick this up and insert it.
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Hello everyone,
For the last couple of years, I used the code listed in the above posts to do my mouse scrolling and it worked fairly well. One thing I didn't like was that if I was debugging my program and the program hit a break point, VB would close with the dreaded "VB must shutdown now..." message. If I had made a couple of changes but forgotten to hit the save button prior, oh well. Small inconvenience I suppose.
The other day I found this zip file in one of my folders and wondered why I had never tried it. Maybe it's been mentioned on this board before and if so, I apologize. I unzipped it and loaded it and I swear, it couldn't work more perfectly for me. The only setting I changed that wasn't a default was on the Settings tab where I checked the "Scroll the window underneath the mouse pointer" option. I had concerns that it might not work for Vista but I loaded it on a Vista machine and it worked perfectly. It even overrides the MouseWheel code if you leave it in your application. (I commented out all my code so I wouldn't have the debug problem anymore.)
Re: VB6 - MouseWheel with Any Control (originally just MSFlexGrid Scrolling)
Originally Posted by Elroy
I'll stand by both of those quotes until I'm shown some specific code that contradicts them. I subclass all kinds of stuff in my primary project (with 100s of module and 100s of forms), and I don't have any problems at all with crashing the IDE.
If you really want to experience the crash yourself, it's very easy to replicate. Slap a "Microsoft InkEdit Control" on a form, subclass it with your favorite method, don't even need to write any additional code, press F5 to run the project, close the form, the IDE will crash. To avoid the crash, unsubclass it explicitly.
Just because unsubclassing on "WM_DESTROY" works for most controls doesn't mean it's a good practice but to each his own I guess...
Last edited by Shaggy Hiker; Feb 5th, 2023 at 10:47 PM.
Reason: Removed sniping.