Scrollbar breite ermitteln in CListCtrl


  • Mod

    Mr Evil schrieb:

    die breite hab ich nicht durch GetClientRect, da ich es in abhaengigkeit des fenster setz - dh ich hab immer angegeben breite = fensterbreite-x usw

    Selbst wenn Du sie irgendwie setzte so gibt GetClientRect angewandt auf das entsprechende Control die sichtbare Fläche wieder.
    Es ist also der korrekteste Weg die sichtbare Nutzfläche eines Fensters zu bestimmen.



  • warum soll das der korrekteste weg sein ?
    ich setz die groesse NUR in OnSize - sonst nirgends und wie das immer beim proggen ist gibt es mehere loesungen

    int iSizeScroll = GetSystemMetrics(SM_CXVSCROLL);
        // pixels from the right side or bottom
    int x = cx-200;
    int y = cy-150;
    
        // resize the list
    m_ListView.MoveWindow(0, 0, x, y);
        // get numbers of items and number of maximum possible shown items per page
        // is list larger as list and scrollbar will appear then resize the columns smaller
    int iListCount = m_ListView.GetItemCount();
    int iListSize = m_ListView.GetCountPerPage();
    if(iListCount > iListSize)
        x = (x/2)-(iSizeScroll/2);
    else
        x /= 2;
    m_ListView.SetColumnWidth(0, x);
    m_ListView.SetColumnWidth(1, x);
    

    breite des fenster festlegen, schauen ob scrollbar gezeigt wird, coloumn setzen - feddich - warum sollte ich mit GetClientRect die breite holen wo ich sie doch direkt vorger selber gesetzt hab ?



  • Tja, warum einfach, wenn's auch kompliziert geht 😃



  • kannst du das weiter ausfuehren ?


  • Mod

    @Mr Evil:

    Dein Code ist ist einfach falsch! Zumindest ist er nicht universell.
    Er geht davon aus, dass der äußere Rahmen gleich der Cient Area ist. Dass ist aber oft genug nicht so, davon geht nämlich ein Rahmen auch noch ab. Er berücksichtigt eben auch keine Scrollbars etc!

    Wenn es um das innere Anpassen an die Breite geht, ist der einzig korrekte Weg GetClientRect zu verwenden!

    Just my 2 cents!



  • In Kurzfassung: GetClientRect() liefert dir die tatsächliche Größe des Cliente-Bereiches (abzüglich eventueller Scrollbars etc), da brauchst du nicht noch selber ausrechnen, ob ein Scrollbar existieren könnte.

    Übrigens hoffe ich, daß dich die Rundungsfehler in deiner Rechnung nicht weiter stören 😉

    PS: Der Scrollbar kann übrigens nicht nur beim Resize auftauchen/verschwinden, sondern auch bei Inhaltsänderungen.



  • wegen auftauchen - darum hatte ich ja immer den count der items geholt - das dann immer berechnet wurde ob scroll angezeigt wird oder nicht - die horizontale bar interessiert ja nicht

    trotzdem vielen dank fuer die ausfuehrlichen antworten - habs entsprechend geaendert:

    CRect *rect = new(CRect);
    m_ListView.GetClientRect(rect);
    m_ListView.SetColumnWidth(0, (rect->Width()/2));
    m_ListView.SetColumnWidth(1, (rect->Width()/2));
    delete rect;
    rect = NULL;
    

  • Mod

    Warum verwendest Du unnötigerweise eine Allokation?

    CRect rect;
    m_ListView.GetClientRect(&rect); 
    m_ListView.SetColumnWidth(0, (rect.Width()/2)); 
    m_ListView.SetColumnWidth(1, (rect.Width()/2));
    


  • warum sollte ich unnoetigerweise eine instanz die ganze funktion durchweg leben lassen wenn ich die nur einmal an dieser stelle brauch ?
    holen - benutzen und speicher freigeben - was ich nicht brauch kann auch weg



  • Deine Sorgen möchte ich haben - als ob ein CRect soo viel Speicher benötigen würde 😃

    Den Heap verwendet man eigentlich eher, um große Datenmengen zu verwalten. Oder um Daten aufzuheben, die das Ende der Funktion überleben sollen. Lokal verwendete "Wegwerf-Variablen" gehören eher auf den Stack.

    (und außerdem kannst du den Block, wo du den CRect brauchst, auch in {...} einschließen, da wird er auch sofort wieder beseitigt)



  • CStoll schrieb:

    Deine Sorgen möchte ich haben - als ob ein CRect soo viel Speicher benötigen würde 😃

    jeder hat sein paeckchen #ggg

    CStoll schrieb:

    (und außerdem kannst du den Block, wo du den CRect brauchst, auch in {...} einschließen, da wird er auch sofort wieder beseitigt)

    na klar - warum bin ich da nicht selber drauf gekommen #gg
    danke {o;


  • Mod

    Mr Evil schrieb:

    warum sollte ich unnoetigerweise eine instanz die ganze funktion durchweg leben lassen wenn ich die nur einmal an dieser stelle brauch ?
    holen - benutzen und speicher freigeben - was ich nicht brauch kann auch weg

    Deine Funktion wird durch so etwas mindestens tausendmal langsamer! Und ich möchte nicht wissen, wie Dein Heap aussieht wenn Du das immer so machst...

    Der Stack ist für solche Variablen (4*int = 16bytes) die beste Position für solche Daten. Zudem ist das ganze auch noch in einer Funktion wie OnSize, die keine bleibenden Ansprüche hat...

    Dieser Stil ist übel...
    Just my 2 cents.

    BTW: Selbst wenn Du das CRect in einen eigenen Block entschließt wird der Speicher am Ende des Blockes nicht freigegeben! Allerdings kann der Compiler diesen Stack Bereich neu nutzen, wenn es Bedarf gibt und ein neuer Block geöffnet wird.
    Ansonsten bringt es nichts.
    Es bringt sicherlich etwas wenn man die Lebenszeit eines Objektes gezielt begrenzen möchte...
    Das was auf dem Stack benötigt wird, wird maximal am Anfang der Funktion angelegt. Das schließt alle Variablen ein die auch in inneren Blöcken später noch dazukommen!


Anmelden zum Antworten