Drag&Drop zwischen zwei Dialogen



  • Möchte Drag&Drop zwischen einer CListCtrl und einem CEdit realisieren. Hatte beide vorher in einem
    Dialog.Dort funktionierte auch alles ganz toll mit dem folgenden Quellquode:

    ////////////////////////Anfang Drag&Drop////////////////////////////////////////

    //Legt die Drag-Quelle fest
    void CCompPlayerDlg::OnBegindragListLeft(NMHDR* pNMHDR, LRESULT* pResult)
    {
    //Schaffen der notwenigen Variabeln f¸r Drag&Drop
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

    //Index des Items der verschoben wird sichern in m_nDragIndex
    m_nDragIndex = pNMListView->iItem;

    //Drag-Bild erzeugen
    POINT pt;
    //offset in pixel f¸r Drag-Bild (positiv= hoch nach links; negativ= runter nach rechts)
    int nOffset = -10;
    //Mehr als ein Item ausgew‰hlt
    if(m_listL.GetSelectedCount() > 1)
    pt.x = nOffset;
    pt.y = nOffset;

    //Schaffen des Bildes
    m_pDragImage = m_listL.CreateDragImage(m_nDragIndex, &pt);
    //Absichern das es geschaffen wurde
    ASSERT(m_pDragImage);

    // Mauszeiger wird jetzt in Drag-Bild ge‰ndert
    m_pDragImage->BeginDrag(0, CPoint(nOffset, nOffset - 4));
    m_pDragImage->DragEnter(GetDesktopWindow(), pNMListView->ptAction);

    //Wir sind gerade in einer Drag&Drop Operation
    m_bDragging = TRUE;
    //Ziel noch nicht bekannt
    m_nDropIndex = -1;
    //Quelle
    m_pDragList = &m_listL;
    //Ziel
    m_pDropWnd = &m_listL;

    SetCapture ();

    *pResult = 0;
    }

    //Bestimmt die Optik des Mouszeigers beim beim Drag&Drop
    void CCompPlayerDlg::OnMouseMove(UINT nFlags, CPoint point)
    {

    //// Wenn wir gerade in einer Drag&Drop-Operation sind
    if (m_bDragging)
    {
    // aktuelle Mauskoordinaten
    CPoint pt(point);
    //In Bildschirmkoordinaten ‰ndern
    ClientToScreen(&pt);
    //Drag-Bild dort hinbewegen
    m_pDragImage->DragMove(pt);
    m_pDragImage->DragShowNolock(false);

    //CWnd Zeiger des Fensters unter dem Mauszeiger
    CWnd* pDropWnd = WindowFromPoint (pt);
    //Sicher gehn das wir ein Fenster haben
    ASSERT(pDropWnd);

    //Wenn au?erhalb unseres Fensters muss Aktivierung ver‰ndert werden
    if (pDropWnd != m_pDropWnd)
    {
    //Wenn ¸ber Listekopf
    if (m_nDropIndex != -1)
    {
    TRACE("m_nDropIndex is -1\n");
    CListCtrl* pList = (CListCtrl*)m_pDropWnd;
    VERIFY (pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED));
    VERIFY (pList->RedrawItems (m_nDropIndex, m_nDropIndex));
    pList->UpdateWindow ();
    m_nDropIndex = -1;
    }
    //Au?erhalb der Liste
    else
    {
    TRACE("m_nDropIndex is not -1\n");
    CListCtrl* pList = (CListCtrl*)m_pDropWnd;
    int i = 0;
    int nCount = pList->GetItemCount();
    for(i = 0; i < nCount; i++)
    {
    pList->SetItemState(i, 0, LVIS_DROPHILITED);
    }
    pList->RedrawItems(0, nCount);
    pList->UpdateWindow();
    }
    }

    // aktuelle Fenster Zeiger sichern
    m_pDropWnd = pDropWnd;

    // Konvertierung der Koordinaten
    pDropWnd->ScreenToClient(&pt);

    //Wenn wir ¸ber einer Liste sind
    if(pDropWnd->IsKindOf(RUNTIME_CLASS (CListCtrl)))
    {
    //Zeigen das hier eingef¸gt werden kann
    SetCursor(LoadCursor(NULL, IDC_ARROW));
    UINT uFlags;
    CListCtrl* pList = (CListCtrl*)pDropWnd;

    pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
    pList->RedrawItems (m_nDropIndex, m_nDropIndex);

    //Liefert Item unter Maus
    m_nDropIndex = ((CListCtrl*)pDropWnd)->HitTest(pt, &uFlags);
    //hervorheben
    pList->SetItemState(m_nDropIndex, LVIS_DROPHILITED, LVIS_DROPHILITED);
    pList->RedrawItems(m_nDropIndex, m_nDropIndex);
    pList->UpdateWindow();
    }
    else
    {
    //Wenn wir uns ¸ber einem Editfeld befinden
    if(pDropWnd->IsKindOf(RUNTIME_CLASS (CEdit)))
    {
    ///Zeigen das hier eingef¸gt werden kann
    SetCursor(LoadCursor(NULL, IDC_ARROW));
    CEdit* pEdit = (CEdit*)pDropWnd;
    CEdit* pEdit1 = (CEdit*)pDropWnd;

    }else{
    //Wenn nicht ¸ber Editfeld oder Liste anzeigen das hier nicht
    //eingef¸gt werden kann
    SetCursor(LoadCursor(NULL, IDC_NO));
    }
    }
    m_pDragImage->DragShowNolock(true);
    }

    CDialog::OnMouseMove(nFlags, point);
    }

    //Legt fest in welche Elemente eingef¸gt werden kann
    void CCompPlayerDlg::OnLButtonUp(UINT nFlags, CPoint point)
    {

    //Wenn wir gerade in einer Drag&Drop-Operation sind
    if (m_bDragging)
    {
    //Maus capture f¸r ander Anwendungen freigenen
    ReleaseCapture ();

    //Keine Drag-Operation mehr
    m_bDragging = FALSE;

    //End-Bild der Operation
    m_pDragImage->DragLeave (GetDesktopWindow ());
    m_pDragImage->EndDrag ();
    //Lˆschen des Bildes
    delete m_pDragImage;

    //Aktuellen Maus-Koordinaten
    CPoint pt (point);
    //Konvertierung in Bildschirmkoordinaten
    ClientToScreen (&pt);
    //CWnd Zeiger des Fensters unter der Maus
    CWnd* pDropWnd = WindowFromPoint (pt);
    //Sicher gehen das wir einen Zeiger haben
    ASSERT (pDropWnd);
    //Wenn das Fenster eine Liste ist
    if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl)))
    {
    //Zeiger auf Liste setzen
    m_pDropList = (CListCtrl*)pDropWnd;
    DropItemOnList(m_pDragList, m_pDropList);
    }
    //Wenn das Fenster ein Editfeld ist
    if (pDropWnd->IsKindOf (RUNTIME_CLASS (CEdit)))
    {
    //Zeiger auf Editfeld setzen
    m_pDropEdit = (CEdit*)pDropWnd;
    DropItemOnEdit(m_pDragList, m_pDropEdit);
    }
    }

    CDialog::OnLButtonUp(nFlags, point);
    }

    //Funktion zum Einf¸gen in einem Editfeld
    void CCompPlayerDlg::DropItemOnEdit(CListCtrl* pDragList, CEdit* m_pDropEdit)
    {

    char szLabel[256];
    LVITEM lviT;

    ZeroMemory(&lviT, sizeof (LVITEM));
    lviT.iItem = m_nDragIndex;
    lviT.mask = LVIF_TEXT;
    lviT.pszText = szLabel;
    lviT.cchTextMax = 255;

    lvItem lvi;
    lvi.plvi = &lviT;
    lvi.plvi->iItem = m_nDragIndex;
    lvi.plvi->mask = LVIF_TEXT;
    lvi.plvi->pszText = szLabel;
    lvi.plvi->cchTextMax = 255;

    pDragList->GetItem (lvi.plvi);

    //Name des Titels in die Liste ¸bertragen
    lvi.sCol2 = pDragList->GetItemText(lvi.plvi->iItem, 0);
    m_pDropEdit->SetWindowText(lvi.sCol2);

    }
    ////////////////////////Ende Drag&Drop////////////////////////////////////////

    Nun war ich aber gezwungen das Editfeld in einen anderen Dialog zu packen. Nur leider funktioniert
    nun meine Drag&Drop Operation nicht mehr.

    Der zweite Dialog wird aus dem ersten durch folgenden Quellcode aufgerufen:

    CPlayer* dlg1=new CPlayer;
    dlg1->Create(IDD_Player);
    dlg1->ShowWindow(SW_SHOW);
    dlg1->SetWindowPos(&wndTop,601,100,380,70,SWP_SHOWWINDOW);
    dlg1->UpdateWindow();

    Bin dringend auf eure Hilfe angewiesen. Echter Notfall!!!!
    Danke schon mal für eure Bemühungen.



  • versuchs mal so:

    CPlayer* dlg1=new CPlayer; 
    dlg1->Create(IDD_Player); 
    dlg1->ShowWindow(SW_SHOW); 
    dlg1->SetWindowPos(&wndTop,601,100,380,70,SWP_SHOWWINDOW); 
    dlg1->SetDlgItemText(ID_DEINER_EDIT_BOX, szLabel); 
    dlg1->UpdateWindow();
    

    Gruß
    :: NoName ::



  • Danke erst mal für die Antwort.
    Doch leider realisiert dein Code doch nur das Eintragen eines Textes in das Editfeld. Doch wann löse ich dieses Eintragen aus.
    Schließlich soll die Drag&Drop-Operation beliebig oft möglich sein.

    Und aufgerufen hatte ich den zweiten Dialog in der OnInit-Funktion des ersten Dialoges.

    Also wie bekomm ich raus wann er sich gerade mit der Maus auf dem Edit im zweiten Dialog befindet? Denn die OnBegindDragListLeft des ersten Dialogs scheint mit SetCapture() die Maus für andere Anwendungen zu sperren.

    Wenn ich das auskommentiere, bekomme ich im zweiten Dialog MouseMoveNachrichten. Aber LButtonDown sendet mir im zweiten Dialog keine Nachrichten wenn ich die Maustaste wieder loslasse.

    Wer hat eine Lösung?


Anmelden zum Antworten