TListView Drag&Drop / DragAcceptFiles ?



  • Hallo,

    Wie kann ich eine TListview Drag und Drop-fähig machen,
    sodaß ich Dateien in diese ziehen kann ?

    In dem Beispiel hier funktioniert das aber hierbei ist das gesamte
    Form Drag und Drop-fähig das soll aber nur dann funktionieren
    wenn der Mousezeiger über die ListView steht.

    Wäre cool mir jemand helfen kann.

    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
            void __fastcall FormCreate(TObject *Sender);
    private:	// Anwender-Deklarationen
            void __fastcall WMDropFiles(TWMDropFiles &Message);
    public:		// Anwender-Deklarationen
            __fastcall TForm1(TComponent* Owner);
    
            TListView *ListView1;
            TListItem *Titem;
    
            BEGIN_MESSAGE_MAP
                    MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,WMDropFiles)
            END_MESSAGE_MAP(TForm)
    };
    
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {    
            this->Width = 400;
            this->Height = 250;
    
            ListView1 = new TListView(this);
            ListView1->Parent = Form1;
            ListView1->Name = "TL";
            ListView1->Top = 5;
            ListView1->Height = 150;
            ListView1->RowSelect = true;
            ListView1->ViewStyle = vsReport;
            ListView1->Width = this->Width - 8;
    
            //Zwei Spalten einfügen
            TListColumn  *NewColumn;
            NewColumn = ListView1->Columns->Add();
            NewColumn->Caption = "FilePfad/FileName";
            NewColumn->Width = 270;
            // eine zweite Spalte mal dahinter
            NewColumn = ListView1->Columns->Add();
            NewColumn->Caption = "DateiName-Länge";
            NewColumn->Width = 110;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
            //DragAcceptFiles(ListView1->Handle , True); //funzt nicht
            DragAcceptFiles(Handle, True);
    }
    
    void __fastcall TForm1::WMDropFiles(TWMDropFiles &Message)
    {
            int ilFilesCount, ilStrLength;
            char caFileName[MAX_PATH];
    
            // Anzahl der Dateien bestimmen:
            ilFilesCount=DragQueryFile((HDROP)Message.Drop,-1,NULL,0);
    
            for(int ilIndex=0; ilIndex<ilFilesCount; ilIndex++)
            {
                    // Länge des Dateinamens bestimmen:
                    ilStrLength=DragQueryFile((HDROP)Message.Drop,ilIndex,NULL,0);
                    // Dateinamen in char-Array caFileName übernehmen:
                    DragQueryFile((HDROP)Message.Drop, ilIndex, caFileName, ilStrLength+1);
    
                    Titem = ListView1->Items->Add();
                    Titem->Caption = caFileName;
                    Titem->SubItems->Add(ilStrLength);
            }
    }
    


  • siehe bei ListView Ereignisse
    OnDragDrop
    OnDragOver
    in der Hilfe sind da auch Beispiele.



  • Soweit ich weis sind diese Events nur innerhalb des eigenen
    Programms anwendbar, nicht aber wenn von einem anderen
    fremden Programm bzw Fenster heraus etwas gezogen wird.

    bis denne





  • Tach,

    Habe doch glatt eine Lösung anzubieten.

    Mein Beispielprojekt:

    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
            void __fastcall FormCreate(TObject *Sender);
            void __fastcall FormDestroy(TObject *Sender);
    private:	// Anwender-Deklarationen
            void __fastcall OnDropFiles(TMessage Message);
    public:		// Anwender-Deklarationen
            __fastcall TForm1(TComponent* Owner);
    
            TListView *ListView1;
            TListItem *Titem;
    
            TWndMethod OriginalProc;
            void __fastcall SubClassProc(TMessage &Message);
    };
    
    void __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
            this->Width = 400;
            this->Height = 250;
    
            ListView1 = new TListView(this);
            ListView1->Parent = Form1;
            ListView1->Name = "LView";
            ListView1->Top = 5;
            ListView1->Height = 150;
            ListView1->RowSelect = true;
            ListView1->ViewStyle = vsReport;
            ListView1->Width = this->Width - 8;
    
            //Eine Spalten einfügen
            TListColumn  *NewColumn;
            NewColumn = ListView1->Columns->Add();
            NewColumn->Caption = "FilePfad/FileName";
            NewColumn->Width = 370;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
            OriginalProc = ListView1->WindowProc;
            ListView1->WindowProc = SubClassProc;
            DragAcceptFiles(ListView1->Handle , True);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnDropFiles(TMessage Message)
    {
            int ilFilesCount, ilStrLength;
            char caFileName[MAX_PATH];
            // Anzahl der Dateien bestimmen:
            ilFilesCount=DragQueryFile((HDROP)Message.WParam,-1,NULL,0);
    
            for(int ilIndex=0; ilIndex<ilFilesCount; ilIndex++)
            {
                    // Länge des Dateinamens bestimmen:
                    ilStrLength=DragQueryFile((HDROP)Message.WParam,ilIndex,NULL,0);
                    // Dateinamen in char-Array caFileName übernehmen:
                    DragQueryFile((HDROP)Message.WParam, ilIndex, caFileName, ilStrLength+1);
                    // ...und ab in die Listbox:
    
                    Titem = ListView1->Items->Add();
                    Titem->Caption = caFileName;
            }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::SubClassProc(TMessage &Message)
    {
            if(Message.Msg == WM_DROPFILES)
                    OnDropFiles(Message);
            else
                  OriginalProc(Message);
    }
    
    void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
            DragAcceptFiles(ListView1->Handle, false);
    }
    

    So das wäre dann DRAG&DROP in einer TListView,
    geht auch für andere Komponenten.

    BYE



  • Weiß auch zufällig jemand wie es in die andere Richtung funktioniert?
    Also wie ich aus einer TListView etwas auf z.B. den Desktop ziehen kann?

    Ich habe den DragMode schon auf dmAutomatic gesetzt aber ich bin Planlos wann ich welche Funktion aufrufen muss, damit ich z.B. CopyFile oder was auch immer verwenden kann, damit sich die Datei dann am "Drop-Ort" befindet.

    Weiß jemand Rat?



  • Hat keiner eine Idee?



  • Siehe zB. die Empfehlungen am Ende dieses Threads: http://groups.google.com/group/borland.public.cppbuilder.vcl.components.using/browse_thread/thread/509ed50f0a815fec/46dd8f2ed73fe46e

    Ohne WinAPI-Kenntnisse wirst du aber wohl nicht weit kommen.


Anmelden zum Antworten