Focus Verlust bei Wechsel zu anderem Programm

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
im Forum gibt es einen Beitrag "Focus Verlust bei Wechsel zu anderem Programm". Den habe ich mir gründlich durchgelesen und habe ihn aber nicht verstanden. Gibt es auch eine leichtere Version dazu?
Meine Problem:
In einem CRT Fenster habe ich ein Objekt mit einer Klasse, in einer Methode wird ein xbpdialog Fenster und diverse Buttons erstellt und in einer 2. Methode mit einem xbpbrowse die Daten angezeigt. Das funktioniert.

Code: Alles auswählen

oLFZEingabe:=ArrayBrowse():New(       ,       , {210,15} , {942,460} ,     ,          ,Daten, Fensterueberschrift, abuttons):Create()

DO WHILE nEvent <> xbeP_Close
  nEvent := AppEvent( @mp1, @mp2, @oxbp )
?setAppWindow()             // dient nur zum Testen
?setAppFocus()
?seconds()
  do case
    case nEvent =  xbe_None // dies wird ausgeführt wenn die Zeit in appevent überschritten ist
*					z.B. Daten alle 2 Minuten neu auslesen
    case nEvent =  xbeP_Keyboard
      do case
        case mp1 = xbeK_ESC .or. (mp1 = asc("e") .or. mp1 = asc("E")) // immer Konstanten aus appevent.ch nutzen, wenn möglich
	oLFZEingabe:destroy()
	setAppWindow ( oCrt )
	exit
	case mp1 ......
	..........
        otherwise
          oxbp:HandleEvent ( nEvent, mp1, mp2 )
    endcase
enddo
Führe ich das Programm aus, so ist CRT das Anwendungsfenster und der xbpbrowse hat den Focus. Wechsele ich mit ALT TAB zu einem anderen Programm und wieder zurück, dann hat das CRT Fenster den Focus und nicht mehr xbpbrowse. Ich habe dann versucht mit setappwindows (oLFZEingabe) oder setappWindows(oLFZEingabe:BrowseFenster) das Objektfenster als Anwendungsfenster zu bestimmen, so wie es in der Hilfe zu setappWindows auch gemacht wird. Leider gab das immer nur Fehlermeldungen. Im Prinzip ein ähnliches Problem wie beim anderen Beitrag.
Ich mach das so ähnlich, wie Jimmy das beschrieben hat. Beim Sprung in ein XBPart wird der Name des Parts in eine Variable geschrieben. Wenn dann das Programm wieder den Fokus bekommt, dann wird der SetInputFocus-Slot mit SetAppFocus(XbPartInDerVariablen) aufgerufen. Klappt einwandfrei.
Ab hier war es für mich in dem anderen Beitrag nicht mehr verständlich.

mfg
Wolfgang
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von ramses »

Hallo Saul

hast du beim Anlegen der Objekte (XBP....) die Angaben für oParent und oOwner korrekt gesetzt?

Cu Carlo
Valar Morghulis

Gruss Carlo
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


mit diesem Problem habe ich mich vor einiger Zeit auch herumgeschlagen, allerdings in einem reinen GUI Programm. Ich nehme jedoch an, dass die Problemursache die gleiche ist.

Windows stellt nur "rudimentäre" Funktionen zur Verfügung, den Rest müssen die Programmierer machen.

Mein Ansatz ist es, für jedes Xbase Part ein eigenes abzuleiten, und gerade auch die XbpDialog() Klasse um einige Funktionalität zu erweitern. Bei jedem SetFocus Event wird im XbpDialog Parent festgehalten, welche Xbase Part betroffen ist. Nach einem Alt-Tab zu einem anderen Fenster erfolgt ja wieder ein Alt-Tab (oder Mausklick), und dabei gibt es ein SetFocus Event für den XbpDialog. Dieses Event fange ich ab und setze dann den Focus aus das letzte Xbase Part, das den Focus erhielt.

Seitdem funktioniert das bei mir.

Beispiele:

Code: Alles auswählen

CLASS MyXbpDialog FROM XbpDialog
   EXPORTED:
   VAR LastElementWithFocus
   METHOD handleEvent
ENDCLASS

METHOD MyXbpDialog:handleEvent(nEvent, mp1, mp2)
   DO CASE
   CASE nEvent = xbeP_SetInputFocus
      IF self:LastElementWithFocus <> NIL
         SetAppFocus(self:LastElementWithFocus)
         RETU(self)
      ENDIF
   OTHERWISE
   ENDCASE
   self:XbpDialog:handleEvent(nEvent, mp1, mp2)
RETURN (Self)
Wenn :handleEvent für das XbpDialog() Element ausgeführt wird, prüfte ich, ob es einen Eintrag in :lastElementWithFocus gab, und wenn ja, bekommt dieses Element den Fokus.

Code: Alles auswählen

CLASS MyXbpCheckBox FROM XbpCheckBox
   EXPORTED:
   VAR DataLinkName
   VAR ChainSeq
   VAR PartParent
   METHOD create
   METHOD handleEvent
ENDCLASS

METHOD MyXbpCheckBox:create(oParentExt, oOwner, aPos, aSize, aPresParam, lVisible)
   Local cClassName
   Local oParent

   IF oParentExt == NIL
      oParent := self:setParent()
   ELSE
      oParent := oParentExt
   ENDIF
   WHILE .T.
      cClassName := oParent:className()
      IF cClassName == "MyXbpDialog"
         self:PartParent := oParent
         EXIT
      ENDIF
      oParent := oParent:setParent()
   END
   self:XbpCheckBox:create(oParentExt, oOwner, aPos, aSize, aPresParam, lVisible)
RETURN (Self)
Beim Erstellen des Xbase Parts gehe ich die Hierarchie nach oben durch, bis ich ein MyXbpDialog() Element finde, und trage dieses als :PartParent ein, damit später der Zugriff ohne den Suchvorgang erfolgen kann.

Code: Alles auswählen

METHOD MyXbpCheckBox:handleEvent(nEvent, mp1, mp2)
   DO CASE
   CASE nEvent = xbeP_SetInputFocus
      IF self:PartParent <> NIL
         self:PartParent:LastElementWithFocus := self
      ENDIF
   CASE nEvent = xbeP_KillInputFocus
   OTHERWISE
   ENDCASE
   self:XbpCheckBox:handleEvent(nEvent, mp1, mp2)
RETURN (Self)
Erhält das Xbase Part den Focus, trägt es im :LastElementWithFocus seines :PartParent eine Referenz auf sich selbst ein: "Hey, Alter, ich bin dran!"

In meinen Programmen verwende ich einfach weiter XbpDialog() und die normalen Xbase Parts, füge aber eine .CH Datei ein, die folgende Anweisungen enthält:

Code: Alles auswählen

#TRANSLATE XbpActiveXControl() => MyXbpActiveXControl()
#TRANSLATE XbpBrowse()         => MyXbpBrowse()
#TRANSLATE XbpCheckBox()       => MyXbpCheckBox()
#TRANSLATE XbpComboBox()       => MyXbpComboBox()
#TRANSLATE XbpDialog()         => MyXbpDialog()
#TRANSLATE XbpListBox()        => MyXbpListBox()
#TRANSLATE XbpMLE()            => MyXbpMLE()
#TRANSLATE XbpPushButton()     => MyXbpPushButton()
#TRANSLATE XbpRadioButton()    => MyXbpRadioButton()
#TRANSLATE XbpSLE()            => MyXbpSLE()
#TRANSLATE XbpSpinButton()     => MyXbpSpinButton()
#TRANSLATE Thread()            => MyThread()
Und das funktioniert (bisher ohne Probleme).


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Danke,
das muss ich erstmal durcharbeiten.

mfg
Wolfgang
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von Tom »

So kann man es machen, aber etwas pfiffiger und eleganter ist es, das im (zentralen) Handler zu erledigen - schließlich hat man dort das Event und Zugriff auf das entsprechende Objekt. Wenn man es - wie hier gezeigt - direkt in eigenen Klassen erledigt, empfiehlt es sich, eine "Super"-Klasse für alle XbParts zu schaffen, die (u.a.) im HandleEvent-Slot dieses Ereignis abfängt, statt jede Klasse im Slot darauf reagieren zu lassen.
Herzlich,
Tom
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Tom -


danke für Deinen Hinweis auf die Super-Klasse. Da ich allerdings normalerweise mit mehreren Threads arbeite, gibt's keinen zentralen Handler, und mit diesem Ansatz bleiben die Event-Loops auch recht klein, da die SetFocus Events direkt beim Objekt und nicht im Event-Loop verarbeitet werden.

Oder habe ich da etwas missverstanden?


Gruss,

Georg
Zuletzt geändert von georg am Do, 27. Sep 2012 9:53, insgesamt 1-mal geändert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Wenn ich das alles bisher richtig begriffen habe, setze ich mit setfocus das xbpart welches den Eingabefokus hat.
Was veranlast denn das Programm bei Alt+Tab und wieder zurück den Focus zu ändern?

Code: Alles auswählen

DO WHILE nEvent <> xbeP_Close
  nEvent := AppEvent( @mp1, @mp2, @oxbp )
  do case
  case nEvent =  xbe_None // dies wird ausgeführt wenn die Zeit in appevent überschritten ist
*					z.B. Daten alle 2 Minuten neu auslesen
  case nEvent =  xbeP_Keyboard
    do case
    case mp1 = xbeK_ESC .or. (mp1 = asc("e") .or. mp1 = asc("E")) 
      oAuswahl:destroy()
      exit
    case nfilterein=1 .and. (sprache="GERMAN" .and. chr(mp1)$"cC") .or. (sprache<>"GERMAN" .and. chr(minkey)$"cC")
.......
enddo
Tastaturbefehle nimmt da Programm an beim Zurückkommen. Also hängen tut das Programm nicht. Kann man das mit einfachen Worten beschreiben was da passiert?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


wenn der Fokus z.B. durch Alt-Tab verloren geht und wiederkommt, dann wird ein xbeP_SetInputFocus an den XbpDialog() gesendet. Dieses Event fange ich ab und prüfe in der Instanzvariablen LastElementWithFocus, ob da was drin steht (ist normalerweise der Fall). Dann bekommt diese Objekt den Focus.

Die Tatsache, dass die Xbase Laufzeitumgebung den Focus auf das Programmfenster, und nicht das letzte aktive Objekt legt, ärgert mich schon. Aber wahrscheinlich ist das eben "Windows-like".


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von Dieter »

Hallo Georg,

Die Instanzvariable PartParent ist meiner Meinung nach für die Wiederherstellung des Focus eines xbase-Parts nicht erforderlich. Das letzte aktive xbp liegt doch immer in SetAppWindow(). Somit funktioniert auch:

Code: Alles auswählen

Method MyXbpCheckBox:handleEvent(nEvent,mp1,mp2)
	DO CASE
  	CASE nEvent = xbeP_SetInputFocus
			/* nicht notwendig
      IF self:PartParent <> NIL
         self:PartParent:LastElementWithFocus := self
      ENDIF*/
			SetAppWindow():LastElementWithFocus := SELF
   	CASE nEvent = xbeP_KillInputFocus
  OTHERWISE
  ENDCASE
  self:MyXbpCheckBox:handleEvent(nEvent, mp1, mp2)
RETURN SELF
Somit kann man auch auf die Überladung der :create()-Methoden der xbase-Parts verzichten.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von brandelh »

Hi,

ich meine es gibt genau einen Ort um sich das aktuell aktive Control zu merken und das ist bei MDI jedes Dialogfenster selbst.
Wenn man allerdings mehrere Tabs anbietet und es dort auch noch will, muss man diese Controls bei dem TAB anlegen.
Das in einer Anwendung aktive MDI Fenster sollte automatisch aktiv sein, wenn nicht, muss man dieses bei der Anwendung (bzw. dem obersten Fenster) hinterlegen.

Man könnte auch eine Funktion erstellen, die Fenster und Control als Objekte erhält, aber ich ziehe meine Klassen vor.
Und es gibt Controls, die keinen Focus bekommen sollen ! Z.B. Drucker Button ;-)

Beispiel wie man es per Funktion machen könnte:

SetFocusArray( oWin, oCon ) // wenn beides übergeben wird static Array sehen ob es schon da ist und eindeutig speichern.
SetFocusArray( oWin ) // wenn nur das Fenster übergeben wird, dann das dazugehörige Control zurückgeben.
SetFocusArray( ) // so das aktive oWin ...
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Guten Morgen,


und danke! an Dieter und Hubert für ihre Gedanken.

Auf den ersten Blick war Dieter's Überlegung schon recht praktisch, aber ich denke, wir kommen hier auch an die Grenze zur persönlichen Einschätzung, d.h. wie wir als Programmierer wollen, dass sich das Programm verhält.

Nehmen wir an, wir haben ein Programmfenster, oDlg, sowie zwei MDI-Fenster, oMDI1 und oMD2. In oMDI1 war oSLE3 im Foku, als oMDI2 geöffnet wurde. Dort ist jetzt oCheck5 im Fokus. Der Anwender wechselt in ein anderes Programm und minimiert das Programm und klickt jetzt auf oMDI1. Dann würde - nach Dieter's Modell - der Fokus auf oCheck5 in oMDI2 gehen. Der Anwender aber wollte in oMDI1 weiterarbeiten.

Um einem solchen Vorgang zu begegnen, braucht es die Information im jeweiligen Fenster, das angeklickt werden kann.

Ich muss mir das aber erst mal in einem kleinen Testprogramm ansehen.


Gruss,

Georg
Zuletzt geändert von georg am Mo, 24. Sep 2012 8:19, insgesamt 1-mal geändert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Guten Morgen,
zwischendurch muß ich mal eine Frage zu den Grundlagen stellen, die ich jetzt erst richtig zu verstehen lerne.

Code: Alles auswählen

DO WHILE nEvent <> xbeP_Close
  nEvent := AppEvent( @mp1, @mp2, @oxbp )
  ?nEvent
  ?nevent=xbeM_RbClick     // nur zur Probe ob Rechtsclick etwas auslöst
  ?seconds()                       // damit man bei gleichen Zahlenwerten unterscheiden kann ob überhaupt etwas passiert.
Enddo
Georgs Ausführungen haben mich auf etwas aufmerksam gemacht. Ich habe mir mal ein Fenster gebaut in dem mir nEvent angezeigt wird. Ich war überrascht, was da passierte. Sobald ich die Maus über das Fenster zog oder eine Taste drücke passiert etwas, aber nur solange das Programm sichtbar ist. Wechsele ich mit Alt Tab auf ein anderes Programm und bewege dort in dem Fenster die Maus passiert nichts.
Ich nehme an, dass das xbase Programm auf Übergaben vom Betriebssystem wartet, diese aber nur bekommt wenn das Programmfenster in Benutzung ist oder ich mit der Maus über das Fenster, selbst wenn es im Hintergund liegt, fahre. Bei Alt Tab passiert auch etwas.
Mit fiel auf, dass je nach Aktion die Do While Schleife verschieden oft durchlaufen wird und oftmals der Zahlenwert der Gleiche ist. Woher kommt das und wozu dient das?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


Windows nimmt alle Events auf und leitet sie an die betroffenen Programme weiter, wobei normalerweise nur das Programm, das gerade den Fokus hat, auch Events erhält. (Wobei ich vermute, dass z.B. Timer-Events auch hochkommen können, habe damit aber keine Erfahrung.)

Wenn Du also mit Alt-Tab zu einem anderen Programm wechselst, dann erzeugt die Mausbewegung dort Events, aber nicht mehr in Deinem Programm, da ja der Fokus woanders ist.

Eine Mausbewegung wird jedesmal den gleichen Zahlenwert erzeugen, wobei ich die Granularität nicht kenne, die Windows zugrunde legt, könnte mir jedoch vorstellen, dass ein Event generiert wird, sobald sich die Position in Pixel ändert. Wndows weiss ja nicht, was das Programm aus dieser Information macht, vielleicht wird ja eine Aktion im Programm ausgelöst, wenn die Maus eine bestimmte Pixelposition erreicht.

Das gilt analog für alle anderen Events.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
mit der Maus das wäre mir einleutend je nach Anzahl der überstreiften Pixel. Drücke ich aber 1 x die Cursor down Taste, so wird die Schleife 3 mal durchlaufen. Das hat mich ein wenig gewundert.

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


bei mir sind es zwei Events:

65576
1048580

Wenn man in der AppEvent.CH nachschaut, findet man 65576 recht schnell: xbeK_DOWN, das ist "Pfeil nach unten" Taste.

1.048.580 ist dagegen schwieriger. xbeB_Event hat den Wert 1.048.576, die Differenz ist 4:

Code: Alles auswählen

#define xbeP_Keyboard                  (004 + xbeB_Event)
Allerdings habe ich als Musterprogramm ein XbpCRT-Programm gewählt.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von AUGE_OHR »

saul hat geschrieben:In einem CRT Fenster habe ich ein Objekt mit einer Klasse, in einer Methode wird ein xbpdialog Fenster und diverse Buttons erstellt und in einer 2. Methode mit einem xbpbrowse die Daten angezeigt. Das funktioniert.
ich kann nur noch einmal betonen das es viel leichter wäre wenn dein "Main" ein XbpDialog "Fenster" wäre ...
saul hat geschrieben:
Ich mach das so ähnlich, wie Jimmy das beschrieben hat. Beim Sprung in ein XBPart wird der Name des Parts in eine Variable geschrieben. Wenn dann das Programm wieder den Fokus bekommt, dann wird der SetInputFocus-Slot mit SetAppFocus(XbPartInDerVariablen) aufgerufen. Klappt einwandfrei.
Ab hier war es für mich in dem anderen Beitrag nicht mehr verständlich.
du verwendest ein CRT "Fenster" als "Main".
aus dem "Main" Fenster startest du ein XbpBrowse als neues "Fenster"

wenn du nun in eine andere Application mit ALT-TAB wechselst und zurück
muss deine Application darauf reagieren. hierfür gibt es die Callback Slots

:killDisplayFocus := {| uNIL1, uNIL2, self | ... }
:setDisplayFocus := {| uNIL1, uNIL2, self | ... }

sowie

:killInputFocus := {| uNIL1, uNIL2, self | ... }
:setInputFocus := {| uNIL1, uNIL2, self | ... }

die ersten beiden mit "Display" sind für "Fenster" gedacht
die beiden anderen für die Child, also XbParts.

wenn ein "Fenster" den Focus verliert ( "kill") muss ich mir bei "mehreren
Fenstern" merken was das "letzte" war.

bekommt die MDI Application den Focus dann ist es die "Main".
wenn man MDI Childs hat muss man nacheinander den Focus
durchgehen bis zum "letzten" was "on-top" der Z-Achse liegt.



in in deiner Hybrid Application hast du nun aber 2 "Fenster" statt
ein "Main" mit einem Child "Fenster" ...
woher soll also Windows nun "wissen" was es machen soll ... ?

mit ALT-TAB schaltest du zwischen Application um und nicht "Fenster"
du landest also in der "Main" und mit oMain:setDisplayFocus muss du
nun per SetAppWindow(oBrowse) zu einem Browse "Fenster" weiterleiten ...



mein Vorschlag war ja nun das du mit einem XbpDialog als "Main"
anfängst und in einem vCRT Object, welches sich auf der oMain:drawingarea
befindet, deinen alten Cl*pper Code laufen läst.

die oMain:drawingarea ist dann auch für alle XbParts der Parent und
folgen damit den Windows Regeln.

p.s. schon mal überlegt dein Konzept zu ändern und mit einem Browse anzufangen
und dann in eine (oder mehrere MDI) Detail Maske(n) zu gelangen ?
gruss by OHR
Jimmy
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
ich habe das Beispiel vom Georg übernommen und habe MyxbpCheckBox aber bei mir durch MyxbpSLE ersetzt. Weitere zwei mal habe ich diesen Code kopiert und jeweils MyxbpCheckBox durch MyxbpBrowse und xbpPushbutton ersetzt.

Code: Alles auswählen

METHOD MyXbpSLE:create(oParentExt, oOwner, aPos, aSize, aPresParam, lVisible)
   Local cClassName
   Local oParent

   IF oParentExt == NIL                                       ///// oParentExt ist NIL bei mir
      oParent := self:setParent()                           ///// hier wird reingesprungen
   ELSE
      oParent := oParentExt
   ENDIF
   WHILE .T.
      cClassName := oParent:className()              /////   hier gibt es die Fehlermeldung
      IF cClassName == "MyXbpDialog"
         self:PartParent := oParent
         EXIT
      ENDIF
      oParent := oParent:setParent()
   END
   self:XbpSLE:create(oParentExt, oOwner, aPos, aSize, aPresParam, lVisible)
RETURN (Self)
Leider gibt es bei der Ausführung eine Fehlermeldung:
Beschreibung: Parameter hat falschen Typ
Operation: classname

oParent:setParent() ergibt "Arraybrowse"
oParent:className() ergibt "xbpIWindows"

Arraybrowse ist ein von mir erstelltes Objekt. Dort wird mittels xbpdialog ein Fenster erzeugt, xbpbutton mehrere Buttons erzeugt, xbpbrowse ein Fenster mit Daten angezeigt und wird aufgerufen:

oLFZEingabe:=ArrayBrowse():New( , , opos , osize , , ,awelchespalten, Fensterueberschrift, abuttons, aArray, Fensterueberschrift2):Create()

Wenn ich im xbpbrowse mit Alt Tab verlasse und wieder mit ALT Tab zurückkomme, so muss ich erst mit der Maus auf die xbpbrowse Fläche klicken. Also steht beim Verlassen mit Alt Tab das Programm auf xbpbrowse.
Wenn ich xbpsle in meinem Programm ausklammere, so kommt der gleiche Fehler bei der Klasse myxbpPushButton an der gleichen Stelle.

Was kann das Problem sein?

Was passiert In der Do While Schleife? Wie wird die Schleife denn wieder verlassen wenn cClassName nicht MyxbpDialog ist? Es wird doch nichts in der Schleife verändert oder?
Georg:
Beim Erstellen des Xbase Parts gehe ich die Hierarchie nach oben durch, bis ich ein MyXbpDialog() Element finde, und trage dieses als :PartParent ein, damit später der Zugriff ohne den Suchvorgang erfolgen kann.
Wie geht das Programm da von oben nach unten durch?

Danke

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


etwa so:

Code: Alles auswählen

oParent := oXbp:setParent()
WHILE .T.
   IF oParent:className() = MyXbpDialog()
      EXIT
   ENDIF
   oParent := oParent:setParent()
NEXT
Nach der Schleife enthält oParent die Referenz auf MyXbpDialog().

Wichtig: hier ist jetzt keine Fehlerprüfung drin, z.B. für den Fall, dass kein MyXbpDialog() verwendet wurde. In diesem Fall gibt es irgendwann einen Abbruch - oder eine Endlosschleife, ich habe es noch nicht ausprobiert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
genau das habe ich nicht verstanden.

Code: Alles auswählen

while .t.
  ** hier wir etwas geprüft oder sonst was
  skip
  if geprüft o.K.
    exit
  endif
end
In meinem Beispiel wird einen Datensatz weiter gesprungen. Somit hat sich für "geprüft" irgend etwas verändert was den Ausstieg aus der Schleife bewirken könnte.
In Deinem While sehe ich nichts was sich da verändern würde oder läuft da etwas im Hintergrund ab?

Hast Du eine Idee zu der Fehlermeldung?

mfg
Wolfgang
Dieter
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 237
Registriert: Do, 14. Aug 2008 14:59
Wohnort: Straelen
Hat sich bedankt: 2 Mal
Danksagung erhalten: 3 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von Dieter »

Hallo Wolfgang,

Code: Alles auswählen

cClassName := oParent:className()              /////   hier gibt es die Fehlermeldung
oParent ist doch die DrawingArea der xbpDialog-Klasse
Du schreibst selber:
oParent:className() ergibt "xbpIWindows"
Da aber
oParent:setParent() ergibt "Arraybrowse"
ist hier wohl der Fehler, da
oParent:setParent() xbpDialog ergeben müsste!
Dein ArrayBrowse sollte doch in der DrawingArea der xbpDialog-Klasse liegen. Schau doch mal welchen Parent dein ArrayBrowse hat.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Guten Morgen, Wolfgang -


es gibt da eine Art Hierarchie, die etwa so aussehen könnte:

Code: Alles auswählen

Windows-Desktop
+-> MyXbpDialog
    +-> MyXbpStatic
        +-> MyXbpSLE
Wenn Du davon ausgehst, dass Dein Programm eine Referenz auf MyXbpSLE erhält, dann gilt:

MyXbpSLE:setParent() = MyXbpStatic
MyXbpStatic:setPareant() = MyXbpDialog

Was in einer normalen Schleife der Zähler ist, wird hier durch das :setParent() bewirkt, nämlich der Zugriff auf das nächsthöhere Element in der Hierarchie, und wenn es das nicht ist, dann gehen wir eben noch einen Schritt weiter nach oben.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
Georg, hast Du eine Idee wegen der Fehlermeldung?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


eventuell ist entweder "self" oder oParentExt kein Xbase-Part. Wenn Du z.B. (falsche Parameterfolge wäre ein Grund) an dieser Position einen String übergibst, versuchst Du, :className() für einen String abzurufen, und das geht nicht.

Anders kann ich die Fehlermeldung derzeit nicht interpretieren.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von saul »

Hallo,
beim Starten des Programes richte ich ein CRT Fenster ein

Code: Alles auswählen

PROCEDURE AppSys()
  oCrt := XbpCrt():New ( NIL, NIL, aPos, DEF_ROWS, DEF_COLS )
  ......
  SetAppWindow ( oCrt )
return 
setAppwindows() bringt "xbpCrt"
Dann habe ich eine Klasse (ArrayBrowse) eingerichtet mit xbpdialog, xbpSLE, xbpbutton und xbpBrowse. Diese rufe ich auf mit:

Code: Alles auswählen

oLFZEingabe:=ArrayBrowse():New(  , , opos     , osize ,     ,           ,awelchespalten, Fensterueberschrift, abuttons, aArray, Fensterueberschrift2):Create()

Code: Alles auswählen

METHOD ArrayBrowse:init( oParent, oOwner, aPos, aSize, aPP, lVisible, welcheSpaltendaten, Fensterueberschrift, buttons, Arrayinhalt, Fensterueberschrift2 )

  setAppwindows() bringt "xbpCrt"

  ::BrowseFenster:init( oParent, oOwner, aPos, aSize, aPP, .F. , ::aSpaltendaten, Fensterueberschrift, buttons, Fensterueberschrift2)
Return
Nachstehend wird nun das Fenster erstellt mit

Code: Alles auswählen

METHOD BrowseFenster:init( oParent, oOwner, aPos, aSize, aPP, lVisible , aSpaltendaten, Fensterueberschrift,buttons, Fensterueberschrift2) 
  
  setAppwindows() bringt "xbpCrt"

  ::XbpDialog:init( , oOwner, aPos, aSize, aPP, lVisible )
Return
Ich kann mir vorstellen, dass mein Problem was mit Parent und Owner zu tun hat. Deine Do while leicht umgebaut

Code: Alles auswählen

   DO WHILE .T.
?oParent:className()
inkey(2)
      cClassName := oParent:className()
      IF cClassName == "MyXbpDialog"
         self:PartParent := oParent
         EXIT
      ENDIF
      oParent := oParent:setParent()
   ENDDO
?oParent:className() ergibt
xbpIWindow
ArrayBrowse
xbpCrt
xbpIWindow
dann kommt die Fehlermeldung. Ich nehme an ich bin an der Decke angekommen ohne auf MyxbpDialog gestossen zu sein.

Ich habe aus den Beispielen von xbase das Programm EBrowse genommen da dies an meine Bedürfnisse am besten herankam und habe das Stück für Stück umgebaut.
Da gab es bisher noch keine Probleme mit Parent und Owner.
Die Hilfe schreibt zwar in Fenster und Beziehungen von der Wichtigkeit mir fällt es mal wieder schwer die einzelnen Fragmente der Hilfe zu einem Programm zusammenzubauen. Wo kann ich da etwas nachlesen?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2825
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Focus Verlust bei Wechsel zu anderem Programm

Beitrag von georg »

Hallo, Wolfgang -


das Beispiel funktioniert ja nur dann, wenn Du auch in der Hierarchie ein MyXbpDialog() Objekt erzeugst und verwendest.

Du Einstieg ist ein XbpCRT() Objekt, also bleibt Dir nichts anderes übrig, als ein MyXbpCRT abzuleiten und die entsprechenden Änderungen an dieser Klasse vorzunehmen, und dann in Deiner Schleife auf MyXbpCRT abzufragen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Antworten