I used to use VB 6.0 and now I'm switching to .net and I'm finding lots of things have changed. Back in the day, I used to store graphics assets in pictureboxes, make them invisible, and then bitblt them to the form / screen / canvas when I needed to. This was a nice, tidy way of doing it but now I'm trying to do the same thing in VB.NET and it wont work.
If the picturebox is on screen and visible, everything works perfectly, however making the picturebox invisible or moving it offscreen messes up the graphics that bitblt draws. I can successfully load a bitmap that's stored externally, but what I wanted to know was, what is the best way to store graphics (bitmap) assets inside a VB.NET application for use with bitblt?
for reference, here is a code snippet:
#Region " Members "
Public mouseX As Integer
Public mouseY As Integer
Public srcGraphics As Graphics
Public TargetGraphics As Graphics
Public srcHdc As IntPtr
Public targetHdc As IntPtr
Public srcSize As Size
Private blnShowWheel As Boolean
#End Region
#Region " Internals "
Const SRCCOPY As Integer = &HCC0020
' Wraping things up
Private Sub MyBitBlt(ByVal SourceGraphics As Graphics, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer)
' Creating a DeviceContext to capture from
Dim SourceHDC As IntPtr = SourceGraphics.GetHdc
' Blitting (Copying) the data
BitBlt(TargetHDC, 0, 0, width, Height, SourceHDC, 0, 0, SRCCOPY)
' Releasing the Device context used
SourceGraphics.ReleaseHdc(SourceHDC)
End Sub
Private Sub MyBitBlt(ByVal SourceHDC As IntPtr, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer, ByVal PosX As Integer, ByVal PosY As Integer)
' Copying data to a specific position on the target Device Context
BitBlt(TargetHDC, PosX, PosY, width, Height, SourceHDC, 0, 0, SRCCOPY)
End Sub
' Cleanning Up
' Before Destroying this class, dispose of objects to reclaim memory
Protected Overrides Sub Finalize()
DisposeObjects()
MyBase.Finalize()
End Sub
' Disposing of objects
Private Sub DisposeObjects()
TargetGraphics.Dispose()
srcGraphics.Dispose()
End Sub
#End Region
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
Finalize()
End
End Sub
Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Finalize()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Width = 800
Me.Height = 600
Me.Left = (Screen.PrimaryScreen.Bounds.Width - Me.Width) / 2
Me.Top = (Screen.PrimaryScreen.Bounds.Height - Me.Height) / 2
srcSize = picColourWheel.Size
End Sub
Private Sub frmMain_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
srcGraphics = picColourWheel.CreateGraphics
TargetGraphics = Me.CreateGraphics
srcHdc = srcGraphics.GetHdc
targetHdc = TargetGraphics.GetHdc
If Not blnShowWheel = True Then
blnShowWheel = True
Else
blnShowWheel = False
End If
If blnShowWheel = True Then
MyBitBlt(srcHdc, targetHdc, srcSize.Width, srcSize.Height, mouseX - (srcSize.Width / 2), mouseY - (srcSize.Height / 2))
Else
Me.Refresh()
End If
srcGraphics.ReleaseHdc(srcHdc)
TargetGraphics.ReleaseHdc(targetHdc)
End Sub
Private Sub frmMain_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
mouseX = e.X
mouseY = e.Y
End Sub
In Solution Explorer, Right Click the Project --> Add --> Existing Item --> Select Image. Select newly added Image entry in Solution Explorer. Down below in the Properties Pane, change "Build Action" to "Embedded Resource". Now the image will be embedded in the application, and you can draw it like this:
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim bmp As New Bitmap(Me.GetType, "Smiley1.jpg") ' <-- Exactly as it appears in Solution Explorer (it IS cAsE-sEnSiTiVe!)
Using G As Graphics = Me.CreateGraphics
G.DrawImage(bmp, New Point(25, 25))
End Using
End Sub
End Class