CapeSoft.Com
Clarion Accessories
CapeSoft MessageBox
Documentation
CapeSoft Logo

CapeSoft MessageBox
Documentation

Download Latest Version JumpStart FAQ History
Installed Version Latest Version

Introduction

Have you ever heard the saying: "I got an error message which said something like..."? or: "This program never works!" Getting the actual message out of the user can be a lengthy process. To try and make a logging system for every message that you make, gets a bit tedious. It either means making a window and calling that window every time, or else calling a function whenever you call the message. Sounds like the job for an object or a template!

Thus came forth CapeSoft MessageBox, which has some useful features enhancing our other products. I found whilst using Special Agent, that there were many occasions where I had to work around that "Are you sure you want to delete this record?" message. Wouldn't it be great to integrate Makeover into your messages and stops to make them look like the rest of your program?

The advantage of using CapeSoft MessageBox is you can use the Message(), Stop() and Halt() commands as usual, but they'll call the CapeSoft MessageBox functions instead of the Clarion ones, so you don't have to go changing all your existing code!!

CapeSoft MessageBox comes in the form of a global object set and a template that makes it easy to use the objects. Because MessageBox is managed in a window that the programmer controls, there really isn't anything you can't do!

Note: Although CapeSoft MessageBox is written using objects, you can use CapeSoft MessageBox in legacy applications as well.

Note:It his highly recommended that you take a bit of time to read up about the Message (in particular), Stop and Halt functions in the Clarion manuals to be able to obtain the full functionality of CapeSoft MessageBox.

Features

Note: The MessageBox text is limited to 1024 characters.

Installation Instructions

  1. Run the supplied installation program. (You may have already done this, to get this far).

Note:
Please take note of the example applications section of this doc to demonstrate some of the features of CapeSoft MessageBox.

Getting Started

Step 1 (optional - if you want to log messages to a file in your dictionary):

Open your dictionary (of your application that you want to add MessageBox to) and import the MessageBox.txd file that is found in the clarion\accessory\libsrc\win folder.

Step 2:

Open your application (that you want to add MessageBox to) in the Clarion IDE. If this is a Multi-DLL application, then the application to open is the Data-DLL.

Run the Template Utility 'ImportCSMessageBoxxxx' (In the 'Application' menu, select the 'Template Utility'). xxx meaning abc or leg (for legacy) depending on which template set you are using for this application (for multi-DLL projects - do this only on the data DLL).

Note the names of the 3 procedures added: ds_Stop, ds_Halt and ds_Message (these are the names of the 3 procedures that will be used for the stop(), halt() and message() functions).

Step 3a (For single app systems - for multi-app systems go to step 3b):

Add CapeSoft MessageBox's Global Extension Template to your application.

On the Options tab of the MessageBox Global Extension template select the corresponding procedure for each of the procedures required. So for the MessageBox Procedure, select the ds_Message procedure.

Pick the Use Threaded Class in the Use ThreadSafe MessageBox drop list (the non-threadsafe is for old apps).

NOTE: Clarion 9 users must visit each procedure's properties, as there is a bug in Clarion 9 (fixed in 9.1, not present in C8) that will force a compile error until this is done:

Proceed to step 4.

Step 3b (For multi-app systems):

Add CapeSoft MessageBox's Global Extension Template to your Data DLL application.

On the Options tab of the MessageBox Global Extension template select the corresponding procedure for each of the procedures required. So for the MessageBox Procedure, select the ds_Message procedure.

Pick the Use Threaded Class in the Use ThreadSafe MessageBox drop list (the non-threadsafe is for old apps).

  1. In all apps, including the exe and data dll, go to the Multi-DLL tab and turn on the option "This is part of a Multi-DLL program" checkbox.
  2. In the Data DLL ONLY check the "Export MessageBox from this DLL" checkbox.
You are not required to add the MessageBox extension to any of the other applications in your suite. By adding it to the Data DLL all the MESSAGE calls will use the Capesoft MessageBox window, regardless of where that code is.
However, if you want to make use of the advanced MessageBox features (like a timer for a specific Message) then you will need to add the MessageBox global extension to that app as well. Be sure to set the settings on the Multi-DLL tab of that app correctly (as per item 1 and 2 in the list above.)

Step 4 (optional - if you want to set features using templates):

Using the 'CapeSoft MessageBox Set Features' code template (or you can do it manually), set the features properties that you require, if you're using the 'CapeSoft MessageBox with Features' objects.

Example Applications

CapeSoft MessageBox ships with a number of examples to aid you in implementing some of the features.

There is only one application in each directory, except the Multi-DLL application example, which has all the applications for the multi-DLL in the one directory

The Examples are as follows

AppName Feature Description
msgbox.app 1. Illustrates the use of Messages, Stops and Halts using the 'CapeSoft MessageBox with Features' objects.
2. It uses the example tps logging file that is shipped with CapeSoft MessageBox to log messages.
3. It uses graphics and text coloring on the message box window (Transparent Strings for the message text).
4. A Browse window to show the Log File.
Legacy Multi DLL Illustrates the use of messagebox in a Multi-DLL application. Compile the rootdll.app, then the function.app, then the mainexe.app.
MesBox & HyperActive  Demonstrates CapeSoft MessageBox in conjunction with HyperActive functionality.

CapeSoft's Messaging Features

1. Message Logging to a file

Using this feature enables you to track the messages that occur while the user is using your program. At present, the fields that can be tracked are: Message, Heading, Time and Date of occurrence, Duration (that the message was open), Button Pressed and User (if the message box times out, then the User = 'Timer'). The beauty of using objects for this messaging is you're not tied to the default file structure. You can add extra fields and prime them just before the record is added to the file.

1.1. Steps to implement Message Logging

Step 1
You should add a logging file to your dictionary, or you may use the CapeSoft MessageBox default ASCII file if you like, in which case you may skip this step. There are two ways of doing this, you can either:

  1. Import the CapeSoft Message Logging file (recommended) (Details).
  2. Add your own file to your dictionary. You don't need to use the Topspeed driver.

Step 2
You need to complete the steps for implementing the CapeSoft Messaging laid out in the Getting Started section

Step 3
You need to ensure that the Global Extension template has been set to allow Message Logging.

1.1 In your application's global template open the CapeSoft MessageBox's Global Extension template and follow the steps 1.11 through 1.17 to activate the message logging.

Step 4

You need to set the Logging feature property to activate the logging. You can either:
  1. Just use the Global Extension template template setting.
  2. Use the Set Features Code Template to set the property or
  3. Set the object's LogMessages property directly

Example Code

ThisMessageBox.SetGlobalSetting('LogMessages', 1)         !Activate Message Logging
ThisMessageBox.SetGlobalSetting('LoggedIn', UserName)   !UserName is a string(100) of the user logged in

For temporary logging (i.e. to log just one message):

ThisMessageBox.OnlyOnce.LogMessages = 1

Or to turn off logging for one message (where LogMessages is turned on globally):

ThisMessageBox.OnlyOnce.LogMessages = 0

Step 5 (optional)
It's a good idea to add a browse and/or report for the logging file. You can use the Clarion (abc or legacy) templates to do this. Check the example applications for ideas.

For tips on logging and doing special and unique logging, see the FAQs.

2. Message time-outs

It's often useful to have a time out on a message. A message may be a non-essential, that you don't want a process to be halted if no-one's around, but if someone is around, then they have a chance to respond to the message. You can create a message with a default button and set the time-out length. When the time-out occurs, the default button will be "Pressed" and the message closed so that your program can continue. This feature will not be usable in stops, as the default button is the abort button. It is sometimes handy to inform your user on how much time the window will be open before the TimeOut occurs. There's an object property which you can set to display a counter that indicates the time remaining before the TimeOut occurs in hh:mm:ss.

Note: If you want to have more than one button on your message box and you want to use this feature, then you must have a default button!!!

2.1. Steps to implement the Timeout Feature

Step 1

If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template. If you would like to display the TimeOut counter in all the messages that use the TimeOut feature, you can set this up in the Global Extension Template.

Step 2

You need to set the Time-out object property. You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's Timeout property directly
Example Code

ThisMessageBox.SetGlobalSetting('TimeOut', 3000)  !30 second TimeOut - for all messages
ThisMessageBox.OnlyOnce.TimeOut = 3000            !For just one message
ThisMessageBox.SetGlobalSetting('ShowTimeOut', 1) !Show the TimeOut down-counter to indicate the time until TimeOut occurs

Step 3 (optional)

You can also set the ShowTimeOut property in order to display the time remaining until TimeOut if you don't want to set this in the global extension template.

3. Message with the DontShowThisAgain check box

There are times when you want the user to know something before they use a feature or function, but then to have the same message popping up every time they use the function is tedious for the user. That's when it would be nice to have one of those 'DontShowThisAgain' check boxes, so once the user knows what they need to know, you don't have to display the message again.

If the user checks the 'DontShowThisAgain' check box, then the next time the message is called, the message object will first check if the message should be displayed, and return the button that was clicked immediately (without displaying the window).

Thus in this instance, 3 will be returned in future without the message window being displayed:

don't show this again feature screenshot

So you can safely code the following, and it will be immaterial whether the user sees the MessageBox again:

ThisMessageBox.OnlyOnce.NotAgain = 1
ThisMessageBox.NotAgainID = 50                    
!See the Note 1 below on the use of storing the NotAgain status by ID
case Message('How many times would you like to laugh today?|If you always want to laugh this many times,|then check the DontShowThisAgain checkbox| and you won't be asked this question again.','Try DontShowThisAgain Feature','C:\My Documents\drive.ico','10|97|834|3498',3)
of 1
  NoOfLaughs = 10
of 2
  NoOfLaughs = 97
of 3
  NoOfLaughs = 834
of 4
  NoOfLaughs = 3498
end


Caution:Older versions of MessageBox (ver 1.3 and earlier) saved a 1 if the user checked the DontShowThisAgain checkbox. Thus if the above code existed in a program with ver 1.3, then it would return a 1 if the user ever checked the 'DontShowThisAgain' checkbox, even once the program has been updated to ver 1.4. You should alter the Heading or Message text slightly or use a different storage file/section, thus forcing another instance of this messageBox to appear and allowing the user to select an appropriate option.

Note 1: If you would like to use variables in your message with the DontShowThisAgain feature, then you can use the NotAgainID property which you can use to create your own unique ID for the message. This means that the status of the DontShowThisAgain checkbox will be stored by a numeric identifier rather than by the message text and heading. In this case you can ignore the next 2 notes.

Note 2: You should use the vertical bar ('|') when indicating line breaks rather than the carriage return character set ('<13,10>') when using the 'DontShowThisAgain' feature, as the ini file does not reproduce the carriage return character set correctly.

Note 3: The entry details of the ini file are as follows: 'DontShow: ' & sub(HeadingText,1,len(clip(HeadingText))) & sub(MessageText,1,len(clip(MessageText))). The entry text length can only be a maximum of 42 characters. This means that the following 2 messages will be saved in the same ini entry, and when called will receive the same values back:

don't show this again feature screenshot

Tip: You could set the INI section and file (in your MessageBox Global Extension template) to ensure that each application does not use another application's settings.

3.1. Steps to implement the 'DontShowThisAgain' Feature

Step 1
If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template.

Step 2

You need to set the 'DontShowThisAgain' object property. You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's NotAgain property directly

Example Code

ThisMessageBox.OnlyOnce.NotAgain = 1                !Activate the NotAgain feature, which will display the 'DontShowThisAgain' check box in the next message on this thread.

Step 3 (Optional)
You can set the text to appear next to the checkbox if you don't want the default 'Don't show this again' text to appear next to the check box.

Example Code

ThisMessageBox.SetGlobalSetting('NotAgainText','Save this option' )

4. Message with the PlaySound feature

Sounds can be a way of alerting a user when a message occurs, especially when the message pops-up in the middle of a long process.

4.1. Steps to implement the PlaySound Feature

Step 1
If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template.

Step 2
You need to set the wavfile (an object property) that the PlaySound must perform when the message occurs. You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's PlayWavFile property directly.
Example Code

ThisMessageBox.OnlyOnce.PlayWavFile = WavFileName  !WavFileName is a cstring(255) of the sound file to play  in the next message on this thread.

5. Skip x next Messages

If you're debugging a loop, it can be useful to use a stop or message to watch what's going on. The problem is that you often want to skip a lot of the messages until you're at the right one. It gets tedious pressing the ignore button so many times, and in many instances you go past the point where you're wanting to stop. So you use this feature to skip the correct amount of messages or stops until you're at the right one.

Note: The counter (for how many messages are to be skipped) is stored in a queue, which will be reset when the program is restarted.

Note: If you set the SkipNext property to 10 then, the 1st, 11th, 21st, etc. messages will be displayed. The number (-1) indicates the amount of messages skipped between messages displayed.

5.1. Steps to implement the SkipXNext messages feature

Step 1
If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template.

Step 2

You need to set the Object property so that the object knows how many messages to skip before displaying the next one. The object tracks what messages to skip in a queue so that you can skip (for example) 20 of Message A and skip 27 of Message B and 12 of Message C. You will need to set the property of this message before you display it. You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's SkipNext property directly
Example Code

loop 57 times                                        
  ThisMessageBox.SetGlobalSetting('SkipNext', 56)        
!Skip the following stop 55 times - so it will be shown on the 1st and 57th times
  stop('First/Last time')
  loop 12 times
    ThisMessageBox.SetGlobalSetting('SkipNext', 11)      
!Skip the following stop 10 times - so it will be shown on the 1st and 12th times
    stop('First/Last time Sub')
  end
end
ThisMessageBox.SetGlobalSetting('SkipNext', 0)

6. Icons on the Buttons

Sometimes it can be handy to display an icon on a button instead of or as well as text. There are 2 ways of doing this:

1. Including the icon in the button parameter:

The button parameter will need to be a string, so you will not be able to use the Clarion Button equates when using icons on the buttons as well - using this method (more about this in method 2). You can use the Clarion Icon equates in the string though for the relevant icons. The icon equate or icon file must be enclosed in square brackets. If the filename is placed before the button text, then it will be positioned to the left of the button text, otherwise it will be placed to the right of the button text.

Example Code

message('Message Text here','Heading Text',icon:question,'[' & icon:Open & ']Open|[' & icon:New & ']New|Copy[' & icon:Copy & ']|[' & icon:cut & ']|[' & icon:paste & ']',1)

will display the following MessageBox:



Note: If you want to use square brackets('[]') in the ButtonsString, then you must repeat the first one as follows.

message('Message Text here','Heading Text',icon:question,'Copy[[1]|Paste[[2]|Cut[[3]',3)


will display the following MessageBox:



2. Setting the Default Icon parameters:

This method is useful when you use the button equates (Button:OK, button:Yes, Button:No, etc) in your button parameters. You can simply set a property, and every time these buttons are used, the icon (that is contained in the property) will be displayed. You can also set whether the icons are displayed on the right or the left of the text with another property. You can either do this in handcode, or else you can use the MessageBox control template to set these properties.

7. Hyperlinks and Mailing the Message

Together with CapeSoft's HyperActive, you can place a HyperActive string on the MessageBox. You can even (with a few easy steps) add email support so that your users can mail you the precise message, straight from the MessageBox. Using the email support they won't even have to fill in the MessageBox Text, heading and Date and time of occurrence. This will all be done for them.

7.1. Steps to implement a Hyperlink onto your MessageBox

Step 1
If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template.

Step 2
You need to add the HyperActive Global Extension to your application and add the HyperActive Local Extension Template to your MessageBox procedure (the message window - probably called ds_message). Note: You will need to add the HALink control to the HyperActive controls list on the HyperLinks tab. Check the HyperActive docs for more details on making controls HyperActive.

Step 3
You need to set the HyperLink that the URL must point to in the MessageBox. You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's HyperLink property directly.
Example Code

ThisMessageBox.OnlyOnce.HyperLink = OurWebSite       !OurWebSite is a cstring(255) of the URL for just the next mesagge.
ThisMessageBox.SetGlobalSetting('HyperLink', OurWebSite)   !OurWebSite is a cstring(255) of the URL for all messages.


Step 4 (For mailing)

If you would like the URL to create an email of the MessageBox, then you need to set up the following:

In your Local Message Control Template you need to change the following options on the 'Features' tab:

1.1. You need to enter a variable for the Email details in the field provided. There is a field already supplied which you may use called EmailLink.

1.2.You need to enter an email address (use quotes or a variable). If you want an addressee rather than a mail address to appear in the 'To' field of the email, then you can enter the address as follows (for e.g..): 'Joe McRidgson <<joem@worldwidesupport.com>'

1.3. You can specify a descriptive subject line which will enable the reader of the email to realise that the originator of the email is the program.

email details screenshot

1.4. You can specify whether you would like MessageBox to automatically confirm whether the URL on the MessageBox (that is the hyperlink) is a web URL or not. If you check the 'Override Email if HyperLink is a web URL' checkbox then this will confirm if there is a 'www.' or a 'http://' at the beginning of the URL. If these strings are found at the beginning of the URL string, then the Email construction will be by-passed and the URL will be passed to the browser.

2. In your HyperActive Local Extension Template you need to set the URL of the Hyperlinked string. In the HyperActive Control list on the Hyperlink tab, select the ?HALink control and set the URL to the same variable that you set in 1.1. above (probably EmailLink).

2.1. The ThisMessageBox.OnlyOnce.HyperLink property (in step 3) should be set to the text that must appear in the HyperActive string control on the MessageBox. If this is left blank, then the Hyperlink will be hidden. Thus (with the above template setup):

ThisMessageBox.OnlyOnce.HyperLink = 'Mailto: CapeSoft support'

will yield the following message and email (when the URL is clicked):

hyperlink control screenshot

forwarded messagebox details screenshot

8. The DontShowWindow Feature

There are times when you cannot access a message that is being displayed, such as a Clarion message or a 3rdparty DLL of which you do not have the access to modify the source. If you set this property, then you can prevent this message from being displayed. If the logging is on, then it will still be logged. The message() function will return the default button when the window is not displayed (unless the DontShowThisAgain checkbox was previously checked.

8.1. Steps to implement the DontShowWindow Feature

Step 1
If you have not done so already: complete the steps in the Getting Started section. You need to select the CapeSoft Message Box with features radio button in the Global Extension Template.

Step 2

You need to set the DontShowWindow (an object property). You can either:
  1. Use the Set Features Code Template to set the property; or
  2. Set the object's DontShowWindow property directly.
Example Code

ThisMessageBox.OnlyOnce.DontShowWindow = 1    !For the next window.
ThisMessageBox.SetGlobalSetting('DontShowWindow', 1)    !For all messages in this app.

9. Static Features (obsolete - only used in the old non-threadsafe message class)

It's often useful to be able to set a feature once and then not have to set the feature again, like in the case of Message Logging. 9 times out of 10 you'll want all the messages that occur to be logged, so it's useful to set this feature to be static. But with most of the other features you'll probably not want to make them static as you probably won't want all your messages to (for instance) have the DontShowThisAgain check-box or a Timeout. In the case of the SkipNext feature, this is a static feature, so the property should be cleared after the message (which the property is required for) has been displayed.

You will be able to set these features in the Set Features Code Template or you can set the object's property directly.

Features that can be made static are: the DontShowThisAgain check-box , Timeout , Message Logging , MessageBox HyperLinks , Playing Sounds and DontShowWindow.

Example Code to set the Static Features:

ThisMessageBox.StaticFeatures = bor(ThisMessageBox.StaticFeatures,Glo:Set_NotAgain)
ThisMessageBox.StaticFeatures = bor(ThisMessageBox.StaticFeatures,Glo:Set_MsgLogging)
ThisMessageBox.StaticFeatures = bor(ThisMessageBox.StaticFeatures,Glo:Set_TimeOut)
ThisMessageBox.StaticFeatures = bor(ThisMessageBox.StaticFeatures,Glo:Set_HALink)
ThisMessageBox.StaticFeatures = bor(ThisMessageBox.StaticFeatures,Glo:Set_DontShowWin)


Example Code to clear the Static Features:

ThisMessageBox.StaticFeatures = band(ThisMessageBox.StaticFeatures,65535 - Glo:Set_NotAgain)
ThisMessageBox.StaticFeatures = band(ThisMessageBox.StaticFeatures,65535 - Glo:Set_TimeOut)
ThisMessageBox.StaticFeatures = band(ThisMessageBox.StaticFeatures,65535 - Glo:Set_MsgLogging)
ThisMessageBox.StaticFeatures = band(ThisMessageBox.StaticFeatures,65535 - Glo:Set_HALink)
ThisMessageBox.StaticFeatures = band(ThisMessageBox.StaticFeatures,65535 - Glo:Set_DontShowWin)

10. Property changing

Sometimes you cannot get at the message() commands that are passed to your message window. The message() function could be called from 3rdparty DLLs, Clarion itself, or buried in a class somewhere. Often these messages contain text that is even difficult to interpret for the programmer, let alone the user.

MessageBox makes it easy for you to change the text that will be visible to the user.
  1. Go to the Embeds of your Message window (probably called ds_message) and highlight the following embed:
  2. Insert source such as the following:
if clip(LMBD:MessageText) = 'Change this text'    !If this text is used
  if (LMBD:Buttons = button:yes+button:no) and (LMBD:HeadingText = 'Now')
      !If these buttons are on the window then exit without showing the window.
    ThisMessageBox.OnlyOnce.DontShowWindow = 1
  else
     
!Otherwise just change the displayed window text.
    LMBD:MessageText = 'What should I change this text to?'


  end
 end

embedded source screenshot

The following variables can be used:

LMBD:MessageText contains the text in the first parameter of the Message() call, which is the body text of the message window.
LMBD:HeadingText contains the text in the second parameter of the message() call, which is the text used for the heading of the message.
LMBD:UseIcon contains the equate or file for the icon to be displayed on the message() window.
LMBD:Buttons contains the value of the fourth parameter of the message() call, which is used to determine which buttons must be on the window and what the text on those buttons is.

11. Translation Support

There are a couple of ways of implementing translation support.

1. The easiest (from a MessageBox point of view) is to create a translation file, and set the translation file property. You can do this in the ThisMessageBox.init method (after the parent call) in your global embeds (this is done in your data dll for multi-dll applications):

ThisMessageBox.SetGlobalSetting('TranslationFile',MyTranslationFile)

Your translation file would typically be an ini file containing translated text for each item requiring translation as follows:

[MessageBox_Buttons]
Button:OK=&Bueno
Button:Yes=&Si
Button:No=&No
Button:Abort=&Abortar
Button:Retry=&Reintente
Button:Ignore=&Desatender
Button:Cancel=&Cancelar
Button:Help=Ayudar

[MessageBox_Text]
TimeOutPrompt=Tiempo de espera:
LogTimer=Reloj automático
DontShowThisAgain=No se repite el mensaje
StopHeader=Deténgase
StopDefault=Salida?
HaltHeader=Alto

[MessageBox_Email]
Body=MessageBox routine called for
Time=Tiempo
Date= en
Heading=Título
Text=Texto

[MessageBox_Logging]
Default Header=Fecha,Tiempo,Duración,Nombre de usuario,Botón,Título,Mensaje Texto

2. The other option (for those using a translation tool like AnyText) you will need to translate each item in the ThisMessageBox.init method:

You need to create a procedure that handles global text.

TranslateGlobalText procedure (string pTextToTranslate), string
ThisAnyText Class(AnyText) .
code
ThisAnyText.Init(AnyTextCache,ThisGuts,AnyTextLocal,AnyTextGlobal,'Global') ! AnyText
return ThisAnyText.Translate(pTextToTranslate)


This is what your messagebox global translation will look like:

ThisMessageBox.CSLocale('Button', TranslateGlobalText ('OK,Oui,Non,Abort,Retry,Ignore,Cancel,Help'))
ThisMessageBox.SetGlobalSetting('NotAgainText', TranslateGlobalText ('Don''t Show this again'))
ThisMessageBox.SetGlobalSetting('TimeOutPrompt', TranslateGlobalText ('Time Out: '))
ThisMessageBox.SetGlobalSetting('LogTimer', TranslateGlobalText ('Timer'))
ThisMessageBox.SetGlobalSetting('StopHeader', TranslateGlobalText ('Stop'))
ThisMessageBox.SetGlobalSetting('StopDefault', TranslateGlobalText ('Exit?'))
ThisMessageBox.SetGlobalSetting('HaltHeader', TranslateGlobalText ('Halt'))

3. Translating the TimeOut prompt

The Time Out: Prompt control on the window can simply be changed in the window designer.

Alternatively, in code, in the ds_Message procedure, in the "Before MessageBox Open" embed point, you can set the TimeOutText property. For example;

ThisMessageBox.TimeOutText = 'Thyme Oot'

Template Guide

1. Global Extension Template

The first step (once your application is open) is to add the Global Extension. To do this:

1.1 Click the 'Global' button on the Application tree window.
1.2 Click on the 'Extensions' button on the 'Global Properties' window.
1.3 Click on the 'Insert' button on the 'Extension and Control Templates' window.
1.4 Select the 'Activate_MessageBox' template from the list of extension templates and click on the 'Select' button.

select extension screenshot
1.5 Back at the 'Extension and Control Templates' window there should appear the template with its details on the right.

basic tab screenshot

1.6 Debugging: Check the 'Disable All CapeSoft MessageBox Code' checkbox if you don’t want to generate any CapeSoft MessageBox code. This is useful if your app doesn't compile and you want to exclude all CapeSoft MessageBox source when compiling.
1.7a Use Threadsafe MessageBox: This was implemented in version 2.08. Ideally all apps should be set to "Use Threaded", but this is not backward compatible with previous version of MessageBox, and will probably require some code changes (see FAQ4.9 for details).  For new apps, pick this option, but for old apps you might like to "Use unthreaded" if you have used extensive handcoding of the MessageBox properties, and don't have the time at the moment to change your code. You should come back to this, because you'll need your apps to be threadsafe as soon as possible.
1.7b CapeSoft Functions to Use: If this is part of a Multi-DLL app, then jump to 1.26. Alternatively, select the CapeSoft MessageBox functions that you require. For example, if you would like to use just the Messaging function, then uncheck the 'All' check box and check the 'Messages' check box in the 'CapeSoft Functions to Use:' group.
1.8 Once you've selected which functions you require, the object selection will be enabled.
1.9 Procedure Selection: Select a window procedure on which the message code will be populated. Use the 'Message Box Procedure' drop list to do this. You need to do this even if you do not require the 'Messages' function as the Stop and Halt functions require this procedure.
1.10 You will need to enter a Stop procedure name if you require the Stop function (and like-wise for the Halt function).
1.11 Select the object to use: You can either choose to use the 'Standard Clarion Message' objects, or you can use the 'CapeSoft Message Box with features' objects (see CapeSoft's Messaging features).
1.12 ClarioNET support: If you have the ClarioNET global extension template added to this application, then the ClarioNET Support option will appear. Similarly for WebBuilder applications, you can enable the WebBuilder support in MessageBox.
1.13 logging tab screenshot

Change to the 'Logging' tab to set up the logging options. Leave the 'Disable Logging' check box unchecked (if you require Message logging) and select a file from your dictionary for the Message Logging File. (see Importing the Message Logging File to use the file shipped with MessageBox) You can also leave this blank to use the default ASCII file ('c:\MessageBox.Log').

The Automatically Log Messages checkbox makes it easy for you to turn on logging for all messages in one place. You can override specific messages (see the Features section of this doc).
1.14 Selective Logging: If you only want to log Stops and Halts, then you can check the 'No Logging for Messages' check box. Similarly for only logging Messages, check the other two check boxes, etc.
1.15 If you want to turn message logging on at program startup, then check the 'Automatically Log Messages' check-box.
1.16 Fields: You can equate some fields in your file to the CapeSoft MessageBox Fields if you require them in the entry fields supplied. These fields are optional, and are there because we find them useful. You can create extra fields if you would like to and populate them with your own info. You can use the object embed in the PrimeLog method. These fields are not available if you are using the default ASCII file.
1.17 Record Limits: You can limit the logging file if you want to. You can either limit it by Date or Count. Select either from the 'Limit By:' drop list box. If you are using the default ASCII file, then you will not be able to limit it.
1.18 If you selected to limit the file to Date, then you can select how far back you want to store records. The limiter is in days, so any messages logged more than this 'limit' ago will be deleted. If you selected to limit the file to Count, then you can select the maximum amount of messages to be stored in the log file. The messages will be logged until the limit is reached, when the oldest record will be removed every time a new message is logged to the file. You can use a variable if you like, although you must be sure to set the variable before the first message()/stop()/halt() is called.
1.19 features tab screenshot

Go to the 'Features' tab if you selected to use the 'CapeSoft Message Box with features' objects then you will be able to tweak the template to suite your needs on the 'Features' tab. If you don't require logging, then you can check the 'Disable Logging' check box. This will save you the time of having to create the Logging file in your dictionary (see Creating the Logging File). All the other features will be available as and when you require them, simply by setting the respective properties.
1.20 Remember Features: You can remember Some, All or None of the feature settings by checking/ unchecking the respective check boxes. If you check the 'Remember xxx' check box, then this property becomes static and you need to manually reset the activating property when you do not require it. Alternatively, the property gets cleared after the message box is displayed.
1.21 When the TimeOut feature is used, you can display a counter to indicate the time left before the TimeOut occurs. Check the 'Display TimeOut Counter' checkbox to set this property by default. You can set this feature on at any time using the ShowTimeOut property.
1.22 You may want to display a vertical bar in your Message windows. You can use || double vertical bars and check the 'Allow Double Vertical bars to be displayed as a bar' checkbox in order to display a vertical bar. Otherwise, || will mean two line breaks in your message text.
1.23 Dont Show This Again Settings: You can choose whether you would like to store the DontShowThisAgain setting in an INIFile or the windows registry. If you selected the Registry, then you can set the Registry sub-folder (inside the HKEY_LOCAL_MACHINE\SOFTWARE) which will contain the status of the DontShowThisAgain for your messages. There is also an option to select 'Other' and enter your own Registry sub-folder in the field provided (use quotes for constants or a variable name).
1.24 If you selected an INIFile then you can set the INI file which will contain the status of the DontShowThisAgain for your messages. It was previously set to 'CSMesBox.ini', so existing programs should retain this setting. Appame.ini will be the name of your application file, or you can use the existing default or the win.ini file. There is also an option to select 'Other' and enter your own ini file in the field provided (use quotes for constants or a variable name).

You can set the INI Section which will contain the status of the DontShowThisAgain for your messages. It was previously set to 'CS_Messages', so existing programs should retain this setting. Application will be the name of your application file, or you can use the existing default or the command that was used to start the application (This is useful for DLLs used with different EXEs so that you can retain different settings for the different EXEs). There is also an option to select 'Other' and enter your own section name in the field provided (use quotes for constants or a variable name).

If you are using a variable, then the variable must be set in (or before) the embed point,
Global Embeds,
  CapeSoft Message Box
    ThisMessageBox
      Init
        2) Before Parent Call
1.25 You can enter a HotKey to create a GPF if the Message window is open. This is particularly useful when you have a infinite loop with a stop in it, or you want to debug using GPF Reporter.
1.26 If this is a Multi-DLL application, then check the 'This is part of a Multi-DLL Application' check box. You'll still need to select one of the objects on the 'Message Details' tab if this is not the data DLL.

multi-dll screenshot
1.27 If this is a Multi-DLL application and you want to define the CapeSoft MessageBox code in this DLL and export it to the other DLLs and EXEs (i.e. this is the data DLL), then check the 'Export CapeSoft MessageBox data defined in this DLL'. If you've checked this, then you'll need to fill in all the relevant settings (1.7 - 1.26). 
1.28 If you are going to require translation, then go to the 'Translation' tab and check the 'Use a Translation File' check box on.

translation screenshot
1.29 If you would like the default language to be a language other than English, then you can enter an Initial Translation File. This should include the path() if the file is not in your windows directory.

2. Local Message Control Template

You need to add this template to the window which you will use for the message box. You will need to create a window procedure. (Details) Once you've created the window, you can add the local Control template.
2.1 In the application window, select your message box window procedure and click the 'Properties' button.
2.2 In the 'Procedure Properties' window, click the 'Window' button.
2.3 Click the 'Control Template' item in the 'Populate' menu.
2.4 Select the 'CSMesBox_MessageBoxControl - CapeSoft MessageBox Controls' template, and click on the 'Select' button.

select control template screenshot

2.5 To edit the control properties, quit and save from the window editor and click the 'Extensions' button on the Procedure Properties window.
2.6 Select the 'CapeSoft MessageBox Controls' template and change to the 'Appearance' tab to edit the following:

appearance tab screenshot
2.7 You can check the 'Make Buttons Flat' for flat buttons on the message window.
2.8 You can check the 'Transparent Strings' to make the message text (DontShowThisAgain checkbox, Timer notifier and the Hyperlink string - where used) transparent. This is useful if you are applying Wall paper to the window.

You can check the 'Transparent Buttons' to make the message buttons transparent. This is useful if you are applying Wall paper to the window, although transparent buttons are not supported by manifest files in Windows XP.
2.9 You can check the 'Centralize the text on the window' check box in order to center the message text (other wise the text is left justified).
2.10 On the Icons Tab:
 icons tab screenshot
Default Icon: You may enter a default icon for the messages that don't have icons. If you are using ClarioNET and you would like to make use of icons in your message windows, then you need to enter a default icon. This will ensure that message()s without icons have the default icon assigned to them. You cannot use an equate for a default icon when using ClarioNET and WebBuilder as the equates are not supported by ClarioNET and WebBuilder.

You can enter Default icons for the buttons as well. Use the fields in the Default Button Icons group to stipulate the icons for each button equate.
2.11 On the 'Features Tab':

If you would like to maintain the status of the GlobalRequest and GlobalResponse variables (on by default), then you can check the 'Preserve GlobalResponse and GlobalRequest' checkbox on the Advanced tab.
The diagram below shows the ABC ErrorClass name (in the global properties) on the left and the field where you should fill this in in the MessageBox control template on the right. The procedure name is only available in ABC applications.

global properties screenshot
2.12 Clarion 5.5 (and higher) users only. If you would like to maintain the Procedure name in your GlobalErrors class then you need to check the 'Maintain the Procedure name in the ErrorClass' checked. Checking this checkbox will ensure that the procedure name, from which the message/stop/halt was called, remains the procedure name in the ErrorClass. Alternatively, the name of your MessageBox window will be the name that appears in the procedure name of the ErrorClass. If you checked this checkbox then you need to enter the correct name in the 'Global Error Class name' field. The default is 'GlobalErrors', which is what is normally used. If you have a different name for your global ErrorClass (see on the 'Global Objects' tab in your 'Global Properties') then you need to match that name here.

Note: Checking this will also mean that the FromProcedure property is set with the procedure that is currently active. This means that you will be able to log the procedure name from where the Message() command was called.

If you would like to display the procedure and application name that called the Message() function, then you can check the relevant checkboxes. This will place the Procedure and/or application name in square brackets in the title bar.
2.13 If you would like to display the calling Application name, then check the 'Display the Application name calling the message' checkbox. This useful in a Multi-DLL application (or Multi-EXE), also so that the message is automatically identified with your application.
2.14 HyperActive users only. If you would like to be able to mail your message as a support facility, then you can set this up on the 'Features' tab. (more details)
2.15 Click 'OK' a couple of times to return to the Application window.

3. Local Stop Extension Template

You need to add this template to the procedure, which you will use for the stop function. You will need to create a source procedure. (Details) Once you've created the procedure, you can add the local extension template.
3.1 In the application window, select your Stop source procedure and click the 'Properties' button.
3.2 In the 'Procedure Properties' window, click the 'Extensions' button.
3.3 Click the 'Insert' button on the 'Extension and Control Templates' window.
3.4 Select the 'CSMesBox_ActivateStop - CapeSoft Stop' template, and click on the 'Select' button.

local stop extension screenshot

3.5 Click 'OK' a couple of times to return to the Application window.
There's nothing to be done in CapeSoft MessageBox's Local Stop Extension Template. Remember that the Stop command will use the Message window that you've defined above, so the same settings that will be applied to the stop as to the message window.

4. Local Halt Extension Template

You need to add this template to the procedure, which you will use for the halt function. You will need to create a source procedure. (Details) Once you've created the procedure, you can add the local extension template.
4.1 In the application window, select your Halt source procedure and click the 'Properties' button.
4.2 In the 'Procedure Properties' window, click the 'Extensions' button.
4.3 Click the 'Insert' button on the 'Extension and Control Templates' window.
4.4 Select the 'CSMesBox_ActivateHalt - CapeSoft Halt' template, and click on the 'Select' button.

local halt extension screenshot

4.5 Click 'OK' a couple of times to return to the Application window.

There's nothing to be done in CapeSoft MessageBox's Local Halt Extension Template. Remember that the Halt command will use the Message window that you've defined above, so the same settings that will be applied to the Halt as to the message window.

5. The Set Features Code Template

This template can be used to set the features if you're using the CapeSoft Message Box object. It is a code template, which you can insert anywhere in an embed point.

set features code screenshot

You will see that each feature has a group with the property activator (a field or check box), a remember checkbox and a clear checkbox.

prompts for CSMesBox_Set_Msg_Settings screenshot

5.1.1. The 'Active' check box will activate the 'DontShowThisAgain' check box feature.
5.1.2. The 'Value' field sets the length of the Timeout for the message. The time out value is in One Hundredths of a second. So for an 8 second time-out, set the value to 800. You can also enter the name of a variable.
5.1.3. The 'File:' field indicates the wavfile to be played when the next message is opened. You must use quotes for a string, alternatively you can use a variable.
5.1.4. The 'Enable' check box will enable message logging. You must not have disabled this feature in the Global Extension Template.
5.1.5. The 'x:' field entry is used to set the amount of messages that must be skipped.
5.2. The 'Remember' check box is used to set the Static attribute for the feature. The SkipNext feature is by nature a static feature, so it has no Remember check box. If you set the Static Attribute on in the global extension
5.3. 'Clear checkbox' will place code to clear both the static and the active properties.

If you don't require a property to be changed then leave all the fields unaltered. Thus in this template you will be able to set all or some of the features.

6.The ImportCSMessageBox Utility Template

This template utility is used to import a standard set of Message, Stop and Halt functions to your application. These functions can then be modified (or used as is) to suite your needs.
6.1. In your application window, select the 'Template Utility' item from the 'Application' menu in the window menu bar.

select utility screenshot
6.2. Select the ImportCSMessageBoxABC or the ImportCSMessageBoxLegacy (depending on whether this is a legacy or ABC application) to import the 3 procedures.

General Info

1. Adding a Blank Window Procedure for the Message Function

You should first consider using the Utility Template to perform this function.
1.1 In the Application Tree window, select the 'New' item from the 'Procedure' menu.
1.2 In the window that appears enter a name for your window (like MyMessageBox) and click the OK button.
1.3 In the 'Select Procedure Type' window that appears, select the 'Window - Generic Window Handler' and click the Select button.
1.4 Click the 'Window' button in the Procedure MyMessageBox Properties screen that appears.
1.5 Select the 'Window' option in the list that appears (the object will do all the fancies - so the bare minimum is all we need) and then click OK.
1.6 You don't need to do anything in the window that appears, but it is advisable that you set the Font to the Font you require. You can also add a wallpaper to the background of the window. If you add wall paper, then it is advisable that you check the 'Transparent Strings' check box on in the MessageBox Local Control Template that you will add just now. You can quit the window editor, as the template and objects will do the rest.

Note: You must get the following prototype (1.6) in your Message Window's prototype correct!!!

1.6 In the Prototype field enter the following prototype (with parameters):
(STRING MessageTxt,<STRING HeadingTxt>,<STRING IconSent>,<STRING ButtonsPar>,UNSIGNED Defaults=0,BOOL StylePar=FALSE),UNSIGNED,PROC
It is essential that this prototype is correct.
1.7 In the Parameters field, enter the same string for the parameters (leave the return definition off). For example:
(STRING MessageTxt,<STRING HeadingTxt>,<STRING IconSent>,<STRING ButtonsPar>,UNSIGNED Defaults=0,BOOL StylePar=FALSE)
1.8 Check the 'Declare Globally' checkbox.
1.9 Enter a variable in the 'Return Value' field. This should be a variable of type 'UNSIGNED'.
1.10 Click the OK Button to exit the window.

You'll need to add the Local Message Extension Template to this procedure.

2. Importing the CapeSoft Message Logging File into your Dictionary

1.1 If you're in the Application editor, then quit it and from the File menu, select the Open item. Select your dictionary in the file dialog box (you will probably need to change the 'Files of type' drop list to 'Dictionary (*.dct)') and click the 'Open' button.
1.2 In the dictionary editor, click the 'Import Text' from the File menu.
1.3 Select the MessageBox.txd file that is found in the clarionx\3rdparty\libsrc directory.

3. Adding a Blank Source Procedure for the Stop and Halt Functions

You should first consider using the Utility Template to perform this function.
1.1 In the Application Tree window, select the 'New' item from the 'Procedure' menu.
1.2 In the window that appears enter a name for your window (like MyStop or MyHalt) and click the OK button.
1.3  In the 'Select Procedure Type' window that appears, select the 'Source - Source Procedure' and click the Select button.

Note: You must get the following prototype (1.4.1 for Stop or 1.4.2 for Halt) in your Stop/Halt Procedure's prototype correct!!!
1.4.1 In the Prototype field enter the following prototype (for the Stop function):
(<string StopText>)
It is essential that this prototype is correct.
1.4.2 In the Prototype field enter the following prototype (for the Halt function):
(UNSIGNED Level=0,<STRING HaltText>)
It is essential that this prototype is correct.
1.5.1 In the Parameters field (for the Stop function), enter a parameter for each field in the prototype (i.e. there must be 1 parameter). For example:
(<string StopText>)
1.5.2 In the Parameters field (for the Halt function), enter a parameter for each field in the prototype (i.e. there must be 2 parameters). For example:
(UNSIGNED Level=0,<STRING HaltText>)
1.6 Check the 'Declare Globally' checkbox.
1.7 Click the OK Button to exit the window.
You'll need to add the Local Extension Template to this procedure. (StopDetails or HaltDetails)

4. Adding derived code into your MessageBox object

It is really useful to be able to add your own code to some of the MessageBox objects. You can derive these locally (i.e. for this application only), by going to the Global Embeds and selecting the CapeSoft MessageBox | ThisMessageBox and the name of the method that you want to derive as follows (where the Init method has been derived):

adding derived code screenshot

The above embed point is really useful for setting variables and properties, before initializing MessageBox. In each method you will find 3 (or perhaps 4) embed points: a Data, Before the Parent Call and After the Parent call embed point. If the template generates code after or before the parent call, then there will be an extra embed point to enable you to place code on either side of the parent call as well as on either side of the template generated code.

elationship with other products

ClarioNET support

MessageBox supports ClarioNET with the following limitations:
Besides these limitations, the rest of the MessageBox functionality will be unaltered by the addition of ClarioNET.

Steps to implementing ClarioNET support:

HyperActive support

The best way to make your message()s HyperActive is to set the HyperLink property so that the HyperLink will appear on the MessageBox. If you add you own HyperActive control to the MessageBox window, you will need to position and size it upon receipt of an EVENT:OpenWindow in your own Message() procedure.

WebBuilder support

MessageBox supports WebBuilder with the following limitations:
Besides these limitations, the rest of the MessageBox functionality will be unaltered by the addition of WebBuilder. You need to check the 'Enable WebBuilder support' on the MessageBox global extension
template.
Steps to implementing WebBuilder support:

UBeaut support

If you have a thread manager (e.g. UBeaut) installed, then by default only one copy of your message window can run. So if you happen to have a message window open and then call it from another thread, it will return immediately. This can have tragic results if the user's being asked to confirm some major action.

You will need to disable your thread manager on your MessageBox window. If you are unsure as to how to do this, you will need to contact your Thread manager supplier.

Other Products

Most other 3rdparty products will be completely supported by MessageBox. MessageBox has been tested with all of CapeSoft's products and numerous other 3rdparty products. For queries on specific other 3rdparty products please contact our support division.

Frequently Asked Questions

My app seems to hang when a Message() appears. What's wrong?

I'm getting Compile Errors, also check out general product CompilerErrors.

Logging Problems
1.1 If I get an error in my logfile, it GPFs without warning when I log a message. How do I inform my users of this?
1.2 I am having a problem with logging. Nothing is being logged to my logfile. What could I be doing wrong?
1.3 I'm trying to use the logging feature in my Message/stop/halt functions but it GPFs when the window closes.
1.4 If I set my MessageLog file to Current/DataDir(Messagebox.log) I can't find it.
1.5 If I use the DontShowWindow feature, the user is always logged as Auto, not the user name I specify?
1.6 My logfile has got corrupted, which gets into an endless loop of halt()s.
1.7 I want to set additional fields when I log to the log file. How do I do this?

Logging How Tos...
2.1 How do I add information to the log about where the message box was invoked from(i.e. the procedure that called it)?
2.2 I want to just log all/some of the Clarion Messages without displaying them. How do I do this?
2.3 How do I log extra details to my log file?
2.4 I use Secwin (or another Security template) with this app. How do I get the user name into the MessageBox user name field?
2.5 I only want to log messages, without logging stops as well. Can I do this?
2.6 I only want to log system messages without logging other messages. How do I do this?
2.7 My users reboot the computer when a MessageBox appears. How can I log this?

Compiling Issues

Features Issues
4.1 I'm trying to use the Timeout, but it doesn't work.
4.2 I want other text on my message box buttons than the standard OK/Yes/No/Abort/Retry/Ignore/Cancel/Help text. Is this possible?
4.3 Can I put Icons on the buttons?
4.4 How do I use variables in my MessageBox when I want to use the 'DontShowThisAgain' feature?
4.5 I am trying to use the Hyperlinked email message, but it doesn't seem to work.
4.6 I want to change the text on a message that is generated by Clarion (or a 3rdparty DLL). Is this possible?
4.7. I would like to alter the parameters that are passed to the Message window (Text, buttons and the like).
4.8. I'm getting strangely formatted messages with vertical bars in them.
4.9. What must I change in my application to use the threadsafe MessageBox?
4.10. Why should I use the new thread-safe message class?
4.11. How do I force a message to not show the window and return as if a button was clicked, based on certain text?

General Issues
5.1 I'm trying to use the LOCALE command to set the default button text, but it does not affect my message() buttons.
5.2 When I issue a stop and/or message command the program closes immediately without warning. If I use the Clarion stop and/or message then it works.
5.3 I can't get rid of the Message, Stop and Halt TODO procedures in my application
5.4 I'm using messagebox in a couple of my programs which are running locally without problems, but not so over a Network.
5.5 I'm getting buttons with raised text on my MessageBox buttons occasionally. These are buttons with longer-than-average text length. How can I rectify this?
5.6 I have a legacy single-EXE application which GPFs if I use the CapeSoft MessageBox with Features class.
5.7 Is there a way to default the button icons for the standard buttons instead of sending them in each call to the message procedure?
5.8 Is it possible to change the font, font size or the font type (bold, italic, etc) of the text on the message box?
5.9 My Message window displays the minimize, restore, and close buttons in the caption bar. How do I get rid of these?
5.10 I want to remove MessageBox from my application. How do I do this?
5.11 My app seems to hang when a Message() appears. What's wrong?
5.12 One specific Message() call GPFs my app when using MessageBox.
5.13 Is it possible to dynamically change the font information for any given message?
5.14 How do I change the size of the buttons on the MessageBox window?
5.15 I want more space on either side of the text on the MessageBox window - it looks too cramped.
5.16 I cannot click the buttons on the messagebox. My mouse clicks have no effect.


1.1 If I get an error in my logfile, it GPFs without warning when I log a message. How do I inform my users of this?
Answer: The problem is you can't use your message() function to report the error (as it is open already). One solution is to not use the MessageBoxHalt() function and call the halt if you encounter an error in this instance. This will ensure that the user is given some feedback when the program exits (after all - the program is about to GPF in any case).
 Thus:
    If errorcode() then halt(,'There is a problem with the MessageBox file...') .          !For Legacy

    If access:<MessageBoxFile>.Errors.SaveErrorCode then halt(,'There is a problem with the MessageBox file.') . !For ABC - Clarion5 and C55


If you are using Clarion 6 then:
    If access:<MessageBoxFile>.Errors.Status.V.SaveErrorCode then halt(,'There is a problem with the MessageBox file.') . !For ABC - Clarion6
You can put this code in the embed point - ThisMessageBox|InsertLog|(4) After the Parent Call and generated code. Alternatively, if you are using the LimitLogFile feature, you must put this check in the ThisMessageBox|LimitLog|(4) Before Generated Code, as the LimitLog method is called before the above embed point is reached.

Note for ABC users: Unfortunately the writers of the ABC classes have deemed it beneficial (for reasons best known to them) to make the Errors class a protected property. You need to remove the PROTECTED attribute of the Errors property and the SaveErrorCode property in the ErrorClass. You can do this in the abfile.inc and the aberror.inc header files.
1.2 I am having a problem with logging. Nothing is being logged to my logfile. What could I be doing wrong?
Answer: You need to check that you:
1.are in fact using your own stop - check that the 'Functions To Use' options group on the Basic tab of your MessageBox Global Template has either the 'All' Checkbox checked or the 'Stop' checkbox.
2. have selected the 'CapeSoft MessageBox with features' object on the Basic tab of your MessageBox Global Template.
3. have not disabled MessageLogging (on the Features tab of your Global MesageBox Template).
4. have either checked the 'Automatically log messages' on the Features tab of your MessageBox global Extension template your you have set the ThisMessageBox.SetGlobalSetting('LogMessages', 1) at the beginning of your program.
5. have checked the 'Remember logging' on the Features tab of your MessageBox global template.
6. have all the checkboxes cleared in the Selective logging group on the Features tab of your global template.
7. have specified your file as the logging file on the LogFile tab of your messageBox global template.

if you have checked all these and are still not logging:
8. Do a scan of your source routines for ThisMessageBox.SetGlobalSetting('LogMessages', 0) to make sure that the logging is not being turned off.

if you have checked this and are still not logging:
9. Place a trial stop in your code and set the ThisMessageBox.SetGlobalSetting('LogMessages', 1) immediately before this. If this is the last step and you can see the stop being logged, then your static property has not been set for logging, or has been cleared at some point.
1.3 I'm trying to use the logging feature in my Message/stop/halt functions but it GPFs when the window closes.
Answer: You've probably checked the 'Disable Logging' check box in the Global Extension Template, but you're setting the logging feature flag. You need to uncheck this 'Disable Logging' check box in order to allow you to use and activate the Logging feature.
1.4. If I set my MessageLog file to Current/DataDir(Messagebox.log) I can't find it.
Answer: The ASCII message file name is set in the Init method of the MessageBox class. If you're only setting your path after the call to the ThisMessageBox.Init, then the logfile will be placed in whatever path your application started in.
Example:
  GlobalErrors.Init(GlobalErrorStatus)
  INIMgr.Init('.\msgbox.INI', NVD_INI)                     ! Configure INIManager to use INI file
  DctInit
!You need to set your datapath here
                 !CapeSoft MessageBox init code
  ThisMessageBox.init(1,1)
                 !End of CapeSoft MessageBox init code
  SystemParametersInfo (38, 0, lCurrentFDSetting, 0)       ! Configure frame dragging
1.5. If I use the DontShowWindow feature, the user is always logged as Auto, not the user name I specify?
Answer: This is part of the designed of MessageBox. The logic was that the user couldn't select the option (because the message isn't shown) - so the user was stamped as 'Auto'. You can override this in the PrimeLog derived method, by changing the self.WhoPressed property to what you require.

Typically:

  self.WhoPressed = self.loggedIn

before the parent call.
1. 6. My logfile has got corrupted, which gets into an endless loop of halt()s.
Answer: You need to code a solution to remove the logfile on the second halt:

Full Pathname: CSMesBox.tps

and NOT

Full Pathname: CSMesBox

Note: You will need to amend the code to allow for different file drivers

Global embeds in Data Dll App:

data:

myExtension long before parent call:

  ! this attempts to help with the loop of a halt() relating to a
  ! messageboxlog file error by just wiping the thing,
  ! (then extended a little to try taking a copy first)...
  if not status(MessageBoxLogFile)
    open(MessageBoxLogFile, ReadWrite+DenyNone)
    if errorcode()
      loop myExtension = 1 to 998
        if not exists(MessageBoxLogFile{prop:name} & '.' & format(myExtension,@n03))
          break
        end
      end
      copy(MessageBoxLogFile{prop:name}, MessageBoxLogFile{prop:name} & '.' & format(myExtension,@n03))
      remove(MessageBoxLogFile{prop:name})
    else
      close(MessageBoxLogFile)
    end
  end
1.7 I want to set additional fields when I log to the log file. How do I do this?
Answer: You can do this in the global PrimeLog embed point (before the parent call) in your Data DLL (for multi-dll applications).
2.1 How do I add information to the log about where the message box was invoked from (i.e. the procedure that called it)?
Answer: You can do this in C5.5 or later and is only available in ABC applications.

1. In the MessageBox procedure - extensions - CapeSoft MessageBox Controls template, go to the 'Advanced' tab and check the 'Maintain the Procedure name in the Error Class'.
2. If you are using a table in your dictionary to log the messages, then make sure that you have a field in your MessageBox logfile to store the Procedure name in it (setup in the MessageBox Global Extension template - in the Logging tab)
2.2 I want to just log all/some of the Clarion Messages without displaying them. How do I do this?
Answer: There's a DontShowWindow Property property in the 'CapeSoft Message Box with features' class, which (if set) will just log the message without displaying it. 
This is easy in Clarion5.5 (and above) if you are using ABC methods:

1. Turn off Remember logging in the Messagebox Global Extension Template.
2. You need to insert the following code in the embed before the GlobalObjects | Abc Objects | Error Manager | Msg PROCEDURE | CODE | Parent Call. To get there click the Global button, and then the Embed button and find the embed point in the Embed tree.

case SELF.GetErrorBufferId()                          
of Msg:UpdateIllegal orof Msg:InsertIllegal orof Msg:DeleteIllegal
!This will only disregard illegal file change messages (but will log them)
  ThisMessageBox.OnlyOnce.DontShowWindow = 1
end
2.3 How do I log extra details to my log file?
Answer: This depends whether you are using the Default ASCII text file or your own log file. The best place to add the code is in the CapeSoft MessageBox | ThisMessageBox | PrimeLog | Before the Parent Call global embed point. There is an example in the abcASCIILogFile\useascii.app application that comes with MessageBox that demonstrates the first instance. Using your own log file is a bit simpler, because you simply make the equates in the above embed points. You must remember though, that if the DontShowWindow property is set, then some of the object properties have not been set when the PrimeLog method is called.

For Example, if you wanted to log the text of the button that was pressed you could insert the following into the above embed point:
Log:ButtonPressedText = self.ButtonPressed{prop:text}
2.4 I use Secwin (or another Security template) with this app. How do I get the user name into the MessageBox user name field?
Answer: It's just one line of code (for Secwin and most other Access Control software).
    ThisMessageBox.SetGlobalSetting('LoggedIn',ds_CurrentName(ApplicationNumber) )
You can put this code straight after your Secwin login. Please check your Access Control software's documentation for the correct function name (if you're not using Secwin).
2.5 I only want to log messages, without logging stops as well. Can I do this?
Answer: Yes, there's a checkbox where you can disable logging for stops/messages/halts in the global extension template to do this.
2.6 I only want to log system messages without logging other messages. How do I do this?
Answer: This is easy in Clarion5.5 (and above) if you are using ABC methods:

1. Turn off Remember logging in the Messagebox Global Extension Template.
2. You need to insert the following code in the embed before the GlobalObjects | Abc Objects | Error Manager | Msg PROCEDURE | CODE | Parent Call. To get there click the Global button, and then the Embed button and find the embed point in the Embed tree.

  ThisMessageBox.OnlyOnce.LogMessages = 1
2.7 My users reboot the computer when a MessageBox appears. How can I log this?
Answer: MessageBox logs the message at the point of exit (so that it can track which button was pressed). You need to put the following code in your Global Embeds: CapeSoft MessageBox | ThisMessageBox | Open | After the Parent call:?
self.OpenLog self.WhoPressed = 'Test'
self.ButtonPressed = 0
self.PrimeLog
if self.InsertLog() .
LogPointer = pointer(Log)    
!You need to declare this as threaded global variable
self.CloseLog

and the following code in your Global Embeds: CapeSoft MessageBox | ThisMessageBox | Close | BEFORE the Parent call:

self.OpenLog
get(Log,LogPointer)
delete(Log)
self.closeLog()
4.1 I'm trying to use the Timeout, but it doesn't work.
Answer: You may be using more than 1 button on your window without having a default button. You must have a default button if you're wanting to use the Timeout Feature with multiple buttons.
4.2 I want other text on my message box buttons than the standard OK/Yes/No/Abort/Retry/Ignore/Cancel/Help text. Is this possible?
Answer: Yes, CapeSoft MessageBox can do all that the normal message function can do and more. Here's an example of how you do this: Example Code:

case Message('Would you like to continue or reprocess?','Question',ICON:Question,'Continue|Reprocess',1)
of 1
  !Continue Code (this is the default button)
of 2
  !Reprocess Code
end


question screenshot
4.3 Can I put Icons on the buttons?
Answer: Yes you can. This is one of the additional features of CapeSoft MessageBox (details).
4.4 How do I use variables in my MessageBox when I want to use the 'DontShowThisAgain' feature?
Answer: The easiest way is to set the NotAgainID property as follows:

ThisMessageBox.OnlyOnce.NotAgain = 1
ThisMessageBox.NotAgainID = 8947773
message('We can use variables now quite easily, because the DontThisShowAgain will be identified by 8947773 and not by the message text and heading','Note')

Otherwise:
You will  need to change the way MessageBox stores the Registry entry that shows the status of the DontShowThisAgain for that specific message. For example, you could decide that no variables should appear in the heading and first line of the text as follows: In the Global Embeds, in the embed "CapeSoft MessageBox.ThisMessageBox.PutDontShow.2) Before the Parent Call" you could put the following code:

pEntry = sub(pEntry,1,instring('|',pEntry,1,1))

You will need to put the exact same line of code in the embed "CapeSoft MessageBox.ThisMessageBox.GetDontShow.2) Before the Parent Call" as well.

Remember that all Messages with the NotAgain property set will use this message. Thus, you will need to ensure that the first line and heading of each different Message that you call (from different parts of the program) are unique.
4.5 I am trying to use the Hyperlinked email message, but it doesn't seem to work. I am not getting any compile errors.
Answer: 1. If your HyperLink is not appearing on the MessageBox window then you are not setting the ThisMessageBox.OnlyOnce.HyperLink property before calling the message. If you would like the HyperLink to appear on all messages, then use ThisMessageBox.SetGlobalSetting('HyperLink',<YourEmailURLHere>). You will only need to set this property once then.
2. If your hyperlink string is appearing, but is not 'HyperActive', then you have not added the control to the list of HyperActive controls (see the HyperActive Local Extension Template).
3. If the string is 'HyperActive' but it does not point to the Mail, then you have not entered the same HyperLink variable (EmailLink by default) on both the Local Message Control Template ('Features' tab) and the URL for the ?HALink control on the HyperActive Local Extension Template.
4.6 I want to change the text on a message that is generated by Clarion (or a 3rdparty DLL). Is this possible?
Answer: You need to handcode the changes - but it simple to add the code. Check out the Property Changing section.
4.7 I would like to alter the parameters that are passed to the Message window (Text, buttons and the like).
Answer: You can do this in the MessageBox - Alter Message Parameters embed point. For example, if you would like to change the default button of the confirm delete message, you could do this here with the following code:

if clip(LMBD:HeadingText) = 'Confirm Delete' and |
clip(LMBD:MessageText) = 'Are you sure you want to delete the highlighted record?' and |
    LMBD:Buttons = Button:Yes + Button:No and |
    LMBD:Defaults = Button:Yes
  LMBD:Defaults = Button:No       
!Change the Default button
  ThisMessageBox.OnlyOnce.LogMessages = 0   
!Turn logging off for just this message.
end
You could also include a condition to check for a specific procedure (ABC in Clarion5.5 and higher) and only perform the changes for that procedure. For Example:
if clip(ThisMessageBox.FromProcedure) = 'UpdateTables'
end
4.9. What must I change in my application to use the threadsafe MessageBox?
Answer: There are a number of properties that have changed in 2.08. The threadsafe message class uses a global settings class (an unthreaded class), and a threaded class. The global settings are those that should be set for all instances of the message() function. The Temporary overrides are done in the threaded class. As a result, when switching to the thread safe class, you will need to change some of the ways you set properties in your code - because you will get compile errors where you have handcoded calls to the old unthreadsafe class properties. For example:

  ThisMessageBox.LogMessages = 1

Now becomes:

  ThisMessageBox.SetGlobalSetting('LogMessages',1) 
for application wide logging of  messages or:
  ThisMessageBox.OnlyOnce.LogMessages = 1
to force the next message on this thread to be logged.

The old staticfeatures property falls away, and is replace by the above (either Force temp property to 1 or 0, or use the SetGlobalSetting).
The temp properties' inert state is -1 (initial value - and reset to that after each message).

Note: Previously the LogMessages property was used as both a static and a temporary property (depending on the state of the statisfeatures property). This means that you may have had code something like this:


  TMPLogMessanges = ThisMessageBox.LogMessages
 ThisMessageBox.LogMessages = 0
 message('This message won't be logged - but all others will','Note')
 ThisMessageBox.LogMessages = TMPLogMessanges

This code will now become:

 ThisMessageBox.onlyOnce.LogMessages = 0
 message('This message won't be logged','Note')


The properties with OnlyOnce overrides (that you will need to make a decision as to whether to replace them with the SetGlobalSetting, or the temporary override) are:
LogMessages, NotAgain, TimeOut, HyperLink, PlayWavFile and DontShowWindow
4.10. Why should I use the new thread-safe message class?
Answer: It is possible to have multiple threads calling a messagebox at the same time (especially if you are using the DontShowWindow feature). In the old unthreadsafe messagebox class, this meant, that when logging messsages (or any of the other class properties) - could be changed by a second simultaneous instance of the message window. The new threadsafe message class has been separated into 2 classes - a global unthreaded class (for the static properties shared between all simultaneous instances of the message window) and a threaded class (containing dynamic properties needing to be consistent for the duration of the messagebox display - and independent from interference by another simultaneous message() instance from). By using the new threadsafe message class, you completely eradicate the possibility of a unstable dynamic property that could be caused by another simultaneous message() being called from a different thread.
4.11. How do I force a message to not show the window and return as if a button was clicked, based on certain text?
Answer: The easiest is to derive the PreOpen method before the parent call in the MessageBox window, and put your test code, setting the DefaultButton and the DontShowWindow property as follows:
   if instring('Duplicate Key',MessageText,1,1) and instring('40',MessageText,1,1)
     DefaultButton = button:Ignore
     self.onlyonce.DontShowWindow = 1
   end
5.1 I'm trying to use the LOCALE command to set the default button text, but it does not affect my message() buttons.
Answer: At this stage there is no way of reading what was set by the Locale command, so we've made a method called CSLocale (ThisMessageBox.CSLocale). This method takes the same parameters as the LOCALE function, which you need to call instead. 
5.2 When I issue a stop and/or message command the program closes immediately without warning. If I use the Clarion stop and/or message then it works.
Answer: You probably have the procedures mixed up. In your MessageBox global extension template, check the procedures in the drop lists where the procedure names are entered.
5.3 I can't get rid of the Message, Stop and Halt TODO procedures in my application
Answer: If you are wanting to delete MessageBox from your application, then check out FAQ 5.10
This either means:
1. that you have deleted one or more of your procedures, while you are wanting MessageBox to use them. In this case you need to re-apply the Template Utility to add the Message, Stop and Halt procedures to your application.
- OR -
2. that you have originally set this application to be a root DLL or stand-alone EXE, which is now part of a Multi-DLL application, but is not the root (or data) DLL. You need to:
2.1. Clear the 'This is part of a Multi-Dll application' checkbox on the Multi-DLL tab of your global MessageBox extension.
2.2. Click OK and then go back into the MessageBox template again (if you don't do this, the Procedure fields will still not be able to be edited - that's Clarion bug).
2.3. On the Basic tab, clear the Procedure fields (Message, Stop and Halt).
2.4. Go to the Multi-DLL tab and check the 'This is part of a Multi-Dll application' checkbox.
2.5. Save and Quit the Global Extensions window and the Global Properties. 
2.6. If the Procedures are still To Dos, then you need to:
2.6.1. Export your application to a text file (.txa)
2.6.2. Open the txa file in a text editor.
2.6.3. Delete any references to the Message, Stop and Halt procedures.
2.6.4. Save your application under another name and import the txa to the name of your original application.
5.4 I'm using messagebox in a couple of my programs which are running locally without problems. As soon as I try to access a network the programs are crashing with a stack overflow. Am I doing something wrong?
Answer: You're probably using the CSMesBox.tps file with a variable for the path. This variable must be set before the first Message() is called.
5.5 I'm getting buttons with raised text on my MessageBox buttons occasionally. These are buttons with longer-than-average text length. How can I rectify this?
Answer: This is a Clarion bug when the font color is implemented. The best is to make the font color on the window, COLOR:None, or set the colors on all the buttons of the MessageBox control template to COLOR:None.
5.6 I have a legacy application which GPFs if I use the CapeSoft MessageBox with Features class.
Answer: You need to add the _ABCDllMode_=>0 define to your project's defines.
5.7 Is there a way to default the button icons for the standard buttons instead of sending them in each call to the message procedure?
Answer: Yes there is, check out Method 2 of the Display Icons on Features section.
5.8 Is it possible to change the font, font size or the font type (bold, italic, etc.) of the text on the message box?
Answer: You can edit the window's properties just like any other windows. Go into the window editor window (of your MessageBox window) and set the window's font. The prompt and buttons take on the font that you specify for the window. In the same way you can edit any of the properties of any of the controls. You should not set the operating properties though (like hide and enable). Positional properties are also all set at runtime, so any positional properties set in the window editor will be overridden at runtime.
5.9 My Message window displays the minimize, restore, and close buttons in the caption bar. How do I get rid of these?
Answer: Go to your ds_Message window (the window that is used for the MessageBox) and set the following options:
1. In the Window Formatter, right click and select Properties - change to the Extra tab and clear the Icon field (this will get rid of the Minimize button).
2. Same place - uncheck the 'System menu' checkbox (this will get rid of the close button).
3. Same place - uncheck the 'Maximize Box' checkbox (this will get rid of the restore button).

If the buttons are still present after this, then you probably have a 3rdparty tool that is setting them. You could have Mike Hansen’s SuperStuff Select default icon for the entire app, in which case you'll need to contact BoxSoft in order to find the remedy to disable the icon placement on the Message wiindow.
5.10 I want to remove MessageBox from my application. How do I do this?
Answer: 1. Open your application in the Clarion IDE.
2. In your Global Extension Template list, delete the MessageBox global Extension template.
3. Return to the application tree and delete the 3 MessageBox windows from the procedures list. These will now appear as TODO procedures.
4. Export your app to txa and open the exported txa in a Text editor.
5. Find the TODO procedures (which should appear as follows) and remove them (i.e. delete this whole block of code).
[MODULE]
[COMMON]
FROM ABC GENERATED
[PROMPTS]
[PROCEDURE]
NAME ds_Stop
GLOBAL
[COMMON]
[END]
[MODULE]
[COMMON]
FROM ABC GENERATED
[PROMPTS]
[PROCEDURE]
NAME ds_Halt
GLOBAL
[COMMON]
[END]
[MODULE]
[COMMON]
FROM ABC GENERATED
[PROMPTS]
[PROCEDURE]
NAME ds_Message
GLOBAL
[COMMON]
[END]
6. Save this TXA file. 
7.Create a new application and import this txa. You can then rename this app to the original application name.
8. Set the _NoCSMesBox_=>1 project define in your Project defines (if this is a MultiDLL application, you will need to do this in all the applications that had the MessageBox template added)
9. If you have handcoded references to the MessageBox object, you can enclose these in an omit statement using the above project define (rather than removing or commenting them out, in case you want to add MessageBox back in to the application).span class="s_string">  omit('***',_NoCSMesBox_=1)
ThisMessageBox.OnlyOnce.DontShowWindow=1
  ***
5.11 My app seems to hang when a Message() appears. What's wrong?
Answer: Check and see if the procedure has the "save and restore window position" feature turned on.  (I'm guessing it has). Turn it off....

To do this: Open your application and double click on the cs_Message window procedure to bring up the Procedure properties window. You will see a INI File Settings group - clear the Save and restore window location checkbox. If it's not there, then click the Windows Behaviour button. The INI settings group will be there.

What's happened is that at some point someone moved the window out the way (probably off to the right of the screen) and now it's opening in this "remembered" position.

Another solution is to delete the ini file that stores the positions.
5.12 One specific Message() call GPFs my app when using MessageBox.
Answer: If you call a message() from a source procedure that is called directly from a frame, and prior to the message() call a new MDI child thread is started, then your application will GPF. Unfortunately this is a Clarion oddity, so the best is to either move the message() into the window that is called or into the frame.
5.13 Is it possible to dynamically change the font information for any given message?
Answer: The Message window is a procedure in your application, so you can easily write code in to handle this. What you can do is in your derived MessageBox object (in the global objects) - you can add a few properties to the ThisMessageBox properties (other properties) and then set them immediately before message() call (as you would the other features properties). In your ds_Message procedure, you can set the font of the window based on these properties after the window opens (in the ThisWindow.Init method).
5.14 How do I change the size of the buttons on the MessageBox window?
Answer: Self.buttonheight and self.minbuttonwidth are the 2 properties that you're looking for. In your derived SetControlProperties method - set those there (before the parent call), that should do the trick. Note: For the width, you can stipulate a wider button, than the default, otherwise the text won't fit on the button.
5.15 I want more space on either side of the text on the MessageBox window - it looks too cramped.
Answer: You can quite easily change this by altering the equates in the MessageBox.inc file. Open this file in a text editor and search for GLO:StringXPos. You can set this value to the desired amount.

Note: this file is replaced with each release of MessageBox, so you'll need to make a backup of this file before installing an update of MessageBox, and then re-implement your changes each time.
5.16 I cannot click the buttons on the messagebox. My mouse clicks have no effect.
Answer: If you are using SolaceSoftware's runtime screen design tool, htne make sure that you disable it on the message window.

Compile Errors

1 I have a multi-dll application.  Do I run the utility only on the data (base) DLL and add the global extension to it and the other DLLs, or do I run the utility on all of the APPs?
2 When I add MessageBox to an app, add the required procedures, and then delete them (extension call and procedures), it leaves the procedures as 'To Dos'.
3 I have been using MessageBox for sometime, but since my last download I'm getting a compile error: Unknown identifier: ?HALINK
4 I'm trying to use the MessageLog tps file (instead of the ASCII log file), but I get compile errors (like elements in the log file not found, etc.).
5 I started getting the Unknown Identifier: FROMPROCEDURENAME Error when compiling.
6 Since upgrading, I'm getting a lot of Syntax Errors on MessageBox class properties.
1 In a multi-dll application, do I run the utility only on the data (base) DLL only and add the global extension to it and the other DLLs, or do I run the utility on all of the APPs?
Answer: You just run the Template utility in the data DLL. You need to add the global template to all the  EXEs though (and the DLLs - which will use the MessageBox class). You must set up the Multi-DLL project options on the global extension template in each of the DLLs (where the global template is added) and EXEs correctly.
2 When I add MessageBox to an app, add the required procedures, and then delete them (extension call and procs), it leaves the procs as to-dos. How do I get rid of them?
Answer: This is a bug in Clarion that affects procedures which are called from global extensions. Basically the extension can be deleted, but it refuses to remove the "to-dos". there are 2 work-arounds;

1) Make the procedures simple empty procedures based on the "Source"
template. This will leave them there, but they're empty so don't take up any
space in your eventual program. OR

2) Export the app to a TXA. Edit the TXA (look for the offending procedure
names). Then make a new app and import the TXA...
3 I have been using MessageBox for sometime, but since my last download I'm getting a compile error: Unknown identifier: ?HALINK
Answer: The latest version requires that you delete your MessageBox control template populated on the MessageBox window. There is an extra control in the template which does not get automatically added to the existing control template on the window.
4 I'm trying to use the MessageLog tps file (instead of the ASCII log file), but I get compile errors (like elements in the log file not found, etc.).
Answer: 1. Check that you have entered the log file details correctly on the 'LogFile' tab on the MessageBox global extension template.
2. Check that you have the 'Generate all file declarations' checkbox checked. You will find this on the File Control tab on the Global Properties window.
5 I started getting the Unknown Identifier: FROMPROCEDURENAME Error when compiling.
Answer: The FROMPROCEDURENAME is used to maintain the GlobalErrors class procedure name. This is setup in your extension template on your message() window in your application. Uncheck the 'Maintain the procedure name in the ErrorClass' or ensure that the Class name is the same.

What the users are saying about MessageBox

Trevor Cocks (in a return email - 12 June 2002):
I have built a ?1m business around Clarion, and have over 300 sites waiting for an upgrade that I was (until now) unable to give them. Now ... Messagebox has made the single most RADICAL difference to stability of anything I have tried, all in about 30 mins, all for about $39. I can categorically state it works!

Michael Gould (posting to the News Group - 30 September 2002):
I'd been trying to track down a access denied error for months and within 1 week of implementing message box was able to finally track this down and squash the bug. Today is the first day we've run in a production environment without this nasty bug. To me the money was well spent.

Source Code Policy

We have chosen to ship CapeSoft MessageBox as source code, rather than as a compiled DLL. This makes it much easier for you to modify, but it also makes it much easier for you to pirate. We ask you to please consider the effort involved in writing this product, before you chose to hand it on to any other developers.

If you received this program illegally (i.e. if you didn't pay for it, or you didn't buy it from CapeSoft, ClarionShop, or one of their respective dealers) then we ask you to contact us so that we can remedy this situation. Without the revenue generated from products such as this it is impossible for us to create new products.

We welcome any suggestions from users regarding new features that might be added to CapeSoft MessageBox.

Copyright and License

This product, and all the files contained therein, is copyrighted © 2022 by CapeSoft Software.

You are not allowed to copy any of the files contained in this product, including but not limited to: Application files (APP), Template (TPL) files, Source files (CLW), Include files (INC) and documentation (HTM) files.

CapeSoft Software, employees of CapeSoft Software, and Dealers of CapeSoft Software products, explicitly accept no liability for any loss or damages which occur from using this package. Use of this package constitutes agreement with this license. This package is used entirely at your own risk.

What You Need to Distribute to your Users

You don't need to distribute anything else besides what you would normally distribute (without CapeSoft MessageBox) as all the objects will be compiled into your EXE or DLL.

Support

CapeSoft Support
Email
Telephone +27 87 828 0123

Version History

Download latest version here

Getting Compile Errors after upgrading? (click Here). Why should I use the new threadsafe message class? (See FAQ 4.10)

Version 2.50 - xxx 2022

Version 2.49 - 6 March 2022
Version 2.48 - 3 March 2022

Version 2.47 - 28 February 2022
Version 2.46 - 24 May 2021
Version 2.45 - (25 July 2019) Version 2.44 - (6 Feb 2019) Version 2.43 - (17 Jan 2019) Version 2.42 - (2 Jan 2019) Version 2.41 - (13 Sept 2018) Version 2.40 - (9 July 2018) Version 2.39 - (30 November 2017) Version 2.38 - (7 February 2016) Version 2.37 - (14 August 2015) Version 2.35 - (30 June 2015) Version 2.34 - (25 February 2015) Version 2.33 - (20 February 2015) Version 2.32 - (18 February 2015) Version 2.31 - 3 November 2014 Version 2.30 - 23 July 2014 Version 2.29 - 18 July 2014 Version 2.28 - 27 March 2014 Version 2.27 - 25 March 2014 Version 2.26 - 11 March 2014 Version 2.25 - 3 February 2014 Version 2.24 - 31 January 2014 Version 2.23 - 27 January 2014 Version 2.22 - 12 November 2013
Version 2.20 -
10 September 2013 Version 2.19 - 13 February 2013 Version 2.18 - 6 February 2013 Version 2.17 - 13 February 2012 Version 2.16 - 19 May 2011 Version 2.15 - 6 October 2010 Version 2.13 - 18 August 2010 Version 2.12 - 28 May 2010 Version 2.11 - 21 May 2010 Version 2.10 - 20 May 2010 Version 2.09 - 13 May 2010 Version 2.08 - 28 April 2010 Version 2.07 - 8 January 2010 Version 2.06 - 4 January 2010 Version 2.05 - 17 June 2009 Version 2.04 - 10 November, 2008 Version 2.03 - 22 October, 2008 Version 2.02 - 16 October, 2008 Version 2.01 - 09 October, 2008 Version 2.00 - 06 October, 2008 Version 1.98 - Released 3 September, 2007 Version 1.97 - Released 24 August, 2007 Version 1.96 - Released 23 August, 2007 Version 1.95 - Released 23 August, 2007 Version 1.94 - Released 20 July, 2007 Version 1.93 - Released 13 April, 2007 Version 1.92 - Released 16 July, 2006 Version 1.91 - Released 6 June, 2006 Version 1.90 - Released 20 March, 2006 Version 1.89 - Released December 8, 2005 Version 1.88 - Released July 18, 2005 Version 1.87 - Released April 18, 2005 Version 1.86 - Released March 8, 2005 Version 1.85 - Released January 24, 2005 Version 1.84 - Released November 8, 2004 Version 1.83 - Released November 5, 2004 Version 1.82 - Released November 2, 2004 Version 1.81 - Released October 5, 2004
NB for handcoders!!!! If you have handcoded your Message window, then you need to take note of the following - specifically the property changes. Version 1.80 - Released September 14, 2004 Version 1.79 - Released September 2, 2004 Version 1.78 - Released September 1, 2004 Version 1.77 - Released July 28, 2004 Version 1.76 - Released July 23, 2004 Version 1.75 - Released November 17, 2003 Version 1.74 - Released October 2, 2003 Version 1.73 - Released September 12, 2003 Version 1.72 - Released September 1, 2003 Version 1.71 - Released July 18, 2003 Version 1.70 - Released July 11, 2003 Version 1.6k - Released April 30, 2003 Version 1.6i - Released January 20, 2003 Version 1.6h - Released December 11, 2002
Version 1.6g - Released November 5, 2002
Version 1.6f - Released September 13, 2002
Version 1.6e - Released July 25, 2002
Version 1.6d - Released June 24, 2002
Version 1.6c - Released June 20, 2002
Version 1.6b - Released June 18, 2002
Version 1.6 - Released May 10, 2002
Version 1.56 - Released April 26, 2002
Version 1.55 - Released April 5, 2002
Version 1.54 - Released April 4, 2002
Version 1.53 - Released March 25, 2002
Version 1.5 - Released March 6, 2002
Version 1.4 - Released January 4, 2002
Version 1.3 - Released December 19, 2001
Version 1.2 - Released November 27,2001
Version 1.11 - Released November 7, 2001
Version 1.1 - Released October 29, 2001.

NB: If you are an existing user, you must delete your old MessageBox Control Template and add the new MessageBox Control Template to your MessageBox window. If not you will get a compile error: Unknown identifier: ?HALINK.
Version 1.03 - Released September 6, 2001.
Version 1.01 - Released August 17, 2001.
Version 1.0 Gold - Released August 10, 2001.
Version 1.0 beta 4a - Released July 26, 2001.
Version 1.0 beta 4 - Released July 6, 2001.
Version 1.0 beta 3 - Released June 22, 2001.

NB: If you are an existing user, you must delete your old MessageBox Control Template and add the new MessageBox Control Template to your MessageBox window.
Version 1.0 beta 2 - Released June 4, 2001.
Version 1.0 beta 1 - Released May 24, 2001.