This is one of those often used functions in VB6 that could use a little improvement. The main problem with CreateObject is when it throws an error, it doesn’t report what object it was attempting to create at the time, which would be quite a handy thing to know.
Fortunately, CreateObject is one of small number of intrinsic functions in VB that can be overridden quite easily.
In other words, you can define your own CreateObject function, and VB will call your version instead of it’s built in version anywhere that you use it. This is quite handy because it means you can use the enhanced version without changing any calling code.
For instance, here’s a CreateObject function I put together that expands on the default error message string if it encounters a problem creating the object asked for. It simply adds in the PROGID of the object you’re trying to create.
Public Function CreateObject(ByVal Class$, Optional ByVal ServerName$) As Object '---- override the CreateObject ' function in order to register what ' object is being created in any error message ' that's generated Dim Source$, Descr$, ErrNum On Error Resume Next If Len(ServerName$) Then Set CreateObject = VBA.CreateObject(Class$, ServerName$) Else Set CreateObject = VBA.CreateObject(Class$) End If If VBA.Err Then Source$ = VBA.Err.Source Descr$ = VBA.Err.Description ErrNum = VBA.Err Descr$ = Descr$ & " (ProgID: " & Class$ If Len(ServerName$) Then Descr$ = Descr$ & ". Instantiated on Server '" & ServerName$ & "'" End If Descr$ = Descr$ & ")" On Error GoTo 0 VBA.Err.Raise ErrNum, Source$, Descr$ End If On Error GoTo 0 End Function
Put this function in a normal BAS module, and anywhere that you use CreateObject already, you’ll now be calling this function.
And to answer a few questions:
Q: Why do you use the VBA prefix for CreateObject and the ERR object in this piece of code?
A: In the case of CreateObject, you have to prefix it or this function would end up calling itself instead of the real VB CreateObject function.
In the case of the ERR object, see below.
Q: What other functions can be overridden?
I haven’t done an exhaustive study of it, but I can say that a particularly handy object to override is the built in VB ERR object defined in the VBA library.
Overriding that object allows you to extend error handling functionality in all sorts of ways.
For instance, you could add a LOG method to the ERR class, or a MSGBOX method that automatically formats an error for display in a message box.
But that’s a topic for another post.
8 Comments
Very cool. Another snip of code that’s going in my toolbox.
This is one of those things you don’t realize you know until it’s pointed out. I’ve overloaded VB primitives before by accident, but didn’t recognize how useful it could be. Thanks!
I don’t call those things “PCs” any more – the term PC is an IBM tdaremark (or perhaps was – or should have been). The IBM PC was a computer: so that’s what I call these things: computers.A PC is an IBM product.On the main topic: what is it about the browser, anyway? Firefox is Firefox – no matter what operating system or desktop environment it is using.
You can also hide and unhide the Personal WB. This is handy if you are often wokring with the VBA editor, since it wants you to have the workbook visible to edit the macros. If you are not editing them, it is better to have it hidden, or else it will open the Personal workbook each time you start Excel.
And they say VB6 is dead<g>.
There’s not many you can override like this, at least, not many that would be useful. This is one, there ERR object is another.
Anyone know of any others that are handy to override?
Nice, using the same procedure how would you over come trying to get that object (DLL) to be registered to all users on a Windows2008 server? or in an environment where you create the object (Dll) be able to use regsvr32.exe without an admin user?
Hi th
Thanks for the comment and good question.
The snag about Admin user and REGSVR32 (and self-registering COM dlls in general) is that usually, the reg entries that are compiled into the DLL, and that are added during a self-reg, are directed at the HKLM hive, which, of course requires administrative access to write into.
Windows installer works around this by running a service that runs as local system and that’s generally how most applications deal with that particular problem.
Creating a VB6 COM DLL to self register to either HKLM or HKCU would not be easy. VB6 defines it’s own DLLRegisterServer function, and it’d be tough to override this.
You +could+ create a .net DLL that could self register AND could direct the registry entries to either HKLM or HKCU, I don’t believe that’d be too difficult. You’d just need to modify the DLLRegisterServer and UnregisterServer functions to attempt to write to HKLM, and if it fails, attempt to write the same key to HKCU. But that’s .net
And finally, you might want to look into “registry free com” or “registration free com”. It’s a technique that uses an XML manifest to tell the OS where to locate com dlls instead of the registry. It’s available starting with XP SP2, so be aware of that if you have to support systems older than that (hopefully not!)
Hi
Thank you for the response its perfect, I think we will go down the route of an installer which we can the use the window installer service. Thank you for your response it has pointed us in the right direction
Not a problem. Glad I could help. My take on installers is that you should strive to get your application to the point where you can do an xcopy install if you’re an admin, but then rely on Windows Installer for those few bits you can’t do if the user is NOT admin.
And if you don’t have an installer, check out Wise. I can’t stand InstallShield.
I also really like Innosetup and it’s free, BUT, it doesn’t make use of the Windows Installer service, so it can’t register OCXs or COM DLLs when the installing user is not an ADMIN or poweruser. So that limits its usefulness a bit. Just depends on your audience.