Blinkende Textfelder und Buttons
-
Vorweihnachtliche Grüße an Euch allen! :xmas1:
Ich habe leider so kurz vor Weihnachten eine Denkblockade und hoffe es gibt eine einfache Lösung für meine Fragestellung.
Ich habe eine Funktion, die immer dann aufgerufen wird, wenn sich Zustände ändern. In meiner GUI habe ich eine List Control im report style, die die Variablen mit den aktuellen Zuständen anzeigt. (Kann man sich so Vorstellen wie eine Alarmanlage) Bei OK = GREEN und bei NOK = RED. Jetzt würde ich gerne wenn sich ein Wert von OK nach NOK ändert die Felder in der List Control nicht 'nur' rot einfärben sondern diese sollen auch noch blinken. (Quasi ein Quittierungsmodus)
Mein Problem ist der Blinkmodus. Da die Funktion nur bei Werteänderung aufgerufen wird, frage ich mich wie ich den Blinkmodus am Besten programmieren kann. Weil das blinken läuft ja über setTimer(), der dann jede Sekunde eine Variable von TRUE nach FALSE setzt und umgekehrt. Somit müsste ich bei Werteänderung eine Funktion aufrufen die in einer while(1) Schleife quasi unendlich die Farben jede Sekunde ändert. Das geht aber nicht, da das Programm dann dort ständig verharrt.
Ich brauche also irgendwie ne Möglichkeit diese while() Schleife parallel zu meinem Programmablauf laufen zu lassen. Von threading habe ich gelesen. Wie setze ich das um? Hat einer eine Ideee?Danke schonmal und Euch ein frohes Fest.
Michael
-
Du bekommst doch die Timer-Nachrichten (SetTimer) wie jede andere Nachricht auch durch die Message-Queue. Da blockiert nix zwischendrin. Erstelle einen Timer mit halber "Blink-Wellenlänge" und setze die Farben / Sichtbarkeit der Elemente entsprechend um.
-
Der Timer ist schon genau richtig dafür, du darfst nur nicht dein Programm blockieren, d.h. die while-Schleife ist völlig unnötig.
In der Timer-Funktion erzeugst du einfach ein Aktualisieren deines Controls, d.h. Invalidate() aufrufen. Und in der Zeichen-Routine für dein List-Control prüfst du dann einfach den aktuellen Blinkstatus und zeichnest entsprechend.
-
Wieso thread, warum mit kanonen auf spatzen schießen, setz doch einfach einen timer der im Sekundentakt eine Variable switcht und die anzeige aktualisiert und fertig ist das. Das größere Problem wird sein die anzeige so hin zu bekommen das es nicht flakert denn wenn du im Sekundentakt deine Liste aktualisierst und er immer wieder die Liste neu zeichnet weiss ich nicht wie das optisch aussieht.
das ganze würde ich auf jeden fall in einer eigenen Klasse abgeleitet von CListCtrl kapseln, dann wird die ganze sache nicht unübersichtlich.
-
Hey Leute!
Frohes neues Jahr wünsche ich erstmal allen.
Ich habe das blinken über den Timer realisiert und muss sagen, es funktioniert. Allerdings ist leider eingetreten, was hier schon vermutet wurde. Es flackert und sieht dadurch sehr unschön aus. Bei mir ist es ja der Fall, dass Felder in der List Control und ein paar Buttons blinken sollen. Gibt es nicht eine Möglichkeit nur diese zu aktualisieren? Also nicht die ganze Ausgabe neu zeichnen, sondern nur vordefinierte Teile daraus?
gruß
Michael
-
Wie machst Du es denn nun?
Zeichnest Du alle Controls neu?Ein InvalidateRect auf die Controls die neu gezeichnet werden sollen genügt.
-
Wäre nett wenn du den teil mal posten könntest da ich das so nicht ganz verstehe versuche auch sowas zu realisieren.
-
Also ich hab es folgendermaßen gelöst:
Es gibt eine Klasse, die immer dann aufgerufen wird, wenn sich die Eingangswerte der Peripherie ändern. Wenn diese Klasse also aufgerufen wird überprüfe ich in der selbigen, wie sich die Werte geändert haben, also ob ein Alarm anliegt oder nicht.
STDMETHODIMP CMeinKleinerAlarm::DataChange( bla bla) { .... .... if(ALARM) m_blinkOnOff = TRUE; .... ... }
Die Variable m_blinkOnOff ist eine boolsche Membervariable, die später das blinken ein bzw. ausschaltet.
Jetzt habe ich mir eine Klasse OnTimer erstellt die dann eine Variable im Wert ändert, wenn m_blinkOnOff==TRUE ist:
void CMeinKleinerAlarm::OnTimer(UNIT nIDEvent) { if (m_blinkOnOff==TRUE) { if(m_blink==FALSE) { m_blink = TRUE; Blinking(); } } else { m_blink = TRUE; Blinking(); }
Wie man erkennen kann ist m_blink eine Variable, die sich immer dann ändert, wenn OnTime() aufgerufen wird. Um dies zu realisieren, wird bei mir in der Klasse OnInitDialog() ein Timer mit gesetzt.
SetTimer(1,500,NULL)
So jetzt kann man in der Klasse Blinking, die alle 500ms aufgerufen wird das eigentliche blinken programmieren.
Da ich eine eine modifizierte ListCtrl von CodeGuru benutze brauche ich nur die Variable m_blink abzufragen und das jeweilige Item farblich ändern. Die modifizierte Liste kannst du dir hier anschauen:
http://www.codeguru.com/Cpp/controls/listview/article.php/c4189void CMeinKleinerAlarm::Blinking() { if(m_blink==TRUE) { meineListe.SetItemBgColour(0,0,RGB(255,0,0)) meineListe.SetItemStyle(0,0,LIS_BGCOLOR) } if(m_blink==FALSE) { meineListe.SetItemBgColour(0,0,RGB(0,255,0)) meineListe.SetItemStyle(0,0,LIS_BGCOLOR) } }
Es ist natürlich noch nicht ganz fertig aber die Funktion des Blinkens ist somit schonmal gegeben. Jetzt muss jeder für sich überlegen, wie er die Funktion Blinking() programmiert, damit das blinken so ausgeführt wird wie er sich das wünscht.
Wenn aber irgendjemand gerade heulend vor dem Rechner zusammengebrochen ist, weil er meint: Das geht so aber gar nicht!!!!! Dann bitte belehrt mich. Ich möchte dazulernen!!
schönen Tag Euch noch und Draiman gib mal ein Feedback ob ich dir so helfen konnte, bzw. wie du das gelöst hast.
Gruß
Michael