08 May 2015 @ 6:02 AM 

One of the things I find myself doing occasionally is looking at my old code. When you have over a decade of source code and projects that you’ve worked on, you can, perhaps ironically, learn a lot by reading your own code. When you read your old work, you really should seldom be impressed- that’s not a good thing, by any means, because it means that you have become a better developer in the meantime. It’s when you find your past self to be incredibly skilled even relative to yourself now that you may need to consider that you’ve stagnated. Following this, I thought I would write about some old code I wrote, provide it, and point out where I went wrong and where I went right.

As an example, pretty much my first program that did anything useful was a small Visual Basic 2.0 program, which allowed the selection of colours for HTM LBody tags (the old BGCOLOR, TEXT, LINK, ALINK, VLINK, etc settings), this, despite working with 16-color graphics. At some point, I became rather- obsessed- with gradients. Styles, colours, easing…. the signs of insanity were all there. Thus was the start of my first “Module” for code-sharing- “GRAPHICS.BAS”.

GRAPHICS.BAS ballooned in size as I basically just slapped all sorts of functions into it. the seed was “paintfrm” which itself became rather ridiculous. The comments make me incredibly glad that I was not regularly posting on the Internet at those times, and interestingly I see the symptoms today, where somebody who is 15,16, etc. seems to think they have it all figured out and their silly little program/routine should be heralded as creating a new era for humankind- but that is another story altogether. Just glad that my early contributions to the world wide web are difficult to associate with me personally, as they are quite embarassing.

Despite them being somewhat cringey, I kept the comments in the function intact. This is a Visual Basic routine, and it is rather long.

Just look at this. The hubris in the comment at the start. It uses a few other functions (regularPolygon, HLS, CMY) but those have the sort of implementation you would expect (dare I say, reasonable). What can we say about this function? Some obvious considerations come to mind for criticism:

It tries to do too much

14 special cases for special purpose gradients? Each of which interpret the actual parameters slightly differently? And it isn’t even an enumeration- it’s just a flat Integer value. To be fair to my former self I think I originally wrote it in VB2 which didn’t have enumerations, but nonetheless, it would have been possible to use Constants.

Variables are poorly named

I don’t even know what have of these do. what is SA? LOOPS? objgood? the XT! Array? Why do some of them declare their type with a type declaration character, while others declare their type specifically?


I mean… come on. Really? This isn’t Commodore BASIC, we can create new functions. What was I thinking

In my defense, this was before I learned about Object Oriented programming concepts and really before I learned anything about good design. Of course if you asked me back then I would have said I was a “good programmer” but I think this stuff shows that I would have been a liar to do so. Furthermore, this leaves one thinking.

I like to think I’m a capable programmer, but when I see my old code like this I always consider otherwise. It is notable that more recent programs (Like BCSearch) are really only annoying now because of the technology I used (VB6) and a few minor design decisions. If anything, they are often over-engineered.

One interesting approach is to try to be working on something where your skill level is that low. The goal being that in ten years you can look back and go “man, I barely knew how to use X, but now I consider all those trouble points trivial considerations”. It let’s you know that you’ve progressed.

Posted By: BC_Programming
Last Edit: 08 May 2015 @ 06:02 AM

EmailPermalinkComments Off on Critiquing the code of an amateur
Categories: Visual Basic, Visual Basic
 07 Apr 2014 @ 12:20 PM 

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.

Visia Compiler

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.

Advanced mathematical functions (made in VB6)

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.

Libry Compiler 4.1

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.

Posted By: BC_Programming
Last Edit: 07 Apr 2014 @ 12:20 PM

EmailPermalinkComments (3)
Tags: , ,
Categories: .NET, C#, Programming, Visual Basic
 16 May 2013 @ 1:42 AM 

With the runaway success of Visual Basic 1.0, it made sense for future versions to be released improving incrementally on the existing version. Such was how we ended up with Visual Basic 2.0. In some ways, Visual Basic 2.0 changed Visual Basic from a backwater project like Microsoft Multiplan into something that would become a development focus for years to come- like Microsoft Excel.

Visual Basic 2.0 was quite a leap forward; it improved language features, the IDE, and numerous other things. One of the biggest changes was the introduction of the “Variant” Data type. A full list of new features, from the Visual Basic 2.0 Programmers Guide, with annotations on each by me.

  • Improved Form design tools, including a toolbar and a Properties Window

    Visual Basic 2.0 adds the ability to select multiple controls by dragging a box around them. It also adds a Toolbar, which replaces the area used by the Property modification controls in Visual Basic 1.0. The new Properties Window moves the Property Editing to a separate Window, which is a massive improvement since you can more easily inspect properties.

  • Multiple-Document interface Support

    Another rather big feature. MDI was and is the capability that allows a Window to have it’s own Child Windows. This has started to fall out of vogue and is all but forgotten. Earlier Office versions provided an MDI interface. The core of MDI was basically set by Program Manager itself, which was a MDI Application. Visual Basic 2.0 allows you to create MDI Forms, and MDI Applications. This is provided through a few Properties. I will cover MDI stuff that VB2.0 adds later in this Post.

  • New Properties, Events, and Methods

    Visual Basic 2.0 added several Properties, Events, and Methods to the available controls. It changes the “CtlName” of all Controls to the less stupid “Name”, and added multiple new Events, particularly surrounding Drag and Drop capabilities.

  • Object Variables and Multiple Form instances

    This is a pretty major shift. For one thing, it established Forms not as their own, distinct objects (as was the case in VB1.0) but rather as their own Class of Object. You were also capable of creating new form instances, inspect Object Types, and various other Object-Oriented capabilities. it was still relatively limited, but it was certainly a step forward and it added a wealth of capability to the language.

  • Variant Data Type

    This is another Big one. Visual Basic 1.0 had a number of Data Types, as you would expect; Integer, a 16-bit Integer value, Long, a 32-bit Integer value, Single, a 16-bit floating point value, Double, a 32-bit floating point value, Currency, a Scaled Integer value, and String. Visual Basic 2.0 shakes things up by not only adding Forms as their own ‘Data Type’ of sorts, but it also adds Variant, which is basically a Value that can represent anything.

    Variants are an interesting topic because while they originally appeared in Visual Basic 2.0, they would eventually seep into the OLE libraries. As we move through the Visual Basic versions, we will see a rather distinct change in the Language, as well as the IDE software itself to reflect the changing buttresses of the featureset. One of the additional changes to Visual Basic 2.0 was “Implicit” declaration. Variables that hadn’t been referred to previously would be automatically declared; This had good and bad points, of course- since a misspelling could suddenly become extremely difficult to track down. It also added the ability to specify “Option Explicit” at the top of Modules and Forms, which required the use of explicit declarations. Visual Basic 1.0 also allowed for implicit declarations, but you needed to use some of the ancient BASIC incantations (DefInt, DefLng, DefSng, DefDbl, and DefCur) to set default data types for a range of characters. It was confusing and weird, to say the least.

  • Shape,Line, and Image controls

    The Shape, Line, and Image controls added to VB2 are a new feature known as “windowless” controls, in that they do not actually use a Window handle. One of the larger benefits from this was that the controls were lightweight; the second was that they could be used for simple graphics on a VB2 Form.

  • Grid Custom Control

    Visual Basic 2.0 comes with a Grid Custom Control. I swear this thing has what feels like an entire chapter devoted to it in the Programmers guide. I’m not even Joking- “Chapter 13: Using the Grid Control”. The Grid control is rather awkward to use for those more accustomed to modern programmatic approaches and better designed control interfaces.

  • Object Linking & Embedding Custom Control

    OLE (pronounced “O-Lay” I was pronouncing it as Oh-Ell-Eee for the longest time and don’t think I’ll ever live down the embarassment. The basic idea was to allow one application to be “embedded” inside another. functionality- to the user- it would simply look like inserting a document, which was part of the purpose. For example, you can insert an Excel spreadsheet inside a Word document and then edit that Excel Spreadsheet- from within Word- as if it was Excel. What happened? Well it was bloody confusing. While it was (and still is) a very powerful feature, it was far from intuitive and was something far more likely to be used by power users.

  • Added Debugging Features, including Watch variables and a Calls Window.

    It’s amazing the stuff we did without in older Programming environments, isn’t it? Visual Basic 1.0 provided very simplistic Debugging support. This was not uncommon among the IDE tools of the time. Visual Basic 2.0 added some debugging helpers and in some ways added a new “mode” to the Program; Immediate Mode. Visual Basic 1.0 had similar capabilities, in that it did have something of an “immediate” mode; particularly shown by the Immediate Window. However, Visual Basic 1.0’s implementation was far simpler, and it didn’t support Watch Variables, which is one of the primary new features added in VB 2.0. This paired with with the Toolbar controls that almost emulate “playback” of the application gave rise to the idea of Three Modes; The first, you write code and design forms. The second is where you run the application, and the third. Immediate Mode, is when you are debugging; eg. Your application is Stopped but you can inspect it’s running state.

  • ASCII representation of Forms

    As far as I’m concerned, this is the single best feature added to Visual Basic 2.0. Historically, many applications- including things like Visual Basic as well as other Language interpreters or editors, saved their source in a proprietary, binary format. This was done not so much to protect it, but for space-saving reasons. When you only have a 160K disk, a difference of a single Kilobyte can be important. Additionally, for text formats it takes longer to load and save (at least with the paltry memory and processing power of the time in comparison to today). Visual Basic 1.0 as well as it’s QuickBASIC predecessor allowed for saving files as text, but this was not the default option. Visual Basic 2.0 adds the ability to save not only source code- as the Visual Basic 1.0 Code->Save Text Option did- but also to save the Form design in a text format. this was a massively useful feature since it allowed external tools to manipulate the form design as well as the code, as well as making your software development less dependent on an undocumented format.

  • 256-Color support for bitmaps and color palettes.

    Back in those days, Colour was a trade-off. Video Adapters usually had limited Video Memory, so you usually had a trade-off between either higher resolution and fewer colours, or lower resolution and more colours. Today, this isn’t an issue at all- 32-bit and 24-bit Colour has been the standard for nearly two decades. As this was developing, however, we had the curious instance of 256-colour formats.

    256-colour modes uses a single byte to index each colour, and palette entries are stored separately. The index them becomes a lookup into that table. This had some interesting effects; Applications could swap about the colours in their palette and create animations without really doing anything; the Video Adapter would simply change mappings itself. This was a very useful feature for DOS applications and Games.

    Windows, however, complicated things. Because Windows could run and display the images from several Applications simultaneously, 256-color support was something of a tricky subject. Windows itself reserved it’s own special colours for things like the various element colours, but aside from that 8-bit colour modes depended on realized palettes. What this means is that Applications would tell windows what colours they wanted, and Windows would do what it could to accomodate them. The Foreground application naturally took precedence, and in general when an application that supported 8-bit colour got the focus, it would say “OK, cool… realize my palette now so this owl doesn’t look like somebody vomited on an Oil Painting”. With Visual Basic 1.0, this feature was not available for numerous reasons, most reasonable among them being a combination of it just not being very important paired with the fact that VB was designed primarily as a “front end” glue application for other pieces of code. Visual Basic 2.0 however adds 256-color support. This adds quite a few properties and methods that are used. VB itself manages the Palette-relevant Windows Messages, which was one of the reasons VB 1.0 couldn’t even be forced to support it.

Visual Basic 2.0 Manuals

The Three Visual Basic 2.0 Manuals in their native environment of a random Wooden Table. The “Professional Features” guide is about twice as thick as the other two. Note the use of the old cover style that was typical of MS Documentation of the time.

Visual Basic 2.0 Editing a Command Button's Click Procedure

Visual Basic 2.0 Editing a Command Button’s Click Procedure

As we can see above, Visual Basic 2.0 adds Syntax highlighting over VB1; an additional side effect of this is that the colours can also be customized. I recall I was a fan of using a green background and yellow text for comments to make them stand out, myself.

On a personal Note, Visual Basic 2.0 is dear to me (well, as dear as a software product can be), since it was the first Programming Language I learned and became competent with to the point where I realized that I might have a future with software development. Arguably, that future is now, but it hasn’t actually become sustainable (I may have to relocate). But more so than this is the fact that I was given a full, legal copy of the software. This in itself isn’t exceptional, but what is is the fact that it had all the manuals:

Dog-eared, ragged, and well-used, these books- primarily the Programmers Guide and Language Reference- became the subject of meticulous study for me.

Posted By: BC_Programming
Last Edit: 13 May 2016 @ 06:58 PM

EmailPermalinkComments (1)
 30 Sep 2010 @ 12:24 PM 

I was looking over some of my old project folders, and I found a 54-page (well, 54K text file) development log (devlog.txt) for my VB6 version of BASeParser.

despite what many people would logically assume, it doesn’t appear to contain quite as much development logging as it does general griping about my situation. It’s damn nearly a journal. (you’ll note my quite conscious decision NOT to use the term “diary”. Awful lot of references to Motocross madness, and I seem to like the spell it MotoCross. Oh well.

Because I haven’t posted in a while, I thought it would make an interesting blog post. I’ve gone through and tried to “markup” as much as possible (italicize, code boxes, etc). Everything else exists in the text file (including the “edits” that might appear to be made as I create this).

BASeParser Development Log, Started 30/Dec/2006 13:25
*I’d like to take this opportunity to mention that this development log seems to double as a upgrade log for my computer.
oh well…

Also, it is a DEVELOPMENT log, not a Changelog. I’ll peruse this text later on and make a changelog.


This is NOT my first Expression Parser/Evaluator. My first one, also named “BASeParser” was actually almost as good as
this one (albiet it took about a year to get that way). However, after a series of computer mishaps, I no longer have it’s
code. In fact, I lost the code to all 4 of my large projects during this time. I will explain this, because, looking back,
It is funny. Annoying, but funny. Ok, not funny. Freaky, maybe.

Anyway, I usually kept ALL my Visual Basic files on a small USB thumb drive. Now, I know the importance of back-ups, so I
backed up the important stuff off of this key once a week. One day, I decided to open up one of my programs, BCFile. I was
greeted, from VB, with a nice “path not found: I:\vbproj\vb\BCFile\BCfile.vbg”. I immediately thought that, as usual, the
key had for some reason assigned itself the drive letter “G” or “H” as it sometimes does. However, it appeared as I: in
windows explorer. I immediately became concerned. Looking in I:\vbproj\vb\, and- I found no BCFile directory! I knew what
to do, so, as quick as I could, I copied all the data from the key to a NEW backup folder, on my third hard drive,
E:[DAMNDISK] (the reason for the name involves another long-winded explanation about data-loss as well as a CD-RW drive
getting fried.). OK, so I had all the data I could grab. or did I? I ran Chkdsk /f (NOT scandisk) on the drive. It found
23 megs of lost clusters. I converted them to files, moved the files to E:\CHK, and re-formatted the usbkey. I then
assessed the damage I had received. A major blow. what happened was, for some reason, the FAT on the drive thought a
crapload of files where only occupying one cluster (4K) of space. thus the lost space. Now I just needed to examine all
the files on the backup. My prize program, BASeEdit XP, was completely ruined, with it’s main Class gone and the resource
file truncated, it seemed obvious that re-writing this over would be easier then fixing this one (although I did put a lot
of work into it). another, BASeMetry, suffered fairly heavy damage, with a class representing Polygons was truncated.
BCFile, well, I assume the files were there, but the directory was munged up, so I couldn’t access them.

With all this extensive damage to a random assortment of files on the disk, I got smart- I used the windows find utility
to search for all files that were EXACTLY 4K (4096 bytes) in size. The list was very long. I was very sad. Then began a
excruciatingly long process that I would not wish on my worst enemy…

So, had I lost the files? I had no file-recovery tools to speak of. But I did have the chk files. All the data that was
truncated from ALL the files was inside those CHK files. But every single CHK file was only one cluster, 4K, in size. So I used the COPY command to append all the CHK files into a big file, which I named, “BIGCHK”.(as if the name I chose is relevant here) I then opened this file in editpad. And so began a night-long struggle to recover data.

My first step in each case was to drag one of the 4K files from the search into the editpad window. Then, I would look for
something within that file that would be unique. Using that, I would search the BIGCHK file for that string. When it was
found, I would grab all the data that belonged to the file and paste it back into the truncated one, save it, close it,
and repeat. It worked better then it should have, I got several of my modules and classes back.

This was a monotonous task, but I was determined. If I was to lose my projects, I wasn’t going down without a fight. I
actually managed to recover two projects completely- BASeParser, my expression parser (Not the one for which I wrote this
devlog, as you will see) and BCFile, my File Access component. BCFile, was completely recovered, except for one of the
Type libraries it used was truncated. Until I got that type library, I could not use it.

So I managed to recover from that bout OK- all I had left that was usable from BASeEdit XP was it’s Logo (how very
helpful),as well as a few classes from it. I kept all these old, mostly corrupted files on my E:, third hard disk, becuase
I figured since it had NTFS and was freshly formatted, it should be far more reliable then my D: drive, which consistently
freezes randomly (Actually, I fixed that since then –Bad sectors–). I decided I would work only from my desktop
computer, as the USB key kept failing, and I kept having to pick up the pieces.

So I was working with E: as my code drive. Everything evened out- I accepted the loss of my code. I then decided to see if
I could fix the usbkey- it seemed to believe it had bad sectors. I decided to repartition it. I right-clicked the I: drive
in disk manager, as one would expect to do. I got the basic warning, “all data blah blah deleted blah”. The moment I had
clicked OK, I realized what would happen next. It dismounted Drive I:, as it would for any other drive- however,
dismounting the key made it disconnect as a drive. I watched the drive dissapear from the Disk management window,the
selection move up to my E: drive, and disk management began deleting it’s partition. I will not repeat the expletive I
uttered at this point. I tried to recover the data by somehow re-constructing the partition information alone. I of
course, failed miserably to do so. I re-create the partition, formatted it, and once again, found myself assessing damage.
All my code was gone, with no hope of recovery, at least, not without an expensive software package.

#1 30/Dec/2006 13:25
As a result of either a bug in the disk management program or a misclick by me, my entire E: drive got wiped out.
This means that I have only the code that was in my D:\vbproj directory. As a result, two of my prize libraries,
BASeParser and BCFile, have been lost forever.
***EDIT, 30/Dec/2009 05:35 – theeeeeey’re BACK! BASeParser and BCFile, in FULL Force. of course it’s been 3 years to the
day since I originally wrote this section,(BASeParser is still under semi-active development, but the groundwork was laid down in 9 hours as I state here)

… I did take a “sabbatical” from programming for a while there, too, in those three years.***

On the bright side, I immediately set to work writing a new BASeParser
library. After 9 hours of straight coding (with a short break for food) I have done it. I made a complete replacement for
BASeParser. This version however, is purely my code (The old one was based on a Parser by Konrad Rudolph- that is, I took
his code and made it good (ha- just kidding.)) although I based the algorithms on those found in the previous version. In
addition, I have abstracted both operator and function recognization and execution into a separate interface. This cleans
the BASeParser code up considerably, whereas in the old version the Operation and Function Resolution where both in the
Parse Stack, which made it difficult to implement custom operator and function resolution. Not to mention the ExecFunct routine
was completely irrelevant as far as the Stack itself was concerned.

In short, I think I should be proud of myself. I re-wrote an application that originally took almost a year to build. of
course, I didn’t work on it every day, but still, this much code in so short of a time, and it works. (Well, as far as I

In fact, I’m surprised I set right back to writing it, since I lost EVERYTHING. BASeEdit XP …
***EDIT, 30/Dec/2009 05:35
BASeEdit XP has a project skeleton and basic menu structure created (and I <THINK> the whole IDocument interface stuff, too)
but it’s far from a usable application, still.

…was already a write-off, but
at least I could have salvaged code from the parts that were left. Now I no longer have that luxury. So when I finally to
start that (that will be AFTER I re-create BCFile.dll), I’ll need to rewrite a lot. Thankfully, I still have the awesome
VBAccelerator Components that I downloaded, as well as a module, modCmdBarXML…
***EDIT, 30/Dec/2009 05:35
The stated module is now a Class module and is FAR better then the module was.

…that populates VBAccelerator CommandBars
From XML files/Strings, using the MS XML parser. I also lost my CommandLine Parser, but I should be able to toss that out
in no time. ***EDIT: I did during a few spare moments on my laptop :)*** I can’t seem to escape string parsing, and I have become extremely proficient with the string handling of
Visual Basic (not that I wasn’t before).

#2 31/Dec/2006 3:28 PM

OK, so the BASeParser ENGINE is pretty well completed. All that I need to do now is decide on one thing- do I
implement all the different core operators/functions in a single internal implementation of the IEvalEvents Interface, or
separate them into different modules, like PPCoreArray,PPCoreOpFunc, PPCoreEnviron, etc for (Array,Operator, and
Environment variable evaluation respectively). Now, I think that segregating it will make the files themselves harder to
manage, but tracking down bugs will be a lot easier. Besides, I get to see if this “plugin” architecture works the way I

Oh, I found a pretty old version of the original BASeParser on my Thinkpad laptop, from a time I tried to document it.
It is almost a year old, which is sort of satisfying (if it was newer I would suddenly have TWO really good evaluators).
the good thing is I can borrow the code therin that implements the CallByName function. I totally forgot how to do that.
(Read, I’m to lazy to do it AGAIN!). (EDIT:(2/Jun/2007 5:00) Actually, I didn’t want to include too many references)

3/Jan/2007 1:00 AM

Working on the BPCoreOpFunc’s class. Fixed bugs relating to multi-argument functions (namely, the parsearguments function
would return arguments after the first with the comma included). Fixed that. Now I have a new dilemma- Unary operator
support. Obviously I’m going to need to delve back into the operator parsing and execution code. I also changed all
the function return values into ByRef values from subs, so as to allow for Objects to be returned (otherwise, I’d need to
make two calls, one on an IsObject, and another to actually retrieve it)- the isobject would be used to determine if Set is necessary.

UPDATE: during the same day I THINK I got unary operators working. Don’t be too surprised if you see a new bug arise. I
don’t really want to call the way I implemented it a hack. What happens is, during the resolution of an operator, it
decides that the operator is unary if either it is the first item in the expression or the previous item was a operator.
This takes care of functions and brackets, which implement their interior as sub-parser objects, and operators working,
such as 5*-1, and 4+-5 and such. I am sure I missed something. I just thought I might have problems with an expression
like -(5) and such, but, it turns out, I don’t. What the Unary operator does is NOT move itself around on the stack, like
the other operators. Since the unary operators precedence is essentially the same as the value with which it is paired, it
stays put, so you get a stack like this, before the BuildStack_InFix Procedure runs through:
(this is for “5+-70”)


the BuildStack_Infix rearranges the operators according to their precedence. Their precedence is derived via calls
from the plugins. Higher precedence plugins will always have their operators listed first, and they will be called first,
as well. In this case, the only operator is the +, which, upon encountering, the Stack fixer pushes onto a temporary,
operator stack. after looping through the remaining elements, it pushes all the values from the operator stack back onto
the parse stack, ending up with:


This may look impossible to collapse (evaluate), because the unary operator has no idea about what it is supposed to act
on (since when the loop iteration is at the unary op it still has not reached the IT_VALUE for which it is paired)
however, due to a clever scheme, the IT_OPUNARY does not handle it right away- instead, it sets a module level variable,
which is a event sinker for the ParseStack, as well as another variable that holds the current parse item (which is the
unary operator’s CFormItem). Then, when something happens which Pushes something onto the stack (say, a function is
evaluated, a variable is pushed, a value is pushed, whatever- the DataStack raises this event, we catch it, and already
know the context of execution- and simply call the EvalListeners Unary evaluation, and return that in the ByRef DataStack
Event parameter. (Of course, being able to change the code in the DataStack enabled this event to appear. (I can change it
because it’s mine).

-after getting the basic “-” operator to work, I discovered that it wouldn’t work with the Unary NOT operator. The fix?
well, I traced the bug into the ParseValue function. the string it returned was NOT4 (my expression was NOT 4). I
concluded that for some reason the MakeParsable Function was not re-adding spaces to the NOT operator. Turns out the
entire problem was within my BCoreOpFunc class. the Constant that had all the operators ended with NOT, but there was no
space at the end, so the class was returning that it didn’t recognize the operator (it searches for ” ” & Operator & ” “),
or, ” NOT ” which it can’t find. fixed it by adding a single space to the end of the constant. lo and behold, Not 5 is -4!

Wednesday January 03, 2007

Work for today on BASeParser- implement more functions. This Parser seems much better then my previous one- the previous
one included all sorts of hacks, because I was working with what was not originally my own code. Not to mention the Sinks
for operator and function implementation where completely messy hacks. They worked great, but that didn’t change the fact
that the engine was not originally designed for it. It was like putting a Jet engine in a Volvo (No pun to the Jet
Database engine intended). I designed this one from the ground up to NOT have a single implementation detail inside the
parser- it simply knew how to parse the syntax of an expression. It would then pass on how
to execute the Stack it thus created to external classes. Of course, core stuff, like +,- and a bunch of VB functions, are
implemented internally in a Implementor that is automagically added to the CParser class upon create().

found a bug in ParseArguments. A REALLY stupid one. seems that it only looked for the VERY next “,” – so if a argument to
a function contained another function call with multiple arguments- it wouldn’t work right. I fixed it by moving a If
block that for some reason tested for an impossible condition (it was checking if Char=”(” right AFTER the case that
confirms it ISN’T a “)”. Now it seems that Array values can contain even MORE arrays.

found ANOTHER stupid bug. this time, inside RemoveExtraneousSpaces. it is supposed to add stuff to a buffer- but at one
point instead of appending I simply replaced what was there.(I smart) It also added one too many to the value being used to
pass through the string.


not really a bug fix- just a feature not working as intended. the Unary operators, upon being executed, where setting a
module level variable and a event sink. However, if two unary operators were encountered in a row, only the most recent one
would be present when the next value was pushed on the stack (thus triggering the event). I fixed this by adding each
unary operator to a module level stack. when the event occurs, the stack is emptied, with each operator on it being
executed on the value being pushed. It worked on a expression like “not -sizeof “”TEST””, which returned 3, or (NOT -4)


Geez! A lot of bugs are surfacing. This one had to do with MakeParsable and RemoveExtraneousSpaces, in Cparser.cls. the
functions were not properly handling strings and ended up placing spaces within the string literals themselves. This
occured when I first tested the GetFileDateTime function, which had problems getting the path of a file named “C: \
Autoexec.bat” (not surprisingly) I fixed it by adding the very pervasive inquote variable.(If you looked through my code,
you’d know what I mean)

NEW IDEA:- implementation in progress.
add new exposed interface- IOpFuncInfo. this can be requested via a call to the getinfoobject method of the IEvalEvents

**(EDIT:30/Jun/2007 20:59)**
**That IOpFuncInfo interface is really old now. :))

6/Jan/2007 23:56

UPDATE: finished the previously mentioned idea a few days ago. Now I have a fully functional parser. All that is left to
do now is touch it up.

***EDIT, 30/Dec/2009 05:35
“All I have to do is ….”  I keep saying this! 😛

I think the sample app will be a re-write of my old standby, Grapher. Grapher used my REALLY old
BASeParser, which didn’t support either arrays or strings. It hacked in it’s own support for lists, which was REALLY
kludgy. It ran alright, but it suffered from really bad design. Even I had trouble navigating the dialogs.

FINALLY- I removed those god forsaken GoSub references. I had no idea they were slowing my code down as much as they were!
I initially tested a really long expression, 5+5+5+…. etc for about 600 5’s, and it took almost 3 seconds to execute.
Now, it occurs in less then one one hundredth of a second.

9/Jan/2007 22:18

Just when I think I packed too many features into BASeParser, I think of another one to add! (Good thing I don’t need to
re-version it after release, given the Plugin stuff)- for example, I was reading HardCore Visual Basic, and read his
reference to Pascal’s In operator and his creation of an analogous function in VB, which lacks such a operator. Now
BASeParser has an IN operator.

10/Jan/2007 2:49

I’ve decided to implement some more direct debugging techniques. It’ll be annoying, but I’ll add a MODULE_NAME const to
every module, PROCEDURE_NAME const to every procedure, and a global var CurrModule and CurrProc, that have the current
module and procedure names. to further enhance such an effort, I will manually keep track of the Stack. Of course,
multiple exits in my procedures will make this less then easy. Here goes…

10/Jan/2007 8:08

I just thought of a better way to implement implicit multiplication. I decided before that I couldn’t do it without
severely screwing up my current Object method/property access- for example, my idea was to simply insert a new IT_OPERATOR
multiplication operand when I encounter a IT_OPENBRACKET immediately after another. (well, it wouldn’t be (( since the
parser creates child parsers for those- so it would be like this:


would have a * inserted…


I began implementing this while thinking about how it would regress- then I realized- what if the previous subexpression
ended up evaluating as a Object? Since you cannot multiply objects (unless it is a class Called CRabbit :)) they must want
this next set of parentheses to denote a parameter list to the default method of that object.

After giving up on that idea, I eventually realized that I could implement it.

The trick is to give the client the ability to choose between “Default Object Methods” and “Implicit Multiplication”.

11/Jan/2007 3:27

I was going to go to sleep about two-three hours ago. I finished a OK Console App in FreeBasic that uses my library, and
found a bug in my library. a VERY shameful bug. the IN operator was being parsed out of the SIN function, so a innocent
Would become:
S in (8 + 2)
**EDIT:30/Jun/2007 21:02- notice the single apostrophe right below? I wonder why I put that there?**
**Anyway- if a bug like this Sin() bug arose today, I would be really pissed. Mostly because I hate when the same problems resurface. I want to SQUISH the bugs, not let them multiply. Geez.**

‘which- well, is NOT what they wanted, I imagine. I surmounted this obstacle with a new interface function,
GetHandledFunctionString, which I parse and compare. If I find a function during the iterations (a function name followed
by a “(“, I plop it on the buffer (along with a “(“) and zero out the char value).

11/Jan/2007 19:19

I just realized what regression testing is for, after this two hour debug session.
quite some time ago, I added the ability to define operators that are any string.
I added the IN operator some time ago. What I forgot to test was what happens when I use the SIN function,
the function that removes and adds spaces didn’t skip function names. So I added that- when it encounters
a function name(by checking the functions defined in a new method for the interface, (getHandledFunctionString))
it will skip it. this is important, because if it is allowed to iterate through the consituent characters, it might find a
string within the function name that is also a operator (IE, the SIN function has IN, the STORE has OR, and other stuff)

That was the bug I fixed yesterday. What I forgot to include yesterday was a similiar mechanism for variables. I did it-
but it will only work if that variable has been added already- IE: IEvalEvents implementors need to
add the appropriate variables (regardless of value) to the parsers array of variables.

You know those debugging days that simply don’t go your way? Well, today was one of them for me.
of course, I did find & fix a bunch of problems. I use the word “fix” pretty warily here, because I often end up causing
all sorts of problems on the other side of my program when I kludge out some other bug.

12/Jan/2007 16:50

My next task will be a pretty neat one, I think- it will require another IEvalEvents implementor- FunctionHandler. This
will be responsible for managing the custom Cfunction objects that will exposed via the CParser class. These functions are
simple one-line expressions, with the Alphabet being used to denote the parameters. The basic idea here is actually for my
own benefit- the first program I intend to write that uses the Parser is a Graphing application. It will of course allow
you to name functions and graph them, and as such one function should be allowed to reference any other function.

13/Jan/2007 17:00

Wow. I just squashed another bug in the parser. It was somewhat odd, to be honest, and confused me a heck of a lot.
I forget the exact function location of the bug (regardless of the fact I just fixed it) but it was in one of the many
Select Case Statements that determine the type of a CFormItem. the IT_FUNCTION types were not being placed onto strBuffer
(oh wait- it was ParseValue). Also, I found that my recent change to ParseArguments didn’t allow for single,one character
arguments due to a incorrect Len test of “If Len(arguments(0)) <=1” where that 1 should be a zero, to test for empty
parentheses, which are a required part of the syntax. I tested it with a varied expression just to be sure:


This was the expression I initially found the problem with, and so was a perfect candidate to see it I fixed it. (No, I
didn’t find the error via a incorrect single value- This should have returned a single value, but (this is very strange)
it returned an array- (2,2.5,3,3.5,4,4.5) from 2 incrementing 1/2 each time. This left me bewildered, it couldn’t have
been more wrong. I might have understood if it returned the Sine of the values 1,2,3,4,5 in an array, which would have
indicated a problem with the Object Access @ operator calling Mean to reduce the array into a single value- but no, it was
a completely different value that made absolutely no sense whatsoever. I only wanted to fix the problem- perhaps I should
have looked into the cause of that mysterious Array return? Oh well. It seems to work fine now- rest assured, the next log
entry will quite possibly contain ANOTHER major bug, I’m going to do some more testing right now, and I feel quite
confident that I am not confident in the program just yet.

13/Jan/2007 17:25

Surprise. No less then ten seconds later, I found a terrible, fatal, horrible, awful, crappy problem. I want object access
operators to work- the way it DID work was it would set a flag, and then the method/function after the @ would be found as
either a function or variable. I changed a bunch of code to support other things, so now it only supports methods that
also happened to be intrinsic functions. I fixed this.

15/Jan/2007 0:56

I have made a decision as to BASeParser- No third party controls as long as I can help it. (This doesn’t count the common
controls or other components that CAME with Visual Basic- just the VBAccelerator CommandBar, which I wanted to use for pop-
up menus. (Say, a POPMENU() function or something) But, I think that if I DO add that it would be best added as a separate
as all BPXP knows is the syntax of an expression, how literals and values are separated by operators and used in functions. All of these operators and functions are contained in external “plugins”. For convenience, the Core Function and operator implementations are included in Internal plugins that are automatically loaded when the Parser Object is initialized. In addition to this supreme form of extensibility, BPXP supports what I could only think to call “Core Plugins” These Core plugins are called upon during the very Core Parsing routines, and deal with the same data structures I do within the innermost guts of the library. The purpose? To provide the ability to create new token TYPES. For example currently this is how the Core list support (using the squiggle brackets) {} is implemented.

1/Jul/2007 19:15

Sigh. The last few days I haven’t really even been able to OPEN BASeParser’s project. Not because Visual Basic is busted or anything, but because my video card was (is?) having problems. It all started when I installed MotoCross madness. Then all of a sudden all of my DirectX based games were having problems. AOE2 gets a garbled screen every 30 to 40 seconds. Sure, I can fix it with a Alt-Tab, but that is far from quick to do. Another instance with Need for Speed:High Stakes with Windows apparently detecting and recovering from a device failure, sticking me into 16 colours. Great. So I tried a few things:

Uninstalled MotoCross madness (Duh)
(no effect)
Reinstalled Video Drivers from the CD that came with it.

interesting thing is I can’t use the actual XP drivers for the card, because if I do that it get’s stuck in an infinite loop when drawing the windows desktop after about 30 to 45 minutes of working perfect. Don’t know why. Quite annoying. So (I did this when I first installed the video card too, and it worked for the last year…), was copy the Windows 2000 version of the file ati2dvag.dll over the XP version that was installed on my hard drive (of course, in safe mode).
This just made it worse. Doom Legacy (a kickass OpenGL port of Doom) worked for a while and then froze. surprise- Device failure. Hmmm. I tried various convolutions of XP and 2000 drivers (even using all Windows 2000 versions). Then I had a idea. The cause of the problem was Motocross madness (OK, I had to think back, I couldn’t remember the first instance of the problem, but I remembered it was motocross madness). But that was back in the bad old days of DirectX, when half of the worlds problems were caused by having a corrupt installation (since a crapload of programs would assume that the version they use is the newest one available). The solution was to reinstall 9.0c from my Command And Conquer DVD (thank goodness it was there!) Not sure if it works. Also not sure why I put this completely unrelated information in the develop ment log for BaseParser.

7/Jul/2007 18:01

Fixed an IPF yesterday. THe solution involved adding a err.clear to the end of a procedure. The problem was that even though no error occured err was not zero, and so the calling proc got confused and ended up using TLI to invoke the member improperly. Thus causing an IPF.

31/Jul/2007 19:30

I haven’t really managed to get a lot of coding done in the last month. The main reason is computer hardware problems. I’ve been trying to decipher the problems for a long time, and it’s getting annoying to say the least.
Although I did learn that my motherboard is high-end for it’s age. The problem? Well, first, I suddenly couldn’t play DVD’s for more than, say 20 Minutes. I attributed this to my Video card- since I installed MotoCross madness I had been having all sorts of problems with DirectX. All My OpenGL games worked fine though. Well, Mostly. Then, suddenly, Every once in a while, my third Hard drive would make some, well, Scary noises, then Drive E: would vanish without being prepared for removal, same with the DVD drive. For some reason, I attributed this entirely to the hard drive, Even though it is likely the IDE controller.
My solution? Well, I’ve found that the problems seem to occur only when I access both devices on the second channel simultaneously, so I have two possible solutions:

1: get an PCI-IDE controller card, plug the drive and DVD into it, and disable the secondary IDE controller on the motherboard. See if that fixes the problem, if not, the drive and DVD drive simply don’t like each other.

2: Buy another Hard drive, the exact same one- a WD Caviar SE (80GB). Remove the other one, and install the Data Lifeguard tools to D:. Then, to a Partition copy from my crappy C: drive (2GB- Woop!). This will become my primary Boot drive. This will solve another problem I have, since my current WD Caviar has been subverted from 80GB to 36.2GB due to limitations on my BIOS. I’d update it, but with my luck the upgrade would freeze halfway, there would be a power failure, brownout, or something to cause my BIOS to be corrupt. In addition, I’d also solve my extremely low disk space problem on C:, which, as I write this, has around 80 megabytes free.

Current        New
C: 2GB        C: 80GB
D: 8GB        D: 40GB
E:36.2GB    E: 40GB        (D and E: partitions of old E:, with drive overlay program installed)
F: DVD        F: DVD
G: CD-RW    G: CD-RW

This won’t be a simple upgrade, and the possibility of losing a crapload of data is just so great I almost HAVE to back up my Work files, since whenever I act on something like this, I always lose all my VB code (a copious amount, BTW)
I’ll update this devlog as appropriate with an entry when I do this, as well as after. First I back up all my stuff.
What worries me is the Drive Overlay program I need to use to access the drives as 80GB. I need one to be accessed with the DTD, but the other natively (IE, with 36GB) so I can copy the contents of the other one to the 80GB. The question is, will the DDO (from WD’s Data Lifeguard tools) let me do this? In fact, will the DDO even WORK?

Err… wtf is all that doing in THIS file?

20/Aug/2007 17:52

Added Oops- read “Adding” ability to address functions and specifying the plugin name. For example, BPCoreOpFunc.Sin() should be valid.

22/Aug/2007 2:24

Ha! It seems to work now. I stress seems. The problem I was having before was not that RipFormula couldn’t parse it properly, but that MakeParsable was ironically making it so RipFormula() COULDN’T parse it. too funny. Anyway, it  seems to work now. Not sure about any regressional effects.

23/Aug/2007 2:29

Ah! I finally thought of a feature worth implementing- Events fired from the Plugins, and handled via set BASeParser “Event Expressions”. For example, a keyboard watcher Plugin could install events named “KeyPush” and “KeyRelease”. subsequently a Core routine, InstallEventHandler() could install an event handler for an event.

most of the new code will deal with the new data structures involved. For example, a CEvent and CEvents Class and collection, as well as code therein. In addition to, of course, the code that runs the CEvent’s CFunction.

ROADBLOCK: realized I already HAVE this ability- the appropriate code can be installed as a CFunction object into FunctionHandler, and called THAT way.

26/Aug/2007 20:58

Darn. Now I have nothing to add. Looks like I might actually have to try to get existing code to work for once. darn :).

4/Sep/2007 1:10

Sigh. Another entry that has very little to do with BASeParser, and much to do with my Video card/Driver. Haven’t been able to play DVD’s reliably for a while now, and DirectX started having the same problem. Now my OpenGL games are displaying corrupted video after a while. Sigh. I know! I’ll get a new Video Card. probably won’t help though…

-realized a quirk with the manipulation of Arrays. The parser converts the List delimiter tokens, { and }, into a call to the Array Function. I purposely don’t qualify this with BPCoreOpFunc. Why? Well, now if for some retarded reason you want to override the Default operation (which is to make an array out of the elements) you can. Why you would want to do this I don’t know, but the ability is there.

10/Sep/2007 8:58
ANOTHER redundant entry. replaced my RADEON 7000 64MB AGP (which replaced my ATI Rage Pro Turbo AGP2x 8MB) with a new Radeon 9250. Cool. In a interesting quirk, I have JUST realized that the drivers on it’s CD might have entries for my All-in-Wonder 9000 AGP. which is good, because this 9250 is a PCI card, and, well, I just can’t stand to leave my AGP slot empty. (not to mention the freeing of a PCI slot that I don’t have to insert a TV tuner into, since I eould have one built right into the card 🙂

17/Sep/2007 23:08

reverted InvokeDynamic code to it’s previous form- code was err-ing in situations where it shouldn’t. Will work
on this problem tomorrow, right now I am just too darn sleepy.

18/Sep/2007 9:11

I’m BACK! and refreshed. Not only did I sleep for a full- um- 5 hours… (not sure WHY I couldn’t sleep any further). anyway, I Was browsing through my extensive library of code (not all mine), and discovered FileSystemLib, a library from KillerVB that used to be slightly worse then my Library (Mine could also do pop-up menus for files, although it lacked in about a million other departments. Anyway, I browsed through the code for useful tidbits, and came upon some code dealing with SafeArray’s. long story short, I can now retrieve the dimensions of a Variant into a SafeArray. retrieving them and setting them is all I need to discover.

I also fixed a few syntactic errors in the different projects in the group that were preventing a Shift+F5.

2/Oct/2007 5:27

new stuff on the way:

Ability to load plugins dynamically via a Function (InstallPlugin and LoadPlugin functions- both as CParser Methods for clients as well as part of the Core Operators/Functions.

a big one: Macros. Some may think, yeah- a macro is just a variable. But, I must disagree. a Macro will NOT even be visible within the resulting Parse Stack. Rather, the Core Plugin (yes, a core plugin will be used to implement Macros) will simply use the ParseLocation Function override. If it finds a macro definition, it will insert the macro’s expression into that location (replacing, of course, the existing reference to the macro) and return False to indicate it didn’t do anything, and move the current parse location back one character (so the Parser re-examines the location that had the macro) The Parser will then re-parse the macro. exemplary. Of course, this means there needs to be a way to define macros. Damn.

10/Oct/2007 5:15

wow, I actually thought of an idea! ByRef parameters. Currently the Parser simply discards the changed array from it’s call to the handlers.

UPDATE: Cool, another single-day feature addition. Now I simply need a way for functions to specify that a parameter is ByVal…. oddly enough, too, ByVal is FASTER then ByRef- weird? no- because I’m forced to manually copy the new values back into the original variable. Oh, and assignment doesn’t work for array elements yet. I lied just now. Well, not when I wrote it. It works now. One problem though- I used the assignment operator := and it didn’t work! I had to use store.

11/Oct/2007 18:36

Managed to trace the assignment operator problem to some kind of priority problem. For example, this expression doesn’t work:


However, simply adding parentheses fixes this:


that’s weird- because I’ve set the assignment operator to the lowest priority!

11/Oct/2007 20:28

I swear, this one feature has been on the list of TODO:\\ since the start, and only once have I even come close: DLL function calls. I mean, it can’t be difficult- After all, Every single DLL declaration in VB is invoked this way (IE, an error is raised when you Call a non-existent function, not when you compile) and The Virtual machine DLL exposes DLLFunctionCall. I just don’t know the parameters. this is so very annoying. Anyway, Now that I have By Reference parameters, I need a way to prevent the logic from running. The solution? the FunctionInformation! Simply define a new field for Parameters- “PARAMTYPE” or something.

16/Oct/2007 4:54

mostly cleaned up a bit of the code. Noticed some conditional compilation in ModImprove (which contains my improvements on VB functions) that really wasn’t necessary, since I could move the functions used within the block into the ModImprove module (none of them depended on BASeParser functionality). These two functions were Flatten and Assign. I have moved them. yet to see any regressional bad behaviour.

finally fixed up the code. IT_STATEMENT was so simple and yet I gave up so easily before- It is now implemented in Ripformula, with each statement simply being stored in a fashion similiar to IT_SUBEXPRESSION. in fact, in all fairness, I could probably make RipFormula change the Itemtype to IT_SUBEXPRESSION instead of IT_STATEMENT and it would still work. In any case, IT_STATEMENT’s are always executed in order, but only when they appear on the same level of the expression. the last expression’s result is used as the return value. (NOTE: perhaps it should return an Array consisting of the return value of each IT_STATEMENT? I don’t know….

18/Oct/2007 20:21

Sigh. Everything is in order, except for the issue of DLL calls, but in general that isn’t exactly high on the priority list. sure, if I develop a dll or find a way to do it, of course I’ll add it. In the meantime, I’ll stick to more attainable feature sets.

Had an interesting debug session- I tried to give it garble, but it still parsed it- I had an expression consisting of some random stuff, and it parsed out VARIABLE names and operators! makes sense too!

23/Oct/2007 4:04

Thank god for small favours- I finally got the internet, but not exactly through the proper channels. It was as easy as purchasing a wireless network adapter. Seems at this point none of my neighbours know what a “password” is. On the up side for them, I don’t exactly plan on hogging it or sabotaging it at all, right now I just want to activate the programs I bought that won’t work until I do so, and use MSN to tell the story to my cousins, whom I haven’t had contact with in over a year. THANK GOD. although the card wasn’t cheap- almost 70 bucks. compare that to the meagre 14 dollars I paid for the network card in my other computer (so I can play network games with this one- or, could, until I removed my standard NIC.)

28/Oct/2007 20:44

ANYWAYS: thanks to Internet access, I managed to find a somewhat incomplete class module for calling Functions Dynamically.
needs some work though, and I would have preferred if it included the ASM code. Right now, I simply chucked a new function, DLLFunction() that will add a API function. One up-side is that the functions parameters don’t need to be defined (I know, it IS weird…) Although it will only work with API functions that return long’s. I haven’t found a API function that doesn’t, however. (the API uses the return code for success state, it appears.

So, For example, the following BPS (BASeParser Script) will return the activeWindow’s hWnd:


I lied. That didn’t work. Just returned zero. Although GetActiveWindow() did work as a expression afterward.

-BUGFIX: discovered the cause of the above. turns out it was a simple “Type Mismatch” in the IsFormItemConstant Function when the passed parameters are empty (Lbound/UBound on a Empty Variant). Added Error Handling to return False. Fixed.

31/Oct/2007 8:04

I think I’ll make this my first milestone release. Step one: find an Installer Maker program.

15/Nov/2007 17:34

Did some Internet Searches for Evaluators, to see what the competition has. And the answer is, “Not Much”. I did find several libraries, most notably USPExpress from UBISoft. The disadvantage, of course, is that is costs $149. BASeParser XP (At least how I plan for the foreseeable future) is Free. Or it will be, once I start F-ing distributing it. This is always the hard part. I think I’ll use good old “Advanced Installer”, because I found it to be quite versatile when I tried it before.

25/Nov/2007 20:10

A fairly large bugfix has been implemented. Turns out I only, err, kind of Half Supported implied multiplication. Revised the code during Ripping of the formula to detect when certain items (IT_FUNCTION,IT_VALUE,etc…) occur immediately after each other.

Speaking of which, I’m pondering a new addition in the area of formula ripping, for handling the occurence of multiple operators between expressions. For example, 5+*2
the question is- what does it get turned into? (5+2)*2? probably best to abandon such an effort for fear of promoting ambiguity.

I’m also someone curious as to the actual speed of the parser- sometimes it just seems slow. I’m trying to excuse it for many reasons:

1. My computer is 350Mhz
2. There is way to much debugging code- with file logging and so forth (probably the main reason)
3. so much must occur within the parse and execution for all the different scenarios (IE: Object access)

27/Nov/2007 13:45

Discovered a few simple optimizations I can easily make. The problem is with a few of the Case Statements in RipFormula.
For example, some will go as such:

Case Function()=Value

See the Problem! Function() (that isn’t  the name, but rather ParseValue,GetOperator, Etc…) is being called TWICE. what makes it worse is that these functions are some of the more expensive low-level parsing functions to execute. the question is how do I optimize it? Simple. use a new Store() function that stores a value in a ByRef Variable And returns that value. That way, the only time the function is called is as an argument to that function, and not once for the test and again to use the result. I guess this is a bit of an idosynchrisy of the Select Case Block, but nonetheless…

Also, Discovered a bug in the parsing of a value. for example, some thing like 2t should not be interpreted as a variable name. Since the Variables.Add method will scream bloody murder. Not sure why this is occuring. I believe it may be a result of my support of Hexadecimal being so haphhazard.

28/Nov/2007 1:11

Gave some older features some regression testing. Strings still work and Objects still work. The test expression? Right here:


which returned zero. Silly me, I thought there was an error, and then I was debugging and got to the point where BASeParser uses TLI to call the function and realized that everything was A-OK. the file was just, well, empty. This is XP, after all.

2/Dec/2007 20:12

Unexpected delays deploying BASeParser onto my test machine. First the sample app crashes with a Object defined or Application defined error, next I go to test the DLL as it exists on my W2k Machine. And find that it hangs on the call to Create(). having a hunch this may have something to do with the registry, I go back to my dev machine and do a debug run after deleting the keys. Lo and behold, it goes to the error handler because an Array wasn’t initialized. And what do I find there? A Debug.Assert. And a Resume Statement!

2/Dec/2007 20:36
TODO:\\ Fix-up InvokeDynamic Function to prevent intermittent IPF.

4/Dec/2007 2:53

InvokeDynamic Bug discovered and fixed. Turns out that the error was actually NOT intermittent, but rather occured whenever the parameter list to a object member was empty. For example with the Scripting.File object’s Size(). I had already re-written InvokeDynamic before I discovered this though. However, the new function implementation is much cleaner, requiring only a single loop. Oh, and it doesn’t IPF ( 🙂 ).

18/Dec/2007 8:16

tweaked up the parsing of the Subscript operator ([) to recognize an empty argument list and set the Value property of
that cFormitem to a uninitialized array. As such, it is now a simple task within a plugin to determine wether a empty subscript was passed and act appropriately- for example, now the expression:

“I like words, even looooooong ones.”[][5]

will return “looooooong”, since the core operator/functions handling of strings with array access will split a string into a array of words with empty parentheses. note that the above expression differs from this one:

“I like words, even looooooong ones.”[5]

which returns the fifth character in the string, or “k”. I’ve even successfully done this:

“Words are great and good too”[][3][2,2]

which returns “re” or the string 2 chars long starting at position 2 of the third word.

all in all this parser is really becoming quite powerful, I’m still a bit wary of instability issues that may arise.

6/Jan/2008 18:52

I STILL have yet to actually publish BASeParser on the web. Actually, right now, my access to the net seems to be cut-off at the router. This happens usually when there is a power spike or outage, and I did notice my lights flicker earlier in the day, so I’ll just hang tight for a while, just like last time.

In any case, I haven’t completely stopped development work on BASeParser, although I seem to be in one of my non-programming phases. It happens with me every few months. I seem to stop programming, preferring, well, almost anything else. For example, I have started playing the Megaman series again on my old DOS/Win 3.11 laptop.

I did, however, manage to get my plugin, CScriptFunctions, working properly. I actually pretty much re-wrote the implementation. Originally it would load ALL scripts into the same Script Control object. I have changed this. Now a Key exists in the registry for each Script control to be created,(with a name that ideally describes the files therein). The key contains a “language” value, which is used on the Language property of the ScriptControl created for the section. the “Scripts” section contains values for each Script file that should be loaded.

The actual implementation of the feature within the BASeParser Plugin was easy. The tricky part was the creation of the UI widget that implements the ISettingsPage interface required by the BASeParsert Library’s Configuration Page. (I did manage to fix a bug within the settings page involving the use of height instead of Scaleheight. Took almost three hours to trace the problem of why I couldn’t see the tabs for the plugins.). Why was it so hard? Well, I really don’t like programming the GUI part. Of anything. It seems I always overlook a lot of stuff. for example tab order. speaking of which…. there. Never mind I fixed the tab order, well, at least on the userControl…

Improvements to be made:

As is, the Script Function Plugin is fairly versatile, but, ideally, it would support more functionality. For example, what if the desire is to have several files in different sections with a function of the same name? As it stands now, no error would occur, but the Plugin will only use the first ScriptControl it finds in the collection of script controls for any call to the function. specifically, adoption of the dot notation, as in, SectionName.FunctionName would be useful, and probably quite easy to implement directly in the script control (which is good, I don’t want the parser’s core routines  associating with such vermin :P.

16/Jan/2008 17:08

New modification to the CDataFunc external library plugin. this is a plugin that is used to load functions from a database when the plugin loads. The original design loaded all the functions at once into the CParser objects Functions collection. I decided that that would not do.

6/Feb/2008 4:43

Due to the fact that I released it on the net, I have incremented the version number of the current development project of baseparser. Why this requires mention I don’t know.

In Any case, I’ve been scouring the net for Expression evaluation related stuff.(mainly downloads to other VB made parsers, or even VB.NET. Personally, I have VB.NET installed, but, I don’t think it’ll become usable until I upgrade to a new computer. I’ve been stowing away money in my bank account for quite some time, living on tea and sandwiches from work. And I have just realized that this saving is due almost entirely to the weather! But, back to the whole purpose of this devlog. It’s SUPPOSED to be about BASeParser XP, not a frikkin’ personal journal.

TODO list:

– Either fix or remove the substring parsing. right now it’s enclosed in some conditional compilation, as I have yet to get it working.

Probably a good idea to create some more GUI components, for example, one for defining functions would be useful in the Graphing control I created.

3/26/2008 3:07AM

Note to self: when making backups, ensure to label them as such. I had a complete duplicate of my code tree (D:\VBPROJ”) placed on my E:\ drive as E:\VBPROJ, and
when I went to copy the files to my new computer, I copied from the E:\ drive. (I thought I was working on E:…). Then when I got the project working and started fixing stuff that came up,
I got a strange sense of Deja-vu- I had fixed the problems ALREADY!. Took me a few days to figure it out. Main giveaway was the BPCoreOpFunc.cls file size being over 10k larger with the one on the old D: drive.
and that is how I revived it!

04/02/2008 1:44AM

well, I have a week off starting today, so as better get some coding done, I suppose. Anyway, I thought of a novel plugin to write: a plugin that
allows Scripts to be plugins! This would be fairly simple- just delegate all the calls to the loaded Script Plugins.

05/17/2008 8:13 AM

I’ve finished (untested as of yet, however) the Script Plugin architecture. Now the major hurdle is the SettingsPage Implementor that will be loaded into the Configuration dialog.

For now I’m going to simply release (in the loosest sense of the word) just the Core library itself, without all the extra fluff I’ve added. The first distro will just be a ZIP file with the requisite files, leaving actual installation to the end user (hows that for respect?) I generally falter when it comes to setup, despite the fact that it really is easy with Visual Studio 2005.

Before I do that though, I’m going to make sure the setup program can properly install it without the dreaded “ActiveX component can’t create object” error occuring.

05/20/2008 3:52 PM

New feature in the works: a new interface method, BeforeFunctionCall, that will be called on all IEvalEvents implementors, allowing interception of function calls or redirection of the Interface method to another implementor.

Finally completed implementing the CSet Class’ interface methods for Evaluation. I programmed in all sorts of convolutions to recognize a “SetOf {<set values>}”. Then, I realized something- JUST MAKE IT A BLOODY UNARY OPERATOR! It took over 2 hours to code the ICorePlugin Interface methods, and yet in the last ten minutes I extended the functionality and wrote it from scratch with just the IEvalEvents Operators….

If I’m ever going to release this library I’m going to need one tome of a doc!

05/26/2008 8:13 PM

Now that BASeParser is essentially complete, I need to program in some security features. Although I highly doubt that anybody would target BASeParser for the creation of malware (IE, a implementor that doesn’t do anything Parser-wise, but sits in the background and monitors stuff). Not sure how to go about it though…

05/27/2008 6:04 PM

very useful feature to implement- a more generalized method of changing the settings of plugins from code. As it stands now, a client would need to know the registry keys, INI files, or whatever else is used to change any of those settings. This would be fine, except that plugins could change their behaviours based on these settings (makes sense) and perhaps cause incompatibilities with the way the client wants the expressions to be parsed. Instead, it should stand to reason that there be a generalized way for client code to automatically change the settings of a plugin, without necessarily requiring in-depth knowledge of where it is stored.


new feature that will make use of some of the advanced COM classes I have- the sinking of events from any source with a CFunction object.


Alright; there is NO way i’s been 6 months since I updated this devlog… alright so checking the last modified time confirms that it has. Huh. Anyway- I’ve been making quite
a few changes to several parts of BASeParser, and neglected to document them.

The first change came as a result of my inability to create a small console application that used it’s facilities for simple on the spot parsing; after some testing,
I managed to get the program to run flawlessly, but only when I had BASeParserXP running (the DLL) in the IDE. Odd!

A few hours of code sleuthing later (involving my very forward thinking use of OutputDebugString() in my CDebug class, as well as DebugView) and the placement of some
CDebug.Post methods; the problem was very vexing; when running in the IDE, the Create() method properly executed and added all necessary plugins. However, when I compiled the library, no amount of coazing was able to get it to
load even the basic BPCoreOpFunc plugin. with the CDebug.Post methods littered about, and some error printing in those portions that shouldn’t fail, I managed to trace the problem
to a exact line in IEvalEventSinks; namely, this one:

ParserSettings.VerifyPlugin GetObjectProgID(ObjAdd)

the strange part was, placing a debug print in VerifyPlugin or GetObjectProgID, they never appeared. The error was occuring trying to call GetObjectProgID; the error was
“Object doesn’t support this property or method”. It’s as if the getobjectprogID routine didn’t accept Object parameters; which it did, in fact it only supported object parameters.
Another mystery was why everything was howdy-doodee in the IDE; my first thought was of course optimization options; no dice.

I never solved the mystery, but I decided that the VerifyPlugin call was a bit overzealous; obviously an error will be raised if I was to try to add a object that didn’t support IEvalEvents so I was a bit premature to presuppose otherwise at that point.

the fix was to comment out the code. I have a feeling something along these lines will crop up again, though. But with my enhanced debugging output it will be even easier to trace the problem into the problematic parts of the code.


Fixed Multiple statement parsing; now it could even be used as a programming language… a slow one, but a language nonetheless.

Right now performancec is sub-par, I hope that is caused mostly by the rampant CDebug.post method calls; each one writes to the log file and stores quite a bit of data about the call.
with any luck execution without the debugging facilities enabled will be far faster.


Made a few tweaks and improvements, and added some better error handling for non-existent Object methods (I had a If reversed).
Started BCScript Script program interpreter- works well. Command line prog.


Another couple tweaks here and there- added some implementation to the BPCoreOpFunc function Cases- INSTALLPLUGIN,UNINSTALLPLUGIN,LOADPLUGIN, etc.
I’ve decided (At last) that this WILL be the first release version, just as soon as I find a place to post it.


ALRIGHT… finally created what I believe to be a working installer program for it- installs and uninstalls fine. Only installs BASeParser and the BCScript Scripting engine; will probably add some simple little program to demonstrate BASeParser itself, though.

thought of a change to make while I was reading about javabeans somewhere- automatic use and detection of methods with names such as “setX” and “getX”- for cases where that object doesn’t have a “X” property for reading/writing. (Obviously, this will be in the InvokeDynamic routine)


New feature- “importing” of constants from external typelibs. This will likely require a new object type, CEnumeration, which will implement IOperable and possibly hook Variable accesses.

** Feature implemented, Minor Version number incremented.

the functionality is quite basic, however…


FINALLY got some dynamic DLL calls working. All API’s I’ve tried (MessageBox,GetTickCount, and a few others) worked flawlessly.
uses a COM component I found online, but I’ll reverse engineer that and create my own.


Many changes over the last while thanks to bug reports and some testing by myself.

the STORE() function wasn’t working for expressions like STORE(X,Msgbox(…))- Msgbox was being invoked twice.

Traced the source of the issue to the HandleFunction() routine in CParser, which Evaluates each argument to test for IOperable Objects. I’ve commented out that portion, so for now Objects (such as ccomplex) no longer have their own function handling.
Not sure how to workaround this issue- I might need to place it in BPCoreOpFunc…

Also, discovered a “minor” issue with Variables- for example:


would fail to work, since it finds SIN as a function name. Only way(that I can think of now) would be to change the Plugin Interface to allow for Operators to have unparsed operands…


haven’t been working on BASeParser or BCScript for the last month or so. Was occupied with my other BASeMetry Library. But, coming back to this I had decided to add my “backticks” idea for redirection. It worked as long as I didn’t enclose it in brackets or a function call!

the problem turned out to be my clone routine. The parser simply wasn’t copying a reference to the core plugins collection, so my CPlugBackticks core plugin wasn’t being loaded within any Sub-parsers.

Posted By: BC_Programming
Last Edit: 30 Sep 2010 @ 12:24 PM

EmailPermalinkComments Off on An old Devlog…
 28 Nov 2009 @ 3:59 PM 

In my previous entry, I discussed and provided code that would allow for the detection of Triple-Clicks on a window. By extending the provided architecture, it is relatively trivial to allow any number of consecutive clicks; for example, detecting pentuple clicks.

More »

Posted By: BC_Programming
Last Edit: 28 Nov 2009 @ 03:59 PM

EmailPermalinkComments Off on Triple-Clicks revisited: implementing N-Clicks
 20 Nov 2009 @ 7:58 AM 

Visual Basic 6; and, well- nearly any other relatively modern language; provides a way to detect mouse events. These usually include mouse down, mouse up, mouseclicks, and double clicks. Absent are any higher “N-clicks”; I speak, for the most part, of the triple click. More »

Posted By: BC_Programming
Last Edit: 20 Nov 2009 @ 07:59 AM

EmailPermalinkComments Off on Detecting Triple-Clicks
 03 Nov 2009 @ 12:31 PM 

I have been using Visual Basic 6 for many years; I have come to the point where using it is effortless; nearly any problem I have I can design and program with Visual Basic 6.

However. Visual Basic six is over 10 years old. Mainstream support ended a few years ago, and after Vista Microsoft makes no promises that programs designed with Visual Basic 6 will work. Even creating programs that support the various UI features of XP could be a chore. With Vista, Not only does one need to include the proper manifest resource or file  to force their VB6 applications to link with the newer version of comctl32, but it is almost always necessary to include an additional set of directives in the manifest to make the program request administrator permissions. I have yet to determine why some of my less trivial programs crash before they even start when run with the same security as the user, but I imagine it’s directly related to COM components, their usage, and the permissions surrounding them.

Another area of concern is with the use of proper icons; Visual Basic complains when you try to use a icon with a alpha channel. However, through a few API techniques and some resource editor trickery, it’s possible to have your application use 32-bit icons both as the program file icon as well as the icon for your forms. Rather then repeat the material here, I will point you in the right direction if this type of this piques your interest. www.vbaccelerator.com- I cannot praise that site and it’s creator enough. While many of the projects and controls he has on-line I have personally attempted before finding the site (I had a somewhat working toolbar control and a control I called “menuctl” that allowed moving the main menu around as a toolbar), the sheer number of completed, documented, and well written controls on his site is simply mind-blowing. There is also a .NET section to his site as well, which brings me to my next point.

There are only a few reasons why a programmer would choose to use Visual Basic 6 for a new project today. The main reason is simply because we are stubborn, for the most part. The fact that .NET is better in many ways then VB6 does not sway us to use it. The fact is, we all feel “betrayed” in a way, but the shift to .NET. Millions of lines of code that were dutifully compatible through all 6 versions of Visual Basic 6 now break when loaded in VB.NET. But I believe, that the majority of VB6 programmers have simply been blinded to the number of problems Microsoft would have faced to continue using the same COM oriented framework that VB4 and higher have used.

COM,or, Component Object Model,(sometimes referred to as “Common Object Model” which is dead-wrong) is a Binary compatible method of providing interoperability between applications. COM was essentially designed to prevent what was known as “DLL hell”, since at that point in time DLLs provided their functionality through exposed functions, some versions not compatible with previous versions, meaning it might be necessary to, for example, have 5 different versions of MFC41.dll on ones PC. The idea was, each version of a COM component would be Binary compatible with the previous version, which means, for example, that a program designed for version 1 of “foocomponent” could still run and use version 4, but without the new features of version 4. This functionality was implemented by the creation of Interfaces. Each version of a component would add a new interface- for example, IFooComponent, IFooComponent2,IFooComponent3, etc, and client applications who want to use FooComponent would use the interface appropriate to the version they wish to use.

There was, however, one problem. Most of the maintenance between versions was left to the programmer of the component- they had to create the new interface, make sure previous interfaces worked, that old clients could still instantiate their objects, etc. Basically, it made the critical mistake of putting the user of the technology (in this case, the programmer) in a critical position and with a number of responsibilities to get things to work properly.

Microsoft, of all companies, should know that putting the programmer in a position of such responsibility is prone to failure; hell, many of them can’t even be bothered to follow standard API documentation; for example, actually reading the documentation; this resulted in hundreds of man-hours of programmer time being consumed by the creation of “compatibility shims” to let these programs work. (otherwise, installing a new windows OS would break these programs; they worked before, so as far as the user sees the new Operating System is to blame). Anyway- this failed miserably. Programmers would sometimes simply change their interfaces rather then implement new and old ones, meaning, like with the DLLs of before, new DLL versions were incompatible with the old ones.

It was clear that COM, or, at least, COM as it was presently designed, was far to dependent on the programmer to “do the right thing” then was reasonable. So, Microsoft, at some point, decided they needed a new object framework architecture.

VB6, as a COM-based language, would have required extensive changes to support this new architecture. the prospect of such a huge revision probably made them take a second glance at the language itself, and the cruft it still has from previous iterations of the basic language. aside from retaining such archaic constructs as the “GoSub…Return”, VB6 also “failed” in a sense on a number of other areas. Error-Handling, for example, was still done using “On Error” statements, which redirected flow to another segment of code. It was up to that block of code to evaluated the error, using the “Err” object (In VB1-3 there was only Err which was the error number and Error$, which was the description), and then either resuming that same statement that caused the error (Resume) skipping that line, and continuing with the next, (Resume Next) or even raising the error again, causing the error to cascade up through the call stack.

This Error architecture had a critical flaw- by using this form of error handling, flow could change to the error block for any reason, at any time. This meant that if the procedure dealt with resources, such as file handles or memory blocks, it would have to keep track of what needs to be undone so that the error code could also double as partial cleanup code. Another critical flaw was simply that it was ugly; it looked and functioned nothing like the Try…Catch statements in many other languages. Also, it could become impossible to trace exactly where an error occured when errors cascaded; and error handler might be forced to handle an error from three levels down in the call-stack, so even if it understood the error in the context of the procedure, the context that the original error occured in and exactly what it means was lost.

My main language is Visual Basic 6, but I am not so blind as to reject VB.NET, or .NET as a whole, merely because it essentially replaced VB6. The truth is- we, as VB programmers, have made a large number of requests to the VB developers. VB .NET answered and fixed a huge number of those requests, and yet it is still shunned; it is clear to me that it is not merely the loss of backwards compatibility that causes such antagonism with VB6 programmers, but also the human element of resistance to change.

With previous versions of Visual Basic, one could migrate all their code to the new version with little or no difficulty.

This, however, had a price- since the new version made few, if any, requirements for conversion, old antique code would often be upgraded and imported into the new environment. Since backwards compatibility was the rule, old elements such as line numbers gotos, and gosubs remained in the language. Antiquated concepts such as type declaration characters remained in the language. Such visages of a forgotten era had no place in a modern language.

All the above being said, VB6 is still a language capable of creating modern applications; however it is important for the programmers who still use it to realize that they aren’t using it because it is superior or because .NET or any other language “sucks” by comparison, but rather as a result of their own stubborness and unwillingness to learn new programming concepts.

A anecdote, if I may, can be found in my introduction to the use of “class modules” within Visual Basic. at first, I had no idea what they were- I simply shied away from them, and stuck to Forms and code modules. I used all sorts of excuses- Class modules are slower, they bloat the code, etc. All of which were, almost universally fabricated or found on the web written by grade 8 students who barely understood the meaning of the word “class” in the context of programming or objects.

After, however, creating ActiveX Controls using the “userControl” Object, I realized the similarities, and the possibilities that could arise. My first conversion attempt was on my Current “flagship” program, the game I called “Poing”. At that time, the entire game was designed using User defined types as functions that operated on them. I understood the concept of encapsulation and managed to convert the entire architecture to a Class based object heirarchy- and it worked. My concepts still contained flaws, such as including critical game logic in down-level objects, but for the most part my udnerstanding was sound.

As my understanding of the concepts involved improved, so too did my antagonism disappear. It was clear to me that the fact that I didn’t understand classes at the time lent itself to a distaste for them- basically, the old adage that one is “afraid” of what one doesn’t understand was at least partly true. This, I feel, is at the very core of the antagonism against .NET. the main detractors of the framework are often people that neither understand the concepts involved nor do they realize how said concepts add increased possiblities and easier maintenance.

Even so- .NET has, in my opinion, one critical flaw. the IDE is slow. even on my quad core machine I see huge delays as intellisense is populated or any number of other operations. Perhaps it is a result of a mere 7200RPM hard drive? I don’t know. perhaps I need more then my current 8GB of RAM? who knows. I think, that using a 10 year old program and expecting and recieving quick responses from it have perhaps jaded me in terms of what the extra features of the new IDE actually cost in terms of performance; the delays feel like minutes, but in general it is only a few seconds. On the other hand- a few seconds is a lot longer then necessary to make one lose their train of thought. At the same time, this same argument was used against the initial usage of Intellisense; and there is no denying that although the initial display of a number of said intellisense lists can take some time, subsequent usage is nearly instantaneous, and the lists provide far more in terms of function information then the VB6 OR C++ 6 IDE could provide; this, in addition to the ease of use of assemblies between multiple .NET languages is not something that should be passed up because of an ego-centric desire to prevent change. The IT industry changes constantly. The fact that VB6 is now a “past item” should not dissuade us from moving forward because of a snobbish desire or fictitious affection for the corridor of our programming efforts for many years; the complaints about VB6 when it was introduced were very vocal. This is, no different with VB.NET, however the very complaints made about VB6 that have been remedied with .NET are now being passed off as inconsequential (since in many cases programmers have devised ways of working around limitations or even forcing behaviour that VB6 was not designed for, such as, for example the creation of Command-line programs.

The mistake Microsoft made was not the creation of .NET, but rather the belief that any sane person would move to a new platform if it was superior. They forgot the take account of the psychological factors involved.

Posted By: BC_Programming
Last Edit: 03 Nov 2009 @ 12:31 PM

EmailPermalinkComments Off on Thoughts on VB6

 Last 50 Posts
Change Theme...
  • Users » 47469
  • Posts/Pages » 397
  • Comments » 105


    No Child Pages.

Windows optimization tips

    No Child Pages.

Soft. Picks

    No Child Pages.

VS Fixes

    No Child Pages.

PC Build 1: “FASTLORD”

    No Child Pages.