I know you have to have a special mouse wheel driver to use the mouse wheel in the VB IDE. I have no idea if that will translate into being able to use the mouse wheel on an actual compiled VB .Exe but you could go get the driver and try it out.
(I can't as I don't have any mice, at home or at work, that has a mouse wheel)
Here are a couple of apps that demo the mouse wheel.
Keith
I've been programming with VB for 25 years. Started with VB4 16bit Pro, VB5 Pro, VB6 Pro/Enterprise and now VB3 Pro. But I'm no expert, I'm still learning.
Last year's death of Windows XP is the gift that just keeps on giving. Post-XP versions of Windows offer easy access to both vertical and horizontal scrolling from a mouse supporting wheel tilt as well as roll.
Not a lot to it, and the attachment is only so big because of the sample image it contains. Here's a fragment, but there really isn't that much more involved:
Code:
Option Explicit
Private Type LONG_JOINED
Value As Long
End Type
Private Type LONG_SPLIT
LowValue As Integer
HighValue As Integer
End Type
Private LONG_JOINED As LONG_JOINED
Private LONG_SPLIT As LONG_SPLIT
Public Function SubclassProc( _
ByRef hWnd As Long, _
ByRef uMsg As Long, _
ByRef wParam As Long, _
ByRef lParam As Long, _
ByVal dwRefData As Long) As Long
Const WM_MOUSEWHEEL As Long = &H20A&
Const WM_MOUSEHWHEEL As Long = &H20E& 'Requires Vista or later.
Dim Sum As Integer
LONG_JOINED.Value = wParam
LSet LONG_SPLIT = LONG_JOINED
Select Case uMsg
Case WM_MOUSEWHEEL
With VScroll1
If .Enabled Then
Sum = .Value - LONG_SPLIT.HighValue \ 12
If 0 <= Sum And Sum <= .Max Then .Value = Sum
End If
End With
Case WM_MOUSEHWHEEL
With HScroll1
If .Enabled Then
Sum = .Value + LONG_SPLIT.HighValue \ 12
If 0 <= Sum And Sum <= .Max Then .Value = Sum
End If
End With
Case Else
SubclassProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
End Select
End Function
Last edited by dilettante; Jan 30th, 2015 at 04:37 AM.
Reason: reposted attachment
Select Case uMsg
Case WM_MOUSEWHEEL
With VScroll1
If .Enabled Then
Sum = .Value - LONG_SPLIT.HighValue \ 12
If Sum < 0 Then
.Value = 0
ElseIf Sum > .Max Then
.Value = .Max
Else
.Value = Sum
End If
End If
End With
Case WM_MOUSEHWHEEL
With HScroll1
If .Enabled Then
Sum = .Value + LONG_SPLIT.HighValue \ 12
If Sum < 0 Then
.Value = 0
ElseIf Sum > .Max Then
.Value = .Max
Else
.Value = Sum
End If
End If
End With
Case Else
SubclassProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
End Select
Last edited by dilettante; Jan 30th, 2015 at 04:38 AM.
Also see Scrollbars bart 6 - The wheel for refinement ideas you'd probably want in a real program. Just dividing the zDelta value (high word as signed integer) by 12 was a demo hack, various mouse drivers might return increments in the stock +/- 120 or any whole number divisor of 120 (such as the 30 I am getting here).
@dilettante. every time I see the "XP Obituary" excerpt from you, I can't help but smile.
But I feel that if supporting XP can be done with very minimal effort, then do it. Though XP is officially no-longer supported by M$, I doubt it will be removed from the desktops/laptops of this world for another few to several years. The added plus is that if it does support XP, the potential customer base is quite a bit larger, for now.
Insomnia is just a byproduct of, "It can't be done"
Hey, the code posted above, simplistic as it is, will work on XP. You just don't get the ability to horizontal scroll. Perhaps you know of a pre-Vista message supporting it though?
As for the death of XP, I see it as freeing. No longer are we stuck with pablum because Baby can't eat steak. For far too long we've seen people whining about a solution that requires Vista or later. Vista itself is now pretty long in the tooth and drops off extended support itself in 2017.
How long should we wait to start making use of newer features?
I've always wondered why WM_MOUSEWHEEL is sent to the focused window when WM_MOUSEMOVE is sent to the window that is immediately under the mouse pointer (unless SetCapture is active).
On the other hand all of the MS Office applications respond to wheel just by hovering over the UI widget. For instance in Outlook you can scroll the list of messages then point to the message preview and scroll it without clicking beforehand. The same "clickless" behavior is implemented in all modern browsers.
What I usually do to "fix" this is to implement a get message hook for the Not InIde version with something like this
Code:
If nCode = HC_ACTION Then
Call CopyMemory(uMsg, ByVal lParam, Len(uMsg))
With uMsg
If .lMessage = WM_MOUSEMOVE Then
m_hWndLastMouseMove = .hWnd
ElseIf .lMessage = WM_MOUSELEAVE Then
m_hWndLastMouseMove = 0
ElseIf .lMessage = WM_MOUSEWHEEL Then
If .hWnd <> m_hWndLastMouseMove Then
Call GetCursorPos(pt)
If m_hWndLastMouseMove = WindowFromPoint(pt.X, pt.Y) Then
.hWnd = m_hWndLastMouseMove
Else
.lMessage = WM_NULL
End If
Call CopyMemory(ByVal lParam, uMsg, Len(uMsg))
End If
... <<snip>>
End If
... <<snip>>
End With
End If
This basically synchronizes WM_MOUSEWHEEL target with last WM_MOUSEMOVE target window. Works very satisfactory provided there is some more code for textbox<->up/down controls negotiation.
@dilettante: You know that ComCtl subclassing is available since NT4 (version 4.72+ of ComCtrl comes with IE 4.0 I believe). The only caveat is to access the required API functions by ordinals like this
Code:
Private Declare Function SetWindowSubclass Lib "comctl32" Alias "#410" (ByVal hWnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Private Declare Function DefSubclassProc Lib "comctl32" Alias "#413" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function RemoveWindowSubclass Lib "comctl32" Alias "#412" (ByVal hWnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
Same ordinals are used in all OS version up to Win 8.1 and will be kept forever, I'm using these in production very confidently.
I've always wondered why WM_MOUSEWHEEL is sent to the focused window when WM_MOUSEMOVE is sent to the window that is immediately under the mouse pointer (unless SetCapture is active).
So true. The funniest thing about this behavior is that it's in direct violation of Microsoft's own guidelines.
- Make the mouse wheel affect the control, pane, or window that the pointer is currently over. Doing so avoids unintended results.
- Make the mouse wheel take effect without clicking or having input focus. Hovering is sufficient.
The Declare aliases aren't necessary as long as the loaded ComCtl32.dll is version 6 or higher (achieved by specifying it in the app manifest). However, since it appears that many VB6 developers still aren't using manifests, subclassing code intended for sharing should therefore ensure compatibility with earlier ComCtl32.dll versions by invoking the ordinal number instead of the function name.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
The Declare aliases aren't necessary as long as the loaded ComCtl32.dll is version 6 or higher (achieved by specifying it in the app manifest).
The 1st three below do not require manifests. These were included in v5.8+, without need to alias by ordinal (else earlier version will need the ordinal aliasing). The last one does require manifesting.
SetWindowSubclass
RemoveWindowSubclass
DefSubclassProc
GetWindowSubclass
Edited: GetWindowSubclass was exported as #411 prior to v6 of comctl32.dll
Last edited by LaVolpe; Feb 8th, 2015 at 04:48 PM.
Insomnia is just a byproduct of, "It can't be done"