RichEdit control stop drawing text when it became a parent for other control

1.2k views Asked by At

RichEdit control stop drawing text when it became a parent for other control.

Is this a feature or a bug? Is it possible to make RichEdit to be a parent for other control?

Check out next app:

-- Form1.dfm ---

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 282
  ClientWidth = 418
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 24
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object RichEdit1: TRichEdit
    Left = 16
    Top = 72
    Width = 145
    Height = 105
    Font.Charset = RUSSIAN_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    Lines.Strings = (
      'RichEdit1')
    ParentFont = False
    TabOrder = 1
  end
end

-- Form1.dfm ---

--- Unit1.pas ---

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

type
  TForm3 = class(TForm)
    Button1: TButton;
    RichEdit1: TRichEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
  Button1.Parent := RichEdit1;
  RichEdit1.Invalidate;
end;

end.

--- Unit1.pas ---

Test under Delphi XE5 + Win 7.

I want to create RichEdit with Edit button like this

enter image description here

This is the result that I want to get - RichEdit with DropDown Editor:

enter image description here

1

There are 1 answers

2
Chris Rolliston On BEST ANSWER

Use an interposer class that handles the WM_PAINT message like so:

type
  TRichEdit = class(Vcl.ComCtrls.TRichEdit)
  protected
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  end;

procedure TRichEdit.WMPaint(var Message: TWMPaint);
begin
  DefaultHandler(Message);
end;

For reasons lost in the mists of time, TCustomRichEdit does some special handling of WM_PAINT that was only actually needed for the original version of the rich edit DLL. Moreover, this special handling breaks normal painting when another control is parented to the rich edit. As such, fixing the issue requires re-establishing standard VCL/Windows paint handling, which is what the code above does.

That said, I doubt nesting a button inside a rich edit is really what you want - the text won't wrap around it, for example.