请教一个自定义消息的问题 Topic is solved

这是wxWidgets论坛的中文版本。在这里,您可以用您的母语汉语讨论上面任一子论坛所涉及的所有关于wxWidgets的话题。欢迎大家参与到对有价值的帖子的中英互译工作中来!
Post Reply
sszhw
Earned a small fee
Earned a small fee
Posts: 14
Joined: Tue Aug 11, 2009 7:38 am

请教一个自定义消息的问题

Post by sszhw »

请问各位高人有什么办法,可以让自定义消息按发送顺序读取,而不是前面的消息没有处理就被后面的冲掉?

具体问题是这样的:有两个线程,A是界面显示的主线程,B是负责计算的。B计算后,通过将自定义消息的clientData强制转换为结构体(里面是两个wxString)使用Bl->GetEventHandler()->AddPendingEvent(event1);语句发送,其中Bl是指向界面的wxWindow指针。A在接收到消息后,把ClientData强制转换为同样的结构体,并在ListCtrl中显示。但是运行以后,比如应该显示1、2、3。。。。10十个数,但是实际上显示的是十个10。如果我在发送语句后加上一个Sleep(1),则大部分能够正常显示,但偶尔也有被冲掉的,比如有两个8而没有7。
请问应该怎么办呢?谢谢大家

wxWidgets2.8.9 +VS2005+Windows XP

对了,自定义消息继承自wxCommandEvent
JenT
Earned some good credits
Earned some good credits
Posts: 114
Joined: Fri Oct 24, 2008 9:23 am

Re: 请教一个自定义消息的问题

Post by JenT »

sszhw wrote:请问各位高人有什么办法,可以让自定义消息按发送顺序读取,而不是前面的消息没有处理就被后面的冲掉?

具体问题是这样的:有两个线程,A是界面显示的主线程,B是负责计算的。B计算后,通过将自定义消息的clientData强制转换为结构体(里面是两个wxString)使用Bl->GetEventHandler()->AddPendingEvent(event1);语句发送,其中Bl是指向界面的wxWindow指针。A在接收到消息后,把ClientData强制转换为同样的结构体,并在ListCtrl中显示。但是运行以后,比如应该显示1、2、3。。。。10十个数,但是实际上显示的是十个10。如果我在发送语句后加上一个Sleep(1),则大部分能够正常显示,但偶尔也有被冲掉的,比如有两个8而没有7。
请问应该怎么办呢?谢谢大家

wxWidgets2.8.9 +VS2005+Windows XP

对了,自定义消息继承自wxCommandEvent
改成這個試試看
Bl->GetEventHandler()->ProcessEvent(event1);
sszhw
Earned a small fee
Earned a small fee
Posts: 14
Joined: Tue Aug 11, 2009 7:38 am

Post by sszhw »

谢谢JenT,换了以后确实可以。能指教一下二者的区别吗?印象中我原来用过ProcessEvent,但似乎多线程间冲突,有人说不能在子线程中调用发送给主线程。刚才试了试是正常的,但没有全面测试,不知道原来的错误会不会重现。所以如果愿意的话,您能讲解一下二者的区别和注意事项吗?谢谢


果然还是不行……运行到后来会触发wxTrap的断点,看堆栈,是InsertItem时中断的。 assert "m_count == ListView_GetItemCount(GetHwnd())" failed in wxListCtrl::InsertItem(): m_count should match ListView_GetItemCount
JenT
Earned some good credits
Earned some good credits
Posts: 114
Joined: Fri Oct 24, 2008 9:23 am

Post by JenT »

sszhw wrote:谢谢JenT,换了以后确实可以。能指教一下二者的区别吗?印象中我原来用过ProcessEvent,但似乎多线程间冲突,有人说不能在子线程中调用发送给主线程。刚才试了试是正常的,但没有全面测试,不知道原来的错误会不会重现。所以如果愿意的话,您能讲解一下二者的区别和注意事项吗?谢谢


果然还是不行……运行到后来会触发wxTrap的断点,看堆栈,是InsertItem时中断的。 assert "m_count == ListView_GetItemCount(GetHwnd())" failed in wxListCtrl::InsertItem(): m_count should match ListView_GetItemCount
wxMutexGuiEnter();

Bl->GetEventHandler()->ProcessEvent(event1);
wxMutexGuiLeave();

再試試,如果不行,那可能要用資料交換的方式了。
murusu
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Mar 12, 2009 9:38 am

Re: 请教一个自定义消息的问题

Post by murusu »

sszhw wrote:请问各位高人有什么办法,可以让自定义消息按发送顺序读取,而不是前面的消息没有处理就被后面的冲掉?

具体问题是这样的:有两个线程,A是界面显示的主线程,B是负责计算的。B计算后,通过将自定义消息的clientData强制转换为结构体(里面是两个wxString)使用Bl->GetEventHandler()->AddPendingEvent(event1);语句发送,其中Bl是指向界面的wxWindow指针。A在接收到消息后,把ClientData强制转换为同样的结构体,并在ListCtrl中显示。但是运行以后,比如应该显示1、2、3。。。。10十个数,但是实际上显示的是十个10。如果我在发送语句后加上一个Sleep(1),则大部分能够正常显示,但偶尔也有被冲掉的,比如有两个8而没有7。
请问应该怎么办呢?谢谢大家

wxWidgets2.8.9 +VS2005+Windows XP

对了,自定义消息继承自wxCommandEvent
The difference between sending an event (using the ProcessEvent method) and posting it is that in the first case the event is processed before the function returns, while in the second case, the function returns immediately and the event will be processed sometime later (usually during the next event loop iteration).

A copy of event is made by the function, so the original can be deleted as soon as function returns (it is common that the original is created on the stack). This requires that the wxEvent::Clone method be implemented by event so that it can be duplicated and stored until it gets processed.

remark里面有相关说明的
其实用ListCtrl显示的话为什么不直接操作数据源,这样简单多了。
sszhw
Earned a small fee
Earned a small fee
Posts: 14
Joined: Tue Aug 11, 2009 7:38 am

Post by sszhw »

先谢谢两位!

TO JenT:
现在正在测试,暂时运行正常。有一个问题是,用了ProcessEvent以后(不管用不用锁),整个程序的运行速度都慢了……难道说ProcessEvent是等Event被处理了以后才返回?就像MFC中send和post的区别?
另外,能讲一下为什么加了GUI的锁就没事了吗?谢谢。

To murusu:
直接操作数据源?不好意思,没明白。如果说是指数据库的话,我并没有用到数据库。如果是指普通数据包的话。直接读全局变量也考虑过,后来觉得太不优雅了就算了,何况还得手动加锁。

现在考虑用个全局队列,一边读取,一边写入。不过估计速度上不会有优势,而且对我这个应用来说,更加麻烦了。

最新测试结果,在某次运算当中关闭对话框时,同样的断点又出现了。追查堆栈,还是传递消息后,InsertItem时断的。
Post Reply