This is an old revision of the document!
Demo Script: DevCon 2024
Download and Save Sample Code
- Download twinBASIC BETA 504
- Extract from Zip folder
- Open twinBASIC > Sample 4
- Enter Project Name:
Demo2024
(Do not put spaces in the name) - Save as:
%tmp%\Demo2024\Demo2024.twinproj
- Navigate to:
%tmp%
- Create folder named:
Demo2024
- Filename:
Demo2024.twinproj
Customize the Addin Name and Description
Next, let's customize the friendly name and description of our addin. This is the info that appears in the VBA Add-in Manager dialog box.
- Go to dllRegistration.twin > DllRegisterServer
- In the "FriendlyName" line, replace AddinProjectName with
"DevCon 2024 Demo"
- In the "Description" line, replace AddinProjectName with
"Create a strongly-typed collection class from an existing VBA class object."
- Save the project
- Build the project
- Launch
M:\Repos\NLS\DevCon2024\DevCon2024.accdb
- Switch to VBA: Ctrl + G
- Dock the add-in window
- Go to "Add-Ins" > "Toggle myToolWindow Visibility"
- Go to "Add-Ins" > "Add-in Manager"
- Point out the "DevCon 2024 Demo" item with description below
- Close "Add-In Manager" window
Create the Tool Window Controls
- Open myToolWindow.tbcontrol
- Select all controls and delete them
- Select form and set the following properties:
- Height: 1700
- Width: 2550
- Create a text box and set the following properties:
- Name:
tbObjName
- Anchors > Right: ☑ True
- Height: 300
- Left: 150
- Text: {blank}
- TextHint:
Object Class Name
- Top: 150
- Width: 2250
- Create a text box and set the following properties:
- Name:
tbCollName
- Anchors > Right: ☑ True
- Height: 300
- Left: 150
- Text: {blank}
- TextHint:
Collection Class Name
- Top: 600
- Width: 2250
- Create a button and set the following properties:
- Name:
btnCreateClass
- Anchors > Right: ☑ True
- Caption:
Create Collection Class
- Height: 450
- Left: 150
- Top: 1050
- Width: 2250
Edit the Code in myToolWindow.twin
- Delete the
Timer1_Timer()
andHelloWorld_Click()
subroutines - Add a Click event handler for btnCreateClass using the code below
Private Sub btnCreateClass_Click() MsgBox "Object class name: " & Me.tbObjName.Text & vbNewLine & _ "Collection class name: " & Me.tbCollName.Text, vbInformation, "Create Class" End Sub
Build and Test the Addin on Same Machine
The following instructions assume a machine with 32-bit Office (e.g., mjw20):
- Ensure "win32" is selected in dropdown
- File > Build
- Creates and registers this file:
M:\Repos\NLS\DevCon2024\Build\DevCon2024_win32.dll
- As part of registration, the following registry key and values are created:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\VBA\VBE\6.0\Addins\DevCon2024.myAddIn\
- Description: "DevCon2024"
- FriendlyName: "DevCon2024"
- LoadBehavior: 3 (3 => Loaded/Load at startup)
HKEY_CLASSES_ROOT\DevCon2024.myAddIn\CLSID
HKEY_CLASSES_ROOT\DevCon2024.myToolWindow\CLSID
HKEY_CLASSES_ROOT\CLSID\{9B80DA6E-8B20-4D53-AE54-430ACFAE987B}
- (Default):
myAddIn
\InProcServer32
- (Default):
M:\Repos\NLS\DevCon2024\Build\DevCon2024_win64.dll
(NOTE: The presence of win64.dll here is likely a result of running the win64 build as shown in the next section) - ThreadingModel: Both
\ProgID
- DEBUG CONSOLE should show this:
- [LINKER] SUCCESS created output file 'M:\Repos\NLS\DevCon2024\Build\DevCon2024_win32.dll'
- [LINKER] → Open Folder (NOTE: this is a clickable link)
- [REGISTER] type-library registration completed. DllRegisterServer() returned OK
- Open Excel or Access
- Press [Alt] + [F11] to go to VBA IDE
Build and Test the Addin on a Different Machine and Bitness
The following instructions assume you are building on a machine with 32-bit Office (mjw20), but installing on a machine with 64-bit Office (e.g., gbm18):
- Ensure "win64" is selected in dropdown
- File > Build
- I copied
M:\Repos\NLS\DevCon2024\Build\DevCon2024_win64.dll
to%fb%\12114\DevCon2024_win64.dll
(I will test registering it tomorrow on gbm18) - Open a non-admin cmd prompt
- Run:
regsvr32 DevCon2024_win64.dll
- Receive message: "DllRegisterServer in DevCon2024_win64.dll succeeded."
- Open Word (or Excel) - The add-in appears.
Copy and Paste Working VBA Code into twinBASIC
- Add a standard code module named "MyModule":
- Right-click Sources > Add > Add Module (.TWIN supporting Unicode)
-
- Copy and paste the GetGuidBasedTempPath code
- Copy and paste the FileWrite code
- Handle "Unrecognized datatype symbol 'Scripting'" error in DIAGNOSTICS pane:
- Go to Project > References
- Switch to "Available COM References" tab
- Search for "script" and then click the "Microsoft Scripting Runtime" reference
- Click [Save Changes]
Add fafalone's WinDevLib Package for API Calls
- Project > References…
- Switch to "Available Packages" tab
- Search for "windows"
- Check box next to "☑ Windows Development Library for twinBASIC vX.Y.ZZZ"
- The package will immediately begin downloading in the background
- When the download finishes, the name will change to "☑ [IMPORTED] Windows Development Library for twinBASIC vX.Y.ZZZ"
- NOTE: "WinDevLib for Implements" is a different package
- Click [Save Changes]
- Comment out (or delete) API `Declare` lines throughout the project
- Be aware that if you used non-standard `Alias` names, you may need to adjust your API calls to match the standard versions used in WinDevLib
- myAddIn.twin:
- Delete
Private Type RECT
structure - Delete
GetClientRect()
function declare
- InterProcess.twin:
- Delete
GetCurrentProcessId()
function declare line… - …through
Type UUID
structure
- MyModule.twin:
- Delete
Sleep
sub declare - Comment out
CoCreateGuid
function declare and highlight the failure to compile due to the stricter typing ofid As UUID
in WinDevLib versusid As Any
in my code - Uncomment the
CoCreateGuid
function to show that explicit API declares override the WinDevLib versions
- Pass Unicode strings directly to API declare functions
- Most string-related API functions have ANSI and Unicode versions ("A" and "W" for "ANSI" and "Wide", respectively)
- Lots of legacy VB6/VBA code use the ANSI version of API functions
- WinDevLib encourages the use of Unicode versions by default
- This means that code that passes input strings to API functions may require wrapping the string in `StrPtr()` (or removing `StrPtr()`) from your existing code
- ☐ Remove
StrPtr()
from calls toFindWindowEx()
in InterProcess.callerApplicationObject - ☐ Convert final argument from
0&
tovbNullString
for calls toFindWindowEx()
in InterProcess.callerApplicationObject