简体   繁体   English

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

[英]How to completely remove the selection bar from a TRichEdit control?

On the left side of every line in a TRichEdit control there's an invisible space where the cursor changes to a right-up arrow and when you click there the entire line is selected. TRichEdit控件的每一行的左侧,有一个不可见的空间,光标变为右上箭头,当您单击那里时,整个行被选中。 It's easy to see it when the TRichEdit's text alignment is Center or Right. 当TRichEdit的文本对齐方式为中心或右侧时,很容易看到它。 I believe this space is called a selection bar . 我相信这个空间被称为选择栏

Such a bar doesn't exist in the TMemo control. TMemo控件中不存在这样的条。

My question: 我的问题:

How to remove this selection bar, so that the cursor behaviour would be the same as in TMemo ? 如何删除此选择栏,以便光标行为与TMemo的相同?

I'm using Delphi 7 and there are no TRichEdit properties to control this behaviour. 我正在使用Delphi 7,并且没有TRichEdit属性来控制此行为。

There's an ECO_SELECTIONBAR value you can use with the EM_SETOPTIONS message, but it only adds or removes a small portion of the selection bar (only useful when you want to add a selection bar to a TRichEdit that has a Left Alignment). 您可以在EM_SETOPTIONS消息中使用ECO_SELECTIONBAR值,但它只添加或删除选择栏的一小部分(仅当您要将选择栏添加到具有左对齐的TRichEdit时才有用)。

Thanks everyone for your answers. 谢谢大家的回答。

As there seems to be no "proper" way to do this, I devised the following solution: 由于似乎没有“正确”的方法来做到这一点,我设计了以下解决方案:

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.

It's not elegant at all, but it gets the job done. 它根本不优雅,但它完成了工作。

Note that this code doesn't allow for a double-click full row selection and it doesn't handle triple-click full text selection. 请注意,此代码不允许双击完整行选择,并且它不处理三击全文选择。 For that you'll probably have to use an interceptor class for example. 为此,您可能必须使用拦截器类。

Try using SetWindowLong() to remove the ES_SELECTIONBAR window style from the RichEdit, eg: 尝试使用SetWindowLong()从RichEdit中删除ES_SELECTIONBAR窗口样式,例如:

dwStyle := GetWindowLong(RichEdit1.Handle, GWL_STYLE);
SetWindowLong(RichEdit1.Handle, GWL_STYLE, dwStyle and not ES_SELECTIONBAR);

Alternatively, derive a new component from TRichEdit , or use an interceptor class, to override the virtual CreateParams() method to remove the style: 或者,从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;

There is not documented way to disable this behaviour for the rich edit control. 没有记录的方法可以为富编辑控件禁用此行为。 There are not styles, messages or functions that offer any way to disable this behaviour. 没有样式,消息或函数可以提供任何方法来禁用此行为。

The ES_SELECTIONBAR style that you have mentioned allows a small margin to be added when the text is left aligned. 您提到的ES_SELECTIONBAR样式允许在文本左对齐时添加小边距。 The Delphi wrapper to the rich edit control does not include the ES_SELECTIONBAR style so it's not as if you can remove it since it's never there in the first place. 富编辑控件的Delphi包装器不包含ES_SELECTIONBAR样式,因此它不像你可以删除它,因为它从来没有在那里。

For centred and right aligned text, the selection area is always present, irrespective of the presence or otherwise of the ES_SELECTIONBAR style. 对于居中和右对齐的文本,无论是否存在ES_SELECTIONBAR样式,选择区域始终存在。 In fact the ES_SELECTIONBAR style appears to make no difference at all to the control's behaviour for centred and right aligned text. 事实上, ES_SELECTIONBAR样式似乎对控件的居中和右对齐文本的行为没有任何影响。

I expect that if you reverse engineered the implementation of this selection zone, you'd be able to remove the behaviour by modifying the rich edit control's window procedure. 我希望如果您反向设计此选择区域的实现,您将能够通过修改富编辑控件的窗口过程来删除该行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM