Abfragen von Nachrichten innerhalb einer Reaktion auf eine Meldung
-
Hallo Leute,
ich programmiere erst seit einiger Zeit mit MS Visual C++ 6.0 mit Hilfe der MFC und möglicherweise ist mein Problem ziemlich banal.
In einem Dialogfenster sind mehrere Buttons implementiert. Ein Button startet einen Vorgang, der intern eine Zählschleife und einige andere Dinge in Gang setzt. Hierzu kurz ein wenig Pseudocode:CTestdialog::OnStart() { int i=0; while (i<=30000) { //hier müsste die Abfrage nach WM_KEYDOWN erfolgen i++; WeitereMethode(i); } }
Während das Programm die while-Schleife abarbeitet soll der Benutzer die Ausführung der Schleife mit einem Tastendruck (z.B. ESC) oder mit einem Klick auf den zweiten Button (CTestdialog::OnStop() wird dabei ausgelöst)unterbrechen können. Meiner Meinung nach fragt das Fenster zumindest nicht aus freien Stücken nach anstehenden Meldungen. Weiterhin kann man während des ganzen Ablaufes zwar die Maus bewegen aber ein Klick auf einen Button ist nicht möglich.
Lege ich die Schleife in einen zweiten Thread (was ich eigentlich ungern machen will) dann kann man zwar den Button drücken aber das System ignoriert diese Aktion. Ich habe die Methode CTestdialog::PreTranslateMessage(MSG *pMsg) schon dahingehend überschrieben, dass ich innerhalb des Dialogfeldes auf Tastatureingaben reagieren kann (funktioniert auch). Mir ist leider keine Möglichkeit bekannt, wie man unter der MFC innerhalb der "Reaktionsroutine" auf eine Nachricht nach weiteren Nachrichten (z.B. WM_KEYDOWN) reagieren kann. Kann mir da jemand weiterhelfen?
-
Ich weiß jetzt nicht, ob es für MFC direkt eine Entsprechung gibt.
Deshalb sage ich dir, wie man es in reiner Windows-API programmierung lösen würde, evtl. klappt es auch in deinem Fall.Man unterscheidet bei der Nachrichtenbehandlung zwei Befehle.
1. GetMessage <- liest die nächste Nachricht vom Stapel wenn eine vorliegt, ansonsten wartet(blockiert) der Befehl solange, bis es etwas zu verarbeiten gibt. Das ist im normalfall ok, da eine Anwendung nur etwas tun soll, wenn der Anwender eine Eingabe tätig.2. PeekMessage <- schaut nach, ob eine Nachricht (z.B. Tastendruck vorliegt), blockiert aber nicht, falls nicht.
Also sinngemäß in deinem Problem:while (i<=30000) { if (PeekMessage) { //Nachrichtenweiterleitung evtl. continue } i++; WeitereMethode(i); }
-
SeppSchrot_unreg schrieb:
Ich weiß jetzt nicht, ob es für MFC direkt eine Entsprechung gibt.
Deshalb sage ich dir, wie man es in reiner Windows-API programmierung lösen würde, evtl. klappt es auch in deinem Fall.Man unterscheidet bei der Nachrichtenbehandlung zwei Befehle.
1. GetMessage <- liest die nächste Nachricht vom Stapel wenn eine vorliegt, ansonsten wartet(blockiert) der Befehl solange, bis es etwas zu verarbeiten gibt. Das ist im normalfall ok, da eine Anwendung nur etwas tun soll, wenn der Anwender eine Eingabe tätig.2. PeekMessage <- schaut nach, ob eine Nachricht (z.B. Tastendruck vorliegt), blockiert aber nicht, falls nicht.
Also sinngemäß in deinem Problem:while (i<=30000) { if (PeekMessage) { //Nachrichtenweiterleitung evtl. continue } i++; WeitereMethode(i); }
Danke erst mal für den Tip. Funktioniert leider nicht. Habs in etw so realisiert:
while (i<=30000) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) // habs auch mit PM_NOREMOVE getestet { if (msg.message == WM_KEYDOWN) return TRUE; //Nachrichtenweiterleitung evtl. continue } i++; WeitereMethode(i); }
Gibts eine Möglichkeit in der Schleife die CTestdialog::PreTranslateMessage() aufzurufen?
-
Hallo Andy,
du musst eine Eventschleife aufrufen, damit die Messages ganz normal weiterverarbeitet werden. Dies ist vor allem wichtig, damit auch die Paint-Messages verarbeitet werden. (Z.B. wenn du den Verlauf der Aktion in einem Statusfeld protokollierst)
Damit aber der Dialog nicht geschlossen wird oder eine andere Aktion aufgerufen wird, müssen alle Kontrollen außer dem Stop-Button deaktiviert werden.class CTestdialog { ... BOOL m_bStopped; // sollte im Konstruktor von CTestdialog auf FALSE gesetzt werden ... }; void HandleEvents() { MSG msg; while (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) return; } } CTestdialog::OnStop() { m_bStopped = TRUE; } CTestdialog::OnStart() { // Alle Kontrollen im Dialog außer Stopbutton deaktivieren GetDlgItem(IDOK)->EnableWindow(FALSE); // ... m_bStopped = FALSE; int i=0; while (i<=30000) { HandleEvents(); if (m_bStopped) break; i++; WeitereMethode(i); } // Kontrollen wieder enablen GetDlgItem(IDOK)->EnableWindow(TRUE); //.... }
-
Uwe Philipps schrieb:
Hallo Andy,
du musst eine Eventschleife aufrufen, damit die Messages ganz normal weiterverarbeitet werden. Dies ist vor allem wichtig, damit auch die Paint-Messages verarbeitet werden. (Z.B. wenn du den Verlauf der Aktion in einem Statusfeld protokollierst)
Damit aber der Dialog nicht geschlossen wird oder eine andere Aktion aufgerufen wird, müssen alle Kontrollen außer dem Stop-Button deaktiviert werden.Hallo Uwe,
erst mal vielen Dank für Deinen Tip. Habe jetzt das Beispiel darüber auch soweit, das es zumindest so aussieht, dass es läuft. Dort ist allerdings das Problem, dass das Fenster nur auf Tastaturereignisse reagiert, Buttons kann ich keine drücken (ist auch klar, weil sich die Nachrichtenbearbeitungsroutine MessageMap sich noch in der OnStart befindet und auf nichts weiter reagiert). Was mir daran nicht gefällt ist, dass es nur mit PM_REMOVE läuft und ich nicht weiß was passiert, wenn Keydown-Botschaften dort eintreffen, die nicht dafür bestimmt sind.
Bei Deinem Code kann man zumindest den Ablauf mit den Buttons steuern. Allerdings kenne ich die Methode PumpMessage nicht. In MSDN steht was darüber, dass sie die Nachrichtenbearbeitungsscheife des Threads aufruft. Ist dabei der MainThread gemeint?
Dann bräuchte ich in der HandleEvent() ja nur noch die Reaktion auf Tastaturereignisse implementieren oder mach ich das woanders und die HandleEvent() ruft das über die MessageMap ab?
-
Hallo Andy,
die Funktion HandleMessages muss regelmäßig aufgerufen werden, also auch innerhalb von WeitereMethode(), falls die etwas länger braucht.
Dann sollten eigentlich alle Messages auf ganz normalem Weg über die MESSAGE_MAP ankommen, auch die Buttons sollten funktionieren (so sie nicht deaktiviert sind)
Du darfst allerdings nicht den Dialog selbst deaktivieren. PM_NOREMOVE ist auch wichtig!PumpMessage arbeitet die Messages des aktuellen Threads ab, also in deinem Fall wahrscheinlich des MainThreads.
-
Uwe Philipps schrieb:
Hallo Andy,
die Funktion HandleMessages muss regelmäßig aufgerufen werden, also auch innerhalb von WeitereMethode(), falls die etwas länger braucht.
Dann sollten eigentlich alle Messages auf ganz normalem Weg über die MESSAGE_MAP ankommen, auch die Buttons sollten funktionieren (so sie nicht deaktiviert sind)
Du darfst allerdings nicht den Dialog selbst deaktivieren. PM_NOREMOVE ist auch wichtig!PumpMessage arbeitet die Messages des aktuellen Threads ab, also in deinem Fall wahrscheinlich des MainThreads.
Soweit habe ich das auch verstanden. Wo wird denn in Deiner Routine HandleMessage aufgerufen? (Ich darf doch hoffentlich Du sagen?) Den Dialog habe ich nicht deaktiviert, es funktioniert soweit ja auch alles. Das ganze Fenster ist zur Steuerung eines Schrittmotors gedacht. Dieser bekommt seine Schritimpulse durch das Einschalten/Halten/Ausschalten eines Digitalausganges einer Multifunktions-IO-Karte. Dies wird in WeitereMethode() abgeabrbeitet, wo auch noch drei Messwerte eingelesen werden, die den Prozess stoppen oder nicht. Jetzt soll der Bediener auch entscheiden können, ob schin vor Erreichen der Messwertvorgaben abgebrochen werden soll oder nicht. Dazu soll er die Escape-Tastse drücken, um den ganzen Drehprozess zu stoppen. Wo implementiere ich denn das? Habe jetzt schon in der CTestdialog::PreTranslateMessage was geschrieben, aber das wird ignoriert.....
-
Ich meinte auch HandleEvents, als ich HandleMessages geschrieben habe...
Wenn du die Esc-Taste abfragen willst, sieht's so aus:
void CTestdialog::OnCancel() { if (m_bActionStarted) { m_bStopped = TRUE; return; } EndDialog(IDCANCEL) }
Kann es sein, dass du in WeitereMethode() auf die Hardware wartest? Während dieser Zeit wird natürlich keine Messageschleife abgearbeitet (mit HandleEvents). Im allgemeinen kommt man beim Zugriff auf I/O-Schnittstellen nicht um einen Thread herum.
-
Ja, das habe ich befürchtet. Denn schon das Bewegen der Maus bremst das Ganze, was in gewissen Grenzen aber nicht stören würde. Momentan bastel ich aber erst mal an der Ansteuerung des Motors und habe die Messwerterfassung noch nicht implementiert.
Das mit dem Überschreiben von OnCancel funktioniert nicht. Was ist denn mit m_bActionStarted gemeint? (sicher etwas was charakterisiert, dass die while-Schleife läuft) Ich bin blutiger C-Anfänger, sehe sicher die einfachsten Sachen nicht auf Anhieb (habe früher viel mit Borland Pascal 7.0 und Turbo Vision 2.0 gemacht, das kann ich)...
Muss man dann nicht noch die OnCancel von CDialog aufrufen oder wird das mit EndDialog beendet?
-
Versuche das ganze in einen Thread zu packen. Ist IMHO schönner und Prof.
-
Also, man nimmt keine Threads, nur weil's irgendwie professioneller wirkt, sondern wenn man sie braucht.
Vor allem sollte man Handler für ein Fenster nicht in unterschiedlichen Threads haben.
Zur Abfrage von Hardware ist ein Thread sinnvoll, weil dann das Programm bedienbar bleibt, wenn die Hardware mal auf sich warten lässt.
-
Ich denke das Du dir seinen letzten Beitrag nicht durchgelesen hast den daraus habe ich geelsen das er mit "Message selbst abholen" weiter machen möchte.
Weiters schreibt er das er Anfänger ist. Für eine Anfänger sidn Threads zwar nicht einfach aber er hat sich auch kein einfahces Programm ausgesucht. (Schrittmotorsteuerung)Und für DICH eine ungeschriebene Regel:
Trenne Funktionalität von der GUI.Tatsache ist das ein Fenster eine Thread hat. Dies ist eben der erste Thread. Dieser ist für GUI zuständig.
Wenn man Berechnungen macht darf man sich nicht wundern wenn die GUI nicht so reagiert wie sie soll. Es gibt > 1000 Programme davon.
Man kann sicher die MessageLooop selbst ausführen aer was ist wenn auf solche Messages auch wieder Berechnungen folgen. Daraus ergibt sich das dann das die Reaktion auf die Nachricht die eigentliche Berechnung aufhält was z.B. hier die Schrittmotorsteuerung bzw. Messdatenerf. ist.
-
Hallo Ihr,
auch wenn ich Anfänger in C bin, so programmiere ich doch schon länger. Das mit den Threads habe ich schon ausprobiert und es sogar lauffähig bekommen. Bei mir haperts meist mit der Syntax oder dem doch leicht anderem Konzept der OOP unter Visual C++. Was mir bei den zwei Threads Probleme bereitete war, dass ich zwischen den 2 Klassen (1. Klasse: Thread der den Motor steuert und misst; 2. Thread der den View des Fenster handelt) die Daten nicht so einfach hin und her schieben konnte. Nach der klassischen Doc/View-Trennung sollte es aber gehen. Ich hatte den Thread in eine separate Klasse gepackt und einfach aus dem View heraus aufgerufen. Der Datenaustausch funktionierte nur über globale Variablen, was ja auch nicht im Sinne der OOP ist. Wie ist es eigentlich wenn man den Thread als Methode der Fensterklasse im Doc des Fensters instanziiert? Dann sollte er doch als Methode der Klasse auch auf deren lokale Membervariablen zugreifen können, oder ist da meine Denkweise falsch? Weiterhin war bei es meiner Variante unter besstimmten Umständen möglich, mehrere Instanzen des Threads zun initialisieren (d.h. auch mehrere Motorthreads liefen und griffen (zeitlich geschachtelt aber quasi simultan) auf die Karte zu. Gut, diese Sache könnte man durch Deaktivieren des Startbuttons auschalten, da nur in dieser Methode ein Thread gestartet wird. Komischerweise sollte der Thread nur immer eine Instanz zulassen was aber aus irgendwelchen Gründen nicht funktioniert hat. Weiterhin habe ich mir die Vorgehensweise bei der Verwendung von Threads an einer SDI-Anwendung abgeschaut und es versucht, auf mein Dialogfeld anzupassen. Aber da ist ja schon das Problem, welches Doc-Objekt zu dem Dialogfeld gehört.
Allerdings ist immer noch nicht geklärt, wie ich meine Tastaturereignisse im Fenster abfange. Das was Uwe geschrieben hat habe ich zwar sinngemäß verstanden, es funktioniert aber nicht (auch weil ich nicht weiß, woher die eine Membervariable kommt).
-
AndyDD schrieb:
(auch weil ich nicht weiß, woher die eine Membervariable kommt).
In meinem Beispiel ist diese Membervariable gesetzt, während die Schleife läuft, damit die Doppelbelegung von OnCancel unterschieden werden kann.
Also so:class CTestdialog { ... BOOL m_bStopped; // sollte im Konstruktor von CTestdialog auf FALSE gesetzt werden BOOL m_bActionStarted; // muss im Konstruktor von CTestdialog auf FALSE gesetzt werden ... }; CTestdialog::OnStart() { // Alle Kontrollen im Dialog außer Stopbutton deaktivieren GetDlgItem(IDOK)->EnableWindow(FALSE); // ... m_bStopped = FALSE; m_bActionStarted = TRUE; int i=0; while (i<=30000) { HandleEvents(); if (m_bStopped) break; i++; WeitereMethode(i); } m_bActionStarted = FALSE; // Kontrollen wieder enablen GetDlgItem(IDOK)->EnableWindow(TRUE); //.... }
Was passiert denn eigentlich in WeitereMethode() ? Gib's da irgendwas, wo der Hauptthread auf den Arbeitsthread wartet (z.B. wegen Synchronisierung?)
-
Was passiert denn eigentlich in WeitereMethode() ? Gib's da irgendwas, wo der Hauptthread auf den Arbeitsthread wartet (z.B. wegen Synchronisierung?)
Hallo Uwe,
leider funktioniert das nicht. Ich denke, die Funktion OnCancel reagiert gar nicht auf Tastatureingaben, da wenn ich Escape drücke kein WM_ON_CANCEL-Ereignis ausgelöst wird und folglich dessen m_bStopped nicht TRUE wird (lt. Debugger). Wenn man egal welche Taste drückt wird der Lauf des Motors für einen Bruchteil einer Sekunde angehalten läuft aber dann weiter. Das hat ja aber mit der generellen Nachrichtenverarbeitung was zu tun.
Dann wolltest Du wissen, was in WeitereMethode() passiert. Da muss ich mal ein wenig ausholen. Für die Karte muss man ein von Hersteller mitgeliefertes Programm installieren. In diesem werden die Grundeinstellung (Kartentyp, Adresse der ISA-Karte, Messbereiche) festgelegt und auch irgendwo abgespeichert. Für Visual C gibts eine *.lib-Datei, die beim Linken eingebunden wird. Da sind mir auch schon komische Sachen passiert, aber das habe ich mittlerweile im Griff. Im Programm selber gibts eine Driver.h, in der die Datenstrukturen und Funktionen definiert sind. Die wird halt überall mit eingebunden. In meinem Fenster (spezieller in der Methode OnStart) initialisiere ich die Karte, d.h. ich hole mir einen Zeiger aus das Device mit Hilfe einer ID. Alle weiteren Operationen bekommen auch diesen Zeiger übergeben. Dann wähle ich das Schreibregisterbit aus (2. DigitalOut-Register). In diesem Register steht das 0. Bit für den Takt, das erste Bit für die Drehrichtung und das 2. Bit für die Möglichkeit, die Anbremsung des Motors zu deaktivieren (Entregen). Früher hatte ich unter TP7 ein DOS-Programm, welches direkt über die Systemports auf die Karte zugegriffen hat. Leider konnte man die nur byteweise beschreiben und da gabs einen Haufen Schiebeoperationen. Ist hier zum Glück nicht, ich kann auf jedes Bit eines Bytes direkt zugreifen. Die Funktion WeitereFunktion() bekommt genau diese Informationen als Referenz bzw. direkt übergeben (Drehrichtung und gebremst ja/nein) und macht einen Schritt. Für eine Umdrehung braucht das Teil 200 Schritte. Weiterhin sollen in dieser Funktion drei Messwerte (analoge Spannungen) eingelesen werden, eine auszugebende Analogspannung berechnet und ausgegeben werden, sowie die gemessenen Werte mit Vorgabewerten (Erwartungsfenster) verglichen werden. Danach wird entschieden ob der Motor einen weiteren Schrittmachen soll oder ob abgebrochen wird. Zusätzlich soll aber der Benutzer mit einem Tastendruck das ganze vorzeitig abbrechen können, wenn er Fehler festgestellt hat.
Wenn es zwischen den einzelnen Schritten gewisse zeitliche Dehnungen gibt ist das kein Problem, da das ganze sequenziell abläuft ist auch immer sichergestellt, dass der x-te Messwert zum x-ten Motorschritt gehört.
Zur Kröhnung des Ganzen wird alles graphisch (auch in WeitereMethode) dargestellt.
Ich habe das ganze schon mal unter TP7 und DOS realisiert und es läuft auch. Der Motor kann da bis zu 300 Schritte in der Sekunde (incl. Messen und Darstellen) schaffen, läuft aber alles auf einem 486-DX2 und soll jetzt netzwerkfähig werden.
Soviel erst mal dazu...
-
Zur Kröhnung des Ganzen wird alles graphisch (auch in WeitereMethode) dargestellt.
Aha! Das könnte das Problem sein. Gehört das Fenster, in dem die Graphik ist zu dem 2. Thread (also, der der die Maschine ansteuert)? Dann kann es nämlich sein, das dieses Fenster die Messages frisst.
Du solltest sicherstellen, dass alle Fenster zum Hauptthread gehören und der 2. Thread ein reiner Arbeits-Thread (worker thread) ist, und kein User-interface Thread. (s. Doku zu AfxBeginThread). Der kann dann z.B. die graphischen Infos an den Hauptthread über PostThreadMessage schicken.
-
Aha! Das könnte das Problem sein. Gehört das Fenster, in dem die Graphik ist zu dem 2. Thread (also, der der die Maschine ansteuert)? Dann kann es nämlich sein, das dieses Fenster die Messages frisst.
Du solltest sicherstellen, dass alle Fenster zum Hauptthread gehören und der 2. Thread ein reiner Arbeits-Thread (worker thread) ist, und kein User-interface Thread. (s. Doku zu AfxBeginThread). Der kann dann z.B. die graphischen Infos an den Hauptthread über PostThreadMessage schicken.
Die Grafik habe ich noch nicht implementiert, so weit bin ich noch nicht. Momentan existiert nur ein Dialogfenster (abgeleitet von CDialog), in dem verschiedene Buttons für z.B. Start und Stop, Vorwärts und Rückwärts sowie eine Ok- und ein Abbrechen-Button. Wenn ich das mit den Threads mache dann hätte ich das auch so getrennt. Allerings weiß ich noch nicht, wie der Arbeitsthread seine Messwerte an das Dialogfenster überträgt, ohne auf globale Variablen zurückgreifen zu müssen. Das Beispiel zur Arbeit mit Threads was ich habe habe ich aus irgend so einem VisualC-Buch. Allerdings ist das dort sehr einfach gehalten. Die haben die Threads in eigene Klassen gepackt und rufen die Methoden in dem View auf; der Thread selbst benötigt weder von außen Daten noch gibt er welche an andere Klassen weiter. Allerdings beinhaltet dort der Thread die Zeichenmethoden (ich glaube das ist das bsp. mit den Fraktalen) und der Main-Thread stellt sicher, dass während des Zeichnens das Programm bedienbar bleibt.
Aber um nochmal auf unser Beispiel hier zurückzukommen: das was Kollege SeppSchrot_unreg im ersten Beitrag geschrieben hat funktioniert, indem man auf sämtliche Tastatureingaben reagieren kann (sofern implementiert). Problem ist dabei:
1. in PeekMessage() muss der letzte Parameter PM_REMOVE sein, sonst klappts nicht. Allerdings weiß ich nicht was passiert, wenn Systemmeldungen, die nicht für dieses Dialogfenster bestimmt sind, von PeekMessage() abgefangen und nicht weitergeleitet werden. Regulär sollen ja alle vom Benutzer kommenden Meldungen (Mausereignisse, Tastaturereignisse) für dieses Dialogfenster bestimmt sein, da es sich ja um einen modalen Dialog handelt und der Rest für die Zeit des Existierens des Fensters Sendepause (oder hier besser Empfangspause) hat. Wenn man da nur auf das reagiert, was man benötigt und den Rest halt abfängt dan wäre das ja auch ok.
2. das Programm reagiert nur auf Tastatureingaben; mann kann zwar die Maus bewegen, Buttons lassen sich aber nicht drücken.Bei Deinem Beispiel lassen sich wunderbar die Buttons drücken. Allerdings beim Drücken von Tasten stockt der ablauf des Motors kurzzeiting, läuft aber dann weiter. Die Ereignisse werden wahrscheinlich weitergeleitet und dort wo sie landen gibts keine Methode, die eine Reaktion auslöst. Allerdings weiß ich nicht, wo die landen. Ich habe versucht, die PreTranslateMessage() zu überschreiben. Die reagiert nur, wenn man nicht in der OnStart (Motor läuft) ist, also das Fenster auch den Fokus hat. Gleich sieht es aus, wenn man die OnKeydown() überschreibt. Komischerweise habe ich mal versucht, das Abbrechen auf die Maus zu legen und habe die RButtonDown() dahingehend überschrieben, dass darin die Membervariable m_Stopped auf TRUE gesetzt wird. Das hat komischerweise funktioniert. Warum reagiert das Dialogfenster aber nicht, wenn man OnKeyDown() überschreibt?
-
Leite eine Klasse von CWinThread ab und übergib dieser den this-Zeiger deines Dialogs. Dann kannst du auch auf den Dialog zugreifen.
Es gibt ab auch andere möglichkeiten Daten an den Dialog zu geben. z.B. Message senden, etc.
Zu CWinThread findest du was in der FAQ.
Ohne Thread wirst du nicht auskommen. Vermutlich musst du Variablen auch noch Sync.
-
Unix-Tom schrieb:
Leite eine Klasse von CWinThread ab und übergib dieser den this-Zeiger deines Dialogs. Dann kannst du auch auf den Dialog zugreifen.
Es gibt ab auch andere möglichkeiten Daten an den Dialog zu geben. z.B. Message senden, etc.
Zu CWinThread findest du was in der FAQ.
Ohne Thread wirst du nicht auskommen. Vermutlich musst du Variablen auch noch Sync.Kannste mir da mal ein paar Denkansätze geben? Habe das bisher immer anders gemacht. Da hatte des View-Objekt nur einen Zeiger auf eine CWinThreadklasse, die dann eine Funktion vom Typ
UINT Funktionsname (LPVOID pWnd)
aufgerufen hat. Der Aufruf des Threads erfolgte dann in einer OnButton-Methode in etwa so:
void CTestdialog::OnStart() { m_myThread = AfxBeginThread(Funktionsname, this, THREAD_PRIORITY_irgendwas); }
Meintest Du an dieser Stelle die Übergabe des This-Zeigers? So richtig verstanden habe ich das allerdings nicht was da genau abgeht.
-
Esrtelle ein Klasse welche von CWinThread abgeleitet ist.
Näheres
http://www.c-plusplus.net/forum/viewtopic.php?t=39101