gpt4 book ai didi

c# - RichTextBox:如何确定文本是否超出控件边界?

转载 作者:太空宇宙 更新时间:2023-11-03 11:51:56 26 4
gpt4 key购买 nike

我已经扩展了 RichTextBox 控件以实现 native RichEdit 类中提供的大部分缺失功能。

我遇到了一个问题,如果控件设置为换行到窗口或换行到打印机,水平滚动条会出现,即使在调整控件大小时它不应该出现。

将 wordwrap 循环为 none 并返回似乎可以解决问题,但在包装到打印机时可能相对较慢(即:太慢而无法调用每个 Resize 事件)。

这是我的自动换行代码:

   private void ChangeWordWrap(WordWrap wordWrap)
{
switch (wordWrap)
{
case WordWrap.NoWrap:
{
User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_SETTARGETDEVICE, 0, 1);
break;
}
case WordWrap.WrapToPrintDocument:
{
using (Graphics g = PrintDocument.PrinterSettings.CreateMeasurementGraphics(PrintDocument.DefaultPageSettings))
{
int lParam = ConvertEx.HundredthInchToTwips((PrintDocument.DefaultPageSettings.Bounds.Width - PrintDocument.DefaultPageSettings.Margins.Left - PrintDocument.DefaultPageSettings.Margins.Right));
IntPtr wParam = g.GetHdc();
User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_SETTARGETDEVICE, wParam, lParam);
g.ReleaseHdc();
}
break;
}
case WordWrap.WrapToControl:
{
User32.SendMessage(_RichTextBox.Handle, ApiConstants.EM_SETTARGETDEVICE, 0, 0);
break;
}
}
}

最初我认为问题可能与我正在释放图形句柄有关,但当我包装到控件并且不需要句柄时也会出现此问题。

添加截图:

正确的行为:

alt text http://www.charltonfamily.net/temp/RTB_EM_SETTARGETDEVICE/WrapToPrinter_Correct_Horizontal_Scrollbar.png

不正确的行为(在调整表单大小后非常):

alt text http://www.charltonfamily.net/temp/RTB_EM_SETTARGETDEVICE/WrapToPrinter_Inappropriate_Horizontal_Scrollbar.png

窗口换行/无换行代码来自 http://msdn.microsoft.com/en-us/library/bb774282(VS.85).aspx 的评论

调用::SendMessage(hwnd, EM_SETTARGETDEVICE, NULL, 0) 会将文本换行到窗口,而::SendMessage(hwnd, EM_SETTARGETDEVICE, NULL, 1) 将完全禁用自动换行。我不确定其他地方是否记录了这一点。

我的 p/调用:

    [DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

相关常量:

    public const int WM_USER = 0x400;
public const int EM_SETTARGETDEVICE = (WM_USER + 72);

编辑:

我对此进行了更多研究,我相信 .NET RichTextBox 控件可能会在调整控件大小时发送带有错误值的 SetScrollRange()。这是有道理的,因为它不一定知道 EM_SETTARGETDEVICE 消息。

我可能可以在调整大小后执行 SetScrollRange() 或类似的东西,但我的问题是我不知道正确的值是什么,也不知道我该如何弄清楚。

我注意到的另一件事是,当问题出现时,我可以将控件的大小调整为实际环绕文本的大小。此时,滚动条回到功能状态,我可以调整大小,直到自动换行循环为无并返回。

编辑:(在我下面的非功能性答案中还有一些更多细节)

看起来 EM_GETRECT 并不是我真正想要的,因为它的大小会随着控件大小的变化而变化。这是 MSDN 描述:

EM_GETRECT 消息

Gets the formatting rectangle of an edit control. The formatting rectangle is the limiting rectangle into which the control draws the text. The limiting rectangle is independent of the size of the edit-control window. You can send this message to either an edit control or a rich edit control.

我最初的理解是,这是整个文本的矩形,从中我可以确定客户端窗口是否小于格式化矩形,因此应该显示滚动条。

看起来这个格式化矩形的真正目的是使文本显示在小于编辑控件的区域(即:边距)。

新问题:

那么,有没有我认为 EM_GETRECT 会给我的矩形?一个可以告诉我文本(包括超出屏幕的部分)有多宽的矩形?例如,如果我有一个 400 像素的控件和一行 800 像素长的文本,我想获得 800 像素的值,以便我可以将它与控件宽度进行比较并显示/不显示滚动条。

实际上,我并不关心不受控制的文本的长度,我更关心的是知道IF 文本超出了控制范围。

感谢迄今为止的所有帮助。

最佳答案

我没有试过你的代码,没有 P/Invoke 声明就不容易运行。虽然你的 SendMessage 的 LPARAM 参数声明看起来不对,但它应该是 IntPtr。为 WPARAM 传递 0 也不应该编译,不确定你做了什么。

一定要检查 SendMessage() 的返回值,如果 RichEdit 对您的参数不满意,它会返回 IntPtr.Zero。 SDK 文档中没有提到为设备上下文句柄传递 0 作为可接受的值,您可能需要为屏幕传递 HDC。很容易从 Control.CreateGraphics() 获得。

我也不清楚为什么您不希望出现水平滚动条。我希望您在切换到打印机所见即所得模式时会看到一个。

关于c# - RichTextBox:如何确定文本是否超出控件边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1896618/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com