如何完全从TRichEdit控件中移除选择栏?

9
TRichEdit 控件的每行左侧有一个不可见的空白区域,光标变成向右上方的箭头,并且当单击该区域时,整行都会被选择。当 TRichEdit 的文本对齐方式为居中或右对齐时,这个区域很容易看到。我相信这个区域称为选择栏

TMemo 控件中不存在这样的栏。

我的问题是:

如何删除此选择栏,以使光标行为与 TMemo 相同?

我正在使用 Delphi 7,没有 TRichEdit 属性可以控制此行为。

有一个使用 EM_SETOPTIONS 消息的 ECO_SELECTIONBAR 值,但它只添加或删除选择栏的一小部分(仅在您希望为具有左对齐的 TRichEdit 添加选择栏时才有用)。


4
+1 很好的问题,我认为你无法禁用这种行为。 - David Heffernan
3个回答

1

感谢大家的回答。

由于似乎没有“正确”的方法来解决这个问题,我想出了以下的解决方案:

unit TRichEditRemoveSelectionBar;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    procedure RichEdit1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RichEdit1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  B: Boolean = False;

implementation

{$R *.dfm}

// ------------------------------------------------------------------------- //

procedure TForm1.RichEdit1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if (GetCursor <> Screen.Cursors[crDefault]) and
     (GetCursor <> Screen.Cursors[crIBeam]) then
  begin
    SetCursor(Screen.Cursors[crIBeam]);
    B := True;
  end else
    B := False;
end;

procedure TForm1.RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if B then
  begin
    SetCursor(Screen.Cursors[crIBeam]);
    RichEdit1.SelLength := 0;
  end;
end;

procedure TForm1.RichEdit1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if B then
    SetCursor(Screen.Cursors[crIBeam]);
end;

// ------------------------------------------------------------------------- //

end.

这并不是很优雅,但它完成了工作。

请注意,此代码不允许双击选择整行,并且不能处理三次点击全文本选择。为此,您可能需要使用拦截器类。


0
尝试使用SetWindowLong()从RichEdit中删除ES_SELECTIONBAR窗口样式,例如:
dwStyle := GetWindowLong(RichEdit1.Handle, GWL_STYLE);
SetWindowLong(RichEdit1.Handle, GWL_STYLE, dwStyle and not ES_SELECTIONBAR);

或者,从TRichEdit派生一个新组件,或使用拦截器类来覆盖虚拟的CreateParams()方法以删除样式:

type
  TMyRichEdit = class(TRichEdit)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

Procedure TMyRichEdit.CreateParams(var Params: TCreateParams);
Begin
  inherited;
  Params.Style := Params.Style and not ES_SELECTIONBAR;
End;

3
ES_SELECTIONBAR 从未添加到样式中,因此删除不存在的内容不会改变任何东西。 - David Heffernan

0

目前没有记录的方法可以禁用富文本控件的此行为。没有样式、消息或函数提供任何禁用此行为的方法。

您提到的ES_SELECTIONBAR样式允许在文本左对齐时添加小间距。富文本控件的Delphi包装器不包括ES_SELECTIONBAR样式,因此您无法删除它,因为它从一开始就不存在。

对于居中和右对齐的文本,选择区域始终存在,无论ES_SELECTIONBAR样式是否存在。实际上,ES_SELECTIONBAR样式似乎对居中和右对齐文本的控件行为没有任何影响。

我认为,如果您反向工程化此选择区域的实现,您将能够通过修改富文本控件的窗口过程来删除此行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接