Grundlagen der Informatik: Memory Management Unit MMU
Grundlagen der Informatik: Memory Management Unit MMU
Damit unser Prozessor nicht selbst die logischen Adressen umrechnen muss zu den tatsächlich Adresse im Hauptspeicher gibt es eine MMU. Warum man diesen Teil Hardwaretechnisch ausgelagert hat versteht sich von selbst, da durch diese Rechnungen vom Prozessor pro Zugriff wertvolle Zeit verloren geht.
Bei dieser Grafik wird deutlich, dass der CPU vom die logische Adresse weitergereicht wird, an die MMU, diese überprüft zuerst, ob sich die logische Adresse überhaupt in dem freigegebenen Adressraum des Programms befindet. Die Überprüfung ist ganz simpel, da einfach überprüft wird, ob die Adresse größer ist, als das Grenzregister der Anwendung.
Dadurch kann das Programm nicht eine logische Adresse anfordern, die weit über dem Programm freigegebenen Speicher liegt, um Daten von einem anderen Programm auslesen zu können.
Nun wird die Seiten Nr. ermittelt, dieser Vorgang ist nicht weiter komplex, da die logische Adresse binär maskiert wird. Um das nachrechnen zu können mit dezimalen Adressen, kann man die gesamte logische Adresse durch die Seitengröße teilen. Sollte das Ergebnis nicht ganzzahlig sein, so wird einfach alles nach dem Komma weggestrichen.
Im Nächsten Schritt wird die Prozess/Programm abhängige Seitentabelle geladen und die herausgefundene Seiten Nr. gesucht. Sobald diese gefunden wurde, wird die Rahmen Nr., bzw. die genaue Block-Anfangs-Adresse im Hauptspeicher herausgeladen und ersetzt die Seiten Nr. der logischen Adresse. Das kann man dezimal mit einer einfachen Addition erledigen.
logische Adresse - Seiten Nr. * Seitengröße = Displacement
2055 - 1 * 2048 = 7 -> Das Ergebnis ist das Displacement (Seitengröße in diesem Beispiel: 2 KByte)
Nun wurde bereits oft über das Displacement geschrieben, das Displacement ist die Adresse innerhalb eines Speicherblocks zu dem gewünschten Dateninhalt.
Hierbei wird auch das PresentBit überprüft, wenn dieses nicht 1 (true) ist, dann befindet sich unser gewünschter Speicherblock nicht im Hauptspeicher sondern wurde Geswaped. Der Swap (Auslagerung) lagert unbenutzte Speicherblöcke auf die Festplatte aus, damit wir mehrere Programme öffnen können und auch Inhalte bearbeiten können, die größer sind als unser Hauptspeicher (z. B. Videobearbeitung von HD-Filmen). Jedoch verzögert das Swapen das Ausführen von einem Programm. Wenn auf einen solchen Block zugegriffen wird, wird das Programm blockiert und der Speicherblog wieder in den Hauptspeicher geladen (Pagefoult).
Dieses Phänomen kann man heute auch noch sehen, indem man viele Programme gleichzeitig öffnet und parallel laufen lässt, dadurch wird das System deutlich langsamer und die Programme werden wegen den Pagefoult immer kurzzeitig blockiert, hierbei entsteht die Wartezeit.
Zu der Block-Anfangs-Adresse (Rahmen Nr. * Seitengröße) wird nun das Displacement Addiert.
Nun haben wir die physikalische Adresse, diese kann nun auf den Datenbus gelegt werden, mit der Anweisung auf den Steuerungsbus.
Grundlagen der Informatik: Der Hauptspeicher
Grundlagen der Informatik: Der Hauptspeicher
Jeder weis wie wichtig der Arbeitsspeicher bzw. Hauptspeicher bei einem PC ist, doch was macht er wirklich? Wie organisiert er seinen Inhalt und wie greifen die Programme darauf zu?
Ein Programm oder genauer gesagt, ein laufender Prozess, brauch im (Haupt-)Speicher Daten (Variablen, Attribute) und auch der Programmcode (Funktionen, Prozeduren).
Früher zu DOS Zeiten hat der Compiler/Linker die absoluten Adressen zu den Attributen, Variablen bzw. zu den Funktionen gelegt. Das ist auch einer der Gründe, warum DOS nicht Multitasking fähig war.
Heutzutage erstellt der Compiler/Linker bei dem kompilieren logische Adressen (beginnend ab 0) zu den Bestandteilen im Hauptspeicher, diese kann dann das Betriebssystem selbstständig verwalten und die logischen Adressen können dynamisch berechnet werden.
Logische Adressen kann man sich somit als eine vereinfachte Adresse vorstellen, die unser Betriebssystem frei verwalten kann und einer physikalischen Adresse zuteilen kann.
Ein weiterer Vorteil ist das dynamische Laden. Diese Bestandteile werden erst in den Hauptspeicher geladen, wenn sie für die Laufzeit notwendig werden. Vor allem bei Multitasking Systemen kommt es oft vor, dass 2 oder mehr Programme auf dieselbe Bibliothek zugreifen.
Natürlich wird auch hier jetzt klar, dass unser Betriebssystem jetzt die logischen Adressen frei Verwalten kann und den Arbeitsspeicher effizient verwenden kann. Mittels Paging wird der benötigte Speicher in Seiten bzw. Blöcken aufgeteilt und auf dem Arbeitsspeicher verteilt. In einer Seitentabelle kann nun nachgeschaut werden, wo sich der eigentliche Speicherplatz auf dem Hauptspeicher befindet.
Gemeinsam genutzte Bibliotheken - Bei dem ersten Aufruf des Programms einer Bibliothek, wird ein Platzhalter ("stab") erstellt, dieser untersucht dann ob die Bibliothek bereits geladen wurde. Wenn die Bibliothek noch nicht geladen wurde, wird sie geladen und der Platzhalter bekommt einen Link zu der geladenen Bibliothek. Wenn aber die benötigte Bibliothek vorhanden ist, wird sofort der Platzhalter entfernt und zeigt direkt auf die geladene Bibliothek.
Wenn das unser Betriebssystem das nicht verwalten würde, dann hätte jedes Programm die Bibliothek geladen und das würde unnötig den Speicher beanspruchen.
Jedes Programm hat seinen eigenen Speicherbereich und kann NICHT auf den anderen Speicherbereich zugreifen.
Dies ist aus Sicherheitsgründen notwendig, da sonst Viren oder andere Programme den Inhalt aus anderen Programmen einfach lesen können bzw. diese beeinflussen kann. Diese Schutzvorrichtung ist in der MMU verankert.
Damit unser Prozessor nicht selbstständig alle Speicherbereiche von der logischen Adresse zur physikalischen Adresse berechnen muss, gibt es auf unserer Hardware eine Memory Management Unit MMU
Grundlagen der Informatik – Thread Zustände
Grundlagen der Informatik - Thread Zustände
Immer mehr Programme verwenden Threads, aber viele kennen nicht mal die Zustände und Übergänge diese "Kontrollfäden". Hier ist eine "kleine" Übersicht der Zustände, die ein Thread bekommen kann:
Da dieses Bild recht groß ist, sollte man es im Vollbildmodus anschauen
.
Update: kleiner Pfeilfehler wurde verbessert.
Grundlagen der Informatik – Semaphore (Thread Steuerung)
Grundlagen der Informatik - Semaphore (Thread Steuerung)
Wenn man mit Threads arbeitet, muss man aufpassen, dass die Threads sich nicht gegenseitig blockieren. Deshalb sollte man beachten, ob der Thread in einen kritischen Zustand gerät. Bevor dieser in einen kritischen Zustand kommt, soll gefragt werden, ob ein anderer bereits darin ist. Damit sich die Threads nicht in die Quere kommen.
Kritischer Zustand
Ein kritischer Zustand ist eine Sequenz von einem Thread, die durch das einwirken eines anderen Threads manipuliert bzw. blockiert werden kann. In dem kritischen Zustand kann das Programm abstürzen oder schwere Fehler verursachen. Kommen oft zustande wenn mehrere Threads auf die gleiche Variable bzw. Attribut zugreifen wollen.
Im kritischen Zustand können somit zwei Threads verklemmen!
In Java kann man eine Semaphore so programmieren:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class Semaphore { private int value; public Semaphore(int pInit) { if (pInit < 0) { pInit = 0; } value = pInit; } public synchronized void down() { while (value == 0) { try { wait(); } catch (InterruptedException exp) { } } value--; } public synchronized void up() { value++; notifyAll(); } } |
In dem Konstruktor der Semaphore wird ein Integerwert übergeben, wie viele Threads auf einmal in den überwachten kritischen Zustand kommen dürfen. Natürlich kann dieser Wert nicht kleiner als 0 sein und auch 0 macht wenig sinn, da sonst kein Thread den kritischen Zustand erlangen kann.
In Unserem Beispiel setzten wir den value-Wert auf 1. Wir haben 2 Threads die in einen kritischen Zustand kommen.
Wenn jetzt nun unser 1. Thread in den Zustand kommen möchte, ruft diese den Befehl down() auf. Nun wird value auf 0 gesetzt und unser 1. Thread kann arbeiten. Sollte jetzt der 2. Thread kommen, dann bleibt er bei der Abfrage value == 0 hängen und wartet nun passiv.
Wenn unser 1. Thread nun den kritischen Zustand verlässt wird value wieder auf 1 gesetzt und mittels notifyAll() werden die wartenden Threads geweckt. Der erste der nun geweckt wurde, kann nun den kritischen Zustand erreichen. In unserem Beispiel ist nun der 2. Thread in der Lage den kritischen Zustand zu erreichen.
Klar ist, dass die Semaphore die gleiche sein muss, die beide Threads verwenden. Weil wenn jeder Thread seine eigene Semaphore hat, werden beide nahezu gleichzeitig in den kritischen Zustand wechseln.
Eine Semaphore kann man sich wie eine Ampel vorstellen, die den "Verkehr" regelt. Hierbei kann sie Threads in die Warteliste schieben und auch wieder in den bereiten Zustand ändern.
Wie funktioniert eine Spiele-Engine?
Der Aufbau einer modernen Spiele-Engine
Jedes Computerspiel baut auf einer Engine auf, immer wieder liest man in Zeitschriften und Magazinen über Speile-Engines doch was ist es wirklich?
Ein Spiel zu programmieren ist ein sehr großer Aufwand, den jede Einzelheit in dem Spiel muss vom Programmierer berücksichtigt werden z. B. was passiert, wenn man auf die "Enter"-Taste drückt. Aber wenn die gesamte Logik und das Spielverhalten entwickelt ist, muss man ja auch noch auf irgendeiner Art und Weiße das Ganze als Grafik ausgeben.
Durch die immer komplexer werdenden Spiele und deren Grafikausgabe, ist eine Spiele-Engine unbedingt erforderlich. Den die Engine beinhaltet Elemente wie die Grafikausgabe, Soundausgabe, Steuerung und sogar die Spielephysik. Sozusagen greift der eigentliche Spieleprogrammierer dann nur auf die jeweiligen Objekte und Methoden zu, welche die Game Engine bereitstellt.
Manche Engines sind sogar Plattformunabhängig, d. H. dass man damit ein Spiel programmiert und diese ohne großen Änderungsaufwand auf einer X-Box und der PS3 läuft. Das Programmieren mit einer Engine nimmt viel Arbeit ab, jedoch muss man sich zuerst zurechtfinden.
Es gibt kein einheitliches Schema für Engines, daher brauchen Engines z. B. andere spezielle Objekte und Laufzeitroutinen, damit alles so klappt, wie man es sich vorgestellt hat.
Die Grafik oben zeigt deutlich, welche Teile zwangsläufig in einer normalen Engine enthalten sein müssen. Es gibt sehr viele kostenlose Spiele-Engines, eine davon ist z. B. die GTGE für JAVA. Aber man sollte auf ein paar Kleinigkeiten achten:
1. Jede Engine ist in einer speziellen Programmiersprache entwickelt und man muss somit Zwangsweise auch in dieser Programmiersprache das Spiel schreiben. Es gibt zwar komplexe Ausnahmen über die Einbindung mittels DDL-Dateien, aber das würde den Rahmen der einfachen Erklärung sprengen.
2. Manche Engine sind für spezielle Spiele entwickelt worden, daher kann es ziemlich schwer oder gar unmöglich werden, mittels einer "Rennspiel-Engine" ein Strategiespiel zu programmieren. Genau so auch die Art, mit einer 2D-Engine wird kein Mensch ein 3D-Spiel programmieren, sowie mittels einer 3D-Engine ein 2D Spiel unnötig kompliziert wäre.
3. Für ein kleines Spiel, brauch mein keine unnötig komplexe und riesige Engine. Denn dadurch wird das Einarbeiten in die Engine nur unnötig komplex und man könnte letztendlich an der Unüberschaubarkeit der Engine scheitern.
4. Damit man mit einer Engine ein Spiel programmieren kann, sollte man schon einiges Programmiert haben und die objektorientierte Programmierung verstanden haben. Alle Pakete und Klassen werden als Objekte eingebunden und mit ihnen wird auch so programmiert. Ausnahme sind prozedurale Spiele-Engines (nicht Empfohlen).
Programmieren in C++ – Teil 2
Programmieren in C++ – Teil 2
- zu Programmieren in C++ - Teil 1 ->
Deklaration
Bei einer Deklaration wird eine Variable festgelegt, dabei ist entscheidend welchen Datentyp sie hat und optional kann man einen Startwert angeben.
int meineZahl = 5
<Datentyp> <Variablenname> = <Startwert>
Bedingungen:
Die bekannteste Bedingung, auch Verzweigung genannt, ist die IF-Abfrage:
if ( password == "Hallo" ) { //wenn der Fall zutrifft }else{ //wenn der Fall NICHT zutrifft }
Die Switch’n’Case Mehrfachverzeigung
Die Variable „wert“ darf nur int, long, short oder char sein.
swich(wert) { case 1: // Anweisungen für 1 break; case 2: //Anweisungen für 2 break; case 3: //Anweisungen für 3 break; default: //Anweisung für andern Wert break; }
Schleifen:
Schleifen werden verwendet um oft verwendete Anweisungen bzw. Befehle einfach zu wiederholen, ohne es im Quellcode mehrfach kopieren zu müssen.
Man unterteilt die Schleifen in 3 Arten:
Kopfgesteuerte Schleife:
while( BEDIGNUNG ) { //Aktionen }
Fußgesteuerte Schleife:
do{ //Aktionen }while( BEDINGUNG )
Zählschleife:
for ( int i = 0; i < 70; i++) { //Ausführung die 70 Mal erfolgt }
Compiler
Das wichtigste Element, bei dem erstellen von Programmen. Denn der Compiler wandelt unseren Quellcode um, in einen Maschinencode. Dieser Maschinencode ist dann auf den jeweiligen Prozessor abgestimmt und kann nur auf der ausgewählten Architektur laufen. Eine Architekturist somit von dem verwendete µControler abhängig.

Der Compiler weist auch auf Fehler im Quelltext hin, die nach verschiedenen Kriterien sortiert werden:
Lexikalische Analyse: Überprüft ob Sonderzeichen im Quellcode verwendet werden, die nicht zugelassen sind, wie z. B. „ä“ , „ö“ , „ü“ und „ß“.
Syntaktische Analyse: Untersucht ob alle Syntaxrichtlinien eingehalten worden sind. Darunter fällt z. B., dass jede geöffnete Klammer „{“ eine geschlossene Klammer „}“ hat.
Semantische Analyse: Vergleicht ob die Inhalte der Bibliotheken, Module und Datentypen richtig verwendet wurden.
Benjamin Salchow
Programmieren in C++ – Teil 1
C++ ist eine höhere Programmiersprache und die Weiterentwicklung von C. Mittels der Unterstützung von mehreren Programmierparadigmen, wie z. B. objektorientierte, generische, funktionelle, prozedurale und abstrakte Programmierung ist es eine sehr flexible und leistungsstarke Programmiersprache. C++ ist im Jahre 1979 erschienen und ist eine der meist verwendeten Programmiersprachen für Computersysteme und Mikrocontroller.
Operatoren
| Zeichen |
Bedeutung |
Beispiel |
| = | Zuweisung | meineZahl = 5 |
| + | Addition | meineZahl = 5 + 3 |
| - | Subtraktion | meineZahl = 5 – 3 |
| * | Multiplikation | meineZahl = 5*2 |
| / | Division | meineZahl = 5/2 |
| % | Modulo – Rest bei Division | meineZahl = 5%2 |
| ++ | Inkrement – Erhöht die Variable um 1 | meineZahl++ |
| -- | Dekrement – Verringert die Variable um 1 | meineZahl-- |
Vergleichsoperatoren
| Zeichen | Bedeutung |
| == | Entspricht bzw. Gleich |
| > | Größer als |
| < | Kleiner als |
| >= | Größer gleich als |
| <= | Kleiner gleich als |
| != | ungleich |
Einfache Datentypen - Bezogen auf MEGA128
| Name | Beschreibung | Wertebereich (SoccerBoard) |
| int | Ganze Zahlen | -32767 .. 32768 |
| float, double | Fließkommazahlen | |
| char | Zeichen | ASCII-Code |
| bool | Wahrheitswert | true oder false |
Programmierbausteine
Ein Kommentar wird vom Compiler nicht berücksichtigt und ist in der kompilierten Datei nicht vorhanden. Kommentare dienen dazu, den Quelltext leserlich zu gestalten und um komplexe Vorgänge im Quellcode erklären zu können.
Der einfache Zeilenkommentar:
//Das ist ein Kommentar
Alles nach den zwei „//“ wird als Kommentar angesehen und wird vom Compiler ignoriert. Der Kommentar endet automatisch mit der nächsten Zeile.
Der mehrzeilige Kommentar:
/* ein Langer Text, der auch mehrere Zeilen haben kann */
Benjamin Salchow
Winamp C++ Controll Klasse
Funktionsfähige Winamp c++ Controll Klasse
Für das aktuelle VHPD-Projekt "Smart G15 Winamp Controll Delux" haben wir eine C++ Winamp Steuerungsklasse erstellt, die auf dem offiziellen WinAmp SDK basiert und mittels der Vorlage von b2bk aus einem Forum (link ->).
Die Klasse wurde so erweitert, dass der Titel und der aktuelle Artist getrennt voneinander ausgelesen werden kann. Dabei wird mittels den Stringfunktionen der Bindestrich gesucht und ab diesen getrennt. Jedoch darf der Artist in seinem Namen KEINEN BINDESTRICH "-" haben, sonst wird leider falsch getrennt.
Damit immer die aktuellen Informationen in der Klasse stehen, muss die Funktion UpdateWinampInfo() mindestens ein Mal pro Sekunde aufgerufen werden, da sonst die Angaben falsch sind.
Nur WinAmp Plug-Ins können direkt den Titel und Artist aus dem ID3 Tag laden, daher wurde dies so umständlich über den Fensternamen gemacht.
Das ist das erste c++ Projekt des VHPD-Blogs und alle Klassen sind noch im Betastatus, deshalb sind Verbesserungsvorschläge gerne willkommen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include "stdafx.h" #include "ColorAndMono.h" #include "ColorAndMonoDlg.h" #include "ExtraTester.h" #include "wa_ipc.h" #include "WinUser.h" #include "WinDef.h" #include #include class CWinamp { private: HWND m_hWinamp; public: int m_iCurrentMilliseconds; int m_iCurrentSeconds; int m_iCurrentMinutes; int m_iCurrentMinuteSeconds; int m_iTotalSeconds; int m_iTotalMinutes; int m_iTotalMinuteSeconds; int m_iVolume; bool m_bStopped; bool m_bPaused; bool m_bShuffle; bool m_bRepeat; char m_chOldTitle[512]; char m_chOnlyTitle[512]; char m_chOnlyArtist[512]; char m_chTitle[512]; char m_chScrollingTitle[512]; bool m_bTitleChanged; void UpdateWinampInfo( void ) { m_hWinamp = ::FindWindow( "Winamp v1.x", NULL ); if( m_hWinamp ) { //Winamp läuft m_iCurrentMilliseconds = SendMessage( m_hWinamp, WM_USER, 0, 105 ); m_iCurrentSeconds = m_iCurrentMilliseconds / 1000; m_iCurrentMinutes = m_iCurrentSeconds / 60; m_iCurrentMinuteSeconds = m_iCurrentSeconds - m_iCurrentMinutes * 60; m_iTotalSeconds = SendMessage( m_hWinamp, WM_USER, 1, 105 ); m_iTotalMinutes = m_iTotalSeconds / 60; m_iTotalMinuteSeconds = m_iTotalSeconds - m_iTotalMinutes * 60; m_iVolume = SendMessage( m_hWinamp, WM_USER, -666, 122 ); int iPlayState = SendMessage( m_hWinamp, WM_USER, 0, 104 ); if( iPlayState == 0 ) { m_bStopped = true; m_bPaused = false; } else if( iPlayState == 1 ) { m_bStopped = false; m_bPaused = false; } else { m_bStopped = false; m_bPaused = true; } m_bShuffle = ( SendMessage( m_hWinamp, WM_USER, 0, 250 ) == 1 ); m_bRepeat = ( SendMessage( m_hWinamp, WM_USER, 0, 251 ) == 1 ); char szTemp[512], *pchTemp; GetWindowText( m_hWinamp, szTemp, 512 ); pchTemp = szTemp + strlen( szTemp ); while( pchTemp >= szTemp && *pchTemp != '-' ) { pchTemp--; } pchTemp--; *pchTemp = '\0'; m_bTitleChanged = false; if( strcmp( m_chOldTitle, szTemp ) ) { strcpy( m_chTitle, szTemp ); sprintf( m_chScrollingTitle, "%s ", m_chTitle ); m_bTitleChanged = true; } strcpy( m_chOldTitle, szTemp ); char chTemp; chTemp = m_chScrollingTitle[0]; for( int i = 0; i < (int)strlen( m_chScrollingTitle ); i++ ) { if( m_chScrollingTitle[i + 1] != 0 ) { m_chScrollingTitle[i] = m_chScrollingTitle[i + 1]; } else { m_chScrollingTitle[i] = chTemp; } } *m_chOnlyArtist ='\0'; *m_chOnlyTitle ='\0'; //Aufteilen des Strings const char*p = strchr (m_chTitle, '-'); if(!p) { //Kein Textinhalt strcpy(m_chOnlyArtist, m_chTitle ); } else { //bindestrich gefunden strncpy (m_chOnlyArtist, m_chTitle, p - m_chTitle-1); m_chOnlyArtist[p - m_chTitle-1] ='\0'; strcpy (m_chOnlyTitle, p + 2); } } else { m_bPaused = false; m_bRepeat = false; m_bShuffle = false; m_bStopped = true; m_iCurrentMilliseconds = 0; m_iCurrentMinutes = 0; m_iCurrentMinuteSeconds = 0; m_iCurrentSeconds = 0; m_iTotalMinutes = -1; m_iTotalMinuteSeconds = -1; m_iTotalSeconds = -1; m_iVolume = 0; strcpy( m_chTitle, "Winamp wird nicht ausgeführt" ); strcpy(m_chOnlyArtist, "Winamp wird momentan" ); //Ausgeben das Winamp nicht läuft strcpy(m_chOnlyTitle, " nicht ausgeführt." ); //Ausgeben das Winamp nicht läuft //m_chOnlyTitle[0] ='\0'; //Titel leeren m_bTitleChanged = false; if( strcmp( m_chOldTitle, m_chTitle ) ) { sprintf( m_chScrollingTitle, "%s ", m_chTitle ); m_bTitleChanged = true; } strcpy( m_chOldTitle, m_chTitle ); char chTemp; chTemp = m_chScrollingTitle[0]; for( int i = 0; i < (int)strlen( m_chScrollingTitle ); i++ ) { if( m_chScrollingTitle[i + 1] != 0 ) { m_chScrollingTitle[i] = m_chScrollingTitle[i + 1]; } else { m_chScrollingTitle[i] = chTemp; } } } } void Prev( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40044, 0 ); } } void Play( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40045, 0 ); } } void Pause( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40046, 0 ); } } void Stop( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40047, 0 ); } } void Next( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40048, 0 ); } } void VolumeUp( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40058, 0 ); } } void VolumeDown( void ) { if( m_hWinamp ) { SendMessage( m_hWinamp, WM_COMMAND, 40059, 0 ); } } void OpenJumpToTime (void) { if( m_hWinamp) { SendMessage( m_hWinamp, WM_COMMAND, 40193, 0 );}} void OpenJumpToFile (void) { if( m_hWinamp) { SendMessage( m_hWinamp, WM_COMMAND, 40194, 0 );}} void setRepeat(int i) { if ( m_hWinamp) {SendMessage(m_hWinamp,WM_WA_IPC,i,253);}} void setRandom(int i) { if ( m_hWinamp) {SendMessage(m_hWinamp,WM_WA_IPC,i,252);}} }; |
Damit kann man einfach alle wichtigenInformationen wie Titel, Artist, verbleibende Zeit und Fenster ansteuern, die WinAmp zur Verfügung stellt.
Viel Spaß beim verwenden und testen der Klasse.
Kampf der Giganten – HTML5 gegen Flash
Das neue HTML 5 - Konzept und der Kampf gegen Flash
Und wieder eine Webseite komplett mit Flash programmiert, lange Ladezeiten und dazu eine Aneinanderreihung schräger Töne, die eine Hintergrundmusik ergeben soll.
Ein Anblick auf immer mehr Webseiten, den Flash kämpft sich immer mehr an die Spitze der Webseiten. Aber was ist denn so falsch an Flash?
Flash ist seit mehreren Jahren eine unfreie Skriptsprache, die Vektorgrafiken animieren kann. Dazu beinhaltet es dutzende von Sicherheitslücken und sorgt für instabile Browser. Nun fragen sich die meisten, warum den dann so viele Flash verbauen auf der Webseite?
Die Antwort ist eher mager, genauso wie die Fähigkeiten der Entwickler von Flashseiten. Ein Einfaches hin- und hergeziehe von Elementen, die man dann in Action-Skript, die "Programmiersprache" von Flashanwendungen, bearbeitet und erweitert. Die Folgen sind starke Probleme für Suchmaschinen, langsamere PCs und für schlechte Internetverbindungen.
Aber abgesehen davon, kann man mit Flash problemlos Internetspiele programmieren, die nicht mittels Java direkt auf einer virtuellen Maschine laufen.
Nach vielen Festlegungen der W3C kam man endlich auf die Idee, in HTML selbst einige Flashelemente einzubauen, die dann Suchmaschinen lesen können und vor allem keinen Schaden an dem laufenden System verursachen. Elemente sind:
- 2D Canvas
- Progress
- Video
- Audio
- u.s.w
Praktisch eine Aneignung der Flash Lite Serie, die zur Folge haben kann, dass nun noch mehr Webseiten irgendwelche Musikstücke im Hintergrund laufen lassen und Knöpfe im Menü sich wie ein Schuss einer Pistole anhören.
In Java einen String überprüfen auf unzulässige Zeichen (Char) - nur von 'A' bis 'Z'




Abbonieren