vbAdvance Help and Documentation

Posted On 2018-03-10 by VB6Boy
Tags: VB6 Miscellaneous 
Views: 78

vbAdvance is a Visual Basic Add-In which gives access to advanced build features and many IDE convenience features. This post covers some advanced topics, and discusses some of the samples included with the package.

Webmasters Note

I attempted to contact Karl Peterson, Young Dynamic Software, and the webmaster of mvps.org, with no success.

I have approved the posting of this content on the basis that the persons or entities listed appear to have no further interest in the content, as well as the copyrights appear to have not been updated since at least 2007 for the content, or 2011 for mvps.org.

If any of the people or entities listed above have questions, comments or concerns with this post, please don't hesitate to use the contact form in the footer below to get ahold of me.


VB5 and VB6 are able to build true Win32 native code executables by using what is essentially the Visual C++ compiler and linker. These build tools are a part of every VB 5 and VB 6 installation* and are as full featured as those found in Visual C++. However, the Visual Basic user interface provides access to only a subset of the capabilities found in this extremely powerful build system. For example, function exports and console subsytem applications can be built using the tools that ship with VB 5 and 6, but VB does not provide you with a way to access these features. The features are not missing, you just aren't given a way to access them.

vbAdvance gives you this access. On a per-project basis, you are able to access and configure these powerful build settings, as well as a host of other IDE convenience features. The result is that a range of capabilities that were previously unavailable are now made available to VB developers.

In addition to the build system enhancements, vbAdvance also extends the VB IDE, adding convenience features like Syntax Checking and clearing the Immediate Window when you run your project. vbAdvance is a fast, efficient tool that greatly enhances VB's build capabilities, and makes the Visual Basic IDE better and easier to use.

As a Visual Basic Add-In, vbAdvance runs while you design and compile your applications. Once your app is built, vbAdvance is no longer needed. vbAdvance adds no distributable dependencies to your projects - there is nothing to distribute because vbAdvance is only needed by the VB IDE.

All vbAdvance project settings are stored as plain text in your project's VBP file, ensuring your settings migrate easily with each project, and making it easy to set up advanced build configurations with automated build tools. These settings in no way interfere with the normal workings of VB, and you can build the same project on a machine without vbAdvance installed, without incident. (Albeit also without the advanced build features offered by vbAdvance.)

Because some of the features exposed by vbAdvance were not designed into Visual Basic, special care must be exercised when using these features. You must have a solid understanding of Windows programming to take complete advantage of this tool. At the same time, many of the features will be appreciated by even novice programmers.

* Applies to Visual Basic Professional and Enterprise Editions. Visual Basic Learning edition does not permit creation of native code executables.


vbAdvance is distributed as a single self-extracting installer EXE. Double-click the EXE to launch the installation process. You will be presented with standard installation options. Once installed, the add-in will load automatically the next time you start VB. The vbAdvance Toolbar will be floating in the center of the screen and may be repositioned and docked to your liking.

To uninstall the add-in, go to the Add/Remove Programs Control Panel, select vbAdvance, and select Uninstall. Alternatively, you may launch the uninstaller from the vbAdvance Start Menu entry.

If you are upgrading from a previous version, you may simply run the installer over your existing version. You do not need to first uninstall a previous version.


vbAdvance is now unsupported freeware. Use the following license to register the product:


Copy it all (include the BEGIN and END LICENSE lines). In the Advanced Options dialog, click on the "About" button, then click on the "Register" button. Paste your registration info and click OK.


Visual Basic Professional or Enterprise Edition version 5 or 6 / Service Pack 3 or higher.

Any Microsoft-supported Win32 operating system (server or workstation): Windows 98, ME, NT 4.0 (SP#4 or later), 2000, XP.

Native code compilations only, p-code is not supported.

For building resource-only DLLs, a copy of cvtres.exe is necessary. This utility is not redistributable and so is not installed with vbAdvance. cvtres.exe is installed with Visual C++, and is also downloadable from Microsoft's website. At the time of this writing, the file was available at the following location:


The download link is also specified in Knowledge Base article Q187280.


As a Visual Basic Add-In, vbAdvance runs while you design and compile your applications. Once your app is built, vbAdvance is no longer needed. vbAdvance has no distribution requirements - there is nothing to distribute because vbAdvance is only needed by the VB IDE.

You are expressely forbidden from distributing the vbAdvance.dll DLL, the vbAdvance.tlb Type Library or any of the vbAdvance sample code as raw source code. You are allowed to use the sample source code in your own projects, provided it is only distributed in compiled form.


The vbAdvance.tlb TypeLibrary is provided for your use. You may freely use this file in your applications. However, you do not need to distribute it with your application, nor are you allowed to. This file is required by many of the sample applications.

Because vbAdvance gives you access to features of the VB compiler and linker, and because the compiler and linker are only used when compiling to native code, these features can only be realized in native code compiled projects. P-code compilations are not supported in vbAdvance.

Because vbAdvance exposes functionality that VB was not intended to expose, we cannot provide support beyond that which the product claims to accomplish. i.e. If you wish to export a function, we will only guarantee that the export exists, we will not guarantee that it will be callable under all conditions. What you do with the export is up to you. We are merely giving you the capability.

Due to the nature of some of the techniques vbAdvance must use to control the VB build environment, there may be conflicts with other add-ins that use these same techniques. Should this occur, we will evaluate the conflict to determine if a workaround exists. Note however, that there may be nothing that can be done and that vbAdvance may not be able to coexist with some add-ins. This situation should be rare.

Command Line Builds

Command-line builds are fully supported in vbAdvance. To use the command-line feature of vbAdvance, simply set the Load Behavior for the add-in to "Command Line". Due to a bug in VB, you cannot set the add-in's Load Behavior to both "Load On Startup" and "Command Line". These two settings are mutually exclusive and you must pick one or the other. If both are selected, then "Load On Startup" is used and the add-in will not load on a command line build.


The vbAdvance Toolbar displays six buttons:

vbAdvance Toolbar

  1. Advanced Options - This button brings up the Advanced Options dialog which allows you to configure your project's advanced build settings, as well as the advanced IDE settings.
  2. Send Current Code Module to Text Editor - This sends the currently viewed code module to your default text editor. This allows you to use a far more powerful code editor in concert with the VB IDE.
  3. Check Syntax - This button runs the VB compiler up to, but not including, the point where a binary is built, giving you a full syntax check of your code without the hassles of having to generate a binary.
  4. Build - This button builds your binary without the dialog boxes. This is the equivalent of selecting File->Make but without the "Make Project" and "Do you want to replace it?" dialogs that pop up.
  5. Execute - This button runs your binary, if it exists.
  6. Make Resource-Only DLL - This button builds a resource-only DLL if you have a resource file in your project.

Advanced Options

The Advanced Options dialog contains five tabs:

  • Build Options - Settings for the various build options.
  • Exports - Specify any function exports. For DLL projects only.
  • Resource-Only DLL - Settings for building a Resource-Only DLL. Not tied to a project type.
  • General - All other project settings.
  • IDE Settings - Settings that are not project-specific, but that affect the entire IDE.

All vbAdvance settings are found in this dialog. Press OK to accept your settings and close the dialog. Press Cancel to close the dialog without saving changes. You must save your project for any project-related settings to persist. Press About to see the About dialog. Pressing Help brings up this help file.

Build Options Tab

vbAdvance Build Options Screen

The Build Options Tab of the Advanced Options dialog contains build-specific settings:

  • Version Number - Your project's version number is set in the VB Project Properties dialog. Unfortunately, VB does not give you access to the Revision field. The field that VB calls Revision is actually the Build field of the version number. Whatever values are set in VB's Project Properties dialog will be displayed here in the greyed out boxes. The Revision field is editable, allowing you to specify the Revision number.

    The VB version fields map to the actual version fields like so:
    VB Field Actual Field
    Major Major
    Minor Minor
    - Revision
    Revision Build
    • Build As Console Application - Check this box to build your EXE as a Console Subsystem Application, which will allow it to interact with the Command Prompt.
    • Include XP Manifest Resource - Check this to have vbAdvance automatically compile an XP Manifest into your application in order to support the new XP Themes. Note that you will also need to add a line of code to your application to initialize the Common Controls. See the following Knowledge Base article: http://support.microsoft.com/default.aspx?scid=kb;en-us;309366
    • Generate MAP File - To generate a MAP file for debugging purposes, select this check box. This option automatically generates line-number information.
    • Terminal Server Aware - Check this to mark your application as a Terminal Server Aware application.
    • Application Icon -Use this setting to specify an icon file (*.ico) to use as your application icon.
    • Attach Custom DOS Stub Executable - This setting allows you to change the default DOS Stub EXE which is compiled into your VB Windows app.
    • Advanced Symbolic Debug Info Settings - If you have 'Create Symbolic Debug Info' checked in your Project's Properties dialog under the Compile tab, the following debug file settings can be configured:
      1. Create a seperate PDB file (normal VB6 behavior) - This is the default and does not change anything. You will get a PDB file as always.
      2. Create a seperate PDB file with the private information removed - This setting will strip the private information from your PDB file.
      3. Create a seperate DBG file with the private information removed - This results in a DBG format file being generated rather than a PDB, and again with the private information stripped out.
      4. Compile the debug information into the EXE/DLL - This will essentially embed your PDB file into your EXE/DLL/OCX so that you do not need to ship a seperate file to take advantage of advanced debugging techniques.

    Exports Tab

    vbAdvance Exports Tab

    The Exports Tab of the Advanced Options dialog allows you to specify function exports for DLL projects:

    • All functions available for export in your project will be listed here. To export a function from your DLL, simply check the function in the list, and build the DLL. All Public methods located in BAS modules will be listed here and are selectable for export.
    • The function names must be unique - this is a limitation of the linker. It has no way to specify two exports of the same name.
    • The Exported Names may be renamed. The Local Names are listed from your Public BAS functions. By default, the Exported Names will match the Local Names. The Exported Name is the name with which the export will appear. The Local Name is the function that the export will resolve to.
    • To rename an Exported Name entry, slowly double-click on the Exported Name entry to place it in edit mode, or right-click the entry and select "Rename" to place it in edit mode, then type in the desired export name.

    Resource-Only DLL Tab

    vbAdvance Resource Only DLL Tab

    The Resource DLL Tab of the Advanced Options dialog contains settings needed for building Resource-Only DLLs:

    • Resource-Only DLL Build Filename - This specifies the path and filename of the resource DLL that is built by pressing the "Make Resource-Only DLL" button on the vbAdvance toolbar.
    • Use Default - This resets the Resource-Only DLL Build Filename to the default setting.
    • Path to cvtres.exe - This setting is required and is used to define the location of the file "cvtres.exe". This EXE is required for building resource-only DLLs. Unfortunately, this file is not installed with VB. It also is not redistributable and so cannot be included in the vbAdvance installation. It is installed with Visual C++. If you have Visual C++ installed, you will see the path to the file already entered. There is nothing more you need to do. If you don't have Visual C++ installed, you can download the file from Microsoft. At the time of this writing, the file was available at this location:


      The download link is also specified in Knowledge Base article Q187280.
    • If necessary, download and install cvtres.exe onto your hard drive. Once you've decided where to store the file, enter the full path to the executable into the 'Path to cvtres.exe' textbox. You only need to do this once.

    General Tab

    vbAdvance General Tab

    The General Tab of the Advanced Options dialog contains general project settings:

    • Send Command-Line Args... - Use this setting to tell vbAdvance to send the command-line arguments that are set in the Project Properties dialog when you click the Execute button.
    • Dynamic Conditional Compile Arguments - Enter compile-time conditional compile argument overrides here. Your existing arguments will be displayed but are not editable here.

    IDE Settings Tab

    vbAdvance IDE Settings Tab

    The IDE Settings Tab of the Advanced Options dialog contains the advanced IDE settings:

    • Clear Immediate Window when project runs - This setting clears the Immediate Window automatically whenever you run your project in debug mode.
    • Detect when code modules are changed outside of the IDE - This setting enables VB to detect when any loaded code modules are changed by an outside process. When a change is detected, you will be notified and given the option to automatically reload the affected module(s).
    • Disable build dialogs - This setting eliminates the pair of dialogs that normally pop up when you build your project.

    Code Samples

    Console Applications Overview

    Console applications are Win32 executables that are run from the Windows Command Prompt. They receive input from, and send output to, the Command Prompt. An example is the net.exe utility. Type net into the Command Prompt and you will see an informational message written to the same Command Prompt by this utility.

    How does a Console application differ from any other Windows application? All 32-bit Windows applications contain a piece of information that identifies them as being of a certain sub-type. This sub-type is referred to as the subsystem, and it tells Windows how to run the application. The following subsystems are available in Win32:

    • CONSOLE - Tells Windows to launch the app within a Command Prompt.
    • WINDOWS - Tells Windows that the app will provide it's own windows.
    • NATIVE - For native mode apps, such as device drivers. Not possible with VB.
    • POSIX - For POSIX compliant applications. Not possible with VB.
    • WINDOWSCE - Tells Windows it is a Windows CE application. You use a tool like eMbedded VB, or the .Net Compact Framework to build this type of application.

    Of the 5 subsystem types listed above, only the first two are of interest to VB 5 and 6 developers, and of those two, only the WINDOWS subsystem type is available when you compile your application. VB does not offer you the option of setting the subsystem - it always sets it to be WINDOWS. If you want to build a Console application, you must find a way to set the application's subsystem to CONSOLE.

    You can change the subsystem of your application after your EXE has been built by using the VB linker with the following syntax:

    link.exe /edit /subsystem:console appname.exe

    Where appname.exe is the name of your application.

    This approach works fine, but it requires the additional step after you've built your EXE, which is, at best, bothersome. It would be nice if VB would simply give you the option to build your EXE as a CONSOLE subsytem app in the first place. After all, the ability to do so is clearly built in to the VB linker, as we've demonstrated above. vbAdvance gives you this missing option. Simply check the "Build As Console Application" check box and VB will build your EXE with the subsystem already set to CONSOLE, so there is no post-build step required.

    The other half of the puzzle of how to build a Console app in VB is how to interact with the Command Prompt. How do you receive input, and how do you send output? Not only did Microsoft not provide the option to build a CONSOLE subsystem application, they also did not provide any language syntax for interacting with a Command Prompt. Fortunately, they did provide a way to call Win32 API functions, and this is where we turn for the answer.

    The ReadFile and WriteFile APIs have the ability to read from STDIN (the input pipe that receives text typed or otherwise input into the Command Prompt) and STDOUT (the output pipe that sends text to the Command Prompt).

    The Simple and Advanced Console samples demonstrate how to use these, and more, APIs to provide anything from very simple text output capability, to full-featured Command Prompt interaction and control.

    Another option is to use the Microsoft Scripting Runtime DLL (scrrun.dll). The FileSystemObject in this DLL allows you to access STDIN and STDOUT. We can't recommend this approach due to problems with the Scripting Runtime DLL, but we wanted to mention it for the sake of completeness.

    Simple Console Sample

    This example demonstrates how to build a Console application which simply outputs text to the Command Prompt. This demonstrates just about the bare minimum amount of code required to write to the Command Prompt.

    Two API calls are used:


    GetStdHandle is used to get a handle to STDOUT, which we then pass to WriteFile, along with the text we want sent. A single helper function is used to wrap the API calls.

    Compile the project and run the "Simple Console Example.exe" from a Command Prompt. You will see the text "Hello world!" output to the screen.

    Advanced Console Samples

    These examples demonstrate how to build full-featured console applications in VB and are courtesy of Karl E. Peterson( www.mvps.org/vb ). Karl's MConsole.bas module is a remarkable console-support module for VB, and contains everything you need to build full-featured, robust console applications in VB.

    To see just how powerful this module is, run each of the sample applications:

    ConDemo1.exe (Interactive.vbp)
    Either run this from the command line or better yet from the IDE to see an example of how to build an interactive console application.

    ConDemo2.exe (PipedInput.vbp)
    Run this from the command line like so:

    C:\Program Files\vbAdvance\Samples\Console Applications\Advanced\>dir | ConDemo2.exe

    -- or --

    C:\Program Files\vbAdvance\Samples\Console Applications\Advanced\>ConDemo2.exe < temp.txt

    Either approach will copy whatever is piped into the app to the clipboard. This demonstrates how this console module provides support for piped input.

    ConDemo3.exe (ExitCode.vbp)
    Run this from the command line like so:

    C:\Program Files\vbAdvance\Samples\Console Applications\Advanced\>retval ConDemo3.exe 55

    This demonstrates how the console support module provides support for error return values to your console application.

    Note that the DebugOutput method in these samples not only prints to the Immediate window in the IDE, but also to the system debug stream, which can be monitored with either of the following tools:



    Exports Overview


    Generally speaking, there are two types of DLLs in Windows. There are standard DLLs and COM DLLs. A standard DLL exposes all of it's functions through exports. A COM DLL exposes it's functions through a COM typelibrary interface (along with a few helper functions which are exported).

    VB allows you to call exported functions in a standard DLL (via a typelibrary or the Declare statement), but it doesn't allow you to create them yourself. VB only allows you to build COM DLLs.

    There are some cases where it is desirable to build a standard DLL, such as in the case of a Control Panel Applet. A Control Panel Applet by definition must export one function that conforms to a specific name and footprint. Using VB alone, there is no way to build a Control Panel Applet. Another example would be some application plug-in architectures which require your plug-in DLL to provide exported functions. Again, using VB alone, you would not be able to build this type of plug-in.

    When you have vbAdvance loaded, you gain the ability to specify function exports in your VB DLLs. Any Public methods you have in your project that are located in a BAS module can be exported in your DLL.

    Exporting functions in a VB DLL is not a trivial thing to do. You should not attempt this without fully understanding what is involved. The following text and accompanying sample projects attempt to explain the pitfalls and possibilities. Done properly, standard DLLs in VB are a reality and open up a new world of possibilities with Visual Basic.

    Caveats / Requirements

    VB apps are completely dependent on the VB runtime. The VB runtime 'engine' requires some initialization before it can be used. When you compile your app, VB is automatically adding code to your project to ensure the runtime is initialized when your app starts. When your DLL is called, this runtime initialization code runs and then your code runs, and all is well.

    However, what happens when you expose a new entrypoint into your DLL in the way of a function export? The VB compiler is not only not expecting this, it was never designed to handle the possibility in the first place. The result is that while you have a new exported function in your DLL, the VB compiler never creates the necessary runtime initialization code for that new entrypoint. If your export is called and the runtime has not been initialized, your DLL will GPF.

    So how do we get the VB runtime initialized? When you build your DLL, the VB compiler requires a Public Class in your project so that it can create a Public COM object interface for the DLL. It also adds the necessary runtime initialization startup code to the DLL, so that when this Public COM object is created, the runtime initialization code will run. All we have to do to initialize the VB runtime for our project, is to create this Public COM object once, and the internal runtime initialization code will run.

    Normally, you need to register a COM DLL so that an object within it can be created. However, this is not actually a requirement. You can create a COM object without the Registry and your vbAdvance installation contains a couple of support files that can be used to instantiate an object from your DLL without the need for the DLL to be registered.

    The export samples that are installed with vbAdvance demonstrate how to use the included support files to ensure that the VB runtime engine is initialized before your code executes. Once this requirement is met, writing standard DLLs in VB is easily achieved.

    You might be wondering how VB code can be used to initialize the runtime, when the runtime hasn't been initialized yet - kind of a chicken and egg dilemma. The answer is very carefully. There is very little code that will run without GPFs when the runtime has not yet been initialized. Do not attempt to modify the runtime initialization code unless you know exactly what you are doing, and likewise, do not attempt to run VB code without the runtime initialized without a full understanding of what will and will not work.

    It's important to understand too, that the VB runtime must be initialized on every thread that your VB code will run on. Typically, there is only one thread of execution, and initializing it the one time will suffice. However, depending on the calling process, it is possible that your exports will get called on different threads. You must ensure the runtime is available on each calling thread. Also understand that VB makes heavy use of Thread Local Storage, and so data set in one thread is not necessarily going to be available on another thread. vbAdvance will allow you to create your exports. It will not ensure that you use them wisely or correctly. Use this feature with care.

    If the intended caller of your DLL is another VB app, then you must understand how VB handles Strings in Declare statements. You have to realize that the String will be converted and no longer be available as a VB String. You can use a TypeLibrary to define the export in the caller instead of a Declare to get past this, but then the DLL will not unload until the calling process terminates. To get past that problem, you could use LoadLibrary / GetProcAddress and call the export dynamically, which requires some further reading that is beyond the scope of this help documentation. The VB Caller example demonstrates some of these interactions. Building a standard DLL in VB is probably more useful for non-VB callers than VB callers due to the odd way that VB does String conversion with the Declare statement.

    Exported functions cannot be debugged in-process as exports. You must debug the function as you would any other function in a BAS module. Alternatively, the OutputDebugString API can be used in conjunction with a good debug message viewer such as DebugView fromwww.sysinternals.com.Approaches

    There are a number of different approaches you can take with the exports feature, depending on what you want to accomplish. We break them down loosely here:

    • Standard DLL
    • COM DLL with custom DllRegisterServer and/or DllUnregisterServer routines.
    • Hybrid COM/Standard DLL

    Approach #1, Standard DLL -

    In this case, we are building a standard DLL, which will be called only via the functions it exports. An example of this is a Control Panel Applet. When building this type of DLL, it is easiest to use a DllMain function, which is made possible through vbAdvance. The DllMain function is an optional entry point into a DLL. If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions. What this means is that when your DLL is first loaded by a calling process, you will recieve notification through DllMain, and can call the runtime initialization support code that is included with vbAdvance, ensuring that your exports can be safely called with the knowledge that the VB runtime is already initialized and available to your VB code.

    Approach #2, COM DLL with custom DllRegisterServer and/or DllUnregisterServer routines.

    DllRegisterServer and DllUnregisterServer are two exports that are created by VB in all VB-authored DLLs. These exported functions contain the code that places all necessary entries into the Registry so that the COM objects within the DLL can be found. When you use a tool like regsvr32.exe to register and unregister your DLLs, it is actually calling these exports, which do the actual registration and unregistration. Until now, there has never been a way to run custom code from within these exports, which is a shame as there is the occasional need to do so. vbAdvance allows you to create your own DllRegisterServer and DllUnregisterServer function exports, and conveniently renames the VB-generated ones. You can then optionally write a complete implementation yourself, or simply call the renamed exports and add some of your own custom code to your exports. When you do this, it's important to realize that you cannot use a DllMain export and call the VB-generated registration exports. Using DllMain overrides the normal entrypoint for your DLL which the VB-generated registration code is dependent on. You can use DllMain if you intend to completely replace the VB-generated functionality. The sample included with the vbAdvance installation demonstrates how to do this without a DllMain export.

    Approach #3, Hybrid COM/Standard DLL

    In this case, you will be adding exports to a normal VB COM DLL. You will not be able to use a DllMain entrypoint. You must be certain that the VB runtime is initialized before any of the code in your exported functions is run. The easiest way to do this is to simply require that one of the COM objects in the DLL be called first. You could also provide an Init export and run the runtime initialization support code from there.

    Error Handling

    It's important to understand something about VB's error handling mechanism when dealing with exported functions. Do not expect VB to be able to communicate error information across the export or API boundary of your DLL. Your exports must exist in BAS modules, and VB uses an internal exception handling mechanism for propogating errors from BAS module methods up to their callers. VB rightly expects the caller of a BAS module method to be another module within the same project. Unfortunately, when you create an export, this is not the case. Do not raise errors or allow errors to be raised from your exported functions. You must trap all errors at your API boundary. It is up to you how you want to communicate error information to the caller. Just understand that the caller is not going to be able to handle the error that VB will raise.

    If your caller is another VB app, you might be tempted to use the VB error handling mechanism anyway. This will fail. However, it is possible to raise an error to a VB caller with a little extra work. The reason is that as a caller, VB is prepared to handle COM HRESULT exception information. If you correctly encode your error as an HRESULT, you can raise it to a VB caller, where it will be interpreted correctly.

    Further Reading

    For an in-depth view into how VB works, the pitfalls and workarounds for exports, multi-threading, error handling, calling function pointers, and much more, refer to the book "Advanced Visual Basic 6" by Matthew Curland. Not only is the text content worthwhile, but the tools that are included are also well worth the purchase price. This book is highly recommended.www.powervb.com

    Control Panel Applet

    Control Panel Applets Overview

    Control Panel Applets are standard Windows DLLs that are required to export a single function called CPlApplet. To be installed as a Control Panel, the DLL must be named with a .CPL extension and must be placed in the System/System32 folder.

    The details of the CPlApplet export are explained in MSDN.

    Creating Control Panel Applets Using Visual Basic

    To create a Control Panel in Visual Basic, you must create a DLL project and set up the CPlApplet export so that it calls your Form when the CPL_DBLCLICK message arrives. The sample code demonstrates what is needed in this routine. There is a small amount of helper code required to successfully provide this export in VB. The problem with providing this export from VB is that the export is called by a non-VB thread. Because of this, the VB runtime engine is not yet started and all but the simplest VB code will fail. The sample code demonstrates how to initialize the VB runtimes in order to be able to display your Form.

    This is the general flow of events when your Control Panel Applet is called:

    1. DllMain is called, and the VB runtime engine is initialized.
    2. CPlApplet is called repeatedly with a different message each time. One of these messages is CPL_INQUIRE, which tells you to return a number of resource IDs where the system can find the icon for the Control Panel, as well as the string name and description for the Control Panel. The other message of interest is CPL_DBLCLICK which tells us to display our dialog. At this point we display the Form modally.

    The CPlApplet export requires that a resource file be present to provide the messages and icon that the Control Panel will display.

    To set up your own Control Panel using the sample code as a template, simply change the following:

    1. Change the resource file resources accordingly. The Icon with ID 101 is displayed when the Control Panels window is open. The String with ID 101 is used as a tooltip and the String with ID 102 is used as the name of the Control Panel.
    2. Set up the FCPDialog form to your liking.

    Note that the system caches your Control Panel information, and so you may not see a change reflected if you change an icon or string resource. You may need to log off and back on to see your changes.

    Installing the sample Control Panel Applet

    To install a Control Panel Applet, be sure it has a .cpl extension instead of the .dll extension, and place it into the system folder. That's all that's required. To install the sample Control Panel Applet, simply build the project. It is already set to build in your system folder. Once it's built, open the Control Panels folder. You will see a new Control Panel called "Sample VB Control Panel". Hover your mouse pointer over it to see the tooltip. Launch the Control Panel and witness that the Form opens.

    Uninstalling the sample Control Panel Applet

    To uninstall a Control Panel Applet applet, simply delete it from the system folder. To uninstall the Sample VB Control Panel that you just created, delete the file named "vbcpsample.cpl" from the System or System32 folder (depending on which version of Windows you have).


    The DllRegisterServer sample demonstrates overriding/customizing of DllRegisterServer and DllUnregisterServer.

    To see the results of the sample code, register or unregister the DllRegisterServerSample.dll using regsvr32.exe (or equivalent tool) and witness that these exports have been customized with a standard VB message box, and that the functions return a success value.

    To customize DllRegisterServer, you must create your own Public DllRegisterServer function in a BAS module and export it through vbAdvance's Advanced Options dialog. When you build your DLL, vbAdvance renames the VB-generated DllRegisterServer export "RegisterDllServer", allowing your custom export to co-exist with the default export. If you want to take advantage of the VB-generated code, you simply call the RegisterDllServer export from your own DllRegisterServer export. The sample project demonstrates this technique.

    The accompanying example also demonstrates how to initialize the VB runtime without a DllMain entrypoint.

    Note that VB registers your DLL every time you compile it. It does so by running the code it normally places into the DllRegisterServer export. If you are testing locally, you will need to register your DLL manually to cause your custom code to run.

    Non-VB Called Export Example

    Typically, a standard DLL written in VB will be written for a non-VB caller, such as in the case of a Control Panel Applet. While the Control Panel sample already demonstrates that, this sample code is provided for those that want to see the actual interaction between a non-VB EXE and a VB standard DLL.

    The sample comes with an extremely simple EXE written in MS VC++. It demonstrates the basic interaction between a non-VB caller and a VB standard DLL.

    Simply run the C_App.exe executable and witness that the Form from within the VB DLL is shown.

    VB Called Export Example

    When a VB standard DLL is going to be called by a VB EXE, there are some issues to be aware of. Things like Strings won't pass as you might expect if you are using a Declare statement. Error propagation is not obvious. DllMain can't be used. The export feature really is most useful for non-VB callers, when there is no other option, such as with certain plug-ins and things like Control Panels.

    The sample code demonstrates a number of techniques for passing various data types. It uses a typelibrary instead of Declares. Step through the caller project in the IDE to see what is happening. As with all VB standard DLLs you will not be able to step through the DLL code in the IDE.

    Conditional Compile Sample

    The Conditional Compile sample application demonstrates the use of vbAdvance's Dynamic Conditional Compile Arguments. There is only one argument in the sample, which is IN_IDE. The value of this arg in the standard VB Project Properties dialog is 1. The value in the vbAdvance Advanced Options dialog is 0. This results in a value of 1 at design time and a value of 0 when running compiled.

    To test the sample, run the project from the IDE by pressing F5 and witness that the message box states "In IDE". Next, run the compiled EXE. Witness that the message box states "Compiled".

    Whatever values you have entered in the Compile Time Argument Overrides box are going to be used when the app is compiled. So you may have more or fewer arguments than you have at design time.

    Also, the Syntax Check feature will use the compile-time arguments when checking syntax.

    XP Themes / Manifest Sample

    The Windows XP user interface adds support for larger icons with greater color information. In addition, it allows for 'themes' where the overall look of all windows in the system can be changed simply by changing the visual theme. Unfortunately for Visual Basic developers, Microsoft did not bother to update VB to handle these new icons or themes. Some of the new XP icons cannot be used as a Form's icon property, which means you cannot use them as your application icon. The other problem is that the VB Resource Editor cannot handle the new XP Manifest resource type, and in order to support the new XP themes, you must distribute a seperate XML manifest file with your application. Not only is this a hassle, but there is a bug on Windows NT Server that prevents an application from starting when the application uses the seperate manifest file. (Microsoft KB article Q316625: "You Cannot Start a Program That Uses a Manifest File That Is Stored on a Windows NT 4.0 Server".

    The XP Theme sample application demonstrates just how easy it is to add support for Windows XP's new look by allowing you to specify your application icon without the need to use a Form's icon property (bypassing the problem with VB Forms and XP icons) as well as automatically compiling in the necessary XP Manifest resource, so that you don't need to trouble with a seperate XML file. Simply ticking a checkbox and selecting an icon file is all that's required to add XP Themes support to your VB app.

    Note that you will still need to add one line of code to your app's startup routine. In the XP Themes sample, this is found in Sub Main.

    More information on XP themes can be found at these links:

    Microsoft KB article Q309366: http://support.microsoft.com/default.aspx?scid=kb;en-us;309366

    vbAccelerator XP Visual Styles articles: http://www.vbaccelerator.com/home/VB/Code/Libraries/XP_Visual_Styles/index.asp

    Resource-Only DLL

    The Resource-Only DLL sample demonstrates the steps needed to be able to build resource-only DLLs in VB.

    To test the sample, open the "res-only dll" project and press the "Make Resource-Only DLL" button to build the DLL. Next, open and run the TestProject and witness that the resource is able to be loaded from the DLL.

    Command-line builds that generate resource-only DLLs are not provided by vbAdvance. The reason for this is that VB will try to compile the project - which is not what you want. Instead, all you need to do to build a resource-only DLL from the command line is to call the linker yourself like so:

    link.exe /noentry /dll /machine:i386 /out:project1.dll project1.res

    For the linker to be able to build the resource DLL, the resource file in your project must be converted to a linkable file. This is accomplished by a utility EXE called "cvtres.exe". This utility is not shipped with Visual Basic, and due to the fact that it is not redistributable, is not shipped with vbAdvance. Fortunately, it is not difficult to get a copy of this utility. If you have Visual C++ installed, then you already have a copy of cvtres.exe. If you don't have Visual C++, you can download a self-extracting archive from Microsoft. At the time of this writing, the file was available at the following location:


    The download link is also specified in Knowledge Base article Q187280.

    Once you have the cvtres.exe file installed, you need to specify the location of the file in the vbAdvance Advanced Options dialog, under the Resource DLL Tab. You need do this only once.

    Webmasters Note

    I attempted to contact Karl Peterson, Young Dynamic Software, and the webmaster of mvps.org, with no success.

    I have approved the posting of this content on the basis that the persons or entities listed appear to have no further interest in the content, as well as the copyrights appear to have not been updated since at least 2007 for the content, or 2011 for mvps.org.

    If any of the people or entities listed above have questions, comments or concerns with this post, please don't hesitate to use the contact form in the footer below to get ahold of me.

About the Author

has posted a total of 101 articles.

Comments On This Post

No comments on this post yet!

Do you have a thought relating to this post? You can post your comment here. If you have an unrelated question, you can use the Q&A section to ask it.

Or you can drop a note to the administrators if you're not sure where you should post.

Your IP address is:

Before you can post, you need to prove you are human. If you log in, this test goes away.

Code Links