ScrollBox, Objekt auf Objekt plazieren



  • Uuuups!!!

    Da siehst Du noch durch? 😉

    Das sind ja verschachtelte Familienverhaeltnisse (Parent- maessig) 😕

    Ich denke, Du musst Dich dabei strikt an Koordinaten- Bezug vom Panel halten - das ist Parent beider Images.
    Alle Umrechnungen (ScreenToClient und ClientToScreen) mussen ueber Panel-> laufen - das ist der einzige gemeinsame (exakte) Bezug!

    Die Lage vom Panel haengt von BEIDEN SCROLLBOX- ScrollBar Positionen ab!

    Wozu liegt eine ScrollBox in einer Anderen??? 😕 Eine ScrollBox kann doch in x- und y- Richtung scrollen, das sollte doch genuegen? (Beide liegen doch Left/Top/Width exakt uebereinander)***gruebel***nichtversteh***

    PS: Gut Dass Du schon Futter fuer die neuen Kamele besorgst! (Oder fuetterst Du damit die Haremsdamen? 😃 )



  • Hab im aktuellen Code das Panel als Bezug. Das geht genausowenig.

    Dank @WebFritzis Hilfe kann ich jetzt ganz edel die Mausposition in Screenkordinaten umrechnen. Mit den Controls klappt es einfach nicht. Da finde ich keine Entsprechung. Die Syntax, die ich mir aus der Hilfe zusammengebastelt hab, muß falsch sein. 🙄

    Ja, die vielen Controls übereinander (ich blick noch durch) 😉 . Ich hab zwei Paletten-Panels mit alLeft und alRight. Setz ich jetzt das Statuspanel alBottom, nimmt es die Priorität und setzt sich über die volle Formbreite. Es soll aber nur unter der ScrollBox liegen (die dann mit alClient den restlichen Raum ausfüllt. Darein kann ich das Statuspanel nicht packen, da es sonst mitgescrollt wird. - Wenn ich einen einfacheren Weg finde, änder ich das, die untere ScrollBox fliegt raus. Da scheint aber nichts zu gehen, alBottom hat die Priorität (Mit einem Panel getestet).

    PS: Na klar. Bald ist die Erntezeit für Kamele; da muß man vorsorgen. Hirse anbieten kann man ja hierzulande niemandem. Haremsdamen stehen auch auf Handfest, nicht auf Hirse. 🙄



  • Die Koordinaten der Controls - ich nehm' an Du meinst die Image im Panel - das ist wirklich 'verzwickt'.

    Annahme: Image liegt mit Left bei +25 Pixel
    Panel liegt mit -10 gescrollt in der ScrollBox bei Left=0

    -> Linke Kante von Image muesste bei +15 Pixel Abstand zu ScrollBox- Rand liegen
    -> Du musst wahrscheinlich fuer Umrechnung Left UND ScrollBar->Position UND Left von Image 'verrechnen'!? (Aber wie???) 😕

    (Hatte 'mal 'n aehnliches Problem bei Zoom mit Scrollrad in gezoomten und gescrollten Bild in der ScrollBox unter Beibehaltung des Bilpunktes unter der Maus - Nur mit Verrechnung aller Offsetwerte gelungen! Die Formel geht aber hier nicht!

    Bei Dir noch schlimmer, da Image in Panel in ScrollBox in ScrollBox1 ...???

    PS: Deine armen Haremsdamen, mussen mit HAND- fest zufrieden sein. 😃 Hast Du so wenig Zeit?? :p



  • Ist vielleicht gar nicht so verzwickt. ScrollBox1 Top/Left hab ich. Die Bewegliche ist Panel Top/Left. Hierfür bräuchte ich die ScreenKoordinaten. Die Umrechnung sollte dann klar gehen.

    -Sagst gar nix zu TBitmap::HandleType . Da kannst du die Timer-Auszeiten verlängern. Kein Refresh() oder Invalidate() sondern konkret (bei mir) Image->Refresh(); . Läuft sehr glatt und sauber, die Geschichte - macht schon richtig Fun.

    PS: Nicht HAND- fest sondern handfest. Das meint, soviel Zeit muß jederzeit sein. Da müssen sogar die Knobelkuren zurückstehen. - Hab halt nur die 5, und das soll so bleiben. 😉 😃



  • Original erstellt von <Omega-X>:
    **Hab's jetzt so versucht:

    MarkBase->Parent = ScrollBox;
            MarkBase->Left = ScrollBox->Left;
            MarkBase->Top = ScrollBox->Top;
            MarkBase->Parent = Panel;
    

    **

    ähm, ich hab doch gesagt.
    /me muss sich mal eben selbst zitieren:

    Also muss dann
    Image->Left=0;
    Image->Top=0;

    also:

    MarkBase->Parent = ScrollBox;
            MarkBase->Left = 0;
            MarkBase->Top = 0;
            MarkBase->Height = MarkBase->Parent->ClientHeight;
            MarkBase->Width = MarkBase->Parent->ClientWidth; 
            Sleep(5000); // zum überprüfen des erfolgreichen Parentwechsels 
            MarkBase->Parent = Panel;
            MarkBase->Height = MarkBase->Parent->ClientHeight;
            MarkBase->Width = MarkBase->Parent->ClientWidth;
    


  • waaa..., hast nicht aufgegeben, @AndreasW, dank dir. 🕶

    Den Parent->Wechsel hatte ich probiert. Hab jetzt auch noch mal deinen Coder versucht. Kann alles nicht gehen - sofern ich nicht ganz falsch lieg. Wenn MarkBase (10,10) auf der ScrollBox lag, kommt es auch (10,10) auf das Panel. Beim Wechsel nimmt es seine Koordinaten mit.

    Ich kapier nur nicht, wieso keine Screenkoordinaten gelingen. Die Klasse ist doch nicht als Attrappe eingerichtet. Ein API sollte auch dahinterstehen. Ich geb also die Hoffnung nicht auf. genau wie beim Mitscrollen im OnMouseMove solte das hier eine elegante Lösung ermöglichen.

    -Zur unteren ScrollBox: Überreden hat geholfen. 🙂 Sie mußte einem Panel weichen. War ja Verschwendung und nur wengen eines Versuches + späterer Faulheit einfach dort geblieben.



  • Hi Omega

    Vielleicht hilft das?:

    ScrollBox->Parent->ClientToScreen(Point(ScrollBox->left,ScrollBox->Top))
    -> liefert die Screen- Position der linken/oberen Ecke der ScrollBox!
    -> unabhaengig von ScrollBar- Positionen
    
    ScrollBox->Parent->ClientToScreen(Point(ScrollBox->left-
                                            ScrollBox->HorzScrollBar->Position,
                                            ScrollBox->Top-
                                            ScrollBox->VertScrollBar->Position))
    -> liefert die Screen- Position der linken/oberen Ecke des ScrollBox- Inhaltes!
    -> abhaengig von ScrollBar- Positionen
    ?? bei ScrollBar- Positionen=0 mueste das identisch sein zum Vorherigen??
    
    MarkBase->ClientToScreen(Point(0,0))
    -> liefert die Screen- Position der linken/oberen Ecke der MarkBase!
    -> ob dies in ScrollBox sichtbar ist oder nicht!!! Abhaengig von Scrollstand
    

    Hoffe, das ich nichts verwechselt hab' 😃



  • ...und dabei sah alles so vielversprechend aus. 😉

    Die Idee ist zumindest mal klasse, @Der Altenburger. Jetzt lassen sich immerhin schonmal Control-Punkte in Screenkoordinaten berechnen. 🙂 Aber positionieren läßt sich damit noch nichts. 🙄

    Dieses Mistvieh von MarkBase bleibt an der Position, an der es erstellt wurde. Zumindest wenn ich alles auf Screenkoordinaten umlege.

    Arbeite ich mit ->Left und ->Top, geht es dynamisch. Bisher leider nur mit Abweichungen, die sich mit der Scrollposition multiplizieren oder dividieren. Artillerietechnisch einschießen gelang bisher nicht.

    Ole, hier mal ein glatter Screenkoordinatencode, der glatt und sauber nichts bringt. Die beiden auskommentierten Zeilen bringen ein Ergebnis, allerdings versagt es bei größereen Scrollpositionen. Dann geht man auf die Suche. *ZFac wird zu viel, /ZFac wird zu wenig.

    Wahrscheinlich müßte man im höheren Scrollbereich Range mit berücksichtigen. Ab wann und wie. Mal seh'n, ob sich da ein Bezug finden läßt. Die Beschreibung ist je recht gut.

    POINT img = Image->Parent->ClientToScreen(Point(0,0));
            POINT scrb = ScrollBox->Parent->ClientToScreen(Point(0,0));
            if (img.x < scrb.x && img.y < scrb.y)
                MarkBase->Parent->ClientToScreen(Point(0,0)) = scrb;
            if (img.y < scrb.x && img.y >= scrb.y)
                MarkBase->Parent->ClientToScreen(Point(0,0)) = Point(scrb.x,img.y);
            if (img.x >= scrb.x && img.y < scrb.y)
                MarkBase->Parent->ClientToScreen(Point(0,0)) = Point(img.x,scrb.y);
            if (img.y >= scrb.y && img.y >= scrb.y)
                MarkBase->Parent->ClientToScreen(Point(0,0)) = img;
            //MarkBase->Left = ScrollBox->BoundsRect.Left+
                    ScrollBox->HorzScrollBar->Position;
            //MarkBase->Top = ScrollBox->BoundsRect.Top+
                    ScrollBox->VertScrollBar->Position;
    


  • Hi Omega-X

    Mit Deinem Code
    [cpp]
    **

    if (img.x < scrb.x && img.y < scrb.y)
    MarkBase->Parent->ClientToScreen(Point(0,0)) = scrb;
    if (img.y < scrb.x && img.y >= scrb.y)
    MarkBase->Parent->ClientToScreen(Point(0,0)) = Point(scrb.x,img.y);

    **[/cpp]
    muessten doch Fehlermeldungen kommen!(???)
    ??? Damit wird der Funktion ....->ClientToScreen(...) ein Punkt zugewiesen!
    Das duerfte der BCB nicht dulden?

    Mit:

    //MarkBase->Left = ScrollBox->BoundsRect.Left+
                    ScrollBox->HorzScrollBar->Position;
    

    sagst Du, geht's 'n bissl? Nur ScrollBar- Position stoert?

    Da fehlt glaub' ich Dein Panel in der Formel!(MarkBase liegt doch in Panel, Panel legt in ScrollBox, richtig?)
    So plazierst Du ein MarkBase in ScrollBox, Du musst aber doch MarkBase in Panel, und dieses in der ScrollBox platzieren!(???Aber wie???)



  • Nö, keine Fehlermeldung, keine Warnung. Was ich mach, nützt einfach nur nichts. Im Grunde tu ich wohl nicht mal was. Hab es dann nicht weiter untersucht.

    Nun zum Gag des heutigen Tages: Der "Zweizeiler" wollte noch nicht richtig. Dann war IDE aus, RuntimeError (wie immer) bestätigen, Maschine aus, Omega regenerieren, Maschine an, IDE starten, Projekt laufen lassen angesagt.

    Ole, exakt! ZB. ein Bild 2000x1695, 1000% Zoom, Position ganz am Ende. Er pastet exakt ins sichtbare (0,0) der ScrollBox! Verstehen tu ich das nicht, versuch es auch gar nicht. Denn es gibt viel mehr zwischen Hardware und BCB, als sich unsere... 😃

    Wichtig ist, daß es jetzt exakt läuft, *giganfreu* 🕶 ! Die Aufgabe ist gelöst, Ring frei zu weiteren Abenteuern. :p

    void __fastcall TPixi::PasteClick(TObject *Sender)
    {
        // Bitte nur Bilder, MarkBase ist ein TImage
        if(Clipboard()->HasFormat(CF_PICTURE))
        {
            // ab jetzt keine Zeichenoperationen mehr durchführen
            MarkBtn->Down = true;
            // an Bildgröße anpassbereit machen
            MarkBase->AutoSize = true;
            MarkBase->Stretch = false;
            // Position auf die Situation der ScrollBox abstimmen
            MarkBase->Left = ScrollBox->BoundsRect.Left+
                    ScrollBox->HorzScrollBar->Position;
            MarkBase->Top = ScrollBox->BoundsRect.Top+
                    ScrollBox->VertScrollBar->Position;
            // also, hol dein Bild ab und zeig dich
            MarkBase->Picture->Assign(Clipboard());
            MarkBase->Show();
            // Bereit machen für die Anpassung an den Zoomfaktor
            MarkBase->AutoSize = false;
            MarkBase->Stretch = true; 
            // int, dient zur Berechnung
            // der relativen Größe bei Zoomfaktorwechsel
            mbOldWidth = MarkBase->Width;
            mbOldHeight = MarkBase->Height;
            // Größe an den Zoomfaktor anpassen,
            // nun bereit, verschoben zu werden
            MarkBase->Width = MarkBase->Width*ZFac;
            MarkBase->Height = MarkBase->Height*ZFac;
        }
        // MarkierungsRect wieder aufräumen
        ARect = Rect(0,0,0,0);
    }
    


  • Glueckwunsch!!! (tatatataaaaa) 😉

    PS: Die Zeilen, die nichts tun wuerd ich aber trotzdem entfernen(machen ja eh' nix). Nicht das der die Funktionsadressen ueberschreibt!!! (Wehe wenn die Funktion 'mal gerufen wird!) 😉



  • Ha ja, das sind so die kleinen Frischlingsfreuden. Wenn ich dagegen richtigen Code seh... :p Aber das kommt mit der Zeit. Beispiele und Übung.

    Oh ja hab ich die nutzlosen Zeilen entfernt. Auskommentiert wird ja sowieso immer alles, was nicht aktuell laufen soll (Tests usw.). Was ich gepostet hab, ist die bereinigte Funktion. Copy und paste werden ja praktisch immer zentral gebraucht. Die sollen stimmen. - Normal kommentier ich solche glatt lesbaren Standards nicht. Aber falls doch mal jemand sowas braucht...

    Dank noch mal allen Beleidigten für die Hile. Der nächste Knoten kommt bestimmt. :p


Anmelden zum Antworten