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.

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 = 0x0000, /* play synchronously (default) */
SND_ASYNC = 0x0001, /* play asynchronously */
SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */
SND_MEMORY = 0x0004, /* pszSound points to a memory file */
SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */
SND_NOSTOP = 0x0010, /* don’t stop any currently playing sound */
SND_NOWAIT = 0x00002000, /* don’t wait if the driver is busy */SND_ALIAS = 0x00010000, /* name is a registry alias */
SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
SND_FILENAME = 0x00020000, /* name is file name */
SND_RESOURCE = 0x00040004 /* 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.

.Net Compact Framework: ImageButton ??

Nach langer Funkstille zum Thema Anwendungsentwicklung für Windows Mobile mit dem .Net Compact Framework (CF), möchte ich heute nochmals einen Zwischenbericht abgeben.

Mein Fazit bisher: das CF ist wirklich auf das Nötigste reduziert, fast schon um zu viele Dinge reduziert, wenn man von dem vollen Umfang des normalen Frameworks verwöhnt ist. Weniger Umfang hat wohl nur noch das .Net Micro Framework… Erste Erfahrungen durfte ich ja bereits mit dem OpenFileDialog sammeln, nun habe ich weitere Lücken gefunden, die ich gerade am Schließen bin. So ist es bspw. bei einem Button im CF nicht möglich ein Bild neben einem Label zu platzieren; das normale Framework bietet hier ein Image Property am Button an. Was also tun ? Richtig, neben der Entwicklung der Dialoge zur Erledigung einfachster Ordner- bzw. Dateiauswahloperationen habe ich begonnen eine eigene Controls-Library zu bauen. Diese beinhaltet bisher zwar nur eine Klasse „ImageButton“ (s. Bild), aber das kann ja noch wachsen.

ImageButton

ImageButton

Bzgl. der SimpleFileRequesterDialogs ist der Stand der, dass der Ordnerauswahldialog (DirectoryChooserDialog) funktioniert (s. Bild) und ich nun an dem OpenFileDialog arbeite. Aus dieser Arbeit heraus entstand auch die Notwendigkeit die eigene Controls-Library zu schreiben.

Verzeichnisauswahldialog

Verzeichnisauswahldialog

Alles in allem komme ich aus Zeitgründen nur langsam voran, aber es geht stetig weiter 😉

OpenFileDialog im .Net Compact Framework

Am Wochenende bin ich über eine Sache gestolpert, wo ich nicht so recht glauben wollte, dass das wahr sein könnte. Ich habe ja mehrfach berichtet, dass ich mich derzeit daran versuche eine Windows Mobile Applikation zu entwerfen. Mit genau diesem Thema habe ich mich auch am Wochenende befasst, als ich aber an die Stelle kam, an der es darum ging Sounds abzuspielen, bin ich über eine – meines Erachtens nach – Basisfunktionalität gestolpert: System.Windows.Forms.OpenFileDialog.

Angefangen hat die Geschichte mit der Implementierung der Sound-Funktionalität, wobei ich mich hierbei des Windows Media Players (wmp.dll) bediente und diese in den Code einband. Die Klasse für den Sound war an sich schnell umgesetzt – nur wie testen ? Also habe ich auf dem Einstellungen-Tabreiter einen „Sound auswählen“ Button hinzugefügt und wollte dann einen einfachen Dateiauswahl-Dialog öffnen. .Net bietet wie gesagt hier die Klasse OpenFileDialog an. Diese habe ich dann auch genutzt und die Anwendung im Debug gestartet. Im Emulator kam dann die Anwendung nach vorne und ich drückte auf den Button und was erschien ? Dieses „Ding“:

.Net CompactFramework OpenFileDialog

In der Combobox „Folder“ tauchen bspw. völlig unnütze Einträge auf, kurz gesagt ich war nicht in der Lage intuitiv und wie gewohnt durch die Ordnerstruktur zu navigieren und eine einfache Datei auszuwählen. Zuerst dachte ich, ich würde etwas falsch machen und habe mich dann im Internet auf die Suche nach einer Lösung begeben. Das erste worauf ich stieß waren Drittanbieter-Komponenten, die sie sich äußerst fürstlich entlohnen ließen. Langsam stieg in mir ein leiser Verdacht auf: sollte ich hier etwa auf die erste der von einem Kollegen viel beschworenen Lücken im Compact Framework gestoßen sein ??? In der Tat sah es nach einer weiteren viertel Stunde Suche äußerst düster aus. Entweder fand ich nur besagte Dritthersteller-Controls oder Dialoge mit Quelltext, die aber nicht sonderlich ansprechend oder funktional waren. Jeder kocht hier sein eigenes Süppchen und programmiert diese Funktionalität selbst aus. Das ist das Fazit meiner Recherche 🙁

Daher muss ich nun meinem Projekt „PhoneEventNotifier“ noch eine anderes Projekt vorschalten: „SimpleFileRequesterDialogs“, d.h. ich werde mich nun zuerst hinsetzen und folgende Dinge nachbauen:

  • Verzeichnisauswahldialog
  • Dateiauswahldialog (Öffnen, Speichern, Mehrfach-Selektion, …)

Dies werde ich als DLL erstellen und separat bereitstellen. Im Prinzip sind alle Funktionalitäten im Compact Framework vorhanden, es fehlt nur die Vereinigung dieser in Form eines Dialogs, der sich „wie gewohnt“ bedienen lässt. Danach geht dann die Arbeit am „PhoneEventNotifier“ weiter.

Sachdienliche Hinweise können in Form von Kommentaren hinterlassen werden 😉

Windows Mobile – PhoneEventNotifier Status

Die Entwicklung des PhoneEventNotifier schreitet voran 🙂 Folgende Fähigkeiten hat das Programm bis dato:

  • Registrierung am System Event PhoneMissedCall (und somit automatischer Start der Anwendung bei Auftreten des Events)
  • Anzeige der Rufnummer des zuletzt verpassten Anrufs

Als nächstes ist geplant:

  • dem Einstellungs-Tab Leben einzuhauchen
  • Auswahl und Abspielen von Sounds

Es wird also so langsam und es macht wirklich Spaß 😉

Hier noch die vorangegangen Artikel zu diesem Thema:

Entwickeln für Windows Mobile – Fortschrittsbericht

Nach einer kleineren Pause möchte ich heute kurz ein Update zum Stand der Entwicklung einer Windows Mobile Applikation geben. Nach längerem Zaudern habe ich mich dazu entschlossen die Applikation für Windows Mobile 5 und höher auszulegen, da dass Windows Mobile 5 SDk bereits anständige Benachrichtigungs-Mechanismen mitbringt. Diese lassen sich ganz einfach mittels der im WM 5 SDK enthaltenen Managed DLLs einbinden. Benötigt werden die Namespaces Microsoft.WindowsMobile sowie Microsoft.WindowsMobile.Status. Damit kann man dann schon eine ganze Menge machen, u.a. kann man sich so auf einen verpassten Anruf-Event registrieren (PhoneMissedCall).

Die Oberfläche ist soweit entworfen, die Registrierung der Events ist auch funktionsfähig. Erste Tests sind auch bereits erfolgreich verlaufen, so zeigte das Programm in seiner Logausgabe an: „verpasster Anruf: +49xxxxxxxxxxx“ (die Zahlen wurden bewusst durch x ersetzt). Hier noch zwei Screenshots der Anwendung im Emulator:

Ansonsten gab es doch einige Anlaufschwierigkeiten, so muss man leider sagen, dass man ab einem gewissen Grad nicht um Microsofts Visual Studio herumkommt, da hier die Integration von Deployment und Device Emulator einfach runder wirkt als mit SharpDevelop o.ä. Oder etwas anders formuliert: Microsoft hat seine SDK Installer Files derart mit Voraussetzungen gepflastert (Visual Studio, ActiveSync, …), dass man wohl erst die Chance hat die Installation durchzuführen, wenn man den Orca MSI Editor von Microsoft zum patchen dieser Installer Dateien nutzt. So wollte ich zum Beispiel auf meiner virtuellen Maschine nicht unbedingt ActiveSync installieren (man müllt ja nicht sein Produktiv-System zu 😉 ), also wurde ein Patch der „Windows Mobile 5.0 Pocket PC SDK.msi“ Installer Datei fällig, dass es ActiveSync nicht zwingend erfordert etc. Irgendwann hatte ich dann aber keine Lust mehr die Steine aus dem Weg zu räumen, die Microsoft bereit legt…

Dies nun nur als kleiner Appetit-Anreger und als Zeichen dafür, dass es voran geht. Sobald die erste lauffähige Version fertig wird, werde ich diese hier veröffentlichen.