 |
| |
|
|
 |
Autor |
Nachricht |
 |
| |
| MathiasSimmack |
#1| Verfasst am: 02.03.2003, 19:57 Titel: Tile-Modus und Gruppierung von List-View-Items (WinXP) |
 |
 |
 |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Sprache: Delphi (Win32) Quasi als DP-Exklusivveröffentlichung (wenn ihr so wollt) gibt´s hier die VCL-Variante der o.g. neuen XP-Gimmicks. Meine Ausführungen beziehen sich aber hauptsächlich auf Delphi vor Version 7. Ich nehme an bzw. hoffe, dass D7 diese Neuheiten bereits eingebaut hat. Also zeige ich hier, wie Besitzer von Delphi 5 (wie in meinem Fall) diese neuen Sachen nutzen können.
Für alle, deren Delphi nicht aktuell genug ist, liegt im Anhang meine Unit "CommCtrl_Fragment.pas", die die notwendigen Deklarationen usw. enthält. Sie ist kein Ersatz für die CommCtrl von Borland; sie ist also zusätzlich anzugeben!
Achtung!
Für alle drei Sachen, die nachfolgend besprochen werden, ist die Manifestdatei erforderlich! Das gilt auch, wenn man WinXP im Klassik-Look laufen lässt. Sagt hinterher nicht, ich hätte es nicht erwähnt. Das Manifest, ob nun beiliegend (Dateiname.exe.manifest) oder in den Ressourcen, sorgt dafür, dass die Common Controls 6.0 benutzt werden. Und nur damit funktioniert alles! |
| [ An diesen Beitrag wurden eine oder mehrere Dateien angehängt. Zum Herunterladen bitte anmelden. ] |
|
 |
|
|
|
| |
| MathiasSimmack |
#2| Verfasst am: 02.03.2003, 19:57 Titel: Die Darstellungsmodi unter WinXP umschalten |
 |
 |
 |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Um z.B. den neuen Tile-Modus nutzen zu können, solltet ihr unter Win XP nach Möglichkeit die neue Nachricht "LVM_SETVIEW" bzw. die Funktion "ListView_SetView" benutzen, für die es die folgenden Werte gibt:
| Code: | markieren | LV_VIEW_ICON
LV_VIEW_SMALLICON
LV_VIEW_LIST
LV_VIEW_DETAILS
LV_VIEW_TILE |
|
Also, z.B.
Ich sag´s lieber noch einmal: A) diese Anweisung funktioniert nur unter Windows XP, und B) auch nur, wenn ein Manifest für die Common Controls 6.0 vorhanden ist. Soll eure Anwendung also unter allen Windows-Version laufen, unter XP aber diese zusätzlichen Features benutzen, dann müsst ihr (Non-VCL) sowohl den alten als auch den eben gezeigten neuen Weg zum Wechseln der Ansicht einbauen.
Ich hoffe, Delphi 7 unterstützt (wenn überhaupt) beides, so dass es mit der D7-VCL leichter ist.
Zu Nachricht und Funktion gibt es natürlich auch die Gegenstücke: "LVM_GETVIEW" und "ListView_GetView", mit denen man ermitteln kann, welche Ansicht momentan aktiv ist. |
|
 |
|
|
|
| |
| MathiasSimmack |
#3| Verfasst am: 02.03.2003, 19:58 Titel: Die aktuelle Spalte markieren |
 |
 |
 |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Das einfachste zuerst: Ihr kennt sicher den Effekt aus dem Explorer von Windows XP, bei dem die aktuelle Spalte grau markiert wird. Dazu ist keine Zeichenfunktion erforderlich, das OS stellt mit der Nachricht "LVM_SETSELECTEDCOLUMN" (bzw. "ListView_SetSelectedColumn") die notwendige Funktionalität zur Verfügung.
Man übergibt lediglich den Index der gewünschten Spalte; beim Start des Programms bspw.:
Wenn man eine Sortierfunktion hat, bietet sich natürlich das "OnColumnClick"-Ereignis an, um die Spaltenmarkierung zu wechseln:
| Delphi-Quellcode: | markieren | procedure TForm1.lv1ColumnClick(Sender: TObject; Column: TListColumn);
begin
{ ... sortieren ... }
// sortierte Spalte kennzeichnen
ListView_SetSelectedColumn(lv1.Handle,Column.Index);
end; |
|
Anders herum geht´s auch: mit "LVM_GETSELECTEDCOLUMN" oder "ListView_GetSelectedColumn" könnt ihr ermitteln, welche Spalte sozusagen den Fokus hat.
Soviel dazu. |
|
 |
|
|
|
| |
| MathiasSimmack |
#4| Verfasst am: 02.03.2003, 19:59 Titel: Der Tile-Modus |
 |
 |
 |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Der Tile-Modus ist ebenfalls aus dem Explorer bekannt. Man sieht dabei das Icon, und rechts daneben steht der Dateiname, und darunter (abhängig vom Typ) noch zusätzliche Infos. Zur Benutzung müssen wir der List-View erst mitteilen, wie wir uns den Kachelmodus vorstellen. Dazu gibt´s das Record TLVTileViewInfo, das wir am besten im "OnCreate" der Form füllen:
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · 19
| procedure TForm1.FormCreate(Sender: TObject);
var
tileview : TLVTileViewInfo; // CommCtrl_Fragment.pas
begin
// Recordgröße initialisieren
tileview.cbSize := sizeof(TLVTileViewInfo);
// was wollen wir beeinflussen? die Anzahl der zusätzlichen Zeilen
tileview.dwMask := LVTVIM_COLUMNS;
// die Tiles sollen sich möglichst automatisch anpassen
tileview.dwFlags := LVTVIF_AUTOSIZE;
// wie viele zusätzliche Zeilen sollen es denn sein?
tileview.cLines := 2;
// und ab damit zur List-View
ListView_SetTileViewInfo(lv1.Handle,tileview);
end; |
|
Wichtig erscheint mir diese Zeile:
Damit wird der List-View mitgeteilt, wie viele zusätzliche Zeilen im Kachelmodus zu sehen sein sollen. Das bedeutet: zusätzlich zum Itemnamen (TListItem.Caption), der ja sowieso und in jedem Darstellungsmodus angezeigt wird!
Nehmen wir als Beispiel einen kleinen Explorer, der die Dateien des aktuellen Ordners anzeigt. Im Reportmodus zeigt er außerdem in der Spalte #1 die Dateigröße und in Spalte #2 das Datum. Was wir davon im Kachelmodus sehen, hat ursächlich mit diesen Spalten im Reportmodus zu tun.
Anzumerken ist noch, dass der Kachelmodus für jedes Item separat eingestellt werden muss. Das hört sich umständlich an, bietet aber auch den Vorteil, die Ansicht direkt zu beeinflussen. Ich zeige ein Mini-Beispiel aus dem "OnCreate" der Form:
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · · 20 · · · · 25 · · · · 30 · · · · 35
| res := FindFirst(ExtractFilePath(paramstr(0)) + '*.*',
faAnyFile,ds);
while(res = 0) do begin
if(ds.Attr and faDirectory = 0) then begin
// wie gehabt, füllen wir die List-View
lv := lv1.Items.Add;
lv.Caption := ds.Name;
lv.ImageIndex := 0;
lv.SubItems.Add(inttostr(ds.Size) + ' Bytes');
lv.SubItems.Add(FormatDateTime('',FileDateToDateTime(ds.Time)));
// JETZT KOMMT DER TILE-MODUS -->
// wir initialisieren das TLVTileInfo-Record
tile.cbSize := sizeof(TLVTileInfo);
// welches Item ist´s?
tile.iItem := lv1.Items.Count - 1;
// wie viele zusätzliche Zeilen sollen es für
// dieses spezielle Item sein?
tile.cColumns := 2;
// welche Spalten sollen angezeigt werden?
tile.puColumns := @ca[0];
// an die List-View übergeben
ListView_SetTileInfo(lv1.Handle,tile);
end;
res := FindNext(ds);
end;
FindClose(ds); |
|
Wichtig hierbei ist diese Anweisung:
"ca" ist dabei ein Integer-Array, das die Indexwerte der anzuzeigenden Spalten enthält:
Wenn wir davon ausgehen, dass -wie oben erwähnt!- die erste Spalte die Dateigröße und die zweite das Datum enthält, dann würden wir im Tile-Modus also auch unter dem Dateinamen erst die -größe und dann das Datum sehen. Tauschen wir die Angabe um, etwa
dann sähen wir erst das Datum und dann die Größe. Abhängig von den Spalten, die ihr im Reportmodus habt (oder generell: falls ihr versteckte Subitems habt, die in keiner Spalte auftauchen!), könnt ihr mit dem Array beeinflussen, was im Tile-Modus zu sehen sein soll.
That's all.
(PS: Fehler mit "Code" vs. "Delphi" im Text gefixt.) |
Zuletzt bearbeitet von MathiasSimmack am 03.03.2003, 07:56, insgesamt 1-mal bearbeitet. |
 |
|
|
|
| |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Das Schwierigste zuletzt; ´s hat mich auch am meisten Nerven gekostet. Das Wichtigste hierbei ist, dass man die Gruppen (leider) selbst bilden muss. Diese Arbeit nimmt einem das System nicht ab. Die WinXP-Benutzer unter euch kennen den Effekt, den ich persönlich für recht nützlich halte. Aktiviert im Explorer einfach mal die Option "in Gruppen anzeigen".
Der Explorer sortiert die Dateien dann z.B. alfabetisch. Klickt ihr aber auf die Spalte mit der Dateigröße, dann heißen die Gruppen plötzlich "Sehr klein", "Klein", usw., und die Dateien werden entsprechend zugeordnet.
All das muss man, wie gesagt!, selbst machen. Auf der anderen Seite hat man dadurch die Freiheit, die Gruppen an die jeweilige Anwendung anzupassen. Ich erstelle als Beispiel eine einzige Gruppe, der alle Dateien zugeordnet werden. Dazu brauchen wir das Record TLVGroup, das auch erst mal initialisiert werden muss:
Da wir einen Gruppennamen und eine ID für die Gruppe vergeben (müssen), sind die entsprechenden Flags zu setzen:
Nun kommt der Name unserer Gruppe, der als PWideChar zu übergeben ist:
| Delphi-Quellcode: | markieren | group.pszHeader := pwidechar(widestring('Testgruppe'));
group.cchHeader := lstrlenW('Testgruppe'); |
|
Und die ID unserer Gruppe:
Das ganze reichen wir an die List-View weiter, wobei wir als zweiten Parameter (laut PSDK: Itemindex) -1 angeben, damit die neue Gruppe an das Ende des internen Gruppenarrays der List-View gesetzt wird:
Nun müssen die Items noch irgendwie in die Gruppe rein. Ich hatte meine ersten Versuche dazu mit der Nachricht "LVM_MOVEITEMTOGROUP" (respektive "ListView_MoveItemToGroup") begonnen, aber diese Nachricht hat entweder einen vollkommen anderen Sinn, oder sie funktioniert nicht.
Tatsächlich brauchen wir das erweiterte TLVItem-Record, das man im PSDK und in der Unit "CommCtrl_Fragment.pas" (s. Anhang im ersten Beitrag) finden kann. Dieses erweiterte Record besitzt u.a. die neue Membervariable iGroupId, die wir nun brauchen. Das heißt, wir nehmen eine for-Schleife und laden nacheinander alle Items der List-View:
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 16
| for i := 0 to lv1.Items.Count - 1 do begin
// Record leeren
ZeroMemory(@lv60,sizeof(TLVItem60));
// Flag setzen, weil wir die Gruppen-ID ändern wollen
lv60.mask := LVIF_GROUPID;
// von welchem Item?
lv60.iItem := i;
// wie lautet die ID?
lv60.iGroupId := 1;
// und ab dafür
SendMessage(lv1.Handle,LVM_SETITEM,0,LPARAM(@lv60));
end; |
|
Bitte nicht wundern: um Probleme mit dem Originalrecord zu vermeiden, habe ich in meiner Unit den erweiterten Typ als TVLItem60 deklariert.
So, nun können wir die Gruppenansicht einschalten. Dazu gibt´s "LVM_ENABLEGROUPVIEW" bzw. die Funktion:
Diese Funktion zeigt auch gleich noch das toggeln der Ansicht mit Hilfe von "ListView_IsGroupViewEnabled" (bool-Funktion).
Ja, das war´s auch schon.
Ich bitte um Verständnis, dass ich ein paar Sachen für das nächste Update der Win32-API-Tutorials aufgehoben habe. Dort zeigt euch die neue List-View-Demo dann, wie man z.B. mehrere Gruppen erstellt, wie man prüft, ob es eine Gruppe evtl. schon gibt, und wie man die Gruppen ändert, wenn man die Items nach anderen Kriterien sortieren lässt. Wer nicht so lange warten möchte, hier die Kurzform für die alfabetische Sortierung:
- Den Namen eines Items auslesen und nur das erste Zeichen (UPCASE!) berücksichtigen. Wenn es im Bereich von A bis Z liegt, kann eine entsprechende Gruppe erzeugt werden; alles, was außerhalb davon liegt, ist im XP-Explorer z.B. in der Gruppe "Andere" zu finden.
- Mit Hilfe von "ListView_GetGroupInfo" (PSDK) kann man Informationen zu vorhandenen Gruppen auslesen (in dem Fall wäre nur der Header -der Gruppenname!- interessant). Die Funktion liefert -1 zurück, wenn ein Fehler auftrat, bzw. wenn die Gruppe noch nicht existiert.
- Im Erfolgsfall sind der geplante Gruppenname (1. Zeichen des Items) und der ausgelesene Gruppenname zu vergleichen. Stimmen sie überein, existiert die Gruppe. Man verlässt die Schleife, merkt sich die ID und ordnet das aktuelle Item der gefundenen Gruppe zu. Stimmen Sie nicht überein, macht man mit Punkt #2 und der nächsten Gruppe weiter, bis man die gesuchte Gruppe findet, oder bis man alle Gruppen durchsucht hat.
- Und jetzt wieder bei Schritt #1 beginnen und das nächste Item auslesen, usw.
Wer Delphi 7 hat, kann gern ergänzen, wie es dort funktioniert - sofern die genannten Features dort in der VCL implementiert sind.
Gruß, und viel Spaß damit.
Mathias. |
|
 |
|
|
|
| |
| Luckie |
#6| Verfasst am: 02.03.2003, 22:12 Titel: |
 |
 |
 |
|
Moderator Status: offline Beiträge: 30.058 angemeldet: 29.05.2002 Delphi 2006 Professional

|
Pack ruhig noch ein paar Screenshots rein, damit die Leute auch wissen, von was du redest. |
 Programmieren ist ein Rennen zwischen den Softwareentwicklern, die versuchen größere und bessere idiotensichere Programme zu schreiben und dem Universum, welches versucht größere und bessere Idioten zu produzieren. Zur Zeit liegt das Universum in Führung. |
 |
|
|
|
| |
|
Mitglied Beiträge: 3.817 angemeldet: 30.05.2002

|
Hier also ein Screenshot, der sowohl den Tile-Modus als auch die Gruppierung von Items zeigt:
Bild Link auf Wunsch entfernt, da Bild nicht mehr vorhanden.
Wie gesagt, es handelt sich dabei um eine normale List-View. Es ist keine spezielle Komponente. Einzig WinXP läuft, und die Anwendung benutzt eine Manifest-Ressource.
[i][edit=Luckie]Bild Link entfernt. Mfg, Luckie[/edit] |
Zuletzt bearbeitet von Luckie am 21.11.2004, 20:31, insgesamt 1-mal bearbeitet. |
 |
|
|
|
| |
| wolv |
#8| Verfasst am: 15.08.2003, 19:44 Titel: Re: Tile-Modus und Gruppierung von List-View-Items (WinXP) |
 |
 |
 |
|
Mitglied Status: offline Beiträge: 1 angemeldet: 15.08.2003

|
Weiß irgendwer ob man den Group - View Style auch auf Virtuelle Listviews anwenden kann? d.h. wenn man LVS_OWNERDATA setzt und die OnDispInfo Notification abfängt?
Bei mir scheint die LVM_ENABLEGROUPVIEW hierbei nicht zu funktionieren!
danke im vorraus .. stefan mairhofer |
|
 |
|
|
|
| |
| Experience1986 |
#9| Verfasst am: 03.02.2006, 11:02 Titel: Re: Tile-Modus und Gruppierung von List-View-Items (WinXP) |
 |
 |
 |
|
Mitglied Alter: 24 Status: offline Beiträge: 22 angemeldet: 07.09.2003 Wohnort: 66333 Völklingen Delphi 7 Personal

|
Hi,
Ich habe das nun mal Versucht in Delphi 7 mit XPMan Komponente und VCL umzusetzen. Das Hervorheben von Spalten funktioniert wunderbar. Allerdings die Gruppenansicht verweigert komplett die Darstellung.
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · · 20 · · · · 25 · · · · 30 · · · · 35 · · · · 40 · · · · 45 · · · · 50
| procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
group:TLVGroup;
lvItem: TLVItem60;
begin SetLength(dataset, 0);
for i:=0 to 99 do
begin
SetLength(dataset, length(dataset)+1);
dataset[length(dataset)-1].Name:='Wert '+inttostr(i+1);
dataset[length(dataset)-1].Value:=AValue(random(10)+10, 0);
dataset[length(dataset)-1].Mode:=random(2)+1;
end;
lv.Items.Count:=length(Dataset);
// Spalte Name Grau hinterlegen
ListView_SetSelectedColumn(lv.Handle,1);
// Gruppen "Modus 1" anlegen
group.cbSize := sizeof(TLVGroup);
group.mask := LVGF_HEADER or LVGF_GROUPID;
group.pszHeader := pwidechar(widestring('Modus 1'));
group.cchHeader := lstrlenW('Modus 1');
group.iGroupId := 1;
ListView_InsertGroup(lv.Handle,-1,group); // Gruppe speichern
// Items den Gruppen zuordnen
for i := 0 to lv.Items.Count - 1 do
begin
// Record leeren
ZeroMemory(@lvItem,sizeof(TLVItem60));
// Flag setzen, weil wir die Gruppen-ID ändern wollen
lvItem.mask := LVIF_GROUPID;
// von welchem Item?
lvItem.iItem := i;
if Dataset[i].Mode = 1 then
begin// wie lautet die ID?
lvItem.iGroupId := Dataset[i].Mode; end;
// und ab dafür
SendMessage(lv.Handle,LVM_SETITEM,0,LPARAM(@lvItem));
end;
// Gruppen aktivieren
ListView_EnableGroupView(lv.Handle, true);
lv.Repaint;
end; |
|
Gibt es dafür einen Grund?
Vielen Dank schonmal für jede Antwort. Suche schon ewig nach dieser Darstellungsart. |
Zuletzt bearbeitet von Experience1986 am 03.02.2006, 11:04, insgesamt 1-mal bearbeitet. |
 |
|
|
|
| |
| CCRDude |
#10| Verfasst am: 29.06.2007, 14:13 Titel: Re: Tile-Modus und Gruppierung von List-View-Items (WinXP) |
 |
 |
 |
|
ehem. Benutzer

|
Ist zwar schon ein etwas älterer Beitrag, aber da ich heute gerade nach längerer Suche drüber gestolpert bin und hier die Screenshots inzwischen fehlen, und mir das perfekt für das erste Rumspielen mit einem class helper erschien, hab ich mal eben zwei davon zusammengeschustert und mitsamt Screenshots hier angehängt.
Funktionabel ab BDS X (hier Version einsetzen, ab der es class helper gibt... 2005 oder 2006?), alternativ stehen zumindest 8 Wrapper-Funktionen für dieselben Aktionen zur Verfügung. Die CommCtrl_Fragment.pas ist ebenfalls noch nötig, wollte nicht so frech sein und die als meine Arbeit ausgeben, ich habs ja bloß nochmal in Schönschrift abgeschrieben
Beispiel für die Anwendung:
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · · 20 · · · · 25 · · · · 30 · · 33
| procedure TForm1.AddSomeGroupedThings;
begin
ListView1.AddGroup('Eigene Dateien', 1); // neu
ListView1.AddGroup('Downloads', 2);
ListView1.ViewStyleEx := vsTile; // neu
with ListView1.Items.Add do begin
Caption := 'Hallo Welt.txt';
GroupId := 1; // neu
SetMinimumSubItemCount(2, '?'); // neu
SubItems[0] := '11 B';
SubItems[1] := IntToStr(GroupId);
SetTileViewColumns(2, [1]); // neu
end;
with ListView1.Items.Add do begin
Caption := 'snlListView.pas';
GroupId := 1;
SetMinimumSubItemCount(2, '?');
SubItems[0] := '10 KB';
SubItems[1] := IntToStr(GroupId);
SetTileViewColumns(2, [1]);
end;
with ListView1.Items.Add do begin
Caption := 'Screenshot.png';
GroupId := 2;
SetMinimumSubItemCount(2, '?');
SubItems[0] := '183 KB';
SubItems[1] := IntToStr(GroupId);
SetTileViewColumns(2, [1]);
end;
ListView1.TileViewLines := 1; // neu
ListView1.GroupViewEnabled := true; // neu
end; |
| |
| [ An diesen Beitrag wurden eine oder mehrere Dateien angehängt. Zum Herunterladen bitte anmelden. ] |
|
 |
|
|
|
 |
|
 |
| |
|
|
| |
 
|
|
| |
|
Du darfst keine Beiträge in dieses Forum schreiben. Du darfst auf Beiträge in diesem Forum nicht antworten. Du darfst Deine Beiträge in diesem Forum nicht bearbeiten. Du darfst Deine Beiträge in diesem Forum nicht löschen. Du darfst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum nicht posten. Du kannst Dateien in diesem Forum nicht herunterladen.
|
|
 |