如何从 TRichEdit 控件中完全删除选择栏?
Posted
技术标签:
【中文标题】如何从 TRichEdit 控件中完全删除选择栏?【英文标题】:How to completely remove the selection bar from a TRichEdit control? 【发布时间】:2013-06-05 11:51:24 【问题描述】:TRichEdit
控件中每一行的左侧都有一个不可见的空间,光标变为右上箭头,当您单击该处时,整行被选中。当 TRichEdit 的文本对齐是居中或右时,很容易看到它。我相信这个空间被称为选择栏。
TMemo
控件中不存在这样的栏。
我的问题:
如何移除这个选择栏,使光标行为与TMemo
中的相同?
我使用的是 Delphi 7,没有 TRichEdit
属性来控制这种行为。
有一个ECO_SELECTIONBAR
值可以与EM_SETOPTIONS
消息一起使用,但它只会添加或删除选择栏的一小部分(仅当您想将选择栏添加到TRichEdit
具有左对齐)。
【问题讨论】:
+1 好问题,我认为你没有办法禁用这种行为 【参考方案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.
它一点也不优雅,但它完成了工作。
请注意,此代码不允许双击整行选择,也不能处理三次单击全文选择。为此,您可能必须使用拦截器类。
【讨论】:
【参考方案2】:没有记录的方法可以为富编辑控件禁用此行为。没有样式、消息或函数可以提供任何方式来禁用此行为。
您提到的ES_SELECTIONBAR
样式允许在文本左对齐时添加小边距。富编辑控件的 Delphi 包装器不包含 ES_SELECTIONBAR
样式,因此您不能将其删除,因为它从一开始就不存在。
对于居中和右对齐的文本,无论ES_SELECTIONBAR
样式是否存在,选择区域始终存在。事实上,ES_SELECTIONBAR
样式似乎对控件对居中和右对齐文本的行为没有任何影响。
我希望,如果您对该选择区域的实现进行逆向工程,您将能够通过修改富编辑控件的窗口过程来移除该行为。
【讨论】:
【参考方案3】:尝试使用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;
【讨论】:
ES_SELECTIONBAR 从未添加到样式中,因此删除不存在的内容不会改变任何内容。以上是关于如何从 TRichEdit 控件中完全删除选择栏?的主要内容,如果未能解决你的问题,请参考以下文章