Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1449

Standard DLL Creation (and Usage) with VB6 (à la, The Trick)

$
0
0
Let me say from the outset that it's The Trick who sorted the magic of doing this, and who seems to know all the compiled VB6 headers better than the back of his hand. He's done some work that allows us to create standard DLLs with pure VB6, and then subsequently use them with "Declare ..." API declarations (similar to the way we'd use the kernel32.dll, shell32.dll, msvbvm60.dll, or any other standard DLL). No AddIns, no dependencies (other than a TypeLib used just while compiling the DLL).

First, to use these standard DLLs, we must recognize that our VB6 program must be able to find them. This is typically done by searching our own folder (either the folder where our VBP is, or our compiled EXE is), or, if not found there, searching the environment path. Typically, we don't worry about this, as it's all automatic. But, when we start creating our own standard DLLs, we do have to make sure our program that uses them can find them.

Ok, I'm going to outline the steps to create a standard DLL with VB6, and then I'll go into more detail for those steps that aren't straightforward:

The Steps:
  1. Download the attached MyStandardDll.zip file, and unzip it somewhere. It has five files: MyStandardDll.vbp, VBDll.tlb, MyDllFunctions.bas, DllInitialize.bas, & VBDll.idl. The VBDll.idl isn't really needed, as it's the source code for the VBDll.tlb. And also, the VBDll.tlb is no longer needed once our standard DLL is compiled.
  2. Open the MyStandardDll.vbp in the VB6 IDE.
  3. Open the MyDllFunctions.bas file for editing.
  4. Write/create whatever functions you want in your DLL, making sure they're Public. You can have other Private ones for support if you so choose.
  5. Make a note (using Notepad) of the names of all your Public DLL functions.
  6. Close the MyStandardDll.vbp project (without compiling). If you like, you can execute it in the IDE, but it will immediately terminate, as it has an empty Sub Main (necessary for the VB6 compiler, when we get to that). But, executing it in the IDE is a good way to check for syntax errors.
  7. Open the MyStandardDll.vbp project using Notepad.
  8. Down at the bottom, you'll see a line starting with "LinkSwitches". In this line, make sure there's an -EXPORT argument for each of your Public DLL functions.
  9. Save and close MyStandardDll.vbp from Notepad.
  10. Re-open MyStandardDll.vbp with the VB6 IDE.
  11. Compile it as a standard EXE to MyStandardDll.exe.
  12. Close MyStandardDll.vbp in the VB6 IDE. We're done with this source code.
  13. Rename the new MyStandardDll.exe to MyStandardDll.DLL. You can also rename the core name to anything you like, recognizing that this will affect how the "Declare..." statements reference it.
  14. If we'll only be using our new standard DLL from other VB6 programs, we can delete the LIB & EXP files, as they won't be needed. If we'll be using our new DLL from C/C++, we may want to save them.

At this point, you are done creating your standard DLL.

Also attached is a ExampleUsingMyStandardDll.zip file. It just includes two files: ExampleUsingMyStandardDll.vbp & ExampleUsingMyStandardDll.bas. If you download and unzip these two files into the same folder as your compiled DLL, you can execute this example project directly in your VB6 IDE, and use your new DLL just like you use other standard DLLs. If you just use the MyStandardDll.DLL (created from the above steps) as it is (not expanding on it), it will immediately work.

Here's the "default" code in that MyDllFunctions.bas module:
Code:


Option Explicit

Private Declare Function MessageBoxTimeOut Lib "user32" Alias "MessageBoxTimeoutA" (ByVal hWnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal uType As VbMsgBoxStyle, ByVal wLanguageId As Long, ByVal dwMilliseconds As Long) As Long


' ***********************************************************************************
'
' Here is where we put our public functions that will be exposed in our standard DLL.
'
' ***********************************************************************************

'
' Two example functions.

Public Function ShowMsgBoxFor3Seconds(ByVal sText As String) As VbMsgBoxResult
    MessageBoxTimeOut 0, sText, "", vbInformation + vbOKOnly, 0&, 3000&
    ShowMsgBoxFor3Seconds = vbOK
End Function

Public Function ShowMsgBoxWithTimer(ByVal sText As String, ByVal iMilliseconds As Long) As VbMsgBoxResult
    MessageBoxTimeOut 0, sText, "", vbInformation + vbOKOnly, 0&, iMilliseconds
    ShowMsgBoxWithTimer = vbOK
End Function

And here's the code in that ExampleUsingMyStandardDll.bas module:

Code:


Option Explicit

Public Declare Function ShowMsgBoxFor3Seconds Lib "MyStandardDll" (ByVal bstrMsg As Long) As VbMsgBoxResult
Public Declare Function ShowMsgBoxWithTimer Lib "MyStandardDll" (ByVal bstrMsg As Long, ByVal iMilliseconds As Long) As VbMsgBoxResult


Sub Main()

    ShowMsgBoxFor3Seconds StrPtr("Hello from Dll!  I'll disappear in 3 seconds.")

    ShowMsgBoxWithTimer StrPtr("Hi there.  I'll display for however many milliseconds you specified."), 5000

End Sub

As we can see, we use our new DLL just like any other standard DLL.

-----------------

Ok, just a bit more detail. At present, the only steps I feel needs any further explanation are step #7, #8, & #9 (where we're opening the VBP with Notepad, and editing the last line in it). I assume you can manage getting it opened in Notepad. Here's how it will initially look:
Code:

Type=Exe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation
Reference=*\G{D560371E-24A7-49A2-A53C-D178815145C6}#1.0#0#VBDll.tlb#VB6 Native-DLL type library by The trick
Module=modMyDllFunctions; MyDllFunctions.bas
Module=modDllInitialize; DllInitialize.bas
Startup="Sub Main"
HelpFile=""
Title="MyStandardDll"
ExeName32="MyStandardDll.exe"
Command32=""
Name="MyStandardDll"
HelpContextID="0"
CompatibleMode="0"
CompatibleEXE32="MyStandardDll.dll"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="Microsoft"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=-1
BoundsCheck=-1
OverflowCheck=-1
FlPointCheck=-1
FDIVCheck=-1
UnroundedFP=-1
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
DebugStartupOption=0

[TAT]
GlobalChecking=0

[VBCompiler]
LinkSwitches=-DLL -FIXED:NO -ENTRY:DllMain -EXPORT:ShowMsgBoxFor3Seconds -EXPORT:ShowMsgBoxWithTimer

We're only interested in the very last line of this file, which I've highlighted. And, more explicitly, we're interested in those -EXPORT arguments. You must take your list of Public functions you developed in the MyDllFunctions.bas module, and add an -EXPORT:... entry for each of them, and probably delete those example functions.

Again, be careful that this VBP is not open in the VB6 IDE, or you'll probably overwrite your Notepad work.

-----------------

And that's about it. It all seems to work great from my pure VB6 testing.

-----------------

Also, just as a note, all the "magic" is in that DllInitialize.bas file. But, under most circumstances, there shouldn't be any need at all to tamper with that file.
Attached Files

Viewing all articles
Browse latest Browse all 1449

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>