Correct, nobody cared about "true" VB multithreading. Besides VB supported multi-processing very well, much better than the JS world does today. You could call objects between threads no problem. Behind the scenes it was using DCOM, so if you passed an object from one thread to another, the other thread would get a proxy that'd do RPCs to the first thread. So there was no true shared memory multithreading, but for VB users what they had instead was in some way even better, it was basically web workers but more transparent. Specifically, it meant that object calls couldn't run in parallel to UI updates or other logic so there was no need to think about locking.
But the whole thing of the UI being on the same thread was a really big problem. You could get around it by calling the Win32 Threads API but that would quickly lead to a crashfest due to the no shared memory thing. Electron doesn't have this problem because the UI is handled by the renderer, not the JS engine. So in that sense the UI is in a separate thread. This wasn't the case for VB6.
And events in VB6 were not great. They were good for the time, sure. Because they had to be. If you'd write an app in it today with lots of external API calls it'd be a mess.
VB6 was serviceable at the time but without multithreading support it didn't have a future in an ever more API-driven environment.
I don't quite understand what you mean by UI being in a separate thread. You could have background threads in VB from what I recall (it's been a while...). The only difference is that Electron/JS forces you to do your own IPC messages whereas Windows would abstract that out.
What I mean was that if you ran a large function that would take a few seconds, any UI redraw would be blocked completely for that time. So resizing a window would not cause a redraw of the UI until it came out of the function, pressing a button would not visually reflect the button status, basically it would seem like the application was hanging.
You could avoid this by peppering DoEvents in your loop. However, this was not always possible like if you were calling an external DLL function. I had an application that would talk to a Kodak digital camera by using their DLL and that would take considerable time.
It's really what separates a serious programming language from a toy, or at most a prototyping tool. Like Fisher Price, you can make something quick but it's not capable of actual use.
I think people have this rose-colored view because back in those days UX standards sucked and many apps had a lot of quirkiness. But times were changing and even a few years later this was unacceptable.
There were no official background threads, you could use the Win32 Threads API but it would cause instability due to not having memory protection.
But this "hanging" behaviour was really not suitable for a general purpose application. Electron doesn't have this issue because the renderer is independent from the javascript code.
but from looking it seems like people were doing it by writing VB that ran in a separate EXE and then indeed, COM would let you do RPCs between the different processes. So multi-processing rather than multi-threading.
Javascript is better at asynchronism than VB was, and in Electron the user interface does run in a separate process. Unlike Visual Basic 6, where the UI would completely hang when you were busy with some external function call.