Seite 1 von 2

Focuswechsel übereinanderliegende Dialoge [ERLEDIGT]

Verfasst: Di, 17. Mai 2016 9:08
von Manfred
ich habe ein Problem wenn ich mehrere Dialoge übereinander öffne, dass es dann passieren kann, dass nicht jeder Dialog wieder in den Vordergrund geholt werden kann. Sobald ich es anklicke und wieder loslasse, verschwindet es wieder unter den anderen Dialogen. Die Routine ist immer die gleiche und sollte deshalb m.E. jeden Dialog gleich behandeln. Selbst wenn ich in der Menueleiste in der Cascadenauswahl einen Dialog anklicke, läßt er sich auch nicht auf Dauer in den Vordergrund locken. Wo liegt mein Denkfehler?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:09
von Martin Altmann
Hast Du einen als modal definiert?
Oder vielleicht nicht die :drawingarea als Parent?

Viele Grüße,
Martin

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:18
von Manfred
keines Modal und überall das Hauptfenster als Drawing Area, damit die Dialoge nicht aus dem Hauptbildschirm verschoben werden können.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:25
von brandelh
Wenn du eine MsgBox() öffnest, wird automatisch auf den Dialog geschaltet, der mit SetAppWindow() als Standard definiert wurde.

Bei anderen Dialogen bin ich mir nicht sicher, aber vermutlich ebenso.

Frage sind alle gleichberechtigt ?
Also keiner mit AllwaysOntop ?

Du könntest bei gleichberechtigten Fenstern bestimmen (bei close oder hide oder lost focus), wer als nächstes aktiv werden soll.
Das würde aber nicht dem Windowsstandard entsprechen. Eigentlich solltest du vor dem Aufruf von anderen Fenstern das aktive
(zu dem wieder zurückgesprungen werden soll) mit SetAppWindow() als Hauptfenster markieren, eventuell hast du das aber für ein anderes vorgesehen.

Hier mal ein Beispiel meiner MyMsgBox() Funktion, die den oOwner übergibt und Confirmbox verwendet.
Diese Systemmeldungen zeigen nach dem Schließen immer den oOwner an.

Code: Alles auswählen

*-------------------------------------------------------------
Function MyMsgBox(uText,cTitel,oOwner,nStyle)
   local cText,x,xMax
   DEFAULT nStyle TO XBPMB_WARNING + XBPMB_MOVEABLE
   // XBPMB_QUESTION       Fragezeichen
   // XBPMB_WARNING        Warnung        -> Standard MSGBOX()
   // XBPMB_INFORMATION    Information
   // XBPMB_CRITICAL       Kritische Situation

   // XBPMB_APPMODAL  Confirmbox ist modal in Bezug auf die Xbase++ Anwendung
   // XBPMB_SYSMODAL  Confirmbox ist systemweit modal
   // XBPMB_MOVEABLE  Confirmbox kann verschoben werden

   do case
      case valtype(uText) = "A"                     // reiner Text oder nur debugging
           cText := Var2Char(uText[1])
           xMax  := len(uText)
           for x := 2 to xMax
               cText += chr(13) + Var2Char(uText[x])
           next
      case valtype(uText) = "C"
           cText := uText
      case valtype(uText) = "N"
           cText := ntrim(uText)
      case valtype(uText) = "D"
           cText := ctod(uText)
      otherwise
           cText := "Parameterfehler bei MyMsgBox: "+valtype(uText)+;
                    " statt C, N, D oder A"+chr(13)+;
                    "Bitte diesen Fehler melden."
   endcase
   ConfirmBox(oOwner,cText,cTitel,XBPMB_OK,nStyle)
return NIL

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:30
von Manfred
sie sind alle gleichberechtigt. Was ich aber gerade festgestellt habe ist, wenn ich mehrere Dialoge übereinander aufhabe und dazwischen wechsel, dann kann ich z.B. nicht mehr über das kreuz oben rechts schließen. Nach mehreren Versuchen hin und her, klappt es dann. Dann schließen sich aber die anderen Dialoge, die vorher geschlossen werden sollten auch alle direkt. Alles recht merkwürdig. Ich prüfe gerade, ob ich da irgendeine Regelmäßigkeit entdecken kann, oder ein System.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:35
von brandelh
wir sind wieder im eXpress Forum hatte ich übersehen ...

Normalerweise schaltet ein Fenster seinen Owner wieder in den Vordergrund, wenn es geschlossen wird.

Damit ein Fenster auf das X oben reagiert, muss es auf den close Event reagieren (close Codeblock), hast du das eventuell bei einigen vergessen ?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:39
von Manfred
es sind alles Schablonen, die ich dann nur erweitere. Aber wie ich auch gerade feststellen mußte, sobald ich eines von den Dialogen in den Vordergrund hole,l bzw. zwischen den Dialogen wechsel und dann auf das Kreuz klicke, sind sie nicht mehr zu schließen und auch nicht mehr vernünftig in den Vordergrund zu holen. Beim Anklicken sind sie da und sobald ich die Maus loslasse, werden sie wieder überdeckt. Irgendwas läuft da schief, bzw. habe ich falsch gemacht. Aber wie immer die Frage: Was?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:42
von Tom
Hallo, Manfred.

Du hast "gleichberechtigte" Dialoge, die nicht modal sind. Ich nehme an, dass es z.B. einen Dialog gibt, in dem verschiedene Aktivitäten ausgelöst werden können. Jede davon öffnet einen Dialog, der eben nicht modal ist. Das Problem: Du befindest Dich innerhalb einer Linearität. Es kann innerhalb des Codes nur eine Eventschleife geben, die gerade reagiert - oder eben nicht. In diesem Zusammenhang stellt sich dann auch die Frage, wie der auslösende Dialog (re)agieren soll.

Eigentlich macht man das so:

1. Die "unabhängigen" Dialoge laufen in eigenen Threads. Allerdings verlieren sie dadurch auch die Anbindung an den aufrufenden Dialog - es ist nicht mehr sichergestellt, dass sich beides auf die gleichen Daten bezieht.

2. Die aufgerufenen Dialoge sind nicht unabhängig, sondern modal. Der Fokus der Anwendung geht auf sie über, und sie verlieren ihn erst wieder, wenn man die Dialoge beendet. Dann kann es jeweils immer nur einen davon geben; alles andere im gleichen Thread ist stillgelegt. So arbeitet man, wenn man sich z.B. in einer Kundenverwaltung befindet und etwa Kontaktdaten bearbeitet.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:46
von Manfred
Hi Tom,

so ist alles aufgebaut.

Code: Alles auswählen

//------------------------------------------------------------------------------
          DCGETOPTIONS;
                BORDER XBPDLG_SIZEBORDER;
                  BUSY "Feiertagverwaltung wird gestartet, Daten werden geladen";
             COLORGETS {{ GRA_CLR_BLACK, GRA_CLR_CYAN },{ GRA_CLR_BLACK, GRA_CLR_WHITE }};
                  EVAL {|o| SetAppWindow(o) };                                  /* muß hier stehen für das Cascading*/
           NOESCAPEKEY;
           NOMAXBUTTON;
           NOMINBUTTON;
                 PIXEL;
            SAYOPTIONS XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT;
          TOOLTIPCOLOR GRA_CLR_BLACK, GRA_CLR_YELLOW;
           WINDOWWIDTH oDialogZusatz:nFensterBreite;
          WINDOWHEIGHT oDialogZusatz:nFensterHoehe

          DCREAD GUI;
           APPWINDOW oSysPara:oHauptDialog:drawingArea;
                EVAL {|| oSysPara:erzeugeHilfe(oDialog,"Feiertage.htm"),;
                         oDialogZusatz:oFeiertag:schalteEditControls(.F.),;
                         oDialogZusatz:oPbSpeichern:cargo[3] := "AUS",;
                         oDialogZusatz:oPbAbbruch:cargo[3]   := "AUS",;
                         SetAppFocus(oDialogZusatz:oBrowse);
                     };
             OPTIONS GetOptions;
              PARENT @oDialog;
               TITLE "Feiertageverwaltung " + oDialogZusatz:cVersion
           RETURN

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 9:49
von Tom
Genau. Das ist nicht modal. Sollte es aber vermutlich sein.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 10:11
von Manfred
soll ich denn dann ein MODAL einfügen? Das habe ich mal gemacht, jetzt klappt gar nichts mehr.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 10:32
von Manfred
eigentlich sollte es so klappen, wie die Demo, die Roger beigefügt hat. Alles kann man parallel öffnen und immer wieder anklicken.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 10:36
von Rudolf
Hallo Manfred,
schau Dir die READGUI Optionen OWNER und APPWINDOW an. Bei APPWINDOW kann der Child Dialog nur innerhalb des Hauptfensters bewegt werden, gleich wie GETOPTION LOCKWINDOWTOOWNER.
Momentan hab ich ein Problem mit OWNER, wenn ich im Testprogramm den Child Dialog aufmache und dann zurück ins Hauptfenster clicke und wieder zurück ins Child Fenster, bleibt der Eingabefocus beim Hauptfenster. Erst wenn man ausserhalb des Dialogs z.B. den Desktop anclickt, funktioniert es wieder normal. ALWAYSONTOP funktioniert im Testprogramm auch nicht, keine Ahnung wieso.
Habe es Roger bereits gepostet.
Grüße
Rudolf

Code: Alles auswählen

#include "dcdialog.ch"

* ------------

PROC appsys ; return

* ------------

Procedure Main()
******************************************************************
LOCAL GetList[0], GetOptions, oMenuBar, oMenuFile, oDlg ,nVar := 0
local aData := {},oBrowse1
aadd(aData,{1,"Col1","Col2","Col2"})
aadd(aData,{2,"Col1","Col2","Col2"})
aadd(aData,{3,"Col1","Col2","Col2"})

DCMENUBAR oMenuBar

DCSUBMENU oMenuFile PROMPT 'Menue' PARENT oMenuBar
DCMENUITEM 'Child Window with OWNER'  PARENT oMenuFile ACTION {|| Win(1,oDlg) }
DCMENUITEM 'Child Window with APPWINDOW' PARENT oMenuFile ACTION {|| Win(2,oDlg) }
DCMENUITEM 'Child Window MODAL' PARENT oMenuFile ACTION {|| Win3(3,oDlg) }
DCMENUITEM 'Child Window ALWAYSONTOP' PARENT oMenuFile ACTION {|| Win(4,oDlg) }
DCMENUITEM 'Exit' PARENT oMenuFile ACTION {|| PostAppEvent( xbeP_Quit ) }


@ 1,1 DcSay 'This is the main Window' SAYFONT '9.Arial Bold' SAYSIZE 40,1
@ 2,1 DcSay 'Get' get nVar pict "999" saysize 0
@ 3,1 DCBROWSE oBrowse1 DATA aData SIZE  100,10

DCBROWSECOL ELEMENT 1  WIDTH 4    HEADER "ID"    PARENT oBrowse1
DCBROWSECOL ELEMENT 2  WIDTH 4    HEADER "Col1"  PARENT oBrowse1
DCBROWSECOL ELEMENT 3  WIDTH 4    HEADER "Col2"  PARENT oBrowse1
DCBROWSECOL ELEMENT 4  WIDTH 4    HEADER "Col2"  PARENT oBrowse1

DCREAD GUI FIT TITLE 'Window test' OPTIONS GetOptions Parent @oDlg SETAPPWINDOW

RETURN




Procedure Win(nMod,xoDlg)
******************************************************************
LOCAL GetList:={}, oDlg1,aData := {},oBrowse1 ,nVar := 0
aadd(aData,{1,"Col1","Col2","Col2"})
aadd(aData,{2,"Col1","Col2","Col2"})
aadd(aData,{3,"Col1","Col2","Col2"})

@ 1,1 DcSay 'This is Child Window 1' SAYFONT '9.Arial Bold' SAYSIZE 40,1
@ 2,1 DcSay 'Get' get nVar pict "999" saysize 0
@ 3,1 DCBROWSE oBrowse1 DATA aData SIZE  35,10

DCBROWSECOL ELEMENT 1  WIDTH 4    HEADER "ID"    PARENT oBrowse1
DCBROWSECOL ELEMENT 2  WIDTH 4    HEADER "Col1"  PARENT oBrowse1
DCBROWSECOL ELEMENT 3  WIDTH 4    HEADER "Col2"  PARENT oBrowse1
DCBROWSECOL ELEMENT 4  WIDTH 4    HEADER "Col2"  PARENT oBrowse1

do case
     case nMod = 1
          DCREAD GUI FIT TITLE 'OWNER' OWNER xoDlg Parent @oDlg1
     case nMod = 2
          DCREAD GUI FIT TITLE 'APPWINDOW' APPWINDOW xoDlg Parent @oDlg1
     case nMod = 3
          DCREAD GUI FIT TITLE 'MODAL' MODAL Parent @oDlg1
     case nMod = 4
          DCGETOPTIONS ALWAYSONTOP
          DCREAD GUI FIT TITLE 'Window ALWAYSONTOP'  //Parent @oDlg1

endcase
Return

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 10:51
von Tom
ALWAYSONTOP sollte man nur mit nichtmodalen Fenstern machen, die in eigenen Threads laufen. Das ist für Statusfenster und ähnliches gedacht, nicht für den täglichen Gebrauch. Es bezieht sich immer auf die gesamte Applikation. Es kann auch immer nur ein Fenster geben, das diese Eigenschaft hat.

SetAppWindow(oDlg) gehört nicht in die GetOptions, sondern ins DCREAD GUI.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 11:03
von Manfred
ok, vielleicht hilft das ja weiter?

Ich starte das Programm. Dann öffne ich einen Dialog. Öffne den nächsten Dialog. Wechsel zurück in den ersten Dialog, klicke dort irgendwo rein und versuche dann über den Cascading Button in der Menueleiste (Window) den 2.Dialog zu aktivieren. Der blinkt nur kurz auf und verschwindet dann wieder im Hintergrund. Also keine Chance. Jetzt klicke ich auf das Kreuz im 1.Dialog, es passiert nichts. Nun minimiere ich den 1.Dialog und der 2.ist sichtbar. Dort klicke ich auf das Kreuz und es gehen beide zu. Das kann man auch mit mehreren Dialogen machen. Es gehen dann alle Dialoge auf einmal zu, die vorher beendet werden sollten, aber nicht reagiert haben. Sieht mir verdammt nach einem Eventschleifenproblem aus. Ich dachte man könnte mehrere DCREADs übereinander machen?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 11:44
von Tom
Du musst die Dialoge in eigenen Threads starten.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 12:20
von brandelh
Tom hat geschrieben:Du musst die Dialoge in eigenen Threads starten.
dann muss das aber mit Express zusammen hängen, meine Dialoge funktionieren einwandfrei solange der owner stimmt und sind alle in einem Thread mit einer gemeinsamen Event Schleife.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 12:24
von Manfred
ich denke mal, jedes DCREAD macht eine eigene Eventschleife auf!?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 12:31
von Tom
Es hängt davon ab, was Du erreichen willst. Jedes DCREAD stoppt quasi den Thread/das Programm an dieser Stelle - und erst wenn es beendet wird, geht es zurück ans aufrufende Fenster, weil jeder Dialog seine eigene Eventloop hat. Deshalb hat Modalität an solchen Stellen durchaus Sinn. Es gibt aber auch in eXpress++ Techniken, um anders zu arbeiten. Die einfachste und eleganteste besteht jedoch darin, mit Multithreading zu arbeiten - dann sind alle Dialoge komplett unabhängig voneinander.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 12:34
von Manfred
ich werde das jetzt mal ausprobieren. Man kann ja nur lernen dadurch. Wobei ich das von Anfang schon in Betracht gezogen hatte, aber irgendwie war ich der Meinung es würde mit express++ anders laufen. Das war aber anscheinend ein Irrtum.

Ich sehe gerade, in der Demo arbeitet Roger auch mit Threads. Sowas Dummes, das ich das nicht früher geprüft habe.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 12:57
von Manfred
jetzt stehe ich hier wieder vor der Wand.

Code: Alles auswählen

ACTION {|o|o := Thread():new(), o:start({|| tagesdienste(oMenu1,o)})}
bei o:start wird alles akzeptiert, aber der Parameter wird angemeckert?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 13:02
von Tom
"o" ist im Codeblock nicht bekannt. Wozu brauchst Du dort auch das Threadobjekt?

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 13:05
von Manfred
warum ich das als Parameter übergeben will? Nun, irgendwo muß ich den Thread ja wieder beenden. Und das wollte ich dann in der aufgerufenen Funktion am Ende machen.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 13:07
von Tom
Die aufgerufene Funktion - in der sich der Dialog befindet - beendet sich durch ihr RETURN. Dann verschwindet auch der Thread.

Re: Focuswechsel übereinanderliegende Dialoge

Verfasst: Di, 17. Mai 2016 13:09
von Manfred
hm, das wagte ich nicht zu hoffen. Ich hatte nur geprüft, ob der Thread erzeugt wird. Dann werde ich das mal nachschauen im Debugger.