Registriert: So Mai 11, 2003 10:36 Beiträge: 285 Wohnort: Oldenburg
Programmiersprache: Object Pascal
Hallo,
ich habe vor einiger Zeit angefangen die Idee der eigenen Scrollbox die ich hier beschrieben habe:
viewtopic.php?t=7669 auch um zu setzten. Nach meinen erstauen habe ich das auch ganz gut hinbekommen.
Es gibt nur noch einen hacken: Es werden alle Objekte gezeichnet, auch die Objekte die gar nicht im Sichtbereich sind.
Ich habe zwei Ziele: Zum ersten, soll die Scrollbox nur die Objekte zeichnen die der User auch wirklich sieht zum Zweiten sollen die Objekte selbst nur den Teil von sich zeichnen die auch Sichtbar sind. Dadruch erhoffe ich mir CPU-Last zu sparen.
Ich habe ein Text Objekt um Text dazustellen, ein Image Objekt um Bilder dazustellen.
Hier mal etwas code für euch:
So Zeichne ich die Objekte. Die Objekte werden einfach nur verschoben. z.b. in den Nichtsichtbereich.
Dadurch entsteht der Effekt, das gescrollt wird:
Um den Maximalen bereich zu ermitteln, suche ich mir einmal das weit entfernteste Objekt in Y und in X Richtung rauß:
Code:
function TPLScrollBox.GetYremotelTop:Integer;
var
i,z:Integer;
begin
z:=0;
for i:=0to fItems.Count-1dobegin
if items[i].top+items[i].Height >=z then z:=items[i].top+items[i].Height;
end;// for i
result:=z;
end;// TPLScrollBox.GetYremotelTop
function TPLScrollBox.GetXHigh:Integer;
var
i,z:Integer;
begin
z:=0;
for i:=0to fItems.Count-1dobegin
if items[i].Left+items[i].Width >=z then z:=items[i].Left+items[i].Width;
end;// for i
result:=z;
end;// TPLScrollBox.GetXHigh
Die SetupScrollBalken Methode sieht so aus:
Code:
procedure TPLScrollBox.SetupScrollBars;
begin
if(HandleAllocated)thenbegin
ScrollH:=ClientHeight;
SV.cbSize:=SizeOf(SV);
SV.fMask:= SIF_POS or SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL ;
SV.nPos:= Scrolly;
SV.nMin:=0;
SV.nMax:= GetYremotelTop;
SV.nPage:= ClientHeight;
SetScrollInfo(Handle, SB_Vert, SV,true);
SH.cbSize:=SizeOf(SH);
SH.fMask:= SIF_POS or SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL;
SH.nPos:= ScrollX;
SH.nMin:=0;
SH.nMax:= GetXHigh;
SH.nPage:= ClientWidth;
SetScrollInfo(Handle, SB_Horz, SH,true);
end;
end;// TPLScrollBox.SetupScrollBars
Zum Schluss hier noch mal der Code für das Zeichnen, des Text Objektes, ich habe noch mehr Objekte, aber das hier sollte reichen, wenn nicht beschreibe ich auch noch die anderen Objekte:
Code:
procedure TPLScrollBoxObjText.Paint;
var
i,px,py:Integer;
begin
inherited Paint;
py:=2; px:=2;
Buffer2.Canvas.Rectangle(0,0,Width,Height);
for i:=0to fLines.Count-1dobegin
Buffer2.Canvas.TextOut(px,py,fLines[i]);
py:=py+Buffer2.Canvas.TextHeight(fLines[i])+3;
if py >=PaintHeight thenbreak;
end;// for i
BitBlt(parent.buffer.Canvas.Handle,
Paintx, PaintY, PaintWidth,PaintHeight,
Buffer2.Canvas.Handle,0,0,SRCCOPY
);
end;// TPLScrollBoxObjText.Paint
Ich hoffe die Beschreibungen und die Einzelnen Code-Stücke helfen euch eine Lösung für mich zu finden. Das währe richtig Toll.
Ich sehe diese Scrollbox als Grundlage für viele viele Weitere Komponenten. Z.B. Währe es für mich ein leichtest diese Komponenten zu erstellen:
ListBox, ListView, TreeView, Memo, RichEdit, Edit, MainMenu, PopupMenu
mit HIlfe dieser ScrollBox.
Weil das Scrollen wahr für mich immer ein Problem. Und mit Hilfe meiner ScrollBox hoffe ich einfach, das Problem für mich und evlt. für andere ein für alle mal zu beseitigen.
Auf anfrage lade ich auch das ganze Projekt hier hoch. So groß ist das auch nicht. Wie ihr ja anhand der Code-Stücke sehen solltet.
Ich habe viel vor mit der ScrollBox ! Ob ich das auch alles Schaffe steht auf ein andere Blatt
_________________ MFG<br> Michael Springwald, <br>
Bitte nur Links in Deutsch, nutze überwiegend Lazarus
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich würde einfach eine einfache Rechtecksprüfung machen: Du nimmst dir ersteinmal das "Sichtfenster". Das heißt, du brauchst die Koordinate, die bei dir oben links ist. Ungescrollt ist die (0|0), wenn du scrollst sollte sich das entsprechend ändern. Dann musst du nurnoch die breite und die höhe deiner Scrollbox haben, abzüglich der Scrollbars. Damit kennst du schonmal den Bereich, der sichtbar sein wird.
Nun prüfst du für jedes Element, ob sein Rechteck (definiert anhand seiner relativen Position und seiner Ausmaße), in dem Rechteck des Sichtfensters liegt. Ist das so, zeichnest du, ansonsten überspringst du dieses Element.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: So Mai 11, 2003 10:36 Beiträge: 285 Wohnort: Oldenburg
Programmiersprache: Object Pascal
Danke für den Vorschlag. Die Idee hatte ich schonmal ausprobiert. Ich weiß nicht genau von wo ich aussehen soll.
Denn ScrolLX und ScrollY können auch negative werte Enhalten.
könntest du evlt. ein kleines Beispiel erstellen ? wie du dir das mit der Recheckes Prüfung vorstellst ?
Im Prinzip weiß ich das, aber mir fehlen die Daten Dazu. Ich dachte einfach ich könnte von ScrollX und ScrollY aussgehen + ClientW und ClientH. Aber das geht ausirgendeinen Grund nicht. Weil die Objekte dann nicht mehr richtig "gescrollt" werden. Aber so hattest du dir das auch vorgestellt oder ?
_________________ MFG<br> Michael Springwald, <br>
Bitte nur Links in Deutsch, nutze überwiegend Lazarus
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Da ich jetzt zu Faul bin, mich durch deinen Code zu wühlen, mach ich ne Skizze. Könnte ne zeit dauern, ich hänge sie dann hier an.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
So, hier die Skizze.
Wenn du noch fragen hast, frag. Ich hoffe aber, dass sie einigermaßen klar ist.
//Edit: Negative Werte sollten überhaupt kein Problem darstellen.
Gruß Lord Horazont
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Aus irgendeinengrund ist jetzt das Scroll Verhalten Falsch. Einige Objekte werden einfach bei 0,0 gezeichnet, wobei die eigentlich ganz anders gezeichnet werden sollen.
Im Anhang findest du zwei Bilder. Das ScrollBox1 Zeigt das Falsche Bild. So soll es nicht aussehn. Das ist jetzt mit der Überprüfung.
Das ScrollBox2 Bild zeigt wie es richtig aussieht ohne Überprüfung !
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
_________________ MFG<br> Michael Springwald, <br>
Bitte nur Links in Deutsch, nutze überwiegend Lazarus
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Was ist r?
Du hast es deklariert, du übergibst es an IntersectRect, aber du füllst es nicht mit werten.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Was passiert denn, wenn du nur die Zeile mit dem If auskommentierst? Wie sah dein Code aus, bevor du ihn so umgebaut hast?
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Ich brauche wie du siehst nur die if Zeile auszukommentieren. Dann geht es prima. Allerdings werden jetzt auch alle Objekte gezeichnet. Was ich ja nicht möchte.
_________________ MFG<br> Michael Springwald, <br>
Bitte nur Links in Deutsch, nutze überwiegend Lazarus
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Nein, da ist noch ein ganz relevanter Unterschied. Du setzt PaintX und PaintY erst nach PaintWidth und PaintHeight, das heißt, PaintWidth und PaintHeight basieren dann auf falschen Daten.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: So Mai 11, 2003 10:36 Beiträge: 285 Wohnort: Oldenburg
Programmiersprache: Object Pascal
Jetzt habe ich es so, immer noch der Selber Fehler wenn wenn die IF Anweisung drin ist. Das letzte Objekt wird über dem Ersten gezeichnet.
Warum auch immer. Das Letzte Objekt soll ja nur gezeichnet werden, wenn ich auch wirklich dahin gescrollt bin und nicht früher !
Registriert: So Mai 11, 2003 10:36 Beiträge: 285 Wohnort: Oldenburg
Programmiersprache: Object Pascal
habe die Ursache gefunden, es liegt nicht an der Paint methode sondern an den Objekten. Die auch eine Paint Methode haben wie:
Code:
// TextObj1.Paint;
TextObj1.scrollbox.SetupScrollBars;
// TextObj1.scrollbox.Refresh;
// TextObj2.Paint;
TextObj2.scrollbox.SetupScrollBars;
// TextObj2.scrollbox.Refresh;
// TextObj3.Paint;
// TextObj3.scrollbox.SetupScrollBars;
// TextObj3.scrollbox.Refresh;
// TextObj4.Paint;
TextObj4.scrollbox.SetupScrollBars;
// TextObj4.scrollbox.Refresh;
Damit ich unterschiedliche Scroll Bereiche unterstützen kann, verwende ich meine eigene ScrollBox dafür.
Ich denke der Fehler liegt hier begraben.
edit: jetzt müsste ich wissen, ob das Objekt gezeichnet werden soll oder nicht und zwar im jeweiligen Objekt. falst die Paint Methode einzeln aufgerufen wird. Was aber nur bei einem Object im Moment sin macht.
_________________ MFG<br> Michael Springwald, <br>
Bitte nur Links in Deutsch, nutze überwiegend Lazarus
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich habe auch einen Fehler in meiner Skizze. Das Rechteck der Komponenten muss nicht unter einbeziehung von ScrollX und ScrollY berechnet werden, das war Quatsch. Weiss garnihct, wie ich drauf gekommen bin.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.