Aktualisieren des Inhalts bei schon vorhandener Programminstanz



  • Du musst in den Projekteigenschaften RTTI einschalten. 🙂



  • Ok, vielen Dank!
    Nun habe ich ein Problem alles zu verbinden, so das es Sinn macht:

    Also, ich bekomme nun, wenn ich versuche, meine Anwendung ein zweites Mal zu öffnen, das Handle zum ersten geöffneten Programm:
    hWnd.
    Dieses Handle habe ich im CMainFrame der zweiten Anwendung, die sich aber danach irgendwann schließt.
    Dort will ich dann aber einen Zeiger auf die Ansicht des ersten geöffneten Programms erstellen.
    Dachte, ich erstelle ein neues CMainFrame-Objekt mit Hilfe der FromHandle()-Methode. Doch wie mache ich weiter? Oder bin ich auf dem falschen Weg? 😕

    👍



  • Eventuell könnte ich auch eine Nachricht definieren, welche ich dann per SendMessage an das hWnd schicke, in dessen Behandlungsroutine einfach von dort die Ansicht aktualisiert wird?!
    Was meinst du?

    EDIT: Mist, habe mich vertan, das Handle habe ich nicht im CMainFrame, sondern in der CMyApp. 🤡



  • Das mit der eigenen Nachricht wäre eine Idee.
    Oder du schickst WM_CLOSE - und lässt die neue Instanz laufen als wäre nichts gewesen.



  • Das ist natürlich auch "tricky". Ich probiere es mal mit der Nachricht.
    Du hattest auch mal irgendwo geschrieben, wie man eine Klasse "forward-inlcuden" (richtig?) kann.
    Denn wenn ich den Cast mache, dann erzeugt er ja einen Zeiger vom Typ CMyView.
    In der CMainFrame ist ja MyView.h nicht included (wenn ich es mache, dann gibt es wieder eine Menge Fehlermeldungen).
    Bevor ich mich um die Fehler kümmern muss, wollte ich mal probieren, ob es nicht mit einem Forward-Inlcude funktioniert. Wie ging das nochmal?
    Habe zuerst einfach mal:

    extern CMyView;
    

    geschrieben, dann kam aber Folgendes:

    error C2065: 'pView' : undeclared identifier
    error C2061: syntax error : identifier 'CMyView'



  • class CMyView;
    

    🙂
    Oder Suche mit *Ringinclude* füttern.



  • Die Suche scheint mich manchmal aus mir nicht bekannten Gründen nicht zu mögen.
    Danke nochmals!



  • So, doch noch ein Problem:

    error C2680: 'CMyView *' : invalid target type for dynamic_cast

    Habe nun in der MainFrame den Forward-Include gemacht:

    class CMyView
    

    😕

    EDIT: Ok, ohne dynamic_cast funktioniert es. Was ist eigentlich der Sinn eines dynamic_casts?



  • dynamic_cast gibt dir NULL, wenn es nicht geklappt hat.

    Wenn du aus CWnd ein CEdit machen willst - das aber ein CButton ist, dann bekämst du NULL und wüsstest, dass du mit dem Zeiger nicht arbeiten darfst.



  • Ah!! Man lernt nie aus! Heute habe ich Einiges dazu gelernt.
    Danke nochmals. Wenn ich es hinbekomme melde ich mich nochmal. 🙂
    Wird aber wahrscheinlich morgen erst was.



  • So ein Problem taucht noch auf:

    Ich möchte mit SendMessage() meiner View meine Nachricht übermitteln. Als
    LPARAM - Argument würde ich gerne den Dateipfad + Dateinamen übergeben.
    Da meckert er:

    h:\C++ error C2597: illegal reference to non-static member 'CMyApp::m_strFile'

    Dann habe ich versucht, diese Variable als static zu deklarieren. Dann kommt Folgendes:

    error C2664: 'SendMessageA' : cannot convert parameter 4 from 'CString' to 'LPARAM'

    Warum geht das nicht? 😕

    EDIT: Ich habe es auch mit Zeigern versucht. Das will er auch nicht.
    Ich meine, einen String in eine long-Variable zu packen, geht nicht, ist auch klar, aber wie mache ich das denn dann?



  • Wie hast du es versucht? Mit WM_COPYDATA?



  • Du müsstest dort einen Cast einbauen (und in deiner Nachrichtenbehandlung auch wieder zurückcasten nach LPCTSTR)



  • Ne, ich habe in meiner CMyApp - Klasse eine Membervariable, die den Pfadnamen aus der Kommandozeile nimmt.
    Dies würde ich gerne übergeben.
    Als Nachricht schicke ich meine Selbstdefinierte Nachricht.
    Oder meinst du ich sollte zuerst WM_COPYDATA schicken?
    Habe das jetzt soweit hinbekommen, dass ich stattdessen einen this-Zeiger mitschicke.
    damit wollte ich dann auf die Membervariable zugreifen.
    Jedoch habe ich dann in der CMainFrame das Problem, dass der plötzlich die CMyView Klasse nicht mehr kennt, obwohl ich eine Zeile darüber mir einen Zeiger darauf hole!?!

    CMyView* pView = (CMyView*)(((CFrameWnd*)AfxGetMainWnd())->GetActiveView());
    ASSERT(pView);
    pView->SendMessage(UWM_UPDATEVIEW, NULL, lParam);//hier meckert der
    

    error C2027: use of undefined type 'CMyView'

    EDIT: hatte auch das hier versucht:

    CMyView* pView = (CMyView*)(((CFrameWnd*)AfxGetMainWnd())->GetActiveView());
    ASSERT(pView);
    HWND hView = pView->m_hWnd // dann meckerte er hier
    ::SendMessage(hView, UWM_UPDATEVIEW, NULL, lParam);
    


  • CStoll schrieb:

    Du müsstest dort einen Cast einbauen (und in deiner Nachrichtenbehandlung auch wieder zurückcasten nach LPCTSTR)

    Ich hatte versucht nach LPARAM zu casten, das mag er aber nicht.
    Oder wie meinst du das?



  • Paul_C. schrieb:

    Als Nachricht schicke ich meine Selbstdefinierte Nachricht.
    Oder meinst du ich sollte zuerst WM_COPYDATA schicken?

    Entweder vorher oder gar anstelle.

    So schickt man ab:

    COPYDATASTRUCT cpd;
    		cpd.dwData = nIrgendeineZahl;
    		cpd.cbData = strText.GetLength();
    		cpd.lpData = (void*)strText.GetBuffer(strText.GetLength());
    		pOtherWnd->SendMessage(WM_COPYDATA, (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(), (LPARAM)&cpd);
    

    So empfängt man:
    Im Header:

    afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
    

    In der MessageMap:

    ON_WM_COPYDATA()
    

    Die Funktion:

    BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
    {
    	CString strText = (LPCSTR)(pCopyDataStruct->lpData);
    	strText = strText.Left(pCopyDataStruct->cbData);
    	return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
    }
    

    Ich habe das nach einer Anleitung auf Codeproject gemacht. 🙂



  • Nur als Anmerkung: Man kann auch seine eigene Nachricht definieren (WM_APP + x) und dort einen Zeiger mitschicken...
    Das WM_COPYDATA ist eigentlich primär für den prozess-Übergreifenden Nachrichtenaustausch geadacht und hier vermutlich überdimensioniert... (da es globalen Speicher allokiert und dieser von einem Prozess in den anderen verschoben wird).
    Wenn die Nachrichten im gleichen Prozess bleiben würde ich immer WM_APP + x verwenden...



  • Jochen, wenn ich ihn richtig verstanden habe, sind es zwei Instanzen seiner Anwendung und damit zwei Prozesse.
    Deswegen ist mir beim Zeiger mitgeben usw. auch unwohl - ich bezweifle, dass das gutgeht. 🙄



  • Zu estartu: danke. werde ich mal anschauen.
    zu Jochen: ja, ich habe auch eine eigene WM_APP+ - Nachricht.
    Habe auch noch einen Denkfehler bemerkt.
    Ich hole mir beim Suchen einer schon vorhandenen Instanz ein Handle des dazugehörigen MainFrames.
    Dieses habe ich dann in meiner CMyApp.
    Von da schicke ich per SendMessage() meine Nachricht an dieses MainFrame.
    Von dort aus wollte ich nun an die Ansicht die Nachricht weiterleiten.
    Ist aber, glaube (hoffe) ich mal nicht nötig. Eigentlich sollte ich ja von dort aus mit Zeigern auf meine View und Doc weiterarbeiten können. Da hakt es noch ein wenig, weil er plötzlich die Klassen (CMyView, CMyDoc) nicht kennen will.
    Mache ich das mit einem Forward-Inlcude dann meckert er (siehe Beschreibung einige Post drüber)?!?



  • estartu schrieb:

    Jochen, wenn ich ihn richtig verstanden habe, sind es zwei Instanzen seiner Anwendung und damit zwei Prozesse.
    Deswegen ist mir beim Zeiger mitgeben usw. auch unwohl - ich bezweifle, dass das gutgeht. 🙄

    Das werden wir sehen. 😃
    🤡


Anmelden zum Antworten