-
Impossible Mystery? VB subclass drops messages!
I have a subclass set up on a VB combobox hosted on a usercontrol. The usercontrol
is inside another usercontrol which is in a frame on a form. There are a
lot of windows in this app, probably 100 or so API windows.
Anyway, I'm wondering if it is possible for SetWindowLong to fail to deliver
a window message once in a blue moon. Or maybe VB is doing a setwindowlong
on top of my setwindowlong, then removing it.
Here is the problem. My combo box doesn't get WM_KEYDOWN, WM_CHAR, or WM_KEYUP
messages when I type the arrow keys. I DO get those messages when I type
other characters like the letters. I am using a custom subclassing component
that works well (AFAIK) and I wrote it. Looking at the component, I am NOT
getting any window messages to the combo box's hwnd when I type the up/down
arrow keys to the window function I SetWindowLong against. Except for a
WM_COMMAND message telling the combo to scroll its selection down or up,
that is.
When I use Spy++ to subclass the combo, Spy++ DOES see the character up /
down messages / char messages!
Maybe VB is hooking the SendMessage / Postmessage DLL entry points and eating
the messages and moving the combo box itself?
The weird thing is, when I try this same test with a combo sitting by itself
on a form, my subclass DOES see the WM_CHAR, WM_KEYUP, WM_KEYDOWN messages!
I've got a weird sneaking suspicion that some weird thing VB does with focus
management is making it do some kind of hook that takes precedence over my
SetWindowLong call.
AARRRRRGH!
Matthew Cromer
-
Re: Impossible Mystery? VB subclass drops messages!
Hi Matthew,
: My combo box doesn't get WM_KEYDOWN, WM_CHAR, or WM_KEYUP
: messages when I type the arrow keys.
I believe you have the same problem that I was having - VB eats certain keys
such as the arrow keys. To fix this, you need to over-ride the VB
IOleControlSite's TranslateAccelerator:
Friend Function WndProc(...) As Long
Dim pOleObject As IOleObject
Dim pOleInPlaceSite As IOleInPlaceSite
Dim pOleControlSite As IOleControlSite
Dim pOleInPlaceFrame As IOleInPlaceFrame
Dim grfModifiers As Long
Dim AcceleratorMsg As MSG
Case WM_SETFOCUS
'// OutputDebugStringA "In WM_SETFOCUS" & vbCrLf
Set pOleObject = Me
Set pOleInPlaceSite = pOleObject.GetClientSite
pOleInPlaceSite.GetWindowContext pOleInPlaceFrame, Nothing, 0, 0, 0
pOleInPlaceFrame.SetActiveObject Nothing, ""
WndProc = 0
Case WM_KEYDOWN
'// OutputDebugStringA "In WM_KEYDOWN, LoWord(wParam) = " & LoWord(wParam)
& vbCrLf
Select Case LoWord(wParam)
Case vbKeyUp, vbKeyDown, vbKeyLeft, vbKeyRight
'// OutputDebugStringA "Arrow key" & vbCrLf
'// WndProc = DefWindowProcA(hwndTV, uMsg, wParam, lParam)
Case Else
'// OutputDebugStringA "Other key" & vbCrLf
Dim udtMSG As MSG
udtMSG.hwnd = hwnd
udtMSG.message = uiMsg
udtMSG.wParam = wParam
udtMSG.lParam = lParam
'udtMSG.Time = GetMessageTime
'udtMSG.pt.X = LoWord(GetMessagePos)
'udtMSG.pt.Y = HiWord(GetMessagePos)
'// CopyMemory ByVal ptr, udtMSG, Len(udtMSG)
If GetKeyState(vbKeyShift) < 0 Then grfModifiers = 1
If GetKeyState(vbKeyControl) < 0 Then grfModifiers = grfModifiers Or 2
If GetKeyState(vbKeyMenu) < 0 Then grfModifiers = grfModifiers Or 4
'// OutputDebugStringA "grfModifiers: " & grfModifiers & vbCrLf
If 0 = pOleControlSite.TranslateAccelerator(VarPtr(udtMSG),
grfModifiers) Then Exit Function
'// WndProc = DefWindowProcA(hWnd, uMsg, wParam, lParam)
End Select
End Function
--
Damit Senanayake | damit@mvps.org | http://members.xoom.com/damit
Please reply to newsgroups, not by e-mail. | ICQ: 6930718
-
Re: Impossible Mystery? VB subclass drops messages!
Hi Matthew,
: My combo box doesn't get WM_KEYDOWN, WM_CHAR, or WM_KEYUP
: messages when I type the arrow keys.
I believe you have the same problem that I was having - VB eats certain keys
such as the arrow keys. To fix this, you need to over-ride the VB
IOleControlSite's TranslateAccelerator:
Friend Function WndProc(...) As Long
Dim pOleObject As IOleObject
Dim pOleInPlaceSite As IOleInPlaceSite
Dim pOleControlSite As IOleControlSite
Dim pOleInPlaceFrame As IOleInPlaceFrame
Dim grfModifiers As Long
Dim AcceleratorMsg As MSG
Case WM_SETFOCUS
'// OutputDebugStringA "In WM_SETFOCUS" & vbCrLf
Set pOleObject = Me
Set pOleInPlaceSite = pOleObject.GetClientSite
pOleInPlaceSite.GetWindowContext pOleInPlaceFrame, Nothing, 0, 0, 0
pOleInPlaceFrame.SetActiveObject Nothing, ""
WndProc = 0
Case WM_KEYDOWN
'// OutputDebugStringA "In WM_KEYDOWN, LoWord(wParam) = " & LoWord(wParam)
& vbCrLf
Select Case LoWord(wParam)
Case vbKeyUp, vbKeyDown, vbKeyLeft, vbKeyRight
'// OutputDebugStringA "Arrow key" & vbCrLf
'// WndProc = DefWindowProcA(hwndTV, uMsg, wParam, lParam)
Case Else
'// OutputDebugStringA "Other key" & vbCrLf
Dim udtMSG As MSG
udtMSG.hwnd = hwnd
udtMSG.message = uiMsg
udtMSG.wParam = wParam
udtMSG.lParam = lParam
'udtMSG.Time = GetMessageTime
'udtMSG.pt.X = LoWord(GetMessagePos)
'udtMSG.pt.Y = HiWord(GetMessagePos)
'// CopyMemory ByVal ptr, udtMSG, Len(udtMSG)
If GetKeyState(vbKeyShift) < 0 Then grfModifiers = 1
If GetKeyState(vbKeyControl) < 0 Then grfModifiers = grfModifiers Or 2
If GetKeyState(vbKeyMenu) < 0 Then grfModifiers = grfModifiers Or 4
'// OutputDebugStringA "grfModifiers: " & grfModifiers & vbCrLf
If 0 = pOleControlSite.TranslateAccelerator(VarPtr(udtMSG),
grfModifiers) Then Exit Function
'// WndProc = DefWindowProcA(hWnd, uMsg, wParam, lParam)
End Select
End Function
--
Damit Senanayake | damit@mvps.org | http://members.xoom.com/damit
Please reply to newsgroups, not by e-mail. | ICQ: 6930718
-
Re: Impossible Mystery? VB subclass drops messages!
Thanks Damit.
I just wanted to find out if I was insane or what. It was terribly frustrating
wondering where those keys went to. The worst thing is: sometimes my subclass
works, sometimes it doesn't. I think I leave the OLE interface replacement
alone for right now--this is going into a large-scale production app and
I can't afford to debug something like that right now. I'll probably just
try a keyboard hook or something. I sure wish I knew why it lets me see
the keys when I am using a combo by itself and doesn't when the combo is
sitting in a usercontrol though!
Matthew Cromer
-
Re: Impossible Mystery? VB subclass drops messages!
Thanks Damit.
I just wanted to find out if I was insane or what. It was terribly frustrating
wondering where those keys went to. The worst thing is: sometimes my subclass
works, sometimes it doesn't. I think I leave the OLE interface replacement
alone for right now--this is going into a large-scale production app and
I can't afford to debug something like that right now. I'll probably just
try a keyboard hook or something. I sure wish I knew why it lets me see
the keys when I am using a combo by itself and doesn't when the combo is
sitting in a usercontrol though!
Matthew Cromer
-
Re: Impossible Mystery? VB subclass drops messages!
Hi Matthew,
: I just wanted to find out if I was insane or what.
The OR would be the place for that.
: It was terribly frustrating
: wondering where those keys went to. The worst thing is: sometimes my
subclass
: works, sometimes it doesn't.
That's something I hadn't really experienced. It was all or nothing, in my
case ;-)
: I think I leave the OLE interface replacement
: alone for right now--this is going into a large-scale production app and
: I can't afford to debug something like that right now.
Bill Storage (of vtable replacement fame) has debugged it for you. <g>
Seriously, I borrowed that code from his LBoxPlus sample (which does a full
owner-drawn ListBox)...
: I'll probably just
: try a keyboard hook or something.
One disadvantage of keyboard hooks in UserControls is that they continue to
execute as long as the control is sited, regardless of whether you are
running the form or otherwise... so if you're typing code and you use the
arrow keys, you may find strange things happening!
: I sure wish I knew why it lets me see
: the keys when I am using a combo by itself and doesn't when the combo is
: sitting in a usercontrol though!
The VB Form doesn't call TranslateAccelerator but instead passes the keys on
to your WndProc. The UserControl, OTOH, by default calls VB's
TranslateAccelerator implementation which traps the arrow keys...
--
Damit Senanayake | damit@mvps.org | http://members.xoom.com/damit
Please reply to newsgroups, not by e-mail. | ICQ: 6930718
-
Re: Impossible Mystery? VB subclass drops messages!
Hi Matthew,
: I just wanted to find out if I was insane or what.
The OR would be the place for that.
: It was terribly frustrating
: wondering where those keys went to. The worst thing is: sometimes my
subclass
: works, sometimes it doesn't.
That's something I hadn't really experienced. It was all or nothing, in my
case ;-)
: I think I leave the OLE interface replacement
: alone for right now--this is going into a large-scale production app and
: I can't afford to debug something like that right now.
Bill Storage (of vtable replacement fame) has debugged it for you. <g>
Seriously, I borrowed that code from his LBoxPlus sample (which does a full
owner-drawn ListBox)...
: I'll probably just
: try a keyboard hook or something.
One disadvantage of keyboard hooks in UserControls is that they continue to
execute as long as the control is sited, regardless of whether you are
running the form or otherwise... so if you're typing code and you use the
arrow keys, you may find strange things happening!
: I sure wish I knew why it lets me see
: the keys when I am using a combo by itself and doesn't when the combo is
: sitting in a usercontrol though!
The VB Form doesn't call TranslateAccelerator but instead passes the keys on
to your WndProc. The UserControl, OTOH, by default calls VB's
TranslateAccelerator implementation which traps the arrow keys...
--
Damit Senanayake | damit@mvps.org | http://members.xoom.com/damit
Please reply to newsgroups, not by e-mail. | ICQ: 6930718
-
Re: Impossible Mystery? VB subclass drops messages!
>
>: It was terribly frustrating
>: wondering where those keys went to. The worst thing is: sometimes my
>subclass
>: works, sometimes it doesn't.
>
>That's something I hadn't really experienced. It was all or nothing, in
my
>case ;-)
What I mean is that it worked with a form host but not a usercontrol host.
You are right--it always works with a form host and never with a usercontrol
host.
>
>: I think I leave the OLE interface replacement
>: alone for right now--this is going into a large-scale production app and
>: I can't afford to debug something like that right now.
>
>Bill Storage (of vtable replacement fame) has debugged it for you. <g>
>Seriously, I borrowed that code from his LBoxPlus sample (which does a full
>owner-drawn ListBox)...
I'm sure there wouldn't be any bugs in your code or Bill's. I'm more worried
about putting code I don't fully understand all the ramifications of in my
application. And the other developers here and in the future who have to
maintain this stuff.
When I implemented subclassing I made a component which is profusely documented
so people can understand how it works. I can't just drop in VTable replacement
code without providing some kind of explanation. I'm a consultant here and
right now just contracted to work through October.
>
>: I'll probably just
>: try a keyboard hook or something.
>
>One disadvantage of keyboard hooks in UserControls is that they continue
to
>execute as long as the control is sited, regardless of whether you are
>running the form or otherwise... so if you're typing code and you use the
>arrow keys, you may find strange things happening!
I was thinking I would just hook on the GotFocus event and unhook on the
LostFocus event.
That's what I usually do with my controls when subclassing so I don't have
the overhead of processing windows messages on dozens of windows at once
in my subclass component--and it works pretty well.
I haven't done any keyboard hooking yet, though, so I don't know if this
strategy would work.
>
>: I sure wish I knew why it lets me see
>: the keys when I am using a combo by itself and doesn't when the combo
is
>: sitting in a usercontrol though!
>
>The VB Form doesn't call TranslateAccelerator but instead passes the keys
on
>to your WndProc. The UserControl, OTOH, by default calls VB's
>TranslateAccelerator implementation which traps the arrow keys...
OK. I see now. Thanks for the great info. I was worried that I might not
ever figure out why I couldn't get those WM_KEYDOWN messages.
Matthew Cromer
-
Re: Impossible Mystery? VB subclass drops messages!
>
>: It was terribly frustrating
>: wondering where those keys went to. The worst thing is: sometimes my
>subclass
>: works, sometimes it doesn't.
>
>That's something I hadn't really experienced. It was all or nothing, in
my
>case ;-)
What I mean is that it worked with a form host but not a usercontrol host.
You are right--it always works with a form host and never with a usercontrol
host.
>
>: I think I leave the OLE interface replacement
>: alone for right now--this is going into a large-scale production app and
>: I can't afford to debug something like that right now.
>
>Bill Storage (of vtable replacement fame) has debugged it for you. <g>
>Seriously, I borrowed that code from his LBoxPlus sample (which does a full
>owner-drawn ListBox)...
I'm sure there wouldn't be any bugs in your code or Bill's. I'm more worried
about putting code I don't fully understand all the ramifications of in my
application. And the other developers here and in the future who have to
maintain this stuff.
When I implemented subclassing I made a component which is profusely documented
so people can understand how it works. I can't just drop in VTable replacement
code without providing some kind of explanation. I'm a consultant here and
right now just contracted to work through October.
>
>: I'll probably just
>: try a keyboard hook or something.
>
>One disadvantage of keyboard hooks in UserControls is that they continue
to
>execute as long as the control is sited, regardless of whether you are
>running the form or otherwise... so if you're typing code and you use the
>arrow keys, you may find strange things happening!
I was thinking I would just hook on the GotFocus event and unhook on the
LostFocus event.
That's what I usually do with my controls when subclassing so I don't have
the overhead of processing windows messages on dozens of windows at once
in my subclass component--and it works pretty well.
I haven't done any keyboard hooking yet, though, so I don't know if this
strategy would work.
>
>: I sure wish I knew why it lets me see
>: the keys when I am using a combo by itself and doesn't when the combo
is
>: sitting in a usercontrol though!
>
>The VB Form doesn't call TranslateAccelerator but instead passes the keys
on
>to your WndProc. The UserControl, OTOH, by default calls VB's
>TranslateAccelerator implementation which traps the arrow keys...
OK. I see now. Thanks for the great info. I was worried that I might not
ever figure out why I couldn't get those WM_KEYDOWN messages.
Matthew Cromer
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|