[gelöst] Wie funktioniert _mouseReleased ?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Jonny1
***
Beiträge: 55
Registriert: Mi, 12.01.2011 21:49

[gelöst] Wie funktioniert _mouseReleased ?

Beitrag von Jonny1 »

Folgende Makros habe ich geschrieben:

Code: Alles auswählen

REM  *****  BASIC  *****

'Option Explicit

Global oDocView As Object
Global oMouseClickHandler As Object

Global Anzahl as string, AnzahlAlt as String

Sub RegisterMouseClickHandler
  oDocView = ThisComponent.currentController
  oMouseClickHandler = _
  createUnoListener("MyApp_", "com.sun.star.awt.XMouseClickHandler")
'  writedbginfo oMouseClickHandler
  oDocView.addMouseClickHandler(oMouseClickHandler)
End Sub

Sub UnregisterMouseClickHandler
  on error resume next
  oDocView.removeMouseClickHandler(oMouseClickHandler)
  on error goto 0
End Sub

sub CheckBox1
	Dim LightRed as Long, Green5 as Long, a as Boolean, b as String, c as String, d as Long 	
	LightRed = 16711680
	Green5 = 44544
	a = ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").State
	if a then 
		RegisterMouseClickHandler
		b = "registered"
		c = "Click here to unregister the page."
		d = Green5
	else 
		UnregisterMouseClickHandler
		b = "unregistered"
		c = "Click here to register the page."
		d = LightRed
	end if
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").Label = b
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").helptext = c
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").backgroundcolor = d
end sub

Sub MyApp_disposing(oEvt)
End Sub

Function MyApp_mousePressed(oEvt) As Boolean
  MyApp_mousePressed = False
End Function

Function MyApp_mouseReleased(oEvt) As Boolean
	Dim Anzahl
	Anzahl = oEvt.ClickCount
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("LabelAnzahl").Label = "ClickCount = " & Anzahl
	if Anzahl = 2 then mSubForDoubleClick
	if Anzahl = 1 then mSubForSingleClick
	MyApp_mouseReleased = False
End Function

sub mSubForSingleClick
	print "mSubForSingleClick"
end sub

sub mSubForDoubleClick
	print "mSubForDoubleClick"
end sub
Nur wenn ich "if Anzahl = 1 then mSubForSingleClick" lahm lege, kommt die eine Zeile davor geschriebene Bedingung "if Anzahl = 2" zum Tragen.

Warum?

Meine Vermutung ist es, daß die Funktion MyApp_mouseReleased(oEvt) bei Doppelcklick zweimal durchlaufen wird. Ich vermute, daß beim ersten Durchlauf „Anzahl“ den Wert 1 zugewiesen bekommt und, wenn "if Anzahl = 1 then mSubForSingleClick" vorhanden ist und mSubForSingleClick auferufen wird, die widerstpensige Maus nach sehr kurzem Warten keine Lust mehr verspürt, das Event nochmals auszulösen.

Habe ich richtig geraten oder sind es Hirngespinste?

Mit eigenwilligen Mäusen kenne ich mich nicht gut aus.

Wie kann ich der Anweisung "if Anzahl = 1 then mSubForSingleClick" mitteilen, daß sie ein wenig – wie lange? - warten soll, damit das Mäuschen eventuell das Event ein zweites mal auslöst und mich nicht im Stich läßt?
Zuletzt geändert von Jonny1 am Do, 24.01.2013 21:08, insgesamt 1-mal geändert.
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Wie funktioniert _mouseReleased ?

Beitrag von balu »

Hallo Jonny1,

na ich weiß nicht so recht ob das gut geht, eine IF...THEN-Anweisung ohne ELSE beziehungsweise ohne END IF? Und das ganze gleich 2 mal
Online Hilfe(F1) hat geschrieben: Trifft OpenOffice.org Basic auf eine If-Anweisung, so wird zunächst die Erfüllung der Bedingung geprüft. Ist die Bedingung erfüllt (True), so werden alle nachfolgenden Anweisungen bis zur nächsten Else- oder ElseIf-Anweisung ausgeführt.
Verstehst Du das, oder muss ich das für dich genauer erklären?



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Jonny1
***
Beiträge: 55
Registriert: Mi, 12.01.2011 21:49

Re: Wie funktioniert _mouseReleased ?

Beitrag von Jonny1 »

Die Prozedur:

Code: Alles auswählen

sub Probe
	a=0
	if a=0 then exit sub
	print "balu ist ein sehr schlauer Kerl"
end sub
funktionert einwandfrei auch ohne ELSE und END IF und weigert sich zu verkünden: „balu ist ein sehr schlauer Kerl“.
Verstehst Du das, oder muss ich das für dich genauer erklären?
Dennoch habe ich in das Makro ENDIF eingefügt, um das Restrisiko zu beseitigen. NICHTS hat sich geändert.

Dann habe ich sinnloserweise auch ELSE eingefügt. Und auch da hat sich selbstverständlich NICHTS geändert.

Wie sollte es auch?

Das Problem ist nicht, daß alle nachfolgende Anweisungen bis auf ELSE und/oder ENDIF ausgeführt werden!

Das Problem ist - wie von Anfang an sehr deutlich geschrieben - daß die allererste Abfragung "if Anzahl = 2" als nicht zutreffend beurteilt wird, obwohl ich doppelt geklickt habe. Das ist das Problem.

Also, noch einmal:

"if Anzahl = 2" wird als FALSCH bewertet.

Die nachfolgende Abfragung:

"if Anzahl = 1" wird als WAHR bewertet.

Ich habe unzählige male doppelt geklickt und jedes mal reagierte das Makro so, als hätte ich nur einmal geklickt.

Sind die zwei Abfragungen nicht da, dann schreibt das Makro ganz korrekt die richtige Anzahl der Klicks - ob sie nun 1, 2, 3, 4, 5 oder mehr sind, mit der Anweisung:

"ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("LabelAnzahl").Label = "ClickCount = " & Anzahl"

Offensichtlich ist nicht das Unterlassen von ENDIF und schon gar nicht das Unterlassen von ELSE das Problem.

Ich vermute, daß der erste Klick schon das Durchlaufen von MyApp_mouseReleased(oEvt) veranlasst. Ohne Abfragung wird - nehme ich an - MyApp_mouseReleased(oEvt) wieder durchlaufen und jedes mal wird die korrekte Anzahl der bisherigen Klicks in das Label für jeden sichtbar geschrieben.

Hat sich aber der Verlauf in einer längeren Prozedur verfangen, dann - vermute ich - wird MyApp_mouseReleased(oEvt) nicht mehr durchlaufen, ganz egal wie oft ich noch klicke.
Verstehst Du das, oder muss ich das für dich genauer erklären?
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Wie funktioniert _mouseReleased ?

Beitrag von Karolus »

Hallo
Das Problem ist doch daß deine Funktion schon beim ersten Klick aufgerufen wird →einen klick zählt und deshalb 'subSingleclick' aufruft.
Du kannst nur dafür sorgen das die Funktion beim ersten Klick nur False zurückgibt, um dann die Chance zu haben den 2. Klick zu registrieren.
Etwa so:

Code: Alles auswählen

Function MyApp_mouseReleased(oEvt) As Boolean
       Dim Anzahl
       Anzahl = oEvt.ClickCount
       
       if Anzahl = 1 then 
       MyApp_mouseReleased = False
       end if
       if Anzahl = 2 then 
       ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("LabelAnzahl").Label = "ClickCount = " & Anzahl
       mSubForDoubleClick
       end if
       MyApp_mouseReleased = False
    End Function
Damit erfolgt bei Einfachklicks "keine" Reaktion.

Karolus
Zuletzt geändert von Karolus am Do, 24.01.2013 08:16, insgesamt 1-mal geändert.
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Wie funktioniert _mouseReleased ?

Beitrag von balu »

Hallo

@Jonny1

Code: Alles auswählen

Global Anzahl as string, AnzahlAlt as String

[...]

Function MyApp_mouseReleased(oEvt) As Boolean
   Dim  Anzahl 
Am Makroanfang und in der Function deklarierst Du die Variable Anzahl unterschiedlich. Einmal als String und einmal als Variant. Wäre es nicht besser wenn Du das noch mal überarbeitest?
Dannenhöfer hat geschrieben: Globale Variablen werden ebenfalls im Kopfbereich eines Moduls deklariert, sie haben auch nach beenden des Moduls Gültigkeit.
Und auf Grund dessen kann es wohl zu komplikationen kommen. Die Variablen deklaration sollte schon eindeutig sein, denn sonst kann es später zu noch größeren Problemen kommen. Und ja! Mir ist das auch schon passiert.

Dennoch habe ich in das Makro ENDIF eingefügt, um das Restrisiko zu beseitigen. NICHTS hat sich geändert.

Dann habe ich sinnloserweise auch ELSE eingefügt. Und auch da hat sich selbstverständlich NICHTS geändert.
Wo hast Du diese Änderungen vorgenommen?


Generelle Fragen.
Sind die zwei Abfragungen nicht da, dann schreibt das Makro ganz korrekt die richtige Anzahl der Klicks - ob sie nun 1, 2, 3, 4, 5 oder mehr sind
Sehe ich das richtig, das Du mit der CheckBox einen Zähler konstruieren willst?
Oder willst Du nur den doppelklick abfangen?




@Karolus
Du hast in deinem Code ein END IF vergessen. Denn wenn ich deine Function gegen die von Jonny1 tausche, kommt es zu der Fehlermeldung:

"Sub innerhalb einer Prozedur unzulässig"

Setze ich aber END IF an die richtige Stelle, läufts dann auch. Das nur zur Info.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Jonny1
***
Beiträge: 55
Registriert: Mi, 12.01.2011 21:49

Re: Wie funktioniert _mouseReleased ?

Beitrag von Jonny1 »

Den Fehler habe ich gefunden und hier eine funktionierende Version geschrieben:

Code: Alles auswählen

REM  *****  BASIC  *****

Global oDocView As Object
Global oMouseClickHandler As Object

Global Anzahl as long 

Sub RegisterMouseClickHandler
  oDocView = ThisComponent.currentController
  oMouseClickHandler = _
  createUnoListener("MyApp_", "com.sun.star.awt.XMouseClickHandler")
'  writedbginfo oMouseClickHandler
  oDocView.addMouseClickHandler(oMouseClickHandler)
End Sub

Sub UnregisterMouseClickHandler
  on error resume next
  oDocView.removeMouseClickHandler(oMouseClickHandler)
  on error goto 0
End Sub

sub CheckBox1
	Dim LightRed as Long, Green5 as Long, a as Boolean, b as String, c as String, d as Long 	
	LightRed = 16711680
	Green5 = 44544
	a = ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").State
	if a then 
		RegisterMouseClickHandler
		b = "registered"
		c = "Click here to unregister the page."
		d = Green5
	else 
		UnregisterMouseClickHandler
		b = "unregistered"
		c = "Click here to register the page."
		d = LightRed
	end if
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").Label = b
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").helptext = c
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("Check Box 1").backgroundcolor = d
end sub

Sub MyApp_disposing(oEvt)
End Sub

Function MyApp_mousePressed(oEvt) As Boolean
  MyApp_mousePressed = False
End Function

Function MyApp_mouseReleased(oEvt) As Boolean
	Anzahl = oEvt.ClickCount
	ThisComponent.DrawPage.Forms.getByIndex(0).GetByName("LabelAnzahl").Label = "ClickCount = " & Anzahl
	if Anzahl = 1 then VerteilerSub
End Function

sub VerteilerSub
	dim ZeitGewartet as long
	ZeitGewartet = 0
Sprung1:
	wait(300)
	ZeitGewartet = ZeitGewartet + 300
	select case Anzahl
		case 1
			mSubForSingleClick
		case 2
			if ZeitGewartet = 300 then goto Sprung1
			mSubForDoubleClick
		case 3
			if ZeitGewartet < 900 then goto Sprung1
			mSubFuerDreifachesKlicken
		case 4
			if ZeitGewartet < 1200 then goto Sprung1
			mSubFuerVierfachesKlicken
		case 5
			if ZeitGewartet < 1500 then goto Sprung1
			mSubFuerFuenffachesKlicken
		case 6
			if ZeitGewartet < 1800 then goto Sprung1
			mSubFuerSechsfachesKlicken
		case 7
			if ZeitGewartet < 2100 then goto Sprung1
			mSubFuerSiebenfachesKlicken
		case is > 7
			if ZeitGewartet < 2400 then goto Sprung1
			mSubFuerAchtUndMehrfachesKlicken
	end select
end sub

sub mSubForSingleClick
	print "mSubForSingleClick"
end sub

sub mSubForDoubleClick
	print "mSubForDoubleClick"
end sub

sub mSubFuerDreifachesKlicken
	print "mSubFuerDreifachesKlicken"
end sub

sub mSubFuerVierfachesKlicken
	print "mSubFuerVierfachesKlicken"
end sub

sub mSubFuerFuenffachesKlicken
	print "mSubFuerFuenffachesKlicken"
end sub

sub mSubFuerSechsfachesKlicken
	print "mSubFuerSechsfachesKlicken"
end sub

sub mSubFuerSiebenfachesKlicken
	print "mSubFuerSiebenfachesKlicken"
end sub

sub	mSubFuerAchtUndMehrfachesKlicken
	print "mSubFuerAchtUndMehrfachesKlicken"
end sub
Vielen Dank für deine Hilfe, Karolus.

Wenn du aber schreibst:
Du kannst nur dafür sorgen das die Funktion beim ersten Klick nur False zurückgibt
muss ich widersprechen, weil keines meiner Makros die Funktion aufruft, geschweige denn auswertet. Es sind die verborgenen Programmteile - damit meine ich die Programmteile, welche die Hersteller des BASIC-Interpreters geschrieben haben - welche die Funktion "MyApp_mouseReleased(oEvt)" aufrufen. Die Zuweisung:
MyApp_mouseReleased = False
kam zwar auch in meiner Version vor, aber nur deswegen, weil ich sie in einem Beispiel von einem anderen Programmierer gefunden hatte und damals nicht wusste, ob die verborgenen Programmteile sie benötigten oder nicht. Ich habe mir gedacht, daß es nicht so schädlich seine konnte, sie da zu belassen.
Die Anfrage: "if Anzahl = 1" ist auch deswegen zwecklos, weil die Zuweisung
MyApp_mouseReleased = False
ohnehin am Ende der Sub in deiner Version durchgeführt wird.
Nein.
Die Lösung besteht darin, eine Verteiler-Prozedur schon dann aufrufen zu lassen, wenn die verborgenen Programmteile MyApp_mouseReleased das allerersten mal aufrufen.
Rufen die verborgenen Programmteile MyApp_mouseReleased später ein zweites, drittes, ... hundertfaches mal, dann wird keine meiner sichtbaren Prozeduren mehr durch MyApp_mouseReleased aufgerufen. Diese Funktion beschränkt sich dann darauf, die globale Variable Anzahl nach oben zu verändern.

Meine Verteilerprozedur ist es dann, welche Anzahl wiederholt abliest, eventuell ein wenig wartet, dann sie wieder abliest, bis sie sicher ist, dass sie durch MyApp_mouseReleased nicht mehr verändert wird. Dann ruft VerteilerSub die ausfühjrende Prozedur ab, die dem endgültigen Wert von Anzahl entspricht.

In meinem Beispiel habe ich mich auf ein Maximum von siebenfachem Klicken beschränkt, aber könnte auch viel mehr. Einmal habe ich sogar ein 170-faches Klicken bewirkt. Werte natürlich, die in der Praxis kaum von Nutzen sein dürften, die mir aber geholfen haben, die Arbeitsweise der verborgenen Programmteile zu verstehen.

An Balu:

Vielen Dank auch dir, Balu, für deine Hilfe. An der Adresse viewtopic.php?f=18&t=60995 wirst du dich hoffentlich überzeugen können, daß die Hersteller von BASIC für OO sich die Mühe gemacht haben, den Benutzern zu erlauben, ENDIF wegzulassen (ELSE ohnehin), wenn die Ausführung in derselben Zeile der Abfragung geschieht. Heute habe ich gelernt, daß man ohne ENDIF sogar mehrere Anweisungen durchführen kann, wenn man sie durch einen Doppelpunkt trennt und damit man alle in die Zeile der Abfragung stopft. Eine absolut korrekte Verfahrensweise.

Zu deiner Frage:
Am Makroanfang und in der Function deklarierst Du die Variable Anzahl unterschiedlich. Einmal als String und einmal als Variant. Wäre es nicht besser wenn Du das noch mal überarbeitest?
Ja. Für dich wäre es besser gewesen, wenn ich penibler gearbeitet hätte. Für mich wäre es schlechter gewesen, weil mir das Zeit gekostet hätte, die ich nicht zur Verfügung hatte. Es war ohnehin absolut klar, dass es für die Ausführung meiner Makros vollkommen irrelevant war, da damals Anzahl nur durch MyApp_mouseReleased(oEvt) gesetzt und abgefragt wurde und dort war es zwar nicht sehr elegant aber praktisch vollkommen egal, wenn Anzahl auch global deklariert wurde. In der neuen Version wird Anzahl nur als globale Variable definiert und damit ist nicht nur die praktische Wirkung, sondern auch die peniblere Betrachtungsweise befriedigt.

Zu deiner Frage:
Wo hast Du diese Änderungen vorgenommen?
In den Versuchen, die ich deinetwegen gemacht habe, obwohl ich von deren Überflüssigkeit überzeugt war.

Zu der Frage:
Sehe ich das richtig, das Du mit der CheckBox einen Zähler konstruieren willst?
Ich wollte ursprünglich eine Art Transkriptions-Programm schreiben. Man kann Schreibmarken der Art 01h23m51s oder #01:23:51-7# schreiben. Dann klickt man einfach oder doppelt auf die Zeitmarke und ruft man damit VLC an der durch die Zeitmarke angegebenen Stelle ab.

Dadurch, daß man die Wahl zwischen einfachem, doppeltem, dreifachen, etc. Klick hat, hat man auch die Möglichkeit, dem Benutzer die Wahl anzubieten, ob er das Video bis zur nächsten Zeitmarke, bis zum Ende, mit einer kurzen, mittleren oder langen Rückspülung, etc. abspielen will. Es gibt unendliche Möglichkeiten.

Das Transkriptionsprogramm ist seinerseits ein Mittel, um Sozialpsychologische Probleme wie Schimmelpilzwahn, Meldewahn, Zwangsschulwahn, Reptiloidenwahn, etc. zu behandeln.

Wollt ihr mitmachen?
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: [gelöst] Wie funktioniert _mouseReleased ?

Beitrag von Karolus »

Hallo
Das Transkriptionsprogramm ist seinerseits ein Mittel, um Sozialpsychologische Probleme wie Schimmelpilzwahn, Meldewahn, Zwangsschulwahn, Reptiloidenwahn, etc. zu behandeln.

Wollt ihr mitmachen?
Nö! :shock:
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: [gelöst] Wie funktioniert _mouseReleased ?

Beitrag von balu »

Hallo Jonny1,
weil ich sie in einem Beispiel von einem anderen Programmierer gefunden hatte
Kannst ruhig sagen das Du das von Andrew Pitonyak hast.

Heute habe ich gelernt, daß man ohne ENDIF sogar mehrere Anweisungen durchführen kann, wenn man sie durch einen Doppelpunkt trennt und damit man alle in die Zeile der Abfragung stopft. Eine absolut korrekte Verfahrensweise.
Da muss ich dich doch Fragen: Weisst Du was da geschieht? Ist dir die Funktion des Doppelpunktes wirklich eindeutig bewusst?
Ich habe jetzt irgendwie das Gefühl das Du das für dich gar nicht richtig hinterfragst.

Jonny1 hat geschrieben: Zu deiner Frage:
Am Makroanfang und in der Function deklarierst Du die Variable Anzahl unterschiedlich. Einmal als String und einmal als Variant. Wäre es nicht besser wenn Du das noch mal überarbeitest?
Ja. Für dich wäre es besser gewesen, wenn ich penibler gearbeitet hätte. Für mich wäre es schlechter gewesen, weil mir das Zeit gekostet hätte, die ich nicht zur Verfügung hatte.
Ich wollte dich nur auf etwas aufmerksam machen was durchaus einmal zu komplikationen führen kann, wenn man auf solche kleinigkeiten nicht achtet. Und grad die deklaration von Variablen ist ein nicht zu verachtender Stolperstein den man schnell übersehen kann, wenn man auf einer Fehlersuche oder ähnlichem ist.

In der neuen Version wird Anzahl nur als globale Variable definiert und damit ist nicht nur die praktische Wirkung, sondern auch die peniblere Betrachtungsweise befriedigt.
Ist dir der Einsatz von Global deklarierten Variablen bewusst, und weisst Du auch was das für Konsequenzen mit sich führen kann?

Ich wollte ursprünglich eine Art Transkriptions-Programm schreiben.
Kenn ich net, und sagt mir nix.

Das Transkriptionsprogramm ist seinerseits ein Mittel, um Sozialpsychologische Probleme wie Schimmelpilzwahn, Meldewahn, Zwangsschulwahn, Reptiloidenwahn, etc. zu behandeln.

Wollt ihr mitmachen?
Njet.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Antworten