1

私の質問:ユーザー コントロールを無効にして背景 (または領域) を描画する方法

注:私はすでにOnPaintBackgroundをオーバーライドして空にするか、背景色を透明に設定しようとしました。

カスタム コンテナー内のカスタム ユーザー コントロールの winform ペイントをバイパスしようとしています。そのために、これを試してみようと思いました:Beginners-Starting-a-2D-Game-with-GDIplus

私のセットアップは次のとおりです。

  • 以下を含むフォーム:
    • ユーザー コントロール (DrawingBoard)
    • この DrawingBoard (リストボックス) にドラッグ アンド ドロップできる要素を含むコンテナー。

私のレンダリング ループは、前のリンクで指定されたすべての要素を含む DrawingBoard 内にあります。

public DrawingBoard()
{
    InitializeComponent();

    //Resize event are ignored
    SetStyle(ControlStyles.FixedHeight, true);
    SetStyle(ControlStyles.FixedWidth, true);
    SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);// True is better
    SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, true); // True is better
    // Disable the on built PAINT event. We dont need it with a renderloop.
    // The form will no longer refresh itself
    // we will raise the paint event ourselves from our renderloop.
    SetStyle(System.Windows.Forms.ControlStyles.UserPaint, false); // False is better
}

#region GDI+ RENDERING
public Timer t = new Timer();
//This is your BackBuffer, a Bitmap:
Bitmap B_BUFFER = null;
//This is the surface that allows you to draw on your backbuffer bitmap.
Graphics G_BUFFER = null;
//This is the surface you will use to draw your backbuffer to your display.
Graphics G_TARGET = null;
Size DisplaySize = new Size(1120, 630);
bool Antialiasing = false;

const int MS_REDRAW = 32;

public void GDIInit()
{
    B_BUFFER = new Bitmap(DisplaySize.Width, DisplaySize.Height);
    G_BUFFER = Graphics.FromImage(B_BUFFER); //drawing surface
    G_TARGET = CreateGraphics();

    // Configure the display (target) graphics for the fastest rendering.
    G_TARGET.CompositingMode    = CompositingMode.SourceCopy;
    G_TARGET.CompositingQuality = CompositingQuality.AssumeLinear;
    G_TARGET.SmoothingMode      = SmoothingMode.None;
    G_TARGET.InterpolationMode  = InterpolationMode.NearestNeighbor;
    G_TARGET.TextRenderingHint  = TextRenderingHint.SystemDefault;
    G_TARGET.PixelOffsetMode    = PixelOffsetMode.HighSpeed;

    // Configure the backbuffer's drawing surface for optimal rendering with optional
    // antialiasing for Text and Polygon Shapes            
    //Antialiasing is a boolean that tells us weather to enable antialiasing.
    //It is declared somewhere else
    if (Antialiasing)
    {
        G_BUFFER.SmoothingMode      = SmoothingMode.AntiAlias;
        G_BUFFER.TextRenderingHint  = TextRenderingHint.AntiAlias;
    }
    else
    {
        // No Text or Polygon smoothing is applied by default
        G_BUFFER.CompositingMode    = CompositingMode.SourceOver;
        G_BUFFER.CompositingQuality = CompositingQuality.HighSpeed;
        G_BUFFER.InterpolationMode  = InterpolationMode.Low;
        G_BUFFER.PixelOffsetMode    = PixelOffsetMode.Half;
    }

    t.Tick += RenderingLoop;
    t.Interval = MS_REDRAW;
    t.Start();
}
void RenderingLoop(object sender, EventArgs e)
{
    try
    {
        G_BUFFER.Clear(Color.DarkSlateGray);
        UIPaint(G_BUFFER);
        G_TARGET.DrawImageUnscaled(B_BUFFER, 0, 0);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}
#endregion

次に、私の要素がイベントを発生させ、私が望むものを描画しようとします:

public override void UIPaint(Graphics g)
{     
    Pen p = new Pen(Color.Blue,4);
    p.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;          
    g.DrawLines(p, new Point[] { new Point(Location.X, Location.Y), new Point(Location.X + Width, Location.Y), new Point(Location.X + Width, Location.Y + Height), new Point(Location.X, Location.Y + Height), new Point(Location.X, Location.Y - 2) });

    g.DrawImageUnscaled(GDATA.GetWindowImage(), Location);        
    }

これが私のDrawingBoardで起こっていることです:

画像を投稿できないので...ここにリンクがあります:http://s8.postimage.org/iqpxtaoht/Winform.jpg

  • バックグラウンドは DarkSlateGray です。これは、G_BUFFER の状態が各ティックをクリアするためです。
  • 青い四角形は私が描いたものですが、切り取られてしまいます。
  • テクスチャが切り取られ、KO
  • 私の図面をトリミングする領域は、コントロール サイズです。

そこから、WinFormを無効にしてバックグラウンドで魔法の描画を行うためにできる限りのことを試みました。Form/DrawingBoard/Elements でペイント/更新/リフレッシュ/無効化/検証したすべてのものをオーバーライドして空にしようとしましたが、コントロールの背景によってトリミングされないようにテクスチャや描画を取得することはできませんでした:(

また、要素の背景を透明に設定し、各要素 BackColor = blabla で Form.TransparencyKey = blabla を設定しようとしました。でも毎回失敗。

私は確かに何かが欠けています : / しかし、何がわかりません。

4

1 に答える 1