Thursday, August 18, 2011

XP-SP3 cleanup

Last night I installed a Microsoft XP Mode  virtual machine under VMware
I was having several problems with the project:
  1. In order to initiate connection from the host's file server to the guest machine's application, I was forced to manually ping the guest IP from the host..  I was disappointed with that situation.  Today, I went researching on the VMware support forum and found this thread.  With the suggested method. I think I have cured my connectivity problem.
  2. The VM environment seemed sluggish, with the cursor disappearing for several seconds at a time and the VM becoming unresponsive.  I subsequently discovered that my blog editor interface, which was open in a browser on the host, was at least partially responsible.  I will be using a different editor in the future and will try to assess how much lag remains with in the VM.  A quick review this morning, showed promising improvement. 
  3. I was waiting for a fix to an crash I was experiencing while deleting all records from a volatile (memory only) file in my application.  SIMPOL tech support sent me a new library for volatile files and I will test it soon.  I'm expecting to put that issue behind me. 
  4. I was also having an application crash when I tried to open a second window in my application.  SIMPOL tech suport (thanks Neil) reviewed my sample app and explained what I was doing wrong.  Soon, I will revise the logic accordingly and move on with the application.  My next step will be to install Linux and try the app in that OS.
The latter two items have nothing to do with the virtual machine or XP Mode installation, but they are the tech support issues that were preventing me from progressing with the conversion.  Nothing more to report today.  I'm still groggy from last night and want to get more sleep.  More news perhaps tomorrow.

djinks         Apps and Services:

Installing XP-SP3 under VMware

I received no response to my support request on the VMware forum.  After some thought, I decided that I may not have rebooted after installing the VMware Player.  I deleted the previous VM, rebooted and imported the XP Mode machine again.  This time, I did not touch the default machine configuration.  I had expanded memory on the previous attempts, but decided to keep things standard to see if that made a difference.  This time I made it through setup and now am installing software.  Seems I have to start with a fresh XP Mode install.  No issues with crashing.

Windows immediately started complaining that anti-virus software was not installed, so I decided to install Microsoft Security Essentials this time.  I normally use Zone Alarm Internet Security Suite or Symantec Norton Internet Security suite, but MSE is free, has good recommendations from Windows Secrets, my favorite and only technical newsletter, and this is just a virtual machine.  I thought I might as well try it out.

After installing that, I needed to install VMware Tools, which I think are what make integration of the Virtual Machine with the host OS work better.  That has now finished installing, so I will attempt to upgrade the memory (from 256KB to 2GB) and make sure I can see and access the host's physical hard drive, at least the folders I need. 

Now the VM is configured and I have installed Superbase Classic.  I have tested my medical practice management application and it runs fine.  I tried the contact management application and it cannot connect to the host machine.  It needs to communicate via UDP on two ports with a SIMPOL file server on the host.  I have the VM set up in network adapter bridge mode, which means it has a separate IP address from the host.  I cannot ping between them, even with personal firewalls turned off.  Both machines can ping the gateway and other machines on the network.  I rebooted the VM and now have some connectivity.  However, I must open a command prompt and ping the guest VM's IP from the host before I can connect the file server on the host to the Superbase client on the guest VM.  I was able to turn on the host and guest firewall and still get the connection, but that pinging nonsense needs to be fixed.  I must post another note in the VMware forums to see if anyone else has experienced this.

I also want to see how do I install my app so that it shows up in Unity.  Unity is VMware's method for making apps in the virtual machine show up on the host's desktop, appearing to be native applications.  It adds popup menus just above the host's Start Button and hides the VMware player. Anything that you launch from the Unity menus appears to be part of the host.  That is similar to Virtual Applications used by Microsoft's XP Mode.  I mentioned Virtual Applications in an earlier post.  I mention it here because users don't really want to know or deal with the complexity of virtual machines, so I have to make everything look seemless.

I'm still experiencing lag with VMware, so I may need to live with it, until I replace my development machine with an Intel i7 CPU.  It may not be VMware's fault.  I just noticed the browser interface doing the same thing as I type this blog. I think those pauses are due to the blog being saved automatically while I type.  I'll try to be more observant and determine what is really going on. 

Anything else will need to wait, though.  I have stayed all night working on this and I now need to sleep. Next I'll install Linux in another virtual machine.

-djinks         Apps and Services:

Tuesday, August 16, 2011

VMware Player

To test my applications under Linux, I have decided to install the VMware Player from VMware.  It is a free product, so I made an easy decision to check it out.  I have been using Microsoft Virtual PC for over a year with my Windows 7 64-bit operating system on my laptop/development machine.  I installed it to accommodate a client who purchased two machines with Windows 7 x64 installed.  With Windows 7 x64, Superbase must run in a virtual machine inside a 32-bit Windows OS.  Superbase installs and runs fine in 32-bit versions of Windows, but needs help in 64-bit versions.  That is why I am converting my application to SIMPOL.

Windows Virtual PC and Windows XP-Mode are free downloads from Microsoft for licensed copies of Windows 7 Professional and higher.  They are not available for the Home editions.  Windows Virtual PC is the Microsoft program that runs virtual machines.  Windows XP Mode is the Windows XP-sp3 version that is licensed to run on Windows 7 Professional and higher. 

Windows XP Mode under Windows Virtual PC works pretty well, but there are a few issues: 
  1.  Getting printers to work was a bit difficult.  
  2.  Setting up virtual applications are difficult.  They are applications running in the virtual machine, but the VM is hidden and the application is launched from a shortcut on the host machine's desktop and displays as though it was running natively on the host. I know the tricks to doing that now, but spent much more time than I wanted to learn what worked and what did not.  
  3. Some times the virtual application cannot connect to shared folders on the host.  If that happens I may have to shut down the VM and reopen.  That is OK for me, but I don't like training clients to do that and they don't want the hassle of needing to do that.
  4. Most disturbing to me is that the Superbase program editor can be quite laggy.  Not always, but more often than not, I must wait one to several seconds for the cursor to move or my keystrokes to appear.  This is not normal behavior when running Superbase in a native OS.
For those reasons, I wanted to try an alternative to Windows Virtual PC, so I downloaded and installed the (free) VMware Player.  The current version (3.1.4)  can import Windows XP Mode machines.  Here are the best instructions I found for how to do it.  Unfortunately, the instructions are for a newly installed XP Mode Machine.  Mine has been installed for over a 18 months and I have several applications installed.  I can import it, but cannot run it without crashing the VM.  I posted a note in the VMware online support community asking what to do.  Now I need to wait for a response. 

I'm also waiting on two issues from SIMPOL tech support.  Hopefully I will have a usable response from someone tomorrow. 

-djinks         Apps and Services:

Monday, August 15, 2011

Syncing the Windows

I worked on correcting the master record in the second window today.  Master records for both the main form and the second (notes) form should be the same.  What is a master record?  The one that any child records link to.  If the form is a browse form (multiple records in a detail block) the master record is (in my designs) displayed at the top and the related child records are displayed in rows further down the page.  In this case the main form displays details from the master record and the second form displays notes related to the master record, with a few identifying items from the master record displayed at the top.

I had both forms displaying yesterday, but the master record data was not always the same (synced) as I wanted.  Today I tried to resolve that.  I discovered I was not using the same datasource for both forms, which was why some master records could not sync.  Each form has a built-in datasource for each file that is saved in the form by the Forms  Designer.  In my program I am supposed to override that definition, by opening the file (datasource) before I open the form.  In the second form, I was not doing that, so the form used a small test file in different directory to load the master table.  The records in that table did not always match those in the master record on the main form.

I spotted the difference in the master tables because of some code that checks record count for that table.  I noticed only 6 records in the master table for the second form.  I knew there were over 1000 records in that file, so I went looking for what could cause the difference and confirmed I was not opening the master table for the second form.

I also had a note from the SIMPOL tech support that I did not need to perform a selectkey operation on the second form's master table, but should be able to copy the master table object and master record object from the first form into the second. I went back and changed that code accordingly.  After a bit of tinkering, I was able to confirm that the second forms master record contained the right data.  Whenever I am in doubt as to what is going on, I can usually use the object browser, built into developers IDE to check the value of various objects.  Unfortunately I cannot check the value of a record's fields with it.  Fields must be run through a function to convert them into a readable format.  In these cases, I place statements in the code to convert the field values into a string, number, or date that I can see in the variables watch panel.  The statements are just there to help me when debugging.  Using these statements, I could tell that the correct master record was being used in the second form.

Unfortunately, I am unable to see the form now as a program crash is occurring after my code has finished. It is one of those cases where an error is occurring beyond the reach of my debugger.  I have the source code for just about all the furnished libraries, so I can debug into the them, but the function where the error occurs is not among the source I have in the project.  I prepared a sample project demonstrating the error and shipped it off to my SIMPOL tech support contact.  Neil has been very helpful with these issues where I cannot debug the code for lack of source, and I try not to give him anything until I have exhausted my abilities.  I'm sure he will be able to find the problem soon.

In the meantime, I can make preparations to install Linux in a virtual machine on my computer so that I can start testing the code on a second operating system.

-djinks         Apps and Services:

Sunday, August 14, 2011

Multiple Windows

I worked the last two days on adding a second window.  When the user clicks on a button in the main window, a second window will open and display  a form for browsing through multiple notes created for the main form's current contact record. It took a while to get this going.  The examples showed how to do this, but with a wxwindow object, the underlying windows object.  I needed to do this with the appwindow object, which was derived from the wxwindow object, but has more properties and methods and belongs to the SIMPOL appframework library.  There were no examples of this, so I had to deduct what to do.  Basically I followed the code for creating a new window and modified it to just add a window (type appwindow) to the existing application.

The main thing to learn here, and actually throughout this entire blog, is to learn to navigate and explore the object heirarchy that is provided.  I studied the appwindow object and saw that there was method.  I scanned the sample code projects and saw how it was used to create a primary window, then extrapolated what must be changed to produce a secondary window.  After several false starts, I created a second window.

The more difficult part was to sync the two windows.  I wanted the main record in both forms to be the same, so I needed to determine how to access the main application window's data while creating the second window.  That took a bit of digging, again through the object heirarchy, and several false starts.  I originally wanted to get the main form's master record and set that as the master record for the second form, but I had no luck.  Then I decided to just get the key from the first form's master record and use that to select the record for the second form's master record.  Each window's form has a select key method, so just needed to find the key value for the main form's master record and use that to select the record for the second form.  (Each window contains a form so second form means second window.)

Determining the exact syntax for doing all this required most of my time.  I'm new to the object heirarchy and took longer to find the exact syntax.  The more I learn, the faster I progress.  Finally I had a second window displayed, but there were problems.  For the master record on the second form, I only displayed the first record in the master file,  not the same record as the main window displayed.  I wanted to display multiple notes in the second form that matched in record in the main form.  The master record for both forms must be the same.  Anyway i finally worked out the syntax and I now have both forms displayed.

Well, there still are some problems to work out.  The same master record shows all the time on the second form.  In certain situations, I generate a third window, similar to the second. I'm tracking those down tomorrow.

Overall, I am pleased though.  I have a multi-window application and that is not trivial.  It looks pretty good and I'm confident I can fix the problems.  Soon I'll be moving on to the real purpose of this blog, running the application on more than one operating system.. Stay tuned.

-djinks         Apps and Services:

Wednesday, August 10, 2011

The Main Form

I revised the main form today, in preparation for  creating a multi-window application.  The idea is to have the main form (comprised of page 1 and page 2) show first.  Then, as the users needs, pop-up a second window to review notes (page 3).  Finally there will be a fourth form for adding/changing a note (not yet converted from the old system).

This took a while to get the pages the way I wanted them to look, so that is all I have to show today.  Maybe tomorrow I'll actually try to have the app load both windows.  Today, I looked at the SIMPOL example for displaying multiple windows in an app, and it looks easy.  I'm sure it will be a bit more involved with the way I want the windows to work, but I'm not expecting a major issue.

-djinks         Apps and Services:

Saturday, August 6, 2011

Form Control Part 2 - Resizing the Form

This a continuation of my experiences building this form

First, I need to correct something I said in Part 1:  "With the old system, Superbase, I could just add a where clause to the detail block definition to filter the data, but in the new system, SIMPOL, I did not yet have that ability.  I therefore wrote a filter routine to check the records before adding them to the subset file, which linked to the form."  I have since learned there is indeed a way to add a where clause to a detail block. If the detail block is not linked to the master record, you can set the parameters of the detail block to include a SQL92 compliant where clause.  I tried it initially, but did not have the syntax quite right, so I did not get the desired result.  Anyway, I have already developed a filter routine that works, so I'm not going back to retry the unlinked query approach, but it is there if I need it.

I was still working on this form but I could not get the event handler for the option buttons to work. They allow me to filter the records displayed in the form's detail block.  In fact, the development environment would crash when I tried to debug the source code.  It took a couple of days, but SIMPOL support were able to identify and resolve the problem.  It turned out to be an issue specific to my operating system (Windows 7 64-bit) that could not be reproduced on SIMPOL support's machines because they were using Windows Vista.  I let the technical director (sorry Neil, I'm not sure your real title) debug the problem on my machine.  It involved connecting using remote control software called TeamViewer and installing MS Visual Studio.  Neil was able to find and fix the issue.  I was sympathetic to Neil's plight.  I have been it the same position myself, not being able to reproduce the problem locally and needing to use remote control software to debug remotely.

Next, I decided to make my form resizeable.  Why? I have clients with different monitor resolutions, ranging from 800x600 to 1920x1080.  The standard form is designed to work in the minimum screen size, but that is too small for some of the users, with the highest resolution monitors.  The form needs to be readable regardless of the monitor, and on the large resolution displays, the text can get tiny. 

I decided to allow three resolutions to start: original - 100%, 125%, and 150%.  I added a Form Size menu and added these options to on it.  Further, I decided an Auto option was required.  The Auto option would be the default and the program could determine the display size and decide what was the optimum form size to fit.

I was going to hook everything up to a new menu, "Form Size", but I decided to first write the code and test it that did the real work.  This involves iterating through all the form objects and changing their position (top and left corner) and size (width and height) by the specified amount. I discovered there are actually several collections of objects that I had to work on, the form controls, the pages collection, the graphics collection, and the detailblocks collection. 

Actually, the each page has it's own controls collection, so I did not need to deal directly with the forms controls collection.  Actually collections is a Superbase or Windows term.  SIMPOL uses the term "dring".  A dring is a list of objects linked together and you can go from one to the next in the list and when you reach the end, the next retrieved is the first object again.  (That is the simple definition.) 

Even though I was dealing with a single page form, I wrote code to assume a multi-page form, so I could reuse the function later with multi-page forms.  I cycled through the pages collection first and changed the size of each page, then cycled through the page's controls dring and changes all the controls. When all pages were processed, I cycled through all the form's graphics elements doing the same thing.  Finally, I cycled through the form's detailblocks, changing the offset between rows.

Once I had the form resizing working (at application start-up), with a specified re-size percent, I added the menu and menu items and tried to get it to work on demand.  Adding a menu and menu items was straight forward, but things did not go smoothly.  I needed to work out the logic for restarting the form on the fly.  Up to this point, the program re-sized the form before it was shown to the user.  Now I was letting the user decide to change it and reload the form.  So I muddled around with that until I had the restart working smoothly. 

The final piece of was saving the users selected resizing option in a configuration file, so that the application could use the same setting the next time it was launched.  There is a library supplied with the development environment (conflib.sml) that handles reading and writing to private configuration files.  I added the library to my project, looked up how to use the getprivateprofilestring and writeprivateprofilestring functions, and got them working rather quickly.

This single form project is now relatively compete, but there are a few things missing.  I still need to add logic to filter the detail block records by date, but I may leave that until later, as I don't consider it very hard.  I am also waiting for a revised volatable library that will allow me to delete all records in the (volatile) 'notesubset' table. 

Any time you click one of the option buttons on the form, the app deletes all records in the notesubset table and reloads the table, filtering the records that can be loaded according to the user selection.  My current approach is to delete records one-by-one until the table is empty, but if there are more than 51 records, the delete record statement is hanging.  The problem appears to be beyond the reach of my debugger, so I have asked my SIMPOL vendor to take a look. The problem has only been detected because I am using volatile files in a different way than they were originally designed.  Using physical files, I did not have a problem. I'm using a volatile file because a memory-based file should be faster at deleting records. (I like my apps zippy.)

Once those items are addressed, I think I will progress to the next stage, hooking up the main form and making the app a multi-window application.  I have researched how to add an additional window to the app.  It seems easy enough and I am itching to get started.

-djinks         Apps and Services: