Hi Vincent,

I think you might be right. Years ago, like back in the late 90's or something like that, I needed a class that could float over the top of everything, even programmes which were not DF applications.

From memory I came across it by pure accident by using a text search of all packages and include files with a variety of keywords and found it that way. It was around 1998, so just over 20 years ago.

Anyway, long story, short, it's come in very handy where I needed an object which contained reference information for the user. The user could use the DF application and simply "pop" the reference object up and then move it so it wasn't in their way. Regardless what was done, including using selection lists and other dialogues as well as non DF applications, the "OnTop" panel would always stay on top of everything.

I'm using it now to pop up notifications to the user, so for me, it's become somewhat valuable.


A simple example below, although it works perfectly, it's not quite finished yet:
Code:
Use Windows.pkg
Use cApplication.pkg
Use EnumProcesses.pkg

// Provides a "floating" panel.
Use DFOTPanl.pkg

Class cOnTopPanel is a ToolPanel
    Import_Class_Protocol TopMostMixin
    // Initialise TopMost Mixin
    Procedure Construct_Object
        Forward Send Construct_Object
        Send Init_TopMostMixin
        Set TopMost_State to True
    End_Procedure
End_Class

Object oApplication is a cApplication
    Property String psCriteriaMessage
End_Object

// Main UI
Object oSentinelDialog is a cOnTopPanel
    Set Label to "Notification"
    Set Size to 89 211
    Set piMinSize to 89 211
    Set Locate_Mode to SMART_LOCATE
    Set Border_Style to Border_Thick
    Set Sysmenu_Icon to False

    Object oStartBOSBtn is a Button
        Set Label    to "&Start BOS"
        Set Location to 71 102
        Set peAnchors to anBottomRight
        Procedure OnClick
            // Make the panel invisible, start the programme and
            //  when the programme exits, go back to looking for
            //  records that match the criteria.
            Set Visible_State of oSentinelDialog to False
            Runprogram Wait "BOS.exe"
            Send TimerLoop
        End_Procedure
    End_Object

    Object oExitBtn is a Button
        Set Size to 14 50
        Set Label    to "&Exit Sentinel"
        Set Location to 71 157
        Set peAnchors to anBottomRight
        Procedure OnClick
            // Completely close every component of the applet.
            Send Exit_Application
        End_Procedure
    End_Object

    Object oSentinelMessage is a TextBox
        Set Size to 10 50
        Set Location to 20 20
        Set Label to ""
        Procedure Page Integer iPageObject
            Forward Send Page iPageObject
            Set Label to (psCriteriaMessage(oApplication))
        End_Procedure
    End_Object

    On_Key Key_Alt+Key_S Send KeyAction of oStartBOSBtn
    On_Key Key_Alt+Key_E Send KeyAction of oExitBtn
End_Object

// Open necessary files.
Open BOS

// Check for records which are yet to be processed.
// If one is found, then return True.
Function CriteriaCheck Returns Boolean
    Clear BOS
    Find gt BOS by 5 // ProcessedDate, BOSDate, Id
    If (Found and BOS.ProcessedDate = "") Begin
        Set psCriteriaMessage of oApplication to "A new BOS request has just arrived to be processed."
        Function_Return True
    End
    Else Function_Return False
End_Function

// Wasting time loop using a simple Sleep command. Would a cTimer use less resources???
// If bCheck is True then display the sentinel dialogue.
// NOTE: Initially, Start_UI must be sent to display the UI portion of this applet,
//        but thereafter, a simple Activate message is all that is required.
Procedure TimerLoop
    Integer iCount iProcesses
    Boolean bCheck
    // Use of EnumProcesses.pkg to find out if BOS.exe is already running by querying the CountProcess function.
    // If it is already running (<> 0), then skip the criteria check and just keep looping.
    While (bCheck = False)
        Get CountProcess "BOS.exe" to iProcesses
        If (iProcesses = 0) Get CriteriaCheck to bCheck
        Sleep 900 // 900 is the default, which is 15 minutes.
    Loop
    // If iCount = 1 then start the UI, otherwise just activate.
    If (bCheck) Begin
        Increment iCount
        Set Visible_State of oSentinelDialog to True
        If (iCount = 1) Start_UI oSentinelDialog
        Else Send Activate to oSentinelDialog
    End
End_Procedure

Send TimerLoop