Wie kann man Dateien per Drag & Drop auf einen Button ablegen und auswerten



  • Hallo,

    Ich möchte eine Datei oder auch mehrere) von außerhalb der Anwendung per Drag & Drop auf einen Button in meine Anwendung dropen können. Ich weis leider nicht wie Ich es realisieren soll? Kann mir da einer ein Beispiel posten? Wäre super nett :-).





  • Das Beispiel kenne ich^^, das Problem ist das die Aktion erst passieren soll wenn die Datei auf den Button gedropt wird.

    die Anwendung hat mehrere Buttons die unterschiedliche Kategorien haben:

    button1 button2 button3
    [schriften] [eps] [bilder]

    das Beispiel von dem link nimmt jede Datei an die in die Anwendung gedropt wird, damit kann ich die Selektion in den verschiedenen Kategorien nicht machen, es soll ja auch nur passieren wenn es auf einen von den 3 knöpfen gedropt wird.



  • am liebsten wäre es mir wenn der drop diese Button Funktion ausführen würde, in dem ich dann den Dateiname zur verfügung hätte:

    void __fastcall TForm1::Button1DragDrop(TObject *Sender, TObject *Source,
          int X, int Y)
    {
     // wie kann ich den dateinamen ermitteln ? der gedropt wurde ?
    
    }
    

    wie kann man in dieser Funktion erstmal das annehmen der Dateien erlauben?

    void __fastcall TForm1::Button1DragOver(TObject *Sender, TObject *Source,
          int X, int Y, TDragState State, bool &Accept)
    {
     Accept=true;
    }
    


  • Wenn du Dateien auf deine Anwendung droppen willst, kommst du nicht ohne die WMDrop-Message aus.
    Du müßtest dadrin dann überprüfen, ob der Mauscursor gerade über einem deiner Buttons ist und sonst das Droppen ignorieren.
    Mittels Mouse->CursorPos kommst du an die aktuelle Mausposition (absolute Screenkoordinaten). Nun einfach die (absoluten) Button-Koordinaten damit verglichen, d.h. du schreibst dir am besten eine Funktion IsPointInRect(..).

    P.S. Die Events OnDragDrop etc. funktionieren nur innerhalb der Anwendung, nicht bei Interaktion mit anderen Programmen (z.B. Explorer).



  • eine super idee, nur ich weiss nicht wie ich es programmieren soll? und was passiert wenn die die göße des fensters verändern wird, klappt das dann auch noch?



  • wie ich an die maus posi komme weiss ich jetzt:

    void __fastcall TForm1::Timer2Timer(TObject *Sender)
    {
     Edit16->Text="maus x: "+IntToStr(Mouse->CursorPos.x)+" y:"+IntToStr(Mouse->CursorPos.y);
    }
    

    nur wie komme ich an die (absoluten) button-koordinaten ran ? muss ich da was umrechnen?



  • Da gibt es doch eine Funktion namens ControlAtPos in TWinControl (also auch TForm).



  • Braunstein schrieb:

    Da gibt es doch eine Funktion namens ControlAtPos in TWinControl (also auch TForm).

    TPoint posi;
     Button1->ControlAtPos(posi,true,true);
    
     Edit16->Text="knopf x: "+IntToStr(posi.x)+" y: "+IntToStr(posi.y)+" | maus x: "+IntToStr(Mouse->CursorPos.x)+" y:"+IntToStr(Mouse->CursorPos.y);
    

    danke für den tip nur wie rechne ich es um?

    http://www.budbrain.de/koords.jpg

    auf dem screenshoot bin ich ganz links oben in der buttonecke die maus wurde beim capture nicht erfasst.



  • Schau noch mal in die Hilfe zu ControlAtPos. Die Funktion gibt dir einen Pointer auf das Control an der angegebenen Position (oder 0) zurück. Man kann das etwa so verwenden.

    TPoint point = Mouse->CursorPos; //Cursorposition in globalen Koordinaten holen
    point = Form1->ScreenToClient(point); //Umrechnen globale auf Form-lokale Koordinaten
    TControl* control = Form1->ControlAtPos(point, true, true); //Ist an der Position ein Control
    if( control ) // Ja, da ist ein Control, nur welches?
    {
       TButton* button = dynamic_cast<TButton*>(control);
       if( button ) // Es ist also ein Button
       {
    // Nun hast du einen Button gefunden und kannst etwas damit machen
       }
    }
    


  • Braunstein schrieb:

    Schau noch mal in die Hilfe zu ControlAtPos. Die Funktion gibt dir einen Pointer auf das Control an der angegebenen Position (oder 0) zurück. Man kann das etwa so verwenden.

    TPoint point = Mouse->CursorPos; //Cursorposition in globalen Koordinaten holen
    point = Form1->ScreenToClient(point); //Umrechnen globale auf Form-lokale Koordinaten
    TControl* control = Form1->ControlAtPos(point, true, true); //Ist an der Position ein Control
    if( control ) // Ja, da ist ein Control, nur welches?
    {
       TButton* button = dynamic_cast<TButton*>(control);
       if( button ) // Es ist also ein Button
       {
    // Nun hast du einen Button gefunden und kannst etwas damit machen
       }
    }
    

    Super das ist es fast :-), nur ich hab 5 knöpfe ich muss da unterscheiden können auf welchen er jetzt grad was draufgeschoben hat, auf einen Knopf werden nur Schriften gezogen, auf den anderen nur Grafiken usw..

    if( button11 )
    {
    }

    if( button12 )
    {
    }



  • Hallo

    Benutzt die Eigenschaft TButton::Tag, um die Buttons eindeutig zu markieren und auseinanderzuhalten.

    bis bald
    akari



  • akari schrieb:

    Hallo

    Benutzt die Eigenschaft TButton::Tag, um die Buttons eindeutig zu markieren und auseinanderzuhalten.

    bis bald
    akari

    void __fastcall TForm1::WmDropFiles(TWMDropFiles& Message)
    {
     AnsiString Datei,vDatei,zDatei,zieldatei;
     int flag;
     char buff[MAX_PATH];
     HDROP hDrop = (HDROP)Message.Drop;
    
     TPoint point = Mouse->CursorPos; //Cursorposition in globalen Koordinaten holen
     point = Form1->ScreenToClient(point); //Umrechnen globale auf Form-lokale Koordinaten
     TControl* control = Form1->ControlAtPos(point, true, true); //Ist an der Position ein Control
     if( control ) // Ja, da ist ein Control, nur welches?
     {
      TButton* button = dynamic_cast<TButton*>(control);
      if( button ) // Es ist also ein Button
      {
    
       // knopf
       if(button->Tag==1)
       {
        int numFiles = DragQueryFile(hDrop,-1, NULL, NULL);
        for (int i=0;i<numFiles;i++)
        {
         DragQueryFile(hDrop, i, buff, sizeof(buff));
    
         Datei=StrPas(buff);
         vDatei=Datei.LowerCase();
    
         zDatei=ExtractFileName(Datei);
         zieldatei="c:\\"+zDatei;
         flag=0;
    
         // .lnk ablehnen
         if(vDatei.Pos(".lnk")!=0)
          flag=1;
    
         if(flag==0)
         {
          ShowMessage("Datei: "+StrPas(buff));
          //::CopyFile(Datei.c_str(), zieldatei.c_str(),FALSE);
         }
        }
       }
    
      }
     }
     DragFinish(hDrop);
    }
    

    vielen dank jetzt komme ich zum ziel! ihr habt mir sehr geholfen danke @all! super forum!



  • Hallo,

    zu diesem Thema hätte ich auch mal eine Frage:

    Warum löst das Event mit einer TListView nicht aus?

    Ich habe es schon mit einer TListBox versucht, damit funktioniert es auch einwandfrei.
    Aber da ich auf die Funktion, Icons vor die Einträge zu platzieren, angewiesen bin, und eine TListBox meines Wissens eine solche Funktion nicht beinhaltet, muss ich eine TListView verwenden.

    void __fastcall TfrmMain::WMDropFiles(TWMDropFiles &Message)
    {
         AnsiString sFile;
         char chBuff[MAX_PATH];
         HDROP hDrop = (HDROP)Message.Drop;
    
         int iFileCount = DragQueryFile(hDrop,-1, NULL, NULL);
    
         for( int i = 0; i < iFileCount; i++ ){
             DragQueryFile(hDrop, i, chBuff, sizeof(chBuff));
    
             sFile = StrPas(chBuff).LowerCase();
    
             if( ( sFile.Pos(".zip") != 0 ) &&
                 ( iFileCount == 1 ) &&
                 ( sPath_e.IsEmpty() ) )
             {
                dlgOpen->FileName = sFile;
                open();
                return;
             }
    
             dlgAdd->FileName = sFile;
             add();
    
             DragFinish(hDrop);
         }
    }
    
    void __fastcall TfrmMain::FormCreate(TObject *Sender)
    {
        DragAcceptFiles(lvwFiles->Handle, true);    
    }
    

    Ich hoffe es kann mir einer helfen.

    Gruß FightingWolf



  • Augen auf! Wurde gerade erst besprochen: http://www.c-plusplus.net/forum/viewtopic-var-t-is-189881.html


Anmelden zum Antworten