PostMessage und WindowHandles (Solved)
-
irgendwie versteh ich die WindowHandles nicht richtig, mein programm schmiert immer mit nem stack overflow ab.
zum programm ... (BDS2006)
1 Form mit 1 WndProc die messages von einem TrayIcon liesst 1 SteuerKlasse (sendet Messages an Netwerkklasse und angehängte threads) 1 Netzwerkklasse mit 1 WndProc fängt Messages die per UDP versendet werden mehrere Thread-Klassen mit 1 WndProc fängt Messages die per TCP versendet werdendas Problem wenn ich eine Verbindung aufbaue, hole ich mit allocateHWnd() die WndProc() von einem der Threadklassen, gebe ich diese dann mit deallcateHWnd() wieder frei und klicke auf mein TrayIcon schmiert mein Programm mit Zugriffsverletzung ab
in der WndProc() des Formular steht folgendes
TrayPopup->PopupComponent = Form; :arrow_right: this->BringToFront(); // hier gehts in die knie TrayPopup->Popup(MousePos.x, MousePos.y);PS: Ich habe das Problem schon stark abstrahiert, ein zugriff von der Steuerklasse in die Netzwerkklasse ist nicht mit direktem Aufruf möglich, eventuell hat wer ne idee wie ich das anders lösen kann OHNE die unabhängigkeit von Steuer- und NetzwerkKlasse einzuschränken.
und nochwas:
Eigentlich bin ich auf der suche nach einer eleganten lösung, wie ich mir aus der steuerklasse ein asynchrones signal holen kann (ohne dabei in einer schleife oder ähnliches in der netzwerkklasse auf ein event zu warten, ein callback wäre theoretisch möglich aber nicht asynchron), damit ich in den tcp threads der netzwerkkarte einen aufruf aus der steuerklasse auslösen kann um daten zu lesen und zu versenden, ohne viel in der steuerklasse umschrieben zu müssen (hab ich nämlich nicht geproggt und hab auch nicht den zeitrahmen die klasse vernünftig umzuschreiben)
Und weils Editiern so viel spass macht, NOCH einmal:
der knaller ist ja, selbst wenn ich mehrfach den handle von der netzwerkklasse (gleicher thread-kontext wie das Form) erstelle und wieder freigebe passiert nichts.
Nur wenn ich einen tcp-thread somit auch einen neuen threadkontext erzeuge und wieder freigebe (während der thread läuft funktionierts noch) dann entsteht der fehler.dann schieb ich hier einfach nochmal code nach damit ihr nicht eure glaskugel bemühen müsst
TCP-Thread
switch (Message.Msg) { case WM_TCP_RECV: { //makro WM_USER+XXX ReadData(); //liesst daten aus steuerklasse und sendet diese } break; }Formular
POINT MousePos; switch (Message.Msg) { // Formularsignale fangen und verarbeiten case WM_SYSCOMMAND: { int WParam = Message.WParam & 0xFFF0; switch (WParam) { case SC_MINIMIZE: { Hide(); Open1->Caption = "Open"; return ; } case SC_CLOSE: { Form->ForceExitActionExecute(this); Message.Result = 0; return ; } } } break; } switch (Message.LParam) { // TrayIconSignale verarbeiten case WM_RBUTTONUP: if (GetCursorPos(&MousePos)) { TrayPopup->PopupComponent = Form; :arrow_right: this->BringToFront(); TrayPopup->Popup(MousePos.x, MousePos.y); } else { Show(); Application->BringToFront(); Open1->Caption = "Close"; } break; }Netzwerkklasse
switch (Message.Msg) { case WM_UDP_RECV: { } }
-
Zuerst was nebensächliches: Die Klammern zwischen den case-Marken sind garnicht notwendig.
Ceos schrieb:
case SC_MINIMIZE: { Hide(); Open1->Caption = "Open"; return ; }
-
da ist auch code dabei den ich nicht verzapft habe .... aber eigentlich isses doch wayne
-
Problem gefunden!
Ich weis jetzt allerdings nicht genau ob es NUR das war!!!AllocateHWnd() und DeAllocateHWnd() müssen im selben Thread-kontext ausgeführt werden!
ich habe beide jetzt in den Applicationthread verlagert, kann sein das es immernoch zu problemen kommt wenn man beide in einem fremden threadkontext ausführt, hab ich aber so nicht testen können!
Zur erklärung, ich habe eine Klasse die von TThread ableitet und eine weitere Klasse instanziiert die sie in der Execute Methode bearbeitet.
Durch ein ungünstiges Timing wurden DeAllocate und Allocate nicht immer im gleichen Thread ausgeführt