Programmieren in C und C++: Unterschied zwischen den Versionen

Aus GoPalWiki
Wechseln zu: Navigation, Suche
Zeile 1: Zeile 1:
[[Kategorie:Entwicklung]]
+
<br>
  
= Voraussetzungen =
+
= Voraussetzungen =
  
* Aus den [[Programmierumgebungen für C und C++]] sollte man sich eine herausgesucht und funktionsfähig installiert haben.
+
*Aus den [[Programmierumgebungen für C und C++]] sollte man sich eine herausgesucht und funktionsfähig installiert haben.  
* Dies hier ist kein grundlegender C/C++-Kurs. Man sollte also schon C/C++-Kenntnisse z.B. auf DesktopPC unter Windows, Linux oder sonstigen Betriesbssystemen gesammelt haben. Um diese Grundlagen zuerst auf dem DesktopPC zu erwerben, eignen sich folgende Tutorien:
+
*Dies hier ist kein grundlegender C/C++-Kurs. Man sollte also schon C/C++-Kenntnisse z.B. auf DesktopPC unter Windows, Linux oder sonstigen Betriesbssystemen gesammelt haben. Um diese Grundlagen zuerst auf dem DesktopPC zu erwerben, eignen sich folgende Tutorien:  
** http://www.cpp-tutor.de/
+
**http://www.cpp-tutor.de/  
** http://www.rzbt.haw-hamburg.de/dankert/ccontent.html
+
**http://www.rzbt.haw-hamburg.de/dankert/ccontent.html  
** http://ladedu.com/cpp/
+
**http://ladedu.com/cpp/  
** http://www2.its.strath.ac.uk/courses/c/ (in Englisch)
+
**http://www2.its.strath.ac.uk/courses/c/ (in Englisch)  
** http://www.aasted.org/GC/c-tut.php (in Englisch)
+
**http://www.aasted.org/GC/c-tut.php (in Englisch)  
** http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html (in Englisch)
+
**http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html (in Englisch)
  
= Ziel dieser Seite =
+
= Ziel dieser Seite =
  
* Unabhängig der gewählten Programmierumgebung die zur Verfügung stehende API verstehen und kleine Programme entwickeln, die auf dem GoPal lauffähig sind.
+
*Unabhängig der gewählten Programmierumgebung die zur Verfügung stehende API verstehen und kleine Programme entwickeln, die auf dem GoPal lauffähig sind.
  
= Rund um das 'Hallo Welt' =
+
= Rund um das 'Hallo Welt' =
  
Nach dem Motto ''Keep it simple!'' (Halte es einfach!) ist der erste Schritt eines Entwicklers häufig ein erstes eigenes Programm zu schreiben, um die Funktionsfähigkeit der Toolchain, der gesamten Entwicklungsumgebung, zu prüfen. Also muss ein dann selbstgeschriebenes Programm her, das ein Lebenszeichen von sich gibt. Das Lebenszeichen ist dann häufig die Ausgabe einer Zeichenkette ''Hallo Welt!'' auf dem Bildschirm des Target-Device (Zielgerät). In unserem Fall also soll solch eine Zeichenkette auf dem Bildschirm des GoPal-Gerätes erscheinen.
+
Nach dem Motto ''Keep it simple!'' (Halte es einfach!) ist der erste Schritt eines Entwicklers häufig ein erstes eigenes Programm zu schreiben, um die Funktionsfähigkeit der Toolchain, der gesamten Entwicklungsumgebung, zu prüfen. Also muss ein dann selbstgeschriebenes Programm her, das ein Lebenszeichen von sich gibt. Das Lebenszeichen ist dann häufig die Ausgabe einer Zeichenkette ''Hallo Welt!'' auf dem Bildschirm des Target-Device (Zielgerät). In unserem Fall also soll solch eine Zeichenkette auf dem Bildschirm des GoPal-Gerätes erscheinen.  
  
Ein solches Basis-Programm dann später um sinnvolle Funktionen zu erweitern, stellen sich Entwickler immer gaaaaaanz trivial vor. Ist es ja auch, wenn man weiß wie.
+
Ein solches Basis-Programm dann später um sinnvolle Funktionen zu erweitern, stellen sich Entwickler immer gaaaaaanz trivial vor. Ist es ja auch, wenn man weiß wie.  
  
Aber Schritt für Schritt... Bleiben wir vorerst beim ''Hallo Welt!''.
+
Aber Schritt für Schritt... Bleiben wir vorerst beim ''Hallo Welt!''.  
  
== Das geschenkte 'Hallo Welt' von Microsoft ==
+
== Das geschenkte 'Hallo Welt' von Microsoft ==
  
Je nach verwendeter Entwicklungsumgebung kommt bei dem ''Hello World''-Programm, das die Entwicklungsumgebung erzeugt, anderer Source Code heraus und andere Standardbibliotheken werden verwendet. Daher gehen wir hier nochmals auf die einzelnen Entwicklungsumgebungen ein.
+
Je nach verwendeter Entwicklungsumgebung kommt bei dem ''Hello World''-Programm, das die Entwicklungsumgebung erzeugt, anderer Source Code heraus und andere Standardbibliotheken werden verwendet. Daher gehen wir hier nochmals auf die einzelnen Entwicklungsumgebungen ein.  
  
=== Microsoft eMbedded Visual C++ ===
+
=== Microsoft eMbedded Visual C++ ===
  
Im Hilfe-Menu unter ''About...'' steht etwas von Version 4.00.1610.0. Ich beschreibe hier die englische Version. Ich benutze einfach das Standard SDK (Pocket PC2003), das bei der Installation dabei war. Unter der Verwendung eines anderen nachinstallierten SDKs sind ähnliche Schritte durchzuführen, jedoch mögen die Menu/Punkte dann natürlich ein wenig anders lauten.
+
Im Hilfe-Menu unter ''About...'' steht etwas von Version 4.00.1610.0. Ich beschreibe hier die englische Version. Ich benutze einfach das Standard SDK (Pocket PC2003), das bei der Installation dabei war. Unter der Verwendung eines anderen nachinstallierten SDKs sind ähnliche Schritte durchzuführen, jedoch mögen die Menu/Punkte dann natürlich ein wenig anders lauten.  
  
# Im ''File''-Menu unter ''New'' wählt man da Tab ''Projects'' aus.
+
#Im ''File''-Menu unter ''New'' wählt man da Tab ''Projects'' aus.  
# Wir erstellen eine ''WCE Pocket PC 2003 Application'' mit '''Project name''' ''HelloWorld''. Dabei dürfte die Standardeinstellung unter '''Location''' zu ''C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\HelloWorld'' erweitert werden.
+
#Wir erstellen eine ''WCE Pocket PC 2003 Application'' mit '''Project name''' ''HelloWorld''. Dabei dürfte die Standardeinstellung unter '''Location''' zu ''C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\HelloWorld'' erweitert werden.  
# Ein neuer Arbeitsbereich wird mittels ausgewähltem ''Create new workspace'' angelegt und als '''CPU''' wählen wir mindestens, dass ''Win32 (WCE ARMV4)'' unterstützt wird.
+
#Ein neuer Arbeitsbereich wird mittels ausgewähltem ''Create new workspace'' angelegt und als '''CPU''' wählen wir mindestens, dass ''Win32 (WCE ARMV4)'' unterstützt wird.
  
Streng genommen handelt es sich hier nicht um eine ausgewählte CPU, sondern um ein Instruction Set. Die CPU muss dieses Instruction Set beherrschen, damit das spätere Kompilat darauf laufen kann.
+
Streng genommen handelt es sich hier nicht um eine ausgewählte CPU, sondern um ein Instruction Set. Die CPU muss dieses Instruction Set beherrschen, damit das spätere Kompilat darauf laufen kann.  
  
Abschließend hier ''OK'' auswählen.
+
Abschließend hier ''OK'' auswählen.  
  
Jetzt nochmals ''A typical Hello World application'' auswählen und noch mit ''Finish'' bestätigen. Und nochmal ''OK''...
+
Jetzt nochmals ''A typical Hello World application'' auswählen und noch mit ''Finish'' bestätigen. Und nochmal ''OK''...  
  
Im ''FileView'' den Baum expandieren und unter ''Source Files'' die Datei ''HelloWorld.cpp'' öffnen.
+
Im ''FileView'' den Baum expandieren und unter ''Source Files'' die Datei ''HelloWorld.cpp'' öffnen.  
  
Und schon sehen wir in der Datei, dass die ''Aygshell'' verwendet werden soll.
+
Und schon sehen wir in der Datei, dass die ''Aygshell'' verwendet werden soll.  
  
Wurde als CPU auch der Emulator ausgewählt, so kann man durchaus mal testen, dass im Emulator das Programm funktioniert. Oben nicht die Auswahl des Emulators vergessen!
+
Wurde als CPU auch der Emulator ausgewählt, so kann man durchaus mal testen, dass im Emulator das Programm funktioniert. Oben nicht die Auswahl des Emulators vergessen!  
  
 
----
 
----
  
{||
+
{| class="FCK__ShowTableBorders"
|[[Bild:HelloWorld_Emulator.jpg|Das Hello World im Emulator mit Aygshell.dll]]
 
|[[Bild:HelloWorld_Aygshell_SamsungOmnia_i900_1.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles.]]
 
 
|-
 
|-
|''Das Hello World im Emulator mit Aygshell.dll''
+
| [[Image:HelloWorld Emulator.jpg|Das Hello World im Emulator mit Aygshell.dll]]
|''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles''
+
| [[Image:HelloWorld Aygshell SamsungOmnia i900 1.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles.]]
 
|-
 
|-
|[[Bild:HelloWorld_Aygshell_SamsungOmnia_i900_2.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode...]]
+
| ''Das Hello World im Emulator mit Aygshell.dll''
|[[Bild:HelloWorld_noAygshell_E3210M10.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10]]
+
| ''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles''
 
|-
 
|-
|''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode...''
+
| [[Image:HelloWorld Aygshell SamsungOmnia i900 2.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode...]]
|''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10''
+
| [[Image:HelloWorld noAygshell E3210M10.jpg|Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10]]
 +
|-
 +
| ''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode...''  
 +
| ''Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10''
 
|}
 
|}
  
 
----
 
----
  
Man kann es auch, so wie es ist, für das ARMV4 Instruction Set kompilieren und wenn man einen PDA oder Windows Mobile Phone besitzt, die daraus erhaltene HelloWorld.exe mal laufen lassen. Im Visual Studio oben nicht die Auswahl von ''Win32 (WCE ARMV4) Release'' vergessen. Übertragen des HelloWorld.exe mehr oder weniger umständlich per direktem Deploy auf das Device, per Active Sync oder sonstwie SD card und dann aufs Target Device.
+
Man kann es auch, so wie es ist, für das ARMV4 Instruction Set kompilieren und wenn man einen PDA oder Windows Mobile Phone besitzt, die daraus erhaltene HelloWorld.exe mal laufen lassen. Im Visual Studio oben nicht die Auswahl von ''Win32 (WCE ARMV4) Release'' vergessen. Übertragen des HelloWorld.exe mehr oder weniger umständlich per direktem Deploy auf das Device, per Active Sync oder sonstwie SD card und dann aufs Target Device.  
  
Probiert man dieses HelloWorld.exe nach dem Kompilieren auf einem unmodifizierten GoPal-Gerät aus, kommt nur eine Fehlermeldung, dass irgendwelche Dateien oder Libraries nicht gefunden werden konnten. Und wir stecken mitten im Problem der reduzierten [[Windows Embedded#Lizenz|Core Runtime License im Vergleich zur Professional Runtime License]] oder des reduzierten API sets. Irreführend ist hier die Meldung, dass das ''HelloWorld'' selbst nicht gefunden werden kann. Wer sich mal wieder die Fehlermeldung ausgedacht hat? :-)
+
Probiert man dieses HelloWorld.exe nach dem Kompilieren auf einem unmodifizierten GoPal-Gerät aus, kommt nur eine Fehlermeldung, dass irgendwelche Dateien oder Libraries nicht gefunden werden konnten. Und wir stecken mitten im Problem der reduzierten [[Windows Embedded#Lizenz|Core Runtime License im Vergleich zur Professional Runtime License]] oder des reduzierten API sets. Irreführend ist hier die Meldung, dass das ''HelloWorld'' selbst nicht gefunden werden kann. Wer sich mal wieder die Fehlermeldung ausgedacht hat?&nbsp;:-)  
  
Und da wir nicht mit der [[Windows Embedded#Dynamic Linked Libraries nachinstallieren|Aygshell rumschummeln]] wollen, kommt jetzt die Frage auf, wie wir doch zu einem ''HelloWorld.exe'' kommen, das läuft.
+
Und da wir nicht mit der [[Windows Embedded#Dynamic_Linked_Libraries_nachinstallieren|Aygshell rumschummeln]] wollen, kommt jetzt die Frage auf, wie wir doch zu einem ''HelloWorld.exe'' kommen, das läuft.  
  
Was muss ich also ändern, damit es auf dem GoPal-Gerät auch ohne Microsoft Aygshell.dll und ohne DLLs von Dritten läuft?
+
Was muss ich also ändern, damit es auf dem GoPal-Gerät auch ohne Microsoft Aygshell.dll und ohne DLLs von Dritten läuft?  
  
So und los geht's...
+
So und los geht's...  
  
 
----
 
----
  
{|
+
{| class="FCK__ShowTableBorders"
|[[Bild:GoPal HelloWorld wo aygshell.jpg|Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10.]]
 
 
|-
 
|-
|''Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10''
+
| [[Image:GoPal HelloWorld wo aygshell.jpg|Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10.]]
 +
|-
 +
| ''Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10''
 
|}
 
|}
  
 
----
 
----
  
Aus dem HelloWorld.cpp sind die folgenden Zeilen auszukommentieren oder zu löschen:
+
Aus dem HelloWorld.cpp sind die folgenden Zeilen auszukommentieren oder zu löschen:  
  
  // #include <aygshell.h>
+
  // #include &lt;aygshell.h&gt;
 
  // HWND g_hwndCB; // The command bar handle
 
  // HWND g_hwndCB; // The command bar handle
 
  // static SHACTIVATEINFO s_sai;
 
  // static SHACTIVATEINFO s_sai;
Zeile 102: Zeile 104:
 
         RECT rcMenuBar;
 
         RECT rcMenuBar;
 
  &nbsp;
 
  &nbsp;
         GetWindowRect(hWnd, &rc);
+
         GetWindowRect(hWnd, &amp;rc);
         GetWindowRect(g_hwndCB, &rcMenuBar);
+
         GetWindowRect(g_hwndCB, &amp;rcMenuBar);
 
         rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
 
         rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
 
  &nbsp;
 
  &nbsp;
Zeile 117: Zeile 119:
 
  /*        g_hwndCB = CreateRpCommandBar(hWnd);
 
  /*        g_hwndCB = CreateRpCommandBar(hWnd);
 
             // Initialize the shell activate info structure
 
             // Initialize the shell activate info structure
             memset (&s_sai, 0, sizeof (s_sai));
+
             memset (&amp;s_sai, 0, sizeof (s_sai));
 
             s_sai.cbSize = sizeof (s_sai);
 
             s_sai.cbSize = sizeof (s_sai);
 
  */
 
  */
  
 
  // CommandBar_Destroy(g_hwndCB);
 
  // CommandBar_Destroy(g_hwndCB);
  // SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
+
  // SHHandleWMActivate(hWnd, wParam, lParam, &amp;s_sai, FALSE);
  // SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
+
  // SHHandleWMSettingChange(hWnd, wParam, lParam, &amp;s_sai);
  
 
  /* HWND CreateRpCommandBar(HWND hwnd)
 
  /* HWND CreateRpCommandBar(HWND hwnd)
Zeile 129: Zeile 131:
 
         SHMENUBARINFO mbi;
 
         SHMENUBARINFO mbi;
 
  &nbsp;
 
  &nbsp;
         memset(&mbi, 0, sizeof(SHMENUBARINFO));
+
         memset(&amp;mbi, 0, sizeof(SHMENUBARINFO));
 
         mbi.cbSize    = sizeof(SHMENUBARINFO);
 
         mbi.cbSize    = sizeof(SHMENUBARINFO);
 
         mbi.hwndParent = hwnd;
 
         mbi.hwndParent = hwnd;
Zeile 137: Zeile 139:
 
         mbi.cBmpImages = 0;
 
         mbi.cBmpImages = 0;
 
  &nbsp;
 
  &nbsp;
         if (!SHCreateMenuBar(&mbi))  
+
         if (!SHCreateMenuBar(&amp;mbi))  
 
                 return NULL;
 
                 return NULL;
 
  &nbsp;
 
  &nbsp;
Zeile 155: Zeile 157:
 
                         shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
 
                         shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
 
                         shidi.hDlg = hDlg;
 
                         shidi.hDlg = hDlg;
                         SHInitDialog(&shidi);
+
                         SHInitDialog(&amp;shidi);
 
                         return TRUE;  
 
                         return TRUE;  
 
  &nbsp;
 
  &nbsp;
Zeile 170: Zeile 172:
 
  */
 
  */
  
Um die Möglichkeit zu schaffen, das Programm auch ohne ''OK''-Button oder schließen des Fensters zu verlassen, fügen wir noch eine Zeile ein. Unser ''Hello World'' läuft nämlich jetzt im Vollbildmodus ohne Fensterdekoration.
+
Um die Möglichkeit zu schaffen, das Programm auch ohne ''OK''-Button oder schließen des Fensters zu verlassen, fügen wir noch eine Zeile ein. Unser ''Hello World'' läuft nämlich jetzt im Vollbildmodus ohne Fensterdekoration.  
  
Vor der Zeile
+
Vor der Zeile  
  
 
  case WM_DESTROY:
 
  case WM_DESTROY:
  
fügen wir noch folgendes ein
+
fügen wir noch folgendes ein  
  
 
  case WM_LBUTTONDOWN:
 
  case WM_LBUTTONDOWN:
  
Das sieht also dann in etwa so aus:
+
Das sieht also dann in etwa so aus:  
  
 
  case WM_LBUTTONDOWN:
 
  case WM_LBUTTONDOWN:
Zeile 188: Zeile 190:
 
     break;
 
     break;
  
Das CommandBar_Destroy hatten wir vorher gerade frisch auskommentiert.
+
Das CommandBar_Destroy hatten wir vorher gerade frisch auskommentiert.  
  
Der WM_LBUTTONDOWN sorgt dafür, dass jetzt beim Berühren des Touchscreen an beliebiger Position das ''Hello World'' beendet wird.
+
Der WM_LBUTTONDOWN sorgt dafür, dass jetzt beim Berühren des Touchscreen an beliebiger Position das ''Hello World'' beendet wird.  
  
Und siehe da: Die Aygshell wird nicht benötigt. Die Befehle, Konstanten, etc., die in unserem Beispiel mit SH... beginnen, sind diejenigen, die in der Aygshell enthalten sind. Daher wurden solche Absätze und Zeilen, die solche Aygshell Anteile besaßen, einfach wie oben beschrieben entfernt.
+
Und siehe da: Die Aygshell wird nicht benötigt. Die Befehle, Konstanten, etc., die in unserem Beispiel mit SH... beginnen, sind diejenigen, die in der Aygshell enthalten sind. Daher wurden solche Absätze und Zeilen, die solche Aygshell Anteile besaßen, einfach wie oben beschrieben entfernt.  
  
Das so erhaltene Programm kann als Basis für die weiteren Eigenentwicklungen verwendet werden.
+
Das so erhaltene Programm kann als Basis für die weiteren Eigenentwicklungen verwendet werden.  
  
Viel Spaß beim Ausprobieren...
+
Viel Spaß beim Ausprobieren...  
  
Obwohl hier Microsoft verwendet wurde: Entwicklungsumgebung etc. war kostenlos! Es läuft und man kann eigentlich alles daraus bauen, wenn man noch rausbekommt wie... GoPal-gerätespezifische Fragen bitte an [[Fragen zur Programmierung]]
+
Obwohl hier Microsoft verwendet wurde: Entwicklungsumgebung etc. war kostenlos! Es läuft und man kann eigentlich alles daraus bauen, wenn man noch rausbekommt wie... GoPal-gerätespezifische Fragen bitte an [[Fragen zur Programmierung]]  
  
So böse ist Microsoft zumindest hier also gar nicht: Hallo non-Microsoftler! Willkommen auf der dunklen Seite... Come to the dark side... We have cookies! :-)
+
So böse ist Microsoft zumindest hier also gar nicht: Hallo non-Microsoftler! Willkommen auf der dunklen Seite... Come to the dark side... We have cookies!&nbsp;:-)  
  
=== Microsoft Visual Studio 2005 mit Smart Devices ===
+
=== Microsoft Visual Studio 2005 mit Smart Devices ===
  
Visual Studio 2005 bietet natürlich eine integrierte Entwicklungsumgebung (IDE), die deutlich moderner und komfortabler als das eMbedded Visual C++ ist. Als echter vi, sed, awk und ed User ist das zwar Nebensache, aber wir wollen ja auch den nicht Gurus oder gerade diesen Gurus auch ein wenig Komfort zuteil werden lassen.
+
Visual Studio 2005 bietet natürlich eine integrierte Entwicklungsumgebung (IDE), die deutlich moderner und komfortabler als das eMbedded Visual C++ ist. Als echter vi, sed, awk und ed User ist das zwar Nebensache, aber wir wollen ja auch den nicht Gurus oder gerade diesen Gurus auch ein wenig Komfort zuteil werden lassen.  
  
Gehen wir von Standard ''Hello World'' des Visual Studio 2005 aus und versuchen es auf den abgespeckten GoPal-Geräten zum Laufen zu überreden, so sind noch ein paar andere Hürden zu nehmen. Auch wenn manches ähnlich aussieht...
+
Gehen wir von Standard ''Hello World'' des Visual Studio 2005 aus und versuchen es auf den abgespeckten GoPal-Geräten zum Laufen zu überreden, so sind noch ein paar andere Hürden zu nehmen. Auch wenn manches ähnlich aussieht...  
  
Also nochmal das Ganze:
+
Also nochmal das Ganze:  
  
== 'Hallo Welt' von Anfang an ==
+
== 'Hallo Welt' von Anfang an ==
  
Von einem leeren Zustand etwas neu zu entwickeln wird auch als Entwicklung ''from scratch'' bezeichnet.
+
Von einem leeren Zustand etwas neu zu entwickeln wird auch als Entwicklung ''from scratch'' bezeichnet.  
  
=== In C++ mit Hilfe der WTL ===
+
=== In C++ mit Hilfe der WTL ===
  
Der folgende Ansatz funktioniert in allen Entwicklungsumgebungen gleichermaßen, da man ja überall von einem ''leeren Editor'' ausgehen kann. Die Menü-Bezeichnungen kommen von der englischen Version eines Visual Studio 2005 und können in anderen Entwicklungsumgebungen variieren.
+
Der folgende Ansatz funktioniert in allen Entwicklungsumgebungen gleichermaßen, da man ja überall von einem ''leeren Editor'' ausgehen kann. Die Menü-Bezeichnungen kommen von der englischen Version eines Visual Studio 2005 und können in anderen Entwicklungsumgebungen variieren.  
  
In diesem Abschnitt wird die [http://sourceforge.net/projects/wtl/ WTL] in der Version 8.0 eingesetzt.
+
In diesem Abschnitt wird die [http://sourceforge.net/projects/wtl/ WTL] in der Version 8.0 eingesetzt.  
  
Die Windows Template Library (WTL) ist eine C++ library für die Entwicklung von Windows-Applikationen und Benutzerschnittstellen-Komponenten. Diese Bibliothek erweitert die Microsoft eigene ATL (Active Template Library) und stellt eine Menge von Klassen zur Verfügung wie Kontroll-Elemente, Dialoge, Fensterklassen, GDI Objekte, und sogar noch mehr.
+
Die Windows Template Library (WTL) ist eine C++ library für die Entwicklung von Windows-Applikationen und Benutzerschnittstellen-Komponenten. Diese Bibliothek erweitert die Microsoft eigene ATL (Active Template Library) und stellt eine Menge von Klassen zur Verfügung wie Kontroll-Elemente, Dialoge, Fensterklassen, GDI Objekte, und sogar noch mehr.  
  
 
Die WTL ist Open Source Software und muss natürlich erst mal installiert werden.  
 
Die WTL ist Open Source Software und muss natürlich erst mal installiert werden.  
  
Voraussetzung ist auch hier ein installiertes [http://www.microsoft.com/downloads/details.aspx?familyid=FA1A3D66-3F61-4DDC-9510-AE450E2318C3&displaylang=en Standard SDK für Windows CE 5.0].
+
Voraussetzung ist auch hier ein installiertes [http://www.microsoft.com/downloads/details.aspx?familyid=FA1A3D66-3F61-4DDC-9510-AE450E2318C3&displaylang=en Standard SDK für Windows CE 5.0].  
  
File -> New -> Project -> Visual C++ -> Smart Device -> Win32 Smart Device Project
+
File -&gt; New -&gt; Project -&gt; Visual C++ -&gt; Smart Device -&gt; Win32 Smart Device Project  
  
Name eingeben (z.B. HelloWelt), Location auswählen (z.B. c:\proj ), danach OK klicken.
+
Name eingeben (z.B. HelloWelt), Location auswählen (z.B. c:\proj ), danach OK klicken.  
  
Es erscheint nun der Win32 Smart Device Project Wizard bei dem folgende Einstellungen vorgenommen werden müssen:
+
Es erscheint nun der Win32 Smart Device Project Wizard bei dem folgende Einstellungen vorgenommen werden müssen:  
* Platforms -> Pocket PC 2003 entfernen, STANDARDSDK_500 hinzufügen
+
 
* Application Settings -> Application type: Windows application auswählen
+
*Platforms -&gt; Pocket PC 2003 entfernen, STANDARDSDK_500 hinzufügen  
* Application Settings -> Additional options: Empty project aktivieren
+
*Application Settings -&gt; Application type: Windows application auswählen  
 +
*Application Settings -&gt; Additional options: Empty project aktivieren
  
 
Danach Finish klicken.  
 
Danach Finish klicken.  
  
Wir haben nun ein geeignetes leeres Projekt.
+
Wir haben nun ein geeignetes leeres Projekt.  
  
Zum sinnvollen Arbeiten brauchen wir allerdings eine C++ Datei:
+
Zum sinnvollen Arbeiten brauchen wir allerdings eine C++ Datei:  
  
Im Solution-Explorer, rechter Mausclick auf Source-Files -> Add -> New Item -> Code -> C++ File (.cpp)
+
Im Solution-Explorer, rechter Mausclick auf Source-Files -&gt; Add -&gt; New Item -&gt; Code -&gt; C++ File (.cpp)  
  
Name: HalloWelt.cpp eintragen und Add klicken.
+
Name: HalloWelt.cpp eintragen und Add klicken.  
  
Include und library Pfade für [http://sourceforge.net/projects/wtl/ WTL 8.0] entweder global oder für das Project setzen (beides z.B. c:\wtl80\include) und folgenden Code in HalloWelt.cpp einfügen.
+
Include und library Pfade für [http://sourceforge.net/projects/wtl/ WTL 8.0] entweder global oder für das Project setzen (beides z.B. c:\wtl80\include) und folgenden Code in HalloWelt.cpp einfügen.  
  
  #include <atlbase.h>
+
  #include &lt;atlbase.h&gt;
  #include <atlapp.h>
+
  #include &lt;atlapp.h&gt;
 
  &nbsp;
 
  &nbsp;
 
  extern CAppModule _Module;  
 
  extern CAppModule _Module;  
 
  &nbsp;
 
  &nbsp;
  #include <atlgdi.h>
+
  #include &lt;atlgdi.h&gt;
  #include <atlmisc.h>
+
  #include &lt;atlmisc.h&gt;
 
  &nbsp;
 
  &nbsp;
 
  CAppModule _Module;  
 
  CAppModule _Module;  
 
  &nbsp;
 
  &nbsp;
  class CMainWindow : public CWindowImpl<CMainWindow , CWindow , CWinTraits<WS_VISIBLE> >
+
  class CMainWindow&nbsp;: public CWindowImpl&lt;CMainWindow , CWindow , CWinTraits&lt;WS_VISIBLE&gt; &gt;
 
  {  
 
  {  
 
         // Message map is used to map Windows messages to handlers.  
 
         // Message map is used to map Windows messages to handlers.  
Zeile 266: Zeile 269:
 
         END_MSG_MAP()  
 
         END_MSG_MAP()  
 
  &nbsp;
 
  &nbsp;
         LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)  
+
         LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&amp; bHandled)  
 
         {  
 
         {  
 
                 CPaintDC dc(m_hWnd);  
 
                 CPaintDC dc(m_hWnd);  
Zeile 275: Zeile 278:
 
         }  
 
         }  
 
  &nbsp;
 
  &nbsp;
         LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)  
+
         LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&amp; bHandled)  
 
         {  
 
         {  
 
                 PostMessage(WM_CLOSE);  
 
                 PostMessage(WM_CLOSE);  
Zeile 281: Zeile 284:
 
         }  
 
         }  
 
  &nbsp;
 
  &nbsp;
         LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)  
+
         LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&amp; bHandled)  
 
         {  
 
         {  
 
                 PostQuitMessage(0);  
 
                 PostQuitMessage(0);  
Zeile 303: Zeile 306:
 
  }
 
  }
  
Und damit geht es mit der WTL...
+
Und damit geht es mit der WTL...  
 
 
 
 
  
 +
<br>
  
 +
<br>
  
 +
<br>{{adsense}}
  
{{adsense}}
+
[[Category:Entwicklung]]

Version vom 14. Februar 2010, 02:44 Uhr


Voraussetzungen

Ziel dieser Seite

  • Unabhängig der gewählten Programmierumgebung die zur Verfügung stehende API verstehen und kleine Programme entwickeln, die auf dem GoPal lauffähig sind.

Rund um das 'Hallo Welt'

Nach dem Motto Keep it simple! (Halte es einfach!) ist der erste Schritt eines Entwicklers häufig ein erstes eigenes Programm zu schreiben, um die Funktionsfähigkeit der Toolchain, der gesamten Entwicklungsumgebung, zu prüfen. Also muss ein dann selbstgeschriebenes Programm her, das ein Lebenszeichen von sich gibt. Das Lebenszeichen ist dann häufig die Ausgabe einer Zeichenkette Hallo Welt! auf dem Bildschirm des Target-Device (Zielgerät). In unserem Fall also soll solch eine Zeichenkette auf dem Bildschirm des GoPal-Gerätes erscheinen.

Ein solches Basis-Programm dann später um sinnvolle Funktionen zu erweitern, stellen sich Entwickler immer gaaaaaanz trivial vor. Ist es ja auch, wenn man weiß wie.

Aber Schritt für Schritt... Bleiben wir vorerst beim Hallo Welt!.

Das geschenkte 'Hallo Welt' von Microsoft

Je nach verwendeter Entwicklungsumgebung kommt bei dem Hello World-Programm, das die Entwicklungsumgebung erzeugt, anderer Source Code heraus und andere Standardbibliotheken werden verwendet. Daher gehen wir hier nochmals auf die einzelnen Entwicklungsumgebungen ein.

Microsoft eMbedded Visual C++

Im Hilfe-Menu unter About... steht etwas von Version 4.00.1610.0. Ich beschreibe hier die englische Version. Ich benutze einfach das Standard SDK (Pocket PC2003), das bei der Installation dabei war. Unter der Verwendung eines anderen nachinstallierten SDKs sind ähnliche Schritte durchzuführen, jedoch mögen die Menu/Punkte dann natürlich ein wenig anders lauten.

  1. Im File-Menu unter New wählt man da Tab Projects aus.
  2. Wir erstellen eine WCE Pocket PC 2003 Application mit Project name HelloWorld. Dabei dürfte die Standardeinstellung unter Location zu C:\Program Files\Microsoft eMbedded C++ 4.0\Common\EVC\MyProjects\HelloWorld erweitert werden.
  3. Ein neuer Arbeitsbereich wird mittels ausgewähltem Create new workspace angelegt und als CPU wählen wir mindestens, dass Win32 (WCE ARMV4) unterstützt wird.

Streng genommen handelt es sich hier nicht um eine ausgewählte CPU, sondern um ein Instruction Set. Die CPU muss dieses Instruction Set beherrschen, damit das spätere Kompilat darauf laufen kann.

Abschließend hier OK auswählen.

Jetzt nochmals A typical Hello World application auswählen und noch mit Finish bestätigen. Und nochmal OK...

Im FileView den Baum expandieren und unter Source Files die Datei HelloWorld.cpp öffnen.

Und schon sehen wir in der Datei, dass die Aygshell verwendet werden soll.

Wurde als CPU auch der Emulator ausgewählt, so kann man durchaus mal testen, dass im Emulator das Programm funktioniert. Oben nicht die Auswahl des Emulators vergessen!


Das Hello World im Emulator mit Aygshell.dll Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles.
Das Hello World im Emulator mit Aygshell.dll Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles
Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode... Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10
Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Auf dem Samsung Omnia i900 läuft alles. Auch in Landscape mode... Die gleichen Sourcen unter ARMV4 instruction set kompiliert. Mindestens eine Aygshell.dll fehlt auf dem GoPal E3210 M10

Man kann es auch, so wie es ist, für das ARMV4 Instruction Set kompilieren und wenn man einen PDA oder Windows Mobile Phone besitzt, die daraus erhaltene HelloWorld.exe mal laufen lassen. Im Visual Studio oben nicht die Auswahl von Win32 (WCE ARMV4) Release vergessen. Übertragen des HelloWorld.exe mehr oder weniger umständlich per direktem Deploy auf das Device, per Active Sync oder sonstwie SD card und dann aufs Target Device.

Probiert man dieses HelloWorld.exe nach dem Kompilieren auf einem unmodifizierten GoPal-Gerät aus, kommt nur eine Fehlermeldung, dass irgendwelche Dateien oder Libraries nicht gefunden werden konnten. Und wir stecken mitten im Problem der reduzierten Core Runtime License im Vergleich zur Professional Runtime License oder des reduzierten API sets. Irreführend ist hier die Meldung, dass das HelloWorld selbst nicht gefunden werden kann. Wer sich mal wieder die Fehlermeldung ausgedacht hat? :-)

Und da wir nicht mit der Aygshell rumschummeln wollen, kommt jetzt die Frage auf, wie wir doch zu einem HelloWorld.exe kommen, das läuft.

Was muss ich also ändern, damit es auf dem GoPal-Gerät auch ohne Microsoft Aygshell.dll und ohne DLLs von Dritten läuft?

So und los geht's...


Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10.
Angepasstes HelloWorld.exe, so dass Aygshell nicht verwendet wird auf E3210 M10

Aus dem HelloWorld.cpp sind die folgenden Zeilen auszukommentieren oder zu löschen:

// #include <aygshell.h>
// HWND				g_hwndCB;					// The command bar handle
// static SHACTIVATEINFO s_sai;
// LRESULT CALLBACK	About			(HWND, UINT, WPARAM, LPARAM);
// HWND				CreateRpCommandBar(HWND);
//When the main window is created using CW_USEDEFAULT the height of the menubar (if one
// is created is not taken into account). So we resize the window after creating it
// if a menubar is present
/*	if (g_hwndCB)
   {
       RECT rc;
       RECT rcMenuBar;
 
       GetWindowRect(hWnd, &rc);
       GetWindowRect(g_hwndCB, &rcMenuBar);
       rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
 
       MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
   }
*/
/*    case IDM_HELP_ABOUT:
          DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
          break;
*/
/*         g_hwndCB = CreateRpCommandBar(hWnd);
           // Initialize the shell activate info structure
           memset (&s_sai, 0, sizeof (s_sai));
           s_sai.cbSize = sizeof (s_sai);
*/
//			CommandBar_Destroy(g_hwndCB);
//			SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
//			SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
/* HWND CreateRpCommandBar(HWND hwnd)
{
       SHMENUBARINFO mbi;
 
       memset(&mbi, 0, sizeof(SHMENUBARINFO));
       mbi.cbSize     = sizeof(SHMENUBARINFO);
       mbi.hwndParent = hwnd;
       mbi.nToolBarId = IDM_MENU;
       mbi.hInstRes   = g_hInst;
       mbi.nBmpId     = 0;
       mbi.cBmpImages = 0;
 
       if (!SHCreateMenuBar(&mbi)) 
               return NULL;
 
       return mbi.hwndMB;
}
// Mesage handler for the About box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
       SHINITDLGINFO shidi;
 
       switch (message)
       {
                case WM_INITDIALOG:
                       // Create a Done button and size it.  
                       shidi.dwMask = SHIDIM_FLAGS;
                       shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
                       shidi.hDlg = hDlg;
                       SHInitDialog(&shidi);
                       return TRUE; 
 
                case WM_COMMAND:
                       if (LOWORD(wParam) == IDOK)
                       {
                               EndDialog(hDlg, LOWORD(wParam));
                               return TRUE;
                       }
                       break;
       }
   return FALSE;
}
*/

Um die Möglichkeit zu schaffen, das Programm auch ohne OK-Button oder schließen des Fensters zu verlassen, fügen wir noch eine Zeile ein. Unser Hello World läuft nämlich jetzt im Vollbildmodus ohne Fensterdekoration.

Vor der Zeile

case WM_DESTROY:

fügen wir noch folgendes ein

case WM_LBUTTONDOWN:

Das sieht also dann in etwa so aus:

case WM_LBUTTONDOWN:
case WM_DESTROY:
// CommandBar_Destroy(g_hwndCB);
   PostQuitMessage(0);
   break;

Das CommandBar_Destroy hatten wir vorher gerade frisch auskommentiert.

Der WM_LBUTTONDOWN sorgt dafür, dass jetzt beim Berühren des Touchscreen an beliebiger Position das Hello World beendet wird.

Und siehe da: Die Aygshell wird nicht benötigt. Die Befehle, Konstanten, etc., die in unserem Beispiel mit SH... beginnen, sind diejenigen, die in der Aygshell enthalten sind. Daher wurden solche Absätze und Zeilen, die solche Aygshell Anteile besaßen, einfach wie oben beschrieben entfernt.

Das so erhaltene Programm kann als Basis für die weiteren Eigenentwicklungen verwendet werden.

Viel Spaß beim Ausprobieren...

Obwohl hier Microsoft verwendet wurde: Entwicklungsumgebung etc. war kostenlos! Es läuft und man kann eigentlich alles daraus bauen, wenn man noch rausbekommt wie... GoPal-gerätespezifische Fragen bitte an Fragen zur Programmierung

So böse ist Microsoft zumindest hier also gar nicht: Hallo non-Microsoftler! Willkommen auf der dunklen Seite... Come to the dark side... We have cookies! :-)

Microsoft Visual Studio 2005 mit Smart Devices

Visual Studio 2005 bietet natürlich eine integrierte Entwicklungsumgebung (IDE), die deutlich moderner und komfortabler als das eMbedded Visual C++ ist. Als echter vi, sed, awk und ed User ist das zwar Nebensache, aber wir wollen ja auch den nicht Gurus oder gerade diesen Gurus auch ein wenig Komfort zuteil werden lassen.

Gehen wir von Standard Hello World des Visual Studio 2005 aus und versuchen es auf den abgespeckten GoPal-Geräten zum Laufen zu überreden, so sind noch ein paar andere Hürden zu nehmen. Auch wenn manches ähnlich aussieht...

Also nochmal das Ganze:

'Hallo Welt' von Anfang an

Von einem leeren Zustand etwas neu zu entwickeln wird auch als Entwicklung from scratch bezeichnet.

In C++ mit Hilfe der WTL

Der folgende Ansatz funktioniert in allen Entwicklungsumgebungen gleichermaßen, da man ja überall von einem leeren Editor ausgehen kann. Die Menü-Bezeichnungen kommen von der englischen Version eines Visual Studio 2005 und können in anderen Entwicklungsumgebungen variieren.

In diesem Abschnitt wird die WTL in der Version 8.0 eingesetzt.

Die Windows Template Library (WTL) ist eine C++ library für die Entwicklung von Windows-Applikationen und Benutzerschnittstellen-Komponenten. Diese Bibliothek erweitert die Microsoft eigene ATL (Active Template Library) und stellt eine Menge von Klassen zur Verfügung wie Kontroll-Elemente, Dialoge, Fensterklassen, GDI Objekte, und sogar noch mehr.

Die WTL ist Open Source Software und muss natürlich erst mal installiert werden.

Voraussetzung ist auch hier ein installiertes Standard SDK für Windows CE 5.0.

File -> New -> Project -> Visual C++ -> Smart Device -> Win32 Smart Device Project

Name eingeben (z.B. HelloWelt), Location auswählen (z.B. c:\proj ), danach OK klicken.

Es erscheint nun der Win32 Smart Device Project Wizard bei dem folgende Einstellungen vorgenommen werden müssen:

  • Platforms -> Pocket PC 2003 entfernen, STANDARDSDK_500 hinzufügen
  • Application Settings -> Application type: Windows application auswählen
  • Application Settings -> Additional options: Empty project aktivieren

Danach Finish klicken.

Wir haben nun ein geeignetes leeres Projekt.

Zum sinnvollen Arbeiten brauchen wir allerdings eine C++ Datei:

Im Solution-Explorer, rechter Mausclick auf Source-Files -> Add -> New Item -> Code -> C++ File (.cpp)

Name: HalloWelt.cpp eintragen und Add klicken.

Include und library Pfade für WTL 8.0 entweder global oder für das Project setzen (beides z.B. c:\wtl80\include) und folgenden Code in HalloWelt.cpp einfügen.

#include <atlbase.h>
#include <atlapp.h> 
 
extern CAppModule _Module; 
 
#include <atlgdi.h> 
#include <atlmisc.h> 
 
CAppModule _Module; 
 
class CMainWindow : public CWindowImpl<CMainWindow , CWindow , CWinTraits<WS_VISIBLE> > 
{ 
       // Message map is used to map Windows messages to handlers. 
       BEGIN_MSG_MAP(CMainWindow) 
               MESSAGE_HANDLER(WM_PAINT, OnPaint)
               MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
               MESSAGE_HANDLER(WM_DESTROY, OnDestroy) 
       END_MSG_MAP() 
 
       LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
       { 
               CPaintDC dc(m_hWnd); 
               CRect rect; 
               GetClientRect(rect); 
               dc.DrawText(_T("Hello, Wtl!"), -1, rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER); 
               return 0; 
       } 
 
       LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
       { 
               PostMessage(WM_CLOSE); 
               return 0; 
       } 
 
       LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
       { 
               PostQuitMessage(0); 
               return 0; 
       } 
}; 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int) { 
       // Init module. 
       _Module.Init(0, hInstance, 0); 
       // Create main window. 
       CMainWindow wnd; 
       wnd.Create(NULL, CWindow::rcDefault, _T("Hello, Welt!")); 
       wnd.ShowWindow(SW_SHOW); 
       // Run message loop. 
       CMessageLoop loop; 
       int res = loop.Run(); 
       // Terminate. 
       _Module.Term(); 
       return res; 
}

Und damit geht es mit der WTL...




Vorlage:Adsense