Archiv für Mai, 2008

Media Center / Homecenter Solution

Heute bin ich aufgrund eines Artikels auf dem heise Newsticker über LinuxMCE gestolpert und bin von dem Demo-Video total begeistert; daher wollte ich kurz darüber schreiben. Der Gedanke eine MediaCenter Lösung zu Hause zu etablieren verfolgt mich schon eine Weile, aber wie so oft ist es oft die liebe Zeit, die eine nur schleppende Umsetzung erlaubt.

LinuxMCE scheint auf jeden Fall für eine volle Ausbaustufe der Kandidat der Wahl zu sein, auch wenn darauf hingewiesen wird, dass der Hardware-Support noch stark eingeschränkt ist.

Natürlich möchte ich euch das Demo-Video nicht vorenthalten:

Popularity: 41% [?]

Technorati Tags: , , ,

WordPress Userlevels in-depth

Vor kurzem hatte ich über das WP-Plugin WP-CodeBox berichtet. Dieses Plugin bietet dem Benutzer auch die Möglichkeit Einstellungen vorzunehmen, was ich mir auch ansehen wollte (vielleicht ist ja etwas interessantes dabei, was default-mäßig ausgeschaltet ist ;) ).

Leider meinte das Plugin daraufhin:

You are not a LEVEL 8 or above USER & hence you cannot configure WP-CodeBox. If you are a LEVEL 8 or above USER, then please Logout & Login again.

Achso, natürlich, muss ja admin sein. Moment mal, dachte ich mir, du bist doch als admin angemeldet ?! Zuerst wollte ich mir keinen Stress machen, da das Plugin ja funktionierte und so dramatisch waren die Einstellungsmöglichkeiten nun auch wieder nicht. Sicherheitshalber habe ich aber unter dem Tag wp-codebox im WP-Support noch eine Anfrage abgesetzt, wobei ich natürlich prompt das falsche Forum (Installation allgemein) erwischt habe. Die Moderatoren sind aber fit und der Beitrag wurde schnell in das entsprechende Forum verschoben. Das ist schon etwas irreführend gemacht, finde ich.

Nach 5 Tagen kam immer noch keine Antwort oder eine Reaktion, also dachte ich mir, dass ich dann eben diese Prüfung einfach ausbaue. Glücklicherweise war die Prüfung direkt am Anfang des Quelltexts, so dass ich nicht lange suchen musste. Ein kurzer Blick in die WP-Dokumentation förderte die Erkenntnis zu Tage wie der User-Level ermittelt wird. Ein Blick in die Datenbank-Beschreibung ergab, dass der User-Level in der Tabelle wp_usermeta hinterlegt wird, allerdings nicht für den Benutzer admin ??

Was ist denn dann der Default-Wert, zumal das CodeBox-Plugin hier gemeckert hat ? Daher erzeugte ich einen neuen Benutzer, der auch admin-Rechte hat und siehe da, der User-Level wurde in der Tabelle wp_usermeta hinterlegt. Mit diesem Benutzer funktionierte auch der Aufruf der CodeBox-Konfigurationsseite !

Daher hege ich jetzt einfach mal folgenden Verdacht: der Benutzer admin wird irgendwo hart-kodiert abgehandelt, allerdings wird der User-Level für diesen wohl nicht korrekt ermittelt. Doch eine kleine Trübung des bisher durchweg positiven Eindrucks von WordPress. Vielleicht wird das aber auch noch behoben oder ist bekannt. Da ich mich nicht weiter mit der Thematik befasst habe, kann es natürlich auch sein, dass es so sein soll wie es ist. Wer näheres weiß, darf sich gerne zu Wort melden ;)

Popularity: 28% [?]

Technorati Tags: ,

Quelltexte in Beiträgen

Ich habe mich vor einiger Zeit schon mit dem Problem herum geschlagen, dass ich Quelltexte nicht in ansprechender Form in meine Beiträge einfügen konnte. Entweder ging die Formatierung verloren oder es sah einfach nur unschön aus, da kein Highlighting in der Syntax war o.ä. Nun bin ich über ein äußerst nützliches Plugin diesbzgl. gestolpert, das sich WP-CodeBox nennt. In diesem Post habe ich es erstmals verwendet und bin mit dem Ergebnis eigentlich sehr zufrieden ;)

Das Plugin unterstützt verschiedene Sprachen (Stichwort GeSHi Support) und bietet auch die Möglichkeit den Quelltext mittels verschiedener Optionen zu formatieren (bspw. Zeilennummern einfügen).

Vielleicht ist das Plugin ja auch noch für andere WordPress Nutzer, die Beiträge mit Quelltext garnieren, interessant ;)

Popularity: 28% [?]

Technorati Tags: ,

.Net RowFilter Multi-Wildcard Filter Expressions

In .Net existiert an der Klasse System.Data.DataView ein Property namens RowFilter, das einen Ausdruck in SQL-Syntax erwartet, was wiederum ein Filtern der zugrunde liegenden Daten nach sich zieht. Der Aufbau und die Möglichkeiten des Filterausdrucks werden in in dem Property Expression der Klasse DataColumn beschrieben. Als Wildcards wird der “*” akzeptiert und ist zugelassen.

Man hat ja von einer freien Filtereingabe die Vorstellung, dass man beliebig Wildcards platzieren kann und der Ausdruck nahezu beliebig komplex werden darf. Doch weit gefehlt: “[...] Wildcards are not allowed in the middle of a string. For example, 'te*xt' is not allowed. [...]” (Quelle: MSDN, ZEICHENFOLGENOPERATOREN).

Was tut man also in einem solchen Fall ? Nun, wenn man sich den Ausdruck 'te*xt' ansieht, so kann man diesen zerlegen in 'te* AND *xt'. Daraus ergibt sich eine Ergebnismenge, die alle Daten beinhaltet, die mit “te” beginnen und mit “xt” enden.

Das bedeutet natürlich im Gegenzug, dass man die Erzeugung des Filterausdrucks komplett selbst machen muss. Dafür habe ich mir nun folgendes (und erprobtes) Klassengerüst ausgedacht. Es wird hierbei auf das Factory-Pattern zurückgegriffen (klicken zum Vergrößern):

Filter Klassendiagramm

Hierbei wird auch auf die verschiedenen Editoren und Datentypen Rücksicht genommen. Die Entscheidung, welche Klasse für die Erzeugung des Teilfilterausdrucks (der Ausdruck wird partiell pro Datenspalte erzeugt) genommen wird, erfolgt so:

?View Code CSHARP
this.typesHashtable = new Hashtable();
 
this.typesHashtable.Add(typeof(bool), typeof(BoolGridFilter));
 
this.typesHashtable.Add(typeof(byte), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(short), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(int), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(long), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(float), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(double), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(decimal), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(UInt16), typeof(NumericGridFilter));
this.typesHashtable.Add(typeof(UInt64), typeof(NumericGridFilter));
 
this.typesHashtable.Add(typeof(DateTime), typeof(DateTimeGridFilter));
 
this.defaultGridFilterType = typeof(TextGridFilter);

Später wird dann mittels Reflection entschieden, welche Klasse genommen werden soll. Dies geschieht über den der DataColumn zugrunde liegenden DataType:

?View Code CSHARP
Type dataType = dc.DataType;
if (dataType != null)
{
  if (this.typesHashtable.ContainsKey(dataType))
  {
    Type gridFilterType = this.typesHashtable[dataType] as Type;
    dcFilter = gridFilterType.Assembly.CreateInstance(gridFilterType.FullName, false,
                       BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance,
                       null, new object[] { dc.DataField, PrepareFilterExpression(dc.FilterText) }, null, new object[] { }) as IDataColumnFilter;
  }
  else
  {
     dcFilter = this.defaultGridFilterType.Assembly.CreateInstance(this.defaultGridFilterType.FullName, false,
                       BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance,
                       null, new object[] { dc.DataField, PrepareFilterExpression(dc.FilterText) }, null, new object[] { }) as IDataColumnFilter;
  }
}

Die hier beschriebenen Code-Fragmente wurden in Verbindung mit dem TrueDBGrid von ComponentOne implementiert, die Architektur ist aber recht lose über Interfaces handhabbar, so dass man die Technik ganz leicht zur Zusammenarbeit mit anderen DataGrids überreden können sollte. Den kompletten Quelltext werde ich hier nicht veröffentlichen, ich hoffe aber, dass dieser Beitrag als Ideengeber dienen kann ;)

Popularity: 45% [?]

Technorati Tags: , ,

Compact Framework Design Time Attribute

Wenn man unter dem .Net Framework entwickelt, kann man Properties in visuellen Klassen (UserControls, Forms, Controls, …) mit Attributen versehen, so dass diese gewisse Eigenschaften haben. Zum Beispiel ist es so möglich ein Property “AlternateText” in ein eigenes Control einzufügen. Dieses Property ist im Designer auch sichtbar, nachdem man es auf die gerade zu designende Oberfläche per Drag & Drop gezogen hat. Standardmäßig taucht dieses Property in der Kategorie “Misc” auf. Man kann nun beeinflussen, dass das Property im Properties-Browser im Designer nicht sichtbar ist ([Browsable(false)]), man kann einen Default-Wert festlegen ([DefaulValue("Not set")]) oder auch eine eigene Kategorie definieren ([Category("Advins - Control Visual Properties")]).

Leider hat man genau diese Annehmlichkeiten nicht im Compact Framework zur Verfügung. Man kann sich aber behelfen, indem man eine XMTA Datei dem Projekt hinzufügt und darin diese Eigenschaften in XML-Form festlegt. Eine solche XML-Datei (DesignTimeAttributes.xmta) kann wie folgt aussehen:

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
 <Class Name="AdvControls.ImageButton">
  <Property Name="ButtonText">
   <Browsable>true</Browsable>
   <Category>AdvControls - Properties</Category>
   <Description>Set the text to be displayed in the button here.</Description>
  </Property>
  <Property Name="Image">
   <Browsable>true</Browsable>
   <Category>AdvControls - Properties</Category>
   <Description>Set the image to be displayed in the button here.</Description>
  </Property>
 </Class>
</Classes>

Der Compiler erkennt die Datei und erzeugt daraus eine AdvControls.WindowsCE.asmmeta.dll. So kann man seine Control-Properties doch wie gewohnt (leider nur etwas umständlicher) mit Attributen versehen.

Entwickelt man Code sowohl für den Desktop als auch ein Mobile Device kann man seine Attribute mittels

#if Desktop

#endif

über das Property schreiben ohne Compile-Fehler zu bekommen.

Popularity: 46% [?]

Technorati Tags: , , ,

Wiedergabe von Sounds mit dem Compact Framework

Vor einiger Zeit schon stieß ich auf das Problem unter Windows Mobile Sounds wiedergeben zu wollen. Nahezu ohne Weiteres unterstützt wird das Abspielen von WAV-Sounds, aber wie sieht es mit MP3 und/oder WMA aus ? Nun dazu später mehr, hier erst einmal die Lösung von Microsoft, wie man WAV-Sounds unter Windows Mobile abspielen kann:

public class Sound {
private byte[] m_soundBytes;
private string m_fileName;
private enum Flags
{
SND_SYNC = 0×0000, /* play synchronously (default) */
SND_ASYNC = 0×0001, /* play asynchronously */
SND_NODEFAULT = 0×0002, /* silence (!default) if sound not found */
SND_MEMORY = 0×0004, /* pszSound points to a memory file */
SND_LOOP = 0×0008, /* loop the sound until next sndPlaySound */
SND_NOSTOP = 0×0010, /* don’t stop any currently playing sound */
SND_NOWAIT = 0×00002000, /* don’t wait if the driver is busy */SND_ALIAS = 0×00010000, /* name is a registry alias */
SND_ALIAS_ID = 0×00110000, /* alias is a predefined ID */
SND_FILENAME = 0×00020000, /* name is file name */
SND_RESOURCE = 0×00040004 /* name is resource name or atom */
}

[DllImport("CoreDll.DLL", EntryPoint="PlaySound", SetLastError=true)]
private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);
[DllImport("CoreDll.DLL", EntryPoint="PlaySound", SetLastError=true)]
private extern static int WCE_PlaySoundBytes (byte[] szSound, IntPtr hMod, int flags);

/// <summary>
/// Construct the Sound object to play sound data from the specified file.
/// </summary>
public Sound (string fileName)
{
m_fileName = fileName;
}

/// <summary>
/// Construct the Sound object to play sound data from the specified stream.
/// </summary>
public Sound(Stream stream)
{
// read the data from the stream
m_soundBytes = new byte [stream.Length];
stream.Read(m_soundBytes, 0,(int)stream.Length);
}

/// <summary>
/// Play the sound
/// </summary>
public void Play ()
{
// if a file name has been registered, call WCE_PlaySound,
// otherwise call WCE_PlaySoundBytes
if (m_fileName != null)
WCE_PlaySound(m_fileName, IntPtr.Zero, (int) (Flags.SND_ASYNC | Flags.SND_FILENAME));
else
WCE_PlaySoundBytes (m_soundBytes, IntPtr.Zero, (int) (Flags.SND_ASYNC | Flags.SND_MEMORY));
}
}

Wie bewerkstelligt man es aber nun, MP3 und WMA-Sounds abzuspielen ? Hierzu fand ich folgende Lösung im Netz:

  • Hinzufügen einer Referenz auf C:\Windows\System32\wmp.dll (man benutzt also den Windows Media Player)
  • Folgenden Code zum Abspielen verwenden:

    WMPLib.WindowsMediaPlayer player = new WMPLib.WindowsMediaPlayer();
    player.URL = “\\Amazing.mp3″;
    player.settings.volume = 100;
    player.controls.next();
    player.controls.play();

Ich greife dieses Thema hier auf, weil mich jüngst Martin per Mail nach einer Lösung fragte und dies vielleicht auch noch für andere interessant sein könnte.

Popularity: 45% [?]

Technorati Tags: , , ,

Erholsame Tage… ?

Nach den paar Tagen und dem mitgenommenen Brückentag melde ich mich wieder zurück. Leider konnte ich nicht so viel in der letzten Woche schreiben, versuche das aber diese Woche nachzuholen.

Erholsame Tage waren es leider nicht voll und ganz, denn wie es nun einmal so ist, haben Leute die Neigung viele viele Termine in solche “Freiräume” zu packen. Dazu kam noch, dass meine Mutter Geburtstag hatte. Aber genug der Worte, hier mal der Zeitplan der letzten Tage:

  • Freizeit / Ausspannen: Zoo in Kaiserslautern besucht (s. Bilder am Ende des Beitrags)
  • Einem Freund beim Streichen helfen, meine Mutter besucht und Geschenk überreicht
  • Diesem Freund dann beim Umziehen und Aufbauen helfen, abends bei meiner Mutter zum Grillen gewesen, optional hatte meine Großcousine noch Polterabend, aber das war nicht mehr zu schaffen
  • Training, ausspannen und auf ein Fest in der Innenstadt gegangen

Der Zeitplan war also voll gepackt – ich denke ihr versteht, wieso ich nicht zum Schreiben gekommen bin :)

Hier noch ein paar Bilder aus dem Zoo:

Popularity: 40% [?]

Technorati Tags: , ,