/ Forums / Advansys Formativ / Creating Solutions with Formativ / Clearing the mouse/keyboard buffer after displaying a form

  • Creator
    Topic
  • #4281
    RPP
    Participant

    I am displaying a ‘Please Wait’ type form whilst my applet runs.

    e.g.

    frmWait.show

    /* Applet code runs – verifies users request is valid, etc.

    frmwait.hide

    The problem I have is that if the user clicks the mouse on the Groupwise main window whilst the form is displayed then the events are saved up. Once my applet completes a few seconds later the clicks are processed and this can create some very strange effects, depending on what they clicked.

    Is there some way to flush the mouse click buffer? I would imagine I need to clear the keyboard buffer as well in case they have hit Enter or such but the mouse is more likely.

    Thanks

    Simon

  • Author
    Replies
  • #7714
    Support 1
    Participant

    Simon,

    Thank you for your enquiry.

    The problem you describe is a perennial issue for windowed user interfaces (UIs) which have background processes running half a second or longer. This is a “rule of thumb” time period: the amount of time it will take the average user to notice a pause in the responsiveness of the UI.

    We know of two UI design options to address this issue:

    • Display a “status” dialog for the duration of the background process. The dialog may, optionally, provide quality of service information (eg. a progress gauge or textual counter) and a way to cancel the process. A dialog like this is typically modeless, ie. other windows in the application are accessible at the same time. This means that the user could click on and make changes in another window, even if those changes are not noticeable until after the process completes.

      Your “Please Wait” form is an example of a modeless dialog because it is displayed using the command

        frmWait.Show

    • Display a modal dialog for the duration of the background process. When a modal dialog is active, an application will not permit mouse or keyboard input to be sent to any other window within the application. With a Formativ Form, this is done using the command
        frmWait.ShowModal

      The dialog need not be a dedicated status dialog. It could be one used to specify parameters for the process, in which case it may be necessary to disable certain controls for the duration of the process.

    For both options, window events must be processed with a frequency and regularity to keep the UI responsive. This is done using the command

      Utilities.DoEvents

    Obviously each option has advantages and disadvantages. The one to choose will depend on the specific circumstances of the process and/or UI involved. Below is a code sample demonstrating a simple implementation of the modal solution:

    '-------------------------------------------------------------------------------
    ' The code below assumes that a form MainForm is defined.  The form has the
    ' following controls:
    ' - A listview ListView, to display numbers counted by a background process.
    ' - A button bnConfig, to configure the solution.  This control is disabled when
    '   processing.
    ' - A button bnToggle whose caption is initially "Start", but changes to "Stop"
    '   when processing.  When the caption is "Stop", clicking the button cancels
    '   the process.  The subroutine bnToggleClick is the event handler for clicking
    '   this button.
    '
    ' Note the use of Utilities.DoEvents inside the tight loop of subroutine
    ' bnToggleClick.  Without this command it would not be possible to stop the
    ' process manually after it has started.
    
    dim gCount
    dim gIndex
    dim gIsProcessing
    
    Sub Main(Client, GWEvent)
    
      gIsProcessing = false
      gCount = 0
    
      MainForm.ShowModal
    
    End Sub
    
    
    Sub bnToggleClick(Sender)
    
      dim oItem
    
      with MainForm
        if gIsProcessing then
          gIsProcessing = false
          .bnConfig.Enabled = true
          .bnToggle.Caption = "Start"
        else
          gIsProcessing = true
          .bnToggle.Caption = "Stop"
          .bnConfig.Enabled = false
    
          gIndex = gCount + 1
          gCount = gCount + 1000
          do while (gIndex <= gCount) and gIsProcessing
            set oItem = .ListView.Items.Add
            oItem.Caption = "Item " & CStr(gIndex)
            gIndex = gIndex + 1
            Utilities.DoEvents
          loop
    
          ' Restore the UI if the user did not cancel the process.
          if gIsProcessing then
            call bnToggleClick(nothing)
          end if
        end if
      end with
    
    End Sub
    '-------------------------------------------------------------------------------
    

    I hope this helps.

    Regards,
    Advansys Support

    [This message was edited by Support 1 on August 21, 2006 at 08:40 PM.]

    #7712
    RPP
    Participant

    Hi

    Thanks for the information. I have experimented some with modal/modeless forms in Formativ but can’t quite get them to waork as I need. I’ll explain what I am doing, maybe that will help.

    I have two processes to get through in my applet.

    The first is a test against a particular mailbox looking for a particular email. This is all handled in Formativ and takes about 2 seconds.

    The second process only happens if the first process succeeds (if it doesn’t the applet displays a msg and exits). This process creates an object against my custom VB ActiveX EXE and calls a function therein. This process takes about 2 seconds to get started (creating/calling the object). At that point a form (VB form) is displayed and the user completes this. The applet code execution waits until the VB function completes.

    Since processes 1 and 2 take 4 to 5 secs to get to the point where the VB form is displayed I display a modeless “Please Wait” dialog right at the start of my applet and only hide it just before displaying the VB form.

    In principle this works fine. However if the user clicks around the edges of the Please Wait form, or around the edges of my VB form then those clicks are stored up and passed to GW once the applet completes.

    Also, a lot of the users are keen on double-clicking the toolbar button (a formativ button) to start the applet in the first place. This means the second click waits until the whole applet has completed before being triggered – it then fails because the email has already been ‘logged’ (the purpose of my applet). I realise this is a training issue but some people just don’t do as they’ve been told.

    Version two of my applet was to try and use a modal form. The way I tried to do this was as follows …

    Create a Please Wait form.
    Add a Timer to it that is enabled and has an interval of 100 (0.1sec)

    Add a sub for the Timer’s event that …
    1) switches the timer off so it can only run once
    2) triggers my main applet – the Please Wait form is hidden in this applet but is still running
    3) unloads the Please wait Form once the applet has completed

    In principle this works better. The Please Wait form won’t allow clicks to be directed at GW. Nor will any be done whilst the VB form is up. Double clicking the Applet’s toolbar button doesn’t start it twice. All perfect.

    The one problem I have is “3)” above – I can’t work out how to get rid of my Modal form. In VB, a modal form ceases to be modal when it is hidden with the .Hide method. In Formativ this justs gets me locked out as I have a form I can’t get to to shutdown!

    Is there a way of instructing the form to stop running?

    I realise I could have a OK button and change the Please Wait to say ‘Log Completed’ or something but I’d rather not. They know they’ve logged it because they just filled in the form, another dialog to say OK to would be very annoying.

    I am running all this is the Creator by the way, the finished applets go out as FlexaLocked. Does that change their ‘form’ behaviour at all?

    Thanks

    Simon

    #7713
    Support 1
    Participant

    Simon,

    Please note the following controls on the Formativ component palette:

    • TButton
    • TBitBtn
    • TRzButton
    • TRzBitBtn

    All of these controls have the property ModalResult. If you add one of these controls to a form, you can see the list of legal values for ModalResult in the Object Inspector (open the drop-down list).

    Forms also have the property ModalResult (not shown in the Object Inspector – it is only meaningful at runtime).

    The way to close a modal dialog in code is to set Form.ModalResult to one of the legal values (except mrNone), for example:

      frmWait.ModalResult = mrOK

    The value that you choose will become the result of the function frmWait.ShowModal.

    An applet’s behavior (whether code or forms) is always the same, whether it is an “open source” or Flexalocked applet.

    Regards,
    Advansys Support

    #7710
    RPP
    Participant

    The .ModalResult property/method does the trick!

    My Please Wait form now prevents interaction with Groupwise, runs my applet and then goes away. Just what I wanted.

    Thanks

    Simon

    #7711
    Support 2
    Moderator

    Thanks for the feedback Simon, great news.

    Regards,

    Advansys Support

Viewing 5 replies - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.