ShellExecute in Multi DLL APP not Compiling

Clarion 11.0.13630

I do have a multi dll app (Capesoft Multi-project).
In several of my windows the users can click a button for direct access to web, mail or telephone.
For this i use ShellExecute.
In the Global Embeds, inside the Global Map (in each app) i added:

  ShellExecute(Unsigned, *CString, *CString, *CString, *CString,Signed),Unsigned, Pascal, Raw, Proc,name('ShellExecuteA'),PROC
  GetDesktopWindow(), Unsigned, Pascal

Then the button to activate this has for instance for a telephone call:

  Shellex:Param    =''

This works fine, but in one dll i get 5 errors;

Unknown identiefier: Shellex:AssocFile
Unknown identiefier: Shellex:Param    
Unknown identiefier: Shellex:Directory
Unknown identiefier: Shellex:Operation
No matching prototype available. (pointing at ShellExecute)

I don’t see any difference between the working dll and the one that fails.
Any ideas or suggestions would be very nice, thanks!


Hi Rob,

so you’ve skipped one part in the explanation, which I guess would explain everything;

This line;

Implies that Shellex:AssocFile is a variable, defined in the app, even possibly in the procedure.
Go to one of the apps where it works, and see where that is defined. then either define it (and friends) in the problem app or…

It’s possible those variables are being exported by one of your DLL’s. Multi-Proj includes the ability to generate a template for you to “include” that DLL. So, for example, if you are exporting it from the A.DLL then you’d have an Activate_A extension template, which might be missing from the problem DLL? You’ll know for sure by looking at a working DLL to see how the variables are declared there.

1 Like

As Bruce said the Shellex:Xxxx CSTRING() variables need to be defined some place in scope in the APP. Likely you made them Global. Find them where they work in the other APPs.

IMO there is no need to passGetDesktopWindow() for Window Handle, you can pass a Zero. Another improvement would be to place the 4+ ShellEx: variables inside a GROUP so you can CLEAR(Shellex:Group) to clear them All and not miss one.

Since you are including CWUtil you can call it’s Shell Execute wrapper function OpenUrlLink() which I pasted below so you can see how it works and the parameters. I think you could call as OpenUrlLink('tel:'&CLIP(AGD:TEL), False). This will not pass Show as 3 to Maximize so a bit different but fine IMO.

Rather than define your ShellEx CSTRING variables and call the API Shell Execute what I usually do is create a wrapper function of my own, like below, so I can pass STRINGs and deal with the CSTRINGs in that one procedure.

OpenUrlLink PROCEDURE(STRING urlLink,BYTE forceHttp=1,<STRING path>, <STRING params>)
lWHandle         LONG
lOperation       CSTRING(255)
lFileUrl         CSTRING(255)
lPath            CSTRING(255)
lParam           CSTRING(255)
lShowCmd         LONG(1)
lRetVal          ULONG
    IF LEFT(UPPER(urlLink),4)<>'HTTP' AND forceHttp
       lFileUrl    = 'http://'&clip(urlLink)
       lFileUrl    = clip(urlLink)
    lWHandle    = 0{PROP:Handle}!Get the handle of the current window
    lOperation  = 'Open'    
    lPath       = path
    lParam      = params
    lShowCmd    = 1
    lRetVal = SV_ShellExecuteURL(lWHandle,lOperation,lFileUrl,lParam,lPath,lShowCmd)
    RETURN lRetVal

Thanks Bruce and Carl.
Strange thing i couldn’t find where the Shellex:AssocFile variable was defined, neither Global or in the procedure where it did work.
Looking for the truth takes too much time for me now, so i skipped to Carl’s suggestion using the OpenUrlLink.
This works fine:
OpenUrlLink(‘tel:’&CLIP(AGD:TEL), False)

Still confused but i can go on.

Another thing about GetDesktopWindow(), is that you shouldn’t accept its value verbatim.
Many years back, had at least one user where it returned a “bogus” value (a very low non-zero number, but I don’t remember what the value was). It only happened to one or two users out of many, but it did happen.

Maybe its from an Include(file) try searching the files in your