MessageQueue leeren?



  • Hi Leute!

    Wie kann ich das machen, hab schon in der MSDN gesucht, aber nix passendes gefunden, es gibt zwar "Delete" als Funktion einer MessageQueue, aber die gilt für Queues auf einem Server.
    Ich möchte die lokale löschen. Benutze VC++.NET.
    Ich hab nen Timer, der alle 50 Millisekunden feuert. Dann wird eine Funktion ausgeführt, von der ich annehme, sie dauert länger als 50 Millisekunden, also verstopfe ich die MessageQueue. Das äußert sich in Nichtreaktion nach einer Weile, das Programm fürht nichts mehr aus. Das sollte ich beheben können, wenn ich die Warteschlange am Ende der Funktion löschen kann.

    Danke

    Ranger



  • Hilft es, mit GetMessageTime nachzufragen, ob das schon zu lange her ist? Dann könnte das Programm ja "aufholen". 🙂



  • Also das war es nicht.
    Ich hab inzwischen nach einem Weg gesucht, den Timer auszusetzen oder für die Zeit der Funktionsabarbeitung anzuhalten und dann wieder loslaufen zu lassen. Ist das evtl. ne Variante?

    Ranger



  • Hi!

    Wie wäre es einfach mit einem KillTimer zu beginn der Funktion und SetTimer nach Beendigung?



  • Also mit KillTimer sollte es ja gehen, aber das gleiche Problem, langsam glaub ich, es liegt am System und nicht am Programm, denn wenn er gekillt ist, dürfte er ja keine weitere Message in die Warteschlange feuern.

    Ranger



  • Hi!

    Möglicherweise setzt irgendein Control einen Timer?! Ist es den die gleiche Timer-ID? Wenn ich mich nicht ganz täusche (irgendwo entfernt hab ich mal was gelesen), werden neue Timer-Nachrichten nur versandt, wenn alte beantwortet wurden. Wie gesagt, ist echt lange her und ich kann mich da auch irren. Bevor du verzweifelst nimm eine Hilfsvariable (okay, das wird nicht sehr elegant) und mach folgendes:

    ...

    if(!m_TimerFunkNichtFertig)
       {
       TimerFunkNichtFertig= true;
       ....
       TimerFunkNichtFertig = false;
       }
    

    ...

    Soll heißen, lass die Timer-Messages verstreichen, solange die Funktion arbeitet. Nicht besonders doll, aber möglich.
    Wäre das möglich?

    Gruß,
    A.K.



  • Jetzt wird es ganz verrückt.
    Die Timer funktion ist schon in Ordnung, ich möhcte das am Quellcode und seinen Erscheinungen erklären:

    void CFarbenDlg::OnTimer(UINT nIDEvent)
    {
    	KillTimer(nIDEvent);
    
    	CSliderCtrl * slider;
    	CEdit * edit;
    
    	slider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_BLAU);
    	blau = slider->GetPos();
    
    	slider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_GRUEN);
    	gruen = slider->GetPos();
    
    	slider = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_ROT);
    	rot = slider->GetPos();
    
    	CStatic * stat;
    	CString help;
    
    	stat = (CStatic *)GetDlgItem(IDC_STATIC_BLAU);
    	help.Format("%i",blau);
    	stat->SetWindowText(help);
    
    	stat = (CStatic *)GetDlgItem(IDC_STATIC_GRUEN);
    	help.Format("%i",gruen);
    	stat->SetWindowText(help);
    
    	stat = (CStatic *)GetDlgItem(IDC_STATIC_ROT);
    	help.Format("%i",rot);
    	stat->SetWindowText(help);
    
    	edit = (CEdit *)GetDlgItem(IDC_EDIT1);
    	edit->RedrawWindow(0,0,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
    
    	SetTimer(1,50,NULL);
    }
    

    Ihr seht, es gibt Slider und Ein großes Editfeld, was mir als Farbanzeige dient. Die Werte der Slider, werden zusätzlich daneben angezeigt.
    Das Programm läuft anfangs super stabil, es flackert nicht und alles ist ok. Wenn ich nach einer Weile wieder dazu komm, ohne was getan zu haben scheint es zuu blockieren, wie ich vorher schon beschrieben hab. Nun gibt es ein Kuriosum. Bewege ich die eingefrorenben Slider ändern sich die angezeigten Zahlenwerte der Slider, aber die Anzeige der Slider selbst bleibt stehen, aber sie nehmen andere Werte an. Die FArbe des Editfeldes ändert sich auch nicht mehr. Also Grundsätzlich geht er in diese Funktion, führt dann aber nur noch den Teil aus, wo die Static - Felder aktualisiert werden.

    Kann mir das jemand erklären?

    Danke, Ranger.



  • Hi!

    Mit KillTimer(nIDEvent); killst du ja jeden Timer 😮

    Wenn du SetTimer(1,50,NULL) nutzt, würde ich auch nur diesen Timer killen.

    So am frühen morgen würde ich mal das behaupten:

    m_myTimer = SetTimer(1,50,NULL);
    
    void CFarbenDlg::OnTimer(UINT nIDEvent)
    {
        if(nIDEvent == myTimer )
            {
            KillTimer(nIDEvent);
            ...
    

    Sollte nämlich irgendein Control auch einen Timer nutzen, wird der gnadenlos von dir abgewürgt. Wo durch bestimmte Nachrichten (Mausbewegungen einfangen z.B.) nicht mehr unterbrochen werden. Dieses würde das seltsame Verhalten erklären.

    Gruß A.K.



  • Welchen Datentyp hat denn m_myTimer?



  • UINT_PTR



  • HAb ich schon rtausgefunden, aber der Effekt zeigt sich nicht anders. Das Problem istm die Slider sind nach einiger Zeit gar nicht mehr zu sehen lassen sich aber virtuell noch bewegen, weil sich die Werte der Slider noch anzeigen lassen und sich bei Bewegung Die Positionsanzeige in Form desWertes ändert.

    Ranger.


Log in to reply