Twice in one day I've agreed with something you've posted. One of us must not be well ;)
Printable View
I've never had any problems with people liking or wanting to use VB6. I'm really glad it's die hard fans are finally getting what they wanted for all these years. I'm really happy for you guys. My problem was always with all of the misinformation that came out of the VB6 camp about .Net. and all of the emotionally driven drivel that came with that misinformation campaign.
I have no problem with VB6 but VB.Net really is a great successor that brought a lot of things that I and a lot of people always wanted. However, that came at the cost of compatibility with VB6 and yes, that was a bad thing. It was a terrible thing Microsoft did to VB6 developers when they abandoned VB6 but I fully understand why they did it. When I looked at what .Net has become today, I see now why they couldn't use VB6 as a base. It just would not have worked, at least not without 10x the effort.
Anyways, TwinBASIC really is impressive and based on what I've seen so far, it has a very bright future. Hopefully, the developers won't get burned out before it reaches it's full potential and when it's production ready, I'd have no problem recommending it to anyone. In fact, I'd go so far as to recommend it over VB.Net for beginners looking to get into Windows programming. One of the very few things VB6 does better than any .Net language is that it is far more approachable as a development platform. You can get along in VB6 without knowing anything about classes, inheritance, delegates, generics, lambda expressions, async/await etc. Don't get me wrong, these features do bring a lot of power to a language but beginners, hobbyists and people looking to do something simple will be overwhelmed and you can't really get away from most of this in .Net. You certainly can write code without it but eventually you will need to Google something and you are going to run into these things and as a beginner, it will be very scary. VB6 tends to keep things simple.
That is not to say that TwinBASIC cannot benefit from some modern features. For example, declaring and initializing a variable on the same line:-
No matter how simple a language is, there's no excuse to not have this ability. Of course the biggest modern benefit by far that TwinBASIC will have is a powerful modern IDE behind it which makes a huge difference. A modern IDE alone is enough for me to take it seriously.Code:Dim i As Long = 10
So yea, this is a really good thing for everyone and I'm genuinely happy for all find satisfaction in having this choice.
Thanks Niya! Glad you're liking it.
For the enum parameters intellisense, I've opened an issue in our GitHub tracker here: https://github.com/WaynePhillipsEA/twinbasic/issues/337
For the signature-help formatting, unfortunately VS Code doesn't offer customization here. The active parameter should be both bold and underlined, but I do agree that it's not always particularly clear. Hopefully VS Code will improve their offering for this in the future, but for now we can only provide plaintext for the signature help text, and VS code applies its bold+underline formatting to the active parameter part based on offsets into the plaintext data provided by the language server.
Thanks again for looking at twinBASIC, and for your valuable feedback, all noted.
I'll always be a .Net guy but I really love seeing good work like this and we do have some legacy VB6 stuff that needs maintaining. TwinBASIC would be a good fit.
Nice. That is the issue exactly. I was actually thinking about coming back around to provide a picture myself just in case I wasn't clear enough but you got it.
Ah ok. This also brings me to something else. Did you guys ever consider integration with Visual Studio itself. One other minor pain point I had was how different VS Code is to Visual Studio. I kept trying to do things the "Visual Studio" way. I mean it's not essential, as VS Code isn't that hard use but it really bites when you're so much more familiar with something else. It would be really great if it was integrated into Visual Studio itself. That could also go a long way as well. Visual Studio is really popular on Windows amongst Windows programmers so it would be a big deal if Visual Studio was also available as a choice alongside VS Code.
No problem. Really great work. Keep it up!
twinBASIC connects to VS Code using standard protocols (LSP and DAP), so it should be possible to integrate with Visual Studio, or any other IDE that implements the protocols. I opened an issue on the GitHub tracker to propose this: https://github.com/WaynePhillipsEA/twinbasic/issues/82. The only slight complication is that VS Code uses a virtual filesystem, but I'm sure that can be worked around.
That said, I suspect it's not a priority right now - VS Code is a good fit as it's cross-platform. And the language needs a "primary" IDE for support reasons. Potentially other integrations could be written by the community.
Note, I'm just an interested party, not a tB developer.
Integration with VS was considered, yes. From the start of the project I felt that one of the most important thing was to extend an existing IDE rather than creating one from scratch, and it was just a case of having to choose one. After much research, VS Code seemed to be way ahead of every other option in terms of supporting open-protocols; LSP for the language and DAP for debugging. VS does now offer support for LSP and DAP protocols, but from what I've seen it's nowhere near as feature complete as what is offered by VS Code. Additionally the VS Code API is actually really nice to work with - it is clear the team have put extension authors at the heart of everything VS Code offers.
As @mansellan rightly points out, by using these modern open-protocols (LSP+DAP), it would actually be fairly easy to switch to another IDE at some later point (provided enough of the protocols features are implemented). For support reasons, our current official view is that VS Code is the twinBASIC IDE. If others in the community were to make twinBASIC work with other editors, I would absolutely support their efforts as best as I can.
All that said, I am very aware that there are improvements still needed to help make the transition from VB6 to twinBASIC/VS Code, so expect further improvements in due course as we put more effort into that.
@mansellan
@WaynePhillipsEA
Ok that's fine. VS Code is not a bad IDE. It's just different and seems far more generalized. Every version of Microsoft's IDEs have done certain things the same way since QuickBasic. for example F9 being used to set break points and F8 for single stepping and dozens of other tiny things. At least you guys preserved some of these conventions in VS Code.
@Niya, just to let you know, this should now be working as of v0.10.4125 ( https://github.com/WaynePhillipsEA/twinbasic/issues/337 ). Thanks for your feedback!
Just found a breaking bug in v0.10.4198
The above module level code crashes the compiler.Code:Public Type TESTTYPE
testString As string * 13 * 2
End Type
Another minor bug, Go to Definition doesn't seem to work with constants that are in another module in another .twin file.
Thanks Niya! I created an issue for it over on GitHub:
https://github.com/WaynePhillipsEA/twinbasic/issues/350
And it's now fixed in v0.10.4273.
Issue for tracking : https://github.com/WaynePhillipsEA/twinbasic/issues/351
Thanks!
Wow. You guys work fast. Nice job.
I spent the last 3 days testing out TwinBASIC by taking on something with a more teeth than just printing simple stuff with MsgBox. I decided to really test it by writing a GUI application using pure Win32 from scratch(no copy and pasting code from anywhere) and purely using Visual Studio Code to get a feel for the debugging experience. I just finished it and released it here if anyone wants to check it out.
I have to say, it is really impressive how capable TwinBASIC is, even at this time with bugs and issues popping up here and there. Even though it's still very far from it's goal of VB6 compatibility, it felt like a complete product in it's own right. I had very little trouble coding against the Win32 API and I felt as if I could do anything I wanted. In this regard it is EVERY BIT as capable as VB6.
That being said, I do want to address some major pain points with the debugging experience in Visual Studio Code. Now, the debugger is very solid but not very intuitive to use. The biggest issue I had the entire time was getting breakpoints to work. The biggest pain with that is that I can't just run the application from the Build button if I want Stop or breakpoints to work. I had to use the run feature the "run procedure under cursor" which required me to go back to Sub Main and put the cursor under it every time. This was unbelievably annoying to do. I want to be able to set a breakpoint and run the application from right where I am, like I've been doing since QuickBasic.
Another very important thing that I really missed was the ability to put Debug.Print in my code to spit out data about the state of my application at runtime. Not having this ability slowed me down massively, especially when combined with what I said above about getting breakpoints to work.
There were a lot of other minor issues that I can't recall right now but those were my biggest problems.
Anyways, my overall experience with TwinBASIC was good. I was really impressed and I had a lot of fun testing this out. I'd like to continue but I have already spent 3 days on this and I need to get back to my work. Keep it up guys. TwinBASIC has real promise.
Niya... thanks so much for trying out twinBASIC! I'm very pleased that the overall experience was a good one, and thanks for your kind words.
I hear you about launching the debug session currently being awkward to start in Sub Main() -- I'll address that very soon. Breakpoints and Debug.Print etc should all be working provided you do run the code in the debugger rather than launching via the Build button, but I understand why you were using the Build button currently.
Thanks again - your feedback is invaluable.
@WaynePhillipsEA
Ok, did a little more testing and I want to bring a couple things to your attention. Hope I'm not annoying you with all this.
It seems pressing F5 works exactly the way it should and Breakpoint/Stop work the way I wanted when using it. I'm unsure if this was always working or if it's a recent fix since I haven't used F5 at all during those 3 days writing that application. But the reason I avoided using it was because I thought it wasn't working. Pressing F5 works but when you actually go to Run -> Start Debugging, it just gave me a menu thing to choose a debugger and when I chose twinbasic DEBUGGER, it didn't do anything. I should have been using F5 instead of the Build button all this time, but I didn't because the inconsistent behavior between Run -> Start Debugging and it's shortcut, F5 led me to believe this feature wasn't working. This is an example what what I meant when I said the debugger was unintuitive. A menu option and it's keyboard shortcut should do the same thing regardless of how you invoke it.
Also, using F5 to execute the program with the debugger still requires that you put the cursor in Sub Main which is a major pain point.
Also, I just tested Debug.Print with an F5 run and it works just as you said. However, Debug.Print doesn't show up in the intellisense which I why I assumed it didn't exist.
One last thing I just noticed about the debugger. It inherited a weakness from VB6 and it has to do with way it executes the program in debug mode. Now I'm making some assumptions here so feel free to correct me where I'm wrong, but I'm guessing that VB6 runs the program in the same process as the IDE which means anything that the program does in the process space would affect the IDE as well. I'm guessing it's one of the reasons why bad API calls can crash the VB6 IDE. It seems that TwinBASIC does something similar. Now, I haven't observed bad API calls crashing the Visual Studio Code IDE but I have noticed behaviors that lead me to believe that TwinBASIC programs run in the same address space as VS Code.
Modern versions of Visual Studio when running a program in debug mode actually run it as it's own process. This has a couple of advantages. For one, it lets you see debug the application with the exact behavior it would have when compiled and released in a production environment. Secondly and this is the more important point, it allows Windows to clean up resource leaks when your application terminates. If you are debugging an application in TwinBASIC and it breaks for any reason without cleaning up resources like GDI/User32/Kernel handles, these handles end up polluting the debugging session which can hamper the actual process of debugging the application.
You can test this leaking behavior with this code:-
I've also tested this by leaking Timers and the results were unholy to say the least. Ended up with dozens of timers just running in the process causing all kinds of havoc.Code:Module MainModule
Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal handle As Long) As Long
Private Const GENERIC_READ As Long = &H120089
Private Const NO_SHARE As Long = 0
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Private Const INVALID_HANDLE_VALUE As Long = -1
' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
Public Sub Main()
Dim hfile As Long
Dim sFileName As String = "d:\t.txt"
hfile = CreateFileW(StrPtr(sFileName), GENERIC_READ, NO_SHARE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
If hfile = INVALID_HANDLE_VALUE Then
MsgBox ("Failed to open file")
Else
MsgBox("File open succeeded")
End If
'Comment this line out to see that consecutive F5 runs
'failed to open the file after the first run due to the file
'handle being leaked. Solving it requires that VS Code be completely restarted
'to allow Windows to close the handle.
CloseHandle(hfile)
End Sub
End Module
Hey @Niya, sorry about the 'Start Debugging' menu thing... I am aware of it as someone else also mentioned it previously but haven't had chance to look deeper into it yet. I might open a separate issue for it so that it gets more prominent attention.
> Hope I'm not annoying you with all this
Not at all! It's great to get feedback. I'm way too close to the project to notice the little things that annoy new users, so I do take note of all feedback when it come in :)
Debug.Print not showing in the intellisense is also a known issue (https://github.com/WaynePhillipsEA/twinbasic/issues/269) and this will be addressed soon as I've been doing some work in this area so it makes sense to get that sorted now.
Indeed, the debugging session does run inside the same process as the compiler, and you're right that this does create some pain points, particularly with using the Win32 API. The debugger is tightly bound to the compiler at the moment, but it is planned to be separated out so that the debugged session can be run in a separate process. This change is not imminent, but will be done in the next few months. Thanks again!
Aite man. Keep up the good work!
It just occurred to me that a nice stopgap measure would be some kind of button or shortcut that allows you to restart the IDE and reload the current project. If something like that were easy to implement, you could lean on that in the mean time until you're able to separate the compiler from the debugger.
Started experimenting with classes in TwinBASIC. Found two minor issues so far:-
- Intellisense doesn't work with Handles clause.
- Application crashes if you try to assign an object to an object variable without using Set:-
Code:m_tc = New TestClass(900) 'Crashes
Code:Set m_tc = New TestClass(900) 'Works
Also, would it be more helpful if I posted these on GitHub instead. Do you mind at all having to come over here at read these at VBForums? I'm just very familiar with posting here. I never did anything more than read/download stuff off GitHub.
Another thing I wanted to point about about TwinBASIC. I'm really loving the fact that the compiler can produce Windows executables with zero dependencies, an advantage it has over VB6 and .Net. .Net can't do it as far as I know(except when compiling for Linux) and VB6 does it very poorly(OCX errors, always having trouble finding DLLs etc). Although I will always veer towards using Visual Studio and .Net for any serious work, I could see myself using TwinBASIC to write very small and easy to deploy utility applications. I tend write a lot of little utilities in .Net, both for personal use and help wit h our work. And while I've never had serious problems with them, there is always that slight risk that something might be broken on somebody's computer and it would not run. Bare bones binaries coded against the Win32 API almost never fail to run on any Windows system. It would be nice if you guys could preserve this ability in future versions of TwinBASIC.
Could you provide a full example for this? My following attempt to reproduce generates a runtime unhandled error as expected, but not a hard crash:
Code:Private Class TestClass
Sub New(aValue As Long)
End Sub
End Class
Module MainModule
Dim m_tc As Object
Sub Main()
m_tc = New TestClass(900)
End Sub
End Module
My apologies, I should have chosen my works more carefully. That is what I meant, the program crashes with an exception.
With regards to this issue. I was under the impression that this would qualified as syntax error and not a runtime error which I why I found that exception odd. If not using Set was a violation, I was expecting the compiler to prohibit compilation of the code.
This is good to hear.
I'll see if I can find my GitHub credentials some time soon. I have them in a file somewhere. Been a while since I logged into GitHub.
Ah OK, the runtime error is what is expected here; same as VB6. Without the 'Set', it gets default-member property-put semantics (through IDispatch with DISPID_VALUE). With IDispatch being late-bound, this is a runtime-error instead of a compile-error.
However, twinBASIC could be smarter than VB6 here, as it knows for sure that there's no default members defined on these internally defined classes, and so could throw a compile-error.
v0.10.4333 just released. Handles-clause intellisense is now available, and the Debug object intellisense is also fixed.
Wow, ok. I had no idea it worked like that. My knowledge of the internal workings of COM is no where near yours.
That would be a good idea. Errors like that don't exist in VB.Net or C# as far as I know. That's why it felt so weird to me. A general rule of thumb might be to consider any error that can be caught at compile time should be caught at compile time. This error qualifies but only for scenarios where the type being assigned is known.
Of course this is not what I'd consider a major pain. It would be acceptable if it stayed as it is provided we get a better description of why it crashed instead of just "unhandled error". The first time it happened to me, it took me quite a while to figure out that not using Set to assign objects to variables was the cause.
Just tried them. Works great so far!!
Absolutely. Most runtime errors come through as generic E_FAIL at the moment. There's an open issue for that (https://github.com/WaynePhillipsEA/twinbasic/issues/56), and we'll be tackling it very soon.
There are some things that are making tB difficult and cumbersome to use, but should be easy to fix, thus worth the effort sooner.
Here is my feedback as a long time VB6/VB.NET user:
High
- Need Quick access to common menu items, in the same placement as VB6 and with the same naming convention. The learning curve is a bit of a nuisance, especially if what you're looking for doesn't exist yet. In fact any extra features that are not included in VB6 or laid out as VB6 should be hidden until chosen, or perhaps have 2 simple modes, ie classic mode/tB mode.
- Intellisense does not appear after typing the New keyword, ie Dim v As New {nothing appears here yet}.
- Intellisense does not initiate parameter/return types after typing spacebar (accepts only tab for some reason).
- Automatic Code formatting with options!!! There has never been an excuse for any IDE NOT formatting the code that is the format of the language itself. Code procedures should be displayed with a pretty arrangement after certain input events, ie Enter key, drag/drop, etc.
Moderate
- Make any new auto insertions optional (off by default). Muscle memory is hard and frankly annoying to change. The developer has to delete the extra inserted characters, or move the caret back because of an unexpected position. Getting used to this may not be possible since you have to switch back/forth to VB6 so often.
- Goto definition ?
- Jump to last postion?
- I'm Expecting the "Redo" shortcut accelerator to be Alt+Shift+Backspace, not Ctrl+Y
Low
- Object browser of some sort would be nice.
A smoother transition between VB6 and tB is needed for the user's experience. As mentioned, the developer will often have to switch back and forth between VB6 and tB. A good metaphoric example would be for users that switch between VB6 and VB.NET often. It takes a minute to jump back on the bicycle and remember the subtle differences that have a profound or opposite effect.
EDIT: update undo also has a bug, where it stops for no reason. Seems to be trying re-case or something?
Thanks for your input @TTn.
> Quick access to common menu items
I hear you. Unfortunately VS Code doesn't offer full customization of menus (yet), so we can't copy the menu layout of VB6. At the moment, we've got the twinBASIC panel (with the build button etc), and so we probably need to make better use of that. In order to copy the layout VB6 more precisely, we'd have to fork VS Code, which is not impossible of course, but does have it's own concerns.
>Intellisense does not appear after typing the New keyword
Should already be fixed. This was a bug due to certain type libraries. Please let me know if you're version of tB is up-to-date and you're still experiencing this.
>Intellisense does not initiate parameter/return types after typing spacebar
This one is tricky. We can make the spacebar key do that, but it creates other problems. The issue comes from VS Code, where the intellisense dropdown list automatically pre-selects the top item, and so pressing space at that point then always changes the current entered text to the completion item text, even though you didn't manually select it. In VB6, it doesn't pre-select an item, so you don't have this problem. This one might be worth us creating an issue over on the VS Code repository to ask for an option to turn off the pre-selection of intellisense lists, and then we can more safely enable the traditional spacebar commit key.
> Automatic Code formatting with options
Planned.
> Make any new auto insertions optional (off by default)
Could you give me an example here, as we aren't doing much auto-insertion at the moment. Perhaps it was the automatic End-block statements you were referring to here? If so, we can add an option for that, sure.
> Goto definition
Already implemented. It's on the right-click context menu, or press F12.
> Jump to last postion
Not sure if VS Code offers that, but if not we could probably implement it.
> I'm Expecting the "Redo" shortcut accelerator to be Alt+Shift+Backspace, not Ctrl+Y
I'll look into that.
> Object browser of some sort would be nice
Planned.
> Update undo also has a bug, where it stops for no reason
Known issue. Sometimes 'Undo' fights with the tB prettifier. The prettifier currently wins.
Thanks!
- Ok, I understand that the menu layout may be hard, so expanding the tB panel makes sense.
- Yup, the New keyword is working here now.
- The spacebar issue is important because it hurts my wrist to extend out to tab key constantly, whereas both thumbs are planted at home on the spacebar, especially different keyboard layouts.
- Cool, manual code formatting is a subtle yet insidious distraction
- Type a function name, then type open parenthesis character or the open quotation character. There may be other examples but those kept slipping me up.
- Thanks for the tip on Goto definition, completely missed that.
- Jump back is nice but not needed right away.
- Redo is odd, because VB6 does accept Ctrl+Y, but it deletes lines of code. An accelerator is not listed on the menu item in the IDE. I expected to get Alt+Shift+Backspace, since VB.NET uses that alternative.
- Nice, object browsing!
- Prettify is difficult, but I'm sure you'll knock it out.
I vote again for Ctrl+Y to do what almost every other Windows program does. We can vote more than once right? ;) But seriously, I think it's easier to remap your brain once to a shortcut that works across all apps vs. having to remap it dynamically every time you task switch to another app.
Maybe customizable hotkey to action mapping (similar to what MZTools offers) is what's needed.
No voting required surely? These things should be sorted by configuration.
I mean we all use tools that are newer and do things the 'new' way but we old VB6ers are used to our old IDE, the way we have been using it for 20 years now. It is hard to unlearn. However, I'd be more than happy to use CTRL+R as a replacement for "find and replace" whereas old VB6 requires it to be CTRL+H. Give me the option to configure it exactly how I'd like and I am sure we will all be happy.
Maybe I'm doing it wrong but I find that making new features configurable adds greatly to the time it takes to complete them.
If that's right then I'd prefer for there to be just one twinbasic way of doing things and I can easily live with that if it opens
my vb6 projects. That's the one thing I want.
As another chap here said, some of us will be working with VB6 probably at the same time as TwinBasic, I have real reasons for doing so. It will make life much easier if TB, being the successor to VB6 acts like it. All the tools I create are configurable, it is easy to do so, perhaps we will let the designers tell us how easy it might be for VS Code.
VS Code is extremely configurable in this regard. For example, if you want Ctrl+Y to do what VB6 does, it takes only a few seconds to set it up - details here
The Alt+Shift+Backspace combination isn't assigned to anything in VS Code by default, so it makes sense for us to simply assign that also to the Redo command in the twinBASIC extension. However, for the Ctrl+Y combination, we'll leave it at the more standard default of 'Redo', but you can easily change it as per the above instructions. We might offer an initial welcome/setup page when you first install the twinBASIC extension so that you can easily configure things like this.
Minor suggestion. I think having the IDE append a () after for any function call where the function has no parameters would help code readability. It feels really odd reading code where you see something like:-
instead of:-Code:v = GetValue
Imagine reading code like that 3 years later. It's not hard to envision that you might be wondering what the heck GetValue is. Is it a variable? A function? It needs to be unambiguous.Code:v = GetValue()
In my case I don't have to remap because I almost never use redo, and when I need it, yes, I have to go to the menu because there is no shortcut for it in VB6 IDE, and I acknowledge it is a bit cumbersome not having a shortcut.
BTW, in my case I don't use Ctrl+Y in any other program for redo either.
There are already customization options for shortcuts in the vscode IDE.
I wonder if the customization file can be saved (and restored after a new installation)
@Niya... there is now a restart-compiler button for you in the twinBASIC extension panel (or press Shift+Escape).
https://marketplace.visualstudio.com...asic/changelog
Just tested it with the code I posted in post #256 and it works great and very fast too. Barely takes a second to reload.
Niya has posted a twinBASIC Pure Win32 GUI Sample. It is a simple clock showing the power of twinBASIC even without its GUI tools.
Well worth a look.
https://www.vbforums.com/showthread....n32-GUI-Sample
If you think that's impressive, wait till you see what I'm doing now. I've taken the code from that project and built a very rudimentary GUI foundation similar to what we see VB6 and WinForms in .Net. So far I've created a Form class with some basic properties and events working.
Here is some code where I'm testing the Form's position related properties:-
All of this is implemented using pure Win32 with no dependencies.Code:dim f1 as new TBForm
f1.Show
debug.Print cstr(f1.Left)
debug.Print cstr(f1.top)
debug.Print cstr(f1.Width)
debug.Print cstr(f1.Height)
Already hugely impressive even in this very early preview, twinBASIC at last offers VB6 developers the hope of a way forward.
As long-time VB6 supporter Niya :D:D:D saysQuote:
Looks like you guys are getting your new VB6 after all. You guys have been waiting decades for this. Don't let this fail now.
Considering the potential importance of twinBASIC as a VB6 replacement, this thread really ought to be in the main VB6 forum, not hidden away under 'Other BASIC'.
Practically speaking I agree. I almost posted that TwinBASIC sample in the VB6 section but decided against it. TwinBASIC is technically it's own thing. Although it is 100% VB6 compatible right now, it does depart significantly from VB6 in it's extra offerings.
It's up to the moderators to decide what to do with these threads of course. Personally, I'd put them with the VB6 stuff until TwinBASIC gets powerful and popular enough to stand on it's own.
I'm gonna post the code to it when I finish it. Right now, I'm having trouble deciding how far to take it. I would like to implement at least one control like a Button but I might just end up stopping with just a Form class. I'm not sure where the finish line will be but when I reach it, I'll release the code for that.
I have a deep love for doing technical stuff like this which is what makes VB6/TwinBASIC interesting for me. You don't get to do stuff like this in VB.Net because it's all been done for you already which is good for productivity but not as fun as doing it yourself. However, it doesn't pay the bills. When I'm doing real work and I need serious productivity, I will stick with modern tools like .Net and Visual Studio 2019+. TwinBASIC would also fall in this category. Language wise, TwinBASIC strikes a cord almost perfectly between the power of VB.Net and the simplicity of VB6. And the Visual Studio Code IDE is comparable to modern versions of Visual Studio. I could really see myself using TwinBASIC for smaller workloads. Even at this early stage in it's development with all the bugs and glitches still unsolved, it feels a lot better than VB6 when writing code.
twinBASIC status update:
https://nolongerset.com/twinbasic-up...ugust-15-2021/
The current twinBASIC version is v0.10.4378
Highlights include IntelliSense improvements, a 12-month twinBASIC roadmap, and Niya's Win32 API GUI application written in twinBASIC.
While TwinBasic is similar to VB6, it is different - so the VB6 forum is not right, and OtherBasic is the place.
If it becomes popular (as it looks like it might), we would certainly consider a specific forum for TwinBasic.
That wouldn't be right I'm afraid, but feel free to post a link to this thread (along with some text if you like) in your signature, so it will be seen when people view your posts in the VB6 forum.
@WaynePhillipsEA
I just discovered something that could either be a breaking bug or perhaps it's nothing at all. Either way, I want to draw it to your attention.
Old school VB6 programmers know of this trick where you can pass VB6 COM object references to non-COM clients like the Win32 API. For example, if you have a Win32 or C++ API call that used callbacks, you could pass object references to the callback using this trick. The trick is to create an illegal reference to the COM object which is basically a raw pointer. You can then pass this to the API and when the API makes a callback call, you can dump that pointer back into a VB6 variable and use that variable as you would any object variable. The only catch is that COM would not be aware of this extra reference so if you allow this new variable to go out of scope without removing pointer, it could lead to disaster. I tried this trick in TwinBASIC and it works differently for a potential worrying reason. I'll post code so you can see exactly what I'm talking about:-
I describe the worrying behavior in the comments.Code:Module MainModule
Public Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal count As Long)
Private g_cls As New Class1
' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
Public Sub Main()
g_cls.ShowMsg
'Creates an illegal reference and let it go out of scope
DoIllegalRef
'This is not supposed to work. This would crash in VB6 and for good reason.
'We created an illegal reference and allowed it to go out of scope which means COM
'should have decreased the reference count and since we only have a single
'legal reference, that would have made the reference count zero which means COM
'should have destroyed this object. However in TwinBASIC as of v0.10.4380, this object
'is still alive. This could mean that either TwinBASIC is smart enough to know that it was
'an illegal reference and didn't decrease the reference count. Or it could mean there is a serious
'bug in the TwinBASIC compiler.
g_cls.ShowMsg
End Sub
Private Sub DoIllegalRef()
'Variable to hold illegal reference to the Class1 instance in the g_cls
'module level variable
Dim ref As Class1
'Creates an illegal reference to a Class1 object
'Because it was created this way, COM should not be aware of it and should not increment the
'reference count
CopyMemory VarPtr(ref), VarPtr(g_cls), 4
ref.ShowMsg
'In VB6 COM would decrease the refrence count of
'the Class1 object since the ref variable is about to go out of scope.
End Sub
End Module
Public Class Class1
Public Sub ShowMsg()
MsgBox ("Boo")
End Sub
End Class
The reference count is reaching zero at the correct point, and the object is being destroyed also. However, the memory allocation routines we use are different to VB6, and so the memory block might still be valid for the extra call to work... or it might not... as you're still playing with fire. Once the memory block gets reused/reissued, which depends on factors such as time and memory pressure, you will almost certainly get a crash.
BTW, if you add a Class_Terminate Sub to the class, you'll see the object get destroyed at the correct point:
Code:Public Sub Class_Terminate()
MsgBox "Destroyed!"
End Sub
Well that's very good news. I was concerned that TwinBASIC had some kind of bug in it's COM ABI.
Also, in case anyone who stumbles across this wonders if there is a way to make use of this trick and not get burned, there is. I don't know how other people deal with it but I came up with a way of dealing with it by essentially tricking TwinBASIC/VB6 into updating the object's reference count:-
You can use it like this:-Code:Private Function PtrToObject(ByVal ptr As Long) As Object
'This function allows us to create a COM object from just a pointer
'and makes sure that COM knows about it
'****************************************************************
Dim illegalObj As Object
Dim legalObj As Object
Dim zero As Long
'Create an illegal reference from the pointer
'passed into this procedure. This wouldn't increase the reference count
'which is bad.
CopyMemory VarPtr(illegalObj), VarPtr(ptr), 4
'This assignment increases the reference count of the object
Set legalObj = illegalObj
'Zero our illegal reference so TwinBASIC doesn't try
'to decrement the reference count when this function returns
CopyMemory VarPtr(illegalObj), VarPtr(zero), 4
'Return the legal reference
return legalObj
End Function
This method works in VB6 so I expect it would be acceptable in TwinBASIC as well.Code:Dim myObject As New Class1
Dim clonedRef As Class1
Set clonedRef = PtrToObject(ObjPtr(myObject))