Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » String:anzahl der Pixel

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
31.03.2003, 21:32 Uhr
~Michael
Gast


Hallo Forum ,
ich habe eine CListCtrl gefüllt mit 4 Spalten und 4 Items!
(Danke nochmal an alle die geholfen haben das sie jetzt läuft)
Nun möchte ich die optimale Spaltenbreite ermitteln und setzen!

C++:
/// zuerst Header auslesen
HDITEM pHeaderItem;
pHeaderItem.mask = HDI_TEXT;
m_ctrlPreview.GetHeaderCtrl()->GetItem(col,&pHeaderItem);
// Breite des Strings im Header
int max = pHeaderItem.cchTextMax;
max = pHeaderItem.cchTextMax;
int length = 0;
for(int item=0;item<items;item++)
{
/// Breite bestimmen
length = m_ctrlPreview.GetStringWidth(m_ctrlPreview.GetItemText(item,col));
if(length>max) max=length;
}
/// Breite auf max setzen
LVCOLUMN pColumn;
pColumn.mask = LVCF_WIDTH;
if(m_ctrlPreview.GetColumn(col,&pColumn))
{
pColumn.cx=max;
m_ctrlPreview.SetColumn(col,&pColumn);
}


Damit ermittle ich auch eine Pixelanzahl und setze sie ! Doch in der Anzeige fehlt immernoch ein Teil des Strings! Bei der Funktion GetStringWidth steht aber, daß er auch die aktuelle Schrift beachtet! Was fehlt mir jetzt noch? Muss ich das ganze noch mit einem Faktor multiplizieren? Ich möchte ungern pauschal einen Offset dazu addieren!

Danke für eure Hilfe!

Michael
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.04.2003, 13:27 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Micha,
ich würde jetzt ohne groß über Deine Variante nachzudenken die Methode SetColumnWidth des Controls nehmen. In Bezug auf das gestrige letzte Beispiel von mir hier ein Lösungsansatz.

C++:
// void AutoSizeColums (int col=0);
void CListDlg::AutoSizeColumns(int col /*=0*/) {
    
     int min = col < 0 ? 0 : col;
     int max = col < 0 ? GetColCount()-1 : col;
     for (col = min; col <= max; col++) {
          m_list.SetColumnWidth(col,LVSCW_AUTOSIZE);
          int w1 = m_list.GetColumnWidth(col);
          m_list.SetColumnWidth(col,LVSCW_AUTOSIZE_USEHEADER);
          int w2 = m_list.GetColumnWidth(col);
          int w = MAX(MINWIDTH,MAX(w1,w2));
          m_list.SetColumnWidth(col,w);
     }
     Invalidate();
}

int CListDlg::GetColCount() const {
     CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
     return pHeader->GetItemCount();
}



Im Header:

C++:
#define MINWIDTH 10


Und im stdafx.h

C++:
template <class T> inline const T& MAX(const T& t1, const T& t2)
{
    return t1 < t2 ? t2 : t1;
}

Lass Deine Datei einlesen, danach kannst Du mit

C++:
void CListDlg::OnButton1()
{
    
    m_list.DeleteAllItems();
    
    /* Jetzt der Part des einlesens */
    .............
    .............
    .............
    AutoSizeColumns(); /* 0 ist ja default */
    AutoSizeColumns(1);
    AutoSizeColumns(2);
    AutoSizeColumns(3);
}


Deine Spalten formatieren.
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe

Dieser Post wurde am 01.04.2003 um 13:31 Uhr von Uwe editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
01.04.2003, 17:08 Uhr
~michael
Gast


Danke Uwe
soweit ich habe ich es verstanden! Nur noch paar kleine Fragen.
Wiso rufst du die Funktion dann noch für jede Spalte einzeln auf, wenn du
in der Funktion über alle Spaltn gehst und die Breite setzt?

Michael
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
01.04.2003, 18:07 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Michael,

Zitat:
~michael postete
Wiso rufst du die Funktion dann noch für jede Spalte einzeln auf, wenn du
in der Funktion über alle Spaltn gehst und die Breite setzt?


Ertappt . Die Sache funktioniert mit AutoSizeColumns(); nur korrekt wenn ich das z.B. in der abgeleiteten Klasse MyList mache (für alle Anderen : war ein Bsp. welches ich Micha zugeschickt hatte). Dann muß allerdings

C++:
void AutoSizeColums (int col= -1);


sein. Hatte mir gedacht das es doch ganz praktisch ist, wenn man auf die einzelne Spalten gezielt zugreifen könne. Deshalb der Gag mit der Spaltennummer. Aber die MFC wäre nicht die MFC wenn es da nich ein paar Probleme gäbe. Weiterhin könnte ich mir vorstellen, dass Invalidate() bei langen Listen Probleme macht. Ich sinne nach einer Lösung z.B. über die SetRedraw() Methode.
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe

Dieser Post wurde am 01.04.2003 um 18:10 Uhr von Uwe editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
01.04.2003, 19:27 Uhr
~Michael
Gast


Danke Uwe die Funktion funktioniert super!
Das Invalidate() setzt doch nur ein Flag das das Fenster neu gezeichnet werden soll, oder? Wann wird es dann neu gezeichnet bzw wann wird diese Nachricht WM_PAINT erzeugt? Doch eigentlich nur wenn ich es teilweise verdecke oder Aktionen in dem Fenster vor nehme oder? (Sprich wenn ich die Funktion so aufrufe und dann nix mache, wann wird das Fenster neu gezeichnet?)
Warum sollte diese Funktion Probleme machen?
Und ich habe mir meine Lsg noch einmal angeschaut! Ok meine Funktion geht über einen Umweg an die Sache ran, aber ich sehe nicht warum sie nicht gehen sollte!

Michael
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
01.04.2003, 19:48 Uhr
~Michael
Gast


Ich werde es mit SetRedraw() realisieren!

C++:
SetRedraw(FASLE);
FillListBox();
ColumnBreadth();
SetRedraw(TRUE);


wäre das so richtig? Meine Datein sind bzw können mehrere GB groß sein, da ist dein Tipp wo richtig!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
01.04.2003, 20:42 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo,
ja genau! Solange an der Breite der Spalten gewerkselt wird, darf nicht neu gezeichnet werden, was das Listenelement automatisch ausführen würde da CWnd dem Element übergeordnet ist. Es würde eine Art flackern entstehen. Ist der Job erledigt darf dann erst wieder gezeichnet und auch Invalidate() wieder aufgerufen werden.
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: