Making The Internet Connection

by John Hickey

Published 1998-04-01    Printer-friendly version

Download the code here

Publisher's Note
At several points in this article, the template code is much too long to fit in a normal width document. We've used continuation characters ( the rule character | ) to show where the code is continued. This code will not work as shown in this article. You should use the enclosed templates instead. We hope this message helps eliminate the confusion that could be caused.

Seems like everyone is connected to the Internet these days. And in a lot of programs, you can go to the "About" box, click on the publisher's web page, and your browser is immediately launched and you are taken directly there. I figured, "if other programs can do it, Clarion can too!" And, of course, it can.

SHELLEXECUTE is a windows API command that lets you launch any file with its associated application. For example, you might want to open a Microsoft Word document. With SHELLEXECUTE, you would pass it the name of the document, and it would automatically run MS Word and then open the document.

For a web page, you simply need to pass SHELLEXECUTE the name of the web page, for example, http://www.clariononline.com  SHELLEXECUTE will then launch the default browser and go to the Clarion Online page. For e-mail, the command to pass it is "mailto:" and the e-mail address (for example, mailto:jeff@clariononline.com).

So, what we want to do is to have this effect:

Image8.gif

Where the end-user clicks on Clarion Online and is taken to their Home Page.

No problem, right? Simply:

  1. Declare the SHELLEXECUTE API in your App;
  2. Place a string control with the web address on a window;
  3. Underline it and change its color (so it stands out);
  4. Place a region over the string;
  5. Change the cursor to a Hand for the region;
  6. Embed some source in the MouseUp event that calls the SHELLEXECUTE command for the web or e-mail address.

You could do all that for every link you wanted to create; or you could take the easy way out and write a Template!

The Easy Way!

The Template below accomplishes our goal in a variety of ways. It contains the following:

  1. A Global Extension Template that allows us to include the SHELLEXECUTE API;
  2. A Procedure Extension Template that lets us quickly create links as in the example above;
  3. A Control Template that lets us place a button on the screen that calls a web page or sends e-mail;
  4. And a Code Template that allows us to place code to link to the Internet from anywhere in our application.

To increase the flexibility of the Template, I designed it so you could hard-code in your addresses, or use a variable.

The Global Extension Template

Here is the code for the Global Extension. All this does is allow us to include the SHELLEXECUTE API in our Clarion application. Note that we use a check-box here, in case another Template has already included the extension.

Image9.gif

#TEMPLATE(InternetLink,'Internet Link Template')
#!Copyright 1998, John Hickey, All Rights Reserved
#!
#EXTENSION(InternetLinkGlobal,'Internet Link Global Template'),|
           APPLICATION,LAST
#!
#SHEET
  #TAB('Internet Link Global Template 1.0')
    #BOXED('')
      #DISPLAY('')
      #DISPLAY('The Internet Link Global Template will allow')
      #DISPLAY('you to create Internet Hyperlinks in your CW')
      #DISPLAY('Application.')
      #DISPLAY('')
      #PROMPT('Include SHELLEXECUTE API',CHECK),%PTSIncludeShell,|
               Default(1),AT(10,,,)
      #DISPLAY('')
    #ENDBOXED
  #ENDTAB
#ENDSHEET
#! ----------------------------------------------------------------
#AT(%GlobalMap)
  #PROJECT('hand.cur')
URLHandler(unsigned, STRING)
  #IF(%PTSIncludeShell)
MODULE('winstuff')
    #IF (%Target32)
ShellExecute(UNSIGNED,LONG,*CSTRING,LONG,*CSTRING,|
             SIGNED),UNSIGNED,PASCAL,RAW,NAME('SHELLEXECUTEA')
    #ELSE
ShellExecute(UNSIGNED,LONG,*CSTRING,LONG,*CSTRING,|
             SIGNED),UNSIGNED,PASCAL,RAW
    #ENDIF
END
  #ENDIF
#ENDAT
#! ----------------------------------------------------------------

Note in the above Template declaration that we've made allowances for 16 or 32 bit applications. The only difference between the two prototypes is that the 32 bit prototype gets theNAME('SHELLEXECUTEA') parameter.We've also included the HAND.CURin the Project, and defined a new procedure called URLHANDLER, which is defined below:

#AT(%ProgramProcedures)
URLHandler   PROCEDURE (wHandle, URL) ! Declare Procedure
URLBuffer    CSTRING(256)
EmptyString  CSTRING(254)
  CODE ! Begin processed code
  URLBuffer = CLIP(URL)
  EmptyString=''
  x#=ShellExecute(whandle, 0, URLBuffer, 0, EmptyString, 1)
#ENDAT
#!----------------------------------------------------------------

This procedure takes two parameters; the handle of the calling window, and the URL that will be called (this would be the web address, or the e-mail address). This procedure will do all the work for us.

The Procedure Extension Template

This Extension would be used when you want to create a screen as in our above example (an About Box). The Template takes only a few parameters. First, it needs to know which control you want it to use. Good candidates are STRING or IMAGE controls. If the Internet Link Control is on a TAB, you will want to define that as the Parent Control; otherwise leave it blank (if you don't define a Parent Control on a Tab, then the created REGION will exist on all Tabs, which will give you some bizarre results!)

Next, you tell the Template whether this is an HTML/FTP address, or an e-mail address (so the Template knows whether to append the "mailto:" prefix to the address). Finally, put in the web address. You can use a variable by placing an ! in front of the variable name (for example, !COM:WEBADDRESS).

Image10.gif

Here is the code for this Extension:

#EXTENSION(InternetLinkCreator,'Create Internet Links'),|
           PROCEDURE, LAST
#BOXED('')
  #DISPLAY('Insert controls to use as your Internet Links')
  #DISPLAY('Good candidates are String and Image controls.')
  #PROMPT('Create Controls Starting At:',@N_5),|
           %ILControlStart,DEFAULT(100)
  #BUTTON ('Internet Link Controls'),|
           MULTI(%ILControls, %ILControl), INLINE
    #PROMPT('Internet Link Control:',CONTROL),%ILControl
    #PROMPT('Parent Control:',CONTROL),%ILParent
    #PROMPT('Link To',OPTION),%ILLinkTo
    #PROMPT('HTML/FTP/.html',RADIO)
    #PROMPT('E-Mail',RADIO)
    #PROMPT('Address:',@S200),%ILAddress
    #DISPLAY('Use a ! in front of a variable.')
  #ENDBUTTON
#ENDBOXED
#ATSTART
  #DECLARE(%ILControlNumber)
  #DECLARE(%InternetVar)
#ENDAT
#AT (%AfterWindowOpening)
DO CreateILControls
#ENDAT

After the Window is opened, the program calls a routine called CreateILControls. This routine dynamically creates REGION controls around the control you've defined. It also sets the Cursor for the REGION to a pointing hand.

In the Accept Loop Before Field Handling Embed, the program calls the InternetLinkEvents routine to check and see if the mouse has been clicked inside the region. If it has, the appropriate action is taken.

#AT (%AcceptLoopBeforeFieldHandling)
DO InternetLinkEvents
#ENDAT
#AT(%ProcedureRoutines)
CreateILControls   ROUTINE !Create HyperLink Regions
  #SET(%ILControlNumber,%ILControlStart)
  #FOR(%ILControls)
CREATE(%ILControlNumber, CREATE:Region , %ILParent)
%ILControlNumber{PROP:Imm } = TRUE
%ILControlNumber{PROP:Use } = %ILControlNumber
%ILControlNumber{PROP:Height} = %ILControl{PROP:Height}
%ILControlNumber{PROP:Width } = %ILControl{PROP:Width }
%ILControlNumber{PROP:XPos } = %ILControl{Prop:XPos }
%ILControlNumber{PROP:YPos } = %ILControl{Prop:YPos }
%ILControlNumber{PROP:Hide } = FALSE
%ILControlNumber{PROP:Cursor} = '~hand.cur'
    #SET(%ILControlNumber,%ILControlNumber + 1)
  #ENDFOR
InternetLinkEvents Routine !Handle Internet Link Events
  #SET(%ILControlNumber,%ILControlStart)
  #FOR(%ILControls)
IF FIELD()=%ILControlNumber AND Event()=Event:MouseUp
    #IF(%ILLinkTo='HTML/FTP/.html')
      #IF(SUB(%ILAddress,1,1)='!')
        #SET(%InternetVar,SUB(%ILAddress,2,100))
  URLHandler(%Window{prop:handle},CLIP(%InternetVar))
      #ELSE
  URLHandler(%Window{prop:handle},'%ILAddress')
      #ENDIF
    #ELSE
      #IF(SUB(%ILAddress,1,1)='!')
        #SET(%InternetVar,SUB(%ILAddress,2,100))
  URLHandler(%Window{prop:handle},'mailto:' |
             & CLIP(%InternetVar))
      #ELSE
  URLHandler(%Window{prop:handle},'mailto:%ILAddress')
      #ENDIF
    #ENDIF
  EXIT
END
    #SET(%ILControlNumber,%ILControlNumber + 1)
  #ENDFOR
#ENDAT
#!--------------------------------------------------

The Control Extension Template

This Template allows you to place a Button on your window that links to the Internet. The prompts are very similar to the previous Template:

Image11.gif

Here, all we need to know is what type of address it is, and the address itself. Here's the Template:

#CONTROL(InternetLinkButton,'Internet Link Button Control')
  CONTROLS
    BUTTON('&InternetLink'),USE(?InternetLink)
  END
#BOXED('')
  #PROMPT('Link To',OPTION),%BILLinkTo
  #PROMPT('HTML/FTP/.html',RADIO)
  #PROMPT('E-Mail',RADIO)
  #PROMPT('Address:',@S200),%BILAddress
  #DISPLAY('Use a ! in front of a variable.')
#ENDBOXED
#ATSTART
  #DECLARE(%InternetVar)
  #DECLARE (%InternetLinkButton)
  #FOR (%Control), WHERE(%ControlInstance = %ActiveTemplateInstance)
    #SET (%InternetLinkButton, %Control)
  #ENDFOR
#ENDAT
#AT (%ControlEventHandling, %InternetLinkButton, 'Accepted')
  #IF(%BILLinkTo='HTML/FTP/.html')
    #IF(SUB(%BILAddress,1,1)='!')
      #SET(%InternetVar,SUB(%BILAddress,2,100))
URLHandler(%Window{prop:handle},CLIP(%InternetVar))
    #ELSE
URLHandler(%Window{prop:handle},'%BILAddress')
    #ENDIF
  #ELSE
    #IF(SUB(%BILAddress,1,1)='!')
      #SET(%InternetVar,SUB(%BILAddress,2,100))
URLHandler(%Window{prop:handle},'mailto:' & CLIP(%InternetVar))
    #ELSE
URLHandler(%Window{prop:handle},'mailto:%BILAddress')
    #ENDIF
  #ENDIF
#ENDAT
#!--------------------------------------------------

The Code Template

The Code Template is also similar to the previous Template in its prompts:

Image12.gif

In the example above, we're using a variable called INL:LINK, so we've placed an exclamation mark in front of it. This allows you to dynamically assign a web or e-mail address in your program. An example might be an Internet Address Book.

#CODE(InternetLinkCode,'Internet Link Code Template')
  #BOXED('')
    #PROMPT('Link To',OPTION),%CILLinkTo
    #PROMPT('HTML/FTP/.html',RADIO)
    #PROMPT('E-Mail',RADIO)
    #PROMPT('Address:',@S200),%CILAddress
    #DISPLAY('Use a ! in front of a variable.')
  #ENDBOXED
#ATSTART
  #DECLARE(%InternetVar)
#ENDAT
#IF(%CILLinkTo='HTML/FTP/.html')
  #IF(SUB(%CILAddress,1,1)='!')
    #SET(%InternetVar,SUB(%CILAddress,2,100))
URLHandler(%Window{prop:handle},CLIP(%InternetVar))
  #ELSE
URLHandler(%Window{prop:handle},'%CILAddress')
  #ENDIF
#ELSE
  #IF(SUB(%CILAddress,1,1)='!')
    #SET(%InternetVar,SUB(%CILAddress,2,100))
URLHandler(%Window{prop:handle},'mailto:' & CLIP(%InternetVar))
  #ELSE
URLHandler(%Window{prop:handle},'mailto:%CILAddress')
  #ENDIF
#ENDIF

The Demo App

I've included a Demo application that shows the use of each of these Templates. The application is called ILDEMO, and was written in Clarion For Windows 2.003. You can use the program in 2.003, and it also works in Clarion 4 with the Legacy Templates. An example is also included for Clarion 4 with the ABC Templates.

The Demo is a simple Internet Address book.

Image13.gif

The Code Template was used in the DOUBLE-CLICK embed, so double clicking would launch the web browser or e-mail program. The Visit Topspeed button used the Button Control. In the About Box, the Internet Link Procedure Extension was used.

As has been said before, the Clarion Templates extend the language, making your application development fast and consistent. Now you can quickly and easily help get your clients connected to the web!

Printer-friendly version