From: JanAdam on
Karl, is the link http://vb.mvps.org/tools/MsgHook ok? It comes with an error
message saying that this page cannot be displayed.
--
JanAdam


"Karl E. Peterson" wrote:

> JanAdam wrote:
> > I will try your code Matthias (as well as the others). There are parts in
> > there I do not understand. If I can get through it quick, then of course I
> > will use it. However, I have to understand it first. Subclassing is new to me
> > so it may take too long for the main project.
>
> This is probably the best place in the world to ask about the specifics of code like
> that. And that code Matthias offered is indeed extremely intimidating! This is
> stepping outside the realm that VB was designed for. Fun stuff, but not rookie
> material. :-)
>
> There is another option, though. One I don't recommend too often anymore, because I
> defintely prefer the native approach and try to avoid external dependencies if I
> can. But you could use the old MsgHook control to snag the messages for you. It's
> available here:
>
> http://vb.mvps.org/tools/MsgHook
>
> Install that, create a new project that includes this control, and put one on your
> form. Then add code like this:
>
> Option Explicit
>
> Private Const WM_MOUSEWHEEL As Long = &H20A
>
> Private Sub Command1_Click()
> Unload Me
> End Sub
>
> Private Sub Form_Load()
> With Msghook1
> .HwndHook = Me.hWnd
> .Message(WM_MOUSEWHEEL) = True
> End With
> End Sub
>
> Private Sub Msghook1_Message(ByVal msg As Long, ByVal wp As Long, ByVal lp As
> Long, result As Long)
> Select Case msg
> Case WM_MOUSEWHEEL
> If wp < 0 Then
> Debug.Print "Wheel rolled backwards!", wp, Timer
> Else
> Debug.Print "Wheel rolled forwards!", wp, Timer
> End If
> Case Else
> ' This shouldn't happen, unless you
> ' hook other messages too.
> End Select
> End Sub
>
> The WM_MOUSEWHEEL message is always sent to the parent window if the window under
> the cursor doesn't respond. You can see this in action by putting a command button
> on the form, and rolling the wheel over it -- you'll get the notifications in the
> Immediate window no matter where the cursor is.
>
> More details on the wp and lp parameters in that Message event may be found here:
>
> http://msdn2.microsoft.com/en-us/library/ms645617(VS.85).aspx
>
> Again, ask here if any of that doesn't make sense. (I'm pretty sure a lot of it
> won't. That's okay!) On the same page where you can download MsgHook, notice that
> I also have links to other sample programs that use it for a variety of interesting
> tasks.
> --
> ..NET: It's About Trust!
> http://vfred.mvps.org
>
>
>
From: Karl E. Peterson on
JanAdam wrote:
> Karl, is the link http://vb.mvps.org/tools/MsgHook ok? It comes with an error
> message saying that this page cannot be displayed.

Weird. Works here, just fine. Just clicked it, to be sure. Here's a direct link
to the download:

http://vb.mvps.org/tools/files/msghook.zip

(Can you even get to http://vb.mvps.org ?)
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Matthias Immhoff on
No, I didn't write it. It's Paul Catons code, I only included the
WM_MOUSEWHEEL.
I'm using his code in all my projects since years without any crashes.
From: BeastFish on
Oh, I was just being a bit dramatic <g> You don't have to worry about
hosing the PC or the hard drive melting or corrupting Windows for-evah (or
worse, XP morphing into Vista <g>). Nothing that a reboot won't fix. Just
that you need to take a little extra care when subclassing (save your
project before each run, etc.) so you don't lose anything if some bug or
error in the program stops execution in the IDE while in "subclassed state".
Make sure your app unhooks/unsubclasses when the app ends so it exits
gracefully and doesn't give Windows a hissy fit. Since you've done
programming before, the concept of subclassing should't be that daunting.

Subclassing may seem intimidating, but it isn't that big of a deal. It
helps to understand a little about how Windows itself works. Quick and
dirty explaination... Windows is basically a bunch of objects... a form or
window is an object, a command button is an object, list box, et al. Every
Windows program with a GUI has a bunch of objects. Windows communicates
with these objects for such things as user action by sending "messages" to
them. Each object has their own message handler to interpret and handle
these messages. So when a user mouse clicks on a command button, Windows
sends a mouse click message to that command button and that command button's
message handler interprets that message and acts accordingly... paints
itself as clicked, generates an event, etc.

With VB and its controls, almost all of that message handling is built in
and done automatically behind the scenes. But there are cases in which a
particular message isn't handled by VB objects (like the WM_MOUSEWHEEL
message). Would be nice if the VB objects handled WM_MOUSEWHEEL... it's
just a victim of time and circumstance (scroll wheels didn't become
prevelent until after VB6 was on the market)... but I digress. For such
circumstance where we need to handle messages that aren't handled
automatically, VB gives us the AddresOf operator which we can use to
"re-direct" the default message handler (WNDPROC) into a procedure of our
own. Our own procedure doesn't need to handle ALL the messages (thank
gawd), we can just "sniff out" the ones we want (and execute code when we
do) and pass the rest (or all) of the messages back into the object's
default WNDPROC (message handler).

With the previous example I posted...

We're starting off the subclassing with...

lpPrevWndProc = SetWindowLong(HookedHandle, _
GWL_WNDPROC, _
AddressOf WindowProc)

.... where GWL_WNDPROC identifies the WNDPROC function (default message
handler) of the object being subclassed (HookedHandle... the hWnd of Form1),
and WindowProc is the name of our own procedure (a function in the bas mod)
that will handle the messages. Now our WindowProc function is getting the
messages (and parameters) sent to it...

Function WindowProc(ByVal hw As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long


.... uMsg is the message sent by Winders, wParam and lParam are parameters
that may accompany a message. For our purposes, we're looking for a
WM_MOUSEWHEEL message to arrive (which is the Long value &H20A). So, if
uMsg = WM_MOUSEWHEEL, bingo, we just received one so we can now act on it.
If uMsg isn't WM_MOUSEWHEEL, we'll just throw that message and corresponding
parameters back to the default message handler and let it do the work...

WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)

In my previous example, when it gets a WM_MOUSEWHEEL message (If uMsg =
WM_MOUSEWHEEL Then ...), all I'm doing is determine where the mouse pointer
is and if it's over the command button. And if so, then I'm just doing some
mouse wheelie stuff (how many steps and in what direction) and doing a
Debug.Print to show the direction and steps. Instead of the Debug.Print's,
you'd probably want to call a function or sub with the scroll steps and
direction as parameters (that's what I usually do).


When the app is done running, we need to "detach" our custom message
procedure before the app ends or Windows will cry and complain and let you
know you offended it...

Call SetWindowLong(HookedHandle, _
GWL_WNDPROC, _
lpPrevWndProc)


That's basically it. Ain't really that big a deal. Sure, it's more than
your basic VB coding, but it ain't that bad :-) I'd be hard pressed to
think of an app or project of mine that I don't subclass for one reason or
another now a days.






"JanAdam" <JanAdam(a)discussions.microsoft.com> wrote in message
news:87ACA6DA-473D-45CE-87FD-1FD1BFBB49F7(a)microsoft.com...
> I will try your code Matthias (as well as the others). There are parts in
> there I do not understand. If I can get through it quick, then of course I
> will use it. However, I have to understand it first. Subclassing is new to
me
> so it may take too long for the main project.
> But, regardless, thank you so much for your help.
>
> --
> JanAdam
>
>
> "Matthias Immhoff" wrote:
>
> > JanAdam schrieb:
> > > Gentlemen, thank you all.
> > > Way back, I was quite comfortable with linear programming. Doing other
> > > things, I missed OOP development and have been recently trying to get
some
> > > feel for it by doing a bit of VBA, just for the fun of it. After
carefully
> > > reading your messages and trying to understand the code you kindly
provided,
> > > I am likely to follow Mike's suggestion and have somebody doing it. I
will
> >
> > I already did it for you, what's the problem.
> >


From: JanAdam on
Thanks again BeastFish,

Have you ever been thinking of writing a book on VB? If not you should. Or,
maybe you have already done so? I like your way of explaining things very
much.

And, no, I did not expect my code exploding would destroy my roof, or
changing my xp to vista (who knows what would be worse?).

--
JanAdam


"BeastFish" wrote:

> Oh, I was just being a bit dramatic <g> You don't have to worry about
> hosing the PC or the hard drive melting or corrupting Windows for-evah (or
> worse, XP morphing into Vista <g>). Nothing that a reboot won't fix. Just
> that you need to take a little extra care when subclassing (save your
> project before each run, etc.) so you don't lose anything if some bug or
> error in the program stops execution in the IDE while in "subclassed state".
> Make sure your app unhooks/unsubclasses when the app ends so it exits
> gracefully and doesn't give Windows a hissy fit. Since you've done
> programming before, the concept of subclassing should't be that daunting.
>
> Subclassing may seem intimidating, but it isn't that big of a deal. It
> helps to understand a little about how Windows itself works. Quick and
> dirty explaination... Windows is basically a bunch of objects... a form or
> window is an object, a command button is an object, list box, et al. Every
> Windows program with a GUI has a bunch of objects. Windows communicates
> with these objects for such things as user action by sending "messages" to
> them. Each object has their own message handler to interpret and handle
> these messages. So when a user mouse clicks on a command button, Windows
> sends a mouse click message to that command button and that command button's
> message handler interprets that message and acts accordingly... paints
> itself as clicked, generates an event, etc.
>
> With VB and its controls, almost all of that message handling is built in
> and done automatically behind the scenes. But there are cases in which a
> particular message isn't handled by VB objects (like the WM_MOUSEWHEEL
> message). Would be nice if the VB objects handled WM_MOUSEWHEEL... it's
> just a victim of time and circumstance (scroll wheels didn't become
> prevelent until after VB6 was on the market)... but I digress. For such
> circumstance where we need to handle messages that aren't handled
> automatically, VB gives us the AddresOf operator which we can use to
> "re-direct" the default message handler (WNDPROC) into a procedure of our
> own. Our own procedure doesn't need to handle ALL the messages (thank
> gawd), we can just "sniff out" the ones we want (and execute code when we
> do) and pass the rest (or all) of the messages back into the object's
> default WNDPROC (message handler).
>
> With the previous example I posted...
>
> We're starting off the subclassing with...
>
> lpPrevWndProc = SetWindowLong(HookedHandle, _
> GWL_WNDPROC, _
> AddressOf WindowProc)
>
> .... where GWL_WNDPROC identifies the WNDPROC function (default message
> handler) of the object being subclassed (HookedHandle... the hWnd of Form1),
> and WindowProc is the name of our own procedure (a function in the bas mod)
> that will handle the messages. Now our WindowProc function is getting the
> messages (and parameters) sent to it...
>
> Function WindowProc(ByVal hw As Long, _
> ByVal uMsg As Long, _
> ByVal wParam As Long, _
> ByVal lParam As Long) As Long
>
>
> .... uMsg is the message sent by Winders, wParam and lParam are parameters
> that may accompany a message. For our purposes, we're looking for a
> WM_MOUSEWHEEL message to arrive (which is the Long value &H20A). So, if
> uMsg = WM_MOUSEWHEEL, bingo, we just received one so we can now act on it.
> If uMsg isn't WM_MOUSEWHEEL, we'll just throw that message and corresponding
> parameters back to the default message handler and let it do the work...
>
> WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
>
> In my previous example, when it gets a WM_MOUSEWHEEL message (If uMsg =
> WM_MOUSEWHEEL Then ...), all I'm doing is determine where the mouse pointer
> is and if it's over the command button. And if so, then I'm just doing some
> mouse wheelie stuff (how many steps and in what direction) and doing a
> Debug.Print to show the direction and steps. Instead of the Debug.Print's,
> you'd probably want to call a function or sub with the scroll steps and
> direction as parameters (that's what I usually do).
>
>
> When the app is done running, we need to "detach" our custom message
> procedure before the app ends or Windows will cry and complain and let you
> know you offended it...
>
> Call SetWindowLong(HookedHandle, _
> GWL_WNDPROC, _
> lpPrevWndProc)
>
>
> That's basically it. Ain't really that big a deal. Sure, it's more than
> your basic VB coding, but it ain't that bad :-) I'd be hard pressed to
> think of an app or project of mine that I don't subclass for one reason or
> another now a days.
>
>
>
>
>
>
> "JanAdam" <JanAdam(a)discussions.microsoft.com> wrote in message
> news:87ACA6DA-473D-45CE-87FD-1FD1BFBB49F7(a)microsoft.com...
> > I will try your code Matthias (as well as the others). There are parts in
> > there I do not understand. If I can get through it quick, then of course I
> > will use it. However, I have to understand it first. Subclassing is new to
> me
> > so it may take too long for the main project.
> > But, regardless, thank you so much for your help.
> >
> > --
> > JanAdam
> >
> >
> > "Matthias Immhoff" wrote:
> >
> > > JanAdam schrieb:
> > > > Gentlemen, thank you all.
> > > > Way back, I was quite comfortable with linear programming. Doing other
> > > > things, I missed OOP development and have been recently trying to get
> some
> > > > feel for it by doing a bit of VBA, just for the fun of it. After
> carefully
> > > > reading your messages and trying to understand the code you kindly
> provided,
> > > > I am likely to follow Mike's suggestion and have somebody doing it. I
> will
> > >
> > > I already did it for you, what's the problem.
> > >
>
>
>