twinBASIC Update: January 20, 2026

Highlights include initial OpenGL API call coverage in WinDevLib, improvements to the official docs, and language support for Return in Sub routines.

twinBASIC Update: January 20, 2026

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 Monday week, 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, please leave a comment below.

Here are some links to get involved with the project:


Highlights

Return Syntax in Sub Routines

Support for the Return statement in Functions has been part of twinBASIC from its earliest beta release:

New Syntax in twinBASIC: Part 2
Let’s cover some more new syntax in twinBASIC, including parameterized class constructors, method overloading, and return syntax for functions.

However, prior to BETA 956, the Return statement could only be used with Functions. twinBASIC now allows using the Return statement in Sub routines. Do note that if you try to return a value from a sub (e.g., via Return MyValue), twinBASIC will raise a compile error because you can't directly return values from Subs (of course, you can still indirectly return values from Subs by passing arguments by reference).

Also, like support for Return in Functions, the Return statement can only be used in Subs that do not contain a corresponding GoSub statement.

As to why twinBASIC supported Return for Functions for so long before it supported Return for Subs, it's likely because of when VBA/VB6 would fail with an invalid Return statement in Functions vs. Subs.

Here's Wayne's explanation from Discord:

I remember some discussions around [supporting Return in Subs]. Unfortunately "return" in a sub in VB6 is valid at compile time even without GoSub. It only blows up at runtime, throwing an error. At the time, we kept that behaviour for that edge case of back compatibility.
(which is probably taking things too far just for the sake of trying to be 100% compatible)

Progress Update From Wayne

From Wayne in Discord:

I know some of you may be a little disappointed with the progress in the latest release - I am too. Balancing a growing project, family life, and the general business side of things isn’t always easy, and I also ran into a particularly tricky issue this time which caused some massive knock-on effects.

Next week should be back to normal, and I’ll be putting my foot firmly back on the accelerator!

Discord Chat Summary

* Auto-generated via Claude-Sonnet-4.5

Overview

The week of January 10-20, 2026 saw robust community activity across multiple technical fronts. Major discussions centered on GDI+ wrapper development, SafeArray memory management differences between twinBASIC and VB6, and language design decisions around the Return statement. The community also tackled practical issues with process termination, resource management, and WinRT integration patterns.

GDI+ Package Development

  • okas_o introduced a user-friendly GDI+ package for twinBASIC, modeled after Microsoft's C++ API rather than the low-level flat API. The wrapper adds overhead currently due to compiler limitations, but performance will improve as the tB compiler evolves with better inlining capabilities.
  • fafalone suggested marking GDI+ APIs with [UseGetLastError(False)] for performance improvements in WinDevLib, as these APIs don't use GetLastError.
  • Community members discussed the performance tradeoffs between usability and direct API calls, with general agreement that readable code matters more than micro-optimizations on modern hardware.

Memory Management & SafeArray Behavior

  • VanGoghGaming discovered that twinBASIC destroys locally declared SafeArrays when they go out of scope even with FADF_AUTO flag set, unlike VB6 which leaves them alone. The workaround is to set the array variable to vbNullPtr before exiting.
  • wqweto noted historical issues with SafeArrayDestroy return value handling in tB, suggesting the problem might be related to error acknowledgment differences.
  • The discussion highlighted ongoing differences in cleanup behavior between VB6 and tB that developers need to account for during migration.

Process Termination Challenges

  • twixydon encountered complex issues with XYplorer not fully unloading, eventually traced to missing GdiplusShutdown calls and message pump issues. waynephillipsea recommended using trace logging to compare successful vs. failed shutdown sequences.
  • The investigation revealed that adding DoEvents in Form_Terminate resolved the hanging process issue, suggesting timer or message processing was incomplete during shutdown.
  • AntsAntix shared design patterns for avoiding ghost object instantiation with PredeclaredId=True, recommending custom Create() functions and avoiding Form_Initialize for object instantiation.

Language Design: Return Statement

  • Extended discussion about allowing Return in Sub procedures, currently blocked by legacy GoSub/Return syntax compatibility. waynephillipsea expressed strong preference for Return syntax over traditional function name assignment.
  • wqweto searched Planet Source Code and found Return without GoSub in subs is "extremely rare" - mostly unreachable code from incomplete refactoring.
  • Community consensus emerged that breaking this edge case for language improvement is acceptable. waynephillipsea confirmed BETA 956 implements smart behavior: Return works in subs without GoSub, preserving legacy semantics when GoSub is present.
  • Discussion of Return Nothing as potential syntax was explored but deemed problematic since Nothing already has meaning in the language.

WinRT Integration & Weak References

  • VanGoghGaming developed a cWeakReference class to solve circular reference issues with WinRT objects, simulating IWeakReferenceSource behavior without thread-safety overhead.
  • The implementation allows parent objects to pass weak references to children for callbacks, ensuring Class_Terminate fires properly unlike VB6's more forgiving reference handling.
  • bclothier suggested custom IUnknown::AddRef/Release implementations for more deterministic behavior, though the weak reference approach proved simpler for single-threaded scenarios.

IDE & Development Tools

  • fafalone shared a VBA-targeted OpenGL library (VBGL) that should work in tB with WinDevLib declares, expanding graphics capabilities.
  • AlaskanDruid discovered tB's built-in resource management through the Resources folder in Project Explorer, replacing VB6's external resource editor workflow.
  • Bug reports included PictureBox copy/paste corruption and auto-increment revision numbers not saving without explicit save action.

Backward Compatibility Strategy

  • Productive discussion about balancing extreme backward compatibility with language improvements. waynephillipsea noted CDecl as an example where tB intentionally improves on VB6's runtime-error-only approach.
  • Agreement that thorough documentation of known incompatibilities (asm thunks, VB header hacking, DataObject internals) is more valuable than attempting to support every edge case.
  • fafalone advocated for comprehensive documentation of compatibility breaks with resolution strategies rather than attempting perfect compatibility.

Conclusion

The week demonstrated the community's maturity in balancing practical development needs with language design decisions. The successful resolution of the Return statement debate through empirical analysis of real-world code exemplifies the project's evidence-based approach. Ongoing work on GDI+ wrappers, WinRT integration patterns, and memory management refinements shows steady progress toward production readiness. The collaborative problem-solving around process termination issues and the thoughtful discussion of backward compatibility strategy indicate a healthy, engaged community working toward v1 release goals.

Around the Web

Initial OpenGL Support in WinDevLib

From fafalone in the WinDevLib Updates thread:

PROJECT UPDATE
At long last, Initial OpenGL coverage is now available in v9.2.638.

Covered: Windows SDK gl.h, glu.h; definitions from GLEW through OpenGL 4.6; ARB-approved extensions; FreeGLUT

Still pending: EXT functions, vendor-specific functions for AMD/NVIDIA/INTEL/MS

Note: WDL does not include the FreeGLUT binaries.

Note: Most functions are delegates that will all be auto-initialized on first use of any. It's on you to verify your drivers support the functions you use– being defined in WDL does not guarantee it won't cause a null pointer crash if you use a function wglGetProcAddress could not resolve
GitHub - fafalone/WinDevLib: Windows Development Library for twinBASIC
Windows Development Library for twinBASIC. Contribute to fafalone/WinDevLib development by creating an account on GitHub.

Documentation Improvements

Generated by Claude-Opus-4.5 based on Discord #docs channel discussion

The documentation site received its most substantial update in weeks, while behind the scenes developers uncovered powerful new UDT capabilities.

alexhedley drove multiple pull requests adding monthly challenge pages, an IDE tour, video resources, and configuration improvements, while okas_o published a comprehensive attributes reference page and plans to reorganize the lengthy New Features Overview.

On the technical side, VanGoghGaming revealed that UDTs now support destructors (Type_Terminate), assignment operators (Type_Assignment), and conversion operators (Type_Conversion)—features that surprised even experienced community members. okas_o demonstrated activation context APIs for loading WinRT components without registry entries, sharing working code and manifest structures for runtime package loading. Meanwhile, VanGoghGaming reported partial success with WinUI2 controls: instantiation works via RoGetActivationFactory, but rendering in XAML Islands fails with cryptic E_FAIL errors, suggesting missing dependencies remain.

These combined efforts give users better learning resources today while laying groundwork for modern Windows UI integration tomorrow.

Changelog

Here are the updates from the past week. You can also find this information by visiting the GitHub twinBASIC Releases page.

Releases · WaynePhillipsEA/twinbasic
Contribute to WaynePhillipsEA/twinbasic development by creating an account on GitHub.

AI-Generated Changelog Summary

* Auto-generated via Claude-Sonnet-4.5, sorted in order of its opinion of "most impactful changes."

  • Form Inheritance Enhancement: Changed root user Form/MDIForm/UserControl implementations to use full inheritance rather than Implements-Via, resolving issues where references were held to inner Forms instead of outer instances. This addresses fundamental object handling problems.

  • UserControl Regression Fixes: Resolved critical codegen errors in UserControls that were broken since BETA 951, restoring functionality for projects using custom controls (Issue #2304).

  • Form Event & Runtime Fixes: Fixed Form_Initialize event not firing (regression in BETA 951), resolved AutoRedraw property causing GDI handle leaks at runtime, and corrected control-array menu Click events triggering with wrong Index values.

  • Alias Type Improvements: Fixed multiple edge cases with Alias types, including array usage issues, trace mode crashes when using Alias types, and Go To Definition navigation errors.

  • IDE Designer Enhancements: Fixed grid options dropdown being obscured by controls on the designer (Issue #2298), corrected form designer mini-toolbar caption persistence, and resolved Find/Replace not searching .CLS files in Current Project mode.

  • New Language Feature: Added Return statement support for exiting Subs (when legacy GoSub isn't used) for improved language consistency.

  • Code Quality: Compiler now reports unused line labels as warning TB0032, helping developers identify potential dead code.


WARNING: The following issues are present in each of the releases below:

  • IMPORTANT: This is a BETA release under active development. It is not recommended for production use.

BETA 951

  • fixed: form designer memory corruption issue when using control arrays
  • fixed: changed the root user Form/MDIForm/UC/etc implementations to use full inheritance rather than Implements-Via to fix problems such as holding only a reference to the inner Form instead of the outer MyForm instance [ Aman Jain, discord ]
  • fixed: about box now shows the licence status [ Jeff Imber, private ]
  • fixed: IDE find/replace dialog 'Current Project' option was not searching inside .CLS files
  • fixed: (regression) changing a control caption using the form designer mini-toolbar, would appear to change but would not persist
  • fixed: IDE auto-correct issue for Alias syntax where LongPtr would be changed to 'Long' or 'LongLong incorrectly [ fafalone, discord ]
  • fixed: IDE auto-correct issue for Alias syntax where a symbol might be changed to '{unresolved}' incorrectly [ fafalone, discord ]
  • fixed: using new Alias types in arrays was not always working [ Don, discord ]
  • fixed: the IDE project settings indicated that '${DEBUG}' was the default value for the trace log path incorrectly [ fafalone, discord ]
  • fixed: IDE designer grid options dropdown could be obscured by controls on the designer [#2298]

BETA 952

  • fixed: (regression in BETA 951) Form_Initialize event was not firing [ birnaofthenorth, Discord ]

BETA 953

  • fixed: when compiler has entered trace mode automatically, projects with Alias types (or referencing packages with such types) would cause a crash loop and SafeMode to be entered
  • fixed: some edge cases around handling of Alias types [ Don, discord ]
  • fixed: changing AutoRedraw property at runtime would cause a GDI handle leak [ Don, discord ]

BETA 954

  • fixed: calling a delegate via a class field was not working [ fafalone, discord ]
  • fixed: (regression) hovering over a control-array menu element could trigger the Click event with the wrong Index value [ Don, discord ]

BETA 955

  • fixed: (regression since BETA 951) codegen errors in some UserControls [#2304]
  • improved: added a 1-second dwell time for text input in the Global Search Addin [ Don, discord ]
  • updated: sample 15. Global Search Addin

BETA 956

  • fixed: (regression since BETA 951) DLL projects that contain forms might fail to build [ sokinkeso, discord ]
  • improved: for language consistency Return is now allowed as an exit statement in Subs (when he legacy GoSub statement is not used in that same routine)
  • fixed: F12 / Go To Definition on an Alias type would sometimes take you to a random place in the source code [ Don, discord ]
  • improved: compiler will now report unused line labels as warning TB0032 "Unused Line Label"

All original code samples by Mike Wolfe are licensed under CC BY 4.0