Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dynamic Shell Execute

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,828
JP
Hi All,
So progressing onto my next challenge.

Now that I have the document selection working nicely, and stored in a table, I would like to enable users to select document records from a grid, and when "double-click" the record, it launches the file.
My thought was ShellExecute would work well for this, and I have one that I wrote many years ago, but have since forgotten really what this is, and VFP doesn't seem to document it, since it's really a call to the OS (if I understand it correctly.

The one I currently have is limited to PDF files. I was hoping to find a way to make this work so that whatever file I shove at it, it will launch it automatically... My current Procedure is called LAUNCHPDF, but I'd like something more like "LAUNCHFILE"

The code looks like this:

Code:
PROCEDURE LAUNCHPDF

PARAMETERS ACROFILE, txtType

declare INTEGER ShellExecute in shell32 ;
  INTEGER handle, STRING @ oper, STRING @ ifile,;
  STRING @ iparam, STRING @ ipath, INTEGER showcmd

=SHELLEXECUTE(0,"open",'"'+txtType+ACROFILE+'.PDF'+'"',"","",1)

This works great for launching a dynamic list of PDFS that I create on my top line menu bar (but this was intended to launch "PDF Books" as part of a set of standards (not related to development, but to my application industry).

How would I change this so that if I throw a .XLSX or a .DOC or a .DWG or... an anything at it, that it would launch it?
Or is that the wrong approach?

Do I need some series of CASE statement and identify the file types ahead of time?
I find this one particularly confusing because I just don't know much about the "Shell32" dll.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Pass the complete file name, including path and extension, as parameter.
 
Ah... found an article from Rick Straul on this one...

Rebuilt it to look like his:

Code:
PROCEDURE SHELLEXEC

LPARAMETER lcLink, lcAction, lcParms
*
MESSAGEBOX(lcLink)
*
lcAction = IIF(EMPTY(lcAction), "Open", lcAction)
lcParms = IIF(EMPTY(lcParms), "", lcParms)
 
DECLARE INTEGER ShellExecute ;
    IN SHELL32.dll ;
    INTEGER nWinHandle, ;
    STRING cOperation, ;
    STRING cFileName, ;
    STRING cParameters, ;
    STRING cDirectory, ;
    INTEGER nShowWindow
 
DECLARE INTEGER FindWindow ;
   IN WIN32API ;
   STRING cNull,STRING cWinName
 
RETURN ShellExecute(FindWindow(0, _SCREEN.caption), ;
                    lcAction, lcLink, ;
                    lcParms, SYS(2023), 1)

Took a couple of tweaks to my dynamic menu which builds the PDF list, and I've taken that part out of the core of the application, now if I just pass fully qualified path and file, it works!
Awesome.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Why do you set the working directory for every document you open to TEMP? The typical call should put in the directory of the file or "" at that place.

If you got this from here Rick Strahl most often opens files he puts into TEMP, therefore SYS(2023) is a good default for him, but he also makes it a parameter you can set to what you need.

Also: What's wrong with _screen.hwnd? Any form has a hwnd property and you can simply read it instead of finding it via title bar caption.

Bye, Olaf.
 
Scott, you wrote:
VFP doesn't seem to document it, since it's really a call to the OS

That's right. ShellExecute() is an API call, not part of VFP.

You might want to take a look at this article, Introducing ShellExecute(), which aims to give a full run-down on ShellExecute().

To follow up Olaf's point: One of the commonest mistakes people make with this function is with the location of files, and in particular the assumption that ShellExecute() will find a file because it is on the VFP search path. ShellExecute() - or any other API function - knows nothing about VFP, or its search path, or anything similar. That's also true of VFP variables. If you keep that in mind, you can avoid a lot of difficulties.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike has a good point about the VFP search path. Same applies to the current directory, If you set the directory parameter that is well defined, though. It's not always important, but sometimes needs to be the file path, sometimes the file parameter should include the full path and the working directory is unimportant for the associated application (remember what I said using full paths when it comes to really handling the file?).

The same also applies to OLE automation, even if you write own OLE classes as VFP DLLs. You don't share your working dir or data session or anything, even with single threaded DLLs, which have their object running in your process and thread, a VFP DLL means running a separate runtime session of the vfp9r.dll or more common when compiled as multi threaded DLL the vfp9t.dll

Another helpful thing is, you find lots of API declarations in VFP syntax with sample usages at eg
Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top