Menü-Tastatureingaben machen das System instabil

Auf dem Weg von Clipper, FoxPro u.ä. nach Xbase++

Moderator: Moderatoren

Antworten
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

Menü-Tastatureingaben machen das System instabil

Beitrag von Dieter »

Hallo,

ich bin dabei eine Applikation, die komplett im xbpCrt-Fenster läuft, so umzuschreiben, dass ein xbpDlg-Fenster mit einem Menüsystem xbpCrt-Fenster aufrufen, welche in der DrawingArea des xbpDlg-Fensters liegen. Alles funktioniert prima, solange man das Menü mit der Maus bedient. Wird das Menüsystem per Tastatur (Alt+Buchstabe) aufgerufen, dann friert die Applikation nach dem 2. Aufruf eines Menüpunktes ein. Im Debugger-Modus funktionieren mehrere Menüaufrufe per Tastatur fehlerfrei. Woran kann dieses merkwürdige Verhalten liegen? :?:
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
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:

Beitrag von brandelh »

Hi,

zeig uns doch mal den Code von deinem Menü und von deiner Event-Schleife . Wie hast du denn die Short-Cuts eingebunden ?
Gruß
Hubert
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

Beitrag von Dieter »

Hi Hubert.

Hier der Code:

// Event loop in der Main-Procedure
nEvent := 0 // Event loop
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbp, 0)
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO


PROCEDURE AppSys
LOCAL oDlg, aPos[2], aSize, nHeight:=600, nWidth := 1015, oMenu, oMenuBar

// Größe vom DeskTop feststellen
// um Anwendungsfenster zu zentrieren
aSize := SetAppWindow():currentSize()

aPos[1] := Int( (aSize[1]-nWidth ) / 2 )
aPos[2] := Int( (aSize[2]-nHeight) / 2 )

// Anwendungsfenster erzeugen (application window)
oDlg := XbpDialog():new()

// Hintergrundfarbe für Anzeigebereich
oDlg:drawingArea:SetColorBG( GRA_CLR_PALEGRAY )
// Rahmentyp einstellen
oDlg:border := XBPDLG_RAISEDBORDERTHICK
oDlg:close := {|| session_ende()}
oDlg:icon := 1
oDlg:titleBar := .T.
oDlg:minButton := .T.
oDlg:maxButton := .T.
oDlg:maxSize :={nWidth,nHeight}
oDlg:tasklist := .T.
oDlg:sysMenu := .T.
oDlg:drawingArea:ClipChildren := .T.
oDlg:create(AppDesktop() ,, aPos, {nWidth, nHeight},, .F. )
// XbpMenubar im Dialog erzeugen
oMenuBar := oDlg:menuBar()

oMenu:=SubMenuNew(oMenuBar,"~Belege")
oMenu:addItem( { "~Belegbearbeitung", {|| teil1() } } )
oMenu:addItem( { "~Lösche Beleg", {|| pt61() } } )
oMenu:addItem( { "~Projektbelege suchen", {|| such4() } } )
oMenu:addItem( { "~Firmenbelege suchen", {|| such5() } } )
oMenuBar:addItem( { oMenu, NIL } )

// usw


RootWindow(oDlg)
RETURN
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
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

Beitrag von AUGE_OHR »

hi.
Dieter hat geschrieben: Hier der Code:
RootWindow(oDlg)
RETURN
wenn du XbpCrt() "Fenster" benutzt musst du ausser SetAppFocus() auch
SetAppWindow() benutzten um zum XbpDialog() zu kommen.

Wenn du im Debugger bis musst du ja per ALT-TAB wieder zur Xbase++
Application wechseln und führst dadurch ein SetAppWindow() aus.
gruss by OHR
Jimmy
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

Beitrag von Dieter »

Hi Jimmy,

du hast folgendes geschrieben:

Code: Alles auswählen

wenn du XbpCrt() "Fenster" benutzt musst du ausser SetAppFocus() auch
SetAppWindow() benutzten um zum XbpDialog() zu kommen.
Du hast vollkommen recht! Ich habe vor der Event-Schleife in der Main-Procedure folgende Zeilen stehen:

Code: Alles auswählen

oXbp:=RootWindow()
oXbp:SetTitle("FI-Datenbank "+man->name)
oXbp:show()
SetAppWindow(oXbp)
SetAppFocus(oXbp)
Die Funktion RootWindow() habe ich aus dem Alaska-Source übernommen:

Code: Alles auswählen

/*
 * Routine zur Abfrage des Anwendungsfensters
 */
FUNCTION RootWindow( oDlg )
   STATIC soDialog
   IF PCount() > 0
      soDialog := oDlg
   ENDIF
RETURN soDialog
Die Funktion teil1() die ein CRT-Fenster aufruft sieht wie folgt aus:

Code: Alles auswählen

Function teil1()
// Belege bearbeiten
LOCAL n,i,oCrt,oParent := RootWindow():DrawingArea
PRIVATE neuanlage,gespeichert,maske_verlassen,b[25],s[25],getlist:={ },;
     titel:=man->name
PRIVATE b_loesch
ALTD()
//RootWindow():Disable()  // darf nicht, sonst funktioniert das Get-system nicht mehr
oCrt := XbpCrt():new(oParent,,,25,80,"Belegbearbeitung")
oCrt:titleBar := .F.
oCrt:closeAble := .F.
oCrt:sysMenu := .F.
//oCrt:close := {|| CrtDestroy()}
oCrt:create()
SetAppWindow(oCrt)
SetMouse( .T. )
oCrt:show()
SetAppFocus(oCrt)
farbe()
CLEAR SCREEN
IF .NOT. sicherheit(3)
  SetAppWindow(RootWindow())
  RETURN NIL
ENDIF
bearbeite ("Belegbearbeitung "+man->name,;
          "fin","eine Beleg",6,.F.,"einen Beleg",;
          {|| STR(fin->beleg_nr,6)+STR(fin->baust_nr,6)+SPACE(1)+;
            LEFT(b_dbseek("fir",2,fin->firmen_nr,"firmen_nam"),24)+;
            SPACE(1)+DTOC(fin->rg_datum)+SPACE(1)+DTOC(fin->valuta)+;
            TRANSFORM(fin->betrag,"@E 999,999,999.99")},;
          {|| akt->(DBGOBOTTOM() ) , FIELDPUT(6,akt->nr),;
              FIELDPUT(7,akt->mwst_proz),;
              FIELDPUT(17,CTOD("01.01.2150")),;
              FIELDPUT(22,"N");
          },;
          {|| beleg_maske() },;
          .F.;
          )
SetAppWindow(RootWindow())
RETURN NIL
Wie gesagt: Mit der Mausbedienung funktioniert der Aufruf des Crt-Fensters. Nach dem Schließen des Crt-Fenster (geschieht in der Funktion bearbeite() durch Drücken der ESC-Taste), kann ich das Crt-Fenster wieder aufrufen usw. usw.
Sobald aber das Menü mit der Tastatur durch ALT-B das CRT-Fenster aufruft ( dies funktioniert noch!) friert das System nach einem erneuten Menüzugriff ein.
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
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

Beitrag von Dieter »

Hallo,

:D :D

Des Rätsels Lösung ist wohl, dass jedes von einem xbpDlg-Fenster aufgerufene xbpCrt-Fenster eine titlebar hat, die closeable sein muß!

Deshalb ist fogendes unbedingt notwendig:

Code: Alles auswählen

oCrt := XbpCrt():new(oParent,,,25,80,"Belegbearbeitung")
oCrt:titleBar := .T.
oCrt:closeAble := .T.
oCrt:sysMenu := .T.
Damit das Crt-Fenster mit der Maus und der Tastatur (ESC) geschlossen werden kann habe ich folgende Zeilen im Wartezustand des Crt-Fensters programmiert:

Code: Alles auswählen

      DO CASE
         //CASE LASTKEY() == K_ESC  // alter Clipper-Code
         CASE LastAppEvent() == xbeK_ESC .OR. LastAppEvent() == xbeP_Close
              oCrt:destroy()
              RETURN NIL
Interessant ist, dass man keinen oCrt:close Codeblock benötigt!
Ich freue mich, dass ich einen riesen Schritt bei der Migration meiner Vio-Programme in Richtung Gui gemacht habe und danke für euer Interesse. :) :)
Viele Grüße

Dieter

Was man nicht versteht, besitzt man nicht.
Antworten