RichEdit nach der Benutzung wieder freigeben?
-
Freak33 schrieb:
Also die Console Klassen werden im Main-Thread erstellt. Somit ist die Haut-Queue dafür verantwortlich - das klappt auch alles wunderbar und perfekt bis zum Shutdown.
Dann ist auch der Haupt-Thread für die Ausgaben verantwortlich (alles andere bereitet Probleme). Aber um ein Sprichwort abzuwandeln - "Ein Code sagt mehr als tausend Worte"

-
Freak33 schrieb:
"Es ist sicherlich kein Problem im Debugger Break All anzuklicken und zu sehen was di"
Öhm wir mach ich das?
Debugger laufen lassen. Bis Problem aufttaucht. Dann gibt es in der Button-Leiste den Schalter Break-All. Anklicken. Debug-Thread Window öffnen und die Threads ansehen, was sie tun.
-
Ok, hab ich jetzt gemacht. Hier die laufenden Threads:
> 2948 __tmainCRTStartup __tmainCRTStartup Normal 1 436 Win32 Thread 7c91eb94 Highest 1 2900 Win32 Thread 7c91eb94 Normal 0 3212 CTable::Run 7c91eb94 Normal 1 4088 CTable::Run 7c91eb94 Normal 1 3084 CTable::Run 7c91eb94 Normal 1 380 0Und an folgender Stelle bleibt er hängen:
void CTableManager::Release() { for( int table=0; table < m_aTables.size(); table++ ) { > m_aTables.at(table)->Stop(); // HIER } }Die Methode "Stop" schaue folgendermaßen aus:
BOOL CTable::Stop() { if( m_bInit ) { m_bStop = TRUE; WaitForSingleObject( m_hRunThread, 10000 ); CloseHandle( m_hRunThread ); return TRUE; } return FALSE; }So, WaitForSingleObject() scheint wohl die Ursache zu sein. Wenn ich die Funktion entferne, werden alle Threads durch den Primär Thread zum Ende gezwungen.
Hier mal ein Ausschitt aus der CTable::Run
DWORD WINAPI CTable::Run( LPVOID lpParam ) { // pointer CTable *pT = (CTable*)lpParam; // do some updates while( !pT->m_bStop ) { // Wenn diese Zeile weg ist, klappt alles wunderbar pT->m_cConsole.AddLine( "Update" ); Sleep(0); } OutputDebugString( "\n Thread Finished" ); return 2; }
-
Achja, die Funktion AddLine schaut folgendermaßen aus:
void CConsole::AddLine( char *msg ) { if( m_hWnd != NULL ) { int length = (int)SendMessage( m_hWndConsole, WM_GETTEXTLENGTH, 0, 0 ); SendMessage( m_hWndConsole, EM_SETSEL, length, length ); SendMessage( m_hWndConsole, EM_REPLACESEL, TRUE, (LPARAM)msg ); } }
-
Ok, es gibt auf jedenfall eine Verbindung zwischen den RichEdit funktionen (egal was passiert Ob man texte einfügt ob nur die Länge des Textes abgefragt wird), wenn ich das in einem Thread aufrufe und parallel WaitForSingleObject aufrufe gibt es Probleme.
Wobei ich nicht glaube, dass das Problem bei WaitSingleObject liegt - Hier wird nur gewartet bis der Thread beendet wird (Was er nicht tut).
Es muss ein Problem sein, was mit Thread und einer RichEdit Komponente zu tun hat.
Jemand eine Idee??

-
Neue Theorie:
Könnte es sein, dass durch WaitForSingleObject() Die RichEditKomponente keine Nachrichten mehr verarbeiten kann (da dadurch der Primär-Thread mit der Msg-Queue lahmgelegt ist)?
-
Genau das passiert! Du wartest auf den Thread und nun können keine Nachrichten mehr empfangen werden. Verwende MsgWaitForMutipleObjects und lass die Message Loop weiter laufen.
Es ist gar nicht gut, dass das RTF Control in einem anderen Thread liegt!
Warum machst Du das überhaupt?
-
Also ich hab das mal mit "MsgWaitForMultipleObjects" ausprobiert - war aber kein Erfolg.
MsgWaitForMultipleObjects( 1, &m_hRunThread, TRUE, INFINITE, QS_ALLINPUT ); CloseHandle( m_hRunThread );Mit folgendem Code klappt alles wunderbar:
while( m_bThreadRunning ) { CBaseApp::GetApp()->ProcessMessageQueue(); Sleep(0); }Mit CBaseApp::ProcessMessageQueue
void CBaseApp::ProcessMessageQueue() { MSG msg; if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { TranslateMessage(&msg); DispatchMessage(&msg); } }Warum machst Du das überhaupt?
Das ist automatisch so, da die Klasse CConsole im Primär-Thread erstellt wird und damit auch zu dieser Queue "gehört"!!
Wie könnte man das denn anders regeln? -> Somit hätte jeder Thread eine eig. Queue?
-
1. MsgWaitForMultipleObjects returniert auch, wenn eine Nachriht in der Message Queue drin ist! Dann muss also auch die Nachrichtenschleife laufen. Diese Funktion behandelt keine Nachrichten!
2. Ich verstehe immer noch nicht was CConsole ist! Das ist das RTF Control?
Wenn Du also Nachrichten aus den anderen Threads bekommst, dann musst Du auch bis zum letzten Moment auf Nachrichten reagieren.
Also
MsgWaitForMultipleObjects durchführen.
Wenn eine Nachricht vorhanden ist, diese bearbeiten.
Solange das weiter machen, bis alle Threads terminiert haben.
-
BTW:
Dein Code:int length = (int)SendMessage( m_hWndConsole, WM_GETTEXTLENGTH, 0, 0 ); SendMessage( m_hWndConsole, EM_SETSEL, length, length ); SendMessage( m_hWndConsole, EM_REPLACESEL, TRUE, (LPARAM)msg );Ist nicht threadsicher. Was passiert wenn zwei Threads gleichzeitig hier die Nachrichten "durcheinander" senden. Also nachdem du WM_GETETXTLENGTH ausgeführt hast ein anderer Thread die Länge verändert.
Du solltest Dir einen anderen Mechanismus für die Nachrichten ausdenken.