Page 1 of 1

Dialog with timer bar

Posted: Thu Mar 05, 2015 3:43 am
by skiman
Hi,

I want to display a message for a minimum time. I don't want a user can proceed immediately, but the message should remain 5 seconds. I have done this with a do while and with waitperiod(() (xbtools).

I was wondering if I could display some timer-bar in the messagebox.

I checked functions as dcmsgbox(). This would be usable if there would be some parameter as TIMESTOP where can be defined the minimum time.

Any ideas how I could implement this. If I add a progressbar to my dialog, I don't see how I can accomplish what I need. I use progressbars but they are never part of another dialog.

Re: Dialog with timer bar

Posted: Thu Mar 05, 2015 6:45 am
by bwolfsohn
how about:

DCMSGBOX "WARNING!! WARNING" TIMEOUT 10

will give you the timeout, but no progressbar..

Re: Dialog with timer bar

Posted: Thu Mar 05, 2015 6:56 am
by rdonnay
Chris -

I'm not sure what you mean by a timer bar.
Are you saying that you want a progress bar and message that times out after a specified time?

Do you want it to be modal?

Re: Dialog with timer bar

Posted: Fri Mar 06, 2015 12:55 am
by skiman
Hi Brian, Roger,

It is not the timeout I'm looking for.

I want to display a message which has to stay at least 5 seconds before the user can proceed. The message is for the accounting when there are open invoices. Users now say that they haven't seen the message because they click on OK before reading it. I want some kind of alert that remains 5 seconds before they can proceed. I do this now with a do while loop.

I would like to add some timer bar to my dialog. They can't proceed now with my do while waitperiod() ... enddo, but they don't see why. A timer bar would make this clear.

Re: Dialog with timer bar

Posted: Fri Mar 06, 2015 4:58 am
by Wolfgang Ciriack
Hi,
can`t you use this ?

Code: Select all

dc_WaitOn("Wait......")
sleep(500)
dc_impl(cDialog)

Re: Dialog with timer bar

Posted: Fri Mar 06, 2015 5:39 am
by skiman
Hi,

No, I don't want it to disappear after 5 seconds. It must stay on the screen untill the user clicks OK. If he clicks OK before 5 seconds, nothing may happen. After 5 seconds the OK should work. It's also possible that the user clicks only after 15 seconds.

Re: Dialog with timer bar

Posted: Fri Mar 06, 2015 6:31 am
by Tom
Hi, Chris.

You may try this code. The main function is "MessageWithTimer". It has up to three parameters. If it fits your needs, you may replace "SetTimerEvent" by a thread.

Code: Select all

FUNCTION MessageWithTimer(nTimeOut,cMessage,cTimeOutMessage)
LOCAL GetList := {}, GetOptions := {}, oGroup

DCGET OPTIONS NOTITLEBAR

DEFAULT nTimeOut := 30, cMessage := 'Warning'

TimeOutMessage(nTimeOut)

@ 1,1 DCGROUP oGroup CAPTION 'Information' SIZE 60,4.5 NOTABSTOP
@ 1,1 DCSAY cMessage SIZE 58,3 PARENT oGroup ;
      SAYOPTIONS XBPALIGN_VCENTER+XBPALIGN_HCENTER+XBPSTATIC_TEXT_WORDBREAK


@ 6,1 DCSAY {||TimeOutMessage()} OBJECT oTimeOutMessage

@ 8,1 DCPUSHBUTTON CAPTION 'Close' SIZE 5,1 WHEN {||TimeOutDialogCanBeClosed()} ;
      ACTION {||DC_ReadGuiEvent(DCGUI_EXIT_OK,GetList)} OBJECT oCloseButton

DCREAD GUI TITLE 'Information' OPTIONS GetOptions FIT EVAL {||SetTimerEvent(100,{||DC_GetRefresh(GetList)})}

SetTimerEvent()

RETURN nil

FUNCTION TimeOutDialogCanBeClosed(lSet)
STATIC lCanBeClosed := .F.
IF PCount()>0
  lCanBeClosed := lSet
ENDIF
RETURN lCanBeClosed

FUNCTION TimeOutMessage(nSetSeconds)
STATIC nWaitSeconds, nSecondsAtStart
LOCAL cTimeOutMessage := 'Wait [TIMELEFT] seconds to close this dialog',nSecondsLeft
IF PCount() > 0
  TimeOutDialogCanBeClosed(.F.)
  nWaitSeconds := nSetSeconds
  nSecondsAtStart := Seconds()
ENDIF
IF Seconds()-nSecondsAtStart >= nWaitSeconds
  TimeOutDialogCanBeClosed(.T.)
  cTimeOutMessage := 'You may close the dialog now'
  ELSE
  nSecondsLeft := nWaitSeconds-(Seconds()-nSecondsAtStart)
  cTimeOutMessage := StrTran(cTimeOutMessage,'[TIMELEFT]',LTrim(Str(nSecondsLeft,5,0)))
ENDIF

RETURN cTimeOutMessage
The attached pictures show what the function does.

Re: Dialog with timer bar

Posted: Fri Mar 06, 2015 7:00 am
by Cliff Wiernik
I also use a method which is a modification of dc_msgbox where the message is displayed until they enter a specific override key. That forces them to at least acknowledge that they had a message, pressing enter does not work:

Code: Select all

    
    DO WHILE !LB_MsgBoxOverride({'Transaction posted to non-existent account.; Press @ to continue and Check log.'},'Transaction Error','W','@')
    END DO


#define oYes         aLocals[1]
#define oNo          aLocals[2]
#define l_YesNo      aLocals[3]
#define oOk          aLocals[4]
#define o_Static     aLocals[5]
#define lExitStatus  aLocals[6]
#define cOverridekey aLocals[7]
#define l_Escape     aLocals[8]
#define l_EscHit     aLocals[9]

*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
*+      FUNCTION LB_MsgBoxOverRide(aMessage, cTitle, cSys_Icon, cOverKey)
*+
*+      // Function returns lExitStatus so it should be called from a while loop...
*+
*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
FUNCTION LB_MsgBoxOverride ( aMessage, cTitle, cSys_Icon, cOverKey)

  LOCAL nWidth, i, oDlg, oXbp, oParent, oOwner, ;
        GetList := {}, GetOptions, aLocals[9], lOk, ;
        oAppFocus := SetAppFocus(), nLine, cKey

  lExitStatus := .F.
  cOverridekey := cOverKey

  IF Valtype( aMessage ) = 'C'
    aMessage := { aMessage }
  ENDIF
  
  DC_VALTYPE(  @aMessage,{},  @cTitle,DC_MsgBoxTitle(), @cSys_Icon,'', @cOverridekey,'@' )
  
  cTitle := cTitle + ' [ '+cOverridekey+' ]'                                      // PC CAW 10-13-09 display override key

  FOR i := 1 TO LEN(aMessage)
    aMessage[i] := DC_XtoC(aMessage[i])
  NEXT

  IF LEN(aMessage)>0
    CLEAR TYPEAHEAD
  ENDIF

  nWidth := 0
  FOR i := 1 TO LEN(aMessage)
    nWidth := MAX( nWidth, LEN(aMessage[i]) )
  NEXT

  nWidth := MAX(nWidth,LEN(cTitle)+4)

  @ 1,1 DCSTATIC TYPE XBPSTATIC_TYPE_SYSICON SIZE 5,1.5 ;
            CAPTION IIF(cSys_Icon = "I",XBPSTATIC_SYSICON_ICONINFORMATION,;
                                 IIF(cSys_Icon = "E",XBPSTATIC_SYSICON_ICONERROR,;
                                 IIF(cSys_Icon = "Q",XBPSTATIC_SYSICON_ICONQUESTION,;
                                 IIF(cSys_Icon = "W",XBPSTATIC_SYSICON_ICONWARNING,;
                                                     XBPSTATIC_SYSICON_ICONINFORMATION))))

  IF nWidth < 25
    nWidth := 20
  ENDIF
      
  nLine := 3.5

  IF LEN(aMessage) = 1                           // Don't center message if only one line   // PC CAW  changed to have blank line prior
    nLine++
    @ nLine, 1 DCSAY aMessage[1] SIZE 0,0 
    nLine++
  ELSE
    nLine++
    FOR i := 1 TO LEN(aMessage)
      @ nLine, 1 DCSAY aMessage[i] SIZE 0,0                                     // PC CAW 02-09-09 changed to left justify all lines
      nLine++
    NEXT
  ENDIF

  @ nLine,0 DCSTATIC TYPE XBPSTATIC_TYPE_TEXT SIZE 9, 1.3 OBJECT o_Static   

  @ 0, 0 DCPUSHBUTTON;
          CAPTION DC_LangMsg(DCMSG_OK) ;      // BITMAP_OK_1
          TABSTOP ;
          SIZE 9,1.3 ;
          PARENT o_Static ;
          OBJECT oOk ;
          ACTION {||PostAppEvent( xbeP_Close,nil,nil,oDlg )} ;
          EVAL {|o|SetAppFocus(o)}

  DCGETOPTIONS  ICON DC_IconDefault() ;
           NOMAXBUTTON NOMINBUTTON ;
           BUTTONALIGN DCGUI_BUTTONALIGN_CENTER ;
           FITPAD 10 ;
           HIDE

  DC_ClearEvents()

  DCREAD GUI FIT MODAL TITLE cTitle OPTIONS GetOptions ;
         SETAPPWINDOW        ;                                          // PC CAW 03-01-05 was not set for modal window
         HANDLER S_MsgBoxOverDlgHandler   REFERENCE aLocals ;
         ENTEREXIT ;
         PARENT @oDlg ;
         EVAL {|o|S_CenterStatic(o, aLocals), o:Show()}

  SetAppFocus(oAppFocus)

  RETURN lExitStatus

*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
*+      STATIC FUNCTION S_MsgBoxOverDlgHandler( nEvent, mp1, mp2, oXbp, oDlg,aGetlist, aLocals )
*+
*+
*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
STATIC FUNCTION S_MsgBoxOverDlgHandler ( nEvent, mp1, mp2, oXbp, oDlg, GetList, aLocals )

  IF nEvent == xbeP_Keyboard .AND. !lExitStatus
    IF mp1 == ASC(cOverridekey)
      lExitStatus := .T.
    ELSE
      lExitStatus := .F.
    ENDIF
    SetAppFocus(oOk)
    PostAppEvent(xbeP_Keyboard,xbeK_ENTER,,oOk)
  ENDIF

RETURN DCGUI_NONE


Re: Dialog with timer bar

Posted: Mon Mar 09, 2015 1:04 am
by skiman
Hi Tom, Cliff,

Thanks for the code. It looks as both are a solution. I will test them both to see what I can use.