Need more help with OpenNETCF, IMessageFilter problem

V

vbmark

Hello,

I'm really stuck on this problem. I can't get it to work and really need
it to. I've seen the C# example for this code and translated it to
vb.net. I'm using the Smartphone emulator.

I have a bunch of text boxes and combo boxes that get rearranged during
the program running. The problem is that when the user hits the up or
down arrow the focus does not go to the control above or below since the
order of the controls have changed. So I want to control this by
capturing the up and down arrow key presses.

I have all the code in place and everything seems to be working except
for this one thing. On this line: "If m.HWnd.Equals(pHWnd) Then" the
HWNd of the message is NEVER equal to the HWnd of the control!

Here is the relevant code of the TextBox:

Public Class clsTextBox
Inherits TextBox
Implements OpenNETCF.Windows.Forms.IMessageFilter
Private pHWnd As IntPtr

Delegate Sub MyKeyDownDelegate(ByVal e As KeyEventArgs, _
ByVal lparam As Integer)

Private myfunc As MyKeyDownDelegate

Public Sub New(ByVal DelegateFunction As MyKeyDownDelegate)
myfunc = DelegateFunction
End Sub

Public Function PreFilterMessage(ByRef m As _
Microsoft.WindowsCE.Forms.Message) _
As Boolean Implements _
OpenNETCF.Windows.Forms.IMessageFilter.PreFilterMessage
Try
If m.HWnd.Equals(pHWnd) Then
Select Case m.Msg
Case Window.Messages.WM_KEYDOWN
myfunc.Invoke(New KeyEventArgs(m.WParam.ToInt32), _
m.LParam.ToInt32)
End Select
End If
Catch ex As Exception
'MsgBox(ex.ToString)
End Try
End Function

Public Property HWnd() As IntPtr
Set(ByVal Value As IntPtr)
pHWnd = Value
End Set
Get
Return pHWnd
End Get
End Property
End Class

Here is the relevant code in my main form:
Imports OpenNETCF
Imports OpenNETCF.Windows.Forms
Imports System.Runtime.InteropServices

' Interop declarations
<DllImport("coredll.dll")> _
Private Shared Function GetCapture() As IntPtr
End Function

' This is to allow the interception of the KeyDown events.
Public Shared Sub Main()
ApplicationEx.Run(New frmMain)
End Sub

Private Sub CreateControls()
 
A

Alex Feinman [MVP]

Your code seems to work for me with one minor change:

AddHandler m_oTextBox(x).GotFocus, AddressOf TextBox_GotFocus

' Add this to make sure that your TextBox had a chance to acquire its hwnd

m_oTextBox(x).Focus()

ApplicationEx.AddMessageFilter(m_oTextBox(i))


One thign I have to say about your design - it's not a very good idea to
have each control have its own message filter. This will slow your
application to a crawl since ApplicationEx needs to invoke every single
delegate on every windows message. Since you only want keyboard messages,
keep track of which control is focused (by having Focus event handler in
your control class and setting a global variable to reference this control).
This way you could have a single message filter where you could invoke
Control's own message filter for the active control only
 
V

vbmark

Your code seems to work for me with one minor change:

I already have the below line in my code. I guess you just missed it in
my code post.
AddHandler m_oTextBox(x).GotFocus, AddressOf TextBox_GotFocus

' Add this to make sure that your TextBox had a chance to acquire its
hwnd

Ok, I added the below line.
m_oTextBox(x).Focus()

Not sure if in the below line you meant to put an "i" instead of an "x".
ApplicationEx.AddMessageFilter(m_oTextBox(i))


One thign I have to say about your design - it's not a very good idea
to have each control have its own message filter. This will slow your
application to a crawl since ApplicationEx needs to invoke every
single delegate on every windows message. Since you only want keyboard
messages, keep track of which control is focused (by having Focus
event handler in your control class and setting a global variable to
reference this control). This way you could have a single message
filter where you could invoke Control's own message filter for the
active control only

I understand what you are saying is the problem, but I don't understand
the solution. Also, adding the line m_oTextBox(x).Focus() did not change
anything. The HWnds still never match.

Could you post the code that you got to work or, even better, if I post a
temporary email address would you email it to me?

Thanks!
 
V

vbmark

Yes, your code works for the pocket PC. But I am programming on the
Smartphone and you code does not work there. I opened a new Smarphone
project and imported your form and I still have the same problem.
 
A

Alex Feinman [MVP]

Doh! I haven't noticed the smartphone part. Ok, I'll look into it further,
but keep in mind that the Smartphone edit control is actually a composite
control - the inner EDIT and the outer with a different class name. I
suspect that when you use Capture/GetCapture, you receive the handle of the
outer control, while the message comes for the inner control. Perhaps you
will need to use GetWindow(GW_CHILD) to get the handle of the actual edit
control.
 
V

vbmark

I'm not sure I understand GetWindow. It seems as though you need to pass
it an HWnd. What would be the VB.NET syntax for this?
 
C

Chris Tacke, eMVP

Yes, it requires a reference window. For example, if you say GetWindow and
you want GW_CHILD, it has to somehow know what the parent is that you want
the child for. So you'll pass in the hWnd that your earlier code already
got.

--
Chris Tacke
Co-founder
OpenNETCF.org
Has OpenNETCF helped you? Consider donating to support us!
http://www.opennetcf.org/donate
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top