I found this to be an interesting discovery. I always somewhat expected each .NET language to work in a similar way with regards to things such as field initialization, but as it turns out, C# and VB.NET work differently in this regard, and in both cases it is due to design decisions with the language themselves. To best show this, I created two equivalent class heirarchies in C# and VB.NET
Shared BaseStatic As Integer = 50
Private BaseInstance As Integer = 500
Public Overridable Sub TestSub()
Public Sub New(pInt As Integer)
Me.BaseInstance = pInt
Public Sub New()
Me.BaseInstance = 20
Shared DerivedStatic As Integer = 60
Private DerivedInstance As Integer = 600
Public Sub New(pInt As Integer)
DerivedInstance = 60
Public Overrides Sub TestSub()
Dim dc As DerivedClass = New DerivedClass(50)
private int BaseProperty = 50;
public static int BaseStatic = 500;
public virtual void testmethod()
public BaseClassTest(int propertysetting)
BaseProperty = propertysetting;
class DerivedClassTest :BaseClassTest
private int DerivedProperty = 100;
public static int DerivedStatic = 100;
public override void testmethod()
public DerivedClassTest(int setting) :base(setting)
DerivedProperty = setting;
static void Main(string args)
DerivedClassTest testinit = new DerivedClassTest(45);
Both are effective a base class with a non-default constructor which has a static field and a instance field, and a class derived from that class which implements a similar non-default constructor and sets a derived instance which along with a static field are both initialized at their declaration, then creates an instance of the derived type.
I breakpointed all statements in the program, and traced through each one. in C# the progress was:
In VB.NET, we have the following order:
This has interesting repercussions. for VB.NET the main repercussion is that if you call a virtual (Overridable) method from the base constructor, within that virtual method the instance fields will not be initialized, whereas, with C#, they will be. On the C# side, it is likely the reason that derived instance fields cannot be initialized by calling an instance method, because the initialization of instance fields occurs before the base class static and instance fields have been initialized, so the class state within that method would be difficult to predict. Arguably, it seems that Visual Basic .NET takes a more “You probably know what you are doing” approach, whereas C# is more careful and “safety” conscious.
After I loved on to .NET and C#, I was happy to leave the sinking ship that was VB6. As I learned C#, I became more and more aware of just how shoddy and poor that ship was. I had since put it behind me- Visual Basic 6 being long forgotten before I even came aboard.
It would seem however there are still those, in 2014, insisting that it is actually still used by the majority of programmers. I find this claim difficult to believe. Since the author has no ill-intentions, here is the link to that article.
Under normal circumstances this is the kind of ‘crazy-talk’ one is best to avoid. But I feel I am in a unique position. For many of the arguments presented if you had shown me them 6 years ago, I would have resoundingly agreed. I no longer do so and find my previous stance to be ignorant. With that in mind I’ve decided to write a blog post to fully explain why I switched to C# and why I do not regret it for a second. I may cover some of the deficiencies in VB6’s design role that I thought was par for the course for development environments until I switched.
The article in question starts with a rather brief history of Visual Basic 6. Not surprising. It references the prevalence of ADA and COBOL- which are both still used today- as evidence that “newer is not always better”. On the surface this seems like a reasonable argument. However, by following the link provided we see that the ADA Compiler had a release in 2012; and Cobol has “OpenCOBOL” (Now GNU Cobol) still actively maintained and available for download. This puts a bit of a problem in terms of the comparison, in my opinion; Visual Basic 6 has not seen a software update since 2003, with Service Pack 6. (which, reminds me I still need to install SP6). Thus the comparison is false; those other languages are older, however, they are also actively maintained.
It continues by making two claims. The first is that, with increasing processor speed, compiler designers have become increasingly careless and have overestimated hardware capabilities. The second isn’t really relevant and is a literary device theorizing that the above was taken from 3-D Game Makers.
This has some issues.
First, take BCSearch. This is a Program I wrote in VB6 and haven’t bothered to rewrite yet; this is because I Don’t really use it and because it works (for the most part). The project Group- which consists of BCFile (my IMO very nice Object-based File I/O library, with support for Alternate Data Streams, no less) BCSearch, and a few other programs, amounts to- totalling the .cls,.frm and .bas files, 3,703,486 bytes. BASeBlock consists of 3,640,350 Bytes of C# Code. Pretty comparable.
The Visual Basic 6 compilers takes 3 minutes to perform a full recompile of the entire project.
Visual Studio 2013 takes 40 seconds to perform a Clean&Build of the entire Project.
This would seem to demonstrably show (it is repeatable, both BCSearch and BASeBlocks are available on my github account) that the assertion that Compilers are effectively less efficient and slower to be false.
The next Paragraph has a header of “Why is VB6 still successful ?!”. This I think makes yet another false assertion; that being that VB6 is successful. This is perhaps difficult to properly define- since what exactly “success” means is difficult to come up with. After all, VB6 as it is cannot still be “successful” since it is no longer sold; so I would imagine this means that it is still used; which is what I base my objection on. It is hardly common to find a VB6 developer, and even harder to find programs written in VB6.
It’s next statement is that “VB6 get’s along well with embedded machine code and [Embedded] Assembly Language” This is actually not entirely accurate. The method used to run arbitrary Machine code is hardly “friendly”; the process involves creating a String that contains the binary machine code that you want to execute. In order to execute that code, you use the CallWindowProc() API function, but instead of passing a window procedure, you pass in a pointer to that string. Control will pass to the string and it will execute as machine code. The statement that this “get’s along” with VB6 is not the case; as this is rife with problems that can cause the IDE to crash or simply close itself. Mistakes within that compiled assembly cannot be debugged in place by any means, mistakes and bugs will take your entire application down with them. The article then discusses “advanced VB6 programmers”; what it fails to mention is that all of the advanced programmers that provided the wealth of capability to Visual Basic 6 (vbAccelerator, Edanmo, etc) have all moved on to C# and/or VB.NET. It would seem then that logically if those ‘advanced VB6 programmers’ moved on, moving on was in fact the wiser choice? They have left behind a lot of very useful VB6 oriented articles, type libraries, and controls, which we can still leverage, but it seems a curious omission to not mention how they are no longer active with VB6. It then says “Nowadays, through a simple copy and paste of the myriad of functions created by advanced programmers for VB6, an intermediate level programmer can create VB6 applications that run faster than those designed in C++ (no joke there).” They provide no examples or testable, repeatable observations; therefore this is yet another assertion. That isn’t to say that VB6 code cannot be faster than C++ code, but it has the flaw that it promotes cowboy coding (Just copy and paste this code of which you know very little about into your project) as well as working with a premise that a faster piece of software is always superior to a slower one, which is false.
It continues, and suggests that Microsoft should “perhaps listen to the hundreds of thousands of programmers who demand the introduction of VB6 to the market”; I assume, this means, the re introduction to the market, nearly a decade after it had been shelved. It cites the VB6 petition. This is present [url=http://classicvb.org/petition/]here[/url]. It’s notable, that this petition has been online for nearly a decade; to assert that all of the signatories still agree with the premise of the petition is false- I base this on a simple fact that I am a signatory! That is, my name is on the petition. I signed that petition 12 years ago; as did a large number of the other people listed. I obviously can only speak for myself, but if I was able to do so I would remove my name from the Petition, since I no longer feel the same way. It’s possibly many of the others on the petition also have completely forgotten about the petition and simply moved on. Thus the assertion that all the signatories still desire the petitioned results is disingenuous.
It then cites a few available VB6 projects; the display of these projects is something I find curious; the work and effort and the end result of these projects does not mean VB6 is viable, it simply means the developers are capable. After all, if an artist makes an extraordinary work of art out of a dog turd, people praise the artist, not the turd.
Let’s take a look at some of the examples.
This project appears interesting, However it sadly also steals most of it’s code. Some with attribution, some without. All taken from “Planet-sourcecode”. It was submitted recently, but the project file dates are last edited in 2006; that makes me suspicious that the person submitting it is the real author.
It features many issues that stem from it being in VB6. I was able to crash it by simply shrinking the form (division by zero). The Menu is emulated with PictureBox’s and not responding to any accelerator keys properly being one. These issues are not present in… say… Linqpad, which is written in .NET and runs .NET language code. To me this certainly feels like a project originally created by a high-schooler- the reason I think this is because I used to be one and I know I used to think those sorts of things were actually viable when they weren’t.
The article claims this is “as powerful as Photoshop is”. This is simply not true; and the author of the program makes no such claim. It is only getting layer support now, in the development builds. It’s definitely a very interesting project, but the claims made in the article are simply false, and do it a disservice.
Back in the day, I had a VB Module called “GRAPHICS.BAS”. This was a module I created with one of my early applications for drawing a Gradient. I don’t remember what the gradient was for- I suspect it was a stupid feature that just drew a background for no good reason. the function was called Paintfrm and I put a lot of work into it. It had loads of functions and I had much the same perspective expressed here. At any rate- all of the functions described do in fact have implementations in any number of other languages, and stating otherwise is rather foolish.
This is pretty much the same program as described earlier, but in a earlier variant. It’s posted by the same person on Planet Source Code.
Without a link I cannot really verify this. I guess it’s a program to open a certain file type.
It goes on to cite statistics about Visual Basic usage. the statistics are based on Search engine search results of certain queries. That is not a way to determine the popularity, capability, or even permeance of a Programming Language. remember that those search results will include websites that were indexed years ago; those webmasters could have moved on already. And certainly the argument that there is more code for a given language does not show that the language is better anyway.
VB programmers do not particularly like VB. NET and don’t like any other versions of VB after VB6. Why? VB6 is dependent on a single file, namely: msvbvm60.dll. On the other hand, VB .NET is dependent on the .NET Framework environment, which inhibits the individualism of the programmer and this is not consistent with the human nature.
This is my favourite portion of the article. I used to be a VB6 programmer, and I would have said the same thing. I would have been wrong; Visual Basic 6 applications typically have far more dependencies, including various Common Controls and libraries, depending on the Application. I was a big fan of vbAccelerator components, for example; when using COM components they need to be registered on the machine or else your application fails without a specific error (ActiveX Component cannot create object) and you have to find out what component was not registered. Quite painful. Most systems will have the .NET framework installed; arguing that you need it installed to run an application is pretty dumb, particularly since it doesn’t “inhibit the individualism of the programmer”, which is a extraordinarily silly claim.
Now, with that out of the way, let me be blunt about this.
C# and VB.NET are better languages than Visual Basic 6 in absolutely every single possible way. There is not a single thing that, while working in C#, I think “golly, I wish I could still do that” about VB6 features. Not a single one. I do not miss ANYTHING about that terrible, underachieving IDE and it’s accompanying language. And when I was using it, the only thing driving my dislike of .NET was misunderstanding and a fear of that which I didn’t understand. I slagged .NET and C# in order to bolster myself- I didn’t know C#… “but bah that didn’t matter right because C# is .NET and .NET sucks.” And I continued blithely along in my ignorance, working in VB6.
I can think of many specific situations where VB6’s language falls short. It does not allow for Enumerator Methods, you cannot use threads, and it’s standard library (VBRUN) is dismal. C# and VB.NET with the .NET framework provide a veritable wealth of classes that you can use for any number of purposes; to get many of those same capabilities with VB6 you have to fight against the IDE, the language, or the compiler. It’s simply not economical.
The following consists of my opinion and does not constitute the passing on of an official statement from Microsoft. All thoughts and logic is purely my own and I do not have any more ‘insider’ information in this particular topic than anybody else
I’ve been hearing from the community a bit of noise about Microsoft’s XNA Framework- a Programming library and suite of applications designed to ease the creation of Games- being cut. A google reveals a lot of information, but a lot of it is just plain old rumours. The only one I could find that was based on actual information still makes a lot of assumptions. It is based on this E-mail:
Our goal is to provide you the best experience during your award year and when engaging with our product groups. The purpose of the communication is to share information regarding the retirement of XNA/DirectX as a Technical Expertise.
The XNA/DirectX expertise was created to recognize community leaders who focused on XNA Game Studio and/or DirectX development. Presently the XNA Game Studio is not in active development and DirectX is no longer evolving as a technology. Given the status within each technology, further value and engagement cannot be offered to the MVP community. As a result, effective April 1, 2014 XNA/DirectX will be fully retired from the MVP Award Program.
Because we continue to value the high level of technical contributions you continue to make to your technical community, we want to work with you to try to find a more alternate expertise area. You may remain in this award expertise until your award end date or request to change your expertise to the most appropriate alternative providing current contributions match to the desired expertise criteria. Please let me know what other products or technologies you feel your contributions align to and I will review those contributions for consideration in that new expertise area prior to the XNA/DirectX retirement date.
Please note: If an expertise change is made prior to your award end date, review for renewal of the MVP Award will be based on contributions in your new expertise.
Please contact me if you have any questions regarding this change.
This is an E-Mail that was sent out- presumably- to XNA/DirectX MVPs. I say presumably because for all we know it was made up to create a news story. If it was sent out, I never received it, so I assume it would have been sent to those that received an MVP Award with that expertise. It might have been posted to an XNA newsgroup as well. Anyway, the article that had this E-mail emblazoned as “proof” that MS was abandoning XNA seemed to miss the ever-important point that it actually says nothing about XNA itself, but actually refers to the dropping of XNA/DirectX as a technical Expertise. What this means is that there will no longer be Awards given for XNA/DirectX development. It says nothing beyond that. Now, it could mean they plan to phase it out entirely- but to come to that conclusion based on this is a bit premature, because most such expertise-drops actually involved a merge. For example, in many ways, an XNA/DirectX expertise is a bit redundant, since XNA/DirectX works using a .NET Language such as VB.NET and C# and very few XNA/DirectX MVPs truly can work with XNA in any language at all, it might make sense to just clump them with us lowly Visual C# and Visual Basic MVPs.
To make the assumption that XNA is being dropped based on this E-mail is a bit premature. In my opinion, I think the choice was made for several reasons. I guess some of the misconceptions might be the result of misconceptions about just what a Microsoft MVP is. First, as I mentioned before, a lot of the expertise of XNA/DirectX involves an understanding- and expertise- in some other area. Again, Visual C#, Visual Basic, Visual C++, etc. So in some ways they might have considered a separate XNA/DirectX expertise redundant. Another reason might have to do with the purpose of an MVP. MVP Awards are given to recognize those who make exceptional community contributions in the communities that form around their expertise. For example, my own blog typically centers around C#, solving problems with C# and Visual Studio, and presents those code solutions and analyses to the greater community by way of the internet, as well as sharing my knowledge of C# and .NET in those forums in which I participate. MVP awardees don’t generally receive much extra inside information- and that they do get is typically covered by a NDA agreement. The purpose of the award is to also establish good community members with which Microsoft can provide information to the community. MVPs are encouraged to attend numerous events where they can, quite literally, talk directly to the developers of the Products with which they acquainted. in some way you could consider MVPs “representatives” of the community, who are chosen because their contributions mean they likely have a good understanding of any prevalent problems with the technologies in question, and interacting with MVPs can give the product teams insight into the community for which their product is created. Back to the particulars here, however- as the E-mail states, XNA Game Studio is not under active development. Now, following that, it seems reasonable to work with the assumption that either that product has no Product Team, or those that are on that Product Team are currently occupied in other endeavours, or other products for which their specific talents are required.
It’s not so much that they are “pulling the plug in XNA”- the product is currently in stasis. As a direct result of this, it makes sense that without an active Product Team, having specific MVP Awardees for that expertise isn’t particularly useful for either side- MVPs gain from personal interactions with the appropriate Microsoft Product team as well as fellow MVPs, and Microsoft gains from the aggregate “pulse of the community” that those MVPs can provide. Without a Product Team for a expertise, that expertise is redundant, because there is nobody to get direct feedback. This doesn’t mean the XNA community is going away, just that, for the Moment, there is no reason for Microsoft to watch it’s pulse, because the product is “in stasis” as the OS and other concerns surrounding the technology metamorphize and stabilize (The Windows 8 UI style, Windows Store, and other concerns in particular). Once the details and current problems with those technologies are sussed out, I feel they will most certainly look back and see how they can bring the wealth of game software written in XNA to the new platform. Even if that doesn’t happen, XNA is still heavily used for XBox development- which is also it’s own expertise.
I hope this helps clear up some of the confusion that has been surrounding XNA. It doesn’t exactly eliminate uncertainty- this could, in fact, be a precursor to cutting the technology altogether. But there is nothing to point to that being the direction, either.
One common problem that comes up in the creation of stylized windows such as Splash screens is the desire to have parts of the form be “shadowed” or, in other words, blend with the forms behind them. You can see this effect in action with other application splash screens, such as photoshop:
What witchcraft is this? How does Photoshop do it? One of the first things you might try with .NET is something like the TransparencyKey of the form. Of course, this doesn’t work, instead you get this unsightly ring of the transparency key around it.
The solution, of course, is a bit more complicated.
Starting with Windows 2000, the Win32 API and Window Manager has supported the idea of “layered” Windows. Before this, Windows had concepts known as “regions”; this basically allowed you to define regions of your window where the background would show through. This didn’t allow for per-pixel blending, but that sort of thing was not widely supported (or even conceived of, really) by most graphics Adapters. The “Layered” Windowing API basically provided a way to allow Per-pixel Alpha. Which is what we want.
Windows Forms, however, does not expose this layered window API through it’s methods or properties, with the exception of the opacity property. I don’t recall if WPF does either, but I would be surprised if it’s capabilities exposed more of the Layered Windowing API. Basically- we’re on our own
So what exactly do we need to do? Well, one thing we need to do is override the CreateParams property of the desired form, so that it adds the WS_EX_LAYERED style to the window, letting the Windowing Manager know it has to do more work with this window. Since we would like a neatly decoupled implementation, we are going to create a class that derives from Form, but use that as the base class for another form. This let’s us override the CreateParams property within that base class, but this has a bit of a caveat as well, since I’ve found that makes the Designer a bit annoyed and it complains and won’t let you use the designer. So you will have to deal with that particular point yourself. (I imagine there is a way to make it work, but I don’t want to bloat the class with such functionality). If necessary, the appropriate functions and the CreateParams override can be put into the classes that need this functionality instead.
Here is the PerPixelAlphaForm class. By the way, I’m going with Visual Basic.NET because there are already a million hits for this functionality with C#:
' class that exposes needed windows GDI Functions.
Public Class Win32
Public Enum Bool
bFalse = 0
bTrue = 1
Public Structure Point
Public x As Int32
Public y As Int32
Public Sub New(x As Int32, y As Int32)
Me.x = x
Me.y = y
Public Structure Size
Public cx As Int32
Public cy As Int32
Public Sub New(cx As Int32, cy As Int32)
Me.cx = cx
Me.cy = cy
Public Blue As Byte
Public Green As Byte
Public Red As Byte
Public Alpha As Byte
Public Structure BLENDFUNCTION
Public BlendOp As Byte
Public BlendFlags As Byte
Public SourceConstantAlpha As Byte
Public AlphaFormat As Byte
Public Const ULW_COLORKEY As Int32 = &H1
Public Const ULW_ALPHA As Int32 = &H2
Public Const ULW_OPAQUE As Int32 = &H4
Public Const AC_SRC_OVER As Byte = &H0
Public Const AC_SRC_ALPHA As Byte = &H1
<DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True)>
Public Shared Function UpdateLayeredWindow(hwnd As IntPtr, hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, hdcSrc As IntPtr, ByRef pprSrc As Point, crKey As Int32, ByRef pblend As BLENDFUNCTION, dwFlags As Int32) As Bool
<DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True)>
Public Shared Function GetDC(hWnd As IntPtr) As IntPtr
Public Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer
<DllImport("gdi32.dll", ExactSpelling:=True, SetLastError:=True)>
Public Shared Function CreateCompatibleDC(hDC As IntPtr) As IntPtr
<DllImport("gdi32.dll", ExactSpelling:=True, SetLastError:=True)>
Public Shared Function DeleteDC(hdc As IntPtr) As Bool
Public Shared Function SelectObject(hDC As IntPtr, hObject As IntPtr) As IntPtr
<DllImport("gdi32.dll", ExactSpelling:=True, SetLastError:=True)>
Public Shared Function DeleteObject(hObject As IntPtr) As Bool
Public MustInherit Class PerPixelAlphaForm
Public Sub New()
FormBorderStyle = FormBorderStyle.None
Public Overloads Sub SetBitmap(bmp As Bitmap)
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H80000
Public Overloads Sub SetBitmap(bmp As Bitmap, Opacity As Byte)
If bmp.PixelFormat <> PixelFormat.Format32bppArgb Then
Throw New ApplicationException("The Bitmap must be a 32bpp with a Alpha Channel")
'Create Compatible DC with the screem
'Select bitmap with 32bpp with alpha into the compatible DC
Dim ScreenDC As IntPtr = Win32.GetDC(IntPtr.Zero)
Dim MemDC As IntPtr = Win32.CreateCompatibleDC(ScreenDC)
Dim hBitmap As IntPtr = IntPtr.Zero
Dim oldBitmap As IntPtr = IntPtr.Zero
hBitmap = bmp.GetHbitmap(Color.FromArgb(0))
oldBitmap = Win32.SelectObject(MemDC, hBitmap)
Dim thesize As Win32.Size = New Win32.Size(bmp.Width, bmp.Height)
Dim pointSource As Win32.Point = New Win32.Point(0, 0)
Dim topPos As Win32.Point = New Win32.Point(Left, Top)
Dim blend As Win32.BLENDFUNCTION = New Win32.BLENDFUNCTION()
blend.BlendOp = Win32.AC_SRC_OVER
blend.BlendFlags = 0
blend.SourceConstantAlpha = Opacity
blend.AlphaFormat = Win32.AC_SRC_ALPHA
Win32.UpdateLayeredWindow(Handle, ScreenDC, topPos, New Win32.Size(Size.Width, Size.Height), MemDC, pointSource, 0, blend, Win32.ULW_ALPHA)
Catch ex As Exception
If Not hBitmap = IntPtr.Zero Then
This provides the core implementation. The “Win32” class here provides the needed API declarations.
In order to use this, we need to make our form derive from it, and then use the inherited SetBitmap function:
Public Class Form1
Private useBackground As Bitmap
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
useBackground = New Bitmap("D:\pngtest.png")
(Here I just used an image on my second Hard disk that had a transparency channel, but the Bitmap constructor parameter can easily be changed.). The result:
The Project I used for this can be downloaded from here. This was created using Visual Studio Professional 2012, Update 1- other editions or earlier versions may have problems with the project or source files.