- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
需要从 TMemo 派生的组件(而不是 TSyn 组件)
我需要在 TMemo 的左侧(内部或外部)画一条线,其粗细(可选)和颜色可以控制,仅用于指示目的。它不需要具有排水沟的功能,但看起来特别像 SynMemo,如图所示。 SynMemo 的问题是它不支持像 Tahoma 这样的可变宽度字体,但 TMemo 支持。
我尝试通过将 TShape 与 TMemo 结合起来,使用 CustomContainersPack 制作一些复合组件,甚至将 TMemo 叠加在 TSynMemo 之上,但没有成功,因为拖动时的绘制使其看起来已被拆卸,而且 CCPack 对于我的 IDE 来说并不那么强大.
KMemo、JvMemo 和许多其他 Torry.net安装了组件并检查了是否有任何隐藏的支持来实现相同的目的,但没有任何效果。
对我来说,将组件分组在一起也不是解决方案,因为许多鼠标事件都与 Memo 相关联,并且对 FindVCLWindow 的调用将返回鼠标下更改的组件。此外,还需要许多组件,因此与 TPanel 分组会增加内存使用量。
最佳答案
您可以使用 WM_Paint 消息和 hack 来完成此操作,而无需创建新组件,否则创建 TMemo 的后代并应用下面相同的更改
TMemo = class(Vcl.StdCtrls.TMemo)
private
FSidecolor: TColor;
FSideColorWidth: Integer;
FAskForAttention: Boolean;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure SetSideColorWidth(const Value: Integer);
procedure SetSideColor(const Value: TColor);
procedure SetAskForAttention(const Value: Boolean);
published
property SideColor: TColor read FSideColor write SetSideColor default clRed;
property SideColorWidth: Integer read FSideColorWidth write SetSideColorWidth default 2;
property AskForAttension: Boolean read FAskForAttention write SetAskForAttention;
end;
{ TMemo }
procedure TMemo.SetAskForAttention(const Value: Boolean);
begin
FAskForAttention := Value;
Invalidate;
end;
procedure TMemo.SetSideColor(const Value: TColor);
begin
FSideColor := Value;
Invalidate;
end;
procedure TMemo.SetSideColorWidth(const Value: Integer);
begin
FSideColorWidth := Value;
Invalidate;
end;
procedure TMemo.WMPaint(var Message: TWMPaint);
var
DC: HDC;
Pen: HPen;
R,G,B: Byte;
begin
inherited;
if FAskForAttention then
begin
DC := GetWindowDC(Handle);
try
B := Byte(FSidecolor);
G := Byte(FSidecolor shr 8);
R := Byte(FSidecolor shr 16);
Pen := CreatePen(PS_SOLID, FSideColorWidth, RGB(R,G,B));
SelectObject(DC, Pen);
SetBkColor(DC, RGB(R,G,B));
Rectangle(DC, 1, 1, FSideColorWidth, Height - 1);
DeleteObject(Pen);
finally
ReleaseDC(Handle, DC);
end;
end;
end;
你可以像这样使用它
procedure TForm15.Button1Click(Sender: TObject);
begin
memo1.SideColor := ColorBox1.Selected;
memo1.SideColorWidth := 2;
memo1.AskForAttension := True;
end;
你会得到这个结果
限制:
由于这只是在侧面绘制一个简单矩形的另一种技巧,因此不要指望它在所有情况下都是完美的。我在测试时确实注意到以下几点:
注意:我看到评论中的人建议创建一个将面板和备忘录放在一起的自定义组件,如果您想尝试这个,请看看我的回答
Creating a new components by combining two controls (TEdit and TTrackBar) in Delphi VCL
基本上是相同的想法。
<小时/>编辑:
好的,我考虑了评论中提到的内容并调整了我的答案,
我还更改了获取组件 Canvas 的方式。新的实现变成这样
{ TMemo }
procedure TMemo.SetAskForAttention(const Value: Boolean);
var
FormatRect: TRect;
begin
if FAskForAttention <> Value then
begin
FAskForAttention := Value;
if not FAskForAttention then
begin
Perform(EM_SETRECT, 0, nil);
end
else
begin
FormatRect := GetClientRect;
if IsRightToLeft then
FormatRect.Right := FormatRect.Right - FSideColorWidth - 3
else
FormatRect.Left := FormatRect.Left + FSideColorWidth + 3;
Perform(EM_SETRECT, 0, FormatRect);
end;
Invalidate;
end;
end;
procedure TMemo.SetSideColor(const Value: TColor);
begin
if FSideColor <> Value then
begin
FSideColor := Value;
Invalidate;
end;
end;
procedure TMemo.SetSideColorWidth(const Value: Integer);
var
FormatRect: TRect;
begin
if FSideColorWidth <> Value then
begin
FSideColorWidth := Value;
FormatRect := GetClientRect;
if IsRightToLeft then
FormatRect.Right := FormatRect.Right - FSideColorWidth - 3
else
FormatRect.Left := FormatRect.Left + FSideColorWidth + 3;
Perform(EM_SETRECT, 0, FormatRect);
end;
end;
procedure TMemo.WMPaint(var Message: TWMPaint);
var
Canvas: TControlCanvas;
CRect: TRect;
begin
inherited;
if FAskForAttention then
begin
Canvas := TControlCanvas.Create;
try
Canvas.Control := Self;
Canvas.Font.Assign(Self.Font);
CRect := GetClientRect;
if IsRightToLeft then
CRect.Left := CRect.Right - FSideColorWidth
else
CRect.Width := FSideColorWidth;
Canvas.Brush.Color := FSidecolor;
Canvas.Brush.Style := bsSolid;
Canvas.FillRect(CRect);
finally
Canvas.Free;
end;
end;
end;
大小没有限制,并且不会与滚动条重叠。
最终结果:
我用来写这个答案的引用文献:
关于delphi - 如何在 TMemo 的左侧绘制一条看起来像排水沟的彩色线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55899526/
我有一个从 TMemo 派生的组件。你知道我应该拦截什么 Windows 消息以对文本光标位置的变化使用react吗?我的意思是文本光标,通过按箭头键或单击鼠标左键来改变位置。我在 Delphi 7
有什么方法可以为Memo或RichEdit分配更多的内存(如果使用大文件) 谢谢 最佳答案 用LocalAlloc分配内存,然后使用em_SetHandle消息将其分配给编辑控件。如果编辑控件需要更多
有没有办法让TMemo将长度超过1024的文本显示为1行? 看一下这个简单的代码: procedure TForm1.Button2Click(Sender: TObject); var s:
我有一个巨大的字符串要添加到 Delphi7 中的备忘录中。该字符串大约有 1MB 大,并且有许多 (Unicode) 字符。我的显卡不是最好的(Intel GMA 500)。我添加文本: Memo1
我有一个 Delphi XE2 项目,有 2 个按钮(Button1、Button2)和 1 个备忘录(Memo1)。 我的要求是,在 Button1 上单击一些文本将被写入到第一行(Line1)中的
我有一个 VCL TMemo控件,每次滚动文本时都需要通知。没有OnScroll事件并且滚动消息似乎没有传播到父表单。 知道如何获得通知吗? 作为最后的手段,我可以放置一个外部 TScrollBa
是否可以制作TMemo显示部分可见的线条?我正在寻找一种本地方式来做到这一点,而无需自定义渲染。 我为不熟悉此问题的人制作了示例屏幕截图: 如您所见,在我用红色标记的区域中,有足够的空间来显示默认情况
我有一个 TMemo,我希望它总是足够高以显示它包含的行数。不幸的是,我不太清楚如何计算。我不能以 .Font.Size 为基础属性,因为这会因 DPI 而异。而且我不能使用TCanvas.TextH
我的 Delphi 应用程序中有一个 TMemo 组件。 我如何将组件中的文本水平居中,以便一切都在中间? 最佳答案 只需将备忘录的 Alignment 属性设置为 taCenter。 关于delph
复制和粘贴文本很容易,因为它内置于 TMemo 中,但它似乎只能处理文本。不过在我看来,任何类型的数据都可以表示为字符串。如果我从另一个程序复制一些任意数据并想将其粘贴到 TMemo 中,我如何让 D
处理 Firemonkeys 上的鼠标/拖放事件 TMemo 组件提供鼠标光标坐标。有没有办法根据鼠标坐标计算 CaretPosition? 我想将文本拖动到 TMemo 中,并且该文本应插入到当前的
我在表单上有一个 TMemo,它允许用户输入项目列表。人们可以在这里输入许多项目。当他们单击“保存”时,TMemo 的内容将被选中,然后添加到数据库中。 我在 TStringList 中有第二个列表,
我有一个 TMemo,其中包含相当多的文本,80M(大约 400K 行)。 TMemo 设置为 WordWrap = FALSE,不需要查找换行为 2 行的文本。 我需要一种快速的方法来从头开始查找文
需要从 TMemo 派生的组件(而不是 TSyn 组件) 我需要在 TMemo 的左侧(内部或外部)画一条线,其粗细(可选)和颜色可以控制,仅用于指示目的。它不需要具有排水沟的功能,但看起来特别像 S
有没有办法在禁用的 TMemo 组件中启用滚动条? 即使控件的 Enabled 属性设置为 False,我也想让用户滚动内容。我知道只读和颜色更改(如禁用状态)的可能解决方法,但这对我有很大帮助。 提
我的 TMemo 后代有构造函数 constructor TMyMemo.Create(AOwner: TComponent); begin inherited Create(AOwner);
我正在尝试用 TMemo 制作一个基本的十六进制查看器,我知道这可能并不理想,但只有我个人使用它,所以这并不重要。 (1) 首先,假设备忘录中充满了十六进制信息,如下所示: 如何获得显示的所有文本 b
我正在使用 TMemo 保存从串行端口接收到的字符以供查看。当他们到达时我正在做: Memo1.Text := Memo1.Text + sReceivedChars; 这工作正常,但我认为它效率相当
我的 TMemo 中有 100000 行。我想做一些类似的事情: for i:= 0 to Memo.Lines.Count-1 do Memo.Lines[i]:= SomeTrim(Memo
当您在表单设计器中编辑 TLabel 的标题时,它会为您调整 TLabel 的大小。有什么方法可以让 TMemo 在运行时执行此操作吗? 我希望能够获取一个 TMemo,为其 .lines.text
我是一名优秀的程序员,十分优秀!