MyWpfStateMachine

Hinterlasse einen Kommentar

State-Machines sind, wie der Name schon vermuten lässt, eine gute Strategie um Programme oder Programmteile in einen definierten Zustand zu setzen und so bestimmte Realitäten und deren Abläufe abzubilden, Automaten zu steuern oder zu simulieren. Beispiele sind Kaffeeautomaten (Geld einwerfen, Becher kommt raus, Kaffee wird eingefüllt oder ähnliches…), Geldautomaten oder andere, kompliziertere Maschinen.
MyWpfStateMachine ist ein Wpf Programm das eine sehr einfache aber Abstrakte State-Machine darstellt:

State-Machines haben nicht nur Zustände (States) sondern auch definierte Übergänge (Transitions) von einem Zustand zu einem anderen Zustand. Das wäre auch der Unterschied zu einer einfachen Variablen und einer Case-Struktur. Es sind somit auch bestimmte Übergänge verboten, nämlich die, die nicht definiert sind.
Unsere State-Machine hat folgende Zustände:

  • Start
  • State01
  • State02
  • State03
  • State04
  • End
  • InvalidTransition (wobei das nicht wirklich ein Zustand darstellen soll)

und folgende Übergänge:

  • Command01
  • Command21
  • Command22
  • Command02
  • Command03
  • Command04

deren Zusammenhänge wie folgt sein sollen:

Die Zustände und deren erlaubten Übergänge sind in der Klasse MyStateMachine mit Hilfe eines Dictionary realisiert. Die von Konstruktor aufgerufene Funktion InitStateMachine() definiert diese.
Das eigentliche Programm hat auf der rechten Seite zwei Button Gruppen wobei die eine nur aus einem Button, nämlich Next State besteht und die andere aus den Buttons Start, Command#1 bis Command#4. Unter dem Lable Machine State kann man den Zustand der Maschine sehen.
Man hat nun die Möglichkeit den Button Next State zu drücken und so die alle Zustände zu durch laufen, an der Stelle wo es zwei Möglichkeiten gibt (nämlich bei State#1) erscheint eine MessageBox, die fragt welchen Zweig man wählen möchte, oder man drückt in der zweiten Button Gruppe (Start, Command#1 bis Command#4) ein Kommando und durchläuft so die State-Machine. Dabei kann man auch Fehler machen z.B. wenn die Maschiene den Sate State03 hat und man drückt den Button Command21, dann ertönt ein Beep und der Fehler wir in der TextBox Message unten links ausgegeben.

Folgende Features werden gezeigt:

  • Realisierung einer State-Machine
  • Gebrauch von Dictionarys in C#
  • Anzeigen von Grafiken in Tooltips

Das Projekt auf Github.

Advertisements

WinGUp der coole Updater von Notpad++

Hinterlasse einen Kommentar

wingup ist ein Fork von gup4win/wingup von Don HO dem Programmier von Notepap++ auf GitHub. Es ist der automatische Update-Downloader von Notepad++. Notepad++ fand ich schon immer ziemlich gut und den automatischen Download, das anschließende automatische startet des neuen Setups ist eine schicke Lösung, die unkompliziert und einfach ist.
Deswegen wollte ich den dahinter stehenden Mechanismus gerne für eigene Software nutzen (LogMonitor und ComMonitor). Diese beiden Programme sind aber nicht in C++ geschrieben wie Notepad++ sondern es handelt sich um Wpf bzw. .Net Programme. Dadurch waren einige Änderungen nötig. WinGUp führt im Prinzip 4 Aktionen aus:

  • Es prüft ob eine neuere Version der Software – auf einer bestimmten Quelle im Internet – vorhanden ist und wenn das der Fall ist, dann:
  • lädt es das neue Setup herunter
  • schließt die aktuelle laufende Software
  • und starte anschließend das neue Setup

das Beenden der aktuelle laufende Software funktioniert bei Notpad++ über die registrierte Windows Klasse der Win32 Api. Unter .Net funktioniert das nicht. Aus diesem Grund habe ich WinGUp so geändert das es nach dem Text in der Titelleiste der Anwendung sucht z.B. LogMonitor_ und dann dieses Fenster schließt. Alles andere funktioniert so wie auch bei Notpad++. Für eventuell vorkommende Leerzeichen wird ein _ gesetzt, das dann später getauscht wird.

Den Fork findet man auf GitHub

MyWpfProducerConsumerPattern

1 Kommentar

Möchte/muss man mehrere Geräte steuern/überwachen von einer Anwendung aus, so sollte man sich das Producer–Consumer-Pattern einmal genauer ansehen. Es liegt in so einem Fall nahe jedem Gerät einen Thread zuzuordnen. Die Microsoft TPL (Task Parallel Library) enthält außer den Tasks-Klasse (async/await sind wohl ihre bekanntesten Vertreter) noch andere Klassen die nützlich sind solche Probleme zu lösen z.B. die BlockingCollection Klasse. MyWpfProducerConsumerPattern ist eine kleine Wpf-Anwendung die so ein Szenario simuliert.

Es können bis zu 8 (virtuelle) Devices erzeugenden werden durch drücken des Add-Buttons, repräsentiert durch eine Task, denen man aus dem Haupt-Thread unterschiedliche Aufträge zuordnen kann. Diese werden von der zugeortneten Task abgearbeitet in dem ein zufälliger Return-Code erzeugt wird, der wiederum von in einer Queue zurück gegeben wird. Jeder Task ist eine Farbe und ein eigenes Ausgabe-Fenster zugeordnet um das ganze zu visualisieren:

Ich habe in diesem Beispiel ,die MyColoredLogListBoxDll und Teile von MyListViewControls übernommen.

Die Task, repräsentiert durch eine Lamda Funktion im Konstruktor der Device-Klasse, wartet an der Stelle


// Wait until the main thread orders an action
var action = JobQueueActions.Take();

darauf, dass der Main-Thread eine Aufgabe (JobAction) in die JobQueueActions einfügt.
Wurde die Task zum Leben erweckt mit Hilfe eines der Dynamischen Button in dem ListView so führt die bis dahin wartende Task ihre Aufgabe aus. In unserm Fall nur ein Sleep(500), dann fügt sie das Resultat in die ConcurrentQueue JobResponse ein. So kann der Main-Thread das Ergebnis threadsicher verarbeiten. Das habe wurde hier allerdings nicht implementiert. Stattdessen wurde die QueueDiplayList hinzugefügt aber nur um das Ergebnis in der ComboBox im ListView anzuzeigen. In einem richtigen Anwendungsfall würde man diese weglassen. Ansonsten Läuft sie hier genau synchron mit der JobResponse Queue. Ich habe es auch nach längerem Versuchen nicht hin bekommen die Queue in der ComboBox anzuzeigen, des wegen diese ‚unelegante‘ Lösung.
Der Vorteil des benutzen der Klassen aus der TPL liegt darin das man sich mit den ‚100 Millionen‘ Klassen und Funktionen zum Synchronisieren von Threads, die es in .Net gibt nicht herumschlagen muss (siehe: Lock, Monitor, Mutex, Semaphore, SemaphoreSlim, WaitOne, Release, Wait, AutoResetEvent … usw).

Folgende Features werden gezeigt:

Das Projekt gibt’s wie immer hier auf Github

LogMonitor

Hinterlasse einen Kommentar

ist eine weitere kleine aber vollständige Anwendung zum online betrachten von Log-Files (ähnlich wie ComMonitor, das auch eine eigene abgeschlossene Anwendung ist). Der eigentliche Grundgedanke ist aber mehr ein Anschauungsobjekt als eine professionelle Anwendung. Trotzdem erfüllt sie ihren Zweck. Ich habe mir auch hier mal die Mühe gemacht eine eigene Webseite dafür einzurichten.
Für die optische UI Darstellung habe ich MahApps.Metro library gewählt und da ich die alten Microsoft Blacklight Controls eigentlich immer ziemlich cool fand habe ich mir die Arbeit gemacht die Panels aus der Blacklight Lib heraus zu schneiden und in das Projekt einzubinden.

Ziemlich schwierig gestaltete sich die richtige Auswahl zu treffen, mit welchen der „100 Millionen“ Dateifunktionen, die .Net zur Verfügung stellt, die richtige ist. Es kam zu doch recht merkwürdigen Effekten, wie ich feststellen musste. Zum Beispiel funktionierte das ganze nur eine gewisse zeit lang, dann wurden die Files nicht mehr upgedatet (ein Phänomen das ich übrigens auch bei einigen Linux-Versionen feststellen konnte mit dem Tail-Befehl). Schließlich funktionierte die Strategie mit dem .Net FileSystemWatcher und

using (FileStream stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
}

und

using (StreamReader reader = new StreamReader(stream))
{
}

Folgende Features werden gezeigt:

 

Das Projekt gibt’s hier und die Webseite befindet sich hier.

MySimpleCsvConsoleAppCpp

Hinterlasse einen Kommentar

ist ein C++ Konsolen-Programm das mit VS 2017 erstellt wurde. Es kann neben farbigen Ausgaben in der Windows-Konsole eine Csv Datei mit doubles (als Strings) einlesen und in eine Liste (list<string>) laden oder eine Csv mit random doubles erstellen und zurück in eine Datei schreiben.

Zu bemerken wäre, dass die MyCsvClass nicht sicher programmiert ist. Gemeint ist das sie keine Exceptions wirft oder abfängt. Wird ihr eine Csv-Datei vorgesetzt die sich nicht verarbeiten lässt (kein „;“ als Seperator, keine doubles als Inhalt etc.) kann die Anwendung abstürzt.

Folgende Features werden gezeigt:

  • Farbige Ausgabe in einer Konsole für eine C++ Windows Anwendung
  • Lesen und schreiben in einer Text Datei mit C/C++
  • Csv Datei in C/C++ verarbeiten

Das Projekt auf Github.

Hinweis zum kompilieren ist das Windows 10 SDK notwendig. Der Download ist hier.

MyKillWinAppCpp

Hinterlasse einen Kommentar

ist eine MFC C++ Anwendung, die alle Fenster auf dem Desktop durch iteriert und in einer ComboBox speichert. Wählt man einen Eintrag aus der ComboBox aus wird dieser in das Edit Feld geladen, so dass man es editieren kann wenn man es möchte um dann die Anwendung (das Fenster) mit dem Inhalt in dem Fenster Rahmen zu beenden:

Dies ist eigentlich ein WPF und .Net Blog, gelegentlich gibt es aber Ausnahmen, wie diese. Der Grund hierfür war das kleine ComMonitor Projekt. In dem ich die Software aus dem Internet updaten wollte wenn es eine neue Version gibt. So wie bei Notpad++, dessen Mechanismus ich auch mit freundlicher Genehmigung von Don Ho benutze (WinGup). WinGup hat nur einen kleinen Nachteil für WPF Anwendungen. Es schließt die upzudatende Anwendung auf Grund der unter Win32 registrierten Fenster-Klasse (RegisterClassEx). Die gibt es aber bei .Net Anwendungen so nicht. Deshalb muss man das Programm so ändern, das es auch für WPF Anwendungen brauchbar ist. Ich habe mich dazu entschlossen nach der Titelzeile im Fenster zu suchen und so das Fenster zu schließen. Eine nicht ganz ungefährliche Methode aber bis jetzt hatte ich keine bessere Idee. Nach den Äderungen in WinGup entschloss ich das Ganze in ein eigenes, kleines, „sauberes“ Demo-Projekt zu packen.

Folgende Features werden gezeigt:

  • Beispiel für Win32 EnumWindows
  • Beispiel für eine MFC C++ Dialog Applikation

Das Projekt gibt’s hier.

MyWpfTabApp

Hinterlasse einen Kommentar

ist ein eine Wpf Tab-Anwendung die unterschiedliche Tab-Typen anzeigen kann, die dynamisch hinzugefügt und entfernt werden können:

Dieses Beispiel ist in C# 7.0 kompiliert und mit Visual Studio 2017 erstellt und es ist konsequent im MVVM-Pattern geschrieben. Es werden zur Laufzeit unterschiedliche Typen dem Tab-Control zugewiesen, das kann man in C# mit Interfaces realisieren:

    ITabViewModel itvw = new TabPictureViewModel();
    oder
    ITabViewModel itvw = new TabTextViewModel();

 

Eine Klasse, die von einem Interface abgeleitet wurde kann man einer Variablen von selben Typ dieses Interfaces zuweisen. Auch wenn es in Wirklichkeit unterschiedliche Klassen sind. Umgekehrt geht es nicht, also:

    TabPictureViewModel ipvm = new ITabViewModel(); 
    oder 
    TabTextViewModel ttvm = new ITabViewModel();

 

führt zu einem Compilerfehler, da laut Definition aus einem Interface keine Instanz erstellt werden kann.
Dies ist ein gutes Beispiel für das Inversion of Control Prinzip in der Objektorientierten Programmierung (siehe hier, hier oder hier)

 

 

Das Projekt auf Github.

Older Entries