Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi ListView, Icon und SHGetFileInfo (https://www.delphipraxis.net/22059-listview-icon-und-shgetfileinfo.html)

HomerGER 11. Mai 2004 23:29


ListView, Icon und SHGetFileInfo
 
Hallo

ich lese die Laufwerke aus und zeige sie in ListView

Delphi-Quellcode:
if (laufwerk_type_i = DRIVE_FIXED) then
        begin
            //Label ermitteln
            GetVolumeInformation(PChar(laufwerk_s), @laufwerk_label_c[0], SizeOf(laufwerk_label_c), nil, temp_d, temp_d, nil, 0);

            //Alles in ListView
            Haupt_Form.Wartung_ListView5.Items.Add.Caption := laufwerk_s + laufwerk_label_c;

            SHGetFileInfo('C:\', 0, file_info_si, SizeOf(file_info_si), SHGFI_ICON OR SHGFI_LARGEICON);
            //Das hier nur zum Test hab ich überhaupt ne Icon
            Haupt_Form.Image1.Picture.Icon.Handle := file_info_si.hIcon;
        end;

er zeigt mir aber in file_info_si.hIcon nur das StandardIcon an nicht was ich da wirklich drin habe !!

und wie bekomme ich das icon in das ListView an die erste Stell noch vor der Checkbox?

Luckie 12. Mai 2004 00:04

Re: ListView, Icon und SHGetFileInfo
 
Gerade das Thema hatten wir in den vergangenen Tagen schon häufiger.

MathiasSimmack 12. Mai 2004 08:27

Re: ListView, Icon und SHGetFileInfo
 
Zu dem anderen hat Luckie ja schon was gesagt, so beschränke ich mich auf:
Zitat:

Zitat von HomerGER
und wie bekomme ich das icon in das ListView an die erste Stell noch vor der Checkbox?

Gar nicht. Die Checkbox steht immer vorn, und das ist auch gut und richtig so.

HomerGER 12. Mai 2004 09:00

Re: ListView, Icon und SHGetFileInfo
 
das mit den icon hab ich jetzt auch gefunden
aber nicht warum er mir nur das standard icon anzeigt und nicht das wirklich verwendet anzeigt

MathiasSimmack 12. Mai 2004 10:33

Re: ListView, Icon und SHGetFileInfo
 
Ich bin nicht ganz sicher, aber wenn ich deine kurze Beschreibung richtig verstehe, dann willst du das tatsächliche Symbol eines Laufwerks anzeigen? Ja, wenn sich das von dem Symbol von C:\ unterscheidet, dann solltest du auch den passenden Buchstaben angeben und nicht immer C:\ benutzen:
Zitat:

Zitat von HomerGER
Delphi-Quellcode:
SHGetFileInfo('C:\', 0, file_info_si, SizeOf(file_info_si), SHGFI_ICON OR SHGFI_LARGEICON);


HomerGER 12. Mai 2004 10:41

Re: ListView, Icon und SHGetFileInfo
 
ich habe alle laufwerkicon geändert !! 'c:\' ist im programm ne variable

ich habe für meine C-platte das win Icon, er zeigt mir aber immer nur das Standardicon an

liest SHGetFileInfo nur das icon aus, was win dafür vorsieht, oder das was wirklich benutzt wird ?

MathiasSimmack 12. Mai 2004 11:04

Re: ListView, Icon und SHGetFileInfo
 
Jetzt wo du´s sagst -

Ich habe spaßeshalber einer meiner Partitionen mal ein anderes Symbol verpasst, und die Funktion "SHGetFileInfo" liefert anstandslos eben dieses neue Symbol zurück, und ich sehe es dann in der List-View.

So sieht mein Code aus:
Delphi-Quellcode:
uses
  CommCtrl, ShellAPI;

procedure TForm1.FormCreate(Sender: TObject);
var
  hImgBig : HIMAGELIST;
  fi      : TSHFileInfo;
  dwBufLen : dword;
  buf     : string;
  p       : pchar;
  li      : TListItem;
begin
  // Imageliste für große Symbole holen & zuweisen
  hImgBig := HIMAGELIST(SHGetFileInfo('',0,fi,sizeof(fi),
    SHGFI_SYSICONINDEX or SHGFI_ICON));
  if(hImgBig <> 0) then
    ilBig.Handle := hImgBig;

  // unter der Maßgabe, dass "ilBig" eine ImageList auf
  // der Form ist, die in der List-View als "LargeImages"
  // eingetragen ist



  // List-View leeren
  ListView1.Items.Clear;
  ListView1.Items.BeginUpdate;

  dwBufLen := GetLogicalDriveStrings(0,nil);
  if(dwBufLen > 0) then
  begin
    SetLength(buf,dwBufLen);

    if(GetLogicalDriveStrings(dwBufLen,@buf[1]) <> 0) and
      (buf <> '') then
    begin
      p     := @buf[1];
      while(p[0] <> #0) do
      begin
        li  := ListView1.Items.Add;
        case GetDriveType(p) of
          DRIVE_FIXED:
            li.Caption := Format('Festplatte %s',[p]);
          DRIVE_REMOVABLE:
            li.Caption := Format('Wechsellaufwerk %s',[p]);
          DRIVE_REMOTE:
            li.Caption := Format('Netzlaufwerk %s',[p]);
          DRIVE_CDROM:
            li.Caption := Format('CD/DVD-Laufwerk %s',[p]);
          DRIVE_RAMDISK:
            li.Caption := Format('RAM-Disk %s',[p]);
        end;

        // Symbol ermitteln
        SHGetFileInfo(p,0,fi,sizeof(fi),
          SHGFI_ICON or SHGFI_SYSICONINDEX);
        li.ImageIndex := fi.iIcon;

        inc(p,lstrlen(p)+1);
      end;

      buf := '';
    end;
  end;

  ListView1.Items.EndUpdate;
end;

HomerGER 12. Mai 2004 11:24

Re: ListView, Icon und SHGetFileInfo
 
nein auch mit deinen code zeigt er mir für alle platte nur das standard icon an

wo oder mit was hast du denn plattenicon geändert ?


ist XP

MathiasSimmack 12. Mai 2004 12:41

Re: ListView, Icon und SHGetFileInfo
 
Ich hab´s, getreu der Anleitung im PSDK (Index aufrufen und "Customizing Icons" eintippen), in die Registry geschrieben.

Luckie 12. Mai 2004 12:53

Re: ListView, Icon und SHGetFileInfo
 
Bei mir werden mit MS's Methode auch die sonder Icons meiner Cardreader-Laufwerke korrekt angezeigt.

HomerGER 12. Mai 2004 13:30

Re: ListView, Icon und SHGetFileInfo
 
meine icon habe ich hier eingetragen
HKEY_LOCAL_MACHINE
SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer \DriveIcons\C\DefaultIcon

kannst du mal bitte den link von ms geben

MathiasSimmack 12. Mai 2004 13:48

Re: ListView, Icon und SHGetFileInfo
 
Der Schlüssel passt schon (s. [msdn]"customizing icons"[/msdn]). Evtl. mal kurz ab- und wieder anmelden, damit die Symbole neu geladen werden. Im PSDK steht, mal soll auch [msdn]"SHUpdateImage"[/msdn] aufrufen. Aber das ist nur interessant, wenn man das Icon über ein Programm ändert und nicht durch den eigenen Eingriff auf/in die Registry.

HomerGER 12. Mai 2004 15:19

Re: ListView, Icon und SHGetFileInfo
 
hmm
also die Icon hatte ich schon lange geändert
hat sie mir aber nicht im ListView angezeigt, nach dem Ich erst den Rechner neu geboot habe sind sie da


warum hat sie SHGetFileInfo nicht gleich angezeigt ?

mirage228 12. Mai 2004 15:40

Re: ListView, Icon und SHGetFileInfo
 
Zitat:

Zitat von HomerGER
hmm
also die Icon hatte ich schon lange geändert
hat sie mir aber nicht im ListView angezeigt, nach dem Ich erst den Rechner neu geboot habe sind sie da


warum hat sie SHGetFileInfo nicht gleich angezeigt ?

Wie wärs damit:

Zitat:

Zitat von MathiasSimmack
...Im PSDK steht, mal soll auch SHUpdateImage aufrufen...

mfG
mirage228

MathiasSimmack 12. Mai 2004 15:48

Re: ListView, Icon und SHGetFileInfo
 
Ich kann jetzt nur für mich sprechen: Ich habe das Symbol manuell geändert (also durch Eingriff in die Registry per Hand), und da war es auch erst nach dem Ab- und wieder Anmelden zu sehen.

Wenn du, @HomerGER, schreibst
Zitat:

die Icon hatte ich schon lange geändert
dann heißt das, dass dein Rechner wohl ebenfalls schon so lange läuft. Will sagen: Wenn ich von meiner Situation ausgehe, hättest du in der ganzen Zeit die neuen Symbole auch nicht im Explorer sehen dürfen. Und wenn doch, dann liefert "SHGetFileInfo" auch das entsprechende (in dem Fall: neue) Symbol zurück. Und wenn du jetzt sagst: Im Explorer habe ich die neuen Symbole gesehen, aber "SHGetFileInfo" hat sie mir nicht angezeigt, dann gehe ich -sorry!- von irgendeinem kleinen Flüchtigkeitsfehler in deinem Programm aus.

HomerGER 12. Mai 2004 16:11

Re: ListView, Icon und SHGetFileInfo
 
Zitat:

dann gehe ich -sorry!- von irgendeinem kleinen Flüchtigkeitsfehler in deinem Programm aus.
sorry von DEINEM PROGRAMM :roll: :angle2:

ich habe dein Code genommen und da war es gleich - erst nach dem neustart waren sie zu sehen

irgenwas mit iconcache ? womöglich ?

MathiasSimmack 12. Mai 2004 19:09

Re: ListView, Icon und SHGetFileInfo
 
Zitat:

Zitat von HomerGER
sorry von DEINEM PROGRAMM :roll: :angle2:

Zitate bitte nicht aus dem Zusammenhang reißen
Ich schrieb
Wenn du jetzt sagst: Im Explorer habe ich die neuen Symbole gesehen, aber "SHGetFileInfo" hat sie mir nicht angezeigt, dann gehe ich -sorry!- von irgendeinem kleinen Flüchtigkeitsfehler in deinem Programm aus.

HomerGER 12. Mai 2004 19:52

Re: ListView, Icon und SHGetFileInfo
 
also ich habe die icon schon ewig auf mein pc geändert

ich hab sie nicht mit meinen code und nicht mit deinen code in listview gesehen
wie gesagt erst nach ein reboot
dann hat er sie mit meinen code und mit deinen code angezeigt
im Explorer waren sie immer da
aber dann auch nur wenn ich auf vsIcon gestellt habe bei vsReport hat er überhaupt kein icon angezeigt auch nicht das standard

2 frage noch zu deinem code
warum benutzt du TListItem und übergibst es nicht direkt an ListView

li.ImageIndex := fi.iIcon; und nicht ListView.ImageIndex := fi.iIcon;

was bring das
ListView1.Items.BeginUpdate;
ListView1.Items.EndUpdate;

wenn ich die function aufrufe gib er mir denn nicht die aktuellen werte ?

MathiasSimmack 12. Mai 2004 20:34

Re: ListView, Icon und SHGetFileInfo
 
Zitat:

Zitat von HomerGER
im Explorer waren sie immer da
aber dann auch nur wenn ich auf vsIcon gestellt habe bei vsReport hat er überhaupt kein icon angezeigt auch nicht das standard

Also waren sie im Explorer offenbar doch nicht immer da. Evtl. ein Aktualisierungsproblem auf deinem Rechner, das aber dann am Windows liegt. Musst du mal in den Einstellungen schauen, ob du da versehentlich was verstellt hast.

Zitat:

2 frage noch zu deinem code
warum benutzt du TListItem und übergibst es nicht direkt an ListView

li.ImageIndex := fi.iIcon; und nicht ListView.ImageIndex := fi.iIcon;
Weil das, was du da geschrieben hast, Quatsch wäre. ;)
Delphi-Quellcode:
ListView.ImageIndex
bringt´s glaube ich nicht. Du meinst wahrscheinlich
Delphi-Quellcode:
ListView.Items[ListView.Items.Count-1].ImageIndex
und da deklariere ich mir dann doch lieber eine lokale Variable, weil es sich einfacher arbeiten lässt. Und Ja: Es mag sein, dass das in Delphi 6 oder 7 einfacher geht. Aber ich finde D7 nicht gerade prickelnd, und darum bleibe ich nach wie vor lieber bei Delphi 5.

Zitat:

was bring das
ListView1.Items.BeginUpdate;
ListView1.Items.EndUpdate;
Einen beschleunigten Aufbau bzw. ein etwas schnelleres Laden des Programms, weil die Werte im Hintergrund geladen werden. Das Control (die List-View in dem Fall) zeigt sie allerdings nicht an. Erst wenn das "EndUpdate" kommt, wird das Control aktualisiert. Das macht sich speziell dann sehr schön, wenn du eine ganze Latte an Einträgen hast, die u.U. auch sehr langsam laden.

Im Normalfall guckst du zu, wie die Einträge nacheinander irgendwo reingeschrieben werden. Mit "BeginUpdate" und "EndUpdate" beschleunigst du den Prozess ein bisschen.

Steht in der Hilfe genauer.

HomerGER 12. Mai 2004 21:06

Re: ListView, Icon und SHGetFileInfo
 
Zitat:

Also waren sie im Explorer offenbar doch nicht immer da. Evtl. ein Aktualisierungsproblem auf deinem Rechner, das aber dann am Windows liegt. Musst du mal in den Einstellungen schauen, ob du da versehentlich was verstellt hast.
im exlporer waren sie IMMER DA !
nur nicht im ListView, nicht in meinem code und nicht in deinem Code


thx für die antworten
werde mein code umbauen

HomerGER 13. Mai 2004 11:03

Re: ListView, Icon und SHGetFileInfo
 
ich habe leider noch ein Problem

mein LV steht auf vsReport
In der SmallImages eine ImageList (LargeImage ist ja nur für vsIcon)
aus dieser ImagesList kommen die Icon für die Columns

jetzt lese ich dateien/laufwerke aus dem System ein
und möchte aus SHFIleInfo das passende Icon haben
dieses Icon soll dann in der ListView angezeigt werden

jetzt brauch ich aber noch eine ImagesList, und wie bekomme ich die ins ListView ohne die ImagesList für die Columns zu überschreiben?

MathiasSimmack 13. Mai 2004 12:16

Re: ListView, Icon und SHGetFileInfo
 
IMHO wirst du da wohl auf das API ausweichen müssen, weil die VCL-List-View eben nur "SmallImages" und "LargeImages" kennt. Die Spalten gehören aber zu einem separaten Control (genannt "Header"), und dem Ding kann man über das API eigene Pics verpassen.

Als Anregung empfehle ich dir den List-View-Beitrag in den Win32-API-Tutorials für Delphi von Luckie. Stichwort: "Die Sortierrichtung im Spaltenkopf anzeigen". Da geht es zwar nur darum, den Sortierpfeil korrekt anzuzeigen, aber das Prinzip ist ja eben genau das: Eine Bitmap auf dem jeweiligen Spaltenkopf zu platzieren.

Musst mal schauen ob dir das irgendwie hilft.


@Daniel: Ich fordere ein Update der "bbcode.php", die das Vorkommen von Win32-API-Tutorials für Delphi automatisch in einen Link auf Luckies Homepage umbaut. :mrgreen:

HomerGER 13. Mai 2004 14:29

Re: ListView, Icon und SHGetFileInfo
 
hab die Icon in den Columns weggelassen

nur hab ich jetzt folgenden effekt

ich hab 2 ListView

lass ich mir in ListView1 alle dateien anzeigen zeigt auch die Icon zu den Dateien
lass ich mir dann ListView2 die Dateien anzeigt zeigt er AUCH die Icon an

nun kommt es

start ich das programm neu und laß mir erst die Dateien in ListView2 anzeigen sind keine Icon da
lass ich sie dann wieder in ListView2 anzeigen sind sie da und kann ich sie mir auch in ListView1 anzeigen lassen

Delphi-Quellcode:
//******************************************************************************
//IE CookieCache lesen
Procedure IECache_Cookie_Lesen_IECU();
var
ie_cache : PINTERNETCACHEENTRYINFO;
size_dw : DWord;
cache_dir_dw : DWord;
icon_list_il : HImageList;
list_item_li : TListItem;
file_info_fi : TSHFileInfo;
begin
    //Icon laden
    icon_list_il := HImageList(SHGetFileInfo('', 0, file_info_fi, SizeOf(file_info_fi), SHGFI_SYSICONINDEX or SHGFI_ICON));

    if (icon_list_il <> 0) then
    begin
        Haupt_Form.Wartung_Temp_ImageList1.Handle := icon_list_il;
        Haupt_Form.Wartung_Temp_ImageList1.Height := 16;
        Haupt_Form.Wartung_Temp_ImageList1.Width := 16;
    end;

    Haupt_Form.Wartung_ListView01.Items.BeginUpdate;
    Haupt_Form.Wartung_ListView01.Items.Clear;

    size_dw := 65536;
    ie_cache   := AllocMem(size_dw);

    try
        cache_dir_dw := FindFirstUrlCacheEntry(NIL, ie_cache^,size_dw);

        while cache_dir_dw <> 0 do
        begin
            Application.ProcessMessages;

            if ((ie_cache^.CacheEntryType AND COOKIE_CACHE_ENTRY) = COOKIE_CACHE_ENTRY) then
            begin
                //Name
                list_item_li := Haupt_Form.Wartung_ListView01.Items.Add;
                list_item_li.Caption := ie_cache^.lpszSourceUrlName;

                //Icon
                SHGetFileInfo(ie_cache^.lpszLocalFileName, 0, file_info_fi, SizeOf(file_info_fi), SHGFI_SYSICONINDEX or SHGFI_ICON);
                list_item_li.ImageIndex := file_info_fi.iIcon;

                //Grösse
                list_item_li.SubItems.Add(Datei_Groesse_Format_GU(Datei_Groesse_GU(ie_cache.lpszLocalFileName)));
            end;

            size_dw := 65536;

            if not FindNextURLCacheEntry(cache_dir_dw,ie_cache^,size_dw) then
            begin
                cache_dir_dw := 0;
            end;
        end;
    finally
        FreeMem(ie_cache,65536);
        Haupt_Form.Wartung_ListView01.Items.EndUpdate;
    end;
end;


//******************************************************************************
//IE URLHistoryCache lesen Verläufe
Procedure IECache_URLHistory_Lesen_IECU();
var
ie_cache : PINTERNETCACHEENTRYINFO;
size_dw : DWord;
cache_dir_dw : DWord;
icon_list_il : HImageList;
list_item_li : TListItem;
file_info_fi : TSHFileInfo;
begin
    //Icon laden
    icon_list_il := HImageList(SHGetFileInfo('', 0, file_info_fi, SizeOf(file_info_fi), SHGFI_SYSICONINDEX or SHGFI_ICON));

    if (icon_list_il <> 0) then
    begin
        Haupt_Form.Wartung_Temp_ImageList1.Handle := icon_list_il;
        Haupt_Form.Wartung_Temp_ImageList1.Height := 16;
        Haupt_Form.Wartung_Temp_ImageList1.Width := 16;
    end;      

    Haupt_Form.Wartung_ListView11.Items.BeginUpdate;
    Haupt_Form.Wartung_ListView11.Items.Clear;

    size_dw := 65536;
    ie_cache   := AllocMem(size_dw);

    try
        cache_dir_dw := FindFirstUrlCacheEntry(NIL, ie_cache^,size_dw);

        while cache_dir_dw <> 0 do
        begin
            Application.ProcessMessages;

            if (ie_cache^.CacheEntryType AND URLHISTORY_CACHE_ENTRY) = URLHISTORY_CACHE_ENTRY then
            begin
                //Name
                list_item_li := Haupt_Form.Wartung_ListView11.Items.Add;
                list_item_li.Caption := ie_cache^.lpszSourceUrlName;

                //Icon
                SHGetFileInfo(ie_cache^.lpszLocalFileName, 0, file_info_fi, SizeOf(file_info_fi), SHGFI_SYSICONINDEX or SHGFI_ICON);
                list_item_li.ImageIndex := file_info_fi.iIcon;
            end;

            size_dw := 65536;

            if not FindNextURLCacheEntry(cache_dir_dw,ie_cache^,size_dw) then
            begin
                cache_dir_dw := 0;
            end;
        end;
    finally
        FreeMem(ie_cache,65536);
        Haupt_Form.Wartung_ListView11.Items.EndUpdate;
    end;
end;


Es ist aber immer nur eine ListView sichbar

kannst du helfen ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz