0

I want to make application that I can draw(using mouse) on top of RichTextBox. And my initial approach was to inherit RichTextBox and draw on top of it.

While it did work, it was flickering a lot. Every time RTB gets drawn, RTB itself gets rendered(which clears my image) and my drawing gets drawn. I can see unmodified RTB for a very short time, and that's what causes flickering.

After trying a lot of different things, I gave up. It was just impossible to do without flickering(while I was reduce a lot of flickering, I couldn't prevent it).

So, I've decided to do this in different way. This time, I put PictureBox on top of RichTextBox and making the PB transparent.

But after trying to make it transparent, it was still blocking text inside RTB. After googling and testing, there are some controls that use GDI for rendering, not GDI+(RTB is one of these controls), and it seems like making PB transparent doesn't work with GDI controls(I've tested with Button(with FlatStyle = FlatStyle.System;, which makes Button use GDI) as well, and result was same. With Button in GDI+(default) mode, transparency does work).

Here's code from VS designer:

// 
// rtbEditor -> RichTextBox
// 
this.rtbEditor.Dock = System.Windows.Forms.DockStyle.Fill;
this.rtbEditor.Location = new System.Drawing.Point(0, 24);
this.rtbEditor.Name = "rtbEditor";
this.rtbEditor.Size = new System.Drawing.Size(1029, 557);
this.rtbEditor.TabIndex = 16;
this.rtbEditor.Text = "";
// 
// pbOverlay -> PictureBox
// 
this.pbOverlay.Location = new System.Drawing.Point(32, 43);
this.pbOverlay.Name = "pbOverlay";
this.pbOverlay.Size = new System.Drawing.Size(894, 461);
this.pbOverlay.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pbOverlay.TabIndex = 17;
this.pbOverlay.TabStop = false;

Here's code from constructor for my form:

public MainForm()
{
    InitializeComponent();
    // I'm not sure if both below and pbOverlay.Parent are required
    rtbEditor.Controls.Add(pbOverlay);
    pbOverlay.Visible = true;
    pbOverlay.BackColor = System.Drawing.Color.Transparent;
    pbOverlay.Parent = rtbEditor;
    // I'm using D:\what.png as transparency test image.
    pbOverlay.Image = Image.FromFile("D:\\what.png");

    rtbEditor.Text = "This is a test string";
}

Is there any way to make PB transparent over RTB?

Gippeumi
  • 251
  • 2
  • 18
  • You could. But you won't be able to scroll the RTB without compromising the *effect*. Or write text. You could use a layered Form. That might work. What are you trying to achive with this? Is it meant to be some sort of *watermark*? Should the RTB be accessible/usable? Could you just paint the Text and Bitmaps on a canvas instead? (Btw, don't mind GDI/GDI+, it's inconsequential here. Also, not really what you described) – Jimi Aug 28 '19 at 05:35
  • @Jimi Not watermark, it's notes application that I can draw things on top of editable text. So RTB should be accessible when "drawing mode" is not active. – Gippeumi Aug 28 '19 at 06:40
  • A control must support the DrawToBitmap() method to make this kind of transparency work. Used to produce the background pixels of the overlay. Almost all controls do support it, unrelated to GDI rendering, but [not RichTextBox](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.richtextbox.drawtobitmap?view=netframework-4.8). Only other way to do it is overlay with a [borderless transparent form](https://stackoverflow.com/questions/4503210/draw-semi-transparent-overlay-image-all-over-the-windows-form-having-some-contro). – Hans Passant Aug 28 '19 at 07:21

0 Answers0