我正在更新一个现有的扫描条形码的应用程序,它是用运行在windows compact Framework3.5上的VB.net编写的。该扫描仪是运行windows mobile手持6.5的POCKETPC。我已经在类模块中添加了使用异步TCP套接字的代码。套接字代码读取和发送数据到缓冲池和从缓冲池发送数据。现在我需要“通知”GUI表单,数据已经从TCP套接字接收到,可以处理了。因为这两个进程运行在不同的线程上,所以我意识到我不能直接访问GUI控件。因此,我创建了一条windows消息(WM_CUSTOMMSG = &H400),然后使用“SENDMESSAGE”。现有的WndProc sub (Protected Overrides Sub WndProc(ByRef消息作为Microsoft.WindowsCE.Forms.Message))处理扫描仪消息的WM_DECODEDATA。我添加了代码,以便现在也处理我正在创建的WM_CUSTOMMSG消息。WM_CUSTOMMSG正在到达WndProc,我可以显示MessageBox并写入日志文件,但对GUI控件所做的任何更改都会消失。我试图启动一个表单计时器,但也没有效果。WM_DECODEDATA消息的代码完美地更新了图形用户界面控件。我遗漏了什么/做错了什么?
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发布于 2016-08-07 05:32:26
我不知道你是不是做错了什么,但你也许可以把事情做得容易得多。所有的Control(包括Form)都有一个Invoke()方法,您可以调用该方法让框架处理windows消息。
This article对它进行了更详细的描述,包括InvokeRequired属性,如果您知道数据是从另一个线程发送的,则可以忽略该属性。
如果您确实选择手动处理这些消息(因为您已经有了WndProc例程),请确保捕获更新图形用户界面的方法中的所有异常,并可能检查InvokeRequired以查看控件是否同意您可以从该线程更新它。
发布于 2016-08-08 02:04:45
我会在线程代码中使用委托和平均处理者,并使用带有自定义委托的InvokeRequired来更新GUI线程。
不建议处理自定义消息。或者为什么MS在WindowsCE.Forms中隐藏WndProc?OTOH您可能需要刷新已更改的控件,让它们知道它们需要更新。你使用PostMessage还是SendMessage。如果稍后,这将阻止线程代码,直到消息被处理,这可能会阻止图形用户界面更新自己,如果WndProc本身在代码中使用SendMessage来处理自定义消息。
Private Sub UpdateTextBox(ByVal sender As Object, ByVal e As EventArgs)
'---delegate to update the textbox control
txtMessagesArchive.Text += str
End Sub将从同一个类中的后台线程通过以下方式调用:
Me.Invoke(New EventHandler(AddressOf UpdateTextBox))Different ways to update GUI from background thread,但在C#中
发布于 2016-08-11 12:17:49
感谢所有提供答案的人。我之前尝试过使用invoke进行委托,但这导致系统崩溃。我花了一周多的时间试图找出委托代码的错误之处--我的意思是它是如此简单,但并不成功。然后我尝试了WndProc路由。Josef在他的回答中的例子告诉我,委托必须与后台线程在同一个类中。我将委托放在了form类中。一旦我将委托放在正确的类中,它就可以完美地工作。我有50年的IT和编程经验,你仍然可以学习。我不会试图找出WndProc问题的根源。这现在是理论上的,因为委托路由是一种更好的解决方案,并且现在正在发挥作用。谢谢
https://stackoverflow.com/questions/38800396
复制相似问题