创建一个无窗口、可缩放的文本区域,代理 C# 中的真实 Winforms 文本框
重要提示:我们确实需要所述功能,因此请不要开始建议替代方案。
我们尝试在包含文本和非文本区域的自定义 WinForms 控件上显示和输入文本 - 换句话说,现代画布。
我们需要能够以各种缩放级别并使用其他自定义效果在自定义控件上显示文本和插入符号。但是,我们不想(或没有资金)编写键盘和鼠标输入法代码、线路服务代码等 - 解决方案必须支持标准 TextBox 支持的所有语言。
因此,我们正在考虑的方法是使用隐藏的文本框,并在适当的转换后将键盘和鼠标事件路由到它,并使用其公共访问器来确定字符的布局方式。从理论上讲,这将使我们能够突出显示所选文本、绘制插入符号、在用户按下按键时执行正确的操作(包括使用键盘选择和删除文本)。
换句话说,文本区域是隐藏文本框的代理。 结果是,我们在文本框的功能上进行构建,同时克服了其局限性,例如缺乏缩放等。
我们期望显示部分是可行的,但键盘和鼠标输入可能非常棘手。
问题: 以前是否尝试过这种方法并取得成功?任何工作代码都会很棒。
更新:一个快速而肮脏的实验似乎表明 TextBox 不尊重鼠标消息中发送的鼠标坐标,而是直接读取当前鼠标位置。因此,一个新的问题是:
是否可以以一种适用于所有语言的方式将所有 TextBox 鼠标事件转换为直接 TextBox 操作?我们猜测命中测试方法 GetCharIndexFromPosition 与文本选择方法 Select 一起应该足够了。这看起来合理吗?
Important: we really need the stated functionality, so please don't start suggesting alternatives.
We're trying to display and input text on a custom WinForms control that includes text and non-text regions - in other words, a modern canvas.
We need to be able to display the text and caret on the custom control at various zoom levels and using other custom effects. However, we do not want (or have the wherewithal) to write keyboard and mouse input method code, line services code, etc - the solution must support all languages that the standard TextBox supports.
Therefore, the approach we're considering is to use a hidden textbox, and to route keyboard and mouse events to it after suitable translation, and to use its public accessors to determine how the characters are laid out. This would theoretically enable us to highlight selected text, draw a caret, perform the right actions when the user presses a key (including selecting and deleting text with the keyboard.)
In other words, the text region is a proxy of the hidden textbox.
The result is that we build on the functionality of the textbox while overcoming its limitations such as lack of zoom, etc.
We expect that the display part is doable but the keyboard and mouse input are probably very tricky.
Questions:
Has this been tried before with any success? Any working code would be excellent.
Update: A quick and dirty experiment seems to indicate that the TextBox does not respect the mouse coordinates sent in mouse messages but seems to read the current mouse position directly. Therefore, a new question:
Is it possible to cast all TextBox mouse events in terms of direct TextBox actions, in a way that would work across all languages? Our guess that the hit testing method GetCharIndexFromPosition together with the text selection method Select, should suffice. Does this seem reasonable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议您按照建议使用隐藏的 TextBox,然后向其发送 WM_PRINT 消息,以便将其内容绘制到位图上。然后,您可以将该位图绘制到实际感兴趣的区域上,并应用缩放或旋转等更改。任何键盘消息都可以简单地转发到隐藏的文本框,因此插入符号和内容将按照用户的预期进行更新。棘手的部分只是鼠标处理。您需要获取客户端坐标,然后使用反向转换(缩放、旋转等)从客户端获取隐藏文本框的实际坐标。
I would recommend that you use a hidden TextBox as you suggest and then send it WM_PRINT messages in order to have its content drawn onto a bitmap. Then you can draw that bitmap onto the actual area of interest and in doing apply changes such as zooming or rotation and so forth. Any keyboard messages can be simply forwarded to the hidden TextBox and so the caret and contents will be updated as expected by the user. The tricky part is just the mouse handling. You need to take the client coordinate and then use the reverse transformation (zooming, rotation etc) to get from client to the actual coordinates of the hidden TextBox.