I am nearly there with this ... :)
I have implemented my own double buffer ...
So I create a bitmap:
if (_Bitmap != null) _Bitmap.Dispose();
if (_Graphics != null) _Graphics.Dispose();
_Bitmap = new Bitmap(Bounds.Width, Bounds.Height);
_Bitmap.MakeTransparent(Color.Transparent);
_Graphics = Graphics.FromImage(_Bitmap);
_Graphics.FillRectangle(Brushes.Transparent, Bounds);
I thought that I might have to manually set the bitmap as transparent.
In my handlers OnPaint
method it does this:
protected override void OnPaint(PaintEventArgs e)
{
if (_pDevice != null)
{
try
{
_pDevice.update();
_Graphics.ReleaseHdc();
if (_bZoomWindow)
{
//_Graphics.DrawRectangle(_selectionPen, _rcRubberBand);
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddRectangle(_rcRubberBand);
gp.Widen(_selectionPen);
_Graphics.FillPath(Brushes.WhiteSmoke, gp);
}
}
OdRxDictionary Properties = _graphicsDevice.properties();
//if (helperDevice.UnderlyingDevice.Properties.Contains("WindowHDC"))
// helperDevice.UnderlyingDevice.Properties.AtPut("WindowHDC", new RxVariant((Int32)graphics.GetHdc()));
if (Properties.ContainsKey("WindowHDC"))
Properties.putAt("WindowHDC", new OdRxVariantValue(_Graphics.GetHdc().ToInt32())); // hWnd necessary for DirectX device
}
catch (System.Exception ex)
{
_Graphics.DrawString(ex.ToString(), new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(150.0F, 150.0F));
}
e.Graphics.DrawImageUnscaled(_Bitmap, 0, 0);
}
}
The problem is that the rectangle is drawing with a black background. So it is obliterating the drawing underneath that is on the bitmap:
How do I draw just the rectangle? What am I missing? I am sorry if this is a dumb question!
Painting with transparency is unfortunately only supported in one way: By applying the
RGB
channels in the strenght of thealpha
value.With
alpha = 0
nothing happens.Other modes are desirable but not supported in
GDI+
drawing.One simple workaround is to turn off antialiasing, draw in a weird color you don't need and then call
MakeTransparent
.Of course you can use all
DrawXXX
methods includingFillPath
orDrawRectangle
.The result is a green bitmap with a transparent hole in it. Here it is in Paint.Net:
For other modes, that maybe would copy the alpha channel or mix it with the previous value you would have to write routines of your own or find a lib that has it, but I think this should be all you need atm.
Edit by Andrew Truckle
The proposed answer is really good. However, since I was using Teigha.Net as the basis of the application, in the end I went with this code:
Notice that I am making use of
Region
objects. Also, the invalidating is being handled byOdGsDevice _pDevice
which is a Teigha object. In my situation this worked fabulously.