|
Lorne Klassen wrote:
> I'm using the Windows ShellExecuteA function to open a file with the
> application that is associated with the file's extension. This is
> what I've come up with and it seems to work:
>
> /* SASCBTBL file: */
> ROUTINE ShellExecuteA
> minarg=6
> maxarg=6
> stackpop=called
> module=shell32
> returns=long;
> arg 1 input num byvalue format=PIB4.; /* hWnd */
> arg 2 input char byaddr format=$CSTR20.;
> arg 3 input char byaddr format=$CSTR500.;
> arg 4 input char byaddr format=$CSTR256.;
> arg 5 input char byaddr format=$CSTR256.;
> arg 6 input num byvalue format=PIB4.;
>
> /* Function call */
> rc = MODULEN('ShellExecuteA',0,'Open',parm_file,'','',1);
>
> I had to use trial and error to get this to work and so I have some
> questions.
>
> 1. For "returns=long", I was just guessing on this. Does it really
> matter what I use here? Will "short" work as well? I assume it's not
> safe to use an unsigned type if unsure? MS doc says it returns
> "hInstance".
Long is generally safe. Short will 'work' but the returned value will be
truncated if the value actually returned exceeds the domain of a short.
> 2. What is the difference between functions that end with "A" and
> those that don't? E.g., ShellExecute and MoveFile do not work but
> ShellExecuteA and MoveFileA do work. However, WinExec (no "A") works.
*A functions usually have a corresponding *W function.
A is for Ansi, meaning 1 byte per character and
W is for widechar, meaning unicode, or 2 bytes per character.
>
> 3. When MS documentation says that NULL can be used, how do I specify
> NULL? For the ShellExecuteA above, MS said that args 1, 4 and 5 can
> be NULL. Is the way I wrote it above the only way to do it? I also
> tried the following but got some serious errors:
When passing character strings from SAS to a dll function, you can't pass a
null. The best you can do is pass a pointer to a string of zero length. If
you want to always pass a pointer explicitly, you can change the arg to a
number and pass either a 0 for null, or ADDR(my-char-var).
See http://www.devenezia.com/downloads/sas/sascbtbl#GetOpenFileName
Some of the * LPSTR arguments are specified as num
> /* SASCBTBL file: */
> ROUTINE ShellExecuteA
> minarg=6
> maxarg=6
> stackpop=called
> module=shell32
> returns=long;
> arg 1 input NOTREQD num byvalue format=PIB4.; /* hWnd */
> arg 2 input REQUIRED char byaddr format=$CSTR20.;
> arg 3 input REQUIRED char byaddr format=$CSTR500.;
> arg 4 input NOTREQD char byaddr format=$CSTR256.;
> arg 5 input NOTREQD char byaddr format=$CSTR256.;
> arg 6 input REQUIRED num byvalue format=PIB4.;
>
> /* Function call */
> rc = MODULEN('ShellExecuteA',,'Open',parm_file,,,1);
Never used optional arguments due to potential problems -- use all args and
pass 0 or ''. If you want to try to debug the win32 invocation state, use a
'*IE' argument before the function name argument. *IE will cause
additional info to be dumped into the log.
--
Richard A. DeVenezia
http://www.devenezia.com/
|