HOWTO: Invoke the "Open With..." Dialog Box Using ShellExecute
ID: Q192352
|
The information in this article applies to:
-
Microsoft Visual FoxPro for Windows, versions 3.0, 3.0b, 5.0, 5.0a, 6.0
SUMMARY
The WIN32API function ShellExecute and the corresponding FoxPro Foundation
Class _shellexecute can both be used to run external programs, as well as
open non-executable files if there is a program associated with that file.
However, if there is no program associated with the file, ShellExecute and
_shellexecute return SE_ERR_NOASSOC (31) and no action is taken upon the
file. This article demonstrates how to create a custom class based on
_shellexecute (for Visual FoxPro 6.0) and a procedure (for previous
versions) that use the "Open With..." dialog box to give the user the
option of selecting a program with which to open the file.
MORE INFORMATION
There are two ways to approach this, depending upon the version of FoxPro
that is used. When using Visual FoxPro 6.0, the FoxPro Foundation Class
_shellexecute can be subclassed and the Shellexecute method overridden.
Method 1 describes how to do this. In previous versions of Visual FoxPro,
the process must be either executed from a program function or a class will
have to be created from scratch. Method 2 describes how to do this as a
program function.
Method 1
- Create a new class. Make the class name _shelldoc. In the "Based on"
field, select the _shellexecute class found in the _environ.vcx class
library, which is in the HOME()+"ffc" directory. The class should be
stored in a class library named Ztest and not one of the Foundation
Classes (FFC) class libraries. Make sure that Ztest resides in the home
directory of Visual FoxPro.
- When the class designer appears, select the Shellexecute method from the
properties window and open it. Insert the following code into the code
editor:
*-- Code begins here.
#define SW_SHOWNORMAL 1
#define SE_ERR_NOASSOC 31
liRet = DODEFAULT(tcfilename, tcworkdir, tcoperation)
IF liRet = SE_ERR_NOASSOC && No association exists
DECLARE INTEGER GetSystemDirectory IN kernel32.dll ;
STRING @lsBuffer, ;
INTEGER liSize
lsSysDir = SPACE(260) && MAX_PATH, the maximum path length
*-- Get the system directory so that we know
*-- where Rundll32.exe resides.
liRet = GetSystemDirectory(@lsSysDir, LEN(lsSysDir))
lsSysDir = SUBSTR(lsSysDir, 1, liRet)
lsRun = "RUNDLL32.EXE"
lsParameters = "shell32.dll,OpenAs_RunDLL "
liRet = ShellExecute(0, "open", lsRun,;
lsParameters + tcfilename, lsSysDir, SW_SHOWNORMAL)
ENDIF
*-- Code ends here
- Save the class. The class can now be used as in the following example:
*-- Code begins here.
oShellDoc = NEWOBJECT("_shelldoc",HOME()+"Ztest.vcx")
oShellDoc.ShellExecute("MyDoc.ZZZ") && Pass a filename that has
&& no association.
oShellDoc.Release
*-- Code ends here.
- The "Open with..." dialog box displays if the file has no association.
Otherwise, the file opens with the program with which it is associated.
Method 2
- Save the following code to a program file and save it as ShellDoc.prg:
*-- Code begins here.
PROCEDURE ShellDoc()
LPARAMETERS lsFile
*-- Defines from Winuser.h
*-- These constants will be used with the
*-- ShellExecute function.
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11
#define SE_ERR_NOASSOC 31
*-- GetDesktopWindow gives us a window handle to
*-- pass to ShellExecute.
DECLARE INTEGER GetDesktopWindow IN user32.dll
DECLARE INTEGER GetSystemDirectory IN kernel32.dll ;
STRING @lsBuffer, ;
INTEGER liSize
*-- ShellExecute is of the following format:
*-- HINSTANCE ShellExecute(
*-- HWND hwnd,
*-- LPCTSTR lpOperation,
*-- LPCTSTR lpFile,
*-- LPCTSTR lpParameters,
*-- LPCTSTR lpDirectory,
*-- INT nShowCmd
*-- );
DECLARE INTEGER ShellExecute IN shell32.dll ;
INTEGER, ;
STRING @lsOperation, ;
STRING @lsFile, ;
STRING @lsParameters, ;
STRING @lsDirectory, ;
INTEGER liShowCmd
lsOperation = "open"
liRet = ShellExecute(GetDesktopWindow(), @lsOperation, @lsFile, ;
"", "", SW_SHOWNORMAL)
IF liRet = SE_ERR_NOASSOC && No association exists
lsSysDir = SPACE(260) && MAX_PATH, the maximum path length
*-- Get the system directory so that we know
*-- where Rundll32.exe resides.
liRet = GetSystemDirectory(@lsSysDir, LEN(lsSysDir))
lsSysDir = SUBSTR(lsSysDir, 1, liRet)
lsRun = "RUNDLL32.EXE"
lsParameters = "shell32.dll,OpenAs_RunDLL "
liRet = ShellExecute(GetDesktopWindow(), "open", lsRun,;
lsParameters + lsFile, lsSysDir, SW_SHOWNORMAL)
ENDIF
ENDPROC
*-- Code ends here.
- In the Command window, issue the following command:
SET PROCEDURE TO ShellDoc
- Call the ShellDoc procedure with the following syntax:
DO ShellDoc WITH <cFilename>
You may need to pass a path with the file name if the file is on a
mapped drive. If <cFilename> has no association, the "Open With..."
dialog box appears.
REFERENCES
(c) Microsoft Corporation 1998. All Rights Reserved. Contributions by Mike
A. Stewart, Microsoft Corporation.
Additional query words:
kbVFp600 kbAPI kbFFC kbvfp300 kbvfp300b kbvfp500 kbvfp500a
Keywords :
Version : WINDOWS:3.0,3.0b,5.0,5.0a,6.0
Platform : WINDOWS
Issue type : kbhowto
|