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 ?
Geschwindigkeit bei Aufbau von Bildschirmmasken
Moderator: Moderatoren
- Wolfgang Ciriack
- Der Entwickler von "Deep Thought"
- Beiträge: 2950
- Registriert: Sa, 24. Sep 2005 9:37
- Wohnort: Berlin
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
Re: Geschwindigkeit bei Aufbau von Bildschirmmasken
Hallo Klaus,
ich denke, das Beispiel in XDemo (Set 5 - MergeGets 2) ist für solche Fälle gedacht.
ich denke, das Beispiel in XDemo (Set 5 - MergeGets 2) ist für solche Fälle gedacht.
Viele Grüße
Wolfgang
Wolfgang
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Re: Geschwindigkeit bei Aufbau von Bildschirmmasken
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
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
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Geschwindigkeit bei Aufbau von Bildschirmmasken
Danke euch beiden. Werde das mal ausprobieren, sieht aber sehr kompliziert aus.
Gruß
Klaus
Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Geschwindigkeit bei Aufbau von Bildschirmmasken
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!
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
Tom
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Re: Geschwindigkeit bei Aufbau von Bildschirmmasken
Hallo,
hier ein komplettes Beispiel wie ich es mache. Es sind ein paar spezielle Funktionen dabei die aber leicht nachzumachen sind.
Grüsse
Rudolf
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.
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net