Thursday, June 4, 2015

How to give focus to a FoxPro top-level form at start-up

When I tried to  create a form that comes up without the surrounding FoxPro Form/workspace and menu structure, I used these code:
 
In the form properties:
     ThisForm.ShowWindow = 2  && Set the window to As Top-Level Form

In the form Init method:
     _Screen.visible = .F.

The problem is the form lost focus when it runs. Users have to click the icon on the taskbar  to bring the form to the top.

On MSDN LostFocus Event page, there is explanation:
A form loses the focus when the form has no controls, all its controls have their Enabled and Visible properties set to false (.F.), or another form gets the focus.
 
So the second command caused the problem. I tried to solve this issue. I did some search and finally found this article:
http://hexcentral.blogspot.ca/2013/04/how-to-give-focus-to-foxpro-top-level.html
 
===================================================

How to give focus to a FoxPro top-level form at start-up

 By Mike Lewis

This is a question I often see in Visual FoxPro forums. An application needs to show a top-level form (typically a log-in screen) at start-up. But when you launch the form, it
appears behind other windows on the desktop. Even if it is at the front, it's not necessarily the active form. So how do you give the form focus programmatically?


None of the obvious techniques seem to work. These include toggling the form's AlwaysOnTop property, and calling the SetFocus method for one of its controls. However, the following code will always do the trick:
DECLARE INTEGER SetForegroundWindow IN WIN32API INTEGER
SetForegroundWindow(thisform.HWnd)
CLEAR DLLS "SetForegroundWindow"
 
All you have to do is place that code in the form's Init method, and the problem's solved. (The code works in VFP 7.0 and above.)
 
 
 

Friday, May 8, 2015

VFP function that combines individual xls files

VFP function that combines individual xls files

I need to put get data from VFP and put it into multiple sheets in an Excel file. I found this code on Internet. I have not tested it so far.

--------- Original link and post: ---------

https://social.msdn.microsoft.com/Forums/en-US/a9b81c52-2969-4403-81e2-b5ce891f1a2f/copy-to-excel-and-adding-worksheets?forum=visualfoxprogeneral

I have this function that we use to combine individual xls files:

************************************************************
* Function CombineExcelFiles
************************************************************
* Created...........: Craig Boyd 3/6/2006 23:55:50
*) Description.......:
* Calling Samples...: DIMENSION aXLSFiles(3)
*!*     aXLSFiles(1) = "C:\temp1.xls"
*!*     aXLSFiles(2) = "C:\temp2.xls"
*!*     aXLSFiles(3) = "C:\temp3.xls"
*!*     CombineExcelFiles(@aXLSFiles, "C:\XLSCombined.xls")
* Parameter List....:
* Major change list.:
function CombineExcelFiles (taXLSFiles, tcDestination, tlDeleteOriginal)
external array taXLSFiles
local loExcel as Excel.application, ;
 loWorkBook as Excel.Worksbook, ;
 loWorkSheet , ;
 lnCounter, lcWorkSheetCaption, lcError, ;
 lcValidChars

lcError = ""

try
 lcValidChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
 loExcel = newobject("Excel.Application")
 with loExcel
  .ScreenUpdating = .f.
  .DisplayAlerts = .f.
  .WorkBooks.add()
  lnCounter = 0

** Delete all existing worksheets except 1
  for each loWorkSheet in .WorkBooks(1).WorkSheets
   lnCounter = m.lnCounter + 1
   if m.lnCounter > 1
    loWorkSheet.delete
   endif
  endfor

  for lnCounter = 1 to alen(taXLSFiles,1)
   if file(taXLSFiles[m.lnCounter])
    lcWorkSheetCaption = juststem(taXLSFiles[m.lnCounter])
    loWorkBook = .WorkBooks.open(taXLSFiles[m.lnCounter])
    loWorkBook.WorkSheets(1).copy(null, ;
     .WorkBooks(1).WorkSheets(.WorkBooks(1).WorkSheets.count))
    .WorkBooks(1).ActiveSheet.name = ;
     right(alltrim(chrtran(m.lcWorkSheetCaption, ;
     chrtran(m.lcWorkSheetCaption,m.lcValidChars,"")," ")), 31) &&loWorkBook.Name
    loWorkBook.close(.f.) && Do not save changes
    if m.tlDeleteOriginal
     erase (taXLSFiles[m.lnCounter])
    endif
   endif
  endfor
** Remove the first original sheet from (Sheet1)
  .WorkBooks(1).WorkSheets(1).delete

  .WorkBooks(1).saveas(m.tcDestination)
  .ScreenUpdating = .t.
  .DisplayAlerts = .t.
 endwith

catch to loError
 lcError = Log_Error(m.loError)
finally
 if vartype(m.loExcel) = 'O'
  with loExcel
   .ScreenUpdating = .t.
   .DisplayAlerts = .t.
   .quit()
  endwith
 endif
endtry

return m.lcError
endfunc



Naomi Nosonovsky, Sr. Programmer-Analyst

Useful Excel Automation examples

 
Useful Excel Automation examples
 
Posted: 5 Oct 03 (Edited 8 Oct 03)

Here is an on-going compilation of Excel automation samples.
  1. How to copy a .jpg from a general field to an Excel sheet.

    oExcel =CREATEOBJECT("excel.application")
    oWorkBook = oExcel.workbooks.add()
    oSheet = oWorkbook.activesheet
    USE e:\trans\pics AGAIN IN 0 && The table with the general field that holds the jpg.
    LOCATE && Go op
    KEYBOARD "{CTRL+C}{CTRL+W}" && Copy the jpg
    MODIFY GENERAL pics.pic
    oSheet.paste() && Paste the clipboard content in the the sheet
    oExcel.visible = .t.

  2. How to create a chart via Excel automation

    #DEFINE xlColumnClustered 51
    LOCAL oExcel as Excel.application
    LOCAL oWorkbook,oSheet
    oExcel = CREATEOBJECT("Excel.application")
    oWorkbook= oExcel.Workbooks.Add()
    oSheet = oWorkbook.activesheet
    WITH oSheet
    .Range("A1").Select
    .Range("A1").FormulaR1C1 = "1"
    .Range("A2").Select
    .Range("A2").FormulaR1C1 = "2"
    .Range("A3").Select
    .Range("A3").FormulaR1C1 = "3"
    .Range("A4").Select
    .Range("A4").FormulaR1C1 = "4"
    .Range("A5").Select
    .Range("A5").FormulaR1C1 = "5"
    .Range("A6").Select
    .Range("A6").FormulaR1C1 = "6"
    .Range("B1").Select
    .Range("B1").FormulaR1C1 = "10"
    .Range("B2").Select
    .Range("B2").FormulaR1C1 = "11"
    .Range("B3").Select
    .Range("B3").FormulaR1C1 = "50"
    .Range("B4").Select
    .Range("B4").FormulaR1C1 = "60"
    .Range("B5").Select
    .Range("B5").FormulaR1C1 = "70"
    .Range("B6").Select
    .Range("B6").FormulaR1C1 = "90"
    .Range("A1:B6").Select
    ENDWITH
    WITH oWorkbook
    .Charts.Add
    .ActiveChart.ChartType = xlColumnClustered
    .ActiveChart.SetSourceData(oSheet.Range("A1:B6"))
    .ActiveChart.HasTitle = .f.
    ENDWITH
    oExcel.Visible =.t.


  3. How to delete a sheet from a workbook
    Local oSheet,oWorkBook,oExcel
    oExcel = CREATEOBJECT("Excel.application")
    oWorkBook = oExcel.Workbooks.Add()
    oSheet = oWorkBook.activeSheet
    oSheet.Delete()
    oExcel.Visible = .t.


  4. How to add a sheet to a workbook
    Local oSheet,oWorkBook,oExcel
    oExcel = CREATEOBJECT("Excel.application")
    oWorkBook = oExcel.Workbooks.Add()
    oWorkbook.Sheets.Add
    oExcel.Visible = .t.


  5. How to move a sheet within a Workbook.
    oExcel = CREATEOBJECT("excel.application")
    oWorkbook = oExcel.Workbooks.Add()
    oWorkbook.Sheets.Add
    oSheet = oWorkbook.ActiveSheet
    oSheet.Move(,oWorkbook.Sheets(4)) && Move after sheet3
    oSheet.Move(oWorkbook.Sheets(4),) && Move before sheet3
    oExcel.Visible =.t.

Mike Gagnon

Thursday, February 26, 2015

A useful search tool, Filer, in Virtual FoxPro


This is a good search tool in VFP.

Filer

Years ago, Filer was what most FoxPro developers used to search and find files. After VFP 3.0, this disappeared and many developers screamed. Well, the Fox Team has listened and decided to bring back a little nostalgia. Enter the following in the Command window to see an example of how it runs:

DO FORM (HOME(1) + 'Tools\Filer\Filer.scx')

Search through the VFP Help file and read up on the new Filer, because this one is object-oriented and you can interact with it and implement it in your own applications. I guess you could call this FilerX!


The original article is here:
https://msdn.microsoft.com/en-us/library/ms947597.aspx

Tuesday, September 30, 2014

FoxPro form flashes on the screen and disappeares

I am working on my first Visual Foxpro program. My program was not waiting for any event and just closed immediately. I could not figure out the reason until I found this article.

http://www.alvechurchdata.co.uk/company/foxflash.html

FoxPro form flashes on the screen and vanishes

Everybody meets this problem with their first Visual FoxPro executable; the program runs well in the development environment but fails when run as a stand-alone executable from Windows. The FoxPro window just flashes on the screen and then vanishes. You can search VFP Help for terms like "flash", "vanish" and "disappear" but you will find nothing. The information is hidden away under "How to: Control the Event Loop" and you won't be able to ship your exe until you find it.
This problem crops up because Visual FoxPro is now an event-driven language. It runs through the code for your form, reaches the end, and the program terminates when there is nothing more for it to do. Everything vanishes from the screen. The same thing will happen if your application is based on a main menu; FoxPro will run through the code to create the menu, the menu will flash on the screen but then the program terminates and the menu vanishes.
The solution is a simple one once you realise what FoxPro is doing. You have to tell VFP to start its event-processing loops. The command that does this is:
Read Events
You'll need to add this code in different places depending on whether you are using a form, a menu or a program as the main element of your application.
If you are using a form then add this as the last line in the Activate event. This will allow the form to load and initialise itself before going into the event processing loop and waiting for mouse and keyboard events.
In a menu, add it to the CleanUp code snippet. Select General Options from the View menu then click the Cleanup... tick box. An edit window will open behind the dialog; click OK to close the dialog window and the CleanUp edit window will remain:
[VFP Edit window for menu cleanup code]
If you have a program as the main element of your project then add the Read Events line immediately after you have set up the user interface by loading a form or menu. Fox will then stop executing this sequential code and will start monitoring keyboard and mouse events, waiting to see what it should do next.

One last thing to remember

[Cannot Quit Visual FoxPro message] This will start the event processing loop but we need to stop the loop in order to close the application. If you forget to do this then you'll hit the second most-common problem - the "Cannot quit Visual FoxPro." message.
You avoid this by using the Clear Events command to stop the event-processing loop. Execution will then continue from the line following the Read Events command in the main program.
Read more details on being unable to quit FoxPro here.

Friday, April 25, 2014

Windows Script Host


Microsoft Windows Script Host (WSH) is a language-independent scripting host for Windows Script compatible scripting engines. It brings simple, powerful, and flexible scripting to the Windows 32-bit platform, allowing you to run scripts from both the Windows desktop and the command prompt.

Using Windows Scripting Host, VBScript performed tasks that the Windows shell (batch scripts) simply could not handle. Windows Script Host is ideal for non-interactive scripting needs, such as logon scripting, administrative scripting, and machine automation.

This is the link for Windows Script Host
http://msdn.microsoft.com/en-us/library/9bbdkx3k(v=vs.84).aspx


In VBScript, we can create Windows Script Host (WSH) Objects and automate manual tasks.

These are the 14 WSH Objects:

Scripting.Signer Object  
Enables an author to sign a script with a digital signature and a recipient to verify the signature's authenticity and trustworthiness.

WScript Object 
Provides access to most of the objects, methods, and properties in the WSH object model.

WshArguments Object
 Gives you access to the entire collection of command-line parameters — in the order in which they were originally entered.

WshController Object
 Exposes the method CreateScript() that creates a remote script process.

WshEnvironment Object
 Gives you access to the collection of Microsoft Windows system environment variables.

WshNamed Object
 Provides access to the named command-line script arguments within the WshArguments object.

WshNetwork Object
 Gives you access to the shared resources on the network to which your computer is connected.

WshRemote Object
 Provides access to the remote script process.

WshRemoteError Object
 Exposes the error information available when a remote script (a WshRemote object) terminates as a result of a script error.

WshScriptExec Object
 Provides status and error information about a script run with Exec, along with access to the stdIn, stdOut, and stdErr channels.

WshShell Object
 Gives you access to the native Windows shell functionality.

WshShortcut Object
 Allows you to create a shortcut programmatically.

WshSpecialFolders Object
 Allows you to access the Windows Special Folders.

WshUnnamed Object
 Provides access to the unnamed command-line script arguments within the WshArguments object.

WshUrlShortcut Object
 Allows you to create a shortcut to an Internet resource, programmatically.
 
Link: http://msdn.microsoft.com/en-us/library/a74hyyw0(v=vs.84).aspx


This is the reference page:
http://msdn.microsoft.com/en-us/library/98591fh7(v=vs.84).aspx


Wednesday, April 2, 2014

Script to load program in administrator elevated mode

One of our users needs to run a program in elevated mode. I added her in the local admin group, but she still have to right click the shortcut and select "Run as Administrator" and then click OK in the pop up UAC window. The user complained about all the clicks.

I googled it and found this script to avoid all these steps. User just double click the shortcut to the batch file and the batch file runs the program in elevated mode.


https://sites.google.com/site/eneerge/scripts/batchgotadmin

Basically this just creates a VBS Script on the fly and invokes the batch script using it. It checks to see if the current window is running as administrator by attempting to create a folder that requires administrative access. If the directory can not be created, then it invokes the UAC dialog, then closes the non-admin window. The script can also be executed from an already open administrative CLI.
 
 
========== Batch file: RunProgram.bat =================================

@echo off

:------------------------:
: BatchGotAdmin     :
:------------------------:

REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )


:UACPrompt

    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~s0", "", "", "runas", 1  >> "%temp%\getadmin.vbs"
    "%temp%\getadmin.vbs"
    exit /B

:gotAdmin

    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"

:--------------------------------------
REM  creat a temp batch file to run the real program
    
echo net use p: /delete /y >%temp%\runProgram-temp.bat
echo net use p: "\\Server1\program files" >>%temp%\runProgram-temp.bat
echo net use n: /delete /y >>%temp%\runProgram-temp.bat
echo net use n: \\Server1\groups >>%temp%\runProgram-temp.bat
echo p:\myProgram\myProgram.exe >>%temp%\runProgram-temp.bat
echo exit >>%temp%\runProgram-temp.bat
start /min %temp%\runProgram-temp.bat

======================= End of Batch file =======================