Using SnagIt with dBASE PLUS
by Christopher F. Neumann
 
   

Why SnagIt?

In the past I have had requirements to “scrape” the text off of the windows of other applications. I tried many third party applications and none of them fit the bill except SnagIt from TechSmith.com. The hardest part of this feat was getting SnagIt configured correctly!

SnagIt enhances the functionalities of the Print Screen key: it captures a screen shot then allows the user to add annotations or to improve to the captured image with its image editor. Actually, it can capture a rectangular shape anywhere on your desktop and can capture the contents of a window, including the part not seen.

Using SnagIt as a DDE Server

SnagIt is a fully functional Windows Dynamic Data Exchange (DDE) server. You can use SnagIt’s DDE support to incorporate SnagIt functionality into custom or commercial Windows programs that support DDE. For example, you could write a Microsoft Excel macro to print a portion of the screen using SnagIt. Some of the parameters used are addressed in the TechSmith’s DDE Server guide.

Specifics for my example

  1. This code is based on usage of the TechSmith SnagIt application, version 6.x only. However, it can be easily modified to accomodate SnagIt version 7.x.
  2. It is assumed that the dUFLP is already set in your program.
  3. SnagIt does not need to be the topmost window, or even visible!
  4. You will need to name the variable used here called MyProfile, which will be the profile name that SnagIt will recognize.
  5. You will need to name the variable used here called scrapedtext, which is the name of the text file that the scraped data will be copied to.
  6. You will need to name the file used here called MySnagIt.reg, which will be the your preset registry entries.
  7. You will need to name the file used here called SnagIt.ini, which will be the your preset settings for all of your forms.
Installing SnagIt

Install SnagIt either the normal way by executing the setup application or programmatically. You can install programmatically and silently with:
 
 
{PathToSetup}\snagit.exe /S /M={PathToSetup}\instvar.txt
   

The text file called INSTVAR.TXT will contain:
 
 
MAINDIR=C:\Program Files\TechSmith\SnagIt      // or whatever directory you choose
DESKTOP_LINK=
START_AUTO=
START_MINI=
VIEW_README=
START_NOW=
START_NOW2=
SHORTCUT_TYPE=
   

You can preset your registry entries. The registry file called MySnagIt.reg will contain:
 
 
REGEDIT4

[HKEY_CURRENT_USER\Software\TechSmith\SnagIt\6\Profiles\MyProfile]
"ProfileName"="MyProfile"
"Mode"=dword:00000001
"Preview"=dword:00000000
"SnagKey"=dword:00000908      // This is the setting for the hot key of Ctrl-F8
"Preferences"=dword:51d2bd20
"ExtPreferences"=dword:001fe000
"TimerPreferences"=dword:00000008
"TimerInterval"=dword:00000002
"TimerValue"=dword:00000001
"DelayMode"=dword:00000000
"DelaySec"=dword:0000000a
"DelayDateLow"=dword:00000000
"DelayDateHigh"=dword:00000000
"ScrollForeground"=dword:00000001
"ScrollDelay"=dword:00000000
"ScrollFromTop"=dword:00000001
"ScrollFromLeft"=dword:00000001
"ScrollDirection"=dword:00000001
"FilterOps"=dword:00000000
"LeftMargin"=dword:00000000
"RightMargin"=dword:00000000
"TopMargin"=dword:00000000
"BottomMargin"=dword:00000000
"ScaleOption"=dword:00000002
"KeepAspect"=dword:00000001
"ScaleType"=dword:00000000
"ScaleFactorHeight"=dword:00000064
"ScaleFactorWidth"=dword:00000064
"ScaleHeight"=dword:000000c8
"ScaleWidth"=dword:00000140
"ScaleToHeight"=dword:000000c8
"ScaleToWidth"=dword:00000140
"ScalePercentage"=dword:00000000
"TextInput"="ActiveWindow"
"TextOutput"="File"
"TextMultiOutput"=dword:00000002
"TextAutoScroll"=dword:00000000
"TextClipboardChain"=dword:00000000
"TextFileNaming"=dword:00000001
"TextFileOutputDir"="C:\\"      // This is the directory where the text file will be created
"TextFixedFileName"="scrapedtext"
"TextAutoFilePrefix"="SNAG-"
"TextAutoFileNumDigits"=dword:00000004
"TextDefaultPrinter"=dword:00000001
"TextPrinterName"=""
"TextPrinterPort"=""
"TextPrinterDriver"=""
"TextPrinterSaveSettings"=dword:00000000
"TextPrinterSettings"=hex:
"TextUseMailDef"=dword:00000000
"TextMapiSubject"=""
"TextMapiName"=""
"TextMapiAddress"=""
"TextMapiText"=""
"TextCatalogFileNaming"=dword:00000002
"TextFormat"=dword:00000000
"TextCondenseLines"=dword:00000001
"TextCondenseColumns"=dword:00000000
"TextDelimiter"=dword:0000002c
"TextAnnotateFile"=dword:00000000
"TextAppendFile"=dword:00000000
"TextAppendFileName"=""
"TextAnnotateFilePrefix"=">>>"
"TextFontHeight"=dword:00000000
"TextFontWeight"=dword:00000000
"TextFontItalic"=dword:00000000
"TextFontUnderline"=dword:00000000
"TextFontPitchFamily"=dword:00000000
"TextFontCharSet"=dword:00000001
"TextFontFaceName"="System"
"TextWordWrap"=dword:00000000
"TextUseStartPt"=dword:00000000
"TextRectFixed"="0,0,320,240"
"TextCaptionString"=""
"TextCaptionMru"=""
"ObjectTextOptions"=dword:0000000f

[HKEY_LOCAL_MACHINE\Software\TechSmith\SnagIt\6]
"GlobalInstallPath"="C:\\Program Files\\TechSmith\\SnagIt\\SnagIt32.exe"

   

Now you will need to initialize SnagIt and turn off all of its popup windows:

  1. Open Snagit from Start|Programs
  2. Make sure all popups are selected to not appear on every execution!
  3. Enter your registration key info
  4. Close and reopen Snagit
  5. Select profile view
  6. Again, make sure all popups are selected to not appear on every execution!
  7. Close and reopen Snagit
  8. No popups should appear and you should be in profile view
  9. Close Snagit
  10. Start|Run and then browse to {PathToSetup}\MySnagIt.reg and run it
Finding SnagIt on the workstation programmatically

First and foremost, your application needs to know if and where SnagIt is installed on the workstation. You must delve into the registry (programmatically, of course) and see where it is installed. The standard location for TechSmith applications is HKLM\Software\TechSmith. Within that key should be SnagIt, and under that key should be the version. So initially, the code would be:
 
 
try
   private reg
   reg = new registry(hkey_local_machine,"Software\TechSmith\SnagIt\6")
   _app.snagitlocation = reg.queryvalue("GlobalInstallPath")
   if not reg.error == 0
      // SnagIt is not installed
      _app.snagitlocation := 'no snagit application'
   endif
catch (exception e)
   _app.snagitlocation = 'no snagit application'
endtry
   

At this point, if you have a value in the variable _app.snagitlocation besides 'no snagit application' then SnagIt is installed and it is version 6 and the pointer to the application is located in the variable _app.snagitlocation.

Setting up SnagIt and make sure it is running

SnagIt can be set up with many profiles, whereas, based on which keys are pressed they will do whatever function is assigned to it. For this example, we are going to use a profile called MyProfile.

We are going to do four things in this segment:

  1. We will verify that the pointer to the SnagIt application is correct and the program exists
  2. If the profile MyProfile doesn’t exist, we will create it
  3. We will check to see if SnagIt is already running, whether it is in the foreground, background or even hidden.
  4. If SnagIt isn’t running, we will launch it in hidden mode
 
if file(_app.snagitlocation)
   // The SnagIt program exists so lets check and reset the registry
   reg = new registry(hkey_current_user,"Software\TechSmith\SnagIt\6\Profiles\MyProfile")
   if reg.error == 0
      private r,rv,regsetting,regtest,newregvalue,snagitprofile
      rv = "Software\TechSmith\SnagIt\6\Profiles"
      r = new registry(hkey_current_user,rv)
      regsetting = "ProfileList"
      regtest = r.queryvalue(regsetting)
      if not "MyProfile" $ alltrim(upper(regtest))
         newregvalue = regtest + "MyProfile*"
         checksetreg(r,regsetting,newregvalue)
      endif

      // Now lets check all of the profile parameters and set them if not correct
      regsetting = "CurrentProfile"
      snagitprofile = r.queryvalue(regsetting)
      r = new registry(hkey_current_user,rv + "\MyProfile")
      regsetting = "TextFileOutputDir"
      newregvalue = substr(_app.exename,1,rat("\",_app.exename))
      checksetreg(r,regsetting,newregvalue)
      regsetting = "TextFixedFileName"
      newregvalue = "scrapedtext"
      checksetreg(r,regsetting,newregvalue)

      // Now lets verify that the profile now exists
      if "MyProject" $ snagitprofile
         snagithandle = FindWindow(0,"snagit - MyProfile")
      else
         r = new registry(hkey_current_user,rv + "\" + snagitprofile)
         regsetting = "ProfileName"
         snagitprofile = alltrim(r.queryvalue(regsetting))
      endif

      // Let's see if SnagIt is already running
      extern chandle FindWindow(cstring,cstring) user32 from "FindWindowA"
      snagithandle = FindWindow(0,"snagit - " + snagitprofile)
      if snagithandle < 1
         // Snagit is not running, lets launch SnagIt and wait until it is ready
         snagithandle = shellexecute(_app.framewin.hwnd,"open",_app.snagitlocation,"/h",null,6)
         do while snagithandle = 0
            snagithandle = FindWindow(0,"snagit - " + snagitprofile)
         enddo
      endif

      // This is used for checking SnagIt setup in realtime, since it is not visible
      on key label ctrl+f9 snagitsetup()
   endif
else

   // The SnagIt program does NOT exist
   _app.snagitlocation := 'no snagit application'
endif
if not _app.snagitlocation == 'no snagit application'
   // SnagIt is set up and running, lets set the hot key for my program to trigger it
   on key label ctrl+f8 F8Trigger()
endif

   

SnagIt configuration file contents
 
 
[SnagIt]
Row=7             // this is the form identifier row number
Column=89         // this is the form identifier column number
Width=4           // this is the form identifier width
PrimaryWidth=14   // this is the default width
primaryRow=8      // this is the default row number
primaryColumn=53  // this is the default column number

[CA12]            // this segment is for a form identified as CA12
PrimaryWidth=14   // this is the width
PrimaryRow=12     // this is the row number
PrimaryColumn=21  // this is the column number
 

   

Setting up the manual trigger for SnagIt

The purpose of the F8Trigger() procedure is to scrape the text off of a predefined window and get text based on X, Y & Z coordinates.

I’ll try to guide you thru all of its functions:
 
 
FUNCTION F8Trigger
   private snagtest,snagform,snagrow,snagcolumn,snagwidth,snagini,testsfile,snagi
   store "" to snagtest,snagform

   // Let's open the configuration file and find out where to identify the form
   snagini = new ini(projpath + '\snagit.ini')
   testsfile = new file(substr(_app.exename,rat("\",_app.exename)) + "scrapedtext.txt","r")
   testsfile.seek(0)
   snagini.getvalue("SnagIt","Row")
   snagrow = iif(isblank(snagini.cbuffer),0,val(snagini.cbuffer))
   snagini.getvalue("SnagIt","Column")
   snagcolumn = iif(isblank(snagini.cbuffer),'',alltrim(snagini.cbuffer))
   snagini.getvalue("SnagIt","Width")
   snagwidth = iif(isblank(snagini.cbuffer),0,val(snagini.cbuffer))
   if snagrow > 1
      // The form identifier is not on the first row so lets loop to the right row
      for i = 1 to snagrow
         snagform = testsfile.gets(500)
      next
   else
      // The form identity is on the first row of the scraped text file
      snagform = testsfile.gets(500)
   endif
   snagform = alltrim(substr(snagform,snagcolumn,snagwidth))
   if isblank(alltrim(snagform))
       // We scraped nothing but air, put reject coding here
   else
      // We know what form this is, so lets get that form's coordinates
      snagini.getvalue(snagform,"PrimaryWidth")
      if isblank(snagini.cbuffer)
         snagini.getvalue("SnagIt","PrimaryRow")
      else
         snagwidth = alltrim(snagini.cbuffer)
      endif
      snagini.getvalue(snagform,"PrimaryRow")
      if isblank(snagini.cbuffer)
         snagini.getvalue("SnagIt","PrimaryRow")
      else
         snagrow = alltrim(snagini.cbuffer)
      endif
      snagini.getvalue(snagform,"PrimaryColumn")
      if isblank(snagini.cbuffer)
         snagini.getvalue("SnagIt","PrimaryColumn")
      else
         snagcolumn = alltrim(snagini.cbuffer)
      endif

      // Let's go back to the top of the scraped text and get the data we are looking for
      testsfile.seek(0)
      for snagi = 1 to val(snagrow)
         // Let's loop to the right row
         snagtest = testsfile.gets(500)
      next
      snagtest = alltrim(substr(snagtest,val(snagcolumn),snagwidth))
      if isblank(snagtest)
         // Airball! Put reject code here
      else
         // Bada bing! Do whatever you need to with your results!
      endif
   endif
   testsfile.close()