In the attempt to learn both vb.net and C# better I am taking a project (TreeViewAdv found on SourceForge) and trying to convert its code to VB. Though I hope to get to the point where I can convert the code manually (as this is a learning project), I am currently using a C# to VB code converter (found at www.DeveloperFusion.com) to get the ball rolling and some basic understanding first. The code I have converted is mostly problem free, but there is one problem (maybe 2). See Code:
C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace Aga.Controls
{
public static class BitmapHelper
{
[StructLayout(LayoutKind.Sequential)]
private struct PixelData
{
public byte B;
public byte G;
public byte R;
public byte A;
}
public static void SetAlphaChanelValue(Bitmap image, byte value)
{
if (image == null)
throw new ArgumentNullException("image");
if (image.PixelFormat != PixelFormat.Format32bppArgb)
throw new ArgumentException("Wrong PixelFormat");
BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
for (int i = 0; i < bitmapData.Height; i++)
{
for (int j = 0; j < bitmapData.Width; j++)
{
pPixel->A = value;
pPixel++;
}
pPixel += bitmapData.Stride - (bitmapData.Width * 4);
}
}
image.UnlockBits(bitmapData);
}
}
}
VB.Net (Post Conversion)
Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Namespace Aga.Controls
Public NotInheritable Class BitmapHelper
Private Sub New()
End Sub
<StructLayout(LayoutKind.Sequential)> _
Private Structure PixelData
Public B As Byte
Public G As Byte
Public R As Byte
Public A As Byte
End Structure
Public Shared Sub SetAlphaChanelValue(ByVal image As Bitmap, ByVal value As Byte)
If image Is Nothing Then
Throw New ArgumentNullException("image")
End If
If image.PixelFormat <> PixelFormat.Format32bppArgb Then
Throw New ArgumentException("Wrong PixelFormat")
End If
Dim bitmapData As BitmapData = image.LockBits(New Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
Dim pPixel As Pointer(Of PixelData) = DirectCast(bitmapData.Scan0, Pointer(Of PixelData))
For i As Integer = 0 To bitmapData.Height - 1
For j As Integer = 0 To bitmapData.Width - 1
pPixel.A = value
pPixel += 1
Next
pPixel += bitmapData.Stride - (bitmapData.Width * 4)
Next
image.UnlockBits(bitmapData)
End Sub
End Class
End Namespace
The lines of code in questions, I believe, are: C#
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
Which converts to this in VB
Dim pPixel As Pointer(Of PixelData) = DirectCast(bitmapData.Scan0, Pointer(Of PixelData))
Intellisense tells me that there is something wrong with Pointer(Of PixelData)
My Question: What is the best way to get the VB code above to function like the C# code (in results not methodology), and why the solution works (I wish to understand the reasoning)?
Things that should be kept in mind when answering or commenting:
1) I already understand that CRL or managed programming languages do not use pointers
2) I am not trying to find a way to use pointers or unsafe code in vb.net I know this cannot be done.
3) I am not going to ditch VB nor do I wish to simply keep the C# code in a separate assembly and reference it from VB. I understand it has limitations, but this is a LEARNING project so that when I go to a job interview and they asking me, "Can you do X in VB?" I can confidently say yes.
4) Again, what is paramount here is not which road I take but the destination. I understand that there is a shorter road to the destination through C#, but I wish to go through VB.
For bonus points, I expect the statement
pPixel += 1
to not work on the VB side (as pPixel is a structure, see above), but it builds fine on the C# side. Why does this (work/not work) in the respective languages. This is NOT a question about safe/unsafe code blocks, so much as when the code ACTUALLY RUNS and does not throw an error because of inappropriate casting/type use (int 1 --> struct pPixel), WHY?