twinBASIC Update: August 21, 2022
Highlights include IDE improvements, support for Excel events in COM addins, and a kernel-mode driver written in twinBASIC (yes, really).
On April 23, 2021, I helped Wayne Phillips introduce the world to twinBASIC at the Access DevCon Vienna conference. I boldly predicted that twinBASIC (along with the Monaco editor) would replace VBA and its outdated development environment by 2025. With that goal in mind, this weekly update is my attempt to keep the project fresh in the minds of the VBA development community.
Every Sunday, I will be providing updates on the status of the project, linking to new articles discussing twinBASIC, and generally trying to increase engagement with the project. If you come across items that should be included here, tweet me @NoLongerSet or email me at mike at nolongerset dot com.
Here are some links to get involved with the project:
- Custom twinBASIC IDE Installation Guide (NOTE: the twinBASIC VSCode extension is under a feature freeze until 2023)
- GitHub Issue Tracker (report bugs)
- twinBASIC Discord Server (chat about the project)
After a well-deserved break last week, Wayne appears to have come back re-energized, releasing several improvements and bug fixes over the past week:
- New Standard EXE (console) project type
- Font size configurations for the IDE and code window
- Ctrl + G support for switching to the Debug Console
- 30% improvements in compile-time RAM usage and build size
New IDE Shortcuts
The following IDE shortcuts were added in BETA 95:
- CTRL+TAB to forward cycle through open editor tabs
- CTRL+SHIFT+TAB to backwards cycle through open editor tabs
- 'Code Editor Font Size' setting (independent to 'IDE Font Size' setting)
- CTRL+[+/-] for adjusting the 'Code Editor Font Size'
- CTRL+SHIFT+[+/-] for adjusting the IDE and Code Editor font size
- CTRL+G to jump to the Debug Console
Support for Handling Excel Events in twinBASIC COM Addins
I wrote an article about how to create COM addins in Excel using twinBASIC a couple of months ago.
The built-in sample project (Sample 5) includes code to handle the COM Add-in events as provided by the interface IDTExtensibility2. These are the events that fire when the addin itself gets loaded by the host application (e.g., Excel, Word, etc.), the host application begins to shut down, etc. However, I had trouble getting the add-in to handle the host application's events (e.g., Excel's WorkbookOpen, NewWorkbook, etc.).
It sounds like this was not so easy to solve. Here's Wayne's explanation:
Excel calls it's event handlers through IDispatch::Invoke which is quite normal, but passes arguments using named argument DISPIDs that are known at compile-time, which is more unusual. tB does support named arguments, but the DISPIDs we assign to them are not matching the ones defined in the Excel type library (or assigned automatically via MIDL). Since Excel doesn't query for the DISPIDs at runtime (through IDispatch::GetIDsOfNames), the IDispatch::Invoke call silently fails due to the mismatched DISPIDs for the passed in arguments.
Now that these events are supported in twinBASIC, my spidey sense is telling me that there may be a follow-up HOW-TO article on the horizon. Stay tuned...
Around the Web
Kernel Mode Driver Written in twinBASIC
Consider the concept proved.
Frequent twinBASIC commenter fafalone posted his sample code on VBForums. Here are a few excerpts from his announcement:
This is a demonstration of using twinBASIC to create a kernel mode driver compatible with x64 versions of Windows. ...
For testing purposes, I first made a working VB6 version (included), and then a tB version with all the definitions updated to x64 and taking advantage of a feature tB has to put in-project API declares into the IAT like TLB APIs to avoid late bound resolving requiring external APIs, and a controller (written in tB) to load/unload the driver.
Do I know how any of this works? No.
Am I still suitably impressed? Yes.
Better Built-in Support for Pointers in twinBASIC
GitHub user fafalone begins the discussion to "Consider allowing pointer aliases" thusly:
I firmly believe one of the reasons for VB6's enduring popularity is the marriage of both high level RAD and low level abilities. While these might not be used directly by a lot of people, they let advanced users make modules/controls/classes both for their own more complex use and to make such things easily callable by people simply dropping in the class.
So, might it be worthwhile to consider deeper pointer support? This could be implemented via the already-planned support for aliases; which could be rooted in a mechanism to allow ones from TLBs, increasing TLB support.
The discussion proceeds from there with several developers weighing in on the pros and cons of varying levels of native support for pointer types in twinBASIC. If you have thoughts on the topic (or are simply curious), be sure to check it out.
Language Support for Multithreading in twinBASIC
Unlike VBA, twinBASIC will have full support for multithreading.
In fact, multithreading support already exists in twinBASIC and can be demonstrated via the Debug Console. However, Wayne has not settled on the multithreading language syntax yet.
Andrew Mansell thinks it's time to start having those discussions and he kicked things off over on GitHub:
twinBASIC is designed to support multi-threading. Early reports suggest that low-level Windows threading APIs can be called in twinBASIC, without the active resistance put up by VB6 (is threading even possible in ordinary VBA hosts?)
To make threading accessible though, some kind of language support should be added. I have no idea what that should look like. So I'm opening this issue to start the discussion: what should the language syntax and semantics look like, and how does that affect compiler design?
Here are the updates from the past week. You can also find this information by visiting the GitHub twinBASIC Releases page.
- fixed: 'Standard EXE (Console App)' template now has the 'Is Console Application' project setting ON by default
- fixed: (regression since BETA 91) some compile errors were causing extraneous areas to be flagged as part of the error [ https://github.com//issues/1114 ]
- added: 'Show Advanced Info On Hover' IDE option (via Tools > IDE Options menu)
- improved: hovering over UDTs now provides member offset information if new IDE setting of 'Show Advanced Info On Hover' is enabled
- improved: hovering over classes and interfaces now provides vtable offset information if new IDE setting of 'Show Advanced Info On Hover' is enabled
- improved: better handling of compilation errors in global variables [ FullValueRider/fafalone, discord]
- improved: IDE now supports CTRL+TAB / CTRL+SHIFT+TAB for cycling through open editor tabs [ https://github.com//issues/1079 ]
- added: 'Code Editor Font Size' setting (independent to 'IDE Font Size' setting) [ https://github.com//issues/1079 ]
- improved: IDE now supports CTRL+[+/-] for adjusting the 'Code Editor Font Size' [ https://github.com//issues/1079 ]
- improved: IDE now supports CTRL+SHIFT+[+/-] for adjusting the IDE and Code Editor font size [ https://github.com//issues/1079 ]
- improved: IDE now supports CTRL+G to jump to the Debug Console [ https://github.com//issues/1079#issuecomment-1208350050 ]
- added: new project type of 'Standard EXE (Console App)' [ https://github.com//issues/1110 ]
- improved: NATIVE subsytem mode now generates code without using TLS
- fixed: support for Excel host events, using fixed DISPIDs for IDispatch::Invoke named arguments [ https://github.com//issues/1088 ]
- fixed: Build <-> Revision version number ordering in TWINPACK settings [ Krool, discord ]
- fixed: IDE Outline panel was showing extra component level entries for Static variables declared at procedure level [ https://github.com//issues/1085 ]
- fixed: IDE Outline panel indentation quirk [ https://github.com//issues/1081 ]
- fixed: LongLong integer division and modulus bug in 32-bit builds [ https://github.com//issues/1102 ]
- fixed: edge case where Mid statement variable and RHS expression string overlaps [ https://github.com//issues/1097 ]
- added: compiler error for Mid statement cannot be prefixed with VBA qualifier [ https://github.com//issues/1095 ]
- fixed: Asc() problem with chars in range 128-255 [ https://github.com//issues/1087 ]
- fixed: Mid statement not working with Variants containing arrays [ https://github.com//issues/1096 ]
- fixed: Sub routines inside classes were not always propagating errors [ https://github.com//issues/1089 ]
- improved: PE header checksum value is now calculated and populated on all outputted builds
- fixed: some edge cases around Variants containing arrays and use of VarPtr [ https://github.com//issues/1105 ]
- improved: codegen produces nativecode up to 30% smaller than BETA 90. YMMV
- improved: compile time memory usage up to 30% less than BETA 90. YMMV
- added: LargeAddressAware IDE setting affecting the compiler process in 32-bit builds (Tools menu > IDE Options) [ requires IDE restart ]