Link to websites


I have a question with regard to linking to external webpages from a clarion browse/tree or form. I would like to create a related table to the main table with only tree fields;
id - primary key
description - string - description (of link/webpage and a
weblink - string to hold the hyperlink.

In this table I would store additional links which the user can select and the link would open in the default web browser with the relevant linked page. There is no need to show it in a clarion window.

Can this be done easily with a command/embed in clarion, or do I need to obtain some 3rd party to be able to do this?


you can use standard (cla10 for sure) procedure from MODULE(‘cwutil.clw’)
OpenUrlLink(STRING urlLink,BYTE forceHttp=1,<STRING path>, <STRING params>),ULONG,PROC


I tried your suggestion and did the following:

  • Added ABUTIL.clw to the project in the solution window
  • Made a button (buttonTest) where I added the following source code to the accepted embed point:


!Suggested code from you
!OpenUrlLink(STRING urlLink,BYTE forceHttp=1,, ),ULONG,PROC

!My code

!Opens URL to local newspaper
OpenUrlLink(‘’,BYTE forceHttp=1),ULONG,PROC


I did not really work from my.

Here are my errors:

Unknown procedure label - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,55
Unknown procedure label - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,49
Expected: { ; - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,48
Unknown procedure label - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,7
Unknown identifier: FORCEHTTP - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,36
Expected: ( ) [ , &= { @ . - C:\Users\Werner Lekven\Documents\Clarion\Apps\WinPilot2018\winpilot005.clw:231,36

Are there any missing steps in what I am doing?



In the Global Embeds (Inside the Global Map) add:

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

Then in the button’s accept embed point:

Shellex:Param =’’

Works fine for me.

You don’t need to add anything to the project in the solution!!!

Just add in the global map as rob said:

then you can use
!Opens URL to local newspaper

Works like a dream!

Thanks very much, both of you.


1 Like

Why make it so difficult :slight_smile:
With any recent version of Clarion you can simply use the RUN command eg


which will open the website and wait until the user has closed the browser down.

IMO the “,1” wait for close is a bad idea. It can confuse the user because they can click on your Clarion window and it will show “Not Responding” and paint gray and appear hung. If you make it wait long enough it may actually hang. The confused user may shut it down in task man.

If I want to wait I usually open a Window() that says “waiting for you to finish with xxxx” and have a Cancel button. You cannot use RUN() for that you have to use CreateProcess() or ShellExecuteEx() so you can get a Handle to the Process. With that hProcess you can GetProcessExitCode() to see if it is STILL_ACTIVE (259). I’ll check for Exit<>259 in a Timer, and if they try to Cancel warn them. I have never tried this with a URL to know if a browser gives a unique hProcess for that page. I would probably run IE or Chrome.

A quick-and-dirty way would be to open a Window that explains “You must complete the Webpage xxx. Don’t click here or the program will show ‘Not Responding’ and may hang”. So when it appears hung they know why.

BTW in C11 they added the “Hot Light” Windows System Color for URLs. I think the Window Designer does not handle it right and changes the it to the system RGB color of light blue, so best to set Prop:FontColor at runtime to have the user’s theme.

COLOR:HotLight EQUATE (8000001AH) !Color for a hyperlink or hot-tracked item.

I have a System Colors tool on Git. You’ll see Hot Light on the right side middle:

This code is attached to a button in the form for testing. Most likely I will attached to a browse.
I tested the code with opening a webpage as you suggested. This works fine. But not with a document path from the database. The path is correct in the form and stored in a string.

Source Code below

! Opening the webpage works fine with this code

! Local string variable document(250)

! The code below doesnt work

Document=clip(?tblDoc:FileLocation) !The use variable from the form. It is correctly displayed in the form.

! I use a message box to test the content of the variable ‘document’. The message box shows the number’16’ instead of the content. Why?


! Therefore it will not work. Why does it show a number instead of the ?tblDoc:FileLocation?

Because ?tblDoc:FileLocation is a number, usually it is a number of the control in WINDOW structure. To get a contents you can call CONTENTS(?tblDoc:FileLocation)


Your suggestion works fine. Thanks for your suggestion.

A bit different for a guy used to the text1.text property format in other applications.

Final code:

! Opens stored file using relevant file location field in the database.

! Loads database field into local variable


! Opens the document with default application


If the ENTRY control (in your case ?tblDoc:FileLocation) represents data field (for example a field from a table, in your case tblDoc:FileLocation), then you can use field contents:

OMG. You guys have funny days.

Next to discuss: how to calc 2+2 :joy:

Well, it works for me.


1 Like

I do it a bit differently than others because my needs are a tiny bit more complex.

NameKey                KEY(BRO:Name),NOCASE
Record                 RECORD
Name                     CSTRING(21)                    ! Browser name as shown to the user
FileSpec                 CSTRING(256)

WebQ                 QUEUE(WebQType)
Name                   CSTRING(61)
Type                   BYTE  !1=URL, 2=Email
Tip                    LIKE(URL:Notes)
Address                LIKE(URL:URL)
Browser                LIKE(URL:Browser)      !The full file spec to a browser executable or blank for the default browser

In EVENT:AlertKey for ?WebQ

  IF ?WebQ{PROPLIST:MouseDownZone} = LISTZONE:Field
    LPR:Choice = ?WebQ{PROPLIST:MouseDownRow}
    GET(WebQ, LPR:Choice)

    OpenEmailURL(WebQ.Type, WebQ.Browser, WebQ.Address)

OpenEmailURL         PROCEDURE  (BYTE pType, STRING pBrowser, STRING pAddress) ! Declare Procedure
  SHX:Operation = 'open'
  SHX:Directory = ''

  IF pType = EQ:WebURL
    IF pBrowser
      BRO:Name = CLIP(pBrowser)

      SHX:Document  = BRO:FileSpec
      SHX:Parameter = CLIP(pAddress)

      SHX:Document  = CLIP(pAddress)
      SHX:Parameter = ''
  ELSE !EQ:WebEmail
    SHX:Document  = CLIP(pAddress)
    SHX:Parameter = ''

  ShellExecute(GetDesktopWindow(), SHX:Operation, SHX:Document, SHX:Parameter, SHX:Directory, BCS_SW_SHOWMAXIMIZED)
1 Like

I changed from GetDesktopWindow() to pass Zero for Parent window to ShellExecute(0,…). Its been a long time so I cannot recall if it was because a Parent simply worked fine when Zero, or that GetDesktopWindow() was improper, or both. MSDN clearly says passing a Null Parent window is fine.

A quick search turned up Ray Chen saying its bad idea to use GetDesktopWindow() but does not mention ShellExecute specifically.

I have had GetDesktopWindow() fail on certain client machines. I forget the particulars, but it was on machines with a very strict group policy in place and no accessibility for diagnostics.

So it looks like there are times when the DesktopWindow is not available.
Desktops - Win32 apps | Microsoft Docs

By default, there are three desktops in the interactive window station: Default, ScreenSaver, and Winlogon.

The Default desktop is created when Winlogon starts the initial process as the logged-on user. At that point, the Default desktop becomes active, and it is used to interact with the user.

Whenever a secure screen saver activates, the system automatically switches to the ScreenSaver desktop, which protects the processes on the default desktop from unauthorized users. Unsecured screen savers run on Winsta0*Default*.

The Winlogon desktop is active while a user logs on. The system switches to the default desktop when the shell indicates that it is ready to display something, or after thirty seconds, whichever comes first. During the user’s session, the system switches to the Winlogon desktop when the user presses the CTRL+ALT+DEL key sequence, or when the User Account Control (UAC) dialog box is open.

The Winlogon desktop’s security descriptor allows access to a very restricted set of accounts, including the LocalSystem account. Applications generally do not carry any of these accounts’ SIDs in their tokens and therefore cannot access the Winlogon desktop or switch to a different desktop while the Winlogon desktop is active.

So if the Winlogin desktop/window, UAC window, Ctrl Alt Del window or Secure Screensaver desktop/window is active, ie not the default users interactive desktop/window, then I would imagine the GetDeskTopWindow() api could fail, and I’d expect this api call in services may cause problem as well.

I think this 3 desktop/window setup is what prompted MS to make a cutdown version of Windows Server and called it Server Core as discussed here, where even more desktop/user functionality is restricted. Clarion 10/11 program running on Windows Server Core - questions - ClarionHub

TL;DR I wonder if I witnessed an attack vector by slowing up the windows machine cpu using the bios!

So a few weeks back on a couple of windows machines after a reboot they seemed to really really slow down so much so it took like over 5mins to get to the windows login window to appear and then after logging in, it took like another 5 or 10mins before the taskbar and icons appeared and anything could be done using the desktop.

So I’m wondering if there was some bios malware which slowed the cpu right up, to then exploit this wait 30seconds before automatically activating the windows desktop.