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.
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