Visual Basic Sample Code


About this code

   A number of VB experts have been very generous in making sample code available on the Internet for VB6 and Win32 API functions, but some things are still poorly documented for VB. The samples here are for things that may be hard to find elsewhere. No particular claim is made for the quality of this code, and it is not backed up by the "reassurance" of any Microsoft awards, decorations, certifications, or other (possibly dubious) tokens of officiality. You use this code at your own risk.

The Visual Basic Landscape

   VB6 The code here is for VB, also known as VB6 or "VB Classic". VB6 and Visual Studio 6 were released in 1998 as a set of RAD (rapid application development) tools for writing compiled Windows software. To this day, VB6 still works, the IDE runs on Win10, and VB6 software is supported on virtually all running Windows computers without needing additional software installed. Anyone who has or gets a copy of the VB or Visual Studio 6 software can write VB software. VB is designed to be easy, especially in terms of setting up graphical window elements. But it's also capable of using Win32 API STDCALL functions and most any COM object. With extra work it can also use CDECL functions. There's very little that VB can't do on Windows.

   VB.Net These days, people often assume that VB means VB.Net, but VB.Net is very different. Released in 2000, the .Net system was designed for writing web services, as a Java competitor. Like Java, it requires a massive runtime library set and serves as a wrapper around Windows functions. .Net is popular for backend software on Windows servers, just as Java is popular server-side. Neither has ever been widely used for desktop software due to the bloat and relatively slow speed. There is no .Net code here.

   VB.Net has the advantage that it's been developed over the years to incorporate newer functionality. For example, the PNG code below would be unnecessary on VB.Net because PNG files can be handled in VB.Net as easily as JPG files can be handled in VB. So VB.Net can do more things easily. The disadvantages of VB.Net are that it's relatively slow, comes with gigantic dependencies, and exists in a large number of versions. That means that code you write today will run fine on the newest computers, but may not work on older computers. In some cases older computers will need a massive runtime installed, up to 1/2 GB of files. In other cases, an older system might not be able to run your software at all. By comparison, VB6 software can be made to run on Win98 to Win11. Most of the software here at JSWare will run on WinXP and later, with no extra files needed. And the programs are all 2.5 MB or less.

   twinBASIC twinBASIC is a more recent development that promises the ability to compile VB6 code to 64-bit. That's an attractive option, but in actuality, only Shell Extensions require 64-bit code on 64-bit systems. In other words, with VB6 you can write EXEs or ActiveX EXEs that run just fine on 64-bit Windows. But you can't write shell extensions like Explorer Bars or Property Sheet pages because those are in-process DLLs. 32-bit and 64-bit can't be combined in the same process.

   So, is twinBASIC a good option? As of this writing, twinBASIC is only a beta project and it's not just code. It's a breathtakingly expensive compiler that can only be rented, starting at $648US per year for an uncrippled version that can compile to 64-bit! Thus, twinBASIC probably makes no sense unless you happen to be making big money on your old VB6 software and want to fully update to 64-bit. There's no guarantee that twinBASIC will ever even be finished. There is no twinBASIC code here.

What is the Future of VB?

   The future direction of Windows is always uncertain. Also, Microsoft have increasingly been restricting the system and pushing developers toward WinRT/Metro apps, which are limited, sandboxed programs designed to look and act like cellphone apps. It's possible that at some point it won't be possible to install compiled software that can freely and fully use Windows functionality. Microsoft would like to rent "Windows as a service", charging for the use of software and not just for the software itself. But until that day comes, VB6 can be used to write just about any kind of program. And since VB is compiled to native code, it can run at about the same speed as a C++ program.


Index
Info-zip DLL
   Info-ZIP makes zip libraries that are provided to the public for free. This package contains a sample program that uses Info-ZIP's Zip32.dll to make zip files. The sample is fairly simple and includes only zip - no unzip. Zip32.dll provides numerous options when making a zip file but those options make the operation fairly complex and there's very little documentation available regarding how to code the options in VB. The main part of this sample is a module that provides a simple interface to Zip32.dll. If you just want basic zip functionality this will provide it, with an easy function that creates a zip file given a list of file names, the destination path and the desired compression level.

Download zip32.zip (17 KB)

Back to Index
Active Accessibility
   Active Accessibility is the system that Microsoft has developed to provide functions for handicapped people. In particular, it can be used in making screen readers for blind people. AA provides methods to find out what is currently onscreen, what item is selected, etc.

   Except for the function AccessibleObjectFromPoint, there is very little documentation dealing with the use of AA functions in VB. This sample includes example usage of AccessibleObjectFromEvent, AccessibleObjectFromWindow and AccessibleChildren functions. Included is a class that can list the main elements of a window by using the AccessibleChildren to go down partially through the window hierarchy of a given window. For example, it can list the title, caption, buttons and focussed button of a message box.

Download actac1.zip (25 KB)

There is also an ActiveX DLL available. jsShell.dll wraps the awkward AA API, allowing onscreen windows and window elements to be accessed as a simple object hierarchy. The DLL download also includes an extensive help file. (The original version of this DLL was jsAA.dll. jsShell.dll is a newer replacement that supports Windows Vista/7 and combines AA functionality with other related shell functionality.)

Back to Index
VB6 Setup1 Project (Package and Deployment Wizard)
   Setup1 is the executable that carries out VB installations when the Package and Deployment Wizard (PDW) is used. Setup1 is a VB project that can be found in the Wizards\PDWizard folder. Setup1 can be modified. In fact, the original project code includes a great deal of commenting for use in modifying the project.

The sample code here is a modified version of Setup1.exe. Seldom-used functionality has been stripped out (such as silent install and remote install options), some of the more convoluted code has been simplified, and the project has been streamlined to yield an executable of about 1/2 original size (120 KB). Functions have also been added to decorate windows with color gradients, to provide an EULA click-through window, and to provide an option to create a Desktop shortcut when installation is finished.
   These downloads are not intended to be used as-is, but the editing required to make a unique, professional installer, complete with custom GUI, logos and icons, is minimal.

Updated July, 2006:
• Updated to display a program icon and program size in the Windows XP Add/Remove applet.

• Improved documentation, including a step-by-step guide to making a customized PDW installer for any software program.

Download pdwstp1.zip (296 KB)

Back to Index
VB6 Setup1 Project #2 - The noSE Version
   This is a further rebuild of Setup1, the executable used by the PDW for VB6 setup. This is the "noSE" version. (no Setup.Exe). The Setup.exe functions have been added into the Setup1.exe code, so the total size of your setup can be reduced by a further 135 KB (in addition to the reduction of approximately 120 KB resulting from the weeding and cleanup of the original Setup1 code). And there is no ugly gray box flashing by at the beginning of setup. (That was caused by Setup.exe.)

   When the PDW was first created it was designed for use on Windows 95/98/NT4, where the VB6 runtime was not installed. Setup.exe was needed in that case to install the runtime and reboot. Today, virtually all PCs have the VB6 runtime installed, so setup.exe is unnecessary. At the same time, the PDW is showing its age in some respects. This rebuild of Setup1 provides the necessary updating and adds flexibility to easily create unique, professional installers with custom graphics - something that is difficult or impossible to do with most other installers.

   This rebuild of Setup1 also adds more new functions to update VB setups. In addition to adding an EULA clickthrough, graphical options, and new settings for an Add/Remove icon, this version of Setup1 also adds an option to install files to a subfolder of Application Data. And it adds options for Desktop and Quick Launch icons to the GUI.

   This Setup1 still uses the PDW. You just run the PDW and create a setup package as usual, then substitute your own custom version of Setup1.exe and make some minor changes to the package. The download includes the VB6 code project, a sample installation, and full directions.

   The GUI of this setup can be easily redesigned to create a custom setup for each individual software product. (A background gradient in any color combination is one option that is pre-coded.) To get an idea, see this picture of a basic sample setup. The pictured sample uses the background gradient option, but customizing this setup's GUI is as easy as customizing a VB form. As long as you don't change any control names on the forms you won't need to make any code changes.

UPDATE September, 2009: The basic project files have not been changed, but a compact class has been included (and updated) to provide permissions options during installation on Windows Vista/7. The class has functions to set all-user read/write permission for a given folder or Registry key. See the explanation file for further details.

Download PDWnoSE.zip (255 KB)

Back to Index
RichTextBox Functions
   This zip contains a sample project that demonstrates some of the RTB API functions. There are 11 EM_ functions used in a simple RTB program. Some of these are very easy to use. Others are tricky and hard to find sample code for. Some are included here because they're faster than the normal RTB control version of the function. Others are included because they're useful functions that have been left out of the RTB control. The functions used in this project:

EM_EXSETSEL - sets selected text range.
EM_FINDTEXT - direct version of RTB.Find.
EM_FINDWORDBREAK - finds word boundaries.
EM_GETFIRSTVISIBLELINE - returns number of top line showing.
EM_GETLINE - returns text string of 1 line.
EM_GETTEXTRANGE - returns text string from between two offsets.
EM_LINEINDEX - returns offset of 1st character in line.
EM_LINELENGTH - returns length of given line.
EM_LINESCROLL - scrolls the RTB.
EM_POSFROMCHAR - returns coordinates of a given character offset.
EM_REPLACESEL - replaces selected text.

Download RTB-EM.zip (21 KB)

Back to Index
ActiveX DLL Sample
   This is a sample project for a simple ActiveX DLL. It demonstrates how to provide public objects in a DLL, both creatable and not. It also demonstrates the use of GUI elements and the format used to provide public methods and properties.

Download dllsamp.zip (19.5 KB)

Back to Index
Email Sending UserControl
   This is a UserControl for sending email, HTML or not, with or without attachments. Oddly, it seems that no one has made available basic VB code to simply send email without dependencies on the Winsock OCX or worse (i.e. CDO, MAPI, Outlook, etc).

   The CTL module can be added to a project and adds only about 40 KB of code with no dependencies and no extra BAS modules. It requires only wsock32.dll, which seems to be pre-installed on all Windows versions, including Win95.

   This UserControl may need slight editing for your purposes. It handles all basic requirements for sending email, such as Winsock functions, SMTP server conversation, two forms of password submission(if required), email formatting, Base64 encoding, and the detailed MIME headers required for different data formats in email. Some extra options, such as CC mailing and proxy server settings, have not been coded.

Detailed explanation:

   Email is sent using SMTP (Simple Mail Transfer Protocol). SMTP itself is, indeed, simple. It is just a standardized text-based "conversation" between an SMTP server and a client that contacts that server. Unfortunately, the documentation for SMTP is not at all simple. The official standard is contained in what are known as "RFC" documents, which are long-winded expositions, unnecessarily abstruse and legalistic, and all but useless to anyone who reads them to glean information.

   This UserControl provides all the functionality to send email via SMTP, with no dependencies, but some kind of email account is still required. Email programs like Thunderbird, Eudora, Outlook Express, etc. work by formatting your email and carrying out the SMTP server conversation. They require that you provide the address of a valid SMTP server (typically something like "smtp.someisp.com") that will accept your email and send it along. Likewise, this UserControl is a replacement for the email program, not a replacement for the SMTP server.

   The download also includes a file explaining email layout. The text strings sent to the SMTP server as email header and content require very specific formatting, but no one should have to suffer slogging through the all-but-useless, official "RFC" documents in order to find that information. With that in mind, the included text file contains basic template layouts for four email variations: Plain text, with or without attachments; and HTML email, with or without embedded images.

Download smtpuc.zip (21 KB)

Back to Index
Email Sending UserControl - Version 2
   This download is similar to the one above. It started out as the same userControl. It has the same functionality to send email as plain text or HTML, with or without attachments, with no dependencies and no ActiveX controls used. And like the first version, it can also send an HTML webpage file as an email. (A convenient ability for creating custom e-greeting cards and the like, yet an ability that is simply not included in most email programs. One can send an HTML email with "wallpaper" and colored text in most email programs, but taking advantage of the full graphical range available with HTML is generally not possible.)

   This version adds some updated functionality. At the same time, it's also more limited than the first version. Updating the code has resulted in breaking compatibility with pre-XP. If you need to support Win98/2000/ME then use the original version above.

   This version adds two notable things:

1) Transparent support for both IPv4 and IPv6. As of this writing, IPv4 IP numbers have run out. On the other hand, XP does not support IPv6 by default, and many retail routers do not even support IPv6. It may be a long time before IPv6 email capability is needed. In any case, this update has it. As per Microsoft's recommendations, the function gethostbyname and the structure SOCKADDR have been replaced with getaddrinfo and the structure SOCKADDR_STORAGE. The newer method allows a host name to be resolved to either an IPv4 or IPv6 version, at the discretion of the querying party and/or the host server. And the SOCKADDR_STORAGE structure is backward compatible with the SOCKADDR structure, so that all basic winsock functions can remain the same. Functions like connect can just take a SOCKADDR_STORAGE parameter in place of the SOCKADDR parameter. That design is especially convenient given that IPv6 "numbers" are 16 bytes. With getaddrinfo there's no need to handle that value directly. It just gets passed around in the SOCKADDR_STORAGE structure.

2) The ability to look up MX records that hold host names for a domain's SMTP servers. This is not as exciting as it might seem. It would be nice to be able to always, dependably find an SMTP server IP given an email address, but that is simply not possible. There is a widespread misunderstanding about the role of MX records. (For explanation of server record types in general see here.) MX records hold a listing of SMTP host names for a domain. But those host names are generally not usable by email software. To understand that it's necessary to know about how the email transfer process works. There are 3 types of "agents" involved with SMTP:

MUA: Mail user agent (email programs)
MSA: Mail submission agent (the server like mail.somewhere.com that one contacts to send email)
MTA: Mail transfer agent (servers that transmit emails across the Internet, between servers)

   Email programs send through an MSA. MX records list the host names of MTAs. MTAs send email between servers, using their own authentication. An MTA that accepted email from an MUA would be an open relay -- accepting and forwarding any and all email -- and open relays have been phased out in the interest of security. In other words, in the vast majority of cases, an MTA contacted from a PC for the purpose of sending email will reject the connection.

   The entire SMTP system is surprisingly disorganized and willy nilly. There is no standard for the name of an MSA (mail.somewhere.com, smtp.somewhere.com, outgoing.somewhere.com, etc). There is no standard for the log-on name used. Port numbers can vary to some extent. And there is no method to query DNS records for an MSA host name. Mozilla maintains a database of MSA SMTP servers, but Mozilla does not offer their database for download. Even if they did, it is far too limited to be useful. Nevertheless, the ability to retrieve MX records can be useful in that it provides a way to at least find the true hosting domain for SMTP. In other words, ed@edsmith.com may have an SMTP server set up, accepting mail through mail.edsmith.com. But Ed might also have his email hosted through gmail, or some other free service, or through his hosting server, if he does not operate his own server. MX records identify the actual host server for SMTP email, and that can at least narrow down any attempt to find the relevant MSA host name.

Download smtpuc2.zip (34 KB)

Back to Index
Email Sending - Simplified source code and HTML email sender freeware
   The other two email code downloads here are intended to provide information for programmers. This download is similar, but it's a simplified version of the code and includes a compiled freeware program, HMailer, that can be used to send HTML email easily by anyone who knows their email settings. The main idea is to allow people to send true HTML email. That is, to email a webpage, with images, just as it appears. HMailer can be used to do things like sending greeting cards. If the recipient does not have HTML email enabled they will see a message explaining how to enable it.

   Most email programs can send HTML email of a sort, but don't allow access to the source code and have very limited ability to create webpages, mostly just offering custom fonts and colors. With HMailer you can create an HTML webpage by hand, or in any webpage editor software, then send that HTML file directly as an email. It won't cramp your creative style. HMailer will also take care of embedding any images that are part of the webpage. In other words, HMailer converts any webpage to an email and sends it. (Within reason. Most email programs these days will block external links. That's not a problem with embedded images. They're in the email. But you can't send an email with links to external images, javascript, etc. Security restrictions will block that.)

Download hmailer.zip (160 KB)

Back to Index
HTTP UserControl for File Download and IP UserControl for Hostname Resolution
   This download was formerly just the HTTP UserControl. It now contains two UCs. Between them they're basically what's inside of the jsHTTP.exe component on the scripts page.

1) UserControl for downloading files via HTTP. It uses Winsock1.1 (wsock32.dll) for functionality, making it compatible with all versions of Windows from Win95 up. The only dependency is the VB6 runtime. You don't need to bother with the Winsock OCX or check the installed version of IE. This UC is fairly basic. It starts Winsock, connects to a server, requests a file, and handles the download. Server response codes and redirect info. (if any) are also retrieved with the file, and there are functions to write text and binary files to disk after download.

2) UserControl for IP -> hostname resolution with a timeout option. The details are explained in the download. The long and the short of it is that gethostbyaddr locks up a process with no controllable timeout. WSAAsyncGetHostByAddr does the same thing without locking up the process, but has no controllable timeout option. WSACancelAsyncRequest is supposed to be able to cancel a call to WSAAsyncGetHostByAddr, enabling timeout functionality, but it doesn't work, is not recommended, and according to Microsoft, was never intended or expected to work! This code achieves a basic IP -> hostname function with a timeout option by using a UserControl with a Timer, a subclassed form, and a UC event, to make a call to WSAAsyncGetHostByAddr and ignore the result if it returns after the desired timeout has expired. (That is Microsoft's officially recommended method for achieving what WSACancelAsyncRequest is supposed to be able to do.)
   The IP -> hostname functionality was written for processing website server logs, with hundreds of IP addresses needing to be processed. The timeout is quite handy in that scenario. While gethostbyaddr seems to have a built-in timeout of about 30 seconds, 5 seconds seems to be an adequate time to wait for a nameserver response. So having the ability to select a 5 second timeout can greatly speed up processing of large server logs.

Download httpip.zip (25 KB)

Back to Index
ListBox UserControl - simple subclassing
   This is a ListBox UserControl that adds a few extra, useful functions to the common ListBox:
    • Add a horizontal scroll bar for wide items.
    • Specify color of text and background for each ListBox item.
    • Find given text among ListBox items.

Custom listbox    Included with this sample project is a discussion of UserControls for people who may not be familiar with them. In brief:

   The convenience of VB controls makes it fast and easy to set up a functional graphic interface but available controls do not always have the required functions built in, and the process of compiling them as external OCX files reduces their efficiency.

   A UserControl is just the code of an OCX before it is compiled. A UC can be compiled directly into your EXE. That makes it faster and easy to modify for each project, while maintaining the separation of code, the easy drag-and-drop placement in the VB IDE, and the convenient OCX wrapper properties such as Top, Left, Height, Width, hWnd, etc.

Download ListBox UC project - lboxuc.zip (14 KB)

Back to Index

Easily using multiple, subclassed "API-drawn" controls
   The downside of UserControls is in handling multiple subclassing functions when multiple UCs are used that require subclassing for their extra functionality. This ListBox UC, for example, requires subclassing to handle the drawing of differently colored ListBox items.

   Subclassing is generally awkward in VB. It is easy to crash a project running in the IDE with subclasses active. It also requires at least one hook, unhook and WindowProc function for each subclass. If that awkwardness could be avoided then numerous UserControls could easily be used in a project to encapsulate modified control behavior (like this ListBox sample) and also to enable the easy use of highly efficient API-drawn and owner-drawn windows.

   An "API-drawn" window is a control such as a ListBox, TextBox, TreeView, etc. that is created directly from the system DLLs using CreateWindowEx, as is typically done in C++. The API-drawn window is then handled using Windows API messaging to do things like add an item to a ListBox. VB controls and third-party OCXs take care of all that work, providing simple properties and methods like ListBox.Add that make it easy for VB programmers to use visual components. But the problem with using controls, especially anything that's not among the basic VB "intrinsic controls", is that they're relatively slow, limited and require shipping extra files with your program.
   They're slow because there is an extra call for every method. For example, if you want to search for a given string in a RichTextBox, you call the RTB OCX using the RTB.Find method. The RTB OCX then makes the API call to the actual RTB that it has created and finally returns the result to you.
   Controls are also often limited because you can only access the properties and methods that have been provided by the author of the OCX. Example: The VB ListBox does not provide access to a method that can search for a given string in the ListBox, even though the built-in Windows ListBox, which the VB ListBox is a wrapper for, does provide such a method (the LB_FINDSTRING message).

RichTextBox UserControl - API-drawn subclassing
   Creating API-drawn control windows on a UserControl has a dual advantage. On the one hand you get the efficiency and flexibility of using the built-in Windows components directly. On the other hand, you also have the convenient design-time properties provided by using a UserControl (a visible design-time object with width and height, etc.). The result is the ability to design and use customized, API-drawn windows as easily as if they were ActiveX controls. For example, you can use your own RichTextBox control, without needing to use the RTB OCX. Since your version would be drawing the RTB itself, and using direct API calls that don't need to be routed through an external RTB OCX, it will be significantly faster than the VB RTB control and you won't have to ship the RTB OCX.

...So then the big challenge is how to take advantage of these API-drawn windows without creating subclass spaghetti in order to do it....

   Matthew Curland outlined a "scalable" subclassing method in his book Advanced Visual Basic 6 (Addison Wesley publ.) that solved the problem of handling multiple subclass procedures by sending the subclass WindowProc pointer back inside the UserControl during the initial subclass function, with the result that all of your UCs can subclass themselves internally. Unfortunately, Matthew Curland's methods are not compatible with the newer DEP restrictions on WinXP and later. But there is another option. The project here is a RichTextBox, API-drawn on a userControl. It uses RichEdit v. 2/3, not requiring the VB RTB OCX. The RTB UC essentially subclasses itself, meaning that any number of these controls can be used easily. The original code that makes this possible is here:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=68737&lngWId=1
The code has been generously made available without limitations by its authors. It provides a way to subclass multiple controls/UCs/forms in a VB IDE-friendly manner and without causing DEP conflicts.

   This RichTextBox userControl uses a simplified, compact version of the code linked above, using a single class that can be added to any project. All subclassed controls then subclass themselves via that one class. Each can have one or more WindowProc functions that receives the messages you choose, before and/or after those messages are sent on to the original WindowProc (or not). So this sample may be of interest as a fast, flexible, dependency-free RichTextBox control, and/or as a template for easy, multiple subclassing.

Update 6/2018: Adds a few minor things like text zoom and line height options. Update 4/2016: The RichEdit window sample now includes a file with directions for using RichEdit v. 4.1. RE4.1 is unicode-only, but that is reasonably easy to adapt to. A big advantage, in addition to being an updated RichEdit window, is that RE4.1 supports UTF-8 text.

Download rtbuc.zip (37 KB)

Back to Index
GlowButton UserControl - more self-subclassing
   This is a self-subclassing UserControl that uses the same subclassing code from Paul Caton and others that is linked to above. This control is a very simple, basic button. It uses an Image control and two Shapes. By setting the shapes to have a transparent background, then adjusting their FillColor and DrawMode, the button appearance can be altered to display as disabled -- or to "glow" when the mouse hovers over it -- by showing or hiding the Shapes. The UserControl subclasses itself to track "MouseLeave" for the hover-glow effect. Since it's composed of a UserControl, Image and 2 shapes, there's only 1 window handle involved.

   This button shows easy self-subclassing of UserControls, but it's mainly directed toward people with a graphical bent. The button is whatever you want it to be. The picture in the Image control is the button. A few sample pictures/buttons are included to provide an idea of what might be done. Any image can be used, and different buttons can be created by just altering the text on the image. ("OK", "Close", "Browse", etc.) The text could be drawn dynamically, but that option has not been coded into this sample button.

Download glowbut.zip (28 KB)

Back to Index
Webmaster's Raw Log Host Name Converter
   This is a simple program for webmasters who like to read and/or process their "raw" server logs. It is listed on this page because it's a technical utility, not of interest to most people, and because it has only been minimally developed but source code is included.

   The download includes a VB6 project and a compiled EXE. The EXE can be used as-is to process raw server logs. It will convert all IP addresses in your logs to more readable host names, where possible. For example, where a log line begins with:
    100.100.100.100 - [15/Mar/2005:00:11:12 -0500]...
             ... "GET /jsware/boss.html HTTP/1.0" 200 1118....
the program will find the host name and replace the IP address, resulting in something more readable and informative, like:
    server1.acmeaccounting.com - [15/Mar/2005:00:11:12 -0500]...
            ... "GET /jsware/boss.html HTTP/1.0" 200 1118....
The program then writes a new log file incorporating the IP/host name translations. In some cases, depending on the layout of your raw logs, the program source code may need to be edited and recompiled before use. The download includes an info. file with further explanation.

The Host Name Converter program has had an update that adds location information. Whereas the earlier version would convert something like 100.100.100.100 to something like server.acme.com, with location information it will now read something like server.acme.com•Dayton-OH-US. The new location data functionality is provided by the free GeoLite database and COM DLL provided by MaxMind at http://www.maxmind.com/app/geolitecity. It works extremely well, recognizing and resolving nearly all IP addresses.

Download logpack.zip (95 KB)

Back to Index
RSS ActiveX Control
   This is an OCX that has functionality to process RSS files. The "Roll Your Own StartPage" utility includes a component for partial processing of RSS, but this control is more flexible. It can download files, write downloaded files to disk, and return a downloaded RSS file as an RSSFile object, which provides structured object model access to the RSS elements.

   This download includes a compiled OCX control , ready for use, which does not require any VB experience. It also includes source code for the control.

   This control has had limited testing. Please feel free to email with questions, reports, etc.

Download jsrss.zip (52 KB)

Back to Index
Type Library Reader / Object Browser
   The object browser in VB and in MS Word provides a view into type libraries - binary documentation of COM objects. The file TLBINF32.DLL provides that functionality and is redistributable. TLBINF32.DLL wraps the functionality in OLEAUT32.DLL that provides the ability to read type libraries. TLBINF32.DLL can be used by VB programmers who want to build their own object browser or otherwise read type libraries. But it's actually probably easier to use OLEAUT32.DLL directly than it is to use TLBINF32.DLL. (And it also avoids needing to ship a 150 KB file that's incompatible with the VB5 version.) As is so often the case, writing the code is not nearly so difficult as is finding thorough, accurate documentation.

   The code here includes a sample program and a single, compact class that reads typelibs and extracts the information into orderly data structures. (This is essentially the same code used in the Typelib reader ActiveX DLL on the VBScript samples page.) This code is designed for use in an object browser or for object interface research. In other words, it extracts information and organizes it in accord with what's relevant for an object browser, as opposed to just reading all typelib data and "dumping" it as a list of interfaces like Microsoft's OLEView.exe Type Library browser does.

   The updated version includes more thorough explanation of how the code works, and also adds functionality to list early-bound interfaces. (The vast majority of COM interfaces are dual, but there are a few cases where an early bound interface is present without a dispatch interface. Those were not listed in the first version of this code.)

Download tlbread.zip (25 KB)

Back to Index
CAB Files - Creation, Extraction, Information
   Creating and unpacking CAB files is often useful from VB, but VB is not capable of using the system file, cabinet.dll, that provides the functionality. So people are left to paste together hokey command-line alternatives, using makecab.exe, cabarc.exe, etc.

   If you look online for VB code you will find several examples that use SetupIterateCabinet, from setupapi.dll, for extracting from CAB files. One example is a project named Cab Explorer. There was also an in-depth article detailing the use of SetupIterateCabinet in the November, 2000 issue of VBPJ, by one Ken Getz. But SetupIterateCabinet doesn't really work! And none of the available code or articles bothers to mention that. SetupIterateCabinet can extract only from CAB files compressed using the MSZIP format. It fails if the CAB was compressed with the LZX or QUANTUM method. And LZX compression is actually fairly common.

   Other operations, like listing files in a CAB, can be done by directly parsing the CAB file header. So learning about the setupapi.dll functions is probably a waste of time.

   Using the CAB API in cabinet.dll is awkward from VB because the functions all use CDECL calling convention, and VB cannot normally call CDECL functions. The first solution offered here was to provide C++ code. But since then we have also written an all-VB version. Altogether there are 3 different options here:

1) C++ DLL code - This is code for a very simple C++ DLL, made in VC6. It provides the basic functionality needed to extract from and create CAB files programmatically using cabinet.dll. This download includes a .CPP, .H and .DEF file. In combination with the LIB and header files from the Microsoft CAB SDK it provides everything needed to build your own DLL for use from VB.

Download vbcab.zip (9 KB)

2) VB CAB code - This is straight VB code providing access to cabinet.dll FDI (extraction) and FCI (creation) functions. Many thanks to Paul Caton, who wrote a simple and easy class that enables VB to call CDECL functions. This download also provides a good selection of template code for calling various CDECL functions. Cabinet.dll has some of the most complex functions in the entire Win32 API. One function has 13 parameters, 10 of which are addresses of callback functions! But Paul Caton's class works flawlessly, even with that kind of complexity.
   The code here involves 1 class that enables CDECL calling, and 3 .bas modules for the CAB operations. It's not compact because cabinet.dll is designed in such a way that it uses callback functions to do most of it's work. So cabinet.dll is small but calling code must be extensive. Nevertheless, this is a full-featured CAB API wrapper in pure VB.

Download vbcab2.zip (20 KB)

3) ActiveX DLL for scripting - This is a component designed for use with VBScript, but it can also be used from VB or any other COM-compatible language. It wraps the CAB functions in a convenient package. (But note that since this is a COM DLL, it must be registered before use.)

Go to jsCAB download on the VBScripts page.

Back to Index
Easily Create a Standard Windows DLL in VB
   It is generally said that a "standard" DLL with exported functions cannot be made in VB. In fact, it only requires a simple process of hooking into the linker command line at compile time, in order to tell VB to add extra functions to the export table.

   Thank you to Ron Petrusha for this. Although creating a standard DLL (or controlling the compiler switches generally) turns out to be an extremely simple task, it is not at all an obvious one.

Download vbdll1.zip (22 KB)

Back to Index
Shell Operations - Explorer Folders
   This is an interesting collection of methods to access open Explorer folders and return such things as a list of currently selected items. The sample code uses the Shell object and Active Accessibility to access open folder windows. There are actually three separate methods used here to get a folder's items, selected items, focused item, etc. Each method is more funky than the last. But they work!

   1) The first method is used on pre-XP systems, where a folder window view is actually a webpage in an IE browser window. It provides access to the actual Document object, the ShellFolderView, and the Shell's Folder object for any open folder. The way it does that is to use ObjectFromLresult (in oleacc.dll) to get the true Document object from a folder window's embedded IE browser window. It then accesses the DOM to get the ShellFolderView from the Document, which is an ActiveX control on the folder.htt webpage that represents a folder view.

   2) The second method is used on XP because XP has a fake Web View. XP folder windows have been returned to the plain Win95-style ListView window. There is no IE window, no webpage, and thus no actual Document object for XP folder views. With no Document object the first method can't be used. But Microsoft seems to have emulated the basic Web View objects in XP for compatibility, so the ShellFolderView and Folder objects are still available. In the second method, a QueryInterface for the ShellFolderView is called on the Document property of the pseudo-IE instance returned from the Shell.Windows collection. Raymond Chen, an official Microsoft "blogger", actually showed how to do something like this with some very involved C++ code. But it turns out that most of his code is unnecessary. The method is actually quite simple (aside from the fact that it takes a little work to get at IUnknown in VB).

   3) The third method, which should never normally be necessary but was added for thoroughness, uses Active Accessibility (oleacc.dll). It doesn't return the ShellFolderView or Folder objects, but it still returns a list of items and selected items in a folder. So all three methods will return the currently selected items in an open folder.

   This code also shows how to return a true Document object from a running instance of IE, and that method can be easily adapted to also return the Document object from a running HTA. In fact, a Document object can be returned from any process that has a child window titled "Internet Explorer_Server", which is the actual browser window. That includes IE, HTAs, folder windows in Windows versions with WebView (Win95-2000), and even Outlook Express when an HTML email is being viewed.

Download shellop.zip (14 KB)

Back to Index
Windows Installer (MSI)
   This is not VB6 code but rather VBScript that uses the Windows Installer automation interface to make an MSI Utility. It's listed here because it might be useful to people wanting to author MSI packages, or to those who want to know more about how MSI packages work. For more details, see the MSI Utilities page.

Back to Index
ZLib.dll Ops
   ZLib.dll is a free library for compression operations. A Windows version using STDCALL functions is available as zlibwapi.dll. The documentation is limited and can be confusing, while most Windows sample code consists only of using the functions compress and uncompress to handle byte arrays or strings. By itself, that has limited usefulness.

   The original code here uses compress2, uncompress, gzopen, gzclose, gzread and gzwrite. It demonstrates creating and extracting from .gz files, and decompressing streams such as the content of compressed Flash files. Methods are included to save and retrieve the file name and last-modified-time of stored files in the .gz header. (Zlib.dll handles the compression/decompression but does not handle the file header operations.)

   The newer code (9/13) is a compact .bas module that uses inflateInit2, inflate and inflateEnd to decompress byte streams from Web servers. Many servers will transfer files that have been gzip-compressed if the client can handle it. (Accept-encoding and content-encoding header parameters are used to establish that.) Whole files are converted to a gzip stream. The sample code here consists of a simple function to decompress such a stream.
   The use of inflateInit2, inflate and inflateEnd is actually very simple, but most code samples available online are wrong, for one simple reason: The author of the Windows version of zlib.dll (zlibwapi.dll) changed the functions without documenting them. The zlibwapi versions do not even have the same number of parameters! Most available samples are using the documented methods for zlib.dll with zlibwapi.dll, so they fail. Once one knows the changes in declaration and usage, inflateInit2, inflate and inflateEnd are easy and dependable.

Download zlibops.zip (56 KB)

Back to Index
NTFS Permissions/Restrictions - Getting and Setting
   This is the same sample project included with the PDW "no SE" download above. There is a simple, concise class for getting and setting permissions settings related to files, folders and Registry keys, for the Current User, Administrators group, or Users group. The class uses a language-independent method that provides the means to easily check permission details, to set full permissions for any user or group, and to revoke previously set permissions.

   If you've looked into the permissions API you will know that there are lots of methods, using various API functions, in very obscure and complex operations. Just the sheer number of acronyms used can be quite intimidating. And one code sample to set permissions might be 4 times more verbose than another sample, and use entirely different API functions! The code here is designed to be a distillation/simplification of that API mess, demonstrating a fairly simple system for handling permissions.

Download ntperms.zip (15 KB)

Back to Index
NTFS Restrictions - Part 2
   The NTFS code above is aimed specifically at setting full access on one's own program folder and/or Registry keys during program installation. That's a relatively simple job because the items are created by oneself. This code is for removing all restrictions, on all file system items, on all NT systems.

   Microsoft actually makes tools available for removing file system restrictions, but they don't make it easy. Their two programs Takeown and CACLS (only available as command-line versions), when used together, are claimed to allow system administrators to change permissions at command line, while being too obscure and tedious to be used by anyone else. When it comes to the Windows API, Microsoft seems to have taken a similar approach of security through abstruseness: The API is too discombobulated and tedious for most people to bother wrestling with it.

   The code here is especially designed to deal with the problems on Windows Vista/7, which is so hobbled by restrictions that even Administrators have very little control over the system. As noted, the API for handling these restrictions is convoluted, confusing and overproduced. It can require a dozen or more pointless API calls just to give yourself the control required to give yourself control over a file or folder. On the bright side, it is at least possible for an Administrator to give all Administrators the control that they should have had all along. The process is so ridiculous as to be comical. And it's ugly. But it does work. And the code here, despite the circuitous route required, is probably the simplest, most direct way to remove restrictions on Windows file system items.

   How it works: The operation works by calling OpenProcessToken on the current process, then calling AdjustTokenPrivileges to get the SeTakeOwnershipPrivilege privilege, which allows one to change ownership of a file system item. With privilege in hand, it walks through obscure API muck to prepare to call SetFileSecurity, which is then used to give oneself ownership of a folder or file. Finally it walks through more API muck to give back the borrowed privilege. At that point the currently logged on Administrator owns the object and can proceed to grant full access authority to all Administrators -- which involves an additional pile of unnecessarily complex API muck, including calls to GetNamedSecurityInfo, AllocateAndInitializeSid, LookupAccountSid, BuildExplicitAccessWithName and SetNamedSecurityInfo. (Note that while restrictions can be removed from anything for all Administrators, this method will fail in some cases if one tries to remove restrictions for all users.)

   The whole process is analogous to owning a house, but not being allowed to enter your house. But then you discover that if you file some very complex and very official paperwork you can grant yourself authority to be yourself and to enter your own house at will. So you do that. First you file the official paperwork that authorizes you to file very official paperwork. Then you file the very official paperwork that allows you to officially declare that you yourself are none other than you yourself. Then you file the official paperwork that authorizes you to stop filing very official paperwork. Then, with the authority-to-be-you that you've attained via paperwork filing, you officially declare that you yourself are allowed to enter the house owned by you yourself. (Which involves more very official paperwork, but at least by this point you have a pre-existing authority to file such paperwork without first filing for official authorization.) At that point, finally, you can enter your own house... for a well deserved rest.

   The class here represents all of the paperwork, so to speak, wrapped into a convenient package. There are 2 simple functions that remove all restrictions on a file or folder, recursively for folders if desired. There are no functions to add restrictions. That functionality may be feasible with minor code edits.

Download ntperms2.zip (13 KB)

Back to Index
PNG Files - Read, draw, convert to BMP
   This is a single class that incorporates everything needed to display PNG files with straight VB. Much of the code here was written by others. (See the credits in the download.) But this may be the first version that can actually display all PNG formats properly. Functions include getting info./comments from a PNG file, drawing the image to a specified device context, and saving the image to a BMP file.

Download vbpng.zip (20 KB)

Back to Index
Mime Filter for Internet Explorer
Note that MIME filters are no longer feasible in Internet Explorer. This code has been left here as a curiosity.

   A Mime Filter is an unusual and interesting, but generally unknown, component. As part of Microsoft's plan in designing Internet Explorer primarily for corporate use, Microsoft created two options for controlling the content of the IE browser window programmatically -- the mime filter and the protocol handler. The idea was to allow corporate IT people to control what employees can access. A mime filter can also be used for something like parental control software, to filter adult content from webpages. A mime filter is not Document Object Model scripting. This is total control over the content of webpages that IE receives. The mime filter option is just one of the many reasons why IE is not safe to use. But a mime filter can be put to good use.

   The code here was written as part of a project to help blind people in particular, and anyone stuck using IE in general. The details are explained in the download. The project involves providing filtering options for webpages, so that any page in IE can have anything removed, on a per-domain basis: Images, script, iframes, etc. can be removed from the page. Elements can be removed on the basis of their CSS ID or ClassName. Etc.

   The gist of how this all works is as follows: One can write a protocol handler or a mime filter plugin for IE. A protocol handler deals with getting a requested file through a specific protocol, such as http:, file:, res:, etc. A mime filter is a middleman. It receives all files of a specified content-type (such as text/html) from the designated protocol handler. The default protocol handler is urlmon.dll, but that can be replaced. Both a protocol handler and a mime filter have total control over what reaches IE. The protocol handler gets the content from the server. The mime filter acts as a middleman to pass the content on to IE. Both can change/edit the content in any way desired.

   While these components are poorly documented and little-known, a mime filter is not actually difficult to set up. Once installed, a mime filter gets access to webpages (or other chosen content-type files) in the form of a byte stream handed off by the protocol handler. The filter can then remove risky items like script, remove ads, simplify the page layout to help the job of screenreaders for the blind, etc. The filter can decide what the webpage is, before IE loads the page, which can allow for detailed customizing and security improvements. (Anyone who knows about the NoScript extension for Firefox, or who has used the Firefox userContent.css file to customize webpages in Firefox, can understand that a mime filter provides possibilities far beyond the available Firefox tweaks.)

Download mimeflt.zip (19 KB)

Back to Index
Extracting JPG Thumbnails and Using Turbojpeg.dll
This package has two projects in it:

1) A small class that parses JPG headers very quickly at the level of binary data, providing the ability to extract thumbnails from JPG files that have them (which is most images from cameras). Functions include painting the thumbnail to a picturebox and providing the thumbnail file byte stream, which can be easily written to disk.

2) A project built around turbojpeg.dll, which is a compact, open source library for JPG operations. Turbojpeg.dll decompresses JPG files, given the file byte stream, and returns decompressed RGB data as an array. The code here shows how to get resized, high quality images from turbojpeg.dll very quickly, which can then be used to create thumbnails. The code here is useful for both creating thumbnails and for general down-sizing. Functions include options to save the resized image to disk or paint it onto a DC.

Notes: The vast majority of embedded JPG thumbnails are themselves small JPG files. In rare cases they may be stored as uncompressed RGB data. There are also two more uncompressed formats possible, occurring as YCbCr and grayscale, respectively. This code can extract JPGs. It can also extract RGB data and build a BMP file from it. The other two formats are not dealt with, mainly because they seem to be all but nonexistent.

Acknowledgements: Thank you to Paul Caton for his flawless CDECL code. (VB cannot normally call CDECL functions and turbojpeg.dll uses CDECL.) Also, thank you to Peter Scale for his efficient and compact resampling code, which allows for straight-VB replacements of StretchBlt and GDI+ resizing, which both seem to be undependable when dealing with large images. The bilinear and "nearest neighbor" resizing routines here are based on code from Peter Scale's sample program at Planetsourcecode.com, which is well worth downloading.

Download jpgops.zip (198 KB)

Back to Index
Explorer Bar (jsFolderView code project)
   This is the code for the jsFolderView+ Explorer Bar shell extension. Included is a BHO for loading the Bar, as well as an installer and uninstaller. VB6 can only create 32-bit DLLs and Windows 64 uses 64-bit Explorer, so this Explorer Bar won't install on newer systems because a shell extension runs "in process" with Explorer. There may also be limitations in Windows 10+, due to Internet Explorer being removed. Nevertheless, this code might be of some value to anyone who wants to create an Explorer bar for older 32-bit systems, or anyone who wants to build a 64-bit shell extension for later Windows versions and needs guidance with the COM interfaces used.

Download JSFVcode.zip (721 KB)

Back to Index