Geschwindigkeit bei Aufbau von Bildschirmmasken

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Koverhage »

Hallo,

leider kommt man ja an die Beiträge aus dem alten Webboard nicht mehr dran.
Folgendes Problem. Die Bildschirmmaske zum Kunden umfasst 10 Tabs, die relativ viel Daten
enthalten. dadurch dauert der (nicht nur gefühlte ) Aufbau und Anzeige relativ lange.
Soweit ich mich erinnere gab es da was, wie man das umgehen bzw. beschleunigen kann.
Kann mir jemand von den Express++ Spezialisten mal einen Tritt in die richtige Richtung
geben ?
Gruß
Klaus
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Wolfgang Ciriack »

Hallo Klaus,
ich denke, das Beispiel in XDemo (Set 5 - MergeGets 2) ist für solche Fälle gedacht.
Viele Grüße
Wolfgang
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Rudolf »

Hallo,
habe auch viele Tabs und komplexe Dialoge, mit der Methode vom Beispiel kann man es wesentlich beschleunigen. Ich verwende es bereits standardmäßig in allen Tabs. Hab nur noch ein paar Probleme mit gotfocus() und lostfocus(). Manchmal werden diese Events nicht richtig registriert.
Grüsse
Rudolf
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Koverhage »

Danke euch beiden. Werde das mal ausprobieren, sieht aber sehr kompliziert aus.
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Tom »

Hallo, Klaus.

Ist aber nicht kompliziert. Du baust die Tabpages im Dialog selbst auf und ihre Elemente erst, wenn die Tabs den Fokus bekommen, und zwar im GOTFOCUS-Codeblock. Über eine Get-/Set-Funktion oder über Variable oder eine Klasseninstanz merkst Du Dir (für jeden Tab), ob das bereits geschehen ist. Die Aufbauprozedur bekommt den Owner (den Dialog) und die allgemeine GetList (z.B. als "aGetList"). Dann erzeugst Du den "Unterdialog" wie gehabt: GetList auf {} initialisieren, Elemente erzeugen. Das DCREAD muss mit den Optionen EXIT und SAVE versehen werden (auf GetOptions verzichten, die erbt der Dialog vom Owner!), als Parent muss (ohne Referenz!) der Owner angegeben werden (also PARENT oOwner). Feddisch. Ans Ende gehört dann "DC_MergeGetLists(aGetList,GetList)". Alle Elemente der "gemergten" Dialoge verhalten sich wie im Dialog direkt erzeugte Elemente. Vorsicht nur bei der Verwendung von lokalen Variablen in der Merge-Prozedur!
Herzlich,
Tom
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Geschwindigkeit bei Aufbau von Bildschirmmasken

Beitrag von Rudolf »

Hallo,
hier ein komplettes Beispiel wie ich es mache. Es sind ein paar spezielle Funktionen dabei die aber leicht nachzumachen sind.
Grüsse
Rudolf



Code: Alles auswählen

function sampledialog(nID,nITab,nMod)
******************************************************************
local getlist := {}
*-------------------- Definition -------------------------
local nMaxTab := 5
local cTitel  := "Kontaktdaten"
local cSel    := "LAG,BAS,KON,KUN"
local cAlias  := "KON",cOrder := "AUSER"
*------------------------------------------------------------
local nLeft := SIZE_X-20,nAbst := 1
local nLine := -1 ,bGotFocus
local bColor,oDialog,cInfo := "",oInfo
local aoTabStatic := array(nMaxTab)
local aTitel      := array(nMaxTab)
local aAlias      := array(nMaxTab)
local aScopeBlock := array(nMaxTab)
local nTab := 1,nRec := 0
local aSel := saveopen(cSel)

private aoMsg       := array(nMaxTab)
private aTabs       := array(nMaxTab)
private aoTabPage   := array(nMaxTab)
private aoBrowse    := array(nMaxTab)

afill(aTabs,.f.)
afill(aTitel,"")

if empty(aSel)
     return .f.
endif

default nID   to 0 // wenn Filter auf ID
default nITab to 0 // wenn Tab init
default nMod  to 0 // Mod: 1=add, 0=edit

select (cAlias)

if nID # 0 // Scope oder direkt positionieren oder Tab 2 für Details sofort öffnen
     (cAlias)->(setorder(cOrder))
     kon->(DC_SETSCOPE(0,nID))
     kon->(DC_SETSCOPE(1,nID))
endif
(cAlias)->(dc_dbgotop())

aTitel[1] := "Tab 1"
aTitel[2] := "Tab 2"
aTitel[3] := "Tab 3"
aTitel[4] := "Tab 4"
aTitel[5] := "Tab 5"

aAlias[1] := "KON"
aAlias[2] := "BAS"
aAlias[3] := "TRA"
aAlias[4] := "INT"
aAlias[5] := "LAG"

aScopeBlock[2] := {||kun->(setorder("NUMMER")),;
                     kun->(DC_SETSCOPE(0,kon->kunde)),;
                     kun->(DC_SETSCOPE(1,kun->nummer)),;
                     kun->(dc_dbgotop()),;
                     dc_getrefresh(aoBrowse[2]),;
                     dc_getrefresh(aoMsg[2])}

//bColor  := {||browcolor(!empty((cAlias)->aktiv))}

*---------------------- Tab 1 ---------------------------------------------------
@  .5,.5 DCTABPAGE aoTabPage[nTab] CAPTION aTitel[nTab] SIZE SIZE_X-.4,SIZE_Y-.4 PREOFFSET 0 POSTOFFSET 95 STATICAREA aoTabStatic[nTab] ;
                 GOTFOCUS  &("{||checkfocus(" + ntrim(nTab) + ",0)}");
                 LOSTFOCUS &("{||checkfocus(" + ntrim(nTab) + ",1)}")

nLeft := SIZE_X-18
nLine := -1

nLine += 1.2;@  nLine,nLeft  DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "Anfang"     BITMAP ID_B1  CONFIG BUCFG1 SIZE 12,1.2   ACTION {||PostAppEvent(xbeP_Keyboard,xbeK_CTRL_PGUP,,aoBrowse[1])} TOOLTIP 'Beginn der Tabelle'
nLine += 1.2;@  nLine,nLeft  DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "Ende"       BITMAP ID_B4  CONFIG BUCFG1 SIZE 12,1.2   ACTION {||PostAppEvent(xbeP_Keyboard,xbeK_CTRL_PGDN,,aoBrowse[1])} TOOLTIP 'Vorhergehender Datensatz'
nLine += 1.2;@  nLine,nLeft  DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "zurück"     BITMAP ID_B2  CONFIG BUCFG1 SIZE 12,1.2   ACTION {||PostAppEvent(xbeP_Keyboard,xbeK_UP,,aoBrowse[1])}        TOOLTIP 'Nächster Datensatz'
nLine += 1.2;@  nLine,nLeft  DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "vor"        BITMAP ID_B3  CONFIG BUCFG1 SIZE 12,1.2   ACTION {||PostAppEvent(xbeP_Keyboard,xbeK_DN,,aoBrowse[1])}        TOOLTIP 'Dateiende'
nLine += .5

nLine += 2;@    nLine,nLeft    DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "ändern"      CONFIG BUCFG1  SIZE nSize,1.2 ACTION {||eg_leer(0,cAlias,aoBrowse[1]),dc_getrefreshb(aoBrowse[1])}   FONT BUTTON_FONT
nLine += 1.2;@  nLine,nLeft    DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "neu"         CONFIG BUCFG1  SIZE nSize,1.2 ACTION {||eg_leer(1,cAlias,aoBrowse[1]),dc_getrefreshb(aoBrowse[1])}   FONT BUTTON_FONT
nLine += 1.2;@  nLine,nLeft    DCPUSHBUTTONXP PARENT aoTabStatic[nTab] CAPTION "löschen"     CONFIG BUCFG1  SIZE nSize,1.2 ACTION {||eg_leer(2,cAlias,aoBrowse[1]),dc_getrefreshb(aoBrowse[1])}   FONT BUTTON_FONT

@ 2.1,.5 DCBROWSE aoBrowse[nTab] PARENT aoTabStatic[nTab] ALIAS aAlias[nTab] SIZE  SIZE_X-22,SIZE_Y-14  PRESENTATION cstat("BROWSEPRES") ID 'BROWSE1' ;
         COLOR {||{GRA_CLR_BLACK,GraMakeRGBColor(cstat("SYS_BROWSECOLOR"))}}  DATALINK {||(cAlias)->(eg_leer(0,cAlias,cAliasaoBrowse[1]))} CURSORMODE XBPBRW_CURSOR_ROW ZEBRA {|lEven|zebra(lEven)}

DCBROWSECOL FIELD (cAlias)->status        WIDTH 2  HEADER "Status"            PARENT aoBrowse[nTab]
DCBROWSECOL FIELD (cAlias)->datum         WIDTH 7  HEADER "Datum"             PARENT aoBrowse[nTab]

*----------------- Tabpage/Browser 2 -------------------------------------------
nTab++
@  0,0 DCTABPAGE aoTabPage[nTab] CAPTION aTitel[nTab] RELATIVE aoTabPage[nTab-1] STATICAREA aoTabStatic[nTab] GOTFOCUS aScopeBlock[2]

@ .5,.5 DCSAY {||DP_KUNNAME} SAYHVCENTER FONT '12.Arial Bold' SAYSIZE SIZE_X - 22,1.4 PARENT aoTabStatic[nTab] COLOR GRA_CLR_YELLOW,GRA_CLR_DARKBLUE object aoMsg[nTab]



@ 2.1,.5 DCBROWSE aoBrowse[nTab] PARENT aoTabStatic[nTab] ALIAS aAlias[2] SIZE  SIZE_X-22,SIZE_Y-6.5 PRESENTATION cstat("BROWSEPRES") //SCOPE

//DCBROWSECOL DATA   {||bmp_leer()}                       WIDTH 1   HEADER "S"           PARENT oBrowse2  TYPE XBPCOL_TYPE_BITMAP // Beispiel Bitmap
DCBROWSECOL FIELD BAS->NUMMER                          WIDTH  7  HEADER 'Nummer'      PARENT oBrowse2
DCBROWSECOL DATA {||substr(BAS->BEZEICHN,1,35)}        WIDTH 25  HEADER 'Bezeichnung' PARENT oBrowse2

nTab++
// --------------- dynamische Tabpage ----------------------------------------------------------
bGotFocus := &("{||checkfocus(" + ntrim(nTab) + ",0),Build_t" + ntrim(nTab) + "(" + ntrim(nTab) + ",GetList)}") // tab 3
@  0,0 DCTABPAGE aoTabPage[nTab] CAPTION aTitel[nTab] RELATIVE aoTabPage[nTab-1] STATICAREA aoTabStatic[nTab] GOTFOCUS bGotFocus

*------------------------------------------------------------
DCREAD GUI fit modal title cTitel eval {||if(nITab # 0,DC_TabActivate(nITab),DC_TabActivate(1))}
saveopen(aSel)
return .t.

static function build_t3(nTab,aGetlist,cAlias)
******************************************************************
local getlist := {}
local getoptions := {}
local nLine := 1
local nLeft := SIZE_X-20
local nsize := 15
local nAbst := 1.2
local nHoch := (SIZE_Y / 3) - 1
if !aTabs[nTab]
     aoTabPage[nTab]:lockUpdate(.t.)
     @ .5,.5 DCSAY {||"dynamischer Tab 3"} SAYHVCENTER FONT '12.Arial Bold' SAYSIZE SIZE_X - 22,1.4 PARENT aoTabStatic[nTab] COLOR GRA_CLR_YELLOW,GRA_CLR_DARKBLUE object aoMsg[nTab]
     @ 2,1 DCSAY "dynamische Tabpage 3 " 0 PARENT aoTabStatic[nTab]




     aoTabPage[nTab]:lockUpdate(.t.)
     DCREAD GUI PARENT aoTabPage[nTab] EXIT  OPTIONS GetOptions SAVE
     DC_MergeGetLists(aGetList,GetList)
     aoTabPage[nTab]:lockUpdate(.f.)
     aoTabPage[nTab]:invalidateRect()
     aTabs[nTab] := .t.
endif
//init_tab(cAlias,aoBrowse[nTab])
aoBrowse[nTab]:gobottom() // ?
SetAppFocus(aoBrowse[nTab])
return .t.

static function checkfocus(n,nMod) // Focus Tabpages prüfen
******************************************************************
static nTab
default nTab to 1
default nMod to 0
if nMod = 0 // gotfocus,
     if n = 2
          //loaddata()
     else
          if nTab = 2  // wenn z.B. letzer Details bearbeitet wurden
               //savedata()
          endif
     endif
elseif nMod = 2 // lostfocus
     if n = 2 // wenn auf Detailseite
          savedata()
     endif
elseif nMod = 3 // wenn exit
     if nTab = 2
          savedata()
     endif
endif
nTab := n // aktuellen Tab speichern
return .t.

static function bmp_leer()
*******************************************************************************
local cRet := BITMAP_LEVEL1
if .t.
    return BITMAP_LEVEL3 // gelb
else
     return BITMAP_LEVEL2 // rot
endif
return BITMAP_LEVEL1   // grün


static function eg_leer(nMod,cAlias,oBrowse)
******************************************************************
local nNeu   := 0,aTmp,lOk := .f.
local nRec   := (cAlias)->(recno())
local cField := "ID"
local cOrder := "ID"
local rRepl  := cAlias + "->" + cField
// 1 = neu, 2 = löschen, 3 = kopieren
if nMod = 1 .or. nMod = 3
     if nMod = 3
          aTMp := (cAlias)->(scatter())
     endif
     nNeu := (cAlias)->(dbf_newkey(cOrder,cField,,.t.)) // Datensatz neu angelegt, Index ID, Feld ID++
     if nNeu = 0
          (cAlias)->(go(nRec))
          return .f.
     endif
     if nMod = 3
          (cAlias)->(gather(aTmp))
          repl &cField with nNeu // wieder korrigieren
     endif
     dc_getrefreshb(oBrowse)
endif
if nMod = 2
     (cAlias)->(del_rec(1,,oBrowse))
     dc_getrefreshb(oBrowse)
     return .t.
endif
if (cAlias)->(rec_lock())
     //@   1,  1 DCSAY "Test"         GET (cAlias)->feldname          SAYSIZE 15



     DCREAD GUI FIT EVAL {|o|SetAppWindow(o)} TITLE "Test" ADDBUTTONS TO lOk
     (cAlias)->(unlock())
     if lOk


     endif
endif
return .t.

static function savedata()
******************************************************************

return .t.
Antworten