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.