SDI OnCopyData



  • Hallo

    Noch ne Frage zu einer SDI Applikation. Ich empfange in CMainFrame Daten von einer anderen Applikation über WM_COPYDATA. Soweit funktioniert es. Wenn ich nun aber meine Applikation in den Tray minimiere erhalte ich kein WM_COPYDATA mehr.

    Dies war bei meiner Dialogbasierten Applikation nicht der Fall.

    Was muss man da ändern?


  • Mod

    Das hat nichts mitenander zu tun.
    Beim Sender muss das Handle stimmen. Weder die Fensterklasse noch die Sichtbarkeit noch Enabled/Disabled spielen hier eine Rolle.

    Kontrolliere im Sender wohin gesendet wird. Kontrolliere im Spy++ ob dieses Handle wirklich dasist was Du meinst und nicht der View oder sonst wasd.



  • Ich ermittle mir die ProzessId meiner Applikation. Dann dazu mit EnumWindows die dazugehörigen Handles. Dann erhalte ich eine Liste mit allen Handels der Applikation. Dann sende ich meine Daten in einer Schleife an alle Handels der Applikation.

    Das oberste Fenster empfängt dann die Nachricht. Aber allerdings nur wenn die Applikation sichtbar ist.

    Da ich ja an alle Handels der Applikation sende muss ich ja mal das richtige erwischen.


  • Mod

    1. Ich würde das erstmal kontrollieren ob das Handle dabei ist.
    2. Finde ich so etwas overkill. Warum verwendest Du keine eigene Fenserklasse und suchst das Handle damit, oder ein globales Atom, oder sonst ein IPC mit dem Du das Handle direkt erzeugst.
    Ist Dir nicht klar, dass jeder Speicherblock bei einem WM_COPY direkt gemarshalled werden muss?



  • Ok erst mal danke.

    1. Das Handle ist dabei. Egal ob es im Tray ist oder nicht. Es wird ja auch an das richtige Handle gesendet.

    2. Verstehe ich nicht ganz. Was meinst du mit eigener Fensterklasse? Woher kennt meine sendende Applikation das Handle der empfangenden Applikation?
    Also ich habe das bisher halt nur so gekannnt dass man mit dem Applikationsnamen die Prozessid herausfinden kann. Und über die Prozessid die zugehörigen Handles ermitteln. Welcher Handle nun die Nachricht entgegennimmt weiß ich nicht. Darum an alle. Könntest du mir ne kleine Hilfestellung geben wie das anders geht.

    Warum das ganze aber bei einer dialogbasierten Anwedung geht und bei einer SDI nicht, ist dann mir aber immer noch schleierhaft.


  • Mod

    Es gibt doch FindWindow. Wenn man also seinem Fenster eine eigene Fensterklasse gibt kann man gezoelt das Mainframe finden.



  • Auch hier meinen Dank. Hier muss ich aber nochmals nachfragen. Sorry

    Wenn man also seinem Fenster eine eigene Fensterklasse gibt...

    .
    Das war genau das was ich nicht weiß wie das geht. Habe hier auch schon gegoogelt aber irgendwie verwende ich die falschen Begriffe oder steht vieleicht einfach auf dem Schlauch.

    Könntest du mir dazu noch ne kleine Hilfestellung geben oder auf nen Link verweisen wo das erklärt wird. Danke.


  • Mod



  • Jo war es. Habe nach "mfc eigene Fensterklasse" gesucht. Danke.



  • So jetzt Frage ich nochmals nach auch auf die Gefahr hin dass ich verspotet werde:

    Was muss ich den bei ::GetClassInfo(); angeben. Habe das übergeben was da steht.
    Der Name wird aber im Spy++ nicht angezeigt. Muss doch an ::GetClassInfo liegen beim Rest kann man ja nicht viel falsch machen.



  • Also jetzt habe ich mal eine neue Applikation angelegt. SDI diesesmal mit Doc/View. Ohne sonst igrendwas am Code zu machen, habe ich wie beschrieben in Initinstance der App Klasse die folgenden Zeilen hinzugefügt:

    WNDCLASS wc;
    GetClassInfo(AfxGetInstanceHandle(), "#32770", &wc)
    wc.lpszClassName = "MyPrivateClassName";
    AfxRegisterClass(&wc)
    

    Leider kein Erfolg. Wenn ich mit Spy++ kontroliere heißt meine Klasse nach wie vor: "Afx:00400000:b:00010013:00000006:00C109C7".

    Also viel anders kann man da ja nicht machen.


  • Mod

    Du gehst IMHO nicht vor wie dokumentiert. Wo ist Deine PreCreateWindow Funktion?



  • Wieso kommst du darauf?

    Also auf der genannten Seite sind 3 Möglichkeiten beschrieben wie man vorzugehen hat.

    1. In der Ressourcenansicht
    2. Dirket in der RC Datei
    3. Programmatisch in der InitInstance() der App Klasse.

    so 1 und 2 kommen ja nicht in Frage.

    So also habe ich genau das getan was für Punkt 3 in Frage kommt. Habe die Zeilen implementiert.

    PreCreateWindow Funktion? Also von der ist auf der Seite kein Wort erwähnt.


  • Mod

    Mein Fehler. Tut mir leid!
    Ich hatte irgendwie im Kopf, der TN070 (zweiter Link) enthält diese Infos.
    Scheinbar ist diese Info doch ncith so weit verbreitet im Netz wie ich dachte.

    Ok schrittweise:
    1. PreCrateWindow überschrieben.
    2. Default aufrufen.
    3. GetClassInfo ausführen
    4. Eigenenen Klassennamen setzen
    5. Klasse registrieren
    6. Diesen Klassennamen in die Precreatestruct einsetzen
    Fertig



  • Hallo Martin.

    Super vielen Dank. Jetzt funktioniert es. Aber in der TN070 ist aber auch nicht wirklich beschrieben was man da genau machen muss. Also du musst zugeben dass es schwierig ist hier ne genaue Anleitung zu finden.

    So nun aber nochmal zu meinem eigentlichen Problem. Die Nachricht wird auch jetzt nur empfangen wenn der Dialog nicht ausgeblendet ist. Nun weiß ich aber warum. Weiß nur noch nicht wie lösen.

    Also habe die Klasse CSystemTray verwendet von Codeproject. Das Problem daran ist dann wenn die Applikation in den Tray verschoben wird, diese einem anderen Fenster untergeordnet wird. Ohne Titel und Klassenname Afx:00400000:0.

    Dies ist aber nur der Fall wenn es eine SDI Applikation ist. Verwende ich eine Dialogbasierte Anwendung wird sie nicht untergeordnet.


  • Mod

    Was sagt Spy++?
    Wie sieht der Messagemap Eintrag aus?



  • Was sagt Spy++?

    Äm genau das was ich geschrieben habe.

    Also wenn mein Fenster eingeblendet ist es auf oberer Ebene direkt unter Desktop. Wenn es ausgeblendet ist wird es untergeordnet unter dem besagten Fenster. Spy++ zeigt an dass die WM_COPYDATA empfangen wird. Aber nur wenn die Applikation nicht im Tray ist.

    Was wolltest du noch wissen bzw. was muss ich noch anschauen im Spy++?

    Wie sieht der Messagemap Eintrag aus?

    Von WM_COPYDATA?

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
       ...
       ON_WM_COPYDATA()
       ...
    END_MESSAGE_MAP()
    

    Irgendwie habe ich das Gefühl du willst was anderes wissen. 😕



  • Also nochmal.

    Wenn ich mit Spy++ nach dem Fenster mit dem gewählten Klassennamen suche, findet er das Fenster egal ob untergeordnet oder nicht.

    Wenn ich programmatisch mit FindWindow("MyClassName",NULL) suche, ist das Hwnd dass ich erhalte NULL, wenn das Fenster untergeordnet ist.

    Arbeitet FindWindow nicht gleich wie der Spy++?


  • Mod

    FindWindow findet nur "Top-Level" Fenster!

    Ich verstehe Deinen Konstrukt nicht. Ist es kein Top-Level-Fenster?

    Bei mir arbeitet WM_COPYDATA mit jedem Fenstertyp, ob versteckt oder nicht.



  • FindWindow findet nur "Top-Level" Fenster!

    Ja habe ich in der Zwischenzeit auch gelesen 🙂

    Ich verstehe Deinen Konstrukt nicht. Ist es kein Top-Level-Fenster?

    Nein sage ich doch die ganze Zeit wenn das Fenster ausgeblendet ist, wird es einem anderen Fenster untergeordnet. Das ist halt so in der CSystemTray von Codeproject realisiert.

    Bei mir arbeitet WM_COPYDATA mit jedem Fenstertyp, ob versteckt oder nicht.

    Ja WM_COPYDATA funktioniert. Ich finde halt nur das HWND nicht.

    Wenn Spy++ doch das Fenster findet nur anhand des Klassennamen sei es Top-Level oder nicht. Dann muss doch das auch programmatisch gehen, oder nicht?


Anmelden zum Antworten