wxWidgets过滤部分事件失效, 这是什么原因呢?

这是wxWidgets论坛的中文版本。在这里,您可以用您的母语汉语讨论上面任一子论坛所涉及的所有关于wxWidgets的话题。欢迎大家参与到对有价值的帖子的中英互译工作中来!
Post Reply
cnfnjatmzx
Earned a small fee
Earned a small fee
Posts: 12
Joined: Wed Sep 07, 2011 2:10 pm

wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by cnfnjatmzx »

大家好, 我是 wxWidgets 新手, 在匆匆看完了 <<使用wxWidgets进行跨平台程序开发>> 这本书后, 我感觉有很多地方都不扎实, 所以又从头开始看了, 今天刚开始就遇到了一个问题:

3.3 过滤某个事件 章节介绍的过滤键盘按键的小例子: 如果按键是 字母, 则正常输出, 否则什么也不输出.
这个程序我在 Linux 测试通过, 但在 Win7 64位下表现不正常: 如果按 数字键 1, 程序会提示按键不是字母, 但还是把 1 显示出来了, 之后再按任何数字都不会再输出了.
之后我测试了键盘上所有的符号(非字母), 发现对于所有的非字母键, 程序是可以判断出它不是字母, 但有一小部分符号会显示出来.

请问各位这是怎么造成的呢? 这在应用中会不会造成重大漏洞呢?


附C++代码:

Code: Select all

#include <wx/wx.h>


class MyApp : public wxApp
{
public:
	virtual bool OnInit();
};


IMPLEMENT_APP(MyApp)

class MyFrame : public wxFrame
{
public:
	MyFrame();
};

class MyTextCtrl : public wxTextCtrl
{
public:
	MyTextCtrl(wxWindow* parent) : wxTextCtrl(parent, wxID_EDIT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE)  {}

	void OnChar(wxKeyEvent& event)
	{
		if (wxIsalpha(event.GetKeyCode()))
		{
			event.Skip();
		}
		else
		{																													   
			wxBell();
			wxMessageBox(_("Must be a character!"), _("ERROR"), wxICON_ERROR | wxOK);
		}
	}
};


bool MyApp::OnInit()
{
	MyFrame* frame = new MyFrame();
	frame->Show(true);

	return true;
}

MyFrame::MyFrame() : wxFrame(NULL, -1, _("过滤键盘按键事件"))
{
	Centre();
	MyTextCtrl* textCtrl = new MyTextCtrl(this);
	textCtrl->Connect(wxID_EDIT, wxEVT_KEY_DOWN, wxKeyEventHandler(MyTextCtrl::OnChar));
}
cnfnjatmzx
Earned a small fee
Earned a small fee
Posts: 12
Joined: Wed Sep 07, 2011 2:10 pm

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by cnfnjatmzx »

在Linux 下一切正常, 在 Windows 下, 用 VS2010 和 Code::blocks 的结果相同, 都是有这种问题.
希望大侠们帮忙看看, 在 Windows 下为什么会有这种错误产生.
小弟先行告谢!
cnfnjatmzx
Earned a small fee
Earned a small fee
Posts: 12
Joined: Wed Sep 07, 2011 2:10 pm

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by cnfnjatmzx »

没有人回答........................
sishui
Earned some good credits
Earned some good credits
Posts: 121
Joined: Mon Mar 10, 2008 6:13 am
Location: 中國

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by sishui »

event.skip()的意思貌似不是过滤事件
event.skip()的作用是告诉MainLoop继续处理这个消息,而不是在当前handler处理完了就中断了,

就是说如果其他的parent的窗口或者paragate窗口还有相应的handler时,也应该调用他们。
直接return试试
work work!!!
cnfnjatmzx
Earned a small fee
Earned a small fee
Posts: 12
Joined: Wed Sep 07, 2011 2:10 pm

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by cnfnjatmzx »

sishui wrote:event.skip()的意思貌似不是过滤事件
event.skip()的作用是告诉MainLoop继续处理这个消息,而不是在当前handler处理完了就中断了,

就是说如果其他的parent的窗口或者paragate窗口还有相应的handler时,也应该调用他们。
直接return试试
你误会我的意思了, event.Skip() 是不会过滤掉事件. 我的问题是:

Code: Select all

      if (wxIsalpha(event.GetKeyCode()))  // 如果输入的是字母, 则把它显示出来;否则把它过滤掉并弹出一个警告窗口.
      {
         event.Skip();
      }
      else   // 过滤掉按键并弹出一个警告窗口.实际情况是弹出警告窗口, 并把数字显示出来.
      {    // 如果把下面内容改为 return; 就可以真正的过滤到非字母按键事件了.                                                                                      
         wxBell();
         wxMessageBox(_("Must be a character!"), _("ERROR"), wxICON_ERROR | wxOK);
      }
书上说只有在输入字母时才会显示出来, 如果输入数字什么的, 都会被过滤掉. 但现实的情况却是:程序可以捕捉的按键事件, 并判断出它是非字母, 程序按照自定义的方法处理了该事件后, 又把这个事件交给了wxWidgets的默认处理机制, 所以导致数字显示处理了. 但如果把 else 部分改为 return, 则就能真正的过滤到非字母按键事件了.
为什么必须使用 return 语句呢?如果不是用 return 语句, 那需要怎样才能过滤掉按键事件?
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 340
Joined: Mon Oct 06, 2008 12:55 pm

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by samsam598 »

是wxMessageBox造成的,注释掉wxMessageBox 一句应该就可以了。如果要用MessageBox调试或提醒用户,改用wxLog家族,如wxLogStatus,wxLogError,wxLogMessage,等等,反正这里不要用wxMessageBox就行了。
估计是wxMessageBox的一个bug, 谁有空去report.
Regards,
Sam
-------------------------------------------------------------------
Windows 10 64bit
VS Community 2019
msys2-mingw13.2.0 C::B character set: UTF-8/GBK(Chinese)
wxWidgets 3.3/3.2.4 Unicode Mono Static gcc static build
sishui
Earned some good credits
Earned some good credits
Posts: 121
Joined: Mon Mar 10, 2008 6:13 am
Location: 中國

Re: wxWidgets过滤部分事件失效, 这是什么原因呢?

Post by sishui »

简单跟了下 wxMessagebox底层调用windows的MessageBox,
MessageBox弹出来,字符就进去了,(⊙o⊙)…

要么按sam兄的说法 用wxLogMessage,wxLogMessage 没问题,要么自己用wxDialog实现个对话框。
work work!!!
Post Reply