从文本控件中检索字符位置的客户区坐标

我需要编写一个函数,它可以从文本编辑控件中的字符位置获取屏幕坐标。 我正在使用wxWidgets框架提供的文本编辑控件。 wxTextCtrl没有公开任何可以提供此信息的API函数。 在Windows上,我可以通过将EM_POSFROMCHAR发送到文本控件来获取信息。

我想知道如何在Linux等其他环境中做同样的事情。 目前,这只需要在运行在X Window系统之上的桌面环境(如GNOMEKDEXFCE)上完成 。 有办法吗? 在这些DE上,谁像文本编辑那样绘制控件? 它是由X管理并由特定DE设计的吗?

任何帮助,将不胜感激。

嗯,这是可能的,但你需要实现一个wxTextCtrl派生控件,它依赖于任何特定wxWidgets端口(wxMSW,wxGTK等)的平台function。

所以,因为你问过Linux的实现。 让我解释一下如何为wxGTK 2.9实现它。 下面是wxTextCtrlExt控件定义:

 #include  #include  //----------------------------------------------------------------------------- // wxTextCtrlExt //----------------------------------------------------------------------------- class wxTextCtrlExt : public wxTextCtrl { public: wxTextCtrlExt() : wxTextCtrl() { } wxTextCtrlExt(wxWindow* parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr) : wxTextCtrl(parent, id, value, pos, size, style, validator, name ) { } wxPoint GetPositionCoords(long pos); }; 

和wxGTK实现:

 #include "wxTextCtrlExt.h" #include  #include  wxPoint wxTextCtrlExt::GetPositionCoords(long pos) { if ( IsMultiLine() ) { GtkTextView* txtView = GTK_TEXT_VIEW(m_focusWidget); GtkTextBuffer* txtBuffer = gtk_text_view_get_buffer(txtView); GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(txtBuffer, &iter, pos); GdkRectangle location; // output location in buffer coordinates gtk_text_view_get_iter_location(txtView, &iter, &location); return wxPoint(location.x, location.y); } return wxPoint(0,0); } 

您可能还想将缓冲区坐标转换为小部件的坐标:

  // If we need to convert our coordinates to GdkPoint out; gtk_text_view_buffer_to_window_coords(txtView, GTK_TEXT_WINDOW_WIDGET, location.x, location.y, &out.x, &out.y ); return wxPoint(out.x, out.y); 

如您所见,此特定实现不考虑单行文本条目,这就是您在创建wxTextCtrlExt控件时需要使用wxTE_MULTILINE样式的wxTextCtrlExt

好吧,下面是如何使用它。 设m_Text2是指向wxTextCtrlExt类的子对象的指针:

 long iCharPos = m_Text2->GetInsertionPoint(); long iCharPosMax = m_Text2->GetLastPosition(); wxPoint pos = m_Text2->GetPositionCoords(iCharPos); 

现在我们在pos获得了角色位置坐标。 而已!

您可能感兴趣的一些链接:

  • GtkTextView – 显示GtkTextBuffer的小部件
  • GtkTextBuffer – 存储在GtkTextView中显示的属性文本

现在关键是你的第二个问题。

在这些DE上,谁像文本编辑那样绘制控件? 它是由X管理并由特定DE设计的吗?

这取决于您使用的wxWidgets端口。 wxMSW和wxGTK端口分别使用Win32和GTK + 2本机控件。 基于wxUniversal的端口(例如wxX11,wxMGL)通过wxWidgets本身绘制所有控件。 X Window系统本身并不强制要求用户界面。 它提供了构建GUI环境的基本框架:在屏幕上绘制和移动窗口以及与鼠标和键盘交互。

我不完全清楚找到哪个字符位置,但解决方案可能涉及wxTextCtrl::XYToPosition()和/或wxTextCtrl::PositionToXY() ,但不清楚结果应该表示在哪个坐标系中。

wxTextCtrlinheritance自wxWindow ,它提供了wxWindow::GetPosition() 。 父类由wxWindow::GetParent找到。

在他们之间,我怀疑答案很容易得出。

自从我上次wxWidgets经历以来已经有一段时间了,但是如果找不到更简单(更短)的方法,那么在插入符号之前计算文本的范围(例如使用wxDC :: GetTextExtent())是一种可能的查找方法你追求的位置? 这将为您提供相对于wxTextCtrl中文本开头的位置。 您可能必须考虑边框大小和边框与实际文本之间的间距。 如果需要通过wxTextCtrl :: HitTest()进行细化?
BTW wxStyledTextCtrl怎么样?

您是否考虑过使用HitTest函数进行二进制搜索? 不是很优雅,但它应该很快,并且HitTest是为wxGTK2实现的,所以它应该工作。