MSDN Magazin > Home > Ausgaben > 2006 > December >  Grafiken für unterwegs: Erstellen einer mo...
Grafiken für unterwegs
Erstellen einer mobilen Bildbearbeitungsanwendung mit .NET Compact Framework 2.0
Rob Pierry

Themen in diesem Artikel:
  • Verwalteter Code für mobile Anwendungen
  • Testen mit Geräteemulatoren
  • Grafiken mit .NET Compact Framework
  • Interaktion mit Pocket Outlook
In diesem Artikel werden folgende Technologien verwendet:
.NET Compact Framework 2.0, Windows Mobile 5.0, Visual Studio 2005
Laden Sie den Code für diesen Artikel herunter: PocketPC2006_12.exe (157 KB)
Code online durchsuchen
Mit der Einführung von .NET Compact Framework hat Microsoft alle Vorteile der Entwicklung von verwaltetem Code für mobile Anwendungen verfügbar gemacht. Entwickler, die bereits mit dem Schreiben von Windows® Forms-Anwendungen vertraut sind, dürften auch beim Programmieren für mobile Geräte schnell Forschritte machen. Version 2.0 von Microsoft® .NET Compact Framework ist nun verfügbar. Durch die damit eingeführten neuen Tools (wie dem Geräteemulator-Manager) und einer Ausdehnung des Abdeckungsbereichs ist das Entwickeln nun noch einfacher. In Version 2.0 wurden insbesondere weitere Klassen und Methoden für das Arbeiten mit Grafiken hinzugefügt, unter anderem abgewinkelter Text, benutzerdefinierte Stifte, Bildbearbeitung sowie Interaktion mit der integrierten Gerätekamera. In diesem Artikel werden diese und andere Verbesserungen erläutert, die mit Visual Studio® 2005 und .NET Compact Framework Version 2.0 verfügbar sind.
Wenn Sie .NET Compact Framework zum Entwickeln für Windows Mobile® 5.0 verwenden, gibt es zwei Hauptgerätetypen, die Sie berücksichtigen können: Smartphones und Pocket PCs. Auch wenn zum Entwickeln auf diesen Plattformen die gleichen Tools zur Verfügung stehen, wurde das Entwicklungsverhalten für die jeweilige Geräteklasse angepasst. Pocket PCs sind in der Regel größere PDA-Geräte, die unter Umständen zusätzlich eine Telefonfunktion enthalten. Smartphones dagegen sind kleinere Geräte, die hauptsächlich als Telefon dienen und nebenbei als PDA genutzt werden können. Im Allgemeinen sind Pocket PCs leistungsfähiger, bieten Touchscreens, eine höhere Bildschirmauflösung, mehr Speicher und schnellere Prozessoren. Dieser Artikel richtet sich hauptsächlich an Entwickler für Pocket PCs. Sobald Sie jedoch das Entwickeln für Pocket PCs beherrschen, dürfte das Entwickeln für Smartphones kein Problem mehr sein.
Bevor Sie beginnen, müssen Sie das Windows Mobile 5.0 SDK für Pocket PC installieren. Das SDK enthält Emulatoren für Pocket PC-Geräte, Dokumentationsmaterial und Beispiele. Nach der Installation können Sie sofort beginnen.
In diesem Artikel werden Sie durch die Entwicklung einer einfachen Bildverarbeitungsanwendung geführt, mit dem Text- und Linienobjekte auf einem Hintergrundbild gezeichnet werden können. Als Hintergrundbild kann entweder ein vorhandenes Bild verwendet werden, oder Sie können mit der im Gerät integrierten Kamera ein Bild aufnehmen. Für beide Aufgaben (Öffnen und Aufnehmen von Bildern) werden Standarddialogfelder verwendet, die in Version 2.0 von Compact Framework neu sind. Sie lernen, wie Sie die neuen unterstützten Funktionen für benutzerdefinierte Stifte und abgewinkelten Text zum Zeichnen auf dem Hintergrund verwenden können. Sie können Ihre Bilder sogar in der Anwendung speichern, nachdem Sie darauf gezeichnet haben. Nebenbei erfahren Sie, wie Sie E-Mail-Unterstützung zum Senden von Bildern an einen Pocket Outlook®-Kontakt hinzufügen können.

Arbeiten mit Bildern
Als Basisfunktion muss die Anwendung in der Lage sein, das Hintergrundbild und die Vordergrundebene aus Text und Linien zu speichern und diese Elemente zu einem einzigen Bild zusammenzufügen (siehe Abb. 1). Intern bleiben die Bilder separate Elemente, bis die Anwendung das endgültige Bild speichert. Damit werden die grundlegenden Bearbeitungsmöglichkeiten gewährleistet: der Hintergrund kann ersetzt werden, wobei der Vordergrund beibehalten wird, oder der Vordergrund wird entfernt und der Hintergrund bleibt erhalten.
Abbildung 1 Separate Hintergrund- und Vordergrundebenen 
Beim Laden des Hauptformulars werden zwei Instanzen der Bitmap-Klasse erstellt: eine für den Hintergrund (standardmäßig hellgrau) und eine für den Vordergrund (standardmäßig transparent). Das Formular zeichnet zuerst den Hintergrund und dann den Vordergrund.
Zur Unterstützung der Transparenz verwendet die Anwendung die Klasse „ImageAttributes“. Im Allgemeinen kann diese Klasse verwendet werden, um einen Farbbereich als transparent festzulegen oder um Farben durch andere Farben zu ersetzen. Auch die Bearbeitung von Bitmaps, Pinseln und Stiften ist möglich. In Compact Framework werden nur die Transparenzeinstellungen unterstützt. Die Anwendung stellt die Transparenz zunächst in einer bestimmten Farbe dar und verhindert anschließend mithilfe der Klasse „ImageAttributes“, dass diese Farbe beim Zeichnen des im Formular verwendet wird. In diesem Beispiel verwenden Sie die Farbe „Color.AliceBlue“ für Transparenz und legen dann fest, dass der Benutzer diese Farbe nicht zum Zeichnen von Text und Linien verwenden kann. Die Anwendung muss nur die Methode „SetColorKey“ für eine Instanz von „ImageAttributes“ aufrufen und „Color.AliceBlue“ für beide Parameter angeben, da genau eine Farbe transparent sein soll. Der Code zum Zeichnen des Vordergrunds auf den Hintergrund sieht wie folgt aus:
private void DrawOverlay(Graphics g, Rectangle region)
{
    using(ImageAttributes attribs = new ImageAttributes())
    {
        attribs.SetColorKey(_transparentColor, _transparentColor);
        g.DrawImage(_overlay, region, region.X, region.Y,
            region.Width, region.Height, GraphicsUnit.Pixel, attribs);
    }
}
Der Einfachheit halber beschränkt die Anwendung die Bildgröße auf den sichtbaren Bereich des Gerätebildschirms, der über die Eigenschaft „ClientRectangle“ angegeben wird. Beachten Sie, dass dieser Wert nicht unbedingt konstant ist. Auf Geräten mit herausziehbarer Tastatur hängt der Wert der Eigenschaft „ClientRectangle“ unter Umständen davon ab, ob die Tastatur offen (320×188) oder geschlossen ist (240×268). Um dies zu umgehen, nimmt die Anwendung als Standardwert für die Bilder die Client-Bildgröße, die beim Starten der Anwendung gilt. Deshalb ist es wichtig, Ihre Windows Mobile-Anwendung auf der eigentlichen Hardware zu testen, da der Emulator nicht alle Hardwarekonfigurationen abdecken kann.
Auch wenn der hellgraue Hintergrund recht angenehm ist, wäre es wünschenswert, dass die Benutzer eigene Bilder als Hintergrund auswählen können. In der Anwendung wird dafür die Klasse „SelectPictureDialog“ verwendet. In Abbildung 2 sehen Sie die Benutzeroberfläche von „SelectPictureDialog“. Diese Klasse ist in der Microsoft.WindowsMobile.Forms-Assembly verfügbar. Sie müssen darauf verweisen, wenn Sie dieses Dialogfeld verwenden möchten. Mit den Eigenschaften der Klasse können Sie den Dialogtitel angeben (Title), steuern, ob der Benutzer mit der integrierten Kamera ein neues Bild aufnehmen kann (CameraAccess), die angezeigten Bilder nach Dateityp filtern (Filter), festlegen, ob die Bilder durch die Verwaltung digitaler Rechte (DRM) geschützt sind (ShowDrmContent und ShowForwardLockedContent), bestimmen, welcher Ordner anfangs angezeigt wird (InitialDirectory) und festlegen, dass der Benutzer den Ordner nicht wechseln kann (LockDirectory). Nachdem Sie dieses Dialogfeld geschlossen haben, können Sie die Eigenschaft „FileName“ aktivieren, um den Dateinamen des vom Benutzer ausgewählten Bilds abzurufen.
Abbildung 2 Bildauswahl 
Nachdem der Benutzer ein Bild ausgewählt hat, ersetzt die Anwendung den aktuellen Hintergrund durch das ausgewählte Bild, das an die Größe des Bildschirms angepasst wurde. Nach dem Aufrufen des Objekts „Graphics“ für das Hintergrundbild wird die Methode „DrawImage“ verwendet, um das neu ausgewählte Bild auf den Hintergrund zu zeichnen. Der zweite Parameter stellt das Zielrechteck dar, in dem Sie zeichnen können (in diesem Fall auf dem gesamten Hintergrund). Der dritte Parameter ist das Rechteck des Quellbilds (also das gesamte Quellbild), das in das Zielrechteck eingefügt wird. Diese Methode ist sehr flexibel. Auf diese Weise werden kleinere Bilder gestreckt und größere Bilder entsprechend der Hintergrundgröße verkleinert. Sie können jedoch auch einen Ausschnitt in der Größe des Hintergrundbilds aus dem neuen Bild ausschneiden, indem Sie in beiden Parametern das Hintergrundrechteck angeben.
Nachdem die Anwendung nun in der Lage ist, den Hintergrund und den Vordergrund zu erstellen und zu zeichnen, ist das Speichern recht einfach. Statt im Formular zu zeichnen, verwenden Sie „SaveFileDialog“, um den Benutzer zur Eingabe eines neuen Dateinamens aufzufordern. Damit wird eine Kopie des Hintergrunds erstellt und anschließend der Vordergrund darüber gezeichnet. Nachdem Sie das endgültige Bild haben, verwenden Sie die Methode „Save“ (neu in Version 2.0 von Compact Framework), um das Bild im JPEG-Format auf der Festplatte zu speichern. (BMP, GIF und PNG werden ebenfalls unterstützt.) Der Code zum Erstellen und Speichern des Bilds lautet wie folgt:
using (Bitmap newImage = new Bitmap(_background))
{
    using (Graphics g = Graphics.FromImage(newImage))
    {
        DrawOverlay(g, new Rectangle(
            0, 0, _overlay.Width, _overlay.Height));
    }
    newImage.Save(dlgSave.FileName, ImageFormat.Jpeg);
}

Zeichnen von Formen und Text
Nun kann der Benutzer den Hintergrund anpassen, indem er ein Bild auswählt, er soll aber auch noch den Vordergrund zeichnen können. Zum Zeichnen von Formen wird das Objekt „Graphics“ verwendet. Dies bietet Methoden wie „DrawEllipse“, „DrawLine“ und „DrawRectangle“, die alle einen Stift (Pen) als Parameter aufweisen. Der Stift bestimmt Farbe und Stärke beim Zeichnen der Form. Früher konnten nur Stifte in einer bestimmten Farbe erstellt werden, aber mit Compact Framework Version 2.0 wurde die Eigenschaft „Width“ und ein weiterer Konstruktor eingeführt, wodurch Sie die Stärke und die zu verwendende Farbe festlegen können.
In der Anwendung implementiert „SelectPen.cs“ ein Formular, in dem der Benutzer eine Farbe und die Linienstärke zum Zeichnen von Formen auswählen kann. Die verfügbaren Farben werden in einem Kombinationsfeld aufgelistet, die Stärke wird über ein NumericUpDown-Steuerelement angegeben. Nachdem der Benutzer seine Auswahl getroffen hat, wird im Hauptformular der aktuelle Stift auf die neue Instanz der Klasse „Pen“ mit der ausgewählten Farbe und Linienstärke festgelegt. In allen folgenden Zeichnungen wird dieser Stift verwendet. Stellen Sie in diesem Formular sicher, dass die Farbe, die als Transparenz für die Vordergrundebene dient (AliceBlue), nicht im Kombinationsfeld aufgelistet ist. Andernfalls kann es passieren, dass der Benutzer versehentlich unsichtbare Formen zeichnet.
Die Option zum Zeichnen der Linie im Linienmenü zeigt, wie der aktuelle Stift verwendet werden kann, um eine Linie auf dem Bild zu zeichnen. Zuerst wählt der Benutzer die beiden Endpunkte der Linie aus. Anschließend erhält die Anwendung ein Graphics-Objekt zum Zeichnen des Vordergrunds und verwendet die Methode „DrawLine“ mit dem aktuellen Stift, um die beiden Punkte mit einer Linie zu verbinden.
Als letzter Schritt wird „Invalidate“ mit dem gesamten ClientRectangle-Parameter aufgerufen. Daraufhin wird das Formular mit dem Hintergrund und dem aktualisierten Vordergrund erneut gezeichnet. Genau genommen ist der einzige Teil des Formulars, der aktualisiert werden muss, das Rechteck, das die soeben gezeichnete Linie enthält. Deshalb können Sie zur Optimierung „Invalidate“ nur auf dieses Rechteck statt auf den gesamten Clientbereich anwenden.
Das Graphics-Objekt enthält auch die Methode „DrawString“. Mit dieser Methode wird eine Zeichenfolge in der angegebenen Schriftart und Farbe an der festgelegten Position gezeichnet. Da Version 2.0 von Compact Framework abgewinkelten Text unterstützt, können Sie den Benutzer zwei Punkte zur Definition einer Linie auswählen lassen, entlang derer der Text gezeichnet wird, und anschließend ein Dialogfeld anzeigen lassen, in dem der Benutzer den Text eingeben und die Größe auswählen kann.
Abgewinkelter Text wird über die Klasse „LogFont“ unterstützt. Dieser Name steht für „logische Schriftart“, eine Struktur, die intern von Windows CE verwendet wird, dem zugrunde liegenden Betriebssystem, auf dem Windows Mobile 5.0 basiert. Um den Textwinkel anzupassen, legen Sie für die Eigenschaft „Escapement“ einer LogFont-Instanz einen Winkel in Gradangaben fest, multipliziert mit 10. Um beispielsweise einen Text anzugeben, der vertikal von unten nach oben verläuft, setzen Sie „Escapement“ auf 900 (90 Grad von der positiven X-Achse).
Der Code zum Erstellen einer Schriftart über „LogFont“ wird in der Methode „GetFont“ des Dialogfelds zur Texteingabe, TextDialog.cs, angegeben. Am Anfang befindet sich ein kleiner Trigonometrie-Abschnitt, mit dem der Winkel für den Text anhand der beiden Punkte abgeleitet wird. Die Y-Achse des Geräts ist invertiert, 0 befindet sich oben am Bildschirm statt unten. Wenn Sie dies und den Bereich der Funktion „arctan“ beachten, erhalten Sie den richtigen Winkel für die Eigenschaft „Escapement“.
Bei der Verwendung von „LogFont“ müssen Sie stets die Eigenschaft „Orientation“ (Ausrichtung) auf den gleichen Wert wie „Escapement“ setzen. Für die Höhe von „LogFont“ verwenden Sie die Größe, die vom Benutzer angegeben wurde, und passen sie an die Geräte-DPI an. (Sie können den DPI-Wert anhand der neuen Eigenschaften „DpiX“ und „DpiY“ des Graphics-Objekts bestimmen.) Wenn Sie eine negative Zahl angeben, wählt Framework die Schriftart mit der Punktgröße aus, die am ehesten dem absoluten Wert der Eigenschaft entspricht. Es gibt noch weitere Optionen, die in der Dokumentation zu MSDN® erläutert werden. Abbildung 3 enthält den Code zum Aufrufen einer Schriftart (Font) über „LogFont“.
public Font GetFont(Point p1, Point p2, float dpi)
{
    int y = -(p2.Y - p1.Y); //adjust for inverted y axis
    int x = p2.X - p1.X;
    int angle = (int)(Math.Atan2(y, x) * 180 / Math.PI);
        
    //adjust for quadrant
    if (y < 0) angle = 360 + angle;

    LogFont lf = new LogFont();
    lf.Height = (int)(-EnteredSize * dpi / 96);
    lf.Escapement = angle * 10;
    lf.Orientation = lf.Escapement;
    lf.FaceName = Font.Name;

    return Font.FromLogFont(lf);
}

Nachdem „LogFont“ entsprechend eingerichtet wurde, können Sie durch Aufrufen der statischen Methode „FromLogFont“ der Font-Klasse eine Font-Instanz erstellen. Nachdem Sie nun eine Schriftart in geeigneter Größe, den Text und einen Punkt haben, können Sie das Bild mit der Methode „DrawString“ ausgeben.

Geräteemulator-Manager
Falls Sie bereits mit Visual Studio für mobile Geräte entwickelt haben, kennen Sie den Geräteemulator wahrscheinlich schon. Der Emulator verhält sich wie ein Pocket PC, auf dem Sie Ihre Programme wie auf einem echten mobilen Gerät ausführen können. Der Emulator kann für verschiedene Bildschirmgrößen, Speicherkapazitäten und verfügbare Anschlüsse konfiguriert werden. Er kann sogar eine Telefonfunktion simulieren.
In Visual Studio 2005 werden Emulatoren über den Geräteemulator-Manager bedient, den Sie im Menü „Extras“ aufrufen können. Der Geräteemulator-Manager listet beim Starten alle verfügbaren Emulatoren nach Zielbetriebssystem angeordnet auf. Für Windows Mobile 5.0 Pocket PC SDK gibt es mehrere Auswahlmöglichkeiten, darunter der Basisemulator, einer mit Telefonfunktion und einer mit VGA-Bildschirmauflösung (640×480).
Klicken Sie mit der rechten Maustaste auf einen Emulator, und wählen Sie „Verbinden“, um ihn zu starten. Der Geräteemulator-Manager zeigt daraufhin einen grünen Pfeil neben dem Emulator an. In Abbildung 4 sehen Sie den Geräteemulator-Manager mit einem ausgeführten Emulator.
Abbildung 4 Geräteemulator-Manager mit ausgeführtem Emulator (Klicken Sie zum Vergrößern auf das Bild)
Durch ein neues Feature in Visual Studio 2005 und ActiveSync® 4.0 können Sie zwischen dem Desktopcomputer und dem Emulator eine Partnerschaft erstellen, bei der der Emulator wie ein echtes Gerät behandelt wird. Öffnen Sie dazu ActiveSync, und wählen Sie „Datei | Verbindungseinstellungen“. Stellen Sie sicher, dass die Option für zulässige Verbindungen aktiviert ist, und wählen Sie in der Dropdownliste „DMA“ (der Emulator kommuniziert mit ActiveSync über DMA). Klicken Sie auf „OK“. Klicken Sie nun im Geräteemulator-Manager mit der rechten Maustaste auf den ausgeführten Emulator (mit grünem Pfeil gekennzeichnet), und wählen Sie die Option für die Basisstation. ActiveSync wird aktiviert und fordert Sie auf, eine Partnerschaft mit dem neuen Gerät herzustellen. Der Geräteemulator-Manager ändert den grünen Pfeil in ein neutrales Symbol, um anzugeben, dass sich das Gerät an der Basisstation befindet. Um den Emulator von ActiveSync zu trennen, klicken Sie einfach im Geräteemulator-Manager mit der rechten Maustaste auf den Emulator und wählen „Aus Basisstation“.
Auch wenn Emulatoren in Visual Studio 2005 durch den Geräteemulator-Manager leistungsfähiger geworden sind, haben sie doch ihre Grenzen. Wie bereits erwähnt, kann der Emulator derzeit keine Geräte mit ausziehbaren Tastaturen simulieren. Eine weitere kritische Grenze wird beim Hinzufügen von Hintergründen, die über die Gerätekamera aufgenommen wurden, erreicht. Gegenwärtig unterstützt der Emulator keine Kamerafunktion. Wenn Sie versuchen, das Kameradialogfeld im Emulator aufzurufen, erhalten Sie einen Ausnahmefehler für einen ungültigen Vorgang.

Verwenden der Kamera
Lassen Sie nun den Benutzer ein Bild aufnehmen, das als Hintergrund dienen soll. Um diesen Teil der Anwendung auszuführen, benötigen Sie einen Windows Mobile 5.0 Pocket PC mit Kamera. Nachdem Sie das Gerät an Ihren Computer angeschlossen und ggf. ein Profil in ActiveSync erstellt haben, ändern Sie das Zielgerät in der Dropdown-Liste der Geräte-Symbolleiste von Windows Mobile 5.0 Pocket PC-Emulator in Windows Mobile 5.0 Pocket PC-Gerät. Führen Sie anschließend das Projekt wie gewohnt durch. (Wenn Sie ein echtes Gerät verwenden, funktionieren die Haltepunkte und die Fehlerbehebung weiterhin wie bei der Fehlerbehebung im Emulator.)
Wenn der Benutzer im Menü „Datei“ einen neuen Hintergrund auswählt, erstellt die Anwendung eine neue Instanz von „CameraCaptureDialog“. Diese befindet sich in der gleichen Assembly wie „SelectPictureDialog“, Microsoft.WindowsMobile.Forms. In diesem Dialogfeld können Sie die anfänglichen Kameraeinstellungen konfigurieren, wobei die Benutzer diese weiterhin über das normale Optionsmenü anpassen können. Mit der Eigenschaft „Mode“ wird angegeben, ob der Benutzer nur ein einzelnes Bild (CameraCaptureMode.Still), ein Video (CameraCaptureMode.VideoOnly) oder ein Video mit Ton (CameraCaptureMode.VideoWithAudio) aufnehmen kann. Da es sich um ein Hintergrundbild handelt, soll sich die Anwendung im Einzelbildmodus befinden und die höchste Qualität für Standbilder verwenden (Eigenschaft „StillQuality“). Sie können auch Eigenschaften festlegen, die ein optionales Zeitlimit für die Länge von Videos festlegen (VideoTimeLimit) und sicherstellen, dass das Video zum Senden in einer MMS geeignet ist (VideoTypes).
Optional können Sie die Auflösungseigenschaft „Resolution“ zum Steuern der aufgenommenen Bildgröße einstellen. Im Allgemeinen werden willkürliche Werte nicht unterstützt. Stattdessen sollten Sie einen Wert entsprechend der Geräteauflösung wählen (z. B. 640×480 oder 1280×1024). Da Sie das Bild herunterskalieren, damit es der Bildschirmgröße entspricht, lassen Sie „Resolution“ unverändert.
Nachdem der Benutzer ein Bild aufgenommen hat, gibt die Methode „ShowDialog“ das Ergebnis „DialogResult.OK“ zurück. Um nun das aufgenommene Bild zu laden, können Sie dieselbe Skalierungstechnik verwenden, die Sie zuvor für die Anpassung der Größe des vorhandenen Bilds an den Hintergrund angewendet haben. Da nur das Hintergrundbild ersetzt wird, bleiben die Linien oder Texte, die der Benutzer bereits gezeichnet hat, unverändert. Nachdem das Bild in den Hintergrund übernommen wurde, können Sie „Invalidate“ auf das gesamte Clientrechteck anwenden. Daraufhin wird das neue Bild als Hintergrund auf dem Bildschirm angezeigt.

Überprüfen des Systemstatus
Sie können „CameraCaptureDialog“ aufrufen, und falls das Gerät über keine Kamera verfügt, wird der Fehler „InvalidOperationException“ angezeigt. Es ist jedoch angebracht, vorher zu bestimmen, ob eine Kamerafunktion vorhanden ist, und andernfalls die entsprechende Menüoption zu deaktivieren. Dazu fragen Sie die allgemeine Konfiguration des Geräts ab und überwachen die Echtzeiteigenschaften auf Änderungen.
Informationen über das Gerät sind in der Klasse „SystemState“ verfügbar, die sich in der Microsoft.WindowsMobile.Status-Assembly befindet. Sie können diese Informationen in Ihrer Anwendung verwenden, indem Sie einen Verweis auf die Assembly und die zugehörige Abhängigkeit „Microsoft.WindowsMobile“ hinzufügen. Die Klasse „SystemState“ enthält verschiedene statische Eigenschaften, mit denen Sie feste Konfigurationsinformationen sowie Echtzeitinformationen, wie das aktuelle Datum und die Uhrzeit oder den Ladestatus der Batterie, abrufen können.
Die Anwendung muss nur einmal beim Starten die Eigenschaft „CameraPresent“ überprüfen und dann ggf. – falls keine Kamera vorhanden ist – die Menüoption für den neuen Hintergrund deaktivieren. Die Klasse „SystemState“ bietet jedoch das Ereignis „Changed“, mit dem Sie sich benachrichtigen lassen können, wenn sich der entsprechende Status ändert. Statt die statischen Eigenschaften zu verwenden, können Sie eine Instanz von „SystemState“ erstellen; Sie leiten die zu überwachenden Systemeigenschaften an den Konstruktor weiter und fügen anschließend einfach einen Ereignishandler für „Changed“ hinzu. Beispielsweise können Sie die Anwendung so einstellen, dass die Systemeigenschaft „DisplayRotation“ überwacht wird, damit die Anwendung benachrichtigt wird, wenn der Benutzer die Gerätetastatur herauszieht und sich die Darstellung von Hochformat in Querformat ändert. Oder die Anwendung könnte die Eigenschaft „ActiveSyncStatus“ überwachen, um eine Aktion auszuführen, wenn das Gerät synchronisiert wird.
Die Klasse „SystemState“ berücksichtigt auch die Eigenschaften „ComparisonType“ (Vergleichstyp) und „ComparisonValue“ (Vergleichswert), bevor das Änderungsereignis „Changed“ eintritt. Standardmäßig führen alle Änderungen in der überwachten Eigenschaft dazu, dass „Changed“ ausgelöst wird. Wenn Sie jedoch beispielsweise die Eigenschaft „ComparisonType“ auf „ComparisonType.Greater“ (Größer als) und „ComparisonValue“ auf 2 setzen, wird „Changed“ nur ausgelöst, wenn die überwachte Systemeigenschaft sich auf einen Wert ändert, der größer als 2 ist. Mit anderen Vergleichstypen wie „Equals“, „Contains“ oder „StartsWith“ können Sie ganz genau steuern, auf welche Ereignisse die Anwendung reagiert.
Eine wesentliche Einschränkung von „SystemState“ besteht darin, dass die Anwendung nur dann über Statusänderungen informiert wird, wenn sie zum Zeitpunkt der Änderung ausgeführt wird. Darüber hinaus müssen Sie die für das Änderungsereignis relevante Instanz von „SystemState“ nicht als lokale Methodenvariable, sondern als Feld auf Klassenebene deklarieren. Andernfalls wird sie möglicherweise von der Freispeichersammlung (Garbage Collection) erfasst, wodurch Sie Ereignisse verpassen könnten.

Arbeiten mit Pocket Outlook
Windows Mobile 5.0 bietet eine neue Assembly, Microsoft.WindowsMobile.PocketOutlook, für die Interaktion mit Messaging-Konten, Aufgaben, Kalendereinträgen und Kontakten, die auf einem Gerät gespeichert sind. Sie können diese Assembly in Ihrer Anwendung verwenden, damit der Benutzer einen Kontakt mit einer E-Mail-Adresse auswählen und ein Bild an ihn senden kann.
Mit dem neuen Dialogfeld zur Auswahl von Kontakten „ChooseContactDialog“ können Sie den Benutzer auffordern, einen gesamten Kontakt oder eine bestimmte Eigenschaft eines bestimmten Kontakts auszuwählen (siehe Abbildung 5). Eine der nützlichsten Funktionen in diesem Dialogfeld ist die Möglichkeit zum Filtern der Liste der verfügbaren Kontakte. Für diese Anwendung möchten Sie nur Kontakte mit E-Mail-Adressen anzeigen, da die Funktion zum Versenden eines Bilds per E-Mail an den Kontakt dient. Die Eigenschaft „RequiredProperties“ des Dialogfelds enthält mehrere ContactProperty-Enumerationen, die das Filtern steuern. Die Anwendung verwendet die Kontakteigenschaft (ContactProperty) mit dem Wert „ContactProperty.Email1Address“, um anzugeben, dass nur Kontakte mit gültiger E-Mail-Adresse angezeigt werden sollen. Diese Enumeration enthält alle Eigenschaften des Kontakts, einschließlich Geburtstag, Geschäftsadresse und private Telefonnummer. Mit „RequiredProperties“ können Sie ganz einfach die Liste der Kontakte auf eine übersichtliche Anzahl reduzieren, die dafür relevant ist, wie der Kontakt in dieser Anwendung eingesetzt wird.
Abbildung 5 Auswählen eines Kontakts 
Verwenden Sie eine Instanz der Klasse „EmailMessage“, um die eigentliche Nachricht zu senden. Fügen Sie einfach einen neuen Empfänger (Recipient) zur Auflistung in der Eigenschaft „To“ hinzu, legen Sie die Eigenschaften für Betreff und Text (Subject und Body) fest und fügen Sie das Bild zur Auflistung der Anlagen (Attachments) hinzu. Die wesentliche Interaktion mit allen Messagingkonten, dem Kalender und anderen Outlook-Funktionen wird über „OutlookSession“ erreicht. Nachdem Sie eine Instanz von „OutlookSession“ erstellt haben, können Sie die Eigenschaft „EmailAccounts“ verwenden, um das erste E-Mail-Konto abzurufen und die Nachricht zu senden. Basierend auf Status und Einstellungen des Geräts wird die E-Mail entweder sofort gesendet oder erst wenn der Benutzer das nächste Mal mit den Netzwerk verbunden ist und einen Sendevorgang startet. In Abbildung 6 sehen Sie den Code zum Senden der E-Mail.
if (dlgContact.ShowDialog() == DialogResult.OK)
{
    //send an email
    EmailMessage msg = new EmailMessage();
    msg.To.Add(new Recipient(dlgContact.SelectedContact.Email1Address));
    msg.Subject = "Here is an image I created...";
    msg.BodyText = "...using Windows Mobile 5";
    msg.Attachments.Add(new Attachment(filename));

    using (OutlookSession outlook = new OutlookSession())
    {
        outlook.EmailAccounts[0].Send(msg);
    }

    MessageBox.Show("Send successful.");
}


Erweiterte Synchronisierungsideen
Auch wenn das Senden einer E-Mail für dieses vereinfachte Beispiel gut geeignet ist, ist es nicht immer die beste Wahl zum Übertragen von Daten. In komplexeren Szenarios, wenn Sie Daten zwischen einem Gerät und dem Desktopcomputer übertragen möchten, ist ActiveSync besser geeignet. Obwohl Microsoft den Umfang von Compact Framework in Version 2.0 deutlich erweitert hat, sind einige Bereiche mit verwaltetem Code nach wie vor nicht zu realisieren. Die Interaktion mit ActiveSync und die Kommunikation mit einem Gerät vom Desktopcomputer aus erfordert nach wie vor die Verwendung von nicht verwaltetem Code. Es gibt jedoch Möglichkeiten, auch ohne das Schreiben von nicht verwaltetem Code zu beginnen.
ActiveSync synchronisiert Daten zwischen einem mobilen Gerät und dem Desktopcomputer durch eine Partnerschaft und verschiedene Dienstprovider (z. B. die Outlook-Funktion zum Synchronisieren der E-Mails und Kalenderinformationen). Jeder Provider besteht aus einem Satz DLLs (eine auf dem Gerät und eine auf dem Desktop), die bestimmte COM-Schnittstellen implementieren. Diese Provider sind sehr leistungsfähig, aber auch schwierig zu entwickeln. Für einfache Szenarien, in denen keine komplexe Synchronisierung erforderlich ist, gibt es eine einfache Möglichkeit zur Benachrichtigung, wenn eine Verbindung zu einem mobilen Gerät hergestellt oder getrennt wurde, ohne einen Dienstprovider zu implementieren.
In der Registrierung gibt es eine Liste mit Programmen, die automatisch ausgeführt werden, wenn ein Gerät angeschlossen oder getrennt wurde. Die Schlüssel befinden sich unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\AutoStartOnConnect und \AutoStartOnDisconnect. Um diese Schlüssel zu verwenden, erstellen Sie eine Zeichenfolge mit einem eindeutigen Namen, die den Pfad zur auszuführenden Datei enthält. Wenn Sie beispielsweise eine Zeichenfolge mit dem Namen „NotepadTest“ und den Wert notepad zu „AutoStartOnConnect“ hinzufügen, startet Editor jedes Mal, wenn ein Gerät mit dem System verbunden wird. Wenn Sie Befehlszeilenargumente an das Programm übergeben möchten, schließen Sie den Namen des Programms in doppelte Anführungszeichen ein. Der Wert "notepad" c:\test.txt startet Notepad mit dem Inhalt von test.txt, wenn ein Gerät angeschlossen wird. Alternativ haben Sie in Windows Mobile 5.0 die Möglichkeit, den ActiveSync-Prozess programmgesteuert vom Gerät aus zu starten, indem Sie die nicht verwalteten Funktionen „ActiveSyncStart“ und „ActiveSyncStop“ verwenden.
Da Sie nun wissen, wie Sie eine Anwendung auf dem Desktop starten, sobald ein Gerät angeschlossen wird, besteht der nächste Schritt in der Kommunikation mit dem Gerät, die über die Remote-Anwendungsprogrammierschnittstelle (RAPI) erfolgt. .NET Framework enthält gegenwärtig keine verwaltete RAPI-Version. Da es sich bei RAPI lediglich um eine systemeigene API handelt, unterstützt .NET die Möglichkeit zum Aufrufen der verfügbaren Funktionen mittels „Platform Invoke“. Das Erstellen einer .NET-basierten Anwendung, die diese API verwendet und automatisch gestartet wird, sobald ein Gerät angeschlossen wird, ist eine einfache Möglichkeit zum Datenaustausch zwischen dem mobilen Gerät und einem Desktopcomputer.

Schlussbemerkung
Compact Framework Version 2.0 (wie auch Visual Studio 2005) baut auf dem Erfolg der ersten Version auf, mit der das Entwickeln von mobilen Anwendungen bereits vereinfacht wurde. Die Anwendungen, die Sie damit erstellen, sind jetzt noch leistungsfähiger. Da Entwickler dieselben Tools und Klassen zum Entwickeln mobiler Anwendungen wie für das Entwickeln anderer Anwendungen mit verwaltetem Code verwenden können, werden mehr Entwickler schneller mit dem Schreiben funktionsreicher mobiler Anwendungen beginnen.
Gleichzeitig ermöglichen die neuen APIs den Entwicklern, die Funktionen der zunehmend leistungsfähigeren mobilen Geräte besser auszunutzen. Sie können nun Anwendungen schreiben, die mit der Gerätekamera interagieren, und Funktionen für die Kommunikation mit anderen Geräten integrieren. Endlich sind Entwickler in der Lage, unter Verwendung der entsprechenden Funktionen auf den jeweiligen Geräten die am besten angepassten Lösungen für ihre Anforderungen zu erstellen, ohne sich über zusätzlichen Aufwand und zusätzliche Kosten für die Entwicklung Sorgen zu machen.

Rob Pierry ist leitender Berater bei Geniant, einem führenden IT-Beratungsunternehmen für Großunternehmen, das sich auf dienstorientierte Architektur spezialisiert hat. Sie erreichen ihn unter rpierry+msdn@gmail.com.

Page view tracker