Seiten-Inhalt

Programmierung von Windows CE mit eVB - eine kleine Hilfe

Ich versuche in den folgenden Abschnitten, Fragen zu klären, von denen mir des öfteren aufgefallen ist, dass diese immer wieder im Usenet gestellt werden - oder beschreibe einige "Tricks", von denen ich meine, dass sie Entwicklern helfen können, ihre Arbeit schneller und einfacher zu erledigen.

Tips und Tricks, die ich kenne und für wichtig halte, habe ich hier veröffentlicht - dies ist hoffentlich für viele Einsteiger eine Hilfe. Aus Zeitgründen kann und will ich keinen Support für Microsoft und eVB-Programmierung bieten. Für andere Fragen, die auftreten verweise ich (zurück?) an Google, Google-Groups oder die einschlägigen Newsgroups (z.B. microsoft.public.windowsce.embedded.evb).


Download und Installation der Win CE-Entwicklungsumgebung

Größte Hürde war hier für mich der Anfang: Welches Programm brauche ich, was kostet es und woher bekomme ich es. Es hat lange gedauert, für mich alle Fragen zu beantworten:

  1. Eine ca. 300 MB große Datei. Hier sind alle Komponenten enthalten, die benötigt werden um Programme mit embedded Visual Basic (eVB) zu erstellen. Die aktuelle Version ist 3.0 (Achtung: bei der Installation kann man die Erstellung der C-Entwicklungsumgebung unterbinden. So spart man sich 150 MB Festplattenspeicher.)
  2. Gute Nachricht: es ist umsonst - schlechte: die Datei ist immer noch 300 MB groß und nicht jedes Modem verträgt so viele Bits am Stück. Man kann sich aber auch bei Microsoft eine CD bestellen.
  3. Download - direkt bei Microsoft.

Interface-Design für Pocket-PC

Im Rahmen meiner Diplomarbeit habe ich mich mit dem Design von ergonomischen Interfaces auf Pocket-PC beschäftigt. Teilwese stellt es - je nach zu bearbeitenden Daten - eine große Herausforderung an die Entwickler dar, übersichtliche Dialoge zu entwerfen und sich nicht in Menü- und verschachtelten Fensterstrukturen zu verlieren (das ist ähnlich, wie mit den verschachtelten Sätzen *g*).

Ich stelle Interessenten meine Diplomarbeit auch als Download (2.2 MB, PDF-Datei) zur Verfügung. Um allerdings ein wenig den Überblick zu behalten, wer, wann, wo und welhalb meine Arbeit nutzt, erstelle ich individuelle Download-Links und maile diese auf Anfrage an Sie.

Bitte nehmen Sie über das Kontakt-Formular Verbindung zu mir auf!


Probeme mit der ActiveSync-Verbindung zur Projektaktualisierung

Um aus der Entwicklungsumgebung heraus das Projekt auf den PocketPC zu übertragen muss eine ActiveSync Verbindung bestehen. In der IDE muss nun noch das externe Gerät konfiguriert werden: Als übertragungsart muss hier nicht 'ActiveSync' sondern 'PPP' als übertragungs-Protokoll gewählt werden, damit die übertragung wir gewünscht funktioniert.

Möchten Sie Artikel bei Amazon suchen?
Büchersuche bei amazon.de

Schnellere Aktualisierung des aktuellen Projekts auf PPC

Das erste Problem, dass bei mir auftauchte war, dass ich meine geänderte Version via "Application Install Wizzard" auf dem Pocket PC installieren wollte. Alle erforderlichen Schritte wurden nach Test im Emulator durchgeführt, aber trotzdem lief auf dem Pocket PC noch die alte Version.
Abhilfe brachte der Versuch, vor der Installation jeweils durch [File]|Make....vb] eine neue .vb-Datei zu erstellen. Da der Installation Wizzard nicht automatisch eine neue Version des eigentlichen Executables erstellt ist dieser Extra-Schritt leider nötig.

Ist die .vb-Datei dann erstellt, so kann man durch ziemlich wilde Mausklickerei das Programm auf dem Pocket PC istallieren. Es werden durch den Wizard alle Dateien auf den PPC kopiert. Ist allerdings schon das Programm dort installiert und es soll nur durch eine neue Version ersetzt werden, so reicht es, die neue .vb-Datei mit dem Explorer o.ä. in das entsprechende Verzeichnis zu verschieben und somit die alte Version zu überschreiben. (Dies sollte auch durch ein Stapelverarbeitungsprogramm erledigt werden können. Ich weiß allerdings leider nicht, wie ich damit auf den PPC zugreifen kann. Wer dies weiß, kann mir gerne eine Lösung zukommen lassen, die ich gerne hier veröffentlichen werde.)


Arbeiten mit Datenbanken und Win CE

Im Usenet (z.B. in microsoft.public.windowsce.embedded.evb) wird immer wieder die Frage gestellt, wie man MS-Access Datenbankdateien in das für CE-Rechner kompatible CDB-Format konvertieren kann, um damit in der Emulationsumgebung arbeiten zu können. Warum Microsoft nicht schon längst ein simples Tool ins Netz gestellt hat, welches das komplizierte Procedere vereinfacht, ist mir unverständlich (vielleicht kann mir jemand eine Erklärung liefern?). Hier also die nötigen Schritte:

Möchte man eine Access-Datenbankdatei (MDB) auf dem Pocket PC nutzen, so reicht es, mit dem Explorer (via ActiveSync) die Datei auf das 'mobile Gerät' zu kopieren. Die Konvertierung zur CDB-Datei erfolgt automatisch durch ActiveSync (wenn die Option nicht deaktiviert ist). Probleme treten erst auf, wenn man mit dem CDB-Dateien in der Emulations-Umgebung arbeiten möchte.

  • Eine Idee ist, die .MDB durch eine Kopie auf den PPC die ActiveSync-Konvertierung anzustoßen. Nun kann man die Datei wieder zurück auf den Desktop PC kopieren. Vorher muss nun aber in den Optionen von ActiveSync die Konvertierung für .CDB-Dateien deaktiviert werden.
    Dieses Verfahren funktioniert leider "nicht immer zuverlässig". Daher habe ich noch einen zweiten Vorschlag:
  • Bei DevBuzz hole man sich ein Tool, welches man in der Emulations-Umgebung ausführt. Mit diesem können dann in der Emulation MDBs über einen Umweg nach CDB konvertiert werden: Ein VB-Programm mit ODBC-Zugriff erstellt eine TDB-Text-Datei, die alle notwendigen SQL-Befehle enthält, die die neue Datenbank und in der MDB enthaltenen Tabellen erzeugen (ähnlich dem Befehl mysqldump für MySQL). Auch die enthaltenen Daten werden via SQL-Befehl INSERT in die erstellten Tabellen eingefügt. Ein weiteres Programm wird in der Emulations-Umgebung gestartet, welches nun die Befehle ausführt und nun die CDB-PocktPC-Datenbank-Datei erzeugt. In der mir vorliegenden Version gibt es allerdings Probleme, wenn auf der Tabelle kein Index definiert ist. Es reicht allerdings, manuell die Leerzeile(n) in der TDB-Datei zu entfernen und jetzt erst das Programm in der Emulation zu starten, welches die Pocket Access-Datei erstellt - die dann allerdings nur in der Emulation richtig "funktioniert"...
    Bei der Verwendung dieses Tools gibt es leider noch zwei Fehlerquellen, die mir aufgefallen sind (für die es aber auch noch eine einfache Lösung gibt):
    1. Das MDB_2_TDB-Tool erzeugt eine Text-Datei, in der die auszuführenden SQL-Befehle stehen. Für Tabellen, die nicht indiziert sind (die also keinen Index haben), werden dort Leerzeilen eingefügt. Mit diesen Leerzeilen kann das TDB_2_CDB-Tool allerdings nicht umgehen. Löscht man einfach mit einem Text-Editor diese Leerzeilen, so funktioniert das Programm.
    2. Das TDB_2_CDB-Tool nutzt u.a. das FileSystem-Steuerelement. Dies ist auf frisch installierten Emulations-Umgebungen nicht standardmässig installiert und man erhält eine Fehlermeldung. Ich habe einfach in meinem Projekt temporär dieses Steuerelement (das FileSystem-Steuerelement) eingebaut. Die DLL wird nun bei Programmstart in das entsprechende Vereichnis kopiert und registriert. Und schon ist das Problem keines mehr... Welche DLL, woher, wann und wohin kopiert wird ist egal, da sich die Umgebung darum kümmert...

Datenbanken mit Windows CE

SQL mit Windows CE

Dem Programmierer wird schnell klar, dass die SQL-Version für Windows CE (ADOCE) "einigen" Beschränkungen unterliegt. Ich habe es nicht glauben wollen (und bin mir jetzt auch noch nicht wirklich sicher): Um einen Datensatz zu aktualisieren, muss man die Objektmethoden von 'Recordset' benutzen! Es ist also wohl nicht möglich mit

aktTAB.Open "UPDATE Konstanten SET Wert='emil' WHERE Name='Benutzer'", aktDB

einen Wert zu ändern. Statt dessen gibt es wohl nur den Workaround, der im folgenden Code-Schnipsel dargestellt wird

    
  Dim aktDB, 
  ' Verbindung zu Datenbank
  Set aktDB = CreateObject("ADOCE.Connection.3.0")
    aktDB.Open Pfad & "\Datenbank.cdb"
  ' aktualisiere...
    Set aktTAB = CreateObject("ADOCE.Recordset.3.0")
    aktTAB.Open "SELECT * FROM Konstanten WHERE Name='Benutzer'", _
                aktDB, adOpenKeyset, adLockOptimistic
    aktTAB.Fields("Wert") = "emil"
    aktTAB.Update
    aktTAB.Close
    aktDB.Close
    Set aktTAB = Nothing
    Set aktDB = Nothing

Schade eigentlich...

ACHTUNG - ACHTUNG - Speicherproblem mit CreateObject

Meine Projekte, die ich für Windows CE Pocket PCs erstellt habe, arbeiten schon mal mit Datenbanken. Dabei ist aufgefallen, dass im Laufe des Programmes immer mehr Speicher angefordert und nicht wieder freigegeben wird. Inter- und Usenet-Recherche brachte mich zu dem Ergebnis, dass es ein Speicher-Leck bei der Arbeit mit Datenbanken gibt. Problem ist wohl, dass obige CreateObject-Funktion oder ...=Nothing-Zuweisungen nicht richtig arbeiten - also bei einer neuen CreateObject-Aktion wieder neuer Speicher benutzt wird (Es erinnert ein wenig an die Speicherverwaltung von alten Windows-Versionen. Microsoft weiß um dieses Problem - behebt es aber nicht - warum? Ich weiß es nicht!! ;-)

Behoben habe ich das Problem, indem ich zwei globalen Objekte aktTAB und aktDB beim Programmstart mittels CreateObject die entsprechenden Objekte zuweise und diese im ganzen Programm nutze. Erst bei Beendigung des Programmes nutze ich noch die (sinnlose??) =Nothing-Zuweisungen. Bei Programmende steht der ganze Speicher dann wieder zur Verfügung.


Probleme mit der Left-Funktion und eVB

Viele Programmierer stolpern bei ersten (oder auch späteren) Gehversuchen darüber, dass die Left-Funktion, die die linken n Zeichen eines Strings zurückliefen soll, scheinbar nicht funktioniert. Im Usenet ist sogar manchmal die Antwort zu lesen, dass es diese Funktion für eVB nicht geben soll...

Das Problem besteht darin, dass die Funktion - aus einem Dialog.Modul aufgerufen - die Left-Methode des Dialoges aufruft, die den Abstand eines Steuerelementes zu seinem übergeordneten Container zurückliefert. Zur Umgehung dieses Problems gibt es zwei Möglichkeiten:

  1. Man erstetzt den Aufruf der Left-Funktion in dem Dialog durch den Aufruf der Funktion Mid.
  2. Man entwirft sich in einem neuen Modul eine eigene Funktion (z.B. MyLeft), die dann ohne Probleme im ganzen Projekt verwendet werden kann.

Welche Lösung man nun benutzt ist Geschmackssache und ggf. eine Geschwindigkeitsfrage (die ich aber noch nicht untersucht habe).


Grafiken als Hintergrund eines Forms

Irgendwann brauchte ich dieses Feature und konnte einfach nicht ergründen, wo das Problem liegt: Eine Anfrage im Usenet brachte mir zwei Vorschläge, von denen nur der zweite bei mir geholfen hat:

  • Man versuche nicht, die Grafik in den Hintergrund zu "schieben", sondern man schiebe die anderen Elemente des Forms in den Vordergrund.
  • Man ignoriere, dass die Grafik während der Entwicklung vor den anderen Steuerelementen angezeigt wird oder verschiebe diese temporär an den Rand. Nun kann während der Laufzeit die Grafik mit "Grafik1.ZOrder vbSendToBack" in den Hintergrund gebracht werden.

Sanduhr darstellen (Mauszeiger verändern)

Um dem "Mauszeiger" unter Windows CE zu verändern, um dem Benutzer eine Wartezeit anzukündigen kann man, wie auch im Desktop PC, den Mauszeiger zu einer Sanduhr 'umschalten':

Screen.MousePointer
         = 11 'Display hourglass

Der Ursprungszustand wird durch die Zuweisung des Wertes 0 wieder hergestellt.


Eigene Hilfe-Funktion mit eVB

Es gibt natürlich auch die Möglichkeit eine eigene Hilfe bei den Programmen zu bieten. Das Procedere dafür erfordert einige Schritte, die ich in den folgenden Punkten step-by-step beschreiben will. HTH

  • Unter "Project" - "Components" muss in dem folgenden Dialog die Komponente "Microsoft CE Common Dialog Control" angewählt sein, so dass das Häckchen davor erscheint;
  • Ein solches (im Dialog später 'unsichtbares') Steuerelement muss nun in jeden Dialog eingefügt werden, in dem eine Hilfe zur Verfügung gestellt werden soll;
  • Damit 'die Hilfe' weiss, wann sie welche Hilfe(-Datei) aufrufen soll, kann dies wie im folgenden Code-Schnipsel festgelegt werden. Man kann natürlich bei Fokuserhalt/-verlust eines jeden Elements diese zuordnung entsprechend ändern.
CommonHelp.HelpFile = Pfad & "\help.htm"
CommonHelp.HelpContext = "shortcuts"
CommonHelp.HelpCommand = cdlHelpContext
CommonHelp.ShowHelp

Der Aufruf der Hilfe kann dann jeweils mit der Funktion "ShowHelp" realisiert werden. Da ich noch nicht herausgefunden habe, wie die Darstellung des "?" in der Menueleiste zu aktivieren ist, habe ich in ein Menue einfach den Punkt Hilfe eingebaut und rufe dann die genannte Funktion auf.

Naja - sogar bei Microsoft gibt's was dazu - hier wird auch das Format der Hilfe-Dateien beschrieben.


Dialog abbrechen

Da ich noch keine Lösung gefunden habe, wie man in eVB 3.0 einen Cancel-Button neben den OK-Button einfügt, habe ich eine Idee zugetragen bekommen. Total simpel aber sehr effektiv:
Man füge (in einer globalen Funktion für alle Dialoge) ein Menue ein, welches die beiden Punkte beinhaltet. Dies geht dann z.B. mit folgender Befehlsfolge:

Public Function Init_Menu(frm As Form)
  Dim mnuDialog As MenuBarLib.MenuBarMenu
  Set mnuDialog = frm.MyMenuBar.Controls.AddMenu("Dialog", "mnuDialog")

  mnuDialog.Items.Add 1, "mnuOK", "Ok"
  mnuDialog.Items.Add 2, "mnuCancel", "Abbrechen"
End Function

Vorher muss in jedes der betreffenden Formulare ein Objekt vom Typ Menubar eingefügt werden (dieses muss erst über [Project][Components] in die Palette der Objekte eingefügt werden). Die Aktionen werden nun durch die Methode MenuClick des MenuBars bearbeitet.

(Dank an Jean-Louis)


ComboBoxes (Kombinationsfelder) mit eigenen Werten füllen

Als Access-Programmierer bin ich es gewohnt, Kombinationsfelder mit Tabelleninhalten oder Wertelisten zur Designphase zu füllen. In eVB ist dies so einfach nicht möglich. Ich habe eine Funktion erstellt, die aus dem Tag-Feld (durch ; getrennte) Wertelisten in die ComboBox als Auswahlelemente einfügt.

Public Function Set_List_Values(CB As Control)
' fügt die Einträge des ComboBox.Tag-Datenfeldes, die durch ';'
' getrennt sind in die Liste ein (Datenfeld endet mit ';' !!)
' (Vorgabe wird erstes Element, wenn 'CB.Text' leer und ungleich ';')

    If (CB.ListCount > 0) Then Exit Function ' nur bei erstem Öffnen des Forms
    Dim i As Integer
    Dim Text As String: Text = ""
    CB.Visible = False      ' beschleunigt Aktualisierung ?!! :-))
    For i = 1 To Len(CB.Tag)
        Select Case Mid(CB.Tag, i, 1)
            Case ";":
                CB.AddItem (Text)
                Text = ""
            Case Else:
                Text = Text & Mid(CB.Tag, i, 1)
        End Select
    Next i

    If ((Len(CB.Text) = 0) And (CB.Text <> ";")) Then CB.Text = CB.List(0)
    If (CB.Text = ";") Then CB.Text = ""
    CB.Visible = True
End Function

Eine zweite Funktion füllt das Kombinationsfeld mit den Inhalten einer einspaltigen Abfrage auf eine Tabelle: Doppelte Einträge in der Tabelle werden nicht in das Kombinationsfeld eingefügt ("mein eigenes

'GROUP BY'")

Public Function SetData(DB As String, ctl As Control,
                        table As String, feld_name As String)
' liest das Tabellen-Feld 'feld_name' aus Tabelle 'table' der Datenbank 'DB'
' und fügt nicht-Duplikate in Steuerelement 'CB' (ComboBox) ein
On Error Resume Next

    ctl.Visible = False
    Screen.MousePointer = 11 'Display hourglass
    Dim aktDB, aktTAB
    Dim newVal As String, i As Integer, contained As Boolean
    Set aktDB = CreateObject("ADOCE.Connection.3.0")
    aktDB.Open DB
    If Err Then MsgBox "1 - " & Err.Description
    Set aktTAB = CreateObject("ADOCE.Recordset.3.0")
    aktTAB.Open table, aktDB, adOpenKeyset, adLockOptimistic
    If Err Then MsgBox "2 - " & Err.Description
    If (aktTAB.RecordCount > 0) Then
        Do While Not aktTAB.EOF
            newVal = aktTAB.Fields(feld_name).Value
            If Err Then MsgBox "3 - " & Err.Description
            contained = False
            For i = 0 To ctl.ListCount - 1 ' überprüfe, ob Eintrag schon vorhanden
                If (newVal = ctl.List(i)) Then 
                    contained = True
                    Exit For
                End If
            Next i
            If Not contained Then ctl.AddItem newVal ' wenn nicht -> einfügen
            aktTAB.MoveNext
        Loop
    End If
    aktTAB.Close
    Set aktTAB = Nothing
    aktDB.Close
    Set aktDB = Nothing
    Screen.MousePointer = 0 'Hide hourglass
    ctl.Visible = True
End Function

Hilfreiche Sites, die auch noch weitere Hilfen, Programme etc. bieten


Drucken
letzte Änderung: 18.Sep 2005

rechte Spalte

Felicitas-Fernsehservice

Ein E-Mail-Dienst, der Ihnen täglich eine Auswahl des TV-Programms zusendet, das anhand einer individuellen Suchwortliste erstellt wurde.
Klicken Sie hier.