繁体   English   中英

透明TMemo-文本在未选中时似乎保持选中状态

[英]Transparent TMemo - text appears to remain selected when it isn't

我希望在Delphi 7中获得有关透明TMemo控件的帮助。我在网上找到了一些行之有效的代码,在一定程度上刷新率有点令人讨厌,但我可以接受。 主要问题是未选择的文本看起来就像是实际被选择的一样。

这是使用SelectAll()选择所有文本的地方; 这是使用SelectAll()选择所有文本的地方;

在这里,实际上没有选择任何文本,但是以前已经选择过该文本,请注意,浮行提示键入将在“改进”中的“ p”之后进行。 在这里,实际上没有选择任何文本,但是以前已经选择过该文本,请注意,浮行提示键入将在“改进”中的“ p”之后进行。

最后是一张图片,显示了差异。 最后是一张图片,显示了差异。

我觉得很奇怪的是,例如,当我按下箭头键时,错误的突出显示消失了,但是当使用鼠标时却没有。

此自定义TMemo的代码如下:

unit TrMemo;

interface

uses
 Messages, Controls, StdCtrls, classes;

const TMWM__SpecialInvalidate=WM_USER+1111;

type
  TTransparentMemo = class(TMemo)
  private
   procedure SpecialInvalidate(var Message:TMessage); message TMWM__SpecialInvalidate;
   procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
   procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
   procedure WMSetText(var Message:TWMSetText); message WM_SETTEXT;
   procedure CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT); message CN_CTLCOLOREDIT;
   procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
   procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  protected
   procedure CreateParams(var Params: TCreateParams); override;
  public
   constructor Create(AOwner: TComponent); override;
  end;

procedure Register;

implementation

uses Windows;

{ TTransparentMemo }

procedure TTransparentMemo.WMHScroll(var Message: TWMHScroll);
begin
 inherited;
 PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;

procedure TTransparentMemo.WMVScroll(var Message: TWMVScroll);
begin
 SendMessage(Handle,TMWM__SpecialInvalidate,0,0);
 inherited;
 PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;

procedure TTransparentMemo.CNCTLCOLOREDIT(var Message:TWMCTLCOLOREDIT);
begin
 with Message do
 begin
  SetBkMode(ChildDC,TRANSPARENT);
  Result:=GetStockObject(HOLLOW_BRUSH)
 end
end;

procedure TTransparentMemo.WMSetText(var Message:TWMSetText);
begin
 inherited;
 if not (csDesigning in ComponentState) then PostMessage(Handle,TMWM__SpecialInvalidate,0,0)
end;

procedure TTransparentMemo.SpecialInvalidate(var Message:TMessage);
var
 r:TRect;
begin
 if (Parent <> nil) then
 begin
  r:=ClientRect;
  r.TopLeft:=Parent.ScreenToClient(ClientToScreen(r.TopLeft));
  r.BottomRight:=Parent.ScreenToClient(ClientToScreen(r.BottomRight));
  InvalidateRect(Parent.Handle,@r,true);
  RedrawWindow(Handle,nil,0,RDW_FRAME+RDW_INVALIDATE);
 end;
end;

procedure TTransparentMemo.WMKeyDown(var Message: TWMKeyDown);
begin
 SendMessage(Handle,TMWM__SpecialInvalidate,0,0);
 inherited;
 PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
end;

procedure TTransparentMemo.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
 Message.Result:=1
end;

constructor TTransparentMemo.Create(AOwner: TComponent);
begin
 inherited;
 ControlStyle:=[csCaptureMouse, csDesignInteractive, csClickEvents,  csSetCaption, csOpaque, csDoubleClicks, csReplicatable, csNoStdEvents];
end;

procedure TTransparentMemo.CreateParams(var Params: TCreateParams);
begin
 inherited CreateParams(Params);
 with Params do
 begin
  ExStyle:=ExStyle or WS_EX_TRANSPARENT and not WS_EX_WINDOWEDGE
   and not WS_EX_STATICEDGE and not WS_EX_DLGMODALFRAME and not
   WS_EX_CLIENTEDGE;
 end;
end;

procedure Register;
begin
 RegisterComponents('Samples', [tTransparentMemo]);
end;

end.

任何提示/提示/答案将不胜感激! 提前加油!

这不是一个完整的修复程序,但是您可以例如执行以下操作

protected
  procedure Click; override;

procedure TTransparentMemo.Click;
begin
  PostMessage(Handle,TMWM__SpecialInvalidate,0,0);
  inherited;
end;

等等。 也许有更好的地方可以做到这一点。 在您的VCL源(StdCtrls.pas)一看,你会发现在一些TCustomEditTCustomMemo这将是更好的选择覆盖。

暂无
暂无

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

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