Pushbutton Doppelklick [erledigt]

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Pushbutton Doppelklick [erledigt]

Beitrag von Werner_Bayern »

Servus,

ein Pushbutton kennt ja auch o. g. Methode. Macht aber keinen Sinn. Ich schaffe es nicht, das Ereignis auszulösen.
Ein Kunde schafft es jedoch, mit einem Doppelklick den activate-Slot 2x auszulösen, obwohl der so aussieht:

Code: Alles auswählen

oXbp := MeinImageButton():new(drawingArea, , {nX, nY})
oXbp:caption := "Ausbuchen"
oXbp:Image := oIcon_Buch
oXbp:autoSize := .t.
//oXbp:lbDblClick := {||hinweis("Das war jetzt ein Doppelklick auf einen Pushbutton, macht keinen Sinn!")}
oXbp:default := .t.
oXbp:tabStop := .t.
oXbp:activate := {|uNIL1, uNIL2, self|self:disable(), oFenster:disable(), Ausbuchen(sleval(oBetrag:editBuffer()), sdBuchdatum,;
sleval(oSkonto:editBuffer()), if(oZahlart:XbpListbox:getdata()[1] == 1, "B", "K"), aSystem, aWW)), oFenster:enable(),;
PostAppEvent(xbeP_Close,,,oFenster)}
oXbp:create()
Wie kann das sein? Der Pushbutton wird ja "sofort" disabled?
Zuletzt geändert von Werner_Bayern am Mo, 08. Dez 2014 15:24, insgesamt 1-mal geändert.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Scarmo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 188
Registriert: Di, 24. Jul 2007 9:17

Re: Pushbutton Doppelklick

Beitrag von Scarmo »

Hallo Werner

Ich denke, dass dies auf relativ langsamen Maschinen möglich ist... Deshalb würde ich ein Flag (z.B. "In_Ausbuchen") auf true setzen und diese externe Variable als Erstes in der Funktion Ausbuchen() abfragen. Wenn diese true ist, einfach return auslösen. Am Ende der Funktion Ausbuchen() das Flag natürlich wieder auf false setzen.

Gruss
Marco
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Pushbutton Doppelklick

Beitrag von brandelh »

Das dachte ich auch, aber schau mal das Beispiel an, bei einem CLICK werden nacheinander diese Events erzeugt:

Code: Alles auswählen

13:41:09	lbDown        // Maus wird über Button gedrückt
13:41:09	lbUp            // Maus wird losgelassen, auch wenn sie nicht mehr über dem Button ist  :!:  :!:  :!: 
13:41:09	lbClick         // dieser wird nur ausgelöst, wenn lbUp über dem Button ausgeführt wurde  :!:  
13:41:09	Activate *** // dieser wird ausgelöst durch den lbClick im XbpPushButton
man kann auch einen lbDblClick erzeugen, wenn man schnell ist ;-)
das sieht dann so aus:

Code: Alles auswählen

13:44:08	lbDown
13:44:08	lbUp
13:44:08	lbClick
13:44:08	Activate ***
13:44:09	lbDblClick
13:44:09	lbUp
13:44:09	lbClick
13:44:09	Activate ***
ob das jetzt intern ein Fehler ist :?:

Ich hatte früher den Fall auf einem älteren Rechner, dass er Tastatureingaben verzögert hat und somit die Tastaturmenüauswahl nicht richtig funktioniert hat,
damals habe ich eine Art von Prellsperre eingebaut, je nach Rechner mehr oder weniger, das war eine Fummelei.

Du kannst nach einem Activate Event eines PushButtons die nächte Sekunde die Activates dieses Puttons ignorieren.

Code: Alles auswählen

///////////////////////////////////////////////////////////////////////////////
//
//  Function-oriented code created by the Xbase++ FormDesigner
//    Creation date: 08.12.2014 Time: 13:06:40
//
///////////////////////////////////////////////////////////////////////////////

#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Font.ch"

#PRAGMA LIBRARY( "ascom10.lib" )

procedure AppSys
return

PROCEDURE Main
   LOCAL nEvent, mp1, mp2, aSize
   LOCAL oDlg, oXbp, drawingArea, aEditControls := {}

   IF IsMemberVar(XbpDialog(),"ClientSize") == .T.
      aSize := {0,0}
   ELSE
      aSize := {154,155}
   ENDIF

   oDlg := XbpDialog():new( AppDesktop(), , {636,703} , aSize, , .F.)
   IF aSize[1] == 0 .AND. aSize[2] == 0
      oDlg:ClientSize := {300,400}
   ENDIF
   oDlg:taskList := .T.
   oDlg:title := "New form"
   oDlg:create()

   drawingArea := oDlg:drawingArea
   drawingArea:setFontCompoundName( "8.Arial" )

   oXbp := XbpMLE():new( drawingArea, , {16,50}, {280,300}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
   oXbp:tabStop := .T.
   oXbp:editable := .f.
   oXbp:wordWrap := .t.
   oXbp:horizScroll	:= .f.

   oXbp:create()

   logger(oXbp) // Logger initialisieren

   oXbp := XbpPushButton():new( drawingArea, , {16,16}, {100,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } } )
   oXbp:caption := "Pushbutton"
   oXbp:tabStop := .T.
   oXbp:create()
   oXbp:activate   := {|| logger("Activate ***")   }
   oXbp:lbDblClick := {|| logger("lbDblClick")  }
   oXbp:lbClick    := {|| logger("lbClick") }
   oXbp:lbDown     := {|| logger("lbDown") }
   oXbp:lbUp       := {|| logger("lbUp") }
   CenterControl(oDlg)

   oDlg:show()
   SetAppFocus(oDlg)

   nEvent := xbe_None
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO
RETURN

function logger(cTxt)
   static oLog := NIL
   if valtype(cTxt)="O"
      oLog := cTxt
   else
      oLog:setData( oLog:editBuffer()+chr(13)+chr(10)+time()+chr(9)+cTxt )
   endif
RETURN NIL
PS: Ich habe das auf einem i5-2500 probiert, der ist schnell :!:
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Pushbutton Doppelklick

Beitrag von brandelh »

Werner_Bayern hat geschrieben:Der Pushbutton wird ja "sofort" disabled?
wenn du dir mein Beispiel ansiehst, wirst du sehen, dass der doppelclick erfolgte bevor activate überhaupt aufgerufen wurde.
Auch wenn du den dblClick Slot nicht belegt hast, wartet doch der zweite Click-Event bevor das activate zum ersten Mal ausgeführt wurde.
Das Disable kommt also nach dem auslösen des zweiten Clickevents.

Du könntest eine iVar im lbDblClick Slot auf .t. setzen => Doppelklick wurde ausgelöst,
und im activate abfragen ob diese auf .t. steht. Wenn ja, dann den nächsten activate überspringen.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Pushbutton Doppelklick

Beitrag von brandelh »

Hier habe ich mal eine "Doppelclicksperre" eingebaut, wobei die Events tatsächlich kommen und nur 3/10 Sekunden Activate blockiert wird.
Die hier verwendete LOGGING() Funktion ist träge, die 3/10 Sekunden sind hier nur ein Beispiel und müssen je nach Anwendung angepaßt werden.

Code: Alles auswählen

///////////////////////////////////////////////////////////////////////////////
//
//  Function-oriented code created by the Xbase++ FormDesigner
//    Creation date: 08.12.2014 Time: 13:06:40
//
///////////////////////////////////////////////////////////////////////////////

#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Font.ch"

#PRAGMA LIBRARY( "ascom10.lib" )

procedure AppSys
return

PROCEDURE Main
   LOCAL nEvent, mp1, mp2, aSize
   LOCAL oDlg, oXbp, drawingArea, aEditControls := {}
   LOCAL nLastEvent, oPB

   IF IsMemberVar(XbpDialog(),"ClientSize") == .T.
      aSize := {0,0}
   ELSE
      aSize := {154,155}
   ENDIF

   oDlg := XbpDialog():new( AppDesktop(), , {636,703} , aSize, , .F.)
   IF aSize[1] == 0 .AND. aSize[2] == 0
      oDlg:ClientSize := {300,400}
   ENDIF
   oDlg:taskList := .T.
   oDlg:title := "New form"
   oDlg:create()

   drawingArea := oDlg:drawingArea
   drawingArea:setFontCompoundName( "8.Arial" )

   oXbp := XbpMLE():new( drawingArea, , {16,50}, {280,300}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } } )
   oXbp:tabStop := .T.
   oXbp:editable := .f.
   oXbp:wordWrap := .t.
   oXbp:horizScroll	:= .f.

   oXbp:create()

   logger(oXbp) // Logger initialisieren

   oXbp := XbpPushButton():new( drawingArea, , {16,16}, {100,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } } )
   oXbp:caption := "Pushbutton"
   oXbp:tabStop := .T.
   oXbp:create()
   oXbp:activate   := {|| logger("Activate ***")   }
   oXbp:lbDblClick := {|| logger("lbDblClick")  }
   oXbp:lbClick    := {|| logger("lbClick") }
   oXbp:lbDown     := {|| logger("lbDown") }
   oXbp:lbUp       := {|| logger("lbUp") }

   oPB := oXbp
   CenterControl(oDlg)

   oDlg:show()
   SetAppFocus(oDlg)

   nEvent := xbe_None
   nLastEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      if oXbp = oPB .and. nEvent = xbeP_Activate
         if nLastEvent+0.30 > seconds()
            nEvent := xbe_None
            tone(1000,3)
         else
            nLastEvent := seconds()
         endif
      endif
      if nEvent # xbe_None
         oXbp:handleEvent( nEvent, mp1, mp2 )
      endif
   ENDDO
RETURN

function logger(cTxt)
   static oLog := NIL
   if valtype(cTxt)="O"
      oLog := cTxt
   else
      oLog:setData( oLog:editBuffer()+chr(13)+chr(10)+time()+chr(9)+cTxt )
   endif
RETURN NIL
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Pushbutton Doppelklick

Beitrag von Werner_Bayern »

Vielen Dank Ihr beiden!
Ich machs mit einer lVar, dann gibts keine Verzögerung.

Korrekt ist m. M. n. das Verhalten hier aber von Xbase++ nicht.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Pushbutton Doppelklick

Beitrag von Werner_Bayern »

Lösung sieht jetzt so aus:

Code: Alles auswählen

oXbp:activate := {||if(++nAusbuchen == 1, eval({||oFenster:disable(), Ausbuchen(sleval(oBetrag:editBuffer()), sdBuchdatum,;
sleval(oSkonto:editBuffer()), if(oZahlart:XbpListbox:getdata()[1] == 1, "B", "K"), aSystem, aWW), oFenster:enable(), nAusbuchen--}),;
fehler("2. Mehrfachaufruf beim OP-Ausbuchen, Buchungsanfrage wird abgewiesen: " + ltrim(str(nAusbuchen)),,-1)), PostAppEvent(xbeP_Close,,,oFenster)}
Testen muss es der Kunde, ich kann es nicht.
es grüßt

Werner

<when the music is over, turn off the lights!>
Antworten