Dialog im Hintergrund anzeigen per Thread

Nach langer Zeit fühlte ich mich wieder einmal gedrängt einen Blogeintrag zu verfassen.

Momentan entwickle ich eine Software zum steuern von Pipettierrobotern. Genauer gesagt dem BioMek 2000. Das ganze ist eine sehr spezielle Anwendung und auf die Wissenschaftler unseres Unternehmens abgestimmt.

Mein Programm erstellt aus einer Exceldatei ein Script für den Roboter und lässt dieses von einer anderen Software ausführen. Meine Anwendung soll automatisch erkennen wann der Nutzer das Programm zur Ausführung des Scripts beendet hat. Soweit sogut, das funktioniert auch wunderbar. Nun wollte ich heute noch einen schicken Dialog an den Nutzer ausgeben, damit dieser weiß was genau gerade passiert und was er tun muss. Dazu hatte ich im Vorfeld schon eine WorkDialog Klasse erstellt. Mit dieser kann ein Dialog (wie ich ihn mehrfach in meiner Software brauche) angezeigt werden.

Das Problem an der Sache? Wie den Dialog anzeigen und automatisch schließen, wenn das Programm geschlossen wird?
Dazu gibt es mehrere Ansätze. Ich habe folgenden heute ausprobiert und bin sehr zufrieden.

Ein Wort als Hinweis noch: Die Klasse WorkDialog bietet an den Dialog als unschließbar und TopMost zu instanzieren.

Die Aufrufende Methode

void Run()
{			
  Process b2k = new Process();
  b2k.StartInfo.FileName = @"C:\BIOWORKS\b2krun.exe"; 
  b2k.StartInfo.Arguments = "run(\"" + "BIOSCRIPTER" + "\") /a";
			
  Thread userNotificationThread = new Thread(this.ShowBioWorkUserNotification);
  userNotificationThread.Start();
			
  try {
    b2k.Start();
    b2k.WaitForExit();
  } catch (Exception ex) {
    throw new Exception("Unable to run B2K, check your intallation!", ex);
  } finally {
    userNotificationThread.Abort();
}

Hier wird das Programm zum Ausführen des Scripts gestartet und solange gewartet bis es beendet wurde. Um das zu erreichen braucht man nur die Methode WaitForExit() nach dem Starten aufrufen.

An dieser Stelle sieht man auch das Problem nochmal. Die Methode wartet nun, wie kann ich also trotzdem einen Dialog anzeigen? Dazu wird hier ein Thread erstellt und dort die Methode ShowBioWorkUserNotification() ausgeführt.

Die Thread-Methode

void ShowBioWorkUserNotification(object inputData)
{
  WorkDialog wd = new WorkDialog(true, true);
  wd.Caption = "";
  wd.Headline = "BioWorks is running";
  wd.Message = "Please wait until the BioMek 2000 has finished his work." + Environment.NewLine + "Then close the BioWorksRun Window to " + "come back to BioScripter.";
  wd.SetWaitingIcon();
			
  wd.ShowDialog();
}

In dieser Methode wird nur mein WorkDialog instanziert (unclosable and topmost) und konfiguriert.
Damit dieser Thread nicht einfach zu Ende geht, verwende ich ShowDialog() statt nur Show(). Dadurch wird gewartet bis der Dialog geschlossen wird. Da dieser aber nicht vom Benutzer geschlossen werden kann, bleibt der Thread (und der Dialog) aktiv.

Wurde BioWorks nun vom Benutzer beendet läuft auch meine erste Methode weiter. Dort wird dann im Finally-Block der Thread mit dem Dialog beendet. Damit schließt sich auch automatisch der Dialog.

Schnell und recht einfach kann man so eine Meldung dauerhaft neben anderen Operation anzeigen lassen.

jQuery Plugin Galleria zeigt beim laden einen schwarzen Kasten

Beim jQuery Plugin Galleria wird ein schwarzer, seitenbreiter Kasten über der Seite angezeigt. Dies scheint nur aufzufallen, wenn der Seitenaufbau, z.B. durch viele Grafiken, länger dauert. Der Kasten geht für ca. 3 Sekunden auf und verschwindet dann wieder.
Zurückzuführen ist das Problem auf folgende Zeilen in galleria.js:

var testElem = this.create('div', 'galleria-container galleria-stage');
this.moveOut(testElem);
document.body.appendChild(testElem);

Lösen kann man das auch recht leicht. Ich habe eine CSS Klasse „invisible“ mit der Eigenschaft display: none; Dann noch folgende Änderung am JS und schon ist der Kasten weg:

var testElem = this.create('div', 'galleria-container galleria-stage invisible');
//this.moveOut(testElem);
document.body.appendChild(testElem);

jQuery Plugin Galleria zeigt im Opera keine Thumbnails

Wieder einmal stieß ich wärend meiner Arbeit an einem Webprojekt auf ein Problem mit dem Browser Opera. Diesmal im Zusammenhang mit Galleria (jQuery Galerie Plugin). Diese recht schicke Galerie war perfekt für das anliegende Projekt geeignet. Leider wurden die Thumbnailgrafiken im Opera nicht angezeigt. Nach etwas Debugging fand ich das Problem. Dem Thumb div (class galleria-image) wurde eine Höhe und eine Breite von 0px zugewiesen, dem Bild demnach auch. Dies trat allerdings nur im Opera auf.
Beheben lässt sich das ganze, indem man in der CSS Datei galleria.classic.css die Attribute height und width bei .galleria-image mit !important markiert. Dann funtionierts auch im Opera.

Ob das hier erwähnte auch mit andern Styles als der classic funktioniert weiß ich nicht, da ich keinen anderen Style benutzt habe.

Opera schneidet Seiteninhalt ab

Im Opera kann es vorkommen, dass dieser Inhalte abschneidet oder gar nicht anzeigt. Dies ist mir bei ausgeschalteter „an Breite anpassen“-Funktion aufgefallen.

Versuch man über folgendes CSS einem Element eine Größe zu geben ignoriert Opera dies, bzw. kann es nicht interpretieren.

.myElement {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}

Hierbei wird ein Element über den gesamten Bereich des darüberliegenden Elements gespannt. Ob das Element relative oder absolute positioniert is spielt dabei keine Rolle. Opera kann mit diesen angaben nicht umgehen. Abhilfe schafft hier folgendes:

.myElement {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  height: 100%; /* Opera Bugfix */
}

Durch angabe einer Höhe macht auch Opera was er soll.

Wie man ein Element über einen bestimmten Bereich aufzieht

Ich habe heute versucht einen div über einen bestimmten Bereich der Seite zu ziehen. Um’s genauer zu machen war es der Content Bereich einer Website. Dabei wolle ich, dass sich dieser über die Seite erstreckt. Möglich wird das, wenn man das Element absolute Positioniert:

#container {
  position: relative;
  margin: 3% auto 0;
  min-height: 100%;
}

#contentwrapper {
  width: 100%;
  position: absolute;
  top: 4.85em;
  bottom: 0;
}

Hier noch der relevante HTML Ausschnitt:

<div id="container">
<div id="header">
[...]
</div> <!-- header -->

<div id="contentwrapper">
 [...]
</div> <!-- contentwrapper -->
</div> <!-- container -->

Der umliegende div #container wird per min-width auf die gesammte Höhe gebracht und relativ Positioniert. Der Content-Div wird dann absolute von oben bis nach unten gezogen. Die 4.85em oberer Abstand liegen daran, dass bei mir über dem Content noch ein Header ist.

Linktext in einem Element zentrieren

Um den Linktext in einer horizontalen Navigation zentriert in den <li> anzuzeigen habe ich folgenden CSS Code genutzt:

#navigation li {
  float: left;
  width: 10.875em;
  background-position: -3.65em -11.7em;
  margin-left: -1.3em;
  position: relative;
	
  z-index: 1;
}

#navigation li a {
  /* Zentriert den Text */
  position: absolute; 
  left: 50%; 
  text-align:center; 
  width: 100%; 
  margin-left: -50%;
  /* vertikale Zentrierung */
  padding-top: 0.4em;
	
  color: #828282;
}

Browser beenden mit VB.NET

Um mit VB.NET zuverlässig Browserprozesse zu schließen habe ich folgenden Code verwendet:

SetOutput("Beende Prozess " & oApp.Id & " : " & oApp.StartInfo.FileName)

oApp.CloseMainWindow()

Thread.Sleep(1000)

While oApp.HasExited = False
  SetOutput(" warte auf Prozessende...")
  oApp.CloseMainWindow()
  Thread.Sleep(1000)
End While

SetOutput("Prozess erfolgreich beendet.")

Anklickbare SVGs im Opera 8.54

Will man ein SVG anklickbar machen klappt dies indem man einen Link darüber legt. Das ganze funktioniert in den gängigsten Browsern auch wunderbar. Opera 8.54 hat damit allerdings Probleme.

Wie ich aus dem Changelog von Opera 9 erfahren habe, ist es vorher nicht möglich gewesen ein positioniertes Element vor einen object Tag zu legen. Unter der Überschrift „Display“ erfährt man folgendes:

„Allowed positioned elements to appear in front of iframes and objects.“

Link zum Changelog

Solaris RDP auf Windows mit rdesktop

Hier ein Verbindungsstring der sowohl Ton als auch Hintergrundbild unterstützt:

rdesktop -u ‚username‘ -p ‚passwd‘ -d ‚domaine‘ -k de -f -a 16 -b -z -P -xan -r disk:USB=/home/’benutzername’/Documents/USB -r sound:local -r comport:COM3=$UTDEVROOT/dev/term/a ‚IP‘

Wichtig für Ton: -r sound:local
Wichtig für Wallpaper: -xan
Wichtig für USB: -r disk:USB=/home/’benutzername’/Documents/USB