# Link to websites

**URL:** <https://clarionhub.com/t/link-to-websites/3639>\
**Category:** uncategorized\
**Created:** [November 2, 2020, 1:33pm UTC](https://clarionhub.com/t/link-to-websites/3639 "2020-11-02T13:33:52Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 2, 2020, 1:33pm UTC](https://clarionhub.com/t/link-to-websites/3639/1 "2020-11-02T13:33:52Z")

</div>

Hello,

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?

Brgds

---

<div class="post-metadata">

**Author:** ![Clarion\_clarion](https://clarionhub.com/user_avatar/clarionhub.com/clarion_clarion/32/636_2.png) [@Clarion\_clarion](https://clarionhub.com/u/Clarion_clarion)\
**Post date:** [November 2, 2020, 2:05pm UTC](https://clarionhub.com/t/link-to-websites/3639/2 "2020-11-02T14:05:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 3, 2020, 12:31pm UTC](https://clarionhub.com/t/link-to-websites/3639/3 "2020-11-03T12:31:22Z")

</div>

Hello,

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(‘www.vg.no’,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?

Thanks

Brgds  
Werner

---

<div class="post-metadata">

**Author:** ![rob\_bac](https://clarionhub.com/user_avatar/clarionhub.com/rob_bac/32/686_2.png) [@rob\_bac](https://clarionhub.com/u/rob_bac)\
**Post date:** [November 3, 2020, 1:55pm UTC](https://clarionhub.com/t/link-to-websites/3639/4 "2020-11-03T13:55:09Z")

</div>

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

INCLUDE(‘CWUTIL.INC’),ONCE  
Module(‘WINAPI’)  
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:AssocFile=‘www.vg.no’  
Shellex:Param =‘’  
Shellex:Directory=‘’  
Shellex:Operation=‘open’  
ShellExecute(GetDesktopWindow(),Shellex:Operation,Shellex:AssocFile,Shellex:Param,Shellex:Directory,3)

Works fine for me.

---

<div class="post-metadata">

**Author:** ![Clarion\_clarion](https://clarionhub.com/user_avatar/clarionhub.com/clarion_clarion/32/636_2.png) [@Clarion\_clarion](https://clarionhub.com/u/Clarion_clarion)\
**Post date:** [November 4, 2020, 8:19am UTC](https://clarionhub.com/t/link-to-websites/3639/5 "2020-11-04T08:19:00Z")

</div>

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

Just add in the global map as rob said:

> [@rob\_bac](#):
>
> In the Global Embeds (Inside the Global Map) add:
> 
> INCLUDE(‘CWUTIL.INC’),ONCE

then you can use  
!Opens URL to local newspaper  
OpenUrlLink(‘www.vg.no’)

---

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 4, 2020, 9:47am UTC](https://clarionhub.com/t/link-to-websites/3639/6 "2020-11-04T09:47:08Z")

</div>

Works like a dream!

Thanks very much, both of you.

Werner

---

<div class="post-metadata">

**Author:** ![Graham\_Dawson](https://clarionhub.com/user_avatar/clarionhub.com/graham_dawson/32/1331_2.png) [@Graham\_Dawson](https://clarionhub.com/u/Graham_Dawson)\
**Post date:** [November 4, 2020, 2:19pm UTC](https://clarionhub.com/t/link-to-websites/3639/7 "2020-11-04T14:19:29Z")

</div>

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

run(‘www.vg.no’,1)

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

---

<div class="post-metadata">

**Author:** ![CarlBarnes](https://clarionhub.com/user_avatar/clarionhub.com/carlbarnes/32/1859_2.png) [@CarlBarnes](https://clarionhub.com/u/CarlBarnes)\
**Post date:** [November 4, 2020, 5:28pm UTC](https://clarionhub.com/t/link-to-websites/3639/8 "2020-11-04T17:28:29Z")

</div>

> [@Graham\_Dawson](#):
>
> run(‘www.vg.no’,1)

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:

> **[GitHub - CarlTBarnes/SystemColors: System Color Viewer and Picker. Colors organized...](https://github.com/CarlTBarnes/SystemColors)**
>
> System Color Viewer and Picker. Colors organized with Text and Background together.

---

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 5, 2020, 2:39pm UTC](https://clarionhub.com/t/link-to-websites/3639/9 "2020-11-05T14:39:41Z")

</div>

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)  
Document=clip(‘www.vg.no’)  
run(Document)

!========================  
! 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?

message(Document)  
run(Document)

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

---

<div class="post-metadata">

**Author:** ![Mike\_Duglas](https://clarionhub.com/user_avatar/clarionhub.com/mike_duglas/32/1061_2.png) [@Mike\_Duglas](https://clarionhub.com/u/Mike_Duglas)\
**Post date:** [November 5, 2020, 3:53pm UTC](https://clarionhub.com/t/link-to-websites/3639/10 "2020-11-05T15:53:30Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 5, 2020, 7:44pm UTC](https://clarionhub.com/t/link-to-websites/3639/11 "2020-11-05T19:44:55Z")

</div>

Mike

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

```
  Document=clip(CONTENTS(?tblDoc:FileLocation))    

```

! Opens the document with default application

```
   run(Document)

```

---

<div class="post-metadata">

**Author:** ![Mike\_Duglas](https://clarionhub.com/user_avatar/clarionhub.com/mike_duglas/32/1061_2.png) [@Mike\_Duglas](https://clarionhub.com/u/Mike_Duglas)\
**Post date:** [November 6, 2020, 9:15am UTC](https://clarionhub.com/t/link-to-websites/3639/12 "2020-11-06T09:15:34Z")

</div>

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:  
`Document=tblDoc:FileLocation`

---

<div class="post-metadata">

**Author:** ![Clarion\_clarion](https://clarionhub.com/user_avatar/clarionhub.com/clarion_clarion/32/636_2.png) [@Clarion\_clarion](https://clarionhub.com/u/Clarion_clarion)\
**Post date:** [November 6, 2020, 10:33am UTC](https://clarionhub.com/t/link-to-websites/3639/13 "2020-11-06T10:33:58Z")

</div>

OMG. You guys have funny days.

Next to discuss: how to calc 2+2 😂

---

<div class="post-metadata">

**Author:** ![Werner](https://clarionhub.com/user_avatar/clarionhub.com/werner/32/1638_2.png) [@Werner](https://clarionhub.com/u/Werner)\
**Post date:** [November 6, 2020, 4:43pm UTC](https://clarionhub.com/t/link-to-websites/3639/14 "2020-11-06T16:43:43Z")

</div>

Well, it works for me.

Werner

---

<div class="post-metadata">

**Author:** ![PeterG](https://clarionhub.com/user_avatar/clarionhub.com/peterg/32/6158_2.png) [@PeterG](https://clarionhub.com/u/PeterG)\
**Post date:** [November 9, 2020, 11:37am UTC](https://clarionhub.com/t/link-to-websites/3639/15 "2020-11-09T11:37:16Z")

</div>

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

```
Browser FILE,DRIVER('TOPSPEED'),RECLAIM,PRE(BRO),CREATE,BINDABLE,THREAD
NameKey KEY(BRO:Name),NOCASE
Record RECORD
Name CSTRING(21) ! Browser name as shown to the user
FileSpec CSTRING(256)
                       END
                     END

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
                     END

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)
    POST(EVENT:CloseWindow)
  END

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

  IF pType = EQ:WebURL
    IF pBrowser
      Access:Browser.Open
      Access:Browser.UseFile
      BRO:Name = CLIP(pBrowser)
      Access:Browser.Fetch(BRO:NameKey)

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

      Access:Browser.Close
    ELSE
      SHX:Document = CLIP(pAddress)
      SHX:Parameter = ''
    END
  ELSE !EQ:WebEmail
    SHX:Document = CLIP(pAddress)
    SHX:Parameter = ''
  END

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

```

---

<div class="post-metadata">

**Author:** ![CarlBarnes](https://clarionhub.com/user_avatar/clarionhub.com/carlbarnes/32/1859_2.png) [@CarlBarnes](https://clarionhub.com/u/CarlBarnes)\
**Post date:** [November 9, 2020, 6:15pm UTC](https://clarionhub.com/t/link-to-websites/3639/16 "2020-11-09T18:15:56Z")

</div>

> [@PeterG](#):
>
> ` ShellExecute(GetDesktopWindow()`

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.

> **[What's so special about the desktop window? - The Old New Thing](https://devblogs.microsoft.com/oldnewthing/20040224-00/?p=40493)**
>
> The window returned by GetDesktopWindow() is very special, and I see people abusing it all over the place. For example, many functions in the shell accept a window handle parameter to be used in case UI is needed. IShellFolder::EnumObjects, for...

---

<div class="post-metadata">

**Author:** ![jslarve](https://clarionhub.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@jslarve](https://clarionhub.com/u/jslarve)\
**Post date:** [November 9, 2020, 11:04pm UTC](https://clarionhub.com/t/link-to-websites/3639/17 "2020-11-09T23:04:41Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![anon23294430](https://clarionhub.com/user_avatar/clarionhub.com/anon23294430/32/3829_2.png) [@anon23294430](https://clarionhub.com/u/anon23294430)\
**Post date:** [March 25, 2022, 9:30pm UTC](https://clarionhub.com/t/link-to-websites/3639/18 "2022-03-25T21:30:42Z")

</div>

So it looks like there are times when the DesktopWindow is not available.  
[Desktops - Win32 apps | Microsoft Docs](https://docs.microsoft.com/en-us/windows/win32/winstation/desktops)

> 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](https://docs.microsoft.com/en-us/windows/desktop/Services/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](https://clarionhub.com/t/clarion-10-11-program-running-on-windows-server-core/2541/11)

---

<div class="post-metadata">

**Author:** ![anon23294430](https://clarionhub.com/user_avatar/clarionhub.com/anon23294430/32/3829_2.png) [@anon23294430](https://clarionhub.com/u/anon23294430)\
**Post date:** [March 26, 2022, 9:02am UTC](https://clarionhub.com/t/link-to-websites/3639/19 "2022-03-26T09:02:20Z")

</div>

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

> [@anon23294430](#):
>
> 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.

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.
