【问题标题】:EM_SETCUEBANNER doesn't work on RichTextBoxEM_SETCUEBANNER 不适用于 RichTextBox
【发布时间】:2019-12-27 01:03:23
【问题描述】:

我一直在使用EM_SETCUEBANNER 在我的TextBoxes 上实现一个占位符,它工作正常,直到我在RichTextBox 上使用它。它不显示任何文本。

这是我的代码:

 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError=true)]
 public static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);

    bool SetPlaceHolder(TextBoxBase control, string text)
            {
               const int EM_SETCUEBANNER = 0x1501;
                return Natives.SendMessage(control.Handle, EM_SETCUEBANNER, 0, text) == 1;
            }

在 RTB 上使用它会返回 false,但 Marshal.GetLastWin32Error() 的值为 0

我在Edit Control Messages 上找不到任何特定于 RTB 的内容。

我该如何解决这个问题?

【问题讨论】:

    标签: c# winforms winapi richtextbox


    【解决方案1】:

    您可以尝试自己实现:

    public class RichTextWithBanner : RichTextBox {
      private const int WM_PAINT = 0xF;
    
      protected override void OnTextChanged(EventArgs e) {
        base.OnTextChanged(e);
        this.Invalidate();
      }
    
      protected override void WndProc(ref Message m) {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT && this.Text == string.Empty) {
          using (Graphics g = Graphics.FromHwnd(m.HWnd)) {
            TextRenderer.DrawText(g, "Type Something", this.Font,
                this.ClientRectangle, Color.DarkGray, Color.Empty,
                TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      这应该不会让你太惊讶,除了the documentation,多行文本框也不支持提示。

      没有什么是你无法解决的,也不是很难做到。向您的项目添加一个新类并粘贴如下所示的代码。编译。将工具箱顶部的新控件拖放到表单上,替换现有控件。

      using System;
      using System.Drawing;
      using System.Windows.Forms;
      
      class RichTextBoxEx : RichTextBox {
          public string Cue {
              get { return cue; }
              set {
                  showCue(false);
                  cue = value;
                  if (this.Focused) showCue(true);
              }
          }
          private string cue;
      
          protected override void OnEnter(EventArgs e) {
              showCue(false);
              base.OnEnter(e);
          }
      
          protected override void OnLeave(EventArgs e) {
              showCue(true);
              base.OnLeave(e);
          }
      
          protected override void OnVisibleChanged(EventArgs e) {
              if (!this.Focused) showCue(true);
              base.OnVisibleChanged(e);
          }
      
          private void showCue(bool visible) {
              if (this.DesignMode) visible = false;
              if (visible) {                          
                  if (this.Text.Length == 0) {
                      this.Text = cue;
                      this.SelectAll();
                      this.SelectionColor = Color.FromArgb(87, 87, 87);
                  }
              }
              else {
                  if (this.Text == cue) {
                      this.Text = "";
                      this.SelectionColor = this.ForeColor;
                  }
              }
          }
      }
      

      【讨论】:

      • 不错。您能从我的answer 中获取文档链接并将其添加到您的链接(以及您可能想要的任何其他内容),以便我可以删除我的吗?你的提供了一个解决方案,而我的只是解释了问题。我很乐意添加一条注释,说明我要求您在删除之前这样做,以便有审计线索。 :-)
      • 我看不出有什么理由删除你的,只是保留它。
      • 好的。我将在这里留下我的评论一段时间,只是为了表明我至少尝试过。 :-)
      【解决方案3】:

      您无法在 RichTextBox 本身中修复它,因为您无法在多行编辑或富文本控件上设置提示横幅。

      来自EM_CUEBANNER 的文档(强调添加):

      备注

      用于开始搜索的编辑控件可能会以灰色文本显示“在此处输入搜索”作为文本提示。当用户点击文本时,文本消失,用户可以输入。

      您不能在多行编辑控件或富编辑控件上设置提示横幅。

      GetLastWin32Error() 返回 false,因为没有错误。 RichTextBox 已经通知您它没有处理消息(因为SendMessage() 返回错误),但这不是错误 - 它只是没有处理消息。 SendMessage 返回消息发送的结果;该结果的含义取决于正在发送的消息,在这种情况下,这意味着 RichTextBox 不支持它收到的消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-19
        • 1970-01-01
        • 2014-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多