Monday, November 14, 2022

Bulk Copying VFP Data to SQL Server

The VFP Upsizing Wizard does a great job of upsizing a VFP database to SQL Server. However, after doing the initial upsizing, you may wish to re-upload the content of one or more tables with doing a complete re-upsize. A new tool, SQLBulkCopy, available from https://github.com/DougHennig/SQLBulkCopy, is great for that.

Thursday, October 27, 2022

Virtual Fox Fest 2022 (October) Follow-up

Here are some follow-up notes about Virtual Fox Fest 2022 (October):

  • Videos for all presentations are now available on YouTube for free to everyone, as our contribution to the VFP community. Be sure to subscribe to our channel.
  • If you didn't attend Virtual Fox Fest and want materials (white papers and sample code) for the presentations, go to  https://geekgatherings.com/Registration and "register" for the conference. You're not really registering since it's over, but in the Registration Fees section of the registration page, you'll see "Virtual Fox Fest Session Materials" for previous events. There's also an opportunity to sponsor Virtual Fox Fest, which means your name will be listed on our Sponsors page.
  • If you didn't attend Virtual Fox Fest, check out our Facebook page and see what you missed, then plan to attend a future one so you can join in the fun.

Tuesday, September 13, 2022

Virtual Fox Fest 2022 (October): Don't Forget or Regret

Thanks to all who have registered for Virtual Fox Fest 2022 (October). Early registrants help us plan ahead. This is another friendly reminder to the rest of you that it takes just a few minutes to register.

We're really excited about this year's Virtual Fox Fest line-up and we know you will be, too. You can find all the details:

You can order your Virtual Fox Fest gear anytime. If you don't like the items or colors we've chosen, click on any item as a starting point and then click "Customize This Product" to choose the product and color you really want.

Virtual Fox Fest is October 13th, 19th, and 25th, 2022.

Monday, August 29, 2022

Virtual Fox Fest 2022 (Oct): Early-Bird ends in 2 days

Last call! (we want to make sure we have your attention)

The Early-Bird discount ends midnight (North American Eastern time) on Wednesday, which is just a couple of days away. Here is the direct link to get registered: http://geekgatherings.com/registration.

Virtual Fox Fest is October 13, 19, and 25, 2022.

Tuesday, August 16, 2022

Virtual Fox Fest Registration Reminder

Thanks to all who have already registered for Virtual Fox Fest; we appreciate your support and our speakers are excited to share their sessions with you soon. Please register for Virtual Fox Fest before September 1st, our Early-Bird deadline. We know you are interested in saving $50, and we would appreciate processing the bulk of the registrations in August. Perfect synergy! As a bonus, we won't process your payment until September. It takes just a few minutes to register. Virtual Fox Fest is October 13, 19, and 25, 2022.

Thursday, August 04, 2022

Virtual Fox Fest 2022 (October): Speakers, Sessions, and Registration

Speakers and sessions for Virtual Fox Fest 2022 (October) have been announced, and registration is open!

While I’m of course interested in all the sessions, the ones that interest me the most are Joel Leach's DevOps with Visual FoxPro and Rick Borup's Switching to SQL Server. I have no experience with the former so I'm keen to learn about it and have lots of experience with the latter so I'm interested in Rick's take.

Virtual Fox Fest is October 13, 19, and 25, 2022. The cost is $299 US but register before September 1 to save $50.

Saturday, May 21, 2022

Formatting Grids Dynamically

I've been working with grids a lot lately, and find setting them up very tedious: set ColumnCount to the desired value, set ControlSource and other properties such as InputMask and Alignment for every column, set Caption and other properties for every header, etc. To make matters worse, if you change the RecordSource for the grid, ControlSource gets reset for every column so now you have to go back and fix them. To matters even worse, if you need to add a new column between two existing ones, you have to move all the property settings for the subsequent columns. (Yes, I know you can just increment ColumnCount and set ColumnOrder for the new column to the proper value, but then the visual appearance of the grid doesn't match the column order in the Properties window. Do that a couple of times and then have fun trying to find a specific column.)

So, I decided to format grids programmatically. At first, I wrote a lot of code like this:

with This.grdOrders
   .ColumnCount  = 22
   .RecordSource = 'orders'

   .Column1.ControlSource   = 'orders.line'
   .Column1.Width           = 30
   .Column1.Header1.Caption = 'Line'

   .Column2.ControlSource   = 'sorder.item'
   .Column2.Width           = 40
   .Column2.Header1.Caption = 'Item #'

   * more code here for the rest of the columns
endwith

That too grew tedious quickly. So, I decided to dynamically format the grid at run time rather than design time. I added a SetupColumns method to my grid base class with code that accepts a format string and applies it to the grid. Then in an instance of the grid, I write code that sets up the format string and calls SetupColumns. Here's an example:

text to lcColumns noshow
Field		|Width	|Caption	|Alignment	|InputMask	|ReadOnly	|Control
Invnum		|70	|Invoice #	|		|		|.T.		|
Date		|70	|Date		|		|		|.T.		|
Name		|*	|Project	|		|		|.T.		|
Amount		|60	|Amount		|1		|99,999.99	|.T.		|
Hours		|40	|Hours		|1		|999.99		|.T.		|
Paid		|70	|Date Paid	|		|		|		|Checkbox
Received	|60	|Received	|1		|99,999.99	|		|
endtext
Thisform.grdInvoices.SetupColumns(lcColumns)

Here are some rules for the format string:

  • The format settings must be in this order and have a header row like shown above
  • Separate format settings with tabs and a pipe
  • "Field" is the field name (aliased or not)
  • Use a tab for an unspecified value, such as Alignment and InputMask for most of the entries in the example
  • Use "*" for Width to "auto-size" a column; that is, size it to the rest of the space after the other columns are sized
  • Control specifies what control to use for the column. Currently only Checkbox is supported but others could easily be added

Now setting up a grid is just a matter of filling out an easy-to-understand "table" of column settings. Need to add a new column in the middle of the grid? Just add a new line to the table.

However, it's still slightly tedious because you have to run the form the grid is on to see what it looks like, close the form, edit the table (adjust column widths and alignment, for example), run the form again, rinse and repeat. So, I created a builder named SFGridBuilder that does the same thing at design time. Select the format string without the "text" and "endtext" statements, copy it, invoke the builder, and ta da, the grid is formatted at design time. Tweak the string, copy it, run the builder again ... repeat until perfect. This builder works with any grid, even a VFP base class.

How do you invoke the builder? Any way you normally would:

  • I added a Builder property to my grid base class and set it to SFGridBuilder.prg
  • You can register it with Thor and invoke it through a Thor hot key or menu
  • You can register it with Builder.app
  • You can run it directly: do (path + 'SFGridBuilder')
Rick Schummer did a session at Virtual Fox Fest 2020 about builders, so watch the video for details.


Monday, May 09, 2022

Virtual Fox Fest 2022 (May) Follow-up

Here are some follow-up notes about Virtual Fox Fest 2022 (May):

  • Videos for all presentations are now available on YouTube for free to everyone, as our contribution to the VFP community. Be sure to subscribe to our channel.
  • If you didn't attend Virtual Fox Fest and want materials (white papers and sample code) for the presentations, go to  https://geekgatherings.com/Registration and "register" for the conference. You're not really registering since it's over, but in the Registration Fees section of the registration page, you'll see "Virtual Fox Fest Session Materials" for previous events. There's also an opportunity to sponsor Virtual Fox Fest, which means your name will be listed on our Sponsors page.
  • If you didn't attend Virtual Fox Fest, check out our Facebook page and see what you missed, then plan to attend a future one so you can join in the fun.

Virtual Fox Fest 2022 (October): Call for Speakers

We're excited to offer you Virtual Fox Fest 2022 (October), a three-day online conference presenting the latest in Microsoft Visual FoxPro development techniques and interoperability with other technologies. This conference provides a venue for VFP developers to come together virtually to learn more about how our fellow developers are using and extending VFP. For details about Virtual Fox Fest, please see https://virtualfoxfest.com.

The conference is going to be on October 13th, 19th, and 25th, 2022. 

We've issued the Call for Speakers for Virtual Fox Fest. If you are interested in presenting, please read the document referenced at https://virtualfoxfest.com/CallForSpeakers.aspx and consider submitting sessions.

Tuesday, April 26, 2022

VFF 2022 (May) Last Chance

Thank you to all who have registered for Virtual Fox Fest; we appreciate your support.

We are down to the last minute and the registration squad is providing one last incentive to get you to register now because the next week is already busy. While we don't mind registering people at the last minute, it is hectic just before the conference and it is much easier to process registrations today than it is the day before or the day of the conference.

Our friends at DBI want to help incentivize you to register in the next 24 hours and have provided us licenses to their awesome products to give away.

1. Two (2) Studio Controls COM 64 Full Developer Licenses (each a USD $699 value, https://www.dbi-tech.com/ProductPage_studiocontrolscom64.aspx)
What's included:
  • 25 Modern Unicode, 64 bit and 32 bit UX Design ActiveX Controls
  • Multiple Access Demos for each component high lighting key industry tested features
  • Detailed, individual component help files
  • Tutorial style 'Developing With' per component help
  • 32 - bit design and Deployment controls
  • 64 - bit Design and Deployment controls
2. One (1) Solutions Schedule COM 64 Version 4.0 (not yet released to the public, USD $1499 value, https://www.dbi-tech.com/ProductPage_SolutionsScheduleCOM64.aspx) Full Developer License
What's currently included:
  • Royalty-Free distribution
  • Source Code Samples written in VFP
  • Compiled (.exe) Samples
  • Annual Product Upgrade Service
  • Direct Access to the Product's Technical Support Group
  • Online license management
  • Online Software Activations
3. Two (2) $100 Microsoft Store Gift Cards.

So here is the deal. Everyone who is registered before 3:00pm (North American Eastern Time, GMT -4) on April 27, 2022 has a chance to win one of the five give-aways, including those who registered earlier. We know this is important so here is the link to the registration site to make things easy: http://geekgatherings.com/Registration

Thursday, April 21, 2022

Virtual Fox Fest: Time to Register

Thanks to all who registered for Virtual Fox Fest; we appreciate your support. This is another friendly reminder to the rest of you that it takes just a few minutes to register, here is the link: register me now

Emails to registered attendees begin next week with all the details about the conference.

You can order your Virtual Fox Fest gear from https://geekgatherings.logosoftwear.com/.

Virtual Fox Fest is May 5, 2022! Only 15 days until we gather virtually via the Internet!

Tuesday, April 05, 2022

Virtual Fox Fest 2022 (May): Registrations available

Friendly reminder: if you have not registered for Virtual FoxFest 2022 (May), head on over to https://geekgatherings.com/Registration and get it done before you get distracted again by work. It is important for your long-term development career.

Tuesday, March 22, 2022

Time to Register for Virtual Fox Fest

Virtual Fox Fest 2022 (May) is a one-day event on Thursday, May 5, 2022. We have some great speakers delivering great sessions, live chatting during presentations, and getting to hang out virtually with new and old friends. This event will feature a mix of new and classic sessions from previous conferences, updated for 2022. Registration details, deadlines, and cost are available on our Web site. Register for the conference here: http://geekgatherings.com/Registration. Don't procrastinate, get this done today!

We're still discussing whether to hold Southwest Fox in Arizona this fall. We expect to announce our plans for a fall conference some time in April.

More details here: https://virtualfoxfest.com 

Wednesday, March 16, 2022

Sending Emails with Modern Authentication

Thanks to Matthew Olson, who did most of the work figuring how to implement this, I've added support for Modern Authentication to SFMail, a VFPX project providing a library to send emails from VFP applications.

Basic Authentication is simply providing a user name and password to connect to a mail server. More and more mail services have already or are soon moving away from Basic Authentication and implementing Modern Authentication, also known as OAuth2. Modern Authentication uses a two-step process to connect to a mail server: first obtaining a token (a string) from a web server, then using that token to connect to the mail server.

Gmail and Office 365 are two of the services moving away from Basic Authentication sometime in 2022. The SFMail repository has detailed documentation for working with Office 365. I started investigating Gmail, but according to https://support.google.com/cloud/answer/9110914, access to Gmail is considered to be a "Restricted scope" and requires undergoing an annual independent, third-party security assessment. That seems like a pain, so I'm not planning on doing much with Gmail yet. However, based on what (little) I know about OAuth2, I believe that SFMail will work with Gmail.



Friday, March 11, 2022

FoxyDialogs and ctl32: Working Together at Last

Cesar Chalom is one of the best VFP developers in the world, and a great contributor to the VFP community. FoxCharts, FoxyPreviewer, and GDIPlusX are just some of the things he's created or contributed to.

A couple of years ago, he released another tool: FoxyDialogs. This cool add-on provides an incredible amount of control over MESSAGEBOX-style dialogs, so much so that you may do away with creating custom forms for some types of dialogs. For example, one line of code creates this dialog:

FoxyDialog("Covid-19 crazy warning - See the timer -->", ;
    "Please stay home!", ;
    " - Clean your hands often." + CHR(13) + ;
    " - Avoid close contact with people who are sick." + CHR(13) + ;
    " - Stay at home as much as possible." + CHR(13) + ;
    " - Put distance between yourself and other people." + CHR(13) + ;
    " - If you have a fever, cough and difficulty breathing, seek medical attention." + CHR(13), ;
    "!2", ; && Exlamation default with yellow backgound (default)
    "\More Info_99,I agree_5341,Leave me!_89,Ok_116802", ; && Button captions, 1st button disabled
    2, ;  && Default button
    "8000,<SECS> secs.") && Timeout


As excited as I was about FoxyDialogs, I quickly found that it doesn't work well with ctl32, Carlos Allotti's library of components such as BalloonTips, date pickers, status bars, and so on (I would provide a link but sadly his web site is long gone). Trying to call FoxyDialogs after using a ctl32 component causes an error. So, I had to abandon FoxyDialogs because I use ctl32 in most of my apps.

However, recently on Foxite, Daniele Rieffoli of Italy and Tomislav Sokol of Croatia posted about solutions they'd found to the problem. The problem is that both FoxyDialogs and ctl32 use VFP2C32.fll, a library that provides low-level functions that make it easier to work with some Windows API functions. Unfortunately, they use different versions of VFP2C32.fll, causing the conflict. (You won't find the actual FLL with the ctl32 files; ctl32_vfp2c32.prg, which is called by ctl32 components, creates it in the user's temporary files folder if it doesn't already exist.) If a ctl32 component is used before FoxyDialogs, it loads the older VFP2C32.fll, and FoxyDialogs errors on the BINDEVENTSEX statements in its DialogCreated function (BINDEVENTSEX is one of the functions in VFP2C32.fll) because it expects different parameters than the older library does. Using the newer VFP2C32.fll doesn't work because ctl32_vfp2c32.prg calls InitVFP2C32 and that function no longer exists in the newer library. 

The solution is actually simple: use the version that comes with FoxyDialogs and SET LIBRARY TO it at startup before anything in ctl32 is used. When a ctl32 component is used, it calls ctl32_vfp2c32.prg, but that PRG sees that VFP2C32.fll has already been loaded, so it does nothing. None of the ctl32 components I tested had a problem with the newer library, so now they both work together.

Monday, February 28, 2022

New VFPX Project: Object Explorer

As you may know, Matt Slay passed away in 2021. He was a great contributor to the Fox community and VFPX and is greatly missed.

The last tool created by Matt and his friend and frequent collaborator Jim Nelson is Object Explorer, which provides an explorer form to view members of the specified object. Jim has kindly agreed to include this tool in VFPX, so it's available there now.


Object Explorer is a very useful tool for debugging applications, including at runtime. I've just implemented it in my applications so time will tell how often I use it, but Jim and Matt used it a lot, and Tore Bleken allows certain end-users to use it to customize applications.

I made a few tweaks to the original code to fix some minor issues I ran into; see the "2022-02-28" release notes for details. I also created my own copy of Explorer.scx named SFObjExplorer.scx, with Desktop = .T. and this code in Init so it uses Segoe UI rather than the default Arial:

Lparameters toObject, tcObjectName, tcFormCaptionSuffix

dodefault(toObject, tcObjectName, tcFormCaptionSuffix)

This.SetAll('FontName', 'Segoe UI')

This.TreeContainer.oleTree.Font.Name = 'Segoe UI'


Thursday, February 03, 2022

Matt Slay

Matt Slay was a great contributor to the Fox community and a great guy. Sadly, he passed away in October 2021. He is sorely missed.

However, his legacy lives on: the VFPX administrators have forked his projects and changed the project list links to the new repositories so community members can continue Matt's work.

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 (archive.org), which nicely solved the problem. Now it starts up in five seconds.

(As an aside, I use a hosts file from Steven Black's https://github.com/StevenBlack/hosts 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: https://github.com/VFPX/Thor.) 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))

EndIf

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=')

loThor.SomeMethod()

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.

Ingenious!