I'm updating an existing application that scans barcodes and is written in VB.net running on windows compact framework 3.5. The scanner is a POCKETPC running windows mobile handheld 6.5. I have added code that uses Asynchronous TCP sockets in a class module. The sockets code is reading and sending data to and from a buffer pool. I now need to “inform” the GUI form that data has been received from the TCP socket and is ready for processing. Because the two processes are running on different threads I realise I cannot access the GUI controls directly. I therefore create a windows message (WM_CUSTOMMSG = &H400) and then use “SENDMESSAGE”. There is an existing WndProc sub (Protected Overrides Sub WndProc(ByRef msg As Microsoft.WindowsCE.Forms.Message)) that handles the WM_DECODEDATA for the scanner message. I added in code to now also process the WM_CUSTOMMSG message I am creating. The WM_CUSTOMMSG is arriving at the WndProc and I am able to display a MessageBox and write a log file, but any changes made to the GUI controls just disappear. I tried to start a forms timer but this also has no effect. Code for the WM_DECODEDATA message updates the GUI controls perfectly. What am I missing / done wrong?
Public Class frmHome
Public SockReceiveMsg As Microsoft.WindowsCE.Forms.Message
Public Sub New()
Private yy As Integer = 0
Private xx As Integer = 0
InitializeComponent()
Me.MsgWin = New MsgWindow(Me)
' Add any initialization after the InitializeComponent() call.
SockReceiveMsg = Microsoft.WindowsCE.Forms.Message.Create(MsgWin.Hwnd, MsgWindow.WM_CUSTOMMSG, New IntPtr(xx), New IntPtr(yy))
end class
Private Sub ReceiveCallback(ByVal ar As IAsyncResult)
'This is the async call back sub
MessageWindow.SendMessage(frmHome.SockReceiveMsg)
end sub
Protected Overrides Sub WndProc(ByRef msg As Microsoft.WindowsCE.Forms.Message)
Dim rc As Integer
Dim ar() As String
If msg.Msg = WM_CUSTOMMSG Then
Try
MsgBox("restart timer") 'this displays
Reader.ReaderEngineAPI.Beeper(8, "") 'a quick ok beep. this works
frmHome.timer1.Enabled = False
frmHome.timer1.Interval = 100
frmHome.timer1.Enabled = True
Catch ex As Exception
MsgBox("wndproc Error1: " & ex.Message)
End Try
End If
'pass all messages onto the base processing. Here the windows ones get processed and our ones get cleared and the storage released
MyBase.WndProc(msg)
End Sub
I don't know if/what you're doing wrong, but you can probably do things alot easier. All
Controls (includingForms) have anInvoke()method that you can call to let the framework deal with the windows messages.This article describes it in a bit more detail, including the
InvokeRequiredproperty, which you can probably ignore if you know the data is sent from another thread.If you do choose to handle these messages manually (since you already have the
WndProcroutine), be sure to catch all exceptions in the method that updates the GUI, and perhaps inspect theInvokeRequiredto see if the control agrees that you can update it from that thread.