Home All Groups Group Topic Archive Search About
Author
3 Jun 2005 8:45 PM
Alastair MacFarlane
Dear All,

I have subclassed a UserControl to detect when the middle scroll mouse is
used and the following sample values are returned from my CMouse class
Event:

nKeys: 0 Delta: -1 XPos: 822 YPos: 187

nKeys (Tells me whether the middle scroll Mouse has been depressed: 16 Yes
and 0 No)
Delta (Tells me whether I am scrolling the mouse up or down: -1 Down and 1
Up)
XPos and YPos give me the co-ordinates on the form

My question is that the class event is only fired when I scroll the middle
mouse and, most importantly, the UserControl on the form has the focus,
where I would like it to be fired, wherever I have the current focus on the
form. This is what I thought would happen. Can someone advise me what I am
doing incorrectly?

I can send all the relevant code in a future post if requested.

Mouse Handling procedure:

Public Function WindowProc(ByVal hwnd As Long, _
    ByVal uMsg As Long, _
    ByVal wParam As Long, _
    ByVal lParam As Long) As Long
    Select Case uMsg
        Case WM_MouseWheel
            nKeys = wParam And 65535
            Delta = wParam / 65536 / WHEEL_DELTA
            XPos = lParam And 65535
            YPos = lParam / 65536
            CMouse.FireMouseWheel nKeys, Delta, XPos, YPos
            WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam,
lParam)
        Case Else
           WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam,
lParam)
    End Select
End Function

Thanks again.

Alastair MacFarlane

Author
3 Jun 2005 11:48 PM
Tom Esh
On Fri, 3 Jun 2005 21:45:39 +0100, "Alastair MacFarlane"
<anonym***@microsoft.com> wrote:

Show quoteHide quote
>
>I have subclassed a UserControl to detect when the middle scroll mouse is
>used and the following sample values are returned from my CMouse class
>Event:
>
>nKeys: 0 Delta: -1 XPos: 822 YPos: 187
>
>nKeys (Tells me whether the middle scroll Mouse has been depressed: 16 Yes
>and 0 No)
>Delta (Tells me whether I am scrolling the mouse up or down: -1 Down and 1
>Up)
>XPos and YPos give me the co-ordinates on the form
>
>My question is that the class event is only fired when I scroll the middle
>mouse and, most importantly, the UserControl on the form has the focus,
>where I would like it to be fired, wherever I have the current focus on the
>form. This is what I thought would happen. Can someone advise me what I am
>doing incorrectly?

From the SDK docs:
"The WM_MOUSEWHEEL message is sent to the focus window when the mouse
wheel is rotated. The DefWindowProc function propagates the message to
the window's parent. There should be no internal forwarding of the
message, since DefWindowProc propagates it up the parent chain until
it finds a window that processes it."

So the OS sends the msg to the control only if it has focus. Otherwise
you would need to subclass the control's parent form, which should get
it in any case. (The Spy++ tool is very handy for verifying msg
traffic.)


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
4 Jun 2005 12:12 AM
Alastair MacFarlane
Tom,

Thanks for the reply. I will now go away and look into the DefWindowProc
function you mention. I am relatively new to subclassing and may need
further guidance from the group.

Thanks for taking the time to reply.

Alastair MacFarlane


Show quoteHide quote
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:k2r1a19nmo04829l3j9p46m9v5ouu80q1e@4ax.com...
> On Fri, 3 Jun 2005 21:45:39 +0100, "Alastair MacFarlane"
> <anonym***@microsoft.com> wrote:
>
>>
>>I have subclassed a UserControl to detect when the middle scroll mouse is
>>used and the following sample values are returned from my CMouse class
>>Event:
>>
>>nKeys: 0 Delta: -1 XPos: 822 YPos: 187
>>
>>nKeys (Tells me whether the middle scroll Mouse has been depressed: 16 Yes
>>and 0 No)
>>Delta (Tells me whether I am scrolling the mouse up or down: -1 Down and 1
>>Up)
>>XPos and YPos give me the co-ordinates on the form
>>
>>My question is that the class event is only fired when I scroll the middle
>>mouse and, most importantly, the UserControl on the form has the focus,
>>where I would like it to be fired, wherever I have the current focus on
>>the
>>form. This is what I thought would happen. Can someone advise me what I am
>>doing incorrectly?
>
> From the SDK docs:
> "The WM_MOUSEWHEEL message is sent to the focus window when the mouse
> wheel is rotated. The DefWindowProc function propagates the message to
> the window's parent. There should be no internal forwarding of the
> message, since DefWindowProc propagates it up the parent chain until
> it finds a window that processes it."
>
> So the OS sends the msg to the control only if it has focus. Otherwise
> you would need to subclass the control's parent form, which should get
> it in any case. (The Spy++ tool is very handy for verifying msg
> traffic.)
>
>
> -Tom
> MVP - Visual Basic
> (please post replies to the newsgroup)
Author
4 Jun 2005 2:02 AM
Tom Esh
On Sat, 4 Jun 2005 01:12:01 +0100, "Alastair MacFarlane"
<anonym***@microsoft.com> wrote:

>Thanks for the reply. I will now go away and look into the DefWindowProc
>function you mention. I am relatively new to subclassing and may need
>further guidance from the group.

Don't let the DefWindowProc remark sidetrack you. Unless VB is doing
something strange with WM_MOUSEWHEEL (which I've no reason to believe
it is), calling the previous handler with CallWindowProc should be
doing the same thing as DefWindowProc. The crucial point is the form
should be getting WM_MOUSEWHEEL even if the control does not, iow when
it does not have focus.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
4 Jun 2005 9:09 AM
Alastair MacFarlane
Tom,

Thanks again for the reply. The way I would imagine solving the problem,
based on your advice and as I understand it, would be to subclass the
control on the form to forward the Mouse Scroll to setting the focus on the
UserControl, which would then handle the Mouse Scroll action. Is this about
right or am I going away of on a tangent?

Thanks again...

Alastair MacFarlane

Show quoteHide quote
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:6q22a1hb6ci6iua4b0pol8macmnmr4v6sg@4ax.com...
> On Sat, 4 Jun 2005 01:12:01 +0100, "Alastair MacFarlane"
> <anonym***@microsoft.com> wrote:
>
>>Thanks for the reply. I will now go away and look into the DefWindowProc
>>function you mention. I am relatively new to subclassing and may need
>>further guidance from the group.
>
> Don't let the DefWindowProc remark sidetrack you. Unless VB is doing
> something strange with WM_MOUSEWHEEL (which I've no reason to believe
> it is), calling the previous handler with CallWindowProc should be
> doing the same thing as DefWindowProc. The crucial point is the form
> should be getting WM_MOUSEWHEEL even if the control does not, iow when
> it does not have focus.
>
>
> -Tom
> MVP - Visual Basic
> (please post replies to the newsgroup)
Author
4 Jun 2005 11:30 AM
J French
On Sat, 4 Jun 2005 10:09:54 +0100, "Alastair MacFarlane"
<anonym***@microsoft.com> wrote:

>Tom,
>
>Thanks again for the reply. The way I would imagine solving the problem,
>based on your advice and as I understand it, would be to subclass the
>control on the form to forward the Mouse Scroll to setting the focus on the
>UserControl, which would then handle the Mouse Scroll action. Is this about
>right or am I going away of on a tangent?

I don't think that Tom meant that you should forward the 'focus'

I think what he meant was to subclass the Form rather than the
UserControl
- and tell the UserControl about the messages received.

I'm not exactly sure what you are up to (though I've some ideas) but I
expect that you want to plonk a UserControl on a Form and get the
UserControl to respond to all MouseWheel messages

Try a quick hack as a test, from the user control subclass the Form
instead of the UserControl
Author
4 Jun 2005 12:16 PM
Alastair MacFarlane
Thanks J French,

I think your approach sounds tidier as mine is now getting a bit messy but
works. You are correct in what I want and at the moment the UserControl
handels the mouse scroll and the form moves the focus of the scroll action
to the UserControl.

With your approach do I use SendMessage to the UserControl to udertake a
WM_MouseWheel action or to I use a Public sub in the UserControl to Scroll
the ScrollBar? Is there a difference?

Thanks again and sorry if I sound a bit dense!

Alastair MacFarlane

Show quoteHide quote
"J French" <erew***@nowhere.uk> wrote in message
news:42a18e29.14904195@news.btclick.com...
> On Sat, 4 Jun 2005 10:09:54 +0100, "Alastair MacFarlane"
> <anonym***@microsoft.com> wrote:
>
>>Tom,
>>
>>Thanks again for the reply. The way I would imagine solving the problem,
>>based on your advice and as I understand it, would be to subclass the
>>control on the form to forward the Mouse Scroll to setting the focus on
>>the
>>UserControl, which would then handle the Mouse Scroll action. Is this
>>about
>>right or am I going away of on a tangent?
>
> I don't think that Tom meant that you should forward the 'focus'
>
> I think what he meant was to subclass the Form rather than the
> UserControl
> - and tell the UserControl about the messages received.
>
> I'm not exactly sure what you are up to (though I've some ideas) but I
> expect that you want to plonk a UserControl on a Form and get the
> UserControl to respond to all MouseWheel messages
>
> Try a quick hack as a test, from the user control subclass the Form
> instead of the UserControl
>
>
Author
4 Jun 2005 5:02 PM
Tom Esh
On Sat, 4 Jun 2005 11:30:07 +0000 (UTC), erew***@nowhere.uk (J French)
wrote:
>
>I think what he meant was to subclass the Form rather than the
>UserControl
>- and tell the UserControl about the messages received.

Exactly :-)

-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
4 Jun 2005 7:38 PM
Alastair MacFarlane
Thanks all for your comments but should I use SendMessage to the UserControl
to udertake a WM_MouseWheel action or to I use a Public sub in the
UserControl to Scroll the ScrollBar? Is there a difference?

Thanks again to all.

Alastair MacFarlane

Show quoteHide quote
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:q1m3a198qmivfl3civ9de7687f8jl2qo92@4ax.com...
> On Sat, 4 Jun 2005 11:30:07 +0000 (UTC), erew***@nowhere.uk (J French)
> wrote:
>>
>>I think what he meant was to subclass the Form rather than the
>>UserControl
>>- and tell the UserControl about the messages received.
>
> Exactly :-)
>
> -Tom
> MVP - Visual Basic
> (please post replies to the newsgroup)
Author
4 Jun 2005 8:22 PM
Tom Esh
On Sat, 4 Jun 2005 20:38:22 +0100, "Alastair MacFarlane"
<anonym***@microsoft.com> wrote:

>Thanks all for your comments but should I use SendMessage to the UserControl
>to udertake a WM_MouseWheel action or to I use a Public sub in the
>UserControl to Scroll the ScrollBar? Is there a difference?

Yeah, since the UC's default behavior doesn't do what you want in
response to WM_MOUSEWHEEL, you're going to have to translate it into
scrolling (or whatever) at some point. I'd go for whichever method is
most convenient without duplicating the translation code. For example
if you intend to keep subclassing the UC (in addition to its parent)
then it might be easiest to do it in the UC's WM_MOUSEWHEEL handler.
That way you can just forward the msg (SendMessage) from the parent to
the UC handler. Otherwise you could just wrap it in a public UC method
and call it from the parent handler.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
4 Jun 2005 5:02 PM
Tom Esh
On Sat, 4 Jun 2005 10:09:54 +0100, "Alastair MacFarlane"
<anonym***@microsoft.com> wrote:

>Thanks again for the reply. The way I would imagine solving the problem,
>based on your advice and as I understand it, would be to subclass the
>control on the form to forward the Mouse Scroll to setting the focus on the
>UserControl, which would then handle the Mouse Scroll action. Is this about
>right or am I going away of on a tangent?

I meant you would need to subclass the parent form in addition to or
instead of the usercontrol and, as Jerry noted, your parent handler
would need to determine if the mouse was over the UC for each msg.
Subclassing the parent from a child can get a little tricky if the
parent is also otherwise subclassed, for example if you have multiple
instances of the usercontrol. In particular you have to pay attention
to the order in which you install subclass handlers for the parent
....so you can use the reverse sequence when un-subclassing.

The only other choice would be to not allow other controls to retain
focus, iow set focus back to your UC in their event handlers.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
Author
4 Jun 2005 6:14 PM
Bonj
There's no reason to ever call DefWindowProc from a VB program - you should
always know the address of the previous wndproc therefore CallWindowProc
should be used.

Show quoteHide quote
"Tom Esh" <tjeshGibber***@suscom.net> wrote in message
news:6q22a1hb6ci6iua4b0pol8macmnmr4v6sg@4ax.com...
> On Sat, 4 Jun 2005 01:12:01 +0100, "Alastair MacFarlane"
> <anonym***@microsoft.com> wrote:
>
>>Thanks for the reply. I will now go away and look into the DefWindowProc
>>function you mention. I am relatively new to subclassing and may need
>>further guidance from the group.
>
> Don't let the DefWindowProc remark sidetrack you. Unless VB is doing
> something strange with WM_MOUSEWHEEL (which I've no reason to believe
> it is), calling the previous handler with CallWindowProc should be
> doing the same thing as DefWindowProc. The crucial point is the form
> should be getting WM_MOUSEWHEEL even if the control does not, iow when
> it does not have focus.
>
>
> -Tom
> MVP - Visual Basic
> (please post replies to the newsgroup)
Author
4 Jun 2005 8:22 PM
Tom Esh
On Sat, 4 Jun 2005 19:14:14 +0100, "Bonj" <a@b.com> wrote:

>There's no reason to ever call DefWindowProc from a VB program - you should
>always know the address of the previous wndproc therefore CallWindowProc
>should be used.

Typically yes, but there are (rare) exceptions. I seem to recall one
involving the VB Listbox back in VB4 where the solution to making
WM_SETREDRAW work properly was to call DefWindowProc instead of
SendMessage.


-Tom
MVP - Visual Basic
(please post replies to the newsgroup)