Hi there. Recently I've been wanting to use the longly-deprecated DirectDraw, but the tutorials out there only existed for full screen. I didn't want to force myself to go with it and I knew there had to be a way, as BGB does it. So, using the fullscreen code as a reference, I decided to get dirty and try it myself. After a while of experimenting, I finally got it.

As you can see, we can have controls, things over the window DirectDraw is being used in, and even border that window. In the screenshot the surface (A 3D bordered panel) is being cleared using a random color. It's extremely fast and you can't even see the whole window one color at once. But anyway, here's the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowedDD
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref Point lpPoint);
public Device dddevice = null;
public Surface primary;
public Surface secondary;
private Rectangle drawingRectangle;
public Form1()
{
InitializeComponent();
this.Show();
}
public void Init()
{
SurfaceDescription description = new SurfaceDescription();
description.SurfaceCaps.PrimarySurface = true;
primary = new Surface(description, dddevice);
Clipper pclipper = new Clipper(dddevice);
pclipper.Window = panel1;
primary.Clipper = pclipper;
description.Clear();
description.SurfaceCaps.OffScreenPlain = true;
description.Width = this.ClientSize.Width;
description.Height = this.ClientSize.Height;
secondary = new Surface(description, dddevice);
}
private void CalculateDrawPoint()
{
drawingRectangle = new Rectangle();
Point p = new Point();
ClientToScreen(this.Handle, ref p);
drawingRectangle.X = p.X;
drawingRectangle.Y = p.Y;
drawingRectangle.Width = this.ClientSize.Width;
drawingRectangle.Height = this.ClientSize.Height;
}
private void Loop()
{
Random r = new Random(255);
CalculateDrawPoint();
do
{
if (!this.Focused)
{
Application.DoEvents();
}
else
{
secondary.ColorFill(Color.FromArgb(r.Next(255), r.Next(255), r.Next(255)));
primary.Draw(drawingRectangle, secondary, DrawFlags.Wait);
Application.DoEvents();
}
} while (this.Created);
secondary.Dispose();
primary.Dispose();
dddevice.Dispose();
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
CalculateDrawPoint();
}
private void Form1_LocationChanged(object sender, EventArgs e)
{
CalculateDrawPoint();
}
private void initializeToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
dddevice = new Device(); // Creating Device Object
dddevice.SetCooperativeLevel(this, CooperativeLevelFlags.Normal);
Init();
initializeToolStripMenuItem.Enabled = false;
Loop();
}
catch (Exception)
{
MessageBox.Show("Error initalizing DirectDraw.", "Error");
return;
}
}
}
}
Not really documented, but there's everything that's needed (besides the designer code which isn't much). If you want to initialize DirectDraw upon application just copy the
code in the Initalize menu button click after the
this.Show(); in the constructor. Also be sure you have some sort of DirectX SDK installed.
~Lin