Kategorie-Archiv: WMDevAdventskalender09

Türchen Nummer 24

Sollte man die Weihnachtsgeschenke für seine Lieben bereits gekauft haben, so kommt man meist zum eher unangenehmen Teil: Dem Verpacken.
Dies gilt jedoch auch für Anwendungen, die auf einem mobilen Gerät installiert werden sollen. Hierfür gibt es das CAB-Datei Format.
 
Um eine entsprechende Installationsdatei zu erstellen, nehmen wir einmal an, dass wir die zu verpackenden Dateien unter c:\HelloWorld abgelegt haben.
Die Dateien, welche dort vorliegen müssen, sind die HelloWorld.exe, welche installiert werden soll, sowie die HelloWorld.inf Datei, welche die Informationen für den CabWizard vorbehält, um eine CAB-Datei erzeugen zu können.

Hier nun der Inhalt der INF-Datei dazu. Hierbei hat die Programmiersprache diesmal keine Relevanz:

[SOURCE FILE]
Name=CHelloWorld.cab
Path=C:\HelloWorld\HelloWorld.cab
AllowUninstall=TRUE

[Version]
Signature=”$Chicago$”
CESignature=”$Windows CE$”
Provider=”Company”

[CEStrings]
AppName=”HelloWorld”
InstallDir=”%CE1%\CHelloWorld”

[CEDevice]
ProcessorType=0
VersionMin=0.0
VersionMax=0.0
BuildMin=0
BuildMax=0

[SourceDisksNames]
1=,Source1,,

[SourceDisksFiles]
“HelloWorld.exe”=1

[CopyFiles1]
“HelloWorld.exe”,,,0x00000001

[DestinationDirs]
CopyFiles1=0,”%CE1%\HelloWorld”

[DefaultInstall]
CopyFiles=CopyFiles1

Wird nun auf der Kommandozeile der Befehl “c:\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\SDKTools\cabwiz.exe” “Company HelloWorld2.inf” ausgeführt (Pfad ist natürlich hinsichtlich seinen Gegebenheiten anzupassen), so findet sich im entsprechenden Zielordner die CAB-Installationsdatei wieder.
Weitere Informationen zum CAB-Wizard erhalten Sie hier:http://msdn.microsoft.com/de-de/library/cc433670%28VS.71%29.aspx

Das war es mit dem Adventskalender für dieses Jahr und wünschen Ihnen ein frohes Fest.

Patrick & Peter

Türchen Nummer 23

So kurz vor weihnachten sollte der Weihnachtsbaum hell leuchten. Warum auch nicht dann die LED des Bluetoothmoduls des Gerätes zum Blinken bringen?
Nichts einfacher als das, in dem man das Bluetooth Modul aktiviert.

Dabei gilt zu beachten, dass dieses Beispiel nur auf Geräten funktioniert, die den Microsoft Bluetooth Stack verwenden.

C++

#include “bthutil.h”
#pragma comment(lib, “Bthutil.lib”)

DWORD dwMode = 0;
BthGetMode(&dwMode);
if(dwMode==BTH_POWER_OFF || dwMode==BTH_CONNECTABLE)
{
    BthSetMode(BTH_DISCOVERABLE);
}




C#

In C# ist es auch an dieser Stelle nötig, mittels P/Invoke auf die nötige DLL zu zu greifen, um auf die entsprechenden Informationen zu erhalten.
Somit hier das Snippet:


public enum RadioMode
{
    Off = 0,
    Connectable = 1,
    Discoverable = 2
}

static class Program
{
    [DllImport(“BthUtil.dll”)]
    private static extern int BthGetMode(out RadioMode dwMode);

    [DllImport(“BthUtil.dll”)]
    private static extern int BthSetMode(RadioMode dwMode);

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [MTAThread]
    static void Main()
    {
        RadioMode rm = RadioMode.Off;
        BthGetMode(out rm);
        if (rm == RadioMode.Off || rm== RadioMode.Connectable)
        {
            BthSetMode(RadioMode.Discoverable);   
        }
    }
}

Patrick & Peter

Türchen Nummer 22

In vielen Fenstern und Wohnungen findet man zur Weihnachtszeit eine ganze Menge an Lichterketten und sonstiger beleuchteter Weihnachtsdekoration.
Das manuelle Einschalten dieser vielen Lichterketten und Lämpchen kann eine zeitraubende Beschäftigung werden.
Gleiches gilt auch für Windows Mobile Applikationen die durchgehend laufen sollen. Wenn der Anwender diese Applikationen manuell starten muss dauert dies natürlich auch eine Weile.
Wäre es nicht angenehmer wenn dies automatisch geschehen würde?
Mit folgendem Codeschnipsel kann aus der eigenen Anwendung heraus, beispielsweise per Optionsdialog, eine Autostartverknüpfung angelegt werden.

C++

//Dies ist eigentlich das gleiche Schnipsel wie Türchen Nummer 8
//jedoch wird diesmal die CSIDL_STARTUP verwendet.
//Autostart Ordner auslesen
WCHAR szShortcutPath[MAX_PATH*2] = L”\0″;
SHGetSpecialFolderPath(NULL,szShortcutPath,CSIDL_STARTUP,0);
wcscat(szShortcutPath,L”\\MeinShortcut.lnk”);
//Modulnamen auslesen
WCHAR szModulePath[MAX_PATH*2] = L”\0″;
GetModuleFileName(GetModuleHandle(NULL), szModulePath, MAX_PATH);
//Shortcut erstellen
SHCreateShortcut(szShortcutPath,szModulePath);





In C# ist es diesmal nicht notwendig P/Invoke zu nutzen, um an diese Informationen zu kommen. Die Klasse Environment hierfür reicht völlig.
Hier also das Snippet:

C#


[DllImport(“coredll.dll”)]
private static extern int SHCreateShortcut(StringBuilder szShortcut, StringBuilder szTarget);

[MTAThread]
static void Main()
{

   StringBuilder shortcut = new StringBuilder(System.Environment.GetFolderPath(Environment.SpecialFolder.Startup)+@”\MeinShortcut.lnk”);
   StringBuilder target = new StringBuilder(@”\windows\calc.exe”);
   SHCreateShortcut(shortcut, target);
}


Patrick & Peter

Türchen Nummer 21

Der große Vorteil eines digitalen Adventskalenders ist, dass man volle Kontrolle über alle Türchen
hat und niemand vorab schon mal die “24” öffnen kann.
Eine vollständige Kontrolle bspw. über sämtliche Tasten kann auch mal in einer Windows Mobile Applikation benötigt werden.
Das folgende Codeschnipsel zeigt wie man dies mit der AllKeys API bewerkstelligen kann.

C++

//Alle Tasten abfangen(bspw. in WM_CREATE)
AllKeys(TRUE);

//In WM_KEYDOWN und WM_KEYUP den WPARAM prüfen.
//Siehe http://msdn.microsoft.com/en-us/library/bb431750.aspx für Keycodes
case WM_KEYDOWN:
    OutputDebugString(L”WM_KEYDOWN\n”);
    //Behandlung für den Tastencode ist hier nicht aufgeführt
    HandleKey(wParam);
    break;
case WM_KEYUP:
    OutputDebugString(L”WM_KEYUP\n”);
    //Behandlung für den Tastencode ist hier nicht aufgeführt
    HandleKey(wParam);
    break;




Im verwaltetem Code ist es mehr Code nötig, um das gleiche Ziel zu erreichen. Das liegt daran, dass eine Windows Form generell die Verarbeitung von derlei Nachrichten intern bereits durchführt.
Um also auf die internen Window Messages zugreifen zu können, ist es nötig, eine Klasse zu erstellen, die von der Klasse MessageWindow ableitet. Zusätzlich ist auch das P/Invoke notwendig, um die AllKeys-Methode auf zu rufen.
Somit ist es diesmal für das Snippet nötig, eine Anwendung für intelligene Geräte anzulegen, welche eine Geräteanwendung darstellt.
Der Code is dann entsprechend ähnlich abzuändern:

C#


using Microsoft.WindowsCE.Forms;

public partial class MessageForm : Form
{
    [DllImport(“coredll.dll”, SetLastError = true)]
    static extern bool AllKeys(bool bAllKeys);
    
    MsgWindow msgWin;

    public MessageForm()
    {
        InitializeComponent();
        AllKeys(true);
        msgWin = new MsgWindow(this);
    }

}

public class MsgWindow : MessageWindow
{
    public const int WM_KEYDOWN = 0x0100;
    public const int WM_KEYUP = 0x0101;

    private MessageForm msgform;

    public MsgWindow(MessageForm msgform)
    {
        this.msgform = msgform;
    }

    protected override void WndProc(ref Message msg)
    {
        switch (msg.Msg)
        {
            case WM_KEYDOWN:
                MessageBox.Show(“Key was down with WPARAM:” + ((int)msg.WParam).ToString() + “and LPARAM:” + ((int)msg.LParam).ToString());
                break;
            case WM_KEYUP:
                MessageBox.Show(“Key was up with WPARAM:” + ((int)msg.WParam).ToString() + “and LPARAM:” + ((int)msg.LParam).ToString());
                break;
        }
        base.WndProc(ref msg);
    }
}

Mehr Informationen zur Klasse MessageWindow erhalten Sie hier:

http://msdn.microsoft.com/de-de/library/microsoft.windowsce.forms.messagewindow%28VS.80%29.aspx

Patrick & Peter

Türchen Nummer 20

Gerade in der Weihnachtszeit sind die Schaufenster derart mit Werbung oder Kunstschnee zugekleistert, das der Blick auf die schönen Dinge dahinter verwehrt ist.
Auch dies gilt für manche Windows Mobile Anwendung, die man im Vollbildmodus betreiben möchte.

C++

//Der folgende Code gilt für Win32 Anwendungen.
//Er ist im IDM_HELP_ABOUT Handler der WM_COMMAND Nachricht
//einer per Visual Studio 2008 Win32 Projekt für intelligente Geräte (Windowsanwendung)
//untergebracht. Der DialogBox Aufruf ist auskommentiert.
//Rückgängig gemacht werden sollte der Fullscrenn Code bspw. über ein Kontextmenu oder beim
//beenden der Applikation
//DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
//Fenster muss für SHFullScreen im Vordergrund sein
SetForegroundWindow(hWnd);
//SIP und Taskbar in den Hintergrund legen
SHFullScreen(hWnd,SHFS_HIDESIPBUTTON|SHFS_HIDETASKBAR);
//Die Menübar soll auch weg
HWND hwndMenu = SHFindMenuBar(hWnd);
//Erst die Menübarhöhe holen. Gilt auch für das Starmenü
RECT rcMenue;
GetWindowRect(hwndMenu, &rcMenue);
//Menübar verschieben
SetWindowPos(hwndMenu, NULL,-1, -1,0, 0,SWP_NOZORDER | SWP_NOACTIVATE);
//Jetzt muss unser Fenster noch neu positioniert werden
RECT rect;
GetWindowRect(hWnd,&rect);
rect.top -= rcMenue.bottom – rcMenue.top;
rect.bottom += rcMenue.bottom – rcMenue.top;
MoveWindow(hWnd,rect.left,rect.top,rect.right,rect.bottom,TRUE);




C#

Eine Anwendung zu erstellen, welche eine Vollbilddarstellung liefert ist mit Bordmitteln des .NET Compact
Frameworks bereits einfach realisierbar.
Dies geht sogar so einfach, dass nicht einmal ein Snippet hierfür notwendig ist.
Setzen Sie für die Vollbilddarstellung Ihrer Form einfach die zugehörige Eigenschaft WindowsState auf den
Wert FormWindowState.Maximized. Hierdurch »verschwindet« die Titelzeile Ihrer Anwendung.
Damit sich jedoch kein vielleicht im Hintergrund startendes Programm in den Vordergrund setzt und Ihre
Anwendung überlagert, sollten Sie gleichfalls die Eigenschaft TopMost der Form auf den Wert true setzten.
Wollen Sie gleichfalls die Menüzeile, welche Ihr Anwendungsmenü darstellt und meist auch die virtuelle
Tastatur aktiviert, deaktivieren, ist auch dies ganz einfach. Leider gibt es für das MainMenu keine Eigenschaft
»Enabled«, um dies zu ermöglichen. Stattdessen reicht es, wenn die Eigenschaft Menu der zugehörigen Form auf
den Wert null gesetzt wird, was auch dynamisch aus der Anwendung möglich ist.
Hierdurch wird die Zuweisung eines MainMenu zur Form entfernt, wodurch Sie eine komplette
Vollbilddarstellung Ihrer Anwendung erhalten. Wenn Sie nun Menu wieder das Objekt vom Typ MainMenu
zuweisen, haben Sie wieder Ihren Ursprungszustand hergestellt.

Patrick & Peter

Türchen Nummer 19

Wer dem Weihnachtstress ein wenig aus dem Weg gehen möchte vermeidet es am besten die Geschenke auf althergebrachte Weise in der Stadt oder sonstigen Einkaufläden zu besorgen.
Nichts ist entspannter als ein Einkaufbummel im Internet. Und wenn man die Einkauftour rechtzeitig beginn bekommt auch keinen Stress mit den Lieferzeiten.
Um aber trotzdem an sein Paket zu kommen muss man natürlich seine eigene Adresse mitteilen.
Gleiches gilt auch für Anwendung die auf Netzwerkdienste zugreifen. Oftmals muss die Anwendung die eigene IP Adresse nicht kennen, da es durch die zugrunde liegenden Protokolle automatisch passiert. Ab und an kann es aber vorkommen dass diese Information benötigt wird.
Dazu kann das folgende Codeschnipsel verwendet werden:

C++

#include “iphlpapi.h”
#pragma comment(lib, “Iphlpapi.lib”)

//Wir listen mal etwas mehr auf als nur die aktuellen IPs.
//Adapter Information anlegen
PIP_ADAPTER_INFO pAdapterInfo;
ULONG lRetLen = sizeof(PIP_ADAPTER_INFO);
//Benötigte Speichergrösse holen
DWORD dwRet = GetAdaptersInfo(NULL,&lRetLen);
//Informationen zu allen Adaptern holen
pAdapterInfo = (PIP_ADAPTER_INFO) malloc (lRetLen);
dwRet = GetAdaptersInfo(pAdapterInfo,&lRetLen);
if(dwRet == ERROR_SUCCESS)
{
    //Informationen nur für den aktuellen Adapter
    PIP_ADAPTER_INFO pCurrentAdapter = pAdapterInfo;
    while (pCurrentAdapter != NULL )
    {
        //Systemindex
        printf(“Adapterindex: %i\n”,pCurrentAdapter->Index);
        //Beschreibung
        printf(“Beschreibung: %s\n”,pCurrentAdapter->Description);
        //IP Addresse
        printf(“IP: %s\n”,pCurrentAdapter->IpAddressList.IpAddress.String);
        //Gateway
        printf(“Gateway: %s\n”,pCurrentAdapter->GatewayList.IpAddress.String);
        //Subnet
        printf(“Subnet: %s\n”,pCurrentAdapter->IpAddressList.IpMask.String);
        //Erweiterte IP Infos anlegen
        PIP_PER_ADAPTER_INFO pPerAdapterInfo;
        lRetLen = sizeof(PIP_PER_ADAPTER_INFO);
        //Benötigte Speichergrösse holen
        dwRet = GetPerAdapterInfo(pCurrentAdapter->Index,NULL,&lRetLen);
        //Erweiterte IP Infos abfragen    
        pPerAdapterInfo = (PIP_PER_ADAPTER_INFO) malloc (lRetLen);
        dwRet = GetPerAdapterInfo(pCurrentAdapter->Index,pPerAdapterInfo,&lRetLen);
        //DNS1
        printf(“DNS: %s\n”,pPerAdapterInfo->DnsServerList.IpAddress.String);
        //DNS2
        if(pPerAdapterInfo->DnsServerList.Next != NULL)
            printf(“DNS2: %s\n”,pPerAdapterInfo->DnsServerList.Next->IpAddress.String);
        //Interface anlegen
        MIB_IFROW IfRow;
        memset( &IfRow, NULL, sizeof( MIB_IFROW ) );
        //Index zum abfragen setzen
        IfRow.dwIndex = pCurrentAdapter->Index;
        //Interface abfragen
        GetIfEntry(&IfRow);
        //MAC Adresse
        printf(“MAC: %02x-%02x-%02x-%02x-%02x-%02x\n”,IfRow.bPhysAddr[0], IfRow.bPhysAddr[1], IfRow.bPhysAddr[2], IfRow.bPhysAddr[3], IfRow.bPhysAddr[4], IfRow.bPhysAddr[5]);
        //Den Namen(ClassID) brauchen wir auch…
        printf(“ClassID: %s\n”,pCurrentAdapter->AdapterName);
        //Nächster Adapter
        pCurrentAdapter = pCurrentAdapter->Next;
    }
}




C#

In C# geht dies ebenfalls ganz einfach, auch wenn es wild aussieht:

using System.Net;

IPHostEntry enty = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ipadress in enty.AddressList)
{
    Console.WriteLine(“IP: ” + ipadress.ToString());   
}

Patrick & Peter

Türchen Nummer 18

Nach einem längeren Abend am Glühweinstand kann es in seltenen Fällen dazu kommen, dass man seinen eigenen Namen am nächsten Morgen vergessen hat.
Gut, wenn dieser im mobilen Gerät gespeichert ist.
Das folgende Beispiel funktioniert natürlich nur dann, wenn der Benutzername in den Besitzerinformationen hinterlegt wurde.

C++

//State & Notification Broker Header Datei
#include “snapi.h”
//Registry Hilfsfunktionen
#include “regext.h”

//Per Registry Helfer Funktion und den State&Notification Broker Konstanten
//die Besitzerinformationen auslesen. Setzt natürlich voraus das der Anwender diese Informationen auch eingegeben hat.
TCHAR szUserName[MAX_PATH] = L”\0″;
if(RegistryGetString(SN_OWNERNAME_ROOT,SN_OWNERNAME_PATH,SN_OWNERNAME_VALUE,szUserName,MAX_PATH)==S_OK)
    _tprintf(L”Username: %s\n”,szUserName);
else
    _tprintf(L”Fehler bei RegistryGetString\n”);




C#

Mittels SnAPI ist das Auslesen mittels managed Code ganz einfach, wenn zuvor die Verweise zu den Bibliotheken Microsoft.WindowsMobile und Microsoft.WindowsMobile.Status hinzugefügt wurden.

Somit besteht das Snippet dann wieder aus einer Zeile ausführbarem Code:

using Microsoft.WindowsMobile.Status;

Console.WriteLine((string)SystemState.GetValue(SystemProperty.OwnerName));

Patrick & Peter

Türchen Nummer 17

Bei einem leckerem warmen Kakao trifft man manchmal Freunde, die man lange nicht mehr gesehen, oder jedoch aus den Augen verloren hat.
Also schnell die Telefonnummern ausgetauscht, bevor man sich wieder verliert.
Wenn man aber seine eigene Nummer nicht auswendig kennt und sich auch nicht selbst als Kontakt aufgeführt hat (Wobei dies zum Versenden seiner eigenen Kontaktdaten sehr praktisch ist) muss man
sich mühsam über die Menüdialoge der Telefonapplikation zur eigenen Rufnummer vorarbeiten.
Wäre es also nicht schön wenn man die Rufnummer aus dem eigenen Code heraus anzeigen lassen könnte? Hier das passende Codeschnipsel dazu:

Es gilt jedoch zu beachten, dass die vorgestellte Funktionalität möglicherweise nicht bei allen funktioniert, da dies ggfs. sogar providerabhängig ist.

C++

//Da dies ein Snippet ist inkludiere ich hier einfach die komplette CPP Datei des SDK Samples
#include “C:\Programme\Windows Mobile 6 SDK\Samples\Common\CPP\Win32\GetPhoneNumber\GetPhoneNumber.cpp”

//Der Aufruf setzt vorraus das die Telefonnummer in die SIM einprogrammiert
//ist. Wird ggf. nicht von jeder SIM bzw. Provider unterstützt.
//Durch verwendung von AT Kommandos ist diese Nummer auch
//editierbar.
SHGetPhoneNumber(szNumber, MAX_LOADSTRING, 1);
_tprintf(L”Nummer: %s\n”,szNumber);




C#

In .NET ist auch diese Aufgabe wieder einmal nicht ganz trivial zu lösen.
Um Ihnen jedoch Menge Tipparbeit zu ersparen, laden Sie sich bitte die MSDN Bibliothek zur Phonefunktionalität unter http://www.microsoft.com/downloads/details.aspx?FamilyId=40CF068B-66CA-4F26-87A1-15B67F2F7AE6&displaylang=en herunter, fügen die dort enthaltene Klasse Phone.cs ihrem Projekt hinzu.
Da der hinzugefügte Code jedoch direkte Speicheroperationen durchführt, ist es notwendig in ihren Projekteigenschaften die Option “Unsicheren Code zulassen” zu aktivieren.

Der zu erstellende Code reduziert sich somit auf eine Zeile auführbaren Code.


using Microsoft.Wireless;

Console.WriteLine(Sim.GetPhoneNumber().Address);


Patrick & Peter

Türchen Nummer 16

Gerade in der Weihnachtszeit kommt man in der Stadt kaum voran, ohne auf irgendwelchen dynamischen Plakatwänden auf die aktuellsten Angebote aufmerksam gemacht zu werden.
Anstatt jedoch Werbung darzustellen, ist es unter Windows Mobile manchmal durchaus sinnvoll, den Benutzer mithilfe einer Notification auf eine bestimmte Gegebenheit hinzuweisen.

C++

// {070A46B7-1C4F-441e-AAE2-5BD96D03477A}
static const GUID CLSID_MyBubble =  { 0x70a46b7, 0x1c4f, 0x441e, { 0xaa, 0xe2, 0x5b, 0xd9, 0x6d, 0x3, 0x47, 0x7a } };

//SHNOTIFICATIONDATA Struktur anlegen
SHNOTIFICATIONDATA bubble = {0};
bubble.cbStruct = sizeof(bubble);
bubble.dwID = 1;
//Anzeigen bis der Benutzer es ausblendet
bubble.npPriority = SHNP_INFORM;
bubble.csDuration = -1;
bubble.hicon = NULL;
//Eine eigene GUID angeben
bubble.clsid = CLSID_MyBubble;
bubble.grfFlags = 0;
//Inhalt festlegen
bubble.pszTitle = L”Türchen Nummer 16″;
bubble.pszHTML = L”<html><body>Das ist Türchen Nummer <b> 16</b><br><br> in unserem Adventskalender.</body></html>”;
//Softkey festlegen
bubble.rgskn[0].pszTitle = L”Ausblenden”;
bubble.rgskn[0].skc.wpCmd = 1;
SHNotificationAdd(&bubble);

//Wir blenden es jetzt selber aus
SHNotificationRemove(&CLSID_MyBubble,1);




C#

In .NET gibt es in der Microsoft.WindowsCE.Forms Bibliothek eine Notification-Klasse, die einen Wrapper für verwalteten Code darstellt, jedoch funktioniert diese ein wenig anders.
Anstatt nun den Softkey einstellen zu können, verwendet dieses Beispiel den speziellen Namen des HTML-Inputbuttons “cmd:1″, welcher die Notification schließt.
Ausgelöst wird die Notifikation durch eine Schaltfläche.

Hier nun das Snippet:


Notification nf = new Notification();

private void btnNotify_Click(object sender, EventArgs e)
{
    nf.InitialDuration = 0;
    nf.Critical = false;
    nf.Caption = “Türchen Nummer 16″;
    nf.Text = “<html><body>Das ist Türchen Nummer <b> 16</b><br><br> in unserem Adventskalender.<br><input type=button name=’cmd:1′ value=’Schliessen’></body></html>”;
    nf.Visible = true;

    //Wir blenden es nun selbst aus
    nf.Visible = false;
}

Patrick & Peter

Türchen Nummer 15

Je nachdem wie groß der Familien und Freundeskreis muss man sich gerade während der Vorweihnachtszeit eine ganze Menge an Geschenkideen, Weihnachtsmarktbesuchen, Weihnachtsfeiern und sonstigen
Termin notieren. Wohl dem der ein Windows Phone sein eigen nennt und jederzeit Zugriff auf seine Termine, Notizen und Kontaktdaten hat.
Nichts ist jedoch ärgerlicher als das man bei der Eingabe von Text noch manuell die Tastatur anzeigen lassen muss nachdem man in ein Textfeld geklickt hat.
Wie man ein solches Verhalten in seiner eigenen Applikation verhindern kann zeigen die folgenden Codeschnipsel:

C++

//Keyboard anzeigen (bspw. wenn wir den Focus bekommen)
SHSipPreference(hwndEdit,SIP_UP);

//Keyboard ausblenden(bspw. wenn wir den Focus verlieren)
SHSipPreference(hwndEdit,SIP_DOWN);




C#

Damit wir den Status des Softkeyboards, bzw. die SIP sauber setzen können, gilt es dieses Mal eine mobile Windows Forms Anwendung zu erstellen.
Zusätzlich ist es notwendig einen Verweis auf die Bibliothek “Microsoft.WindowsCE.Forms” hinzuzufügen.
Wurden 2 Schaltflächen ebenfalls hinzufgefügt, so sieht der zu erstellende Code, wie folgt aus:

using Microsoft.WindowsCE.Forms;

InputPanel panel = new InputPanel();

private void btnSHowSIP_Click(object sender, EventArgs e)
{
    panel.Enabled = true;
}

private void btnHideSIP_Click(object sender, EventArgs e)
{
    panel.Enabled = false;
}

Patrick & Peter