Monday, January 31, 2022

Virtual Fox Fest 2022 (May)

Our one-day Virtual Fox Fest 2022 (May) will be Thursday, May 5, 2022. It still has the same great features everyone loves about VFF: great speakers delivering great sessions, live chatting during presentations, and getting to hang out virtually with new and old friends. This event will feature classic sessions from previous conferences, updated for 2022. 

We’re still discussing whether to hold Southwest Fox in Arizona this fall. We hope to announce our plans for a fall conference before our May event.

Wednesday, January 26, 2022

Speeding up SQL Server Management Studio Startup

SQL Server Management Studio typically takes a minute or so to start on my machine. I just figured it was a slow app, but then I saw it load much faster on another machine. Searching for a solution led me to Microsoft SQL Server Management Studio is too Slow (, which nicely solved the problem. Now it starts up in five seconds.

(As an aside, I use a hosts file from Steven Black's to help block malware and adware.)

Monday, January 03, 2022

How Thor Survives CLEAR ALL

You may be aware that Thor can survive a CLEAR ALL. (If you aren’t familiar with Thor, you really should be: While that seems impossible, it’s actually pretty simple but does require that Thor be designed in a certain way.

As you know, CLEAR ALL nukes all objects (among other things; see the VFP help for a complete list of what it affects). And yet, after executing CLEAR ALL, if you choose any of the functions in the Thor menus or use one of the hot keys you’ve assigned in Thor, it works. How is that possible?

The secret is that _SCREEN and _VFP are the only objects that survive CLEAR ALL. Object members of those objects don’t survive but non-object members retain their values. When Thor starts up, it creates a new property of _SCREEN called cThorDispatcher and puts some code into that property. Near the start of that code is the following:

If PemStatus(_Screen, 'oThor', 5) = .F. or Vartype(_Screen.oThor) # 'O'

   _Screen.AddProperty('oThor', Newobject ('oThor', 'Thor.vcx', lcThorApp, lcThorFolder))


So, if there’s no oThor member of _SCREEN or it doesn’t contain an object, that property is created and the main Thor class is instantiated into it.

How does that help? It turns out that most places that call Thor functionality don’t execute code like _SCREEN.oThor.SomeMethod(). Instead, they use code like this:

loThor = execscript(_screen.cThorDispatcher, 'Thor Engine=')


Of course, Thor had to be designed to support that: every place that calls Thor methods has to go through the Thor dispatcher rather than calling them directly.