您的位置:首页 > 其它

去除wxTextCtrl的右击菜单或者实现wxTextCtrl在windows下Ctrl+A热键

2015-10-13 16:45 239 查看
项目提交验收的时候发现了wxTextCtrl在空内容右击菜单功能项会出现问题,这个功能实际上是冗余的,但是wxWidgets本身并没有提供一个可以手动配置的方法去除,于是我考虑了方法重载。

class PreviewTextCtrl : public wxTextCtrl
{
public:
PreviewTextCtrl(
wxWindow *parent, wxWindowID id, const wxString &value=wxEmptyString, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxValidator &validator=wxDefaultValidator, const wxString &name=wxTextCtrlNameStr
):wxTextCtrl(parent,id,value,pos,size,style,validator,name){};
public:
// 重写右键菜单
void OnContextMenu(wxContextMenuEvent& event){};
DECLARE_EVENT_TABLE()
};


BEGIN_EVENT_TABLE(PreviewTextCtrl, wxTextCtrl)
EVT_CONTEXT_MENU(PreviewTextCtrl::OnContextMenu)
END_EVENT_TABLE()


声明时间表是必须的,因为时间处理机制是根据eventloop来查找下一个处理函数,没有声明处理函数,最后在事件处理表里面存在还是父级的处理函数

注意点一点如果TextCtrl具有 wxTE_Rich 属性 那么textCtrl内部实现将与基本的textCtrl的实现存在区别,我们此时去重写textCtrl的方法将无法对控件生效,

之前重写右击菜单就能很好的验证这一点。

wxTE_Rich这个属性,我之前想利用了他在windwos环境下能够提供Ctrl+A 快捷键的功能,但是发现了这些drawbacks,于是我舍弃了它,实现Ctrl+A热键我也是利用了

函数重写。

通过查看wxTextCtrl的源码,我发现在父类wxTextEntry中存在着 copy redo select等关键字,于是我推测内部wxTextCtrl内部实现复制粘贴等也是调用

wxTextEntry的对应的方法,通过注释我发现了DoSetSelection(from,to,flags) from,to入值为-1时会实现内容全部选择的功能,于是我便确定下一步需要实现的是实现

Ctrl+A监听,

在wxWigdets中间监听按键分 keydown keyup char charhook这四种方式

keydown/up的方式只能响应单键位,无法响应组合键,并且在形参keyevent中不存getModifier()这样的方法(注释:java的keyevent中提供这种方式回去修饰按键),

接下主要的区分点在于charhook和char,

char事件能够满足我们的需求,至少能够识别ctrl+a,

charhook 可以实现按键事件拦截的功能,这个事件在所有其他键盘事件之前产生并处理,如果不适用event.Skip(),那么keydown和char事件是无法处理,但是keyup事件还存在。另外在官方文档中说charhook事件将自动向上传递,目前我还没有深入理解这一特性。

最后实现自己的wxTextCtrl的ctrl+a监听的代码。

void CustomTextCtrl::OnChar(wxKeyEvent& event)
{
switch ( event.GetKeyCode() )
{
case WXK_RETURN:
{
wxCommandEvent event(wxEVT_TEXT_ENTER, m_windowId);
InitCommandEvent(event);
event.SetString(GetValue());
if ( HandleWindowEvent(event) )
if ( !HasFlag(wxTE_MULTILINE) )
return;
//else: multiline controls need Enter for themselves
}
break;

case WXK_TAB:
if ( !(m_windowStyle & wxTE_PROCESS_TAB))
{
if ( FindFocus() == this )
{
int flags = 0;
if (!event.ShiftDown())
flags |= wxNavigationKeyEvent::IsForward ;
if (event.ControlDown())
flags |= wxNavigationKeyEvent::WinChange ;
if (Navigate(flags))
return;
}
}
else
{
// Insert tab since calling the default Windows handler
// doesn't seem to do it
WriteText(wxT("\t"));
return;
}
break;
case WXK_CONTROL_A:
wxTextEntry::DoSetSelection(-1,-1,0);
return;

}

// no, we didn't process it
event.Skip();
}
别忘了添加事件表声明

BEGIN_EVENT_TABLE(CustomTextCtrl, wxTextCtrl)
EVT_CONTEXT_MENU(CustomTextCtrl::OnContextMenu)
EVT_CHAR(CustomTextCtrl::OnChar)
END_EVENT_TABLE()


参考文章
http://www.imooo.com/kaifayuyan/program/402647.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: