Drawing in a picturebox

Co2

Freshman
Joined
May 29, 2003
Messages
34
Location
Universe 2.4.37
Hello,

I want to draw my primary surface in a picturebox but I've not been able to do so properly. I'm programming with vb.net and managed directx 9 using vs studio ent arch 2003.

Here is my code which was greatly base on a sample in the sdk:

Code:
Imports Microsoft.DirectX
Imports Microsoft.DirectX.DirectDraw

Public Class frmMain
	Inherits System.Windows.Forms.Form

	'Déclaration des membres privés
	Private components As System.ComponentModel.IContainer	'Nécessaire pour Window Form Designer

	'Déclaration des objets nécessaire pour DirectX
	Private DrawCount As Long = 0	'Contient le nombre de fois qu'on a dessiner
	Private Dev As Device = Nothing	'Device pour le dessin

	Private Front As Surface = Nothing 'Surface qui sera affichée
	Private Back As Surface = Nothing	'Surface sur laquel sera composée l'ensemble de l'affichage
	Private Blocks As Surface = Nothing	'Surface qui contient les images des bloques
	Private BlocksE As Surface = Nothing	'Surface qui contient les bloques empilés qui sont déjà en bas
	Private Background As Surface = Nothing	'Surface qui contient l'image de fond

	Private Clip As Clipper = Nothing	'Le clipper est utilisé pour indiqué la partie utilisé dans l'affichage parce que l'on partage celui-ci en mode Windowed
	Private Dest As New Rectangle		'Rectangle représentant l'endroit où l'on va dessiner


	Public Sub New()
		MyBase.New()

		'This call is required by the Windows Form Designer.
		InitializeComponent()

		'Add any initialization after the InitializeComponent() call
		Dev = New Device		 ' Create a new DrawDevice, using the default device.
		Dev.SetCooperativeLevel(picGameField, CooperativeLevelFlags.Normal)		' Set the coop level to normal windowed mode.
		CreateSurfaces()	 ' Call the function that creates the surface objects.

	End Sub
	Private Sub Draw()
		'
		' This function Draws the offscreen bitmap surface to the primary visible surface.
		'

		If ((Front Is Nothing) Or (Background Is Nothing)) Then
			' Check to make sure both surfaces exist.
			Exit Sub
		End If

		If (WindowState = FormWindowState.Minimized) Then Return
		'Height = IIf(Height < 50, 50, Height)		' Make sure the height is always valid.

		' Get the new client size to Draw to.
		Dest = New Rectangle(PointToScreen(picGameField.Location), picGameField.ClientSize)
		'Debug.WriteLine("GameField: ClientRec , ClientSize: " & picGameField.ClientRectangle.ToString & ", " & picGameField.ClientSize.ToString)
		'Debug.WriteLine("Form: ClientRec , ClientSize: " & ClientRectangle.ToString & ", " & ClientSize.ToString)
		Debug.WriteLine("Rectangle Screen[" & CStr(DrawCount) & "]: " & Dest.ToString)
		Try
			' Try and Draw the offscreen surface on to the primary surface.
			Front.Draw(Dest, Background, DrawFlags.Wait)
			DrawCount += 1
		Catch e As SurfaceLostException
			' The surface can be lost if power saving
			' mode kicks in, or any other number of
			' reasons.
			CreateSurfaces()		 ' Surface was lost. Recreate them.
		End Try
	End Sub	'Blt
	Private Sub CreateSurfaces()
		'
		' This function is where the surfaces and
		' clipper object are created.
		'
		Dim desc As New SurfaceDescription		 ' Create a new SurfaceDescription struct.
		Dim caps As New SurfaceCaps		 ' Create a new SurfaceCaps2 struct.

		caps.PrimarySurface = True		' The caps for this surface is simply primary.
		desc.SurfaceCaps = caps		' Point the SurfaceCaps member to the caps struct.
		Front = New Surface(desc, Dev)		' Create the primary surface.

		Clip = New Clipper(Dev)		' Create a new clipper.
		Clip.Window = picGameField		' The clipper will use the main window handle.
		Front.Clipper = Clip		' Assign this clipper to the primary surface.

		desc = New SurfaceDescription		 ' Create a new SurfaceDescription struct.
		Background = New Surface(Application.StartupPath + "\TetrisBack.bmp", desc, Dev)			' Create the surface using the specified file.
	End Sub
	'Form overrides dispose to clean up the component list.
	Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
		If disposing Then
			If Not (components Is Nothing) Then
				components.Dispose()
			End If
		End If
		MyBase.Dispose(disposing)
	End Sub

	'NOTE: The following procedure is required by the Windows Form Designer
	'It can be modified using the Windows Form Designer.  
	'Do not modify it using the code editor.
	Friend WithEvents picGameField As System.Windows.Forms.PictureBox
	Friend WithEvents Label1 As System.Windows.Forms.Label
	Friend WithEvents Label2 As System.Windows.Forms.Label
	<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
		Me.picGameField = New System.Windows.Forms.PictureBox
		Me.Label1 = New System.Windows.Forms.Label
		Me.Label2 = New System.Windows.Forms.Label
		Me.SuspendLayout()
		'
		'picGameField
		'
		Me.picGameField.Location = New System.Drawing.Point(80, 32)
		Me.picGameField.Name = "picGameField"
		Me.picGameField.Size = New System.Drawing.Size(200, 400)
		Me.picGameField.TabIndex = 1
		Me.picGameField.TabStop = False
		'
		'Label1
		'
		Me.Label1.Location = New System.Drawing.Point(96, 464)
		Me.Label1.Name = "Label1"
		Me.Label1.Size = New System.Drawing.Size(344, 23)
		Me.Label1.TabIndex = 2
		Me.Label1.Text = "Label1"
		'
		'Label2
		'
		Me.Label2.BackColor = System.Drawing.Color.FromArgb(CType(192, Byte), CType(255, Byte), CType(255, Byte))
		Me.Label2.Location = New System.Drawing.Point(56, 16)
		Me.Label2.Name = "Label2"
		Me.Label2.Size = New System.Drawing.Size(240, 432)
		Me.Label2.TabIndex = 3
		'
		'frmMain
		'
		Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
		Me.ClientSize = New System.Drawing.Size(520, 496)
		Me.Controls.Add(Me.Label1)
		Me.Controls.Add(Me.picGameField)
		Me.Controls.Add(Me.Label2)
		Me.Name = "frmMain"
		Me.Text = "Tetris"
		Me.ResumeLayout(False)

	End Sub

	Private Sub picGameField_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picGameField.Paint
		Draw()
	End Sub

	Private Sub frmMain_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
		'Draw()
	End Sub

	Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

	End Sub

	Private Sub frmMain_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move
		'Label1.Text = "Location - Size: " & Me.Location.ToString & " - " & Me.Size.ToString
	End Sub
End Class

The surface is drew correctly when I move my form and part of my picturebox is offscreen.

Can you help me get started with this ?

Thanks
 
It seems that the picturebox control is doing something wrong with graphics. When I try the same code using the form as the device control and the clipper window, it works flawlessly.

I'll investigate that.
 
I've switch the picturebox for a panel and it is much better. Drawing works fine now. I would suggest anyone who doesnt want to draw on the form itself to draw on a panel.

Thanks everyone (and a great thanks to me :) )
 
Back
Top