Kopierfunktion in einem CListView



  • Hallo Leute,

    nochmals eine Frage,

    Es gibt doch unter Windows die Bekannten funktionen mit Strg + c, x, v.

    Wenn ich jetzt in meiner SDI Anwendung z.b. in einem CListView realisieren möchte, muß ich dies erst selber Programmieren oder gibt es da schon vorgefertigte Funktione ??

    Der Inhalt steht ja auch immer in der Zwischenablage..

    Weis jemand bescheit ??

    Gruß
    andy_mann



  • Ich hab das ganze mit einem CListCtrl grade gemacht. Da bei allen anderen Controls eine Cut/Copy/Paste Funktion vorhanden war, bin ich davon ausgegangen, dass ich es selber machen muss.

    Ist aber ganz einfach. 🙂

    Ich hab den Artikel hier bei CodeProject gefunden (hoffentlich vertipper ich mich nicht):
    http://www.codeproject.com/clipboard/archerclipboard1.asp?print=true

    Der Artikel heißt: Using the Clipboard, Part I

    Sehr empfehlenswert.

    Im Endeffekt läßt es sich auf diese Funktion hier konzentrieren, der Rest hängt davon ab, was du machen willst.

    // ------------------------------------------------------------------------------------------------
    // Legt den gegebenen Text in die Zwischenablage
    // ------------------------------------------------------------------------------------------------
    void CSortListCtrl::CopyToClipboard(CString& f_strText)
    {
    	if(OpenClipboard())
    	{
    		// Leermachen
    		EmptyClipboard();
    
    		// Speicher reservieren (incl. \0)
    		HGLOBAL hCpDaten = GlobalAlloc(GMEM_DDESHARE, f_strText.GetLength() + 1);
    
    		// Daten in systemweiten Speicher schieben
    		char* pchData = (char*)GlobalLock(hCpDaten);
    		strcpy(pchData, LPCSTR(f_strText));
    
    		// Für andere zur Verfügung stellen
    		GlobalUnlock(hCpDaten);
    
    		// Daten in die Zwischenablage schieben
    		SetClipboardData(CF_TEXT, hCpDaten);
    
    		// Fertig
    		CloseClipboard();
    	}
    }
    

    Damit die Anwendung auf die Tasten reagiert musst du die entsprechenden Tasten in der Acceleratortable festlegen - sofern es nicht sowieso funktioniert. Ich weiß grade nicht, ob das nicht automatisch funktioniert, sobald du die Menüitems (ich habe auch ein Kontextmenü) ID_EDIT_CUT, ID_EDIT_COPY und ID_EDIT_PASTE nennst. Wobei ich nur für Copy einen Sinn gefunden habe.

    Hoffe, das hilft dir erstmal. 🙂



  • Hallo estartu_de,

    vielen Dank für deinen Source und Link.

    Aber anscheinend scheine ich mal wieder heute Morgen auf der Leitung zu stehen.

    Ich komme da nicht ganz mit wie ich diese Funktion einbinden soll ??

    Muß ich troztdem eine Funktion OnContextMenü oder OnRButonClick aufrufen und dann die Nachricht weiterleite und dort deine Funktion mit dem enthaltenen String aufrufe ??

    Gruß
    andy_mann



  • Ja, das musst du noch machen.

    Ich hab das nicht dazugeschrieben, weil ich ja nicht weiß, wie du das Kopieren aufrufen willst. Wenn du dazu mehr schreibst, gibt es auch mehr Info. 😉



  • Hallo Leute,

    so realisiere ich es jetzt, im ContextMenu bastle ich meinen string zusammen, jede Spalt von CListView getrennt mit einem Leerzeichen und anschließend schicke ich es mit de Messege in mein CMainFrame in der ich dann auf den Menüpunkt Kopieren reagiere und dies in den Zwischenspeicher schiebe,.

    Das Funktioniert auch, aber wie mache ich es jetzt, dass er mir auf die Tastenkombination Strg+ c reagiert ??

    void CStatistikLogdatenDialog::OnContextMenu(CWnd* pWnd, CPoint point)
    {
    	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein.
    
    	CString m_strCopyString = "";
    
    	POSITION pos = m_wndStatistikLogDaten.GetFirstSelectedItemPosition(); 
    	if (pos == NULL) 
    	{
            TRACE0("No items were selected!\n");
    	}
    	else 
    	{ 		
    		while(pos) 
    		{ 
    			int nItem = m_wndStatistikLogDaten.GetNextSelectedItem(pos); 
    			TRACE1("Item %d was selected!\n", nItem); 
    			TRACE("-- %s\n", m_wndStatistikLogDaten.GetItemText(nItem,0));
    			m_strCopyString = m_strCopyString + 
    				m_wndStatistikLogDaten.GetItemText(nItem,0) + " " +
    				m_wndStatistikLogDaten.GetItemText(nItem,1) + " " +
    				m_wndStatistikLogDaten.GetItemText(nItem,2) + " " +
    				m_wndStatistikLogDaten.GetItemText(nItem,3) + " " +
    				m_wndStatistikLogDaten.GetItemText(nItem,4) + " " +
    				m_wndStatistikLogDaten.GetItemText(nItem,5) + " " +
    				"\n";			
    			// you could do your own processing on nItem here 
    		}
    
    		CMenu menu;
    
    		// Kontextmenü laden
    		menu.LoadMenu(IDR_MENU5);
    		// Erstes Untermenü 
    		CMenu * pContextMenu = menu.GetSubMenu(0);
    
    		pContextMenu->TrackPopupMenu(TPM_LEFTALIGN + TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd());
    
    		char *str = m_strCopyString.GetBuffer(NULL); 
    		AfxGetMainWnd()->SendMessage(WM_MESSAGE_KOPIE,(WPARAM)str);
    	}
    }
    

    Gruß und Danke
    andy_mann



  • Huch, du machst das aber komisch... 😕

    Kann man in deinem Kontextmenü nur kopieren? Naja, jeder wie er mag, ich hätte den oberen Teil der Funktion in den Menühandler geschrieben.
    Weil, so kopierst du immer, auch wenn das Kontextmenü wieder abgewählt wird und du eigentlich nix machen musst.

    Wie heißt denn der Menüpunkt? Wenn du den ID_EDIT_COPY nennst, nimmt dir die MFC einen Teil Arbeit ab.



  • Äääähhh,

    genau dass möchte ich ja machen, aber mir wurde gesagt, dass ich das machen sollte.

    Was für nen Source muß ich denn jetzt in Funktion onCopy schreiben ??

    Gruß
    andy_mann



  • So, hier kommt ohne Garantie mal die Zerlegung, wie es in etwa gehen müßte:

    void CStatistikLogdatenDialog::OnContextMenu(CWnd* pWnd, CPoint point)
    {
            CMenu menu;
    
            // Kontextmenü laden
            menu.LoadMenu(IDR_MENU5);
            // Erstes Untermenü 
            CMenu * pContextMenu = menu.GetSubMenu(0);
    
            pContextMenu->TrackPopupMenu(TPM_LEFTALIGN + TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd());
    }
    

    Nun der Menühandler:

    void CStatistikLogdatenDialog::OnEditCopy() 
    {
        CString m_strCopyString = "";
    
        POSITION pos = m_wndStatistikLogDaten.GetFirstSelectedItemPosition(); 
        if (pos == NULL) 
        {
            TRACE0("No items were selected!\n");
        }
        else 
        {         
            while(pos) 
            { 
                int nItem = m_wndStatistikLogDaten.GetNextSelectedItem(pos); 
                TRACE1("Item %d was selected!\n", nItem); 
                TRACE("-- %s\n", m_wndStatistikLogDaten.GetItemText(nItem,0));
                m_strCopyString = m_strCopyString + 
                    m_wndStatistikLogDaten.GetItemText(nItem,0) + " " +
                    m_wndStatistikLogDaten.GetItemText(nItem,1) + " " +
                    m_wndStatistikLogDaten.GetItemText(nItem,2) + " " +
                    m_wndStatistikLogDaten.GetItemText(nItem,3) + " " +
                    m_wndStatistikLogDaten.GetItemText(nItem,4) + " " +
                    m_wndStatistikLogDaten.GetItemText(nItem,5) + " " +
                    "\n";            
                // you could do your own processing on nItem here 
            }
    
            char *str = m_strCopyString.GetBuffer(NULL); 
            AfxGetMainWnd()->SendMessage(WM_MESSAGE_KOPIE,(WPARAM)str);
        }
    }
    

    Hst du schonmal in die AcceleratorTable geguckt? Da muss sowas stehen:

    ID_EDIT_COPY       Ctrl+C              VIRTKEY
    


  • Hallo,

    vielen Dank,

    doch leider Funktioniert das nicht bei mir.

    ID_EDIT_COPY       Ctrl+C              VIRTKEY
    

    Ist bei mir vorhanden.

    Ich verstehe nicht ganz wo Du die

    OnEditCopy
    

    aufrufen willst ??

    Gruß
    andy_mann



  • Wenn das bei dir nicht vorhanden ist, dann erstell es... :p

    Das OnEditCopy ist der Menühandler. Damit ich dir mal Quelltext und genauere Anleitung geben kann, schreib doch bitte mal, wie die ID für den Menüpunkt "Kopieren" ist. Oder ob du, wie ich schon geschrieben habe, ID_EDIT_COPY genommen hast.



  • Hallo,

    ich habe wie Du die

    ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
    

    in dem Dialog erstellt in dem ich meinen String aufbaue und dort wo das ContextMenü aufgerufen wird.

    Dann habe ich ein Menü (IDR_MENU5) und dem Menüpunkt Kopieren erstellt.

    In meiner CMainFrame rufe ich dann den Menüpunkt auf.

    Ich habe da noch einen Gedankenfehler drin.
    Komm aber nicht drauf.

    Gruß
    andy_mann



  • Ist der Quellcode geheim? Sonst bereinige mal das Projekt, pack es und schick es mir.

    Könnte aber sein, dass ich erst morgen zum Angucken komme. 🙂

    Was mir auffällt: Du hast ZWEI Menühandler? 😕



  • Erste Korrektur:

    pContextMenu->TrackPopupMenu(TPM_LEFTALIGN + TPM_RIGHTBUTTON, point.x, point.y, this);//AfxGetMainWnd());
    

    Sonst werden die Nachrichten an das Hauptfenster gesendet und nicht an den Dialog, wo du sie behandeln willst.



  • TPM_LEFTALIGN + TPM_RIGHTBUTTON

    Seit wann verknüpft man Flags mit +?



  • lol, danke hab ich gar nicht gemerkt - es funktioniert aber.

    Korrektur:

    pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);//AfxGetMainWnd());
    

    Und: Die Acceleratoren funktionieren in modalen Dialogen nicht. Lösung siehe Mail. 🙂



  • Also, erst mal vielen Dank,

    hhhmmmm, tut aber net.

    Dass wir uns richtig verstehen, ich markiere etwas, rechte maustaste , kopieren, und nun sollte ich den makierten bereich irgendwo kopieren können (Editor, word, Excel usw.)

    Und das machte er nicht.

    Ich verstehe auch immernoch nicht wann die Funktion CTabelleDialog::OnEditCopy() aufgerufen werden soll ??

    Gruß
    andy_mann



  • Hast du die Zeile korrigiert?

    Nun musst du noch in

    LRESULT CMainFrame::OnKopie(WPARAM wParam, LPARAM pParam)
    {
    	char *myString = (char*)wParam; 
    	// mach was 
    	m_strKopieString = myString;
    	return 0;
    }
    

    Die Funktion aus meinem ersten Beitrag in diesem Thread mit myString aufrufen. Dann kannst du das in Word einfügen.



  • Ahja,

    vielen Dank, solangsam dämerts....

    Gruß
    andy_mann



  • Sag Bescheid, wenns leuchtet. 😉



  • Es leuchtet....... ;-))

    sag mal arbeitest Du Beruflich in der Branche ??


Anmelden zum Antworten