简体   繁体   English

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

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

I was hoping for some help with regards to a transparent TMemo control in Delphi 7. I found some code online that works well, to an extent, the refresh rate is a bit rubbish but I can live with that. 我希望在Delphi 7中获得有关透明TMemo控件的帮助。我在网上找到了一些行之有效的代码,在一定程度上刷新率有点令人讨厌,但我可以接受。 The main problem is that unselected text can look as if it's actually selected. 主要问题是未选择的文本看起来就像是实际被选择的一样。

Here's where all the text is selected using SelectAll(); 这是使用SelectAll()选择所有文本的地方; 这是使用SelectAll()选择所有文本的地方;

Here's where no text is actually selected, but has been previously, note the floating line suggesting typing will happen after the 'p' in Improvement. 在这里,实际上没有选择任何文本,但是以前已经选择过该文本,请注意,浮行提示键入将在“改进”中的“ p”之后进行。 在这里,实际上没有选择任何文本,但是以前已经选择过该文本,请注意,浮行提示键入将在“改进”中的“ p”之后进行。

And finally an image just showing the difference. 最后是一张图片,显示了差异。 最后是一张图片,显示了差异。

What I find quite odd is that if I hit an arrow key for example, the false highlighting disappears, but when using the mouse it does not. 我觉得很奇怪的是,例如,当我按下箭头键时,错误的突出显示消失了,但是当使用鼠标时却没有。

The code for this custom TMemo is as follows: 此自定义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.

Any tips/hints/answers would be greatly appreciated! 任何提示/提示/答案将不胜感激! Cheers in advance! 提前加油!

This isn't a complete fix, but you could, for example, do something like 这不是一个完整的修复程序,但是您可以例如执行以下操作

protected
  procedure Click; override;

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

And so on. 等等。 Perhaps there's a better place to do this. 也许有更好的地方可以做到这一点。 Have a look in your VCL source (StdCtrls.pas) and you might find something in TCustomEdit or TCustomMemo which would be better options to override. 在您的VCL源(StdCtrls.pas)一看,你会发现在一些TCustomEditTCustomMemo这将是更好的选择覆盖。

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

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