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?