tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von pschilling
ERLEDIGT
JA
ANTWORTEN
14
ZUGRIFFE
623
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hallo ...
    wie kann ich in einem CListCtrl Dateien und Verzeichnisse anzeigen? Ich weis, dass es da die Methode DlgDirList gibt, Aber irgendwie komme ich mit der gar nicht klar. Rückgabewert ist 1, aber die Liste bleibt leer.

    Keine Ahnung, was ich da machen soll.

    Danke für eure Hilfe
     

  2. #2
    Avatar von pschilling
    pschilling pschilling ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Ort
    Duisburg (NRW)
    Beiträge
    192
    Hallo,

    schreibs dir doch in etwa so:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
     
    void listDirectory(CString path) {
      CFileFind ff;
      BOOL bContinue = ff.FindFile(path + "\\*");
      while( bContinue ) {
        bContinue = ff.FindNextFile();
        CString fPath = ff.GetFilePath();
        CString fName = ff.GetFileName();
        if( fName == "." || fName == ".." ) {
          continue;
        }
        UINT attrs = GetFileAttributes(fPath);
        if( (attrs&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) {
          // Verzeichnis
          myListCtrl.InsertItem(0,fName);
        }
        else {
          // Datei
          myListCtrl.InsertItem(1000,fName);
        }
      }
      ff.Close();
    }

    Sollte dir weiterhelfen, denke ich.. Wenn du noch so Sachen wie Dateigröße und so darstellen willst schau dir die Klasse CFileStatus an..

    Viel Erfolg...


    Pit
     
    Der Computer wird das tun, was du programmierst - nicht das, was du willst ;-)

  3. #3
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hi...

    Danke danke... wird mir bestimmt weiterhelfen, auch wenn ich schon über die WinApi gelöst habe. Von den beiden Klassen war mir bisher nichts bekannt. Werd sie mir mal ansehen.

    Was mir jetzt noch fehlt ist die Darstellung der Systemicons... Ein manueller Vergleich der Dateierweiterung ist mir zu aufwendig, und lediglich Icons für Dateien und Directorys ist mir zu wenig und sieht weniger professionell aus. Kannst du mir da auch weiterhelfen ?

    Danke

    Stefan
     

  4. #4
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Hallo,

    schaue dir mal die API-Funktion SHGetFileInfo an. Damit bekommst du auch das der der Datei zugeordnete Icon heraus.

    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  5. #5
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Ja stimmt, abe ich habs bis jetzt noch nicht geschafft, das Icon in mein über das Studio erstellte CListCtrl einzubinden, bzw. die SystemIconList dem CListCtrl zuzuordnen oder die entsprechenden Icons in meine eigene Imagelist zu kopieren.

    Vielleicht könnt ihr da ja auch helfen.


    Danke
    Stefan
     

  6. #6
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Wenn du den Dateipfad (strFilePath) und die Imagelist (m_imageList) schon hast, sollte das doch eigentlich kein Problem mehr sein:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    
    SHFILEINFO sfi; 
    SHGetFileInfo( strFilePath,
                   0,
                   &sfi,
                   sizeof(SHFILEINFO),
                   SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES ); 
     
    int nIndex = m_imageList.Add(sfi.hIcon); // Imagelist-Index für InsertItem
    Gruß
    MCoder
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  7. #7
    Avatar von pschilling
    pschilling pschilling ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Ort
    Duisburg (NRW)
    Beiträge
    192
    Hallo MCoder, hallo Stefan,

    wenn du es über eine eigene Imagelist macht, muss du den Index des Images aufgrund des Typ, der Extension selbst pflegen und so.

    Das willst du glaub ich nicht.

    Wenn du dich um gar nix kümmern willst, mach es einfach so:

    Halte dir eine Membervariable vom Typ CImageList (In meinem Bsp. m_imgList)

    Beim Initialisieren deines Views oder Dialogs schreibst du folgendes:

    Code :
    1
    2
    3
    
        HIMAGELIST hSysImgList = (HIMAGELIST)SHGetFileInfo("C:\\", 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX ); // Liefert das Handle der System-Image-List
        m_imgList.Attach(hSysImgList); // Diese attachen wir an unser CImageList Objekt
        m_cList.SetImageList(&m_imgList, LVSIL_SMALL); // Und hängen unsere Imagelist an das Listcontrol.

    Diese ImageList darfst du aber nicht verändern

    Beim Einfügen eines Objektes in dein Listcontrol:
    Code :
    1
    2
    3
    4
    5
    
            memset(&fi,0,sizeof(SHFILEINFO));
            SHGetFileInfo(fPath, 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX  );
            if( (attrs&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) {
                // Verzeichnis
                m_cList.InsertItem(0,fName,fi.iIcon);

    So bekommst du garantiert die Icons für deine Objekte angezeigt, die auch der Explorer verwendet..

    Der obige Code gilt nur für die kleinen Images... Für die grossen musst du halt SHGFI_ICON und LVSIM_NORMAL verwenden..
    Schönen Gruß,

    Pit
    Geändert von pschilling (06.11.08 um 14:47 Uhr)
    MCoder bedankt sich. 
    Der Computer wird das tun, was du programmierst - nicht das, was du willst ;-)

  8. #8
    MCoder MCoder ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jul 2005
    Ort
    München
    Beiträge
    2.448
    Das vereinfacht die Sache doch erheblich
     
    "The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
    --- Larry Wall

  9. #9
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hallo pschilling, Hallo MCoder,

    vielen Dank erstmal für eure Hilfe...

    habe es schon mit pschillings Methode versucht, hat aber nie geklappt. Vieleichts tuts das ja diesmal.

    Ich nehm an, fi ist ein e SHFILEINFO struktur, und cList ein CListCtrl ?

    was aber ist memset

    Danke und schönen Gruss

    Stefan
     

  10. #10
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hallo ...

    habs jetzt mit folgendem Code probiert:


    void CTest4Dlg::Init()
    {
    SHFILEINFO fi;

    HIMAGELIST hSysImgList = (HIMAGELIST)SHGetFileInfo("C:\\", 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX ); // Liefert das Handle der System-Image-List
    m_imgList.Attach(hSysImgList); // Diese attachen wir an unser CImageList Objekt
    m_fileList.SetImageList(&m_imgList, LVSIL_SMALL); // Und hängen unsere Imagelist an das Listcontrol.

    memset(&fi,0,sizeof(SHFILEINFO));
    SHGetFileInfo("C:\\AUTOEXEC.BAT", 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX );
    // if( (fi.dwAttributes&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) {
    // Verzeichnis
    m_fileList.InsertItem(0,"tst",fi.iIcon);//}
    }

    Das Ergebnis ist nicht grad zufriedenstellend.... Abgesehen davon, das die Bezeichnung "tst" in die Liste eingetragen wird tut sich nichts.

    Warum nur ?

    Guss
    Stefan
     

  11. #11
    Avatar von pschilling
    pschilling pschilling ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Ort
    Duisburg (NRW)
    Beiträge
    192
    Hi Stefan,

    du musst des von mir auch richtig lesen/übernehmen

    Ich denke, Init ist eine Methode, welche du in deiner OnInitDialog-Methode aufrufst.

    Dort darfst du nur folgenden Code ausführen:

    Code :
    1
    2
    3
    4
    5
    
    SHFILEINFO fi;
     
    HIMAGELIST hSysImgList = (HIMAGELIST)SHGetFileInfo("C:\\", 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX ); // Liefert das Handle der System-Image-List
    m_imgList.Attach(hSysImgList); // Diese attachen wir an unser CImageList Objekt
    m_fileList.SetImageList(&m_imgList, LVSIL_SMALL); // Und hängen unsere Imagelist an das Listcontrol.

    Das führt dazu, dass die System-Image-List in deiner Klassen-Member-Variablen m_imgList gespeichert wird.

    Dann hast du sicherlich noch eine Methode, welche dir die Liste mit dem Inhalt eines beliebigen Verzeichnisses gefüllt wird. Ich nenne diese mal fillDirContent(CString path);

    die kann dann so in etwa so aussehen:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
        void CMyDlg::fillDirContent(CString path) {
      SHFILEINFO fi;
      CFileFind ff;
      BOOL bContinue = ff.FindFile(path + "\\*");
      while( bContinue ) {
        bContinue = ff.FindNextFile();
        CString fPath = ff.GetFilePath();
        CString fName = ff.GetFileName();
        if( fName == "." || fName == ".." ) {
          continue;
        }
        memset(&fi,0,sizeof(SHFILEINFO));
        SHGetFileInfo(fPath, 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX );
        UINT attrs = GetFileAttributes(fPath);
        if( (attrs&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) {
          // Verzeichnis, vorne Einfügen, sortierung kannst du hier auch einbauen ;-)
          myListCtrl.InsertItem(0,fName);
        }
        else {
          // Datei, hinten einfügen, sortierung kannst du hier auch einbauen ;-)
          myListCtrl.InsertItem(10000,fName);
        }
      }
      ff.Close();
     
     
        }

    Also die kleine Demo die ich dafür gecoded habe funktioniert super so
    Lese die MSDN zu meinen verwendeten Methoden und probiere etwas rum!

    Ich bin sicher du wirst bekommen, was du dir vorgestellt hast

    Grüße,

    Pit
    Geändert von pschilling (10.11.08 um 11:51 Uhr)
     
    Der Computer wird das tun, was du programmierst - nicht das, was du willst ;-)

  12. #12
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hallo Pit..

    Also irgendwie will das ganze bei mir nicht so richtig. ich häng mal meine header und die .cpp dran. Vielleicht findest du ja den Fehler.

    // test4Dlg.h : Header-Datei
    //

    #if !defined(AFX_TEST4DLG_H__B0665D22_91EE_47DC_946D_AFB6EDD16044__INCLUDED_)
    #define AFX_TEST4DLG_H__B0665D22_91EE_47DC_946D_AFB6EDD16044__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    /////////////////////////////////////////////////////////////////////////////
    // CTest4Dlg Dialogfeld

    class CTest4Dlg : public CDialog
    {
    // Konstruktion
    public:
    void setList (CString pfad);
    void Init();
    CImageList m_imgList;
    CTest4Dlg(CWnd* pParent = NULL); // Standard-Konstruktor

    // Dialogfelddaten
    //{{AFX_DATA(CTest4Dlg)
    enum { IDD = IDD_TEST4_DIALOG };
    CListCtrl m_fileList;
    //}}AFX_DATA

    // Vom Klassenassistenten generierte Überladungen virtueller Funktionen
    //{{AFX_VIRTUAL(CTest4Dlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung
    //}}AFX_VIRTUAL

    // Implementierung
    protected:
    HICON m_hIcon;

    // Generierte Message-Map-Funktionen
    //{{AFX_MSG(CTest4Dlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnButton1();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

    #endif // !defined(AFX_TEST4DLG_H__B0665D22_91EE_47DC_946D_AFB6EDD16044__INCLUDED_)


    // test4Dlg.cpp : Implementierungsdatei
    //

    #include "stdafx.h"
    #include "test4.h"
    #include "test4Dlg.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // CTest4Dlg Dialogfeld

    CTest4Dlg::CTest4Dlg(CWnd* pParent /*=NULL*/)
    : CDialog(CTest4Dlg::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CTest4Dlg)
    // HINWEIS: Der Klassenassistent fügt hier Member-Initialisierung ein
    //}}AFX_DATA_INIT
    // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }

    void CTest4Dlg:oDataExchange(CDataExchange* pDX)
    {
    CDialog:oDataExchange(pDX);
    //{{AFX_DATA_MAP(CTest4Dlg)
    DDX_Control(pDX, IDC_flist, m_fileList);
    //}}AFX_DATA_MAP
    }

    BEGIN_MESSAGE_MAP(CTest4Dlg, CDialog)
    //{{AFX_MSG_MAP(CTest4Dlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CTest4Dlg Nachrichten-Handler

    BOOL CTest4Dlg::OnInitDialog()
    {
    CDialog::OnInitDialog();

    // Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    // wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    SetIcon(m_hIcon, TRUE); // Großes Symbol verwenden
    SetIcon(m_hIcon, FALSE); // Kleines Symbol verwenden

    // ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
    Init();
    return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }

    // Wollen Sie Ihrem Dialogfeld eine Schaltfläche "Minimieren" hinzufügen, benötigen Sie
    // den nachstehenden Code, um das Symbol zu zeichnen. Für MFC-Anwendungen, die das
    // Dokument/Ansicht-Modell verwenden, wird dies automatisch für Sie erledigt.

    void CTest4Dlg::OnPaint()
    {
    if (IsIconic())
    {
    CPaintDC dc(this); // Gerätekontext für Zeichnen

    SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

    // Symbol in Client-Rechteck zentrieren
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;

    // Symbol zeichnen
    dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
    CDialog::OnPaint();
    }
    }

    // Die Systemaufrufe fragen den Cursorform ab, die angezeigt werden soll, während der Benutzer
    // das zum Symbol verkleinerte Fenster mit der Maus zieht.
    HCURSOR CTest4Dlg::OnQueryDragIcon()
    {
    return (HCURSOR) m_hIcon;
    }

    void CTest4Dlg::Init()
    {
    SHFILEINFO fi;

    HIMAGELIST hSysImgList = (HIMAGELIST)SHGetFileInfo("C:\\", 0, &fi, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX ); // Liefert das Handle der System-Image-List
    m_imgList.Attach(hSysImgList); // Diese attachen wir an unser CImageList Objekt
    m_fileList.SetImageList(&m_imgList, LVSIL_SMALL); // Und hängen unsere Imagelist an das Listcontrol.


    }


    void CTest4Dlg::OnButton1()
    {
    // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen
    setList("c:");

    }

    void CTest4Dlg::setList(CString pfad)
    {
    SHFILEINFO fi;
    CFileFind ff;
    BOOL bContinue = ff.FindFile(pfad+"\\*");
    while (bContinue) {
    bContinue=ff.FindNextFile();
    CString fPath=ff.GetFilePath();
    CString fName=ff.GetFileName();
    if (fName=="." || fName=="..") {
    continue;
    }
    memset(&fi,0,sizeof(SHFILEINFO));
    SHGetFileInfo(fPath,0,&fi,sizeof(SHFILEINFO),SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
    UINT attrs=GetFileAttributes(fPath);
    m_fileList.InsertItem(0,fName,fi.iIcon);
    }
    ff.Close();
    }



    Danke dir schon mal....

    und allen anderen die helfen wollen natürlich auch.

    Stefan
     

  13. #13
    Avatar von pschilling
    pschilling pschilling ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Ort
    Duisburg (NRW)
    Beiträge
    192
    Hallo Stefan,

    du fügst ja auch nirgendwo Spalten in deiner Liste ein

    Erzeuge dir in deiner Init-Methode für jede Information, die du darstellen möchtest eine Spalte!

    also ca. so :

    Code :
    1
    2
    3
    4
    5
    6
    7
    
       m_fileList.InsertColumn(0,"Name");
       m_fileList.InsertColumn(1,"Größe");
       m_fileList.InsertColumn(2,"Typ");
    // Setze Standardwerte für die Breite der einzelnen Spalten
      m_fileList.SetColumnWidth(0,100);
      m_fileList.SetColumnWidth(1,100);
      m_fileList.SetColumnWidth(2,100);

    Nach dem Einfügen eines neuen Elementes setzt du die Werte der weiteren Spalten dann so :

    Code :
    1
    2
    3
    
        int pos = m_fileList.InsertItem(0,fileName, fi.iIcon);
        m_fileList.SetItemText(pos,1, fileSize);
        m_fileList.SetItemText(pos,2, fileType);

    Dann funktioniert es auch mit deiner Dateiliste

    Schönen Gruß,

    Peter
    Geändert von pschilling (11.11.08 um 09:58 Uhr)
     
    Der Computer wird das tun, was du programmierst - nicht das, was du willst ;-)

  14. #14
    stefan-rw stefan-rw ist offline Mitglied
    Registriert seit
    Oct 2008
    Beiträge
    24
    Hallo Pit ...

    Stimmt, jetzt wo ich die Spalten hinzugefügt habe funktioniert es. Das ist ja n sch...

    Wer soll denn darauf kommen ? Zumal man ja keine Spalten definieren muss, wenn man mit eigenen Images in einer eigenen Imagelist arbeitet.

    Vielen vielen Dank ...

    Gruss
    Stefan
     

  15. #15
    Avatar von pschilling
    pschilling pschilling ist offline Mitglied Gold
    Registriert seit
    Apr 2007
    Ort
    Duisburg (NRW)
    Beiträge
    192
    Hi und schön, dass es endlich funktioniert ..

    Hat ja auch lang genug gedauert

    Vegiss bitte nicht, deinen Beitrag als erledigt zu markieren..

    Thx..

    Bis zum nächsten Post,

    Pit
     
    Der Computer wird das tun, was du programmierst - nicht das, was du willst ;-)

Ähnliche Themen

  1. Files/Folder anzeigen
    Von heliii im Forum PHP
    Antworten: 0
    Letzter Beitrag: 23.05.07, 13:42
  2. Files im Serververzeichnis anzeigen
    Von dav133 im Forum Hosting & Webserver
    Antworten: 1
    Letzter Beitrag: 07.06.05, 23:11
  3. Antworten: 22
    Letzter Beitrag: 01.06.05, 15:53
  4. PDF-Files laden und anzeigen
    Von jorgeHX im Forum Java
    Antworten: 13
    Letzter Beitrag: 10.05.05, 16:51
  5. CListCtrl Scrollbar immer anzeigen
    Von Topsen im Forum VisualStudio & MFC
    Antworten: 1
    Letzter Beitrag: 10.12.04, 17:17