从文本控件中检索字符位置的客户区坐标
我需要编写一个函数,它可以从文本编辑控件中的字符位置获取屏幕坐标。 我正在使用wxWidgets
框架提供的文本编辑控件。 wxTextCtrl
没有公开任何可以提供此信息的API函数。 在Windows上,我可以通过将EM_POSFROMCHAR发送到文本控件来获取信息。
我想知道如何在Linux等其他环境中做同样的事情。 目前,这只需要在运行在X Window系统之上的桌面环境(如GNOME , KDE和XFCE)上完成 。 有办法吗? 在这些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()
,但不清楚结果应该表示在哪个坐标系中。
wxTextCtrl
inheritance自wxWindow
,它提供了wxWindow::GetPosition()
。 父类由wxWindow::GetParent
找到。
在他们之间,我怀疑答案很容易得出。
自从我上次wxWidgets经历以来已经有一段时间了,但是如果找不到更简单(更短)的方法,那么在插入符号之前计算文本的范围(例如使用wxDC :: GetTextExtent())是一种可能的查找方法你追求的位置? 这将为您提供相对于wxTextCtrl中文本开头的位置。 您可能必须考虑边框大小和边框与实际文本之间的间距。 如果需要通过wxTextCtrl :: HitTest()进行细化?
BTW wxStyledTextCtrl怎么样?
您是否考虑过使用HitTest
函数进行二进制搜索? 不是很优雅,但它应该很快,并且HitTest
是为wxGTK2实现的,所以它应该工作。