Scrollbars

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Scrollbars

Beitrag von andreas »

Hallo Leute,

ich habe im Programm ein Fenster, wo die ganzen Xbaseparts dynamisch eingefügt werden. Da ich mehr Objekte im Fenster haben möchte, als da rein passen, habe ich die Scrollbars

Code: Alles auswählen

::drawingarea:scrollbars := XBP_SCROLLBAR_VERT
freigeschaltet.

Mein Problem ist, dass ich manuell mit der Maus die Fenstergrösse ändern muss, damit die Scrollbars erscheinen. Erst dann kann ich im Fenster scrollen und die anderen Objekte sehen.
Was kann das sein und wie könnte ich es lösen?
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

hast du diese VOR dem Create oder danach freigeschaltet ?
Wenn danach, dann muss man vielleicht ein configure nachschieben ?
Gruß
Hubert
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Hubert,
brandelh hat geschrieben:Hallo,

hast du diese VOR dem Create oder danach freigeschaltet ?
Wenn danach, dann muss man vielleicht ein configure nachschieben ?
ich habe es in der Init-Methode freigeschaltet. Danach wird create ausgeführt und erst dann die restlichen Objekte eingefügt.
Aber irgendwie merkt XBase die Änderungen nicht, bis mit der Maus die Fenstergrösse geändert wird. Erst dann erscheint die Leiste.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Scrollbars

Beitrag von AUGE_OHR »

hi,
andreas hat geschrieben: Mein Problem ist, dass ich manuell mit der Maus die Fenstergrösse
ändern muss, damit die Scrollbars erscheinen. Erst dann kann ich
im Fenster scrollen und die anderen Objekte sehen.
Was kann das sein und wie könnte ich es lösen?
Eine direkte Antwort hab ich nicht, aber :
Frage : was für einen "Border" benutzt du ?
(es geht wohl nicht mit jedem "Border")

ansonsten würde ich ihm ein :

Code: Alles auswählen

PostAppEvent(xbeP_Resize,oDlg:CurrentSize(),oDlg:CurrentSize(),oDlg)
schicken um sich "selbst" zu "resize"n

gruss by OHR
Jimmy
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Jimmy,

ich habe es ausprobiert aber es hat nicht geholfen. Ich muss immer noch die Fenstergrösse manuell ändern, damit die Leisten erscheinen.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
andreas hat geschrieben: ich habe es ausprobiert aber es hat nicht geholfen. Ich muss immer noch die Fenstergrösse manuell ändern, damit die Leisten erscheinen.
em ... hast du den ein oDlg:resize := {|aOld,aNew|...} Codeblock ?

gruss by OHR
Jimmy
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Andreas,
Ich muss immer noch die Fenstergrösse manuell ändern, damit die Leisten erscheinen.
:setSize() bringt's -- wenn die Größe dabei tatsächlich geändert wird.

Code: Alles auswählen

aSize := oDlg:currentSize()
   
oDlg:setSize( { aSize[1]+1, aSize[2]+1 } )
oDlg:setSize( aSize )

Viele Grüße,
Günter
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

AUGE_OHR hat geschrieben:hi,

em ... hast du den ein oDlg:resize := {|aOld,aNew|...} Codeblock ?

gruss by OHR
Jimmy
Nein, habe ich nicht.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Günter Beyes hat geschrieben:Hallo Andreas,

:setSize() bringt's -- wenn die Größe dabei tatsächlich geändert wird.

Code: Alles auswählen

aSize := oDlg:currentSize()
   
oDlg:setSize( { aSize[1]+1, aSize[2]+1 } )
oDlg:setSize( aSize )

Viele Grüße,
Günter
Hallo Günter,

dein Vorschlag funktioniert auch nicht.
Gruß,

Andreas
VIP der XUG Osnabrück
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Andreas,

Hmm. Das folgende funktioniert hier jedenfalls.

Code: Alles auswählen

#include "Appevent.ch"
#include "Xbp.ch"
#include "common.ch"

PROCEDURE Main
   LOCAL nEvent := 0, mp1, mp2, oXbp
   LOCAL oDlg

   oDlg := CreateDialog()
   oDlg:show()
   setappwindow( oDlg )
   setappfocus( oDlg )
   
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO

RETURN
   
PROC AppSys() ; return
PROC DBESys() ; return


FUNCTION CreateDialog()
   LOCAL oDlg, oSle, oXbp, aPos, aSize
   LOCAL nXsize := 240
   LOCAL nYsize := 180

   aSize := AppDesktop():currentSize()

   aPos  := { ( aSize[1]-nXsize )/2, ( aSize[2]-nYsize ) / 2 }

   oDlg          := XbpDialog():new( AppDesktop(),, aPos, {nXsize,nYsize}, , FALSE )
   oDlg:title    := "Standard-Dialog"
   oDlg:drawingArea:scrollbars := XBP_SCROLLBAR_HORIZ+XBP_SCROLLBAR_VERT
   oDlg:taskList  := .T.
   oDlg:create()


   aSize := oDlg:drawingArea:currentSize()

   aPos := { 12, ( aSize[2] - 20 ) / 2 }
   oSle := XbpSle():new( oDlg:drawingArea,, aPos, { aSize[1] - 24, 20 } )
   oSle:TabStop  := .T.
   oSle:create()

   aPos          := { ( aSize[1]-72 ) / 2, 12 }
   oXbp          := XbpPushbutton():new( oDlg:drawingArea, , aPos, {72,24} )
   oXbp:caption  := "OK"
   oXbp:TabStop  := .T.
   oXbp:activate := {|| PostAppEvent( xbeP_Close,,, oDlg ) }
   oXbp:create()

   oXbp          := XbpPushbutton():new( oDlg:drawingArea, , { 300, aPos[2] }, {72,24} )
   oXbp:caption  := "Tut nix"
   oXbp:TabStop  := .T.
   oXbp:create()

   aSize := oDlg:currentSize()
   
   oDlg:setSize( { aSize[1]+1, aSize[2]+1 } )
   oDlg:setSize( aSize )

RETURN oDlg
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Günter,

Entschuldigung!
Ich galube, dass mich Manfred schon angesteckt hat. :D
Da bei mir in diesem Modul alles dynamisch erzeugt wird, habe ich an der falschen Stelle den Testcode eingebaut.
Erst nach dem Zusammenbau eines kleinen Beispiels (änlich deinem) habe ich festgestellt, dass dein Vorschlag funktioniert und habe angefangen, Fehler zu suchen.

Noch eine Frage dazu.
Die Scrollbalken sind jetzt da!
Beim Anzeigen des Fensters werden aber die Objekte versteckt, die sich oben befinden. Es muss aber gerade umgekehrt sein.
Gibt es dafür vielleicht auch eine Lösung?
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21199
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hä?

Angesteckt? Womit? Bitte näher erläutern..... :boxing:
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Andreas,

das müßte hiermit zu beheben sein:

Code: Alles auswählen

#define WM_VSCROLL 0x0115
#define SB_TOP 6

SendMessageA(  oDlg:drawingArea:getHWND(), WM_VSCROLL, SB_TOP, 0 )

DLLFUNCTION SendMessageA( hWnd, nMsg, wparam, lparam ) ;
USING STDCALL FROM user32.dll
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Günter,

Danke für deine Hilfe.
Alles funktioniert so, wie ich es mir vorgestellt habe.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14655
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Nur mal 'ne Vermutung: Geht das vielleicht auch, indem man zwangsweise den Fokus auf einen Xbp ganz oben setzt? Um den dann aktiv anzuzeigen muß doch das Formular nach oben gescrollt werden, oder?

Jan
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Jan hat geschrieben:Nur mal 'ne Vermutung: Geht das vielleicht auch, indem man zwangsweise den Fokus auf einen Xbp ganz oben setzt? Um den dann aktiv anzuzeigen muß doch das Formular nach oben gescrollt werden, oder?

Jan
Hallo Jan,

1. nein, das funktioniert nicht. Ich habe es gerade extra nach deinem Beitrag ausprobiert.
2. Ich müsste mir eine Funktion schreiben, die mir den Objekt zurückgibt, der als erster oben ist, da ich es nicht weiss. Ich schreibe ein Modul für die Anwendung, wo der Kunde die Fenster- und Datenbankverwaltung (Felder) selbst übernehmen möchte. Deswegen kann ich nicht wissen, was wo steht.

Die Lösung von Günter ist schon die Beste in diesem Fall.
Gruß,

Andreas
VIP der XUG Osnabrück
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Jan,
Jan hat geschrieben:Geht das vielleicht auch, indem man zwangsweise den Fokus auf einen Xbp ganz oben setzt? Um den dann aktiv anzuzeigen muß doch das Formular nach oben gescrollt werden, oder?


leider passiert das nicht von alleine. Dazu müßte man in :setInputFocus eine Routine unterbringen, die das Scrollen implementiert.

Viele Grüße,
Günter
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14655
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Beitrag von Jan »

Naja, war auch nur eine Idee. Ich hatte gehofft, daß Xbase das Element mit Fokus immer im Sichtbereich des Formulars platziert, und zur Not das Formular so scrollt, das dieses Element dann eben sichtbar ist.

Jan
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Günter,

ich habe gerade einen komischen Effekt entdeckt.
Wenn alle Objekte ins Fenster reinpassen, Scrollbalken aktiviert wurden und deine API-Funktion zum Scrollen nach oben verwendet wird, dann verschwinden alle Objekte aus dem Fenster.
Gruß,

Andreas
VIP der XUG Osnabrück
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Andreas,

Jau, das ist leider reproduzierbar. Aber dem läßt sich abhelfen.

Viele Grüße,
Günter

Code: Alles auswählen

IF ! AllChildrenOnScreen( oDlg:drawingArea )
	   aSize := oDlg:currentSize()
	   
	   oDlg:setSize( { aSize[1]+1, aSize[2]+1 } )
	   oDlg:setSize( aSize )
	   SendMessageA(  oDlg:drawingArea:getHWND(), WM_VSCROLL, SB_TOP, 0 )
ENDIF

FUNCTION AllChildrenOnScreen( oParent )

LOCAL lOK := TRUE
LOCAL aChildren := oParent:childList()
LOCAL i, aPos, aSize
LOCAL aParentSize := oParent:currentSize()

FOR i := 1 TO len( aChildren )
   aPos  := aChildren[i]:currentPos()
   IF aPos[1] < 0 .or. aPos[2] < 0
      lOK := FALSE
      EXIT
   ENDIF	  
   aSize := aChildren[i]:currentSize()
   IF aPos[1] + aSize[1] > aParentSize[1] .or. ;
      aPos[2] + aSize[2] > aParentSize[2]
	  
      lOK := FALSE
      EXIT
   ENDIF
NEXT

RETURN lOK
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Günter,

jetzt funktioniert alles richtig. Bis jetzt habe ich keine Fehler mehr entdecken können.
Deine Vorschläge habe ich in eine Funktion vereint:

Code: Alles auswählen

#define WM_VSCROLL 0x0115
#define SB_TOP 6

DLLFUNCTION SendMessageA( hWnd, nMsg, wparam, lparam ) ;
	USING STDCALL FROM user32.dll

**Scrollbalken im Fenster nach Oben scrollen.
**Überprüfen, ob alle Objekte ins Fenster passen, wenn nicht dann nach Oben scrollen
FUNCTION ScrollTop( oDlg )
	LOCAL lOK := TRUE
	LOCAL aChildren := oDlg:drawingarea:childList()
	LOCAL i, aPos, aSize
	LOCAL aParentSize := oDlg:drawingarea:currentSize()

	FOR i := 1 TO len( aChildren )
		aPos  := aChildren[i]:currentPos()
		IF aPos[1] < 0 .or. aPos[2] < 0
			lOK := FALSE
			EXIT
		ENDIF
		aSize := aChildren[i]:currentSize()
		IF aPos[1] + aSize[1] > aParentSize[1] .or. ;
				aPos[2] + aSize[2] > aParentSize[2]
			lOK := FALSE
			EXIT
		ENDIF
	NEXT

	IF ! lOk
		aSize := oDlg:currentSize()
		oDlg:setSize( { aSize[1]+1, aSize[2]+1 } )
		oDlg:setSize( aSize )
		SendMessageA(  oDlg:drawingArea:getHWND(), WM_VSCROLL, SB_TOP, 0 )
	ENDIF

RETURN nil
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Ich habe hier noch eine Kleinigkeit!

Gibt es bei einem Fenster die Möglichkeit auf Scrollrad der Maus zu reagieren und Drawingarea zu scrollen und wenn ja, wie kann ich es lösen?
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
andreas hat geschrieben: Gibt es bei einem Fenster die Möglichkeit auf Scrollrad der Maus zu reagieren und Drawingarea zu scrollen und wenn ja, wie kann ich es lösen?
grundsätzlich geht das ja über "o:wheel()" welche den Event
xbeM_Wheel erzeugt.

Code: Alles auswählen

oDlg:DrawingArea:wheel      := {|aPos,aWheel,obj| DlgWheel (aWheel,aoChild,aoDisplay)  }
nun leite ich das o:wheel auf dem Scrollbar um :

Code: Alles auswählen

PROCEDURE DlgWheel(aWheel,aoChild,aoDisplay)

   IF aWheel[2] < 0
      aoChild[CH_BAR]:setData( aoChild[CH_BAR]:getData()+1 )
      Scroll2bar( aoChild[CH_BAR]:getData(), XBPSB_NEXTPOS, aoChild[CH_WMP], aoChild[CH_BAR], aoDisplay[PA_POSI], aoChild[CH_STATBAR], aoChild[CH_STATBAR]:oLauf)
   ELSE
      aoChild[CH_BAR]:setData( aoChild[CH_BAR]:getData()-1 )
      Scroll2bar( aoChild[CH_BAR]:getData(), XBPSB_PREVPOS, aoChild[CH_WMP], aoChild[CH_BAR], aoDisplay[PA_POSI], aoChild[CH_STATBAR], aoChild[CH_STATBAR]:oLauf)
   ENDIF
RETURN
ob das "richtig" ist weiss ich nicht, aber es funktionert.
nun noch die Function Scroll2bar()

Code: Alles auswählen

FUNCTION  Scroll2bar( nScrlPos,nCommand, ...)
...
DO CASE
   CASE nCommand == XBPSB_ENDTRACK              // must be 1st (!)
   CASE nCommand == XBPSB_PREVPOS
...
   CASE nCommand == XBPSB_NEXTPOS
...
   CASE nCommand == XBPSB_PREVPAGE
   CASE nCommand == XBPSB_NEXTPAGE
   CASE nCommand == XBPSB_SLIDERTRACK
...
   CASE nCommand == XBPSB_ENDSCROLL
ENDCASE
RETURN NIL
nun muss du "nur" noch die Stellen "_PREVPOS / _NEXTPOS" sowie
"XBPSB_SLIDERTRACK" füllen mit deiner "Action".

gruss by OHR
Jimmy
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Hallo Jimmy,

auf die wheel()-Methode bin ich auch schon gekommen und zum Testen eingebaut. Nur ich fine keine Veränderungen an der Position von Drawingarea, wenn ich die vorher manuell gescrollt habe.
Wie kann ich diese Änderungen feststellen?
Wie bekomme ich es zum scrollen und wie kann ich den sichtbaren bereich ermitteln und ändern?
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Woher kommen die Parameter aoChild, aoDisplay?
Gruß,

Andreas
VIP der XUG Osnabrück
Antworten