Forms - Image (und andere Controls) per Drag'nDrop verschieben



  • Hi,
    kann mir jemand sagen wie ich ein Image per drag&drop auf einem TForm verschieben kann.......
    Danke!

    [ Dieser Beitrag wurde am 29.03.2002 um 17:26 Uhr von Jansen editiert. ]



  • Drag&Drop ? Wenn es nur darum geht, das Image auf der Form mit der Maus anderst zu plazieren, müsste das mit der selben Methode wie hier mit der Form beschrieben gehen. Musst halt nur anstatt der Form das Image angeben. Probiers mal aus, ich kann das gerade nicht für Dich tun images/smiles/icon_wink.gif



  • @Peter: Welches Handle solltest du nehmen können???
    @23.0: benutze folgenden Code!

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    int scX=0, scY=0, scDyn=0;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Image1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    scX = X;
    scY = Y;
    scDyn = 1;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    if (scDyn == 1 && scX - X < 0)
    Image1->Left = Image1->Left + (X - scX);
    if (scDyn == 1 && scX - X > 0)
    Image1->Left = Image1->Left - (scX - X);
    if (scDyn == 1 && scY - Y < 0)
    Image1->Top = Image1->Top + (Y - scY);
    if (scDyn == 1 && scY - Y > 0)
    Image1->Top = Image1->Top - (scY - Y);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    scDyn = 0;
    }
    //---------------------------------------------------------------------------
    


  • Den Code in Image1MouseMove() kann man auch kürzer gestalten:

    void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
      if(scDyn==1 && scX!=X)
         Image1->Left = Image1->Left + X - scX;
      if(scDyn==1 && scY!=Y)
         Image1->Top = Image1->Top + Y - scY;
    }
    


  • @maloo
    Hab jetzt erst in die BCB-Hilfe gucken können, war vorhin nur so eine Idee. You are right, TImage ist ja nicht von TWinControl abgeleitet und hat daher kein Handle. Schade images/smiles/icon_sad.gif
    Man könnte höchstens das TImage auf ein TPanel (Panel hat Handle) packen, kann dann aber nur im Bereich des Panels verschieben aber nicht indem man auf das Image klickt und zieht.
    Dann halt Deine beschriebene Methode images/smiles/icon_wink.gif



  • Peter, deine Idee mit dem Panel funktioniert gut. Ich hab' mal ein Snippet geschrieben, in dem die nicht von TWinControl abgeleiteten Steuerelemente zum Verschieben auf ein dynamisch erzeugtes TPanel gelegt werden. Diese Vorgehensweise ermöglicht das Verschieben aller von TControl abgeleiteten (also nahezu aller) visueller Steuerelemente:

    //-------- in der Header-Datei frmMain.h --------------
    
    class TForm1 : public TForm
    {
    
    ...
    
    private:
    
      // Zeiger auf Hilfs-TPanel zum Verschieben der Elemente:
      TPanel* pHelpPanel;
    
    public:
    
      // Botschaftsbehandlungsroutine für die Application
      void __fastcall OnAppMessage(tagMSG &Message, bool &Handled);
    
      // Funktion fürs Verschieben der Steuerelemente
      void __fastcall MoveControl(TControl* Sender);
    
      // Schreibt Positionen der Steuerelemente in die Ini-Datei
      bool SaveControlsPositions(void);
    
      // Positionen der Steuerelemente aus der Ini-Datei
      // lesen und wiederherstellen
      bool RestoreControlsPositions(void);
    ...
    
    };
    
    //--------------------------------------------------------
    
    //-------- frmMain.cpp --------------
    
    //---------------------------------------------------------------------------
    // OnShow-Eventhandler des Formulars
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
      // Hilfspanel zum Verschieben der Steuerelemente erzeugen
      pHelpPanel = new TPanel(this);
    
      pHelpPanel->Parent = this;
      pHelpPanel->BorderStyle = bsNone;
      pHelpPanel->BevelInner = bvNone;
      pHelpPanel->BevelOuter = bvNone;
      pHelpPanel->Caption = "";
      pHelpPanel->FullRepaint = false;
      pHelpPanel->Visible = false;
    
      // eigene Botschaftsbehandlungsroutine der Application zuweisen
      Application->OnMessage = OnAppMessage;
    
      // Positionen der Steuerelemente aus der Ini-Datei lesen und wiederherstellen
      RestoreControlsPositions();
    
    }
    
    //---------------------------------------------------------------------------
    // Botschaftsbehandlungsroutine der Application zum
    // Abfangen der Klicks mit der linken Maustaste
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnAppMessage(tagMSG &Message, bool &Handled)
    {
      // nur falls die linke Maustaste gedrückt wurde:
      if(Message.message == WM_LBUTTONDOWN)
      {
        // Zeiger auf das Steuerelement unter dem Mauscursor besorgen:
        TControl * pControl = ControlAtPos(ScreenToClient(
          Message.pt), false, true);
    
        // falls dieses Steuerelement NICHT die Checkbox "Steuerelemente
        // verschiebbar" ist und diese angeklickt ist:
        if(pControl != chkAllowMove && chkAllowMove->Checked)
        {
          // Falls das Steuerelement weitere untergeordnete Elemente
          // beinhaltet, prüfen ob nicht eines davon verschoben werden soll:
          if(pControl)
          {
            TWinControl* pCmp = dynamic_cast<TWinControl*>(pControl);
            TControl*    pCtrl;
            while(pCmp)
            {
              pCtrl = dynamic_cast<TControl*>(pCmp->ControlAtPos(pCmp->
                ScreenToClient(Message.pt), false, true));
              pCmp = dynamic_cast<TWinControl*>(pCtrl);
              if(pCmp) pControl = pCmp;
              else if(pCtrl) pControl = pCtrl;
            }
          }
    
          // Control verschieben:
          MoveControl(pControl);
          Handled = true;
        }
      }
    }
    
    //---------------------------------------------------------------------------
    // Funktion fürs Verschieben der Steuerelemente mit der Maus
    //---------------------------------------------------------------------------
    void __fastcall TForm1::MoveControl(TControl* pControl)
    {
      // versuchen den Komponentenzeiger in TWinControl (Zeiger auf ein
      // fensterorientiertes Steuerelement) umzucasten:
      TWinControl* pWinControl = dynamic_cast<TWinControl*>(pControl);
    
      // falls Umwandlung erfolgreich (Steuerelement fensterorientiert)
      if(pWinControl)
      {
        // "Verschieben"-Modus für das Steuerlement aktivieren:
        ReleaseCapture();
        pWinControl->Perform(WM_SYSCOMMAND, SC_MOVE+HTCAPTION, 0);
      }
      // Falls ein NICHTfensterorientierte Komponente
      // verschoben werden soll:
      else if(pControl)
      {
        // Hilfspanel entsprechend der Position und
        // Grösse der Komponente ausrichten:
        pHelpPanel->Parent = pControl->Parent;
        pHelpPanel->Left   = pControl->Left;
        pHelpPanel->Top    = pControl->Top;
        pHelpPanel->Width  = pControl->Width;
        pHelpPanel->Height = pControl->Height;
        // Das zu verschiebende Steuerelement auf
        // dem Hilfspanel platzieren:
        TWinControl* pSaveParent = pControl->Parent;
        pControl->Parent   = pHelpPanel;
        pControl->Left     = 0;
        pControl->Top      = 0;
        pHelpPanel->Visible = true;
        Application->ProcessMessages();
    
        // "Verschieben"-Modus für das Hilfspanel aktivieren:
        ReleaseCapture();
        pHelpPanel->Perform(WM_SYSCOMMAND, SC_MOVE+HTCAPTION, 0);
    
        // Nach dem Verschieben das Steuerelement an der
        // Zielposition auf dem Formular platzieren:
        pControl->Parent = pSaveParent;  // this = Zeiger auf die frmMain
        pControl->Left = pHelpPanel->Left;
        pControl->Top = pHelpPanel->Top;
        pHelpPanel->Visible = false; // Hilfspanel ausblenden
      }
    }
    

    Beispielprojekt dazu liegt hier: http://rad.bytesandmore.de/cpp/snipp/sc02036.php

    [ Dieser Beitrag wurde am 28.03.2002 um 21:38 Uhr von Serge editiert. ]



  • Hi Serge images/smiles/icon_smile.gif
    Deine Idee ist voll krass images/smiles/icon_wink.gif. Hab ein wenig dran rum basteln müssen images/smiles/icon_wink.gif. Raus gekommen ist folgendes:

    TPanel auf die Form, TImage auf das Panel plazieren. Evtl. Border des TPanel abschalten und genau den Ausmassen des TImage anpassen. Dann in das MouseDown Ereigniss des TImage folgender Code:

    void __fastcall TForm1::Image1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
        POINT mPos;
        HANDLE hWin;
    
        if(Button==mbLeft)
        {   // Position des Cursors bestimmen
            GetCursorPos(&mPos);
    
            // Handle des Fensters an Mausposition holen. Ein TImage
            // ist kein Fenster, also kriegt man das Handle des
            // darunter liegenden TPanel
            hWin=WindowFromPoint(mPos);
    
            // Handle des TPanel zum Verschieben verwenden, TImage geht
            // automatisch mit da TPanel der Parent des TImage ist
            ReleaseCapture();
            SendMessage(hWin, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
        }
    }
    

    Funktioklappt images/smiles/icon_cool.gif

    [ Dieser Beitrag wurde am 28.03.2002 um 23:12 Uhr von Peter editiert. ]



  • @Peter: Frage beantwortet - 1 setzen images/smiles/icon_biggrin.gif
    Wie heißt es so schön: Nichts ist unmöglich - Peter images/smiles/icon_biggrin.gif



  • Serge muss aber auch ne 1 bekommen images/smiles/icon_rolleyes.gif
    Er hat mich schliesslich mit seinem Codebeispiel auf die Idee gebracht, nach dem Control unter dem Image zu glotzen images/smiles/icon_wink.gif



  • ...war aber zu faul den Code auf den Sonderfall von 23.0 zu reduzieren images/smiles/icon_wink.gif , denn dann hätte die Unabhängigkeit von Ereignissen und von der Parent-Verschachtelung der Compos dran glauben müssen images/smiles/icon_wink.gif



  • Wie jetzt... man kann doch gleich schreiben

    void __fastcall TForm1::Image1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
      ReleaseCapture();
      SendMessage(Panel1->Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
    }
    

    [ Dieser Beitrag wurde am 29.03.2002 um 17:07 Uhr von WebFritzi editiert. ]



  • Öhm images/smiles/icon_rolleyes.gif , WebFritzi ich geb meine 1 an Dich ab images/smiles/icon_biggrin.gif
    Du hast natürlich recht. Entweder zuviel gedacht oder es war zu spät gestern ***Schande über mich***
    Ich hab was durcheinander gebracht, hatte mit einem ähnlichen Thema zu tun images/smiles/icon_sad.gif

    [ Dieser Beitrag wurde am 29.03.2002 um 17:19 Uhr von Peter editiert. ]


Anmelden zum Antworten