Browse Source

Erster commit

Kolja Strohm 8 years ago
commit
5d987a3661
119 changed files with 42154 additions and 0 deletions
  1. 63 0
      .gitattributes
  2. 212 0
      .gitignore
  3. 109 0
      AlphaFeld.cpp
  4. 35 0
      AlphaFeld.h
  5. 452 0
      Animation.cpp
  6. 99 0
      Animation.h
  7. 13 0
      Animation3D.h
  8. 635 0
      Array.h
  9. 2210 0
      AuswahlBox.cpp
  10. 233 0
      AuswahlBox.h
  11. 84 0
      Betriebssystem.h
  12. 2204 0
      Bild.cpp
  13. 157 0
      Bild.h
  14. 1076 0
      Bildschirm.cpp
  15. 188 0
      Bildschirm.h
  16. 270 0
      Cube.cpp
  17. 52 0
      Cube.h
  18. 166 0
      DXBuffer.cpp
  19. 79 0
      DXBuffer.h
  20. 806 0
      Datei.cpp
  21. 190 0
      Datei.h
  22. 274 0
      DateiDialog.cpp
  23. 100 0
      DateiDialog.h
  24. 3207 0
      DateiSystem.cpp
  25. 639 0
      DateiSystem.h
  26. 104 0
      DefaultShader.h
  27. 2019 0
      Diagramm.cpp
  28. 383 0
      Diagramm.h
  29. 115 0
      DreieckListe.h
  30. 2473 0
      Fenster.cpp
  31. 357 0
      Fenster.h
  32. 333 0
      Fortschritt.cpp
  33. 90 0
      Fortschritt.h
  34. 28 0
      Framework.sln
  35. 352 0
      Framework.vcxproj
  36. 422 0
      Framework.vcxproj.filters
  37. 37 0
      FrameworkMath.h
  38. 84 0
      Global.cpp
  39. 62 0
      Globals.h
  40. 408 0
      InitDatei.cpp
  41. 150 0
      InitDatei.h
  42. 310 0
      KSGTDatei.cpp
  43. 119 0
      KSGTDatei.h
  44. 310 0
      Kam2D.cpp
  45. 78 0
      Kam2D.h
  46. 216 0
      Kam3D.cpp
  47. 90 0
      Kam3D.h
  48. 872 0
      Knopf.cpp
  49. 164 0
      Knopf.h
  50. 1040 0
      Liste.cpp
  51. 134 0
      Liste.h
  52. 199 0
      M2DVorschau.cpp
  53. 52 0
      M2DVorschau.h
  54. 381 0
      M2Datei.cpp
  55. 85 0
      M2Datei.h
  56. 251 0
      M3Datei.cpp
  57. 77 0
      M3Datei.h
  58. 84 0
      Mat3.h
  59. 109 0
      Mat4.h
  60. 119 0
      Maus.cpp
  61. 58 0
      Maus.h
  62. 8 0
      MausEreignis.cpp
  63. 54 0
      MausEreignis.h
  64. 754 0
      Model2D.cpp
  65. 117 0
      Model2D.h
  66. 324 0
      Model3D.cpp
  67. 192 0
      Model3D.h
  68. 155 0
      Model3DList.cpp
  69. 59 0
      Model3DList.h
  70. 15 0
      ObjectRegister.h
  71. 184 0
      Prozess.cpp
  72. 70 0
      Prozess.h
  73. 50 0
      Punkt.cpp
  74. 37 0
      Punkt.h
  75. 115 0
      Rahmen.cpp
  76. 40 0
      Rahmen.h
  77. 301 0
      Render3D.cpp
  78. 92 0
      Render3D.h
  79. 161 0
      RenderThread.cpp
  80. 56 0
      RenderThread.h
  81. 243 0
      Schluessel.cpp
  82. 120 0
      Schluessel.h
  83. 1013 0
      Schrift.cpp
  84. 364 0
      Schrift.h
  85. 465 0
      Scroll.cpp
  86. 108 0
      Scroll.h
  87. 336 0
      Shader.cpp
  88. 136 0
      Shader.h
  89. 1592 0
      Tabelle.cpp
  90. 353 0
      Tabelle.h
  91. 34 0
      TastaturEreignis.cpp
  92. 81 0
      TastaturEreignis.h
  93. 43 0
      TestShader.hlsl
  94. 1346 0
      Text.cpp
  95. 353 0
      Text.h
  96. 842 0
      TextFeld.cpp
  97. 135 0
      TextFeld.h
  98. 154 0
      Textur.cpp
  99. 58 0
      Textur.h
  100. 189 0
      TexturList.cpp
  101. 58 0
      TexturList.h
  102. 149 0
      Thread.cpp
  103. 74 0
      Thread.h
  104. 190 0
      ToolTip.cpp
  105. 81 0
      ToolTip.h
  106. 156 0
      Vec2.h
  107. 137 0
      Vec3.h
  108. 135 0
      Vec4.h
  109. 120 0
      Welt2D.cpp
  110. 54 0
      Welt2D.h
  111. 199 0
      Welt3D.cpp
  112. 48 0
      Welt3D.h
  113. 972 0
      Zeichnung.cpp
  114. 260 0
      Zeichnung.h
  115. 200 0
      Zeichnung3D.cpp
  116. 96 0
      Zeichnung3D.h
  117. 1983 0
      Zeit.cpp
  118. 719 0
      Zeit.h
  119. 56 0
      main.h

+ 63 - 0
.gitattributes

@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs     diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following 
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln       merge=binary
+#*.csproj    merge=binary
+#*.vbproj    merge=binary
+#*.vcxproj   merge=binary
+#*.vcproj    merge=binary
+#*.dbproj    merge=binary
+#*.fsproj    merge=binary
+#*.lsproj    merge=binary
+#*.wixproj   merge=binary
+#*.modelproj merge=binary
+#*.sqlproj   merge=binary
+#*.wwaproj   merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg   binary
+#*.png   binary
+#*.gif   binary
+
+###############################################################################
+# diff behavior for common document formats
+# 
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the 
+# entries below.
+###############################################################################
+#*.doc   diff=astextplain
+#*.DOC   diff=astextplain
+#*.docx  diff=astextplain
+#*.DOCX  diff=astextplain
+#*.dot   diff=astextplain
+#*.DOT   diff=astextplain
+#*.pdf   diff=astextplain
+#*.PDF   diff=astextplain
+#*.rtf   diff=astextplain
+#*.RTF   diff=astextplain

+ 212 - 0
.gitignore

@@ -0,0 +1,212 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+## TODO: Comment the next line if you want to checkin your
+## web deploy settings but do note that will include unencrypted
+## passwords
+#*.pubxml
+
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# LightSwitch generated files
+GeneratedArtifacts/
+_Pvt_Extensions/
+ModelManifest.xml

+ 109 - 0
AlphaFeld.cpp

@@ -0,0 +1,109 @@
+#include "AlphaFeld.h"
+#include "Punkt.h"
+#include "Bild.h"
+#include "Scroll.h"
+#include "ToolTip.h"
+#include "Text.h"
+
+using namespace Framework;
+
+// Inhalt der AlphaFeld Klasse aus AlphaFeld.h
+// Konstruktor 
+AlphaFeld::AlphaFeld()
+	: Zeichnung(),
+  stärke( 5 ),
+  farbe( 0x9B000000 ),
+  ref( 1 )
+{
+}
+
+// nicht constant 
+void AlphaFeld::setStärke( int st ) // setzt die Stärke
+{
+	stärke = st;
+	rend = 1;
+}
+
+void AlphaFeld::setFarbe( int f ) // setzt die Farbe
+{
+	farbe = f;
+	rend = 1;
+}
+
+void AlphaFeld::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+    __super::render( zRObj );
+	int br = gr.x - 1;
+	int hö = gr.y - 1;
+	int xp = pos.x, yp = pos.y;
+	int a = ( farbe >> 24 ) & 0xFF;
+	int index = ( br / 2 ) * ( br <= hö ) + ( hö / 2 ) * ( br > hö );
+	int fc = farbe & 0x00FFFFFF;
+	int fc2 = farbe;
+	if( stärke > 0 )
+		index = index > ( a / stärke ) ? a / stärke : index;
+	if( stärke < 0 )
+		index = index > ( ( 255 - a ) / -stärke ) ? ( ( 255 - a ) / -stärke ) : index;
+	for( int i = 0; i < index; ++i )
+	{
+		a -= stärke;
+		fc2 = ( a << 24 ) | fc;
+		int i2 = i << 1;
+		zRObj.drawLinieHAlpha( xp + i + 1, yp + i, br - i2, fc2 );		// oben links --- oben rechts
+		zRObj.drawLinieVAlpha( xp + br - i, yp + i + 1, hö - i2, fc2 );	// oben rechts -- unten rechts
+		zRObj.drawLinieHAlpha( xp + i, yp + hö - i, br - i2, fc2 );		// unten rechts - unten links
+		zRObj.drawLinieVAlpha( xp + i, yp + i, hö - i2, fc2 );			// unten links -- oben links
+	}
+	if( index == br / 2 )
+	{
+		for( int i = index; i <= index + ( br - index ) - index; ++i )
+			zRObj.drawLinieVAlpha( xp + i, yp + index, hö - ( index << 1 ) + 1, fc2 ); // rest Fläche senkrecht
+	}
+	else
+	{
+		for( int i = index; i <= index + ( hö - index ) - index; ++i )
+			zRObj.drawLinieHAlpha( xp + index, yp + i, br - ( index << 1 ) + 1, fc2 ); // rest Fläche waagerecht
+	}
+}
+
+// constant 
+int AlphaFeld::getStärke() const // gibt die Stärke zurück
+{
+	return stärke;
+}
+
+int AlphaFeld::getFarbe() const // gibt die Farbe zurück
+{
+	return farbe;
+}
+
+Zeichnung *AlphaFeld::dublizieren() const // Kopiert das Zeichnung
+{
+	AlphaFeld *obj = new AlphaFeld();
+	obj->setPosition( pos );
+	obj->setGröße( gr );
+	obj->setMausEreignisParameter( makParam );
+	obj->setTastaturEreignisParameter( takParam );
+	obj->setMausEreignis( Mak );
+	obj->setTastaturEreignis( Tak );
+	if( toolTip )
+		obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	obj->setStärke( stärke );
+	obj->setFarbe( farbe );
+	return obj;
+}
+
+// Reference Counting 
+AlphaFeld *AlphaFeld::getThis()
+{
+	++ref;
+	return this;
+}
+
+AlphaFeld *AlphaFeld::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 35 - 0
AlphaFeld.h

@@ -0,0 +1,35 @@
+#ifndef AlphaFeld_H
+#define AlphaFeld_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class Bild; // Bild.h
+	class AlphaFeld; // Aus dieser Datei
+
+	class AlphaFeld : public Zeichnung
+	{
+	private:
+		int stärke;
+		int farbe;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) AlphaFeld();
+		// nicht constant 
+		__declspec( dllexport ) void setStärke( int st ); // setzt die Stärke
+		__declspec( dllexport ) void setFarbe( int f ); // setzt die Farbe
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) int getStärke() const; // gibt die Stärke zurück
+		__declspec( dllexport ) int getFarbe() const; // gibt die Farbe zurück
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Kopiert das Zeichnung
+		// Reference Counting 
+		__declspec( dllexport ) AlphaFeld *getThis();
+		__declspec( dllexport ) AlphaFeld *release();
+	};
+}
+
+#endif

+ 452 - 0
Animation.cpp

@@ -0,0 +1,452 @@
+#include "Animation.h"
+#include "Bild.h"
+#include "DateiSystem.h"
+#include "Text.h"
+#include "InitDatei.h"
+#include "ToolTip.h"
+#include "Rahmen.h"
+
+using namespace Framework;
+
+// Inhalt der Animation2DData Klasse aus Animation.h
+// Konstruktor
+Animation2DData::Animation2DData()
+	: bilder( 0 ),
+	  bildAnzahl( 0 ),
+	  fps( 0 ),
+	  wiederhohlen( 0 ),
+	  transparent( 0 ),
+	  ref( 1 )
+{
+	InitializeCriticalSection( &cs );
+}
+
+// Destruktor
+Animation2DData::~Animation2DData()
+{
+	reset();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void Animation2DData::lock()
+{
+	EnterCriticalSection( &cs );
+}
+
+void Animation2DData::unlock()
+{
+	LeaveCriticalSection( &cs );
+}
+
+void Animation2DData::ladeAnimation( InitDatei *datei )
+{
+	if( !datei )
+		return;
+	reset();
+	int anz = datei->getWertAnzahl();
+	lock();
+	if( datei->wertExistiert( "fps" ) )
+	{
+		--anz;
+		fps = TextZuInt( datei->zWert( "fps" )->getText(), 10 );
+	}
+	if( datei->wertExistiert( "wiederhohlen" ) )
+	{
+		--anz;
+		wiederhohlen = datei->zWert( "wiederhohlen" )->istGleich( "true" );
+	}
+	if( datei->wertExistiert( "transparent" ) )
+	{
+		--anz;
+		transparent = datei->zWert( "transparent" )->istGleich( "true" );
+	}
+	Bild **bilder = new Bild*[ anz ];
+	int j = 0;
+	for( int i = 0; i < anz; ++i )
+	{
+		if( datei->zName( i )->istGleich( "fps" ) || 
+			datei->zName( i )->istGleich( "wiederhohlen" ) || 
+			datei->zName( i )->istGleich( "transparent" ) )
+			continue;
+		bilder[ j ] = 0;
+		Text pfad = datei->zWert( i )->getText();
+		if( pfad.hat( ".ltdb/" ) && pfad.getLänge() > 7 )
+		{
+			Text *name = pfad.getTeilText( pfad.positionVon( ".ltdb/", pfad.anzahlVon( ".ltdb/" ) - 1 ) + 6 );
+			pfad.setText( pfad.getTeilText( 0, pfad.getLänge() - name->getLänge() - 1 ) );
+			LTDBDatei *dat = new LTDBDatei();
+			dat->setDatei( pfad.getThis() );
+			dat->leseDaten( 0 );
+			bilder[ j ] = dat->laden( 0, name );
+			dat->release();
+		}
+		++j;
+	}
+	this->bilder = new Bild*[ bildAnzahl ];
+	j = 0;
+	for( int i = 0; i < anz; ++i )
+	{
+		if( !bilder[ i ] )
+			++j;
+		else
+			this->bilder[ i - j ] = bilder[ i ];
+	}
+	delete[] bilder;
+	unlock();
+	datei->release();
+}
+
+void Animation2DData::ladeAnimation( LTDBDatei *datei )
+{
+	if( !datei )
+		return;
+	reset();
+	datei->leseDaten( 0 );
+	int anz = datei->getBildAnzahl();
+	RCArray< Text > *list = datei->zBildListe();
+	lock();
+	Bild **bilder = new Bild*[ anz ];
+	for( int i = 0; i < anz; ++i )
+	{
+		bilder[ i ] = datei->laden( 0, list->get( i ) );
+		if( bilder[ i ] )
+			++bildAnzahl;
+	}
+	this->bilder = new Bild*[ bildAnzahl ];
+	int j = 0;
+	for( int i = 0; i < anz; ++i )
+	{
+		if( !bilder[ i ] )
+			++j;
+		else
+			this->bilder[ i - j ] = bilder[ i ];
+	}
+	delete[] bilder;
+	unlock();
+	datei->release();
+}
+
+void Animation2DData::setFPS( int fps )
+{
+	this->fps = fps;
+}
+
+void Animation2DData::setWiederhohlend( bool wh )
+{
+	wiederhohlen = wh;
+}
+
+void Animation2DData::setTransparent( bool trp )
+{
+	transparent = trp;
+}
+
+void Animation2DData::reset()
+{
+	lock();
+	for( int i = 0; i < bildAnzahl; ++i )
+		bilder[ i ] = bilder[ i ]->release();
+	delete[] bilder;
+	bilder = 0;
+	bildAnzahl = 0;
+	fps = 30;
+	wiederhohlen = 0;
+	transparent = 0;
+	unlock();
+}
+
+// constant
+Bild *Animation2DData::getBild( int i ) const
+{
+	return ( i >= 0 && i < bildAnzahl ) ? bilder[ i ]->getThis() : 0;
+}
+
+Bild *Animation2DData::zBild( int i ) const
+{
+	return ( i >= 0 && i < bildAnzahl ) ? bilder[ i ] : 0;
+}
+
+int Animation2DData::getBildAnzahl() const
+{
+	return bildAnzahl;
+}
+
+int Animation2DData::getFPS() const
+{
+	return fps;
+}
+
+bool Animation2DData::istWiederhohlend() const
+{
+	return wiederhohlen;
+}
+
+bool Animation2DData::istTransparent() const
+{
+	return transparent;
+}
+
+// Reference Counting
+Animation2DData *Animation2DData::getThis()
+{
+	++ref;
+	return this;
+}
+
+Animation2DData *Animation2DData::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der Animation2D Klasse aus Animation.h
+// Konstruktor
+Animation2D::Animation2D()
+	: Zeichnung(),
+	data( 0 ),
+	jetzt( 0 ),
+	ausgleich( 0 ),
+	alpha( 0 ),
+	maxAlpha( 255 ),
+	rahmen( 0 ),
+	ram( 0 ),
+	aps( 255 * 60 ),
+	sichtbar( 0 ),
+	ref( 1 )
+{
+}
+
+// Destruktor
+Animation2D::~Animation2D()
+{
+	if( data )
+		data->release();
+	if( ram )
+		ram->release();
+}
+
+// nicht constant
+void Animation2D::setRahmen( bool ram )
+{
+	rahmen = ram;
+}
+
+void Animation2D::setRahmenZ( LRahmen *ram )
+{
+	if( this->ram )
+		this->ram->release();
+	this->ram = ram;
+}
+
+void Animation2D::setRahmenBreite( int br )
+{
+	if( !ram )
+		ram = new LRahmen();
+	ram->setRamenBreite( br );
+}
+
+void Animation2D::setRahmenFarbe( int f )
+{
+	if( !ram )
+		ram = new LRahmen();
+	ram->setFarbe( f );
+}
+
+void Animation2D::setAnimationDataZ( Animation2DData *data )
+{
+	lockZeichnung();
+	if( this->data )
+		this->data->release();
+	this->data = data;
+	if( alpha )
+		rend = 1;
+	unlockZeichnung();
+}
+
+void Animation2D::setAlphaMaske( unsigned char alpha )
+{
+	maxAlpha = alpha;
+}
+
+void Animation2D::setAPS( int aps )
+{
+	this->aps = aps;
+}
+
+void Animation2D::setSichtbar( bool sichtbar )
+{
+	this->sichtbar = sichtbar;
+}
+
+bool Animation2D::tick( double zeit )
+{
+	lockZeichnung();
+	if( !data || ( !alpha && !sichtbar ) )
+	{
+		bool ret = rend;
+		rend = 0;
+		unlockZeichnung();
+		return ret;
+	}
+	if( sichtbar && alpha < maxAlpha )
+	{
+		if( alpha + aps * zeit >= maxAlpha )
+			alpha = maxAlpha;
+		else
+			alpha += (unsigned char)(aps * zeit);
+		rend = 1;
+	}
+	else if( !sichtbar && alpha > 0 )
+	{
+		if( alpha - aps * zeit <= 0 )
+			alpha = 0;
+		else
+			alpha -= (unsigned char)(aps * zeit);
+		rend = 1;
+	}
+	ausgleich += zeit;
+	int tmp = jetzt;
+	data->lock();
+	if( ausgleich >= 1.0 / data->getFPS() )
+	{
+		ausgleich -= 1.0 / data->getFPS();
+		++jetzt;
+		if( jetzt >= data->getBildAnzahl() )
+		{
+			if( data->istWiederhohlend() )
+				jetzt = 0;
+			else
+				jetzt = data->getBildAnzahl();
+		}
+	}
+	data->unlock();
+	if( tmp != jetzt )
+		rend = 1;
+	bool ret = rend;
+	rend = 0;
+	unlockZeichnung();
+	return ret;
+}
+
+void Animation2D::render( Bild &zRObj )
+{
+	lockZeichnung();
+	if( !data )
+	{
+		unlockZeichnung();
+		return;
+	}
+    __super::render( zRObj );
+	data->lock();
+	if( data->zBild( jetzt ) )
+	{
+		zRObj.setAlpha( alpha );
+		if( data->istTransparent() )
+			zRObj.alphaBild( pos.x, pos.y, gr.x, gr.y, *data->zBild( jetzt ) );
+		else
+			zRObj.drawBild( pos.x, pos.y, gr.x, gr.y, *data->zBild( jetzt ) );
+		if( ram && rahmen )
+		{
+			ram->setPosition( pos );
+			ram->setGröße( gr );
+			ram->render( zRObj );
+		}
+		zRObj.releaseAlpha();
+	}
+	data->unlock();
+	unlockZeichnung();
+}
+
+// constant
+Animation2DData *Animation2D::getAnimationData() const
+{
+	return data ? data->getThis() : 0;
+}
+
+Animation2DData *Animation2D::zAnimationData() const
+{
+	return data;
+}
+
+bool Animation2D::istSichtbar() const
+{
+	return sichtbar;
+}
+
+int Animation2D::getJetzt() const
+{
+	return jetzt;
+}
+
+unsigned char Animation2D::getAlphaMaske() const
+{
+	return maxAlpha;
+}
+
+bool Animation2D::hatRahmen() const
+{
+	return rahmen;
+}
+
+LRahmen *Animation2D::getRahmen() const
+{
+	return ram ? ram->getThis() : 0;
+}
+
+LRahmen *Animation2D::zRahmen() const
+{
+	return ram;
+}
+
+int Animation2D::getRahmenBreite() const
+{
+	return ram ? ram->getRBreite() : 0;
+}
+
+int Animation2D::getRahmenFarbe() const
+{
+	return ram ? ram->getFarbe() : 0;
+}
+
+Zeichnung *Animation2D::dublizieren() const
+{
+	Animation2D *ret = new Animation2D();
+	ret->setPosition( pos );
+	ret->setGröße( gr );
+	ret->setMausEreignisParameter( makParam );
+	ret->setTastaturEreignisParameter( takParam );
+	ret->setMausEreignis( Mak );
+	ret->setTastaturEreignis( Tak );
+	if( toolTip )
+		ret->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	if( data )
+		ret->setAnimationDataZ( data->getThis() );
+	ret->setAPS( aps );
+	ret->setSichtbar( sichtbar );
+	ret->setAlphaMaske( maxAlpha );
+	ret->setRahmen( rahmen );
+	if( ram )
+	{
+		ret->setRahmenBreite( ram->getRBreite() );
+		ret->setRahmenFarbe( ram->getFarbe() );
+	}
+	return ret;
+}
+
+// Reference Counting
+Animation2D *Animation2D::getThis()
+{
+	++ref;
+	return this;
+}
+
+Animation2D *Animation2D::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 99 - 0
Animation.h

@@ -0,0 +1,99 @@
+#ifndef Animation_H
+#define Animation_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class Bild; // Bild.h
+	class LTDBDatei; // DateiSystem.h
+	class InitDatei; // InitDatei.h
+	class LRahmen; // Rahmen.h
+
+	class Animation2DData
+	{
+	private:
+		Bild **bilder;
+		int bildAnzahl;
+		int fps;
+		bool wiederhohlen;
+		bool transparent;
+		CRITICAL_SECTION cs;
+		int ref;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) Animation2DData();
+		// Destruktor
+		__declspec( dllexport ) ~Animation2DData();
+		// nicht constant
+		__declspec( dllexport ) void lock();
+		__declspec( dllexport ) void unlock();
+		__declspec( dllexport ) void ladeAnimation( InitDatei *datei );
+		__declspec( dllexport ) void ladeAnimation( LTDBDatei *datei );
+		__declspec( dllexport ) void setFPS( int fps );
+		__declspec( dllexport ) void setWiederhohlend( bool wh );
+		__declspec( dllexport ) void setTransparent( bool trp );
+		__declspec( dllexport ) void reset();
+		// constant
+		__declspec( dllexport ) Bild *getBild( int i ) const;
+		__declspec( dllexport ) Bild *zBild( int i ) const;
+		__declspec( dllexport ) int getBildAnzahl() const;
+		__declspec( dllexport ) int getFPS() const;
+		__declspec( dllexport ) bool istWiederhohlend() const;
+		__declspec( dllexport ) bool istTransparent() const;
+		// Reference Counting
+		__declspec( dllexport ) Animation2DData *getThis();
+		__declspec( dllexport ) Animation2DData *release();
+	};
+
+	class Animation2D : public Zeichnung
+	{
+	private:
+		Animation2DData *data;
+		int jetzt;
+		double ausgleich;
+		unsigned char alpha;
+		unsigned char maxAlpha;
+		bool rahmen;
+		LRahmen *ram;
+		int aps;
+		bool sichtbar;
+		bool rend;
+		int ref;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) Animation2D();
+		// Destruktor
+		__declspec( dllexport ) ~Animation2D();
+		// nicht constant
+		__declspec( dllexport ) void setRahmen( bool ram );
+		__declspec( dllexport ) void setRahmenZ( LRahmen *ram );
+		__declspec( dllexport ) void setRahmenBreite( int br );
+		__declspec( dllexport ) void setRahmenFarbe( int fc );
+		__declspec( dllexport ) void setAnimationDataZ( Animation2DData *data );
+		__declspec( dllexport ) void setAlphaMaske( unsigned char alpha );
+		__declspec( dllexport ) void setAPS( int aps );
+		__declspec( dllexport ) void setSichtbar( bool sichtbar );
+		__declspec( dllexport ) bool tick( double zeit ) override;
+		__declspec( dllexport ) void render( Bild &zRObj ) override;
+		// constant
+		__declspec( dllexport ) Animation2DData *getAnimationData() const;
+		__declspec( dllexport ) Animation2DData *zAnimationData() const;
+		__declspec( dllexport ) bool istSichtbar() const;
+		__declspec( dllexport ) int getJetzt() const;
+		__declspec( dllexport ) unsigned char getAlphaMaske() const;
+		__declspec( dllexport ) bool hatRahmen() const;
+		__declspec( dllexport ) LRahmen *getRahmen() const;
+		__declspec( dllexport ) LRahmen *zRahmen() const;
+		__declspec( dllexport ) int getRahmenBreite() const;
+		__declspec( dllexport ) int getRahmenFarbe() const;
+		__declspec( dllexport ) Zeichnung *dublizieren() const override;
+		// Reference Counting
+		__declspec( dllexport ) Animation2D *getThis();
+		__declspec( dllexport ) Animation2D *release();
+	};
+}
+
+#endif

+ 13 - 0
Animation3D.h

@@ -0,0 +1,13 @@
+#pragma once
+
+namespace Framework
+{
+
+    class Animation3D
+    {
+    private:
+
+    public:
+
+    };
+}

+ 635 - 0
Array.h

@@ -0,0 +1,635 @@
+#ifndef Array_H
+#define Array_H
+
+#include "Betriebssystem.h"
+#include <stdexcept>
+#include "Text.h"
+
+namespace Framework
+{
+    // Ein Eintrag in einer Linked List
+	template< class TYP >
+	struct ArrayEintrag
+	{
+		TYP var;
+		bool set;
+		ArrayEintrag< TYP > *next;
+		
+        // Setzt den Eintrag auf die Werte des anderen Eintrages
+		ArrayEintrag &operator=( ArrayEintrag &r )
+		{
+			var = r.var;
+			set = r.set;
+			next = r.next;
+			return *this;
+		}
+        // Gibt den aktuell gespeicherten Wert zurück
+		operator TYP()
+		{
+			return var;
+		}
+        // inkrementiert durch die Linked List durch
+		ArrayEintrag< TYP > &operator++( ) // prefix
+		{
+            if( !next )
+            {
+                *this = ArrayEintrag{ 0, 0, 0 };
+                return *this;
+            }
+			*this = *next;
+			return *next;
+		}
+        // inkrementiert durch die Linked List durch
+		ArrayEintrag< TYP > &operator++( int ) // postfix
+		{
+            if( !next )
+            {
+                *this = ArrayEintrag{ 0, 0, 0 };
+                return *this;
+            }
+			*this = *next;
+			return *next;
+		}
+	};
+
+    // Eine Linked List von Klassen, die kein Reference Counting berteiben
+	template< class TYP >
+	class Array
+	{
+	private:
+		ArrayEintrag< TYP > *einträge;
+		int ref;
+
+	public:
+		// Erstellt eine neue Linked List
+		Array()
+		{
+			einträge = new ArrayEintrag< TYP >();
+			einträge->set = 0;
+			einträge->next = 0;
+			ref = 1;
+		}
+
+		// Leert und löscht die Linked List 
+		~Array()
+		{
+			leeren();
+			delete einträge;
+		}
+
+		// Hängt ein Element ans Ende der Liste an
+        //  t: Das neue Element
+		void add( TYP t )
+		{
+			for( ArrayEintrag< TYP > *e = einträge; 1; e = e->next )
+			{
+				if( !e->set && !e->next )
+				{
+					e->var = t;
+					e->set = 1;
+					break;
+				}
+				if( !e->next )
+				{
+					e->next = new ArrayEintrag< TYP >();
+					e->next->set = 0;
+					e->next->next = 0;
+				}
+			}
+		}
+
+        // Fügt ein Element bei einer bestimmten Position in die Liste ein
+        //  t: das neue Element
+        //  i: Die Position, wo das Element eingefügt wird (danach der Index des neuen Elementes)
+		void add( TYP t, int i )
+		{
+			if( i < 0 )
+				return;
+			ArrayEintrag< TYP > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+				{
+					ArrayEintrag< TYP > *ne = new ArrayEintrag< TYP >();
+					ne->set = 0;
+					ne->next = 0;
+					e->next = ne;
+				}
+				e = e->next;
+			}
+			ArrayEintrag< TYP > *ne = new ArrayEintrag< TYP >();
+			ne->var = e->var;
+			ne->set = e->set;
+			ne->next = e->next;
+			e->next = ne;
+			e->var = t;
+			e->set = 1;
+		}
+
+        // Setzt den Wert des i-ten Eintrags
+        //  t: der Neue Wert
+        //  i: Der Index des Eintrages der gesetzt werden soll
+		void set( TYP t, int i )
+		{
+			if( i < 0 )
+				return;
+			ArrayEintrag< TYP > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+				{
+					ArrayEintrag< TYP > *ne = new ArrayEintrag< TYP >();
+					ne->set = 0;
+					ne->next = 0;
+					e->next = ne;
+				}
+				e = e->next;
+			}
+			e->var = t;
+			e->set = 1;
+		}
+
+        // Verändert die Position des i-ten Elementes in der Liste
+        //  i: Der Index des Elementes, welches verschoben werden soll
+        //  p: Die Zielposition des Elementes (danach der neue Index des Elementes)
+		void setPosition( int i, int p )
+		{
+			if( i < 0 || p < 0 || i == p )
+				return;
+			ArrayEintrag< TYP > *e = einträge;
+			ArrayEintrag< TYP > *ve = 0;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+					return;
+				ve = e;
+				e = e->next;
+			}
+			ArrayEintrag< TYP > *e2 = einträge == e ? e->next : einträge;
+			ArrayEintrag< TYP > *ve2 = 0;
+			for( int a = 0; a < p; ++a )
+			{
+				if( !e2 )
+					return;
+				ve2 = e2;
+				if( e2->next == e )
+					e2 = e->next;
+				else
+					e2 = e2->next;
+			}
+			if( !e )
+				return;
+			if( !ve2 )
+				einträge = e;
+			else
+				ve2->next = e;
+			if( ve )
+				ve->next = e->next;
+			else
+				einträge = e->next;
+			e->next = e2;
+		}
+
+        // Löscht ein Bestimmtes Element
+        //  i: Der Index des Elementes das gelöscht werden soll
+		void lösche( int i )
+		{
+			if( i < 0 )
+				return;
+			ArrayEintrag< TYP > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+					return;
+				e = e->next;
+			}
+			if( !e )
+				return;
+			if( e->next )
+			{
+				e->var = e->next->var;
+				e->set = e->next->set;
+			}
+			else
+				e->set = 0;
+			ArrayEintrag< TYP > *del = e->next;
+			if( e->next )
+				e->next = e->next->next;
+			else
+				e->next = 0;
+			if( del )
+			{
+				del->set = 0;
+				del->next = 0;
+				delete del;
+			}
+		}
+
+        // Vertauscht zwei Elemente in der Liste
+        //  vi: Der Index des ersten Elementes
+        //  ni: Der Index des zweiten Elementes
+        void tausch( int vi, int ni )
+		{
+			if( vi < 0 || ni < 0 )
+				return;
+			TYP tmp = get( ni );
+			set( get( vi ), ni );
+			set( tmp, vi );
+		}
+
+        // Löscht alle Elemente der Liste
+		void leeren()
+		{
+			ArrayEintrag< TYP > *e2 = 0;
+			for( ArrayEintrag< TYP > *e = einträge; e; e = e->next )
+			{
+				delete e2;
+				e2 = e;
+			}
+			delete e2;
+			einträge = new ArrayEintrag< TYP >();
+			einträge->set = 0;
+			einträge->next = 0;
+		}
+
+        // Gibt das Erste Element der Liste zurück.
+        // Mit ++ kann durch die Liste iteriert werden
+		ArrayEintrag< TYP > &getArray() 
+		{
+			return *einträge;
+		}
+
+		// Gibt zurück, wie viele Elemente in der Liste sind
+		int getEintragAnzahl() const
+		{
+			int i = 0;
+			for( ArrayEintrag< TYP > *e = einträge; e && ( e->set || e->next ); e = e->next )
+				++i;
+			return i;
+		}
+
+        // Gibt den Wert des i-ten Elementes zurück
+        //  i: Der index des gesuchten Elementes
+        // throws:
+        //  std::out_of_range wenn i < 0 oder i >= getEintragAnzahl()
+		TYP get( int i ) const
+		{
+            if( i < 0 )
+            {
+                Text err = "Index out of Range Exception File: ";
+                err += __FILE__;
+                err += " Line: ";
+                err += __LINE__;
+                err += " Index: ";
+                err += i;
+                throw std::out_of_range( err );
+            }
+			ArrayEintrag< TYP > *e = einträge;
+			for( int a = 0; a < i && e; ++a )
+				e = e->next;
+			if( e && e->set )
+				return e->var;
+            Text err = "Index out of Range Exception File: ";
+            err += __FILE__;
+            err += " Line: ";
+            err += __LINE__;
+            err += " Index: ";
+            err += i;
+            throw std::out_of_range( err );
+		}
+
+        // Überprüft, ob ein Element in der Liste enthalten ist
+		//  i: Der Index des gesuchten Elementes
+        //  return: (true), wenn der Index vorhanden ist. (false) sonnst
+        bool hat( int i ) const
+		{
+			if( i < 0 )
+				return 0;
+			ArrayEintrag< TYP > *e = einträge;
+			for( int a = 0; a < i && e; ++a )
+				e = e->next;
+			if( e && e->set )
+				return 1;
+			return 0;
+		}
+
+        // Gibt den Index eines Wertes zurück
+        //  t: Der Wert, nach dem gesucht werden soll
+		int getWertIndex( TYP t ) const
+		{
+			int ret = 0;
+			for( ArrayEintrag< TYP > *e = einträge; e; e = e->next )
+			{
+				if( e->set && e->var == t )
+					return ret;
+				++ret;
+			}
+			return -1;
+		}
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		Array< TYP > *getThis()
+		{
+			++ref;
+			return this;
+		}
+
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		Array< TYP > *release()
+		{
+			--ref;
+			if( !ref )
+				delete this;
+			return 0;
+		}
+	};
+
+    // Eine Linked List von Zeigern auf Zeichnunge, die Reference Counting berteiben
+	template< class TYP >
+	class RCArray
+	{
+	private:
+		ArrayEintrag< TYP* > *einträge;
+		int ref;
+
+	public:
+        // Erstellt eine neue Linked List
+		RCArray()
+		{
+			einträge = new ArrayEintrag< TYP* >();
+			einträge->set = 0;
+			einträge->next = 0;
+			ref = 1;
+		}
+
+        // Leert und löscht die Linked List 
+		~RCArray()
+		{
+			leeren();
+			delete einträge;
+		}
+
+        // Hängt ein Element ans Ende der Liste an
+        //  t: Das neue Element
+		void add( TYP* t )
+		{
+			for( ArrayEintrag< TYP* > *e = einträge; 1; e = e->next )
+			{
+				if( !e->set && !e->next )
+				{
+					e->var = t;
+					e->set = 1;
+					break;
+				}
+				if( !e->next )
+				{
+					e->next = new ArrayEintrag< TYP* >();
+					if( e->next->set && e->next->var )
+						e->next->var->release();
+					e->next->set = 0;
+					e->next->next = 0;
+				}
+			}
+		}
+
+        // Fügt ein Element bei einer bestimmten Position in die Liste ein
+        //  t: das neue Element
+        //  i: Die Position, wo das Element eingefügt wird (danach der Index des neuen Elementes)
+		void add( TYP* t, int i )
+		{
+			if( i < 0 )
+			{
+				if( t )
+					t->release();
+				return;
+			}
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+				{
+					ArrayEintrag< TYP* > *ne = new ArrayEintrag< TYP* >();
+					ne->set = 0;
+					ne->next = 0;
+					e->next = ne;
+				}
+				e = e->next;
+			}
+			ArrayEintrag< TYP* > *ne = new ArrayEintrag< TYP* >();
+			ne->var = e->var;
+			ne->set = e->set;
+			ne->next = e->next;
+			e->next = ne;
+			e->var = t;
+			e->set = 1;
+		}
+
+        // Setzt den Wert des i-ten Eintrags
+        //  t: der Neue Wert
+        //  i: Der Index des Eintrages der gesetzt werden soll
+		void set( TYP* t, int i )
+		{
+			if( i < 0 )
+			{
+				if( t )
+					t->release();
+				return;
+			}
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+				{
+					ArrayEintrag< TYP* > *ne = new ArrayEintrag< TYP* >();
+					ne->set = 0;
+					ne->next = 0;
+					e->next = ne;
+				}
+				e = e->next;
+			}
+			if( e->set && e->var )
+				e->var->release();
+			e->var = t;
+			e->set = 1;
+		}
+
+        // Verändert die Position des i-ten Elementes in der Liste
+        //  i: Der Index des Elementes, welches verschoben werden soll
+        //  p: Die Zielposition des Elementes (danach der neue Index des Elementes)
+		void setPosition( int i, int p )
+		{
+			if( i < 0 || p < 0 || i == p )
+				return;
+			ArrayEintrag< TYP* > *ve = 0;
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+					return;
+				ve = e;
+				e = e->next;
+			}
+			ArrayEintrag< TYP* > *e2 = einträge == e ? e->next : einträge;
+			ArrayEintrag< TYP* > *ve2 = 0;
+			for( int a = 0; a < p; ++a )
+			{
+				if( !e2 )
+					return;
+				ve2 = e2;
+				if( e2->next == e )
+					e2 = e->next;
+				else
+					e2 = e2->next;
+			}
+			if( !e )
+				return;
+			if( !ve2 )
+				einträge = e;
+			else
+				ve2->next = e;
+			if( ve )
+				ve->next = e->next;
+			else
+				einträge = e->next;
+			e->next = e2;
+		}
+
+        // Löscht ein Bestimmtes Element
+        //  i: Der Index des Elementes das gelöscht werden soll
+		void lösche( int i )
+		{
+			if( i < 0 )
+				return;
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i; ++a )
+			{
+				if( !e->next )
+					return;
+				e = e->next;
+			}
+			if( !e )
+				return;
+			if( e->next )
+			{
+				if( e->set && e->var )
+					e->var->release();
+				e->var = e->next->var;
+				e->set = e->next->set;
+			}
+			else
+			{
+				if( e->set && e->var )
+					e->var->release();
+				e->set = 0;
+			}
+			ArrayEintrag< TYP* > *del = e->next;
+			if( e->next )
+				e->next = e->next->next;
+			else
+				e->next = 0;
+			if( del )
+			{
+				del->set = 0;
+				del->next = 0;
+				delete del;
+			}
+		}
+
+        // Vertauscht zwei Elemente in der Liste
+        //  vi: Der Index des ersten Elementes
+        //  ni: Der Index des zweiten Elementes
+		void tausch( int vi, int ni )
+		{
+			if( vi < 0 || ni < 0 )
+				return;
+			TYP* tmp = get( ni );
+			set( get( vi ), ni );
+			set( tmp, vi );
+		}
+
+        // Löscht alle Elemente der Liste
+		void leeren()
+		{
+			ArrayEintrag< TYP* > *e2 = 0;
+			for( ArrayEintrag< TYP* > *e = einträge; e; e = e->next )
+			{
+				if( e2 && e2->var && e2->set )
+					e2->var->release();
+				delete e2;
+				e2 = e;
+			}
+			if( e2 && e2->var && e2->set )
+				e2->var->release();
+			delete e2;
+			einträge = new ArrayEintrag< TYP* >();
+			einträge->set = 0;
+			einträge->next = 0;
+		}
+
+        // Gibt das Erste Element der Liste zurück.
+        // Mit ++ kann durch die Liste iteriert werden
+		ArrayEintrag< TYP* > &getArray()
+		{
+			return *einträge;
+		}
+
+        // Gibt zurück, wie viele Elemente in der Liste sind
+		int getEintragAnzahl() const
+		{
+			int i = 0;
+			for( ArrayEintrag< TYP* > *e = einträge; e && ( e->set || e->next ); e = e->next )
+				++i;
+			return i;
+		}
+
+        // Gibt den Wert des i-ten Elementes zurück mit erhöhtem Reference Counter
+        //  i: Der index des gesuchten Elementes, (0) wenn der Index nicht existiert
+		TYP *get( int i ) const
+		{
+			if( i < 0 )
+				return (TYP*)0;
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i && e; ++a )
+				e = e->next;
+			if( e && e->set && e->var )
+				return (TYP*)e->var->getThis();
+			return (TYP*)0;
+		}
+
+        // Gibt den Wert des i-ten Elementes zurück ohne erhöhten Reference Counter
+        //  i: Der index des gesuchten Elementes, (0) wenn der Index nicht existiert
+		TYP *z( int i ) const // gibt den index - ten T zurück
+		{
+			if( i < 0 )
+				return (TYP*)0;
+			ArrayEintrag< TYP* > *e = einträge;
+			for( int a = 0; a < i && e; ++a )
+				e = e->next;
+			if( e && e->set && e->var )
+				return (TYP*)e->var;
+			return (TYP*)0;
+		}
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		RCArray< TYP > *getThis()
+		{
+			++ref;
+			return this;
+		}
+
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		RCArray< TYP > *release()
+		{
+			--ref;
+			if( !ref )
+				delete this;
+			return 0;
+		}
+	};
+}
+
+#endif

+ 2210 - 0
AuswahlBox.cpp

@@ -0,0 +1,2210 @@
+#include "AuswahlBox.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Rahmen.h"
+#include "Scroll.h"
+#include "TextFeld.h"
+#include "Knopf.h"
+#include "Text.h"
+#include "Schrift.h"
+#include "ToolTip.h"
+
+using namespace Framework;
+
+// Inhalt der AuswahlBox Klasse aus AuswahlBox.h
+// Konstruktor 
+AuswahlBox::AuswahlBox()
+	: ZeichnungHintergrund(),
+	schrift( 0 ),
+	msStyle( 0 ),
+	members( new RCArray< TextFeld >() ),
+	ausfahren( new Knopf() ),
+	auswRahmen( new LRahmen() ),
+	auswBgF( 0xFF000000 ),
+	auswBgB( 0 ),
+	auswAf( new AlphaFeld() ),
+	msAuswRahmen( 0 ),
+	msAuswBgF( 0 ),
+	msAuswBgB( 0 ),
+	msAuswAf( 0 ),
+	mausRahmen( new LRahmen() ),
+	mausBgF( 0xFF000000 ),
+	mausBgB( 0 ),
+	mausAf( new AlphaFeld() ),
+	msMausRahmen( 0 ),
+	msMausBgF( 0 ),
+	msMausBgB( 0 ),
+	msMausAf( 0 ),
+	anzahl( 0 ),
+	auswahl( 0 ),
+	ausgeklappt( 0 ),
+	ausklappHöhe( 0 ),
+	ausklapMaxHöhe( 200 ),
+	eintragHöhe( 15 ),
+	tickval( 0 ),
+	mausEintrag( 0 ),
+	scrollAnzeigen( 0 ),
+	eAkP( 0 ),
+	eAk( 0 ),
+	ref( 1 )
+{
+    vertikalScrollBar = new VScrollBar();
+    style = Style::Normal;
+    rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	ausfahren->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::KlickBuffer );
+	ausfahren->setKBFarbe( 0xA0000000 );
+	ausfahren->setKBStärke( 10 );
+	ausfahren->setGröße( 18, 18 );
+	ausfahren->setSchriftFarbe( 0xFFFFFFFF );
+	ausfahren->setText( "\\/" );
+	auswRahmen->setFarbe( 0xFF00FF00 );
+	auswRahmen->setRamenBreite( 1 );
+	auswAf->setFarbe( 0xA000FF00 );
+	auswAf->setStärke( 7 );
+	mausRahmen->setFarbe( 0xFF00FF00 );
+	mausRahmen->setRamenBreite( 1 );
+	mausAf->setFarbe( 0x5000FF00 );
+	mausAf->setStärke( 7 );
+	gr.x = 20;
+	gr.y = 20;
+}
+
+// Destruktor 
+AuswahlBox::~AuswahlBox()
+{
+	if( schrift )
+		schrift->release();
+	if( msStyle )
+		msStyle->release();
+	if( members )
+		members->release();
+	if( ausfahren )
+		ausfahren->release();
+	if( auswRahmen )
+		auswRahmen->release();
+	if( auswBgB )
+		auswBgB->release();
+	if( auswAf )
+		auswAf->release();
+	if( msAuswRahmen )
+		msAuswRahmen->release();
+	if( msAuswAf )
+		msAuswAf->release();
+	if( msAuswBgB )
+		msAuswBgB->release();
+	if( msAuswBgF )
+		msAuswBgF->release();
+	if( mausRahmen )
+		mausRahmen->release();
+	if( mausAf )
+		mausAf->release();
+	if( mausBgB )
+		mausBgB->release();
+	if( msMausRahmen )
+		msMausRahmen->release();
+	if( msMausAf )
+		msMausAf->release();
+	if( msMausBgB )
+		msMausBgB->release();
+	if( msMausBgF )
+		msMausBgF->release();
+}
+
+// nicht constant
+void AuswahlBox::setEventParam( void *p ) // setzt den Event Parameter
+{
+	eAkP = p;
+}
+
+void AuswahlBox::setEventAktion( void( *eAk )( void *p, AuswahlBox *, int, int ) ) // setzt die Event Funktion
+{
+	this->eAk = eAk;
+}
+
+void AuswahlBox::setSchriftZ( Schrift *schrift ) // setzt die schrift
+{
+	if( this->schrift )
+		this->schrift->release();
+	this->schrift = schrift;
+	ausfahren->setSchriftZ( schrift->getThis() );
+	rend = 1;
+}
+
+void AuswahlBox::addEintrag( const char *txt ) // Eintrag hinzufügen
+{
+	TextFeld *tf = new TextFeld();
+	if( schrift )
+		tf->setSchriftZ( schrift->getThis() );
+	tf->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
+	tf->setText( txt );
+	tf->setSchriftFarbe( 0xFFFFFFFF );
+	tf->setLinienRahmenFarbe( 0xFFFFFFFF );
+	tf->setGröße( 0, eintragHöhe );
+	members->add( tf, anzahl );
+	++anzahl;
+	rend = 1;
+}
+
+void AuswahlBox::addEintrag( Text *txt )
+{
+	TextFeld *tf = new TextFeld();
+	if( schrift )
+		tf->setSchriftZ( schrift->getThis() );
+	tf->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
+	tf->setText( txt );
+	tf->setSchriftFarbe( 0xFFFFFFFF );
+	tf->setLinienRahmenFarbe( 0xFFFFFFFF );
+	tf->setGröße( 0, eintragHöhe );
+	members->add( tf, anzahl );
+	++anzahl;
+	rend = 1;
+}
+
+void AuswahlBox::addEintragZ( TextFeld *txt )
+{
+	members->add( txt, anzahl );
+	++anzahl;
+	rend = 1;
+}
+
+void AuswahlBox::setEintrag( int i, const char *txt ) // Eintrag setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setText( txt );
+	rend = 1;
+}
+
+void AuswahlBox::setEintrag( int i, Text *txt )
+{
+	if( members->z( i ) )
+		members->z( i )->setText( txt );
+	else
+		txt->release();
+	rend = 1;
+}
+
+void AuswahlBox::setEintragZ( int i, TextFeld *txt )
+{
+	if( i < anzahl )
+		members->set( txt, i );
+	else
+		txt->release();
+	rend = 1;
+}
+
+void AuswahlBox::löscheEintrag( int i ) // Eintrag entfernen
+{
+	if( i < anzahl )
+	{
+		members->lösche( i );
+		if( msStyle )
+			msStyle->lösche( i );
+		if( msAuswRahmen )
+			msAuswRahmen->lösche( i );
+		if( msAuswBgF )
+			msAuswBgF->lösche( i );
+		if( msAuswBgB )
+			msAuswBgB->lösche( i );
+		if( msAuswAf )
+			msAuswAf->lösche( i );
+		if( msMausRahmen )
+			msMausRahmen->lösche( i );
+		if( msMausBgF )
+			msMausBgF->lösche( i );
+		if( msMausBgB )
+			msMausBgB->lösche( i );
+		if( msMausAf )
+			msMausAf->lösche( i );
+		if( auswahl > i )
+			--auswahl;
+		if( mausEintrag > i )
+			--mausEintrag;
+		--anzahl;
+		rend = 1;
+	}
+}
+
+void AuswahlBox::setAusklappKnopfZ( Knopf *ausK ) // Ausklapp Knopf setzen
+{
+	if( ausfahren )
+		ausfahren->release();
+	ausfahren = ausK;
+	rend = 1;
+}
+
+void AuswahlBox::setEintragRahmenZ( int i, LRahmen *rahmen ) // Eintrag Rahmen setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setLinienRahmenZ( rahmen );
+	else
+		rahmen->release();
+	rend = 1;
+}
+
+void AuswahlBox::setEintragRahmenFarbe( int i, int f ) // Eintrag Rahmen Farbe setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setLinienRahmenFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setEintragRahmenBreite( int i, int rbr ) // Eintrag Rahmen Breite setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setLinienRahmenBreite( rbr );
+	rend = 1;
+}
+
+void AuswahlBox::setEintragHintergrundFarbe( int i, int f ) // Eintrag Hintergrund farbe setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setHintergrundFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setEintragHintergrundBildZ( int i, Bild *bgB ) // Eintrag Hintergrund Bild setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setHintergrundBildZ( bgB );
+	else
+		bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setEintragHintergrundBild( int i, Bild *bgB )
+{
+	if( members->z( i ) )
+		members->z( i )->setHintergrundBild( bgB );
+	else
+		bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setEintragAlphaFeldZ( int i, AlphaFeld *af ) // Eintrag AlphaFeld setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setAlphaFeldZ( af );
+	rend = 1;
+}
+
+void AuswahlBox::setEintragAlphaFeldFarbe( int i, int afF ) // Eintrag AlphaFeld Farbe setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setAlphaFeldFarbe( afF );
+	rend = 1;
+}
+
+void AuswahlBox::setEintragAlphaFeldStärke( int i, int afSt ) // Eintrag AlphaFeld Stärke setzen
+{
+	if( members->z( i ) )
+		members->z( i )->setAlphaFeldStärke( afSt );
+	rend = 1;
+}
+
+void AuswahlBox::setAuswRahmenZ( LRahmen *rahmen ) // Auswahl Rahmen setzen
+{
+	if( auswRahmen )
+		auswRahmen->release();
+	auswRahmen = rahmen;
+	rend = 1;
+}
+
+void AuswahlBox::setAuswRahmenFarbe( int f ) // Auswahl Rahmen Farbe setzen
+{
+	if( !auswRahmen )
+		auswRahmen = new LRahmen();
+	auswRahmen->setFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setAuswRahmenBreite( int rbr ) // Auswahl Rahmen Breite setzen
+{
+	if( !auswRahmen )
+		auswRahmen = new LRahmen();
+	auswRahmen->setRamenBreite( rbr );
+	rend = 1;
+}
+
+void AuswahlBox::setAuswHintergrundFarbe( int f ) // Auswahl Hintergrund Farbe setzen
+{
+	auswBgF = f;
+	rend = 1;
+}
+
+void AuswahlBox::setAuswHintergrundBildZ( Bild *bgB ) // Auswahl Hintergrund Bild setzen
+{
+	if( auswBgB )
+		auswBgB->release();
+	auswBgB = bgB;
+	rend = 1;
+}
+
+void AuswahlBox::setAuswHintergrundBild( Bild *bgB )
+{
+	if( !auswBgB )
+		auswBgB = new Bild();
+	auswBgB->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+	auswBgB->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+	bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setAuswAlphaFeldZ( AlphaFeld *af ) // Auswahl AlphaFeld setzen
+{
+	if( auswAf )
+		auswAf->release();
+	auswAf = af;
+	rend = 1;
+}
+
+void AuswahlBox::setAuswAlphaFeldFarbe( int afF ) // Auswahl AlphaFeld Farbe setzen
+{
+	if( !auswAf )
+		auswAf = new AlphaFeld();
+	auswAf->setFarbe( afF );
+	rend = 1;
+}
+
+void AuswahlBox::setAuswAlphaFeldStärke( int afSt ) // Auswahl Alpha Feld stärke setzen
+{
+	if( !auswAf )
+		auswAf = new AlphaFeld();
+	auswAf->setStärke( afSt );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswRahmenZ( int i, LRahmen *rahmen ) // Multistyle Auswahl Rahmen setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		rahmen->release();
+		return;
+	}
+	if( !msAuswRahmen )
+		msAuswRahmen = new RCArray< LRahmen >();
+	msAuswRahmen->set( rahmen, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswRahmenFarbe( int i, int f ) // Multistyle Auswahl Rahmen Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msAuswRahmen )
+		msAuswRahmen = new RCArray< LRahmen >();
+	if( !msAuswRahmen->z( i ) )
+		msAuswRahmen->set( new LRahmen(), i );
+	msAuswRahmen->z( i )->setFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswRahmenBreite( int i, int rbr ) // Multistyle Auswahl Breite setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msAuswRahmen )
+		msAuswRahmen = new RCArray< LRahmen >();
+	if( !msAuswRahmen->z( i ) )
+		msAuswRahmen->set( new LRahmen(), i );
+	msAuswRahmen->z( i )->setRamenBreite( rbr );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswHintergrundFarbe( int i, int f ) // Multistyle Auswahl Hintergrund Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msAuswBgF )
+		msAuswBgF = new Array< int >();
+	msAuswBgF->set( f, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswHintergrundBildZ( int i, Bild *bgB ) // Multistyle Auswahl Hintergrund Bild setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		bgB->release();
+		return;
+	}
+	if( !msAuswBgB )
+		msAuswBgB = new RCArray< Bild >();
+	msAuswBgB->set( bgB, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswHintergrundBild( int i, Bild *bgB )
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		bgB->release();
+		return;
+	}
+	if( !msAuswBgB )
+		msAuswBgB = new RCArray< Bild >();
+	if( !msAuswBgB->z( i ) )
+	{
+		Bild *z = new Bild;
+		z->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+		z->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+		msAuswBgB->set( z, i );
+	}
+	else
+	{
+		msAuswBgB->z( i )->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+		msAuswBgB->z( i )->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+	}
+	bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswAlphaFeldZ( int i, AlphaFeld *af ) // Multistyle Auswahl AlphaFeld setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		af->release();
+		return;
+	}
+	if( !msAuswAf )
+		msAuswAf = new RCArray< AlphaFeld >();
+	msAuswAf->set( af, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswAlphaFeldFarbe( int i, int afF ) // Multistyle Auswahl AlphaFeld Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msAuswAf )
+		msAuswAf = new RCArray< AlphaFeld >();
+	if( !msAuswAf->z( i ) )
+		msAuswAf->set( new AlphaFeld(), i );
+	msAuswAf->z( i )->setFarbe( afF );
+	rend = 1;
+}
+
+void AuswahlBox::setMsAuswAlphaFeldStärke( int i, int afSt ) // Multistyle Auswahl AlphaFeld stärke setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msAuswAf )
+		msAuswAf = new RCArray< AlphaFeld >();
+	if( !msAuswAf->z( i ) )
+		msAuswAf->set( new AlphaFeld(), i );
+	msAuswAf->z( i )->setStärke( afSt );
+	rend = 1;
+}
+
+void AuswahlBox::setMausRahmenZ( LRahmen *rahmen ) // Maus Rahmen setzen
+{
+	if( mausRahmen )
+		mausRahmen->release();
+	mausRahmen = rahmen;
+	rend = 1;
+}
+
+void AuswahlBox::setMausRahmenFarbe( int f ) // Maus Rahmen Farbe setzen
+{
+	if( !mausRahmen )
+		mausRahmen = new LRahmen();
+	mausRahmen->setFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setMausRahmenBreite( int rbr ) // Maus Rahmen breite setzen
+{
+	if( !mausRahmen )
+		mausRahmen = new LRahmen();
+	mausRahmen->setRamenBreite( rbr );
+	rend = 1;
+}
+
+void AuswahlBox::setMausHintergrundFarbe( int f ) // Maus Hintergrund Farbe setzen
+{
+	mausBgF = f;
+	rend = 1;
+}
+
+void AuswahlBox::setMausHintergrundBildZ( Bild *bgB ) // Maus Hintergrund Bild setzen
+{
+	if( mausBgB )
+		mausBgB->release();
+	mausBgB = bgB;
+	rend = 1;
+}
+
+void AuswahlBox::setMausHintergrundBild( Bild *bgB )
+{
+	if( !mausBgB )
+		mausBgB = new Bild();
+	mausBgB->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+	mausBgB->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+	bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setMausAlphaFeldZ( AlphaFeld *af ) // Maus AlphaFeld setzen
+{
+	if( mausAf )
+		mausAf->release();
+	mausAf = af;
+	rend = 1;
+}
+
+void AuswahlBox::setMausAlphaFeldFarbe( int afF ) // Maus AlphaFeld Farbe setzen
+{
+	if( !mausAf )
+		mausAf = new AlphaFeld();
+	mausAf->setFarbe( afF );
+	rend = 1;
+}
+
+void AuswahlBox::setMausAlphaFeldStärke( int afSt ) // Maus AlphaFeld stärke setzen
+{
+	if( !mausAf )
+		mausAf = new AlphaFeld();
+	mausAf->setStärke( afSt );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausRahmenZ( int i, LRahmen *rahmen ) // Multistyle Maus Rahmen setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		rahmen->release();
+		return;
+	}
+	if( !msMausRahmen )
+		msMausRahmen = new RCArray< LRahmen >();
+	msMausRahmen->set( rahmen, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausRahmenFarbe( int i, int f ) // Multistyle Maus Rahmen Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msMausRahmen )
+		msMausRahmen = new RCArray< LRahmen >();
+	if( !msMausRahmen->z( i ) )
+		msMausRahmen->set( new LRahmen(), i );
+	msMausRahmen->z( i )->setFarbe( f );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausRahmenBreite( int i, int rbr ) // Multistyle Maus Rahmen breite setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msMausRahmen )
+		msMausRahmen = new RCArray< LRahmen >();
+	if( !msMausRahmen->z( i ) )
+		msMausRahmen->set( new LRahmen(), i );
+	msMausRahmen->z( i )->setRamenBreite( rbr );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausHintergrundFarbe( int i, int f ) // Multistyle Maus Hintergrund Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msMausBgF )
+		msMausBgF = new Array< int >();
+	msMausBgF->set( f, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausHintergrundBildZ( int i, Bild *bgB ) // Multistyle Maus Hintergrund Bild setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		bgB->release();
+		return;
+	}
+	if( !msMausBgB )
+		msMausBgB = new RCArray< Bild >();
+	msMausBgB->set( bgB, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausHintergrundBild( int i, Bild *bgB )
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		bgB->release();
+		return;
+	}
+	if( !msMausBgB )
+		msMausBgB = new RCArray< Bild >();
+	if( !msMausBgB->z( i ) )
+	{
+		Bild *z = new Bild;
+		z->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+		z->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+		msMausBgB->set( z, i );
+	}
+	else
+	{
+		msMausBgB->z( i )->neuBild( bgB->getBreite(), bgB->getHöhe(), 0 );
+		msMausBgB->z( i )->drawBild( 0, 0, bgB->getBreite(), bgB->getHöhe(), *bgB );
+	}
+	bgB->release();
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausAlphaFeldZ( int i, AlphaFeld *af ) // Multistyle Maus AlphaFeld setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+	{
+		af->release();
+		return;
+	}
+	if( !msMausAf )
+		msMausAf = new RCArray< AlphaFeld >();
+	msMausAf->set( af, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausAlphaFeldFarbe( int i, int afF ) // Multistyle Maus AlphaFeld Farbe setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msMausAf )
+		msMausAf = new RCArray< AlphaFeld >();
+	if( !msMausAf->z( i ) )
+		msMausAf->set( new AlphaFeld(), i );
+	msMausAf->z( i )->setFarbe( afF );
+	rend = 1;
+}
+
+void AuswahlBox::setMsMausAlphaFeldStärke( int i, int afSt ) // Multistyle Maus AlphaFeld stärke setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msMausAf )
+		msMausAf = new RCArray< AlphaFeld >();
+	if( !msMausAf->z( i ) )
+		msMausAf->set( new AlphaFeld(), i );
+	msMausAf->z( i )->setStärke( afSt );
+	rend = 1;
+}
+
+void AuswahlBox::setAuswahl( int i ) // Eintrag auswählen
+{
+	if( i < anzahl )
+	{
+		auswahl = i;
+		if( eAk )
+			eAk( eAkP, this, 0, auswahl );
+		rend = 1;
+	}
+}
+
+void AuswahlBox::ausklappen() // liste ausklappen
+{
+	ausgeklappt = 1;
+}
+
+void AuswahlBox::einklappen() // liste einklappen
+{
+	ausgeklappt = 0;
+}
+
+void AuswahlBox::scrollZuEintrag( int i ) // liste scrollen
+{
+	if( hatStyle( Style::VScroll ) && vertikalScrollBar && i < anzahl )
+	{
+		int scrollPos = 0;
+		if( hatStyle( Style::MultiStyled ) )
+		{
+			for( int j = 0; j < i; ++j )
+				scrollPos += members->z( j ) ? members->z( j )->getHöhe() : 0;
+		}
+		else
+			scrollPos += i * eintragHöhe;
+        vertikalScrollBar->scroll( scrollPos );
+		rend = 1;
+	}
+}
+
+void AuswahlBox::setMaxAuskappHöhe( int maxHöhe ) // höhe der Liste beim ausklappen
+{
+	ausklapMaxHöhe = maxHöhe;
+}
+
+void AuswahlBox::setEintragHöhe( int höhe ) // setzt die Höhe der Einträge
+{
+	eintragHöhe = höhe;
+}
+
+void AuswahlBox::addMsStyle( int i, __int64 abStyle ) // Multistyle style hinzufügen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msStyle )
+		msStyle = new Array< __int64 >();
+	msStyle->set( msStyle->get( i ) | abStyle, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsStyle( int i, __int64 abStyle, bool add ) // Multistyle style setzen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msStyle )
+		msStyle = new Array< __int64 >();
+	if( add )
+		msStyle->set( msStyle->get( i ) | abStyle, i );
+	else
+		msStyle->set( msStyle->get( i ) & ~abStyle, i );
+	rend = 1;
+}
+
+void AuswahlBox::setMsStyle( int i, __int64 abStyle )
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msStyle )
+		msStyle = new Array< __int64 >();
+	msStyle->set( abStyle, i );
+	rend = 1;
+}
+
+void AuswahlBox::löscheMsStyle( int i, __int64 abStyle ) // Multistyle style entfernen
+{
+	if( hatStyleNicht( Style::MultiStyled ) || i >= anzahl )
+		return;
+	if( !msStyle )
+		msStyle = new Array< __int64 >();
+	msStyle->set( msStyle->get( i ) & ~abStyle, i );
+	rend = 1;
+}
+
+bool AuswahlBox::tick( double tickVal ) // tick
+{
+	if( ausgeklappt && ausfahren && !ausfahren->zText()->istGleich( "/\\" ) )
+	{
+		ausfahren->setText( "/\\" );
+		rend = 1;
+	}
+	else if( !ausgeklappt && ausfahren && !ausfahren->zText()->istGleich( "\\/" ) )
+	{
+		ausfahren->setText( "\\/" );
+		rend = 1;
+	}
+	if( hatStyleNicht( Style::Sichtbar ) || hatStyleNicht( Style::Erlaubt ) )
+		ausgeklappt = 0;
+	rend |= ausfahren->tick( tickVal );
+	this->tickval += tickVal * 300;
+	int val = ( int )this->tickval;
+	if( val < 1 )
+		return __super::tick( tickVal );
+	this->tickval -= val;
+	int maxHöhe = rahmen ? rahmen->getRBreite() : 0;
+	if( hatStyleNicht( Style::MultiStyled ) )
+		maxHöhe += anzahl * eintragHöhe;
+	else
+	for( int i = 0; i < anzahl; ++i )
+		maxHöhe += members->z( i ) ? members->z( i )->getHöhe() : 0;
+	if( maxHöhe > ausklapMaxHöhe )
+	{
+		if( hatStyle( Style::VScroll ) && vertikalScrollBar )
+		{
+			scrollAnzeigen = 1;
+            vertikalScrollBar->update( maxHöhe, ausklapMaxHöhe );
+		}
+		maxHöhe = ausklapMaxHöhe;
+	}
+	else
+		scrollAnzeigen = 0;
+	if( ausgeklappt )
+	{
+		if( ausklappHöhe < maxHöhe )
+		{
+			ausklappHöhe += val;
+			if( ausklappHöhe > maxHöhe )
+				ausklappHöhe = maxHöhe;
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( ausklappHöhe > 0 )
+		{
+			ausklappHöhe -= val;
+			if( ausklappHöhe < 0 )
+				ausklappHöhe = 0;
+			rend = 1;
+		}
+	}
+	for( int i = 0; i < anzahl; ++i )
+	{
+		if( i != auswahl )
+			rend |= members->z( i )->tick( tickVal );
+		else
+			members->z( i )->tick( tickVal );
+	}
+    return __super::tick( tickVal );
+}
+
+void AuswahlBox::doMausEreignis( MausEreignis &me ) // Maus
+{
+	if( me.id == ME_DScroll )
+		int i = 0;
+	mausEintrag = -1;
+	if( hatStyleNicht( Style::Sichtbar ) || hatStyleNicht( Style::Erlaubt ) )
+	{
+		if( toolTip )
+			toolTip->setMausIn( 0 );
+		ausgeklappt = 0;
+		return;
+	}
+	bool removeFokus = 0;
+    bool nmakc = me.verarbeitet == 0;
+	if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y + ausklappHöhe ) )
+	{
+		if( mausIn )
+		{
+			if( toolTip )
+				toolTip->setMausIn( 0 );
+			mausIn = 0;
+			MausEreignis me2;
+			me2.id = ME_Verlässt;
+			me2.mx = me.mx;
+			me2.my = me.my;
+			me2.verarbeitet = 0;
+			doMausEreignis( me2 );
+			return;
+		}
+		removeFokus = 1;
+	}
+	if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y + ausklappHöhe ) && me.id != ME_Verlässt )
+	{
+		if( removeFokus && me.id == ME_RLinks )
+		{
+			if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+				löscheStyle( Style::Fokus );
+			ausgeklappt = 0;
+            me.mx -= pos.x, me.my -= pos.y;
+            if( nmakc && me.verarbeitet && nMak )
+                me.verarbeitet = nMak( nmakParam, this, me );
+            me.mx += pos.x, me.my += pos.y;
+		}
+		if( toolTip )
+			toolTip->setMausIn( 0 );
+		return;
+	}
+	if( !mausIn && me.id != ME_Verlässt )
+	{
+		mausIn = 1;
+		if( toolTip )
+			toolTip->setMausIn( 1 );
+		MausEreignis me2;
+		me2.id = ME_Betritt;
+		me2.mx = me.mx;
+		me2.my = me.my;
+		me2.verarbeitet = 0;
+		doMausEreignis( me2 );
+	}
+	me.mx -= pos.x, me.my -= pos.y;
+	if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+	{
+		bool vera = me.verarbeitet;
+		if( ausfahren )
+		{
+			int tmpMx = me.mx;
+			int tmpMy = me.my;
+			if( me.mx > 0 && me.my > 0 && me.mx < gr.x && me.my < gr.y )
+				me.mx = ausfahren->getX() + 1, me.my = ausfahren->getY() + 1;
+			else
+				me.mx = ausfahren->getX() - 1, me.my = ausfahren->getY() - 1;
+			ausfahren->doMausEreignis( me );
+			me.mx = tmpMx, me.my = tmpMy;
+		}
+		if( me.verarbeitet && !vera && me.id == ME_RLinks )
+		{
+			ausgeklappt = !ausgeklappt;
+			if( ausgeklappt )
+				mausEintrag = auswahl;
+			if( scrollAnzeigen )
+				scrollZuEintrag( mausEintrag );
+		}
+		if( removeFokus && me.id == ME_RLinks )
+			löscheStyle( Style::Fokus );
+		if( !me.verarbeitet && hatStyleNicht( Style::Fokus ) && me.id == ME_RLinks )
+			addStyle( Style::Fokus );
+		if( hatStyle( Style::VScroll ) && vertikalScrollBar && ausgeklappt && scrollAnzeigen )
+		{
+			int rbr = 0;
+			if( rahmen && hatStyle( Style::Rahmen ) )
+				rbr = rahmen->getRBreite();
+			if( ( ( me.mx > gr.x - 15 - rbr && me.my > gr.y ) || me.id == ME_UScroll || me.id == ME_DScroll ) && me.id != ME_Betritt && me.id != ME_Verlässt )
+			{
+                vertikalScrollBar->doMausMessage( gr.x - rbr - 15, gr.y, 15, vertikalScrollBar->getScrollData()->anzeigeHöhe, me );
+				me.verarbeitet = 1;
+			}
+		}
+		if( !me.verarbeitet )
+		{
+			int eintr = -1;
+			int tmp = me.my - gr.y + ( vertikalScrollBar ? vertikalScrollBar->getScroll() : 0 );
+			if( hatStyle( Style::MultiStyled ) )
+			{
+				for( int i = 0; i < anzahl; ++i )
+				{
+					if( tmp > 0 && tmp < ( members->z( i ) ? members->z( i )->getHöhe() : 0 ) )
+					{
+						eintr = i;
+						break;
+					}
+					tmp -= members->z( i ) ? members->z( i )->getHöhe() : 0;
+				}
+			}
+			else
+			{
+				for( int i = 0; i < anzahl; ++i )
+				{
+					if( tmp > 0 && tmp < eintragHöhe )
+					{
+						eintr = i;
+						break;
+					}
+					tmp -= eintragHöhe;
+				}
+			}
+			if( ausgeklappt && me.mx > 0 && me.mx < gr.x && me.my > gr.y && me.my < gr.y + ausklappHöhe )
+			{
+				if( eintr >= 0 )
+				{
+					if( me.id == ME_RLinks )
+					{
+						if( auswahl != eintr )
+							rend = 1;
+						auswahl = eintr;
+						if( eAk )
+							eAk( eAkP, this, 0, auswahl );
+					}
+					if( mausEintrag != eintr )
+						rend = 1;
+					mausEintrag = eintr;
+				}
+			}
+		}
+		me.verarbeitet = 1;
+	}
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+	me.mx += pos.x, me.my += pos.y;
+}
+
+void AuswahlBox::doTastaturEreignis( TastaturEreignis &te ) // Tastatur
+{
+	if( te.verarbeitet || hatStyleNicht( Style::Fokus ) || hatStyleNicht( Style::Erlaubt ) )
+		return;
+	if( te.id == TE_Release )
+	{
+		switch( te.taste )
+		{
+		case T_Oben:
+			if( auswahl > 0 )
+				--auswahl;
+			else
+				auswahl = anzahl - 1;
+			if( eAk )
+				eAk( eAkP, this, 0, auswahl );
+			scrollZuEintrag( auswahl );
+			rend = 1;
+			break;
+		case T_Unten:
+			if( auswahl < anzahl - 1 )
+				++auswahl;
+			else
+				auswahl = 0;
+			if( eAk )
+				eAk( eAkP, this, 0, auswahl );
+			scrollZuEintrag( auswahl );
+			rend = 1;
+			break;
+		}
+	}
+    if( te.verarbeitet && nTak )
+        te.verarbeitet = nTak( ntakParam, this, te );
+}
+
+void AuswahlBox::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+	if( hatStyle( Style::Sichtbar ) )
+	{
+		lockZeichnung();
+		int br = gr.x;
+		int hö = gr.y + ausklappHöhe;
+		if( ( ausklappHöhe && !zRObj.setDrawOptionsErzwingen( pos.x, pos.y, br, hö ) ) || ( !ausklappHöhe && !zRObj.setDrawOptions( pos.x, pos.y, br, hö ) ) )
+		{
+			unlockZeichnung();
+			return;
+		}
+		int rbr = 0;
+		if( hatStyle( Style::Rahmen ) && rahmen ) // Rahmen zeichnen
+		{
+			rahmen->setGröße( br, hö );
+			rahmen->render( zRObj );
+			rbr = rahmen->getRBreite();
+		}
+		if( ( ausklappHöhe && !zRObj.setDrawOptionsErzwingen( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) ) || ( !ausklappHöhe && !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) ) )
+		{
+			zRObj.releaseDrawOptions();
+			unlockZeichnung();
+			return;
+		}
+		if( hatStyle( Style::Hintergrund ) )
+		{
+			if( hatStyle( Style::HAlpha ) )
+				zRObj.alphaRegion( 0, 0, br, hö, hintergrundFarbe );
+			else
+				zRObj.füllRegion( 0, 0, br, hö, hintergrundFarbe );
+            if( hatStyle( Style::HBild ) && hintergrundBild )
+            {
+                if( hatStyle( Style::HAlpha ) )
+                    zRObj.alphaBild( 0, 0, br, hö, *hintergrundBild );
+                else
+                    zRObj.drawBild( 0, 0, br, hö, *hintergrundBild );
+            }
+		}
+		if( hatStyle( Style::Buffered ) && hintergrundFeld )
+		{
+            hintergrundFeld->setGröße( br - rbr * 2, hö - rbr * 2 );
+            hintergrundFeld->render( zRObj );
+		}
+		if( ausfahren ) // Ausklapp Knopf zeichnen
+		{
+			ausfahren->setGröße( gr.y - rbr * 2, gr.y - rbr * 2 );
+			ausfahren->setPosition( gr.x - rbr - ausfahren->getBreite(), rbr );
+			ausfahren->render( zRObj );
+		}
+		if( members ) // Ausgewähtes TextFeld zeichnen
+		{
+			if( auswahl < 0 )
+			{
+				auswahl = 0;
+				if( eAk )
+					eAk( eAkP, this, 0, auswahl );
+			}
+			if( auswahl >= anzahl )
+			{
+				auswahl = anzahl - 1;
+				if( eAk )
+					eAk( eAkP, this, 0, auswahl );
+			}
+			TextFeld *tf = auswahl >= 0 ? members->z( auswahl ) : 0;
+			if( tf )
+			{
+				AlphaFeld *tmpBuffer = 0;
+				bool tmpB = 0;
+				int tmpHFarbe = 0;
+				bool tmpH = 0;
+				Bild *tmpHBild = 0;
+				bool tmpHB = 0;
+				bool tmpHAlpha = 0;
+				LRahmen *tmpRahmen = 0;
+				bool tmpR = 0;
+				if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+				{
+					if( hatStyle( Style::AuswahlBuffer ) )
+					{
+						tmpBuffer = tf->getAlphaFeld();
+						tf->setAlphaFeldZ( auswAf->getThis() );
+						tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+						tf->setStyle( TextFeld::Style::Buffered, hatStyle( Style::AuswahlBuffer ) );
+					}
+					if( hatStyle( Style::AuswahlHintergrund ) )
+					{
+						tmpH = tf->hatStyle( TextFeld::Style::Hintergrund );
+						tmpHFarbe = tf->getHintergrundFarbe();
+						tf->setHintergrundFarbe( auswBgF );
+						tf->setStyle( TextFeld::Style::Hintergrund, hatStyle( Style::Hintergrund ) );
+						if( hatStyle( Style::AuswahlHBild ) )
+						{
+							tmpHBild = tf->getHintergrundBild();
+							tf->setHintergrundBildZ( auswBgB->getThis() );
+							tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+							tf->setStyle( TextFeld::Style::HBild, hatStyle( Style::HBild ) );
+						}
+						if( hatStyle( Style::AuswahlHAlpha ) )
+						{
+							tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+							tf->setStyle( TextFeld::Style::HAlpha, hatStyle( Style::AuswahlHAlpha ) );
+						}
+					}
+					if( hatStyle( Style::AuswahlRahmen ) )
+					{
+						tmpRahmen = tf->getLinienRahmen();
+						tf->setLinienRahmenZ( auswRahmen->getThis() );
+						tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+						tf->setStyle( TextFeld::Style::Rahmen, hatStyle( Style::AuswahlRahmen ) );
+					}
+				}
+				else
+				{
+					if( hatMsStyle( auswahl, Style::AuswahlBuffer ) && msAuswAf )
+					{
+						tmpBuffer = tf->getAlphaFeld();
+						tf->setAlphaFeldZ( msAuswAf->get( auswahl ) );
+						tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+						tf->setStyle( TextFeld::Style::Buffered, hatMsStyle( auswahl, Style::AuswahlBuffer ) );
+					}
+					if( hatMsStyle( auswahl, Style::AuswahlHintergrund ) )
+					{
+						tmpH = tf->hatStyle( Style::Hintergrund );
+						tf->setStyle( TextFeld::Style::Hintergrund, hatMsStyle( auswahl, Style::AuswahlHintergrund ) );
+						if( msAuswBgF && msAuswBgF->hat( auswahl ) )
+						{
+							tmpHFarbe = tf->getHintergrundFarbe();
+							tf->setHintergrundFarbe( msAuswBgF->get( auswahl ) );
+						}
+						if( hatMsStyle( auswahl, Style::AuswahlHBild ) && msAuswBgB )
+						{
+							tmpHBild = tf->getHintergrundBild();
+							tf->setHintergrundBildZ( msAuswBgB->get( auswahl ) );
+							tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+							tf->setStyle( TextFeld::Style::HBild, hatMsStyle( auswahl, Style::HBild ) );
+						}
+						if( hatMsStyle( auswahl, Style::AuswahlHAlpha ) )
+						{
+							tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+							tf->setStyle( TextFeld::Style::HAlpha, hatMsStyle( auswahl, Style::AuswahlHAlpha ) );
+						}
+					}
+					if( hatMsStyle( auswahl, Style::AuswahlRahmen ) && msAuswRahmen )
+					{
+						tmpRahmen = tf->getLinienRahmen();
+						tf->setLinienRahmenZ( msAuswRahmen->get( auswahl ) );
+						tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+						tf->setStyle( TextFeld::Style::Rahmen, hatMsStyle( auswahl, Style::AuswahlRahmen ) );
+					}
+				}
+				int tmpHö = tf->getHöhe();
+				tf->setPosition( 0, 0 );
+				tf->setGröße( gr.x - rbr * 2 - ( ausfahren ? ausfahren->getBreite() : 0 ), gr.y - rbr * 2 );
+				tf->render( zRObj );
+				tf->setGröße( tf->getBreite(), tmpHö );
+				if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+				{
+					if( hatStyle( Style::AuswahlBuffer ) )
+					{
+						tf->setAlphaFeldZ( tmpBuffer );
+						tf->setStyle( TextFeld::Style::Buffered, tmpB );
+					}
+					if( hatStyle( Style::AuswahlHintergrund ) )
+					{
+						tf->setHintergrundFarbe( tmpHFarbe );
+						tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+						if( hatStyle( Style::AuswahlHBild ) )
+						{
+							tf->setHintergrundBildZ( tmpHBild );
+							tf->setStyle( TextFeld::Style::HBild, tmpHB );
+						}
+						if( hatStyle( Style::AuswahlHAlpha ) )
+							tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+					}
+					if( hatStyle( Style::AuswahlRahmen ) )
+					{
+						tf->setLinienRahmenZ( tmpRahmen );
+						tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+					}
+				}
+				else
+				{
+					if( hatMsStyle( auswahl, Style::AuswahlBuffer ) && msAuswAf )
+					{
+						tf->setAlphaFeldZ( tmpBuffer );
+						tf->setStyle( TextFeld::Style::Buffered, tmpB );
+					}
+					if( hatMsStyle( auswahl, Style::AuswahlHintergrund ) )
+					{
+						tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+						if( msAuswBgF && msAuswBgF->hat( auswahl ) )
+							tf->setHintergrundFarbe( tmpHFarbe );
+						if( hatMsStyle( auswahl, Style::AuswahlHBild ) && msAuswBgB )
+						{
+							tf->setHintergrundBildZ( tmpHBild );
+							tf->setStyle( TextFeld::Style::HBild, tmpHB );
+						}
+						if( hatMsStyle( auswahl, Style::AuswahlHAlpha ) )
+							tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+					}
+					if( hatMsStyle( auswahl, Style::AuswahlRahmen ) && msAuswRahmen )
+					{
+						tf->setLinienRahmenZ( tmpRahmen );
+						tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+					}
+				}
+			}
+		}
+		bool vsb = hatStyle( Style::VScroll ) && vertikalScrollBar; // Scroll bar zeichnen
+		if( auswahl >= anzahl )
+		{
+			auswahl = 0;
+			if( eAk )
+				eAk( eAkP, this, 0, auswahl );
+		}
+		if( members )
+		{
+			if( vsb && ausklappHöhe )
+			{
+				br -= 15;
+                vertikalScrollBar->getScrollData()->anzeigeHöhe = ausklappHöhe - rbr;
+                vertikalScrollBar->render( br - rbr, gr.y, 15, ausklappHöhe - rbr, zRObj );
+			}
+			if( ( ausklappHöhe && !zRObj.setDrawOptionsErzwingen( 0, gr.y, br - rbr, hö - rbr - gr.y ) ) || ( !ausklappHöhe && !zRObj.setDrawOptions( 0, gr.y, br - rbr, hö - rbr - gr.y ) ) )
+			{
+				zRObj.releaseDrawOptions();
+				zRObj.releaseDrawOptions();
+				unlockZeichnung();
+				return;
+			}
+			int maxHöhe = 0;
+			int dy = 0;
+			if( vsb )
+				dy -= vertikalScrollBar->getScroll();
+			int mdy = hö - rbr;
+			RCArray< TextFeld > *tmpA = members;
+			anzahl = members->getEintragAnzahl();
+			for( int i = 0; i < anzahl; ++i )
+			{
+				TextFeld *tf = members->z( i );
+				if( dy >= mdy && !vsb )
+					break;
+				tf->setPosition( 0, dy );
+				tf->setGröße( br - rbr * 2, tf->getHöhe() );
+				maxHöhe += tf->getHöhe();
+				bool selected = auswahl == i;
+				AlphaFeld *tmpBuffer = 0;
+				bool tmpB = 0;
+				int tmpHFarbe = 0;
+				bool tmpH = 0;
+				Bild *tmpHBild = 0;
+				bool tmpHB = 0;
+				bool tmpHAlpha = 0;
+				LRahmen *tmpRahmen = 0;
+				bool tmpR = 0;
+				if( selected )
+				{
+					if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+					{
+						if( hatStyle( Style::AuswahlBuffer ) )
+						{
+							tmpBuffer = tf->getAlphaFeld();
+							tf->setAlphaFeldZ( auswAf->getThis() );
+							tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+							tf->setStyle( TextFeld::Style::Buffered, hatStyle( Style::AuswahlBuffer ) );
+						}
+						if( hatStyle( Style::AuswahlHintergrund ) )
+						{
+							tmpH = tf->hatStyle( TextFeld::Style::Hintergrund );
+							tmpHFarbe = tf->getHintergrundFarbe();
+							tf->setHintergrundFarbe( auswBgF );
+							tf->setStyle( TextFeld::Style::Hintergrund, hatStyle( Style::Hintergrund ) );
+							if( hatStyle( Style::AuswahlHBild ) )
+							{
+								tmpHBild = tf->getHintergrundBild();
+								tf->setHintergrundBildZ( auswBgB->getThis() );
+								tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+								tf->setStyle( TextFeld::Style::HBild, hatStyle( Style::HBild ) );
+							}
+							if( hatStyle( Style::AuswahlHAlpha ) )
+							{
+								tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+								tf->setStyle( TextFeld::Style::HAlpha, hatStyle( Style::AuswahlHAlpha ) );
+							}
+						}
+						if( hatStyle( Style::AuswahlRahmen ) )
+						{
+							tmpRahmen = tf->getLinienRahmen();
+							tf->setLinienRahmenZ( auswRahmen->getThis() );
+							tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, hatStyle( Style::AuswahlRahmen ) );
+						}
+					}
+					else
+					{
+						if( hatMsStyle( i, Style::AuswahlBuffer ) && msAuswAf )
+						{
+							tmpBuffer = tf->getAlphaFeld();
+							tf->setAlphaFeldZ( msAuswAf->get( i ) );
+							tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+							tf->setStyle( TextFeld::Style::Buffered, hatMsStyle( i, Style::AuswahlBuffer ) );
+						}
+						if( hatMsStyle( i, Style::AuswahlHintergrund ) )
+						{
+							tmpH = tf->hatStyle( Style::Hintergrund );
+							tf->setStyle( TextFeld::Style::Hintergrund, hatMsStyle( i, Style::AuswahlHintergrund ) );
+							if( msAuswBgF && msAuswBgF->hat( i ) )
+							{
+								tmpHFarbe = tf->getHintergrundFarbe();
+								tf->setHintergrundFarbe( msAuswBgF->get( i ) );
+							}
+							if( hatMsStyle( i, Style::AuswahlHBild ) && msAuswBgB )
+							{
+								tmpHBild = tf->getHintergrundBild();
+								tf->setHintergrundBildZ( msAuswBgB->get( i ) );
+								tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+								tf->setStyle( TextFeld::Style::HBild, hatMsStyle( i, Style::HBild ) );
+							}
+							if( hatMsStyle( i, Style::AuswahlHAlpha ) )
+							{
+								tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+								tf->setStyle( TextFeld::Style::HAlpha, hatMsStyle( i, Style::AuswahlHAlpha ) );
+							}
+						}
+						if( hatMsStyle( i, Style::AuswahlRahmen ) && msAuswRahmen )
+						{
+							tmpRahmen = tf->getLinienRahmen();
+							tf->setLinienRahmenZ( msAuswRahmen->get( i ) );
+							tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, hatMsStyle( i, Style::AuswahlRahmen ) );
+						}
+					}
+				}
+				else if( mausEintrag == i )
+				{
+					if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+					{
+						if( hatStyle( Style::MausBuffer ) )
+						{
+							tmpBuffer = tf->getAlphaFeld();
+							tf->setAlphaFeldZ( mausAf->getThis() );
+							tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+							tf->setStyle( TextFeld::Style::Buffered, hatStyle( Style::MausBuffer ) );
+						}
+						if( hatStyle( Style::MausHintergrund ) )
+						{
+							tmpH = tf->hatStyle( TextFeld::Style::Hintergrund );
+							tmpHFarbe = tf->getHintergrundFarbe();
+							tf->setHintergrundFarbe( mausBgF );
+							tf->setStyle( TextFeld::Style::Hintergrund, hatStyle( Style::Hintergrund ) );
+							if( hatStyle( Style::MausHBild ) )
+							{
+								tmpHBild = tf->getHintergrundBild();
+								tf->setHintergrundBildZ( mausBgB->getThis() );
+								tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+								tf->setStyle( TextFeld::Style::HBild, hatStyle( Style::HBild ) );
+							}
+							if( hatStyle( Style::MausHAlpha ) )
+							{
+								tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+								tf->setStyle( TextFeld::Style::HAlpha, hatStyle( Style::MausHAlpha ) );
+							}
+						}
+						if( hatStyle( Style::MausRahmen ) )
+						{
+							tmpRahmen = tf->getLinienRahmen();
+							tf->setLinienRahmenZ( mausRahmen->getThis() );
+							tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, hatStyle( Style::MausRahmen ) );
+						}
+					}
+					else
+					{
+						if( hatMsStyle( i, Style::MausBuffer ) && msAuswAf )
+						{
+							tmpBuffer = tf->getAlphaFeld();
+							tf->setAlphaFeldZ( msMausAf->get( i ) );
+							tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+							tf->setStyle( TextFeld::Style::Buffered, hatMsStyle( i, Style::MausBuffer ) );
+						}
+						if( hatMsStyle( i, Style::MausHintergrund ) )
+						{
+							tmpH = tf->hatStyle( Style::Hintergrund );
+							tf->setStyle( TextFeld::Style::Hintergrund, hatMsStyle( i, Style::MausHintergrund ) );
+							if( msMausBgF && msMausBgF->hat( i ) )
+							{
+								tmpHFarbe = tf->getHintergrundFarbe();
+								tf->setHintergrundFarbe( msMausBgF->get( i ) );
+							}
+							if( hatMsStyle( i, Style::MausHBild ) && msMausBgB )
+							{
+								tmpHBild = tf->getHintergrundBild();
+								tf->setHintergrundBildZ( msMausBgB->get( i ) );
+								tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+								tf->setStyle( TextFeld::Style::HBild, hatMsStyle( i, Style::HBild ) );
+							}
+							if( hatMsStyle( i, Style::MausHAlpha ) )
+							{
+								tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+								tf->setStyle( TextFeld::Style::HAlpha, hatMsStyle( i, Style::MausHAlpha ) );
+							}
+						}
+						if( hatMsStyle( i, Style::MausRahmen ) && msMausRahmen )
+						{
+							tmpRahmen = tf->getLinienRahmen();
+							tf->setLinienRahmenZ( msMausRahmen->get( i ) );
+							tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, hatMsStyle( i, Style::MausRahmen ) );
+						}
+					}
+				}
+				tf->render( zRObj );
+				if( selected )
+				{
+					if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+					{
+						if( hatStyle( Style::AuswahlBuffer ) )
+						{
+							tf->setAlphaFeldZ( tmpBuffer );
+							tf->setStyle( TextFeld::Style::Buffered, tmpB );
+						}
+						if( hatStyle( Style::AuswahlHintergrund ) )
+						{
+							tf->setHintergrundFarbe( tmpHFarbe );
+							tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+							if( hatStyle( Style::AuswahlHBild ) )
+							{
+								tf->setHintergrundBildZ( tmpHBild );
+								tf->setStyle( TextFeld::Style::HBild, tmpHB );
+							}
+							if( hatStyle( Style::AuswahlHAlpha ) )
+								tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+						}
+						if( hatStyle( Style::AuswahlRahmen ) )
+						{
+							tf->setLinienRahmenZ( tmpRahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+						}
+					}
+					else
+					{
+						if( hatMsStyle( i, Style::AuswahlBuffer ) && msAuswAf )
+						{
+							tf->setAlphaFeldZ( tmpBuffer );
+							tf->setStyle( TextFeld::Style::Buffered, tmpB );
+						}
+						if( hatMsStyle( i, Style::AuswahlHintergrund ) )
+						{
+							tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+							if( msAuswBgF && msAuswBgF->hat( i ) )
+								tf->setHintergrundFarbe( tmpHFarbe );
+							if( hatMsStyle( i, Style::AuswahlHBild ) && msAuswBgB )
+							{
+								tf->setHintergrundBildZ( tmpHBild );
+								tf->setStyle( TextFeld::Style::HBild, tmpHB );
+							}
+							if( hatMsStyle( i, Style::AuswahlHAlpha ) )
+								tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+						}
+						if( hatMsStyle( i, Style::AuswahlRahmen ) && msAuswRahmen )
+						{
+							tf->setLinienRahmenZ( tmpRahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+						}
+					}
+				}
+				else if( mausEintrag == i )
+				{
+					if( hatStyleNicht( Style::MultiStyled ) || !msStyle )
+					{
+						if( hatStyle( Style::MausBuffer ) )
+						{
+							tf->setAlphaFeldZ( tmpBuffer );
+							tf->setStyle( TextFeld::Style::Buffered, tmpB );
+						}
+						if( hatStyle( Style::MausHintergrund ) )
+						{
+							tf->setHintergrundFarbe( tmpHFarbe );
+							tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+							if( hatStyle( Style::MausHBild ) )
+							{
+								tf->setHintergrundBildZ( tmpHBild );
+								tf->setStyle( TextFeld::Style::HBild, tmpHB );
+							}
+							if( hatStyle( Style::MausHAlpha ) )
+								tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+						}
+						if( hatStyle( Style::MausRahmen ) )
+						{
+							tf->setLinienRahmenZ( tmpRahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+						}
+					}
+					else
+					{
+						if( hatMsStyle( i, Style::MausBuffer ) && msAuswAf )
+						{
+							tf->setAlphaFeldZ( tmpBuffer );
+							tf->setStyle( TextFeld::Style::Buffered, tmpB );
+						}
+						if( hatMsStyle( i, Style::MausHintergrund ) )
+						{
+							tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+							if( msAuswBgF && msAuswBgF->hat( i ) )
+								tf->setHintergrundFarbe( tmpHFarbe );
+							if( hatMsStyle( i, Style::MausHBild ) && msAuswBgB )
+							{
+								tf->setHintergrundBildZ( tmpHBild );
+								tf->setStyle( TextFeld::Style::HBild, tmpHB );
+							}
+							if( hatMsStyle( i, Style::MausHAlpha ) )
+								tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+						}
+						if( hatMsStyle( i, Style::MausRahmen ) && msAuswRahmen )
+						{
+							tf->setLinienRahmenZ( tmpRahmen );
+							tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+						}
+					}
+				}
+				dy += tf->getHöhe();
+			}
+			if( vertikalScrollBar )
+                vertikalScrollBar->getScrollData()->maxHöhe = maxHöhe;
+			zRObj.releaseDrawOptions();
+		}
+		zRObj.releaseDrawOptions();
+		zRObj.releaseDrawOptions();
+		unlockZeichnung();
+	}
+}
+
+// constant
+int AuswahlBox::getEintragPos( const char *txt ) const // gibt die Eintrag Position zurück
+{
+	for( int i = 0; i < anzahl; ++i )
+	if( members->z( i ) && members->z( i )->zText()->istGleich( txt ) )
+		return i;
+	return -1;
+}
+
+int AuswahlBox::getEintragPos( Text *txt ) const
+{
+	for( int i = 0; i < anzahl; ++i )
+	{
+		if( members->z( i ) && members->z( i )->zText()->istGleich( txt->getText() ) )
+		{
+			txt->release();
+			return i;
+		}
+	}
+	txt->release();
+	return -1;
+}
+
+Text *AuswahlBox::getEintragText( int i ) const // gibt den Eintrag Text zurück
+{
+	if( i >= anzahl )
+		return 0;
+	return members->z( i ) ? members->z( i )->getText() : 0;
+}
+
+Text *AuswahlBox::zEintragText( int i ) const
+{
+	if( i >= anzahl )
+		return 0;
+	return members->z( i ) ? members->z( i )->zText() : 0;
+}
+
+TextFeld *AuswahlBox::getEintrag( int i ) const // gibt den Eintrag zurück
+{
+	if( i >= anzahl )
+		return 0;
+	return members->get( i );
+}
+
+TextFeld *AuswahlBox::zEintrag( int i ) const
+{
+	if( i >= anzahl )
+		return 0;
+	return members->z( i );
+}
+
+int AuswahlBox::getAuswahl() const // gibt die Position des ausgewählten Eintrages zurück
+{
+	return auswahl;
+}
+
+int AuswahlBox::getEintragAnzahl() const // gibt die Anzahl der Einträge zurück
+{
+	return anzahl;
+}
+
+bool AuswahlBox::istAusgeklappt() const // prüft, ob die Liste ausgeklappt ist
+{
+	return ausgeklappt;
+}
+
+int AuswahlBox::getMaxHöhe() const // gibt die maximale Höhe der Liste zurück
+{
+	if( !hatStyle( Style::MaxHöhe ) )
+		return 0;
+	return ausklapMaxHöhe;
+}
+
+int AuswahlBox::getEintragHöhe() const // gibt die Höhe der Einträge zurück
+{
+	return eintragHöhe;
+}
+
+Knopf *AuswahlBox::getAusklappKnopf() const // gibt den aus-/einklapp Knopf zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return ausfahren ? ausfahren->getThis() : 0;
+}
+
+Knopf *AuswahlBox::zAusklappKnopf() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return ausfahren;
+}
+
+LRahmen *AuswahlBox::getEintragRahmen( int i ) const // gibt den Eintrag Rahmen zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getLinienRahmen();
+}
+
+LRahmen *AuswahlBox::zEintragRahmen( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->zLinienRahmen();
+}
+
+int AuswahlBox::getEintragRahmenFarbe( int i ) const // gibt die Eintrag Rahmen Frabe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getLinienRahmenFarbe();
+}
+
+int AuswahlBox::getEintragRahmenBreite( int i ) const // gibt die Eintrag Rahmen Breite zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getLinienRahmenBreite();
+}
+
+AlphaFeld *AuswahlBox::getEintragAlphaFeld( int i ) const // gibt das Eintrag AlphaFeld zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getAlphaFeld();
+}
+
+AlphaFeld *AuswahlBox::zEintragAlphaFeld( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->zAlphaFeld();
+}
+
+int AuswahlBox::getEintragAlphaFeldFarbe( int i ) const // gibt die Eintrag AlphaFeld Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getAlphaFeldFarbe();
+}
+
+int AuswahlBox::getEintragAlphaFeldStärke( int i ) const // gibt die Eintrag AlphaFeld stärke zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getAlphaFeldStärke();
+}
+
+int AuswahlBox::getEintragHintergrundFarbe( int i ) const // gibt die Eintrag Hintergrund Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getHintergrundFarbe();
+}
+
+Bild *AuswahlBox::getEintragHintergrundBild( int i ) const // gibt das Eintrag Hintergrund Bild zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->getHintergrundBild();
+}
+
+Bild *AuswahlBox::zEintragHintergrundBild( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !members->z( i ) )
+		return 0;
+	return members->z( i )->zHintergrundBild();
+}
+
+LRahmen *AuswahlBox::getAuswRahmen() const // gibt den Auswahl Rahmen zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswRahmen ? auswRahmen->getThis() : 0;
+}
+
+LRahmen *AuswahlBox::zAuswRahmen() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswRahmen;
+}
+
+int AuswahlBox::getAuswRahmenFarbe() const // gibt die Auswahl Rahmen Frabe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswRahmen ? auswRahmen->getFarbe() : 0;
+}
+
+int AuswahlBox::getAuswRahmenBreite() const // gibt die Auswahl Rahmen Breite zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswRahmen ? auswRahmen->getRBreite() : 0;
+}
+
+AlphaFeld *AuswahlBox::getAuswAlphaFeld() const // gibt das Auswahl AlphaFeld zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswAf ? auswAf->getThis() : 0;
+}
+
+AlphaFeld *AuswahlBox::zAuswAlphaFeld() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswAf;
+}
+
+int AuswahlBox::getAuswAlphaFeldFarbe() const // gibt die Auswahl AlphaFeld Farbe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswAf ? auswAf->getFarbe() : 0;
+}
+
+int AuswahlBox::getAuswAlphaFeldStärke() const // gibt die Auswahl AlphaFeld stärke zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswAf ? auswAf->getStärke() : 0;
+}
+
+int AuswahlBox::getAuswHintergrundFarbe() const // gibt die Auswahl Hintergrund Farbe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswBgF;
+}
+
+Bild *AuswahlBox::getAuswHintergrundBild() const // gibt das Auswahl Hintergrund Bild zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswBgB ? auswBgB->getThis() : 0;
+}
+
+Bild *AuswahlBox::zAuswHintergrundBild() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return auswBgB;
+}
+
+LRahmen *AuswahlBox::getMsAuswRahmen( int i ) const // gibt den Multistyle Auswahl Rahmen zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswRahmen )
+		return 0;
+	return msAuswRahmen->z( i ) ? msAuswRahmen->z( i )->getThis() : 0;
+}
+
+LRahmen *AuswahlBox::zMsAuswRahmen( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswRahmen )
+		return 0;
+	return msAuswRahmen->z( i );
+}
+
+int AuswahlBox::getMsAuswRahmenFarbe( int i ) const // gibt die Multistyle Auswahl Rahmen Frabe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswRahmen )
+		return 0;
+	return msAuswRahmen->z( i ) ? msAuswRahmen->z( i )->getFarbe() : 0;
+}
+
+int AuswahlBox::getMsAuswRahmenBreite( int i ) const // gibt die Multistyle Auswahl Rahmen Breite zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswRahmen )
+		return 0;
+	return msAuswRahmen->z( i ) ? msAuswRahmen->z( i )->getRBreite() : 0;
+}
+
+AlphaFeld *AuswahlBox::getMsAuswAlphaFeld( int i ) const // gibt das Multistyle Auswahl AlphaFeld zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswAf )
+		return 0;
+	return msAuswAf->z( i ) ? msAuswAf->z( i )->getThis() : 0;
+}
+
+AlphaFeld *AuswahlBox::zMsAuswAlphaFeld( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswAf )
+		return 0;
+	return msAuswAf->z( i );
+}
+
+int AuswahlBox::getMsAuswAlphaFeldFarbe( int i ) const // gibt die Multistyle Auswahl AlphaFeld Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswAf )
+		return 0;
+	return msAuswAf->z( i ) ? msAuswAf->z( i )->getFarbe() : 0;
+}
+
+int AuswahlBox::getMsAuswAlphaFeldStärke( int i ) const // gibt die Multistyle Auswahl AlphaFeld stärke zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswAf )
+		return 0;
+	return msAuswAf->z( i ) ? msAuswAf->z( i )->getStärke() : 0;
+}
+
+int AuswahlBox::getMsAuswHintergrundFarbe( int i ) const // gibt die Multistyle Auswahl Hintergrund Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswBgF || !msAuswBgF->hat( i ) )
+		return 0;
+	return msAuswBgF->get( i );
+}
+
+Bild *AuswahlBox::getMsAuswHintergrundBild( int i ) const // gibt das Multistyle Auswahl Hintergrund Bild zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswBgB )
+		return 0;
+	return msAuswBgB->get( i );
+}
+
+Bild *AuswahlBox::zMsAuswHintergrundBild( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msAuswBgB )
+		return 0;
+	return msAuswBgB->z( i );
+}
+
+LRahmen *AuswahlBox::getMausRahmen() const // gibt den Maus Rahmen zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausRahmen ? mausRahmen->getThis() : 0;
+}
+
+LRahmen *AuswahlBox::zMausRahmen() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausRahmen;
+}
+
+int AuswahlBox::getMausRahmenFarbe() const // gibt die Maus Rahmen Frabe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausRahmen ? mausRahmen->getFarbe() : 0;
+}
+
+int AuswahlBox::getMausRahmenBreite() const // gibt die Maus Rahmen Breite zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausRahmen ? mausRahmen->getRBreite() : 0;
+}
+
+AlphaFeld *AuswahlBox::getMausAlphaFeld() const // gibt das Maus AlphaFeld zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausAf ? mausAf->getThis() : 0;
+}
+
+AlphaFeld *AuswahlBox::zMausAlphaFeld() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausAf;
+}
+
+int AuswahlBox::getMausAlphaFeldFarbe() const // gibt die Maus AlphaFeld Farbe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausAf ? mausAf->getFarbe() : 0;
+}
+
+int AuswahlBox::getMausAlphaFeldStärke() const // gibt die Maus AlphaFeld stärke zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausAf ? mausAf->getStärke() : 0;
+}
+
+int AuswahlBox::getMausHintergrundFarbe() const // gibt die Maus Hintergrund Farbe zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausBgF;
+}
+
+Bild *AuswahlBox::getMausHintergrundBild() const // gibt das Maus Hintergrund Bild zurück
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausBgB ? mausBgB->getThis() : 0;
+}
+
+Bild *AuswahlBox::zMausHintergrundBild() const
+{
+	if( hatStyle( Style::MultiStyled ) )
+		return 0;
+	return mausBgB;
+}
+
+LRahmen *AuswahlBox::getMsMausRahmen( int i ) const // gibt den Multistyle Maus Rahmen zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausRahmen )
+		return 0;
+	return msMausRahmen->get( i );
+}
+
+LRahmen *AuswahlBox::zMsMausRahmen( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausRahmen )
+		return 0;
+	return msMausRahmen->z( i );
+}
+
+int AuswahlBox::getMsMausRahmenFarbe( int i ) const // gibt die Multistyle Maus Rahmen Frabe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausRahmen )
+		return 0;
+	return msMausRahmen->z( i ) ? msMausRahmen->z( i )->getFarbe() : 0;
+}
+
+int AuswahlBox::getMsMausRahmenBreite( int i ) const // gibt die Multistyle Maus Rahmen Breite zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausRahmen )
+		return 0;
+	return msMausRahmen->z( i ) ? msMausRahmen->z( i )->getRBreite() : 0;
+}
+
+AlphaFeld *AuswahlBox::getMsMausAlphaFeld( int i ) const // gibt das Multistyle Maus AlphaFeld zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausAf )
+		return 0;
+	return msMausAf->get( i );
+}
+
+AlphaFeld *AuswahlBox::zMsMausAlphaFeld( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausAf )
+		return 0;
+	return msMausAf->z( i );
+}
+
+int AuswahlBox::getMsMausAlphaFeldFarbe( int i ) const // gibt die Multistyle Maus AlphaFeld Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausAf )
+		return 0;
+	return msMausAf->z( i ) ? msMausAf->z( i )->getFarbe() : 0;
+}
+
+int AuswahlBox::getMsMausAlphaFeldStärke( int i ) const // gibt die Multistyle Maus AlphaFeld stärke zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausAf )
+		return 0;
+	return msMausAf->z( i ) ? msMausAf->z( i )->getStärke() : 0;
+}
+
+int AuswahlBox::getMsMausHintergrundFarbe( int i ) const // gibt die Multistyle Maus Hintergrund Farbe zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausBgF || !msMausBgF->hat( i ) )
+		return 0;
+	return msMausBgF->get( i );
+}
+
+Bild *AuswahlBox::getMsMausHintergrundBild( int i ) const // gibt das Multistyle Maus Hintergrund Bild zurück
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausBgB )
+		return 0;
+	return msMausBgB->get( i );
+}
+
+Bild *AuswahlBox::zMsMausHintergrundBild( int i ) const
+{
+	if( !hatStyle( Style::MultiStyled ) )
+		return 0;
+	if( !msMausBgB )
+		return 0;
+	return msMausBgB->z( i );
+}
+
+bool AuswahlBox::hatMsStyle( int i, __int64 abStyle ) const // prüft ob Multistyle style vorhanden
+{
+	if( ( style | Style::MultiStyled ) != style || !msStyle || !msStyle->hat( i ) )
+		return 0;
+	return ( msStyle->get( i ) | abStyle ) == msStyle->get( i );
+}
+
+bool AuswahlBox::hatMsStyleNicht( int i, __int64 abStyle ) const // prüft ob Multistyle style nicht vorhanden
+{
+	if( ( style | Style::MultiStyled ) != style || !msStyle || !msStyle->hat( i ) )
+		return 1;
+	return ( msStyle->get( i ) | abStyle ) != msStyle->get( i );
+}
+
+Zeichnung *AuswahlBox::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+	AuswahlBox *obj = new AuswahlBox();
+	obj->setPosition( pos );
+	obj->setGröße( gr );
+	obj->setMausEreignisParameter( makParam );
+	obj->setTastaturEreignisParameter( takParam );
+	obj->setMausEreignis( Mak );
+	obj->setTastaturEreignis( Tak );
+	if( toolTip )
+		obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	obj->setStyle( style );
+	if( schrift )
+		obj->setSchriftZ( schrift->getThis() );
+	if( rahmen )
+		obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+	if( ausfahren )
+		obj->setAusklappKnopfZ( (Knopf*)ausfahren->dublizieren() );
+	obj->setHintergrundFarbe( hintergrundFarbe );
+	if( hintergrundBild )
+		obj->setHintergrundBild( hintergrundBild->getThis() );
+	if( hintergrundFeld )
+		obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+	if( auswRahmen )
+		obj->setAuswRahmenZ( (LRahmen*)auswRahmen->dublizieren() );
+	obj->setAuswHintergrundFarbe( auswBgF );
+	if( auswBgB )
+		obj->setAuswHintergrundBild( auswBgB->getThis() );
+	if( auswAf )
+		obj->setAuswAlphaFeldZ( (AlphaFeld*)auswAf->dublizieren() );
+	if( mausRahmen )
+		obj->setMausRahmenZ( (LRahmen*)mausRahmen->dublizieren() );
+	obj->setMausHintergrundFarbe( mausBgF );
+	if( mausBgB )
+		obj->setMausHintergrundBild( mausBgB->getThis() );
+	if( mausAf )
+		obj->setMausAlphaFeldZ( (AlphaFeld*)mausAf->dublizieren() );
+	obj->setMaxAuskappHöhe( ausklapMaxHöhe );
+	obj->setEintragHöhe( eintragHöhe );
+	for( int i = 0; i < anzahl; ++i )
+	{
+		if( members->z( i ) )
+		{
+			obj->addEintrag( "a" );
+			obj->setEintragZ( i, (TextFeld*)members->z( i )->dublizieren() );
+			if( msStyle && msStyle->hat( i ) )
+				obj->setMsStyle( i, msStyle->get( i ) );
+			if( msAuswRahmen && msAuswRahmen->z( i ) )
+				obj->setMsAuswRahmenZ( i, (LRahmen*)msAuswRahmen->z( i )->dublizieren() );
+			if( msAuswBgF && msAuswBgF->hat( i ) )
+				obj->setMsAuswHintergrundFarbe( i, msAuswBgF->get( i ) );
+			if( msAuswBgB && msAuswBgB->z( i ) )
+				obj->setMsAuswHintergrundBild( i, msAuswBgB->get( i ) );
+			if( msAuswAf && msAuswAf->z( i ) )
+				obj->setMsAuswAlphaFeldZ( i, (AlphaFeld*)msAuswAf->z( i )->dublizieren() );
+			if( msMausRahmen && msMausRahmen->z( i ) )
+				obj->setMsMausRahmenZ( i, (LRahmen*)msMausRahmen->z( i )->dublizieren() );
+			if( msMausBgF && msMausBgF->hat( i ) )
+				obj->setMsMausHintergrundFarbe( i, msMausBgF->get( i ) );
+			if( msMausBgB && msMausBgB->z( i ) )
+				obj->setMsMausHintergrundBild( i, msMausBgB->get( i ) );
+			if( msMausAf && msMausAf->z( i ) )
+				obj->setMsMausAlphaFeldZ( i, (AlphaFeld*)msMausAf->z( i )->dublizieren() );
+		}
+	}
+	obj->setAlphaFeldFarbe( auswahl );
+	return obj;
+}
+
+// Reference Counting
+AuswahlBox *AuswahlBox::getThis()
+{
+	++ref;
+	return this;
+}
+
+AuswahlBox *AuswahlBox::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 233 - 0
AuswahlBox.h

@@ -0,0 +1,233 @@
+#ifndef AuswahlBox_H
+#define AuswahlBox_H
+
+#include "Zeichnung.h"
+#include "Array.h"
+
+namespace Framework
+{
+	class TextFeld; // TextFeld.h
+	class VScrollBar; // Scroll.h
+	class LRahmen; // Rahmen.h
+	class Knopf; // Knopf.h
+	class AlphaFeld; // AlphaFeld.h
+	class Text; // Tet.h
+	class Schrift; // Schrift.h
+
+	class AuswahlBox : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 FeldRahmen = 0x000001000;
+            const static __int64 FeldHintergrund = 0x000002000;
+            const static __int64 FeldHBild = 0x000004000;
+            const static __int64 FeldHAlpha = 0x000008000;
+            const static __int64 FeldBuffer = 0x000010000;
+            const static __int64 AuswahlHintergrund = 0x000020000;
+            const static __int64 AuswahlHBild = 0x000040000;
+            const static __int64 AuswahlHAlpha = 0x000080000;
+            const static __int64 AuswahlBuffer = 0x000100000;
+            const static __int64 AuswahlRahmen = 0x000200000;
+            const static __int64 MultiStyled = 0x000400000;
+            const static __int64 MaxHöhe = 0x004000000;
+            const static __int64 MausHintergrund = 0x008000000;
+            const static __int64 MausHBild = 0x010000000;
+            const static __int64 MausHAlpha = 0x020000000;
+            const static __int64 MausBuffer = 0x040000000;
+            const static __int64 MausRahmen = 0x080000000;
+            //const int NachObenAusklappen	= 0x100000000;
+            //const int AutoAusklappRichtung	= 0x200000000;
+
+            const static __int64 Normal = Sichtbar | Erlaubt | Rahmen | FeldRahmen | AuswahlBuffer | AuswahlRahmen | MaxHöhe | VScroll | MausRahmen | MausBuffer;
+        };
+	private:
+		Schrift *schrift;
+		Array< __int64 > *msStyle;
+		RCArray< TextFeld > *members;
+		Knopf *ausfahren;
+		LRahmen *auswRahmen;
+		int auswBgF;
+		Bild *auswBgB;
+		AlphaFeld *auswAf;
+		RCArray< LRahmen > *msAuswRahmen;
+		Array< int > *msAuswBgF;
+		RCArray< Bild > *msAuswBgB;
+		RCArray< AlphaFeld > *msAuswAf;
+		LRahmen *mausRahmen;
+		int mausBgF;
+		Bild *mausBgB;
+		AlphaFeld *mausAf;
+		RCArray< LRahmen > *msMausRahmen;
+		Array< int > *msMausBgF;
+		RCArray< Bild > *msMausBgB;
+		RCArray< AlphaFeld > *msMausAf;
+		int anzahl;
+		int auswahl;
+		bool ausgeklappt;
+		int ausklappHöhe;
+		int ausklapMaxHöhe;
+		int eintragHöhe;
+		double tickval;
+		int mausEintrag;
+		bool scrollAnzeigen;
+		void *eAkP;
+		void( *eAk )( void *p, AuswahlBox *, int, int );
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) AuswahlBox();
+		// Destruktor 
+		__declspec( dllexport ) ~AuswahlBox();
+		// nicht constant
+		__declspec( dllexport ) void setEventParam( void *p ); // setzt den Event Parameter
+		__declspec( dllexport ) void setEventAktion( void( *eAk )( void *p, AuswahlBox *, int, int ) ); // setzt die Event Funktion
+		__declspec( dllexport ) void setSchriftZ( Schrift *schrift ); // setzt die schrift
+		__declspec( dllexport ) void addEintrag( const char *txt ); // Eintrag hinzufügen
+		__declspec( dllexport ) void addEintrag( Text *txt );
+		__declspec( dllexport ) void addEintragZ( TextFeld *txt );
+		__declspec( dllexport ) void setEintrag( int i, const char *txt ); // Eintrag setzen
+		__declspec( dllexport ) void setEintrag( int i, Text *txt );
+		__declspec( dllexport ) void setEintragZ( int i, TextFeld *txt );
+		__declspec( dllexport ) void löscheEintrag( int i ); // Eintrag entfernen
+		__declspec( dllexport ) void setAusklappKnopfZ( Knopf *ausK ); // Ausklapp Knopf setzen
+		__declspec( dllexport ) void setEintragRahmenZ( int i, LRahmen *rahmen ); // Eintrag Rahmen setzen
+		__declspec( dllexport ) void setEintragRahmenFarbe( int i, int f ); // Eintrag Rahmen Farbe setzen
+		__declspec( dllexport ) void setEintragRahmenBreite( int i, int rbr ); // Eintrag Rahmen Breite setzen
+		__declspec( dllexport ) void setEintragHintergrundFarbe( int i, int f ); // Eintrag Hintergrund farbe setzen
+		__declspec( dllexport ) void setEintragHintergrundBildZ( int i, Bild *bgB ); // Eintrag Hintergrund Bild setzen
+		__declspec( dllexport ) void setEintragHintergrundBild( int i, Bild *bgB );
+		__declspec( dllexport ) void setEintragAlphaFeldZ( int i, AlphaFeld *af ); // Eintrag AlphaFeld setzen
+		__declspec( dllexport ) void setEintragAlphaFeldFarbe( int i, int afF ); // Eintrag AlphaFeld Farbe setzen
+		__declspec( dllexport ) void setEintragAlphaFeldStärke( int i, int afSt ); // Eintrag AlphaFeld Stärke setzen
+		__declspec( dllexport ) void setAuswRahmenZ( LRahmen *rahmen ); // Auswahl Rahmen setzen
+		__declspec( dllexport ) void setAuswRahmenFarbe( int f ); // Auswahl Rahmen Farbe setzen
+		__declspec( dllexport ) void setAuswRahmenBreite( int rbr ); // Auswahl Rahmen Breite setzen
+		__declspec( dllexport ) void setAuswHintergrundFarbe( int f ); // Auswahl Hintergrund Farbe setzen
+		__declspec( dllexport ) void setAuswHintergrundBildZ( Bild *bgB ); // Auswahl Hintergrund Bild setzen
+		__declspec( dllexport ) void setAuswHintergrundBild( Bild *bgB );
+		__declspec( dllexport ) void setAuswAlphaFeldZ( AlphaFeld *af ); // Auswahl AlphaFeld setzen
+		__declspec( dllexport ) void setAuswAlphaFeldFarbe( int afF ); // Auswahl AlphaFeld Farbe setzen
+		__declspec( dllexport ) void setAuswAlphaFeldStärke( int afSt ); // Auswahl Alpha Feld stärke setzen
+		__declspec( dllexport ) void setMsAuswRahmenZ( int i, LRahmen *rahmen ); // Multistyle Auswahl Rahmen setzen
+		__declspec( dllexport ) void setMsAuswRahmenFarbe( int i, int f ); // Multistyle Auswahl Rahmen Farbe setzen
+		__declspec( dllexport ) void setMsAuswRahmenBreite( int i, int rbr ); // Multistyle Auswahl Breite setzen
+		__declspec( dllexport ) void setMsAuswHintergrundFarbe( int i, int f ); // Multistyle Auswahl Hintergrund Farbe setzen
+		__declspec( dllexport ) void setMsAuswHintergrundBildZ( int i, Bild *bgB ); // Multistyle Auswahl Hintergrund Bild setzen
+		__declspec( dllexport ) void setMsAuswHintergrundBild( int i, Bild *bgB );
+		__declspec( dllexport ) void setMsAuswAlphaFeldZ( int i, AlphaFeld *af ); // Multistyle Auswahl AlphaFeld setzen
+		__declspec( dllexport ) void setMsAuswAlphaFeldFarbe( int i, int afF ); // Multistyle Auswahl AlphaFeld Farbe setzen
+		__declspec( dllexport ) void setMsAuswAlphaFeldStärke( int i, int afSt ); // Multistyle Auswahl AlphaFeld stärke setzen
+		__declspec( dllexport ) void setMausRahmenZ( LRahmen *rahmen ); // Maus Rahmen setzen
+		__declspec( dllexport ) void setMausRahmenFarbe( int f ); // Maus Rahmen Farbe setzen
+		__declspec( dllexport ) void setMausRahmenBreite( int rbr ); // Maus Rahmen breite setzen
+		__declspec( dllexport ) void setMausHintergrundFarbe( int f ); // Maus Hintergrund Farbe setzen
+		__declspec( dllexport ) void setMausHintergrundBildZ( Bild *bgB ); // Maus Hintergrund Bild setzen
+		__declspec( dllexport ) void setMausHintergrundBild( Bild *bgB );
+		__declspec( dllexport ) void setMausAlphaFeldZ( AlphaFeld *af ); // Maus AlphaFeld setzen
+		__declspec( dllexport ) void setMausAlphaFeldFarbe( int afF ); // Maus AlphaFeld Farbe setzen
+		__declspec( dllexport ) void setMausAlphaFeldStärke( int afSt ); // Maus AlphaFeld stärke setzen
+		__declspec( dllexport ) void setMsMausRahmenZ( int i, LRahmen *rahmen ); // Multistyle Maus Rahmen setzen
+		__declspec( dllexport ) void setMsMausRahmenFarbe( int i, int f ); // Multistyle Maus Rahmen Farbe setzen
+		__declspec( dllexport ) void setMsMausRahmenBreite( int i, int rbr ); // Multistyle Maus Rahmen breite setzen
+		__declspec( dllexport ) void setMsMausHintergrundFarbe( int i, int f ); // Multistyle Maus Hintergrund Farbe setzen
+		__declspec( dllexport ) void setMsMausHintergrundBildZ( int i, Bild *bgB ); // Multistyle Maus Hintergrund Bild setzen
+		__declspec( dllexport ) void setMsMausHintergrundBild( int i, Bild *bgB );
+		__declspec( dllexport ) void setMsMausAlphaFeldZ( int i, AlphaFeld *af ); // Multistyle Maus AlphaFeld setzen
+		__declspec( dllexport ) void setMsMausAlphaFeldFarbe( int i, int afF ); // Multistyle Maus AlphaFeld Farbe setzen
+		__declspec( dllexport ) void setMsMausAlphaFeldStärke( int i, int afSt ); // Multistyle Maus AlphaFeld stärke setzen
+		__declspec( dllexport ) void setAuswahl( int i ); // Eintrag auswählen
+		__declspec( dllexport ) void ausklappen(); // liste ausklappen
+		__declspec( dllexport ) void einklappen(); // liste einklappen
+		__declspec( dllexport ) void scrollZuEintrag( int i ); // liste scrollen
+		__declspec( dllexport ) void setMaxAuskappHöhe( int maxHöhe ); // höhe der Liste beim ausklappen
+		__declspec( dllexport ) void setEintragHöhe( int höhe ); // setzt die Höhe der Einträge
+		__declspec( dllexport ) void addMsStyle( int i, __int64 abStyle ); // Multistyle style hinzufügen
+		__declspec( dllexport ) void setMsStyle( int i, __int64 abStyle, bool add ); // Multistyle style setzen
+		__declspec( dllexport ) void setMsStyle( int i, __int64 abStyle );
+		__declspec( dllexport ) void löscheMsStyle( int i, __int64 abStyle ); // Multistyle style entfernen
+		__declspec( dllexport ) bool tick( double tickVal ) override; // tick
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override; // Maus
+		__declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ) override; // Tastatur
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant
+		__declspec( dllexport ) int getEintragPos( const char *txt ) const; // gibt die Eintrag Position zurück
+		__declspec( dllexport ) int getEintragPos( Text *txt ) const;
+		__declspec( dllexport ) Text *getEintragText( int i ) const; // gibt den Eintrag Text zurück
+		__declspec( dllexport ) Text *zEintragText( int i ) const;
+		__declspec( dllexport ) TextFeld *getEintrag( int i ) const; // gibt den Eintrag zurück
+		__declspec( dllexport ) TextFeld *zEintrag( int i ) const;
+		__declspec( dllexport ) int getAuswahl() const; // gibt die Position des ausgewählten Eintrages zurück
+		__declspec( dllexport ) int getEintragAnzahl() const; // gibt die Anzahl der Einträge zurück
+		__declspec( dllexport ) bool istAusgeklappt() const; // prüft, ob die Liste ausgeklappt ist
+		__declspec( dllexport ) int getMaxHöhe() const; // gibt die maximale Höhe der Liste zurück
+		__declspec( dllexport ) int getEintragHöhe() const; // gibt die Höhe der Einträge zurück
+		__declspec( dllexport ) Knopf *getAusklappKnopf() const; // gibt den aus-/einklapp Knopf zurück
+		__declspec( dllexport ) Knopf *zAusklappKnopf() const;
+		__declspec( dllexport ) LRahmen *getEintragRahmen( int i ) const; // gibt den Eintrag Rahmen zurück
+		__declspec( dllexport ) LRahmen *zEintragRahmen( int i ) const;
+		__declspec( dllexport ) int getEintragRahmenFarbe( int i ) const; // gibt die Eintrag Rahmen Frabe zurück
+		__declspec( dllexport ) int getEintragRahmenBreite( int i ) const; // gibt die Eintrag Rahmen Breite zurück
+		__declspec( dllexport ) AlphaFeld *getEintragAlphaFeld( int i ) const; // gibt das Eintrag AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zEintragAlphaFeld( int i ) const;
+		__declspec( dllexport ) int getEintragAlphaFeldFarbe( int i ) const; // gibt die Eintrag AlphaFeld Farbe zurück
+		__declspec( dllexport ) int getEintragAlphaFeldStärke( int i ) const; // gibt die Eintrag AlphaFeld stärke zurück
+		__declspec( dllexport ) int getEintragHintergrundFarbe( int i ) const; // gibt die Eintrag Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getEintragHintergrundBild( int i ) const; // gibt das Eintrag Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zEintragHintergrundBild( int i ) const;
+		__declspec( dllexport ) LRahmen *getAuswRahmen() const; // gibt den Auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zAuswRahmen() const;
+		__declspec( dllexport ) int getAuswRahmenFarbe() const; // gibt die Auswahl Rahmen Frabe zurück
+		__declspec( dllexport ) int getAuswRahmenBreite() const; // gibt die Auswahl Rahmen Breite zurück
+		__declspec( dllexport ) AlphaFeld *getAuswAlphaFeld() const; // gibt das Auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zAuswAlphaFeld() const;
+		__declspec( dllexport ) int getAuswAlphaFeldFarbe() const; // gibt die Auswahl AlphaFeld Farbe zurück
+		__declspec( dllexport ) int getAuswAlphaFeldStärke() const; // gibt die Auswahl AlphaFeld stärke zurück
+		__declspec( dllexport ) int getAuswHintergrundFarbe() const; // gibt die Auswahl Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getAuswHintergrundBild() const; // gibt das Auswahl Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zAuswHintergrundBild() const;
+		__declspec( dllexport ) LRahmen *getMsAuswRahmen( int i ) const; // gibt den Multistyle Auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zMsAuswRahmen( int i ) const;
+		__declspec( dllexport ) int getMsAuswRahmenFarbe( int i ) const; // gibt die Multistyle Auswahl Rahmen Frabe zurück
+		__declspec( dllexport ) int getMsAuswRahmenBreite( int i ) const; // gibt die Multistyle Auswahl Rahmen Breite zurück
+		__declspec( dllexport ) AlphaFeld *getMsAuswAlphaFeld( int i ) const; // gibt das Multistyle Auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zMsAuswAlphaFeld( int i ) const;
+		__declspec( dllexport ) int getMsAuswAlphaFeldFarbe( int i ) const; // gibt die Multistyle Auswahl AlphaFeld Farbe zurück
+		__declspec( dllexport ) int getMsAuswAlphaFeldStärke( int i ) const; // gibt die Multistyle Auswahl AlphaFeld stärke zurück
+		__declspec( dllexport ) int getMsAuswHintergrundFarbe( int i ) const; // gibt die Multistyle Auswahl Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getMsAuswHintergrundBild( int i ) const; // gibt das Multistyle Auswahl Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zMsAuswHintergrundBild( int i ) const;
+		__declspec( dllexport ) LRahmen *getMausRahmen() const; // gibt den Maus Rahmen zurück
+		__declspec( dllexport ) LRahmen *zMausRahmen() const;
+		__declspec( dllexport ) int getMausRahmenFarbe() const; // gibt die Maus Rahmen Frabe zurück
+		__declspec( dllexport ) int getMausRahmenBreite() const; // gibt die Maus Rahmen Breite zurück
+		__declspec( dllexport ) AlphaFeld *getMausAlphaFeld() const; // gibt das Maus AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zMausAlphaFeld() const;
+		__declspec( dllexport ) int getMausAlphaFeldFarbe() const; // gibt die Maus AlphaFeld Farbe zurück
+		__declspec( dllexport ) int getMausAlphaFeldStärke() const; // gibt die Maus AlphaFeld stärke zurück
+		__declspec( dllexport ) int getMausHintergrundFarbe() const; // gibt die Maus Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getMausHintergrundBild() const; // gibt das Maus Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zMausHintergrundBild() const;
+		__declspec( dllexport ) LRahmen *getMsMausRahmen( int i ) const; // gibt den Multistyle Maus Rahmen zurück
+		__declspec( dllexport ) LRahmen *zMsMausRahmen( int i ) const;
+		__declspec( dllexport ) int getMsMausRahmenFarbe( int i ) const; // gibt die Multistyle Maus Rahmen Frabe zurück
+		__declspec( dllexport ) int getMsMausRahmenBreite( int i ) const; // gibt die Multistyle Maus Rahmen Breite zurück
+		__declspec( dllexport ) AlphaFeld *getMsMausAlphaFeld( int i ) const; // gibt das Multistyle Maus AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zMsMausAlphaFeld( int i ) const;
+		__declspec( dllexport ) int getMsMausAlphaFeldFarbe( int i ) const; // gibt die Multistyle Maus AlphaFeld Farbe zurück
+		__declspec( dllexport ) int getMsMausAlphaFeldStärke( int i ) const; // gibt die Multistyle Maus AlphaFeld stärke zurück
+		__declspec( dllexport ) int getMsMausHintergrundFarbe( int i ) const; // gibt die Multistyle Maus Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getMsMausHintergrundBild( int i ) const; // gibt das Multistyle Maus Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zMsMausHintergrundBild( int i ) const;
+		__declspec( dllexport ) inline bool hatMsStyle( int i, __int64 abStyle ) const; // prüft ob Multistyle style vorhanden
+		__declspec( dllexport ) inline bool hatMsStyleNicht( int i, __int64 abStyle ) const; // prüft ob Multistyle style nicht vorhanden
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Erzeugt eine Kopie des Zeichnungs
+		// Reference Counting
+		__declspec( dllexport ) AuswahlBox *getThis();
+		__declspec( dllexport ) AuswahlBox *release();
+	};
+}
+
+#endif

+ 84 - 0
Betriebssystem.h

@@ -0,0 +1,84 @@
+#ifndef Betriebssystem_H
+#define Betriebssystem_H
+#define _NOHEAP
+#ifdef _WIN32
+
+#ifdef _DEBUG
+
+#ifndef _NOHEAP
+#ifndef _LTMDB
+
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
+#define new DEBUG_CLIENTBLOCK
+#define _LTMDB
+
+#endif
+#endif
+
+#include <assert.h>
+
+#else
+
+#define assert( x )
+
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#else
+
+#define __stdcall
+#define __declspec( x )
+#define __int64                        long long
+#define __int32                        int
+#define __int16                        short
+#define __int8                         char
+#define assert( x )
+#include <stdlib.h>
+#include <pthread.h>
+#include <stdio.h>
+#ifndef CRITICAL_SECTION_CLASS
+#define CRITICAL_SECTION_CLASS
+class CriticalSection
+{
+public:
+	CriticalSection()
+	{
+		pthread_mutexattr_t attr;
+		pthread_mutexattr_init(&attr);
+		pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
+		pthread_mutex_init( &mutex, &attr );
+  }
+	~CriticalSection()
+	{
+		pthread_mutex_destroy( &mutex );
+	}
+	void Enter()
+	{
+		pthread_mutex_lock( &mutex );
+	}
+	void Leave()
+	{
+		pthread_mutex_unlock( &mutex );
+	}
+private:
+	pthread_mutex_t mutex;
+};
+#else
+class CriticalSection;
+#endif
+#define CRITICAL_SECTION               CriticalSection*
+#define InitializeCriticalSection( x ) ( *( x ) ) = new CriticalSection()
+#define DeleteCriticalSection( x )     delete ( *( x ) )
+#define EnterCriticalSection( x )      ( *( x ) )->Enter()
+#define LeaveCriticalSection( x )      ( *( x ) )->Leave()
+#include <unistd.h>
+#define Sleep( x )   usleep( (x) * 1000 )
+
+#endif
+
+#endif

+ 2204 - 0
Bild.cpp

@@ -0,0 +1,2204 @@
+//---Include---
+#ifdef WIN32
+
+#include <Windows.h>
+#include <GdiPlus.h>
+#pragma comment( lib, "gdiplus.lib" )
+
+#endif
+#include "Bild.h"
+#ifdef WIN32
+#include "DateiSystem.h"
+#include "Scroll.h"
+#include "Rahmen.h"
+#include "MausEreignis.h"
+#include "Globals.h"
+#include "ToolTip.h"
+#include "Text.h"
+#include "AlphaFeld.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef max
+#define max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
+#endif
+#ifndef min
+#define min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
+#endif
+#endif
+
+using namespace Framework;
+
+// Inhalt der Bild Klasse aus Bild.h
+// Konstruktor 
+Bild::Bild( bool options )
+    : fc( 0 ),
+    delFc( 1 ),
+    größe( 0, 0 ),
+    ref( 1 ),
+    drawOff( options ? new Punkt[ 2000 ] : new Punkt[ 1 ] ),
+    dPosA( options ? new Punkt[ 2000 ] : new Punkt[ 1 ] ),
+    dGrößeA( options ? new Punkt[ 2000 ] : new Punkt[ 1 ] ),
+    doa( 0 ),
+    alpha( options ? new unsigned char[ 1000 ] : new unsigned char[ 1 ] ),
+    alphaAnzahl( 0 ),
+    rend( 0 ),
+    alpha3D( 0 )
+{
+    alpha[ 0 ] = 0;
+}
+
+// Destruktor 
+Bild::~Bild()
+{
+    if( delFc )
+    {
+        delete[] fc;
+        fc = 0;
+    }
+    delete[] dPosA;
+    delete[] dGrößeA;
+    delete[] alpha;
+    delete[] drawOff;
+}
+
+// privat
+inline void Bild::alphaPixelP( int x, int y, int f )
+{
+    alphaPixelP( fc[ x + y * größe.x ], f );
+}
+
+inline void Bild::alphaPixelP( int &fc, int colorb )
+{
+    int alpha = ( ( colorb >> 24 ) & 0xFF );
+    int na = ( 0x100 - alpha );
+    fc = ( ( ( ( ( na * ( fc & 0xFF00FF ) ) >> 8 ) + ( ( alpha * ( colorb & 0xFF00FF ) ) >> 8 ) ) & 0xFF00FF ) |
+           ( ( ( ( na * ( fc & 0x00FF00 ) ) >> 8 ) + ( ( alpha * ( colorb & 0x00FF00 ) ) >> 8 ) ) & 0x00FF00 ) |
+           ( ( fc & 0xFF000000 ) ) ) * ( fc != 0 || !alpha3D ) | ( fc == 0 && alpha3D ) * colorb;
+    //unsigned char *fc1 = (unsigned char*)&fc[ i ];
+    //unsigned char *fc2 = (unsigned char*)&colorb;
+    //unsigned char na = ~fc2[ 3 ];
+    //fc1[ 3 ] = fc2[ 3 ];
+    //fc1[ 2 ] = (unsigned char)( ( fc2[ 2 ] * fc2[ 3 ] + fc1[ 2 ] * na ) / 255 );
+    //fc1[ 1 ] = (unsigned char)( ( fc2[ 1 ] * fc2[ 3 ] + fc1[ 1 ] * na ) / 255 );
+    //fc1[ 0 ] = (unsigned char)( ( fc2[ 0 ] * fc2[ 3 ] + fc1[ 0 ] * na ) / 255 );
+}
+
+char Bild::getOutCode( Punkt& p ) const
+{
+    char ret = 0;
+    if( p.x < dPosA[ doa ].x )
+        ret |= 1;
+    else if( p.x >= dGrößeA[ doa ].x )
+        ret |= 2;
+    if( p.y < dPosA[ doa ].y )
+        ret |= 4;
+    else if( p.y >= dGrößeA[ doa ].y )
+        ret |= 8;
+    return ret;
+}
+
+void Bild::drawFlatDreieck( int y1, int y2, float m1, float b1, float m2, float b2, int farbe )
+{
+    const int yStart = max( y1, dPosA[ doa ].y );
+    const int yEnd = min( y2, dGrößeA[ doa ].y );
+    for( int y = yStart; y < yEnd; y++ )
+    {
+        const int xStart = max( (int)( m1 * y + b1 + 0.5f ), dPosA[ doa ].x );
+        const int xEnd = min( (int)( m2 * y + b2 + 0.5f ), dGrößeA[ doa ].x );
+        for( int x = xStart; x < xEnd; x++ )
+            fc[ x + y * größe.x ] = farbe;
+    }
+}
+
+void Bild::drawFlatDreieckTextur( int y1, int y2, double m1, double b1, double m2, double b2, double tx1, double ty1, double tx2, double ty2,
+                                  double tx_1o, double ty_1o, double tx_2o, double ty_2o, double txf, double tyf, Bild &textur )
+{
+    const double yStart = max( y1, dPosA[ doa ].y );
+    const double yEnd = min( y2, dGrößeA[ doa ].y );
+    double tx_1 = tx1 + tx_1o * ( yStart - y1 ), ty_1 = ty1 + ty_1o * ( yStart - y1 ), tx_2 = tx2 + tx_2o * ( yStart - y1 ), ty_2 = ty2 + ty_2o * ( yStart - y1 );
+    for( double y = yStart; y < yEnd; y++, tx_1 += tx_1o, ty_1 += ty_1o, tx_2 += tx_2o, ty_2 += ty_2o )
+    {
+        const double xStart = m1 * y + b1;
+        const double xEnd = m2 * y + b2;
+        drawLinieHTextur( Vec2< double >( xStart, y ), xEnd - xStart, Vec2< double >( tx_1, ty_1 ), Vec2< double >( tx_2, ty_2 ), txf, tyf, textur );
+    }
+}
+
+void Bild::drawFlatDreieckAlpha( int y1, int y2, float m1, float b1, float m2, float b2, int farbe )
+{
+    const int yStart = max( (int)( y1 + 0.5 ), dPosA[ doa ].y );
+    const int yEnd = min( (int)( y2 + 0.5 ), dGrößeA[ doa ].y );
+    for( int y = yStart; y < yEnd; y++ )
+    {
+        const int xStart = max( (int)( m1 * ( (float)y + 0.5f ) + b1 + 0.5f ), dPosA[ doa ].x );
+        const int xEnd = min( (int)( m2 * ( (float)y + 0.5 ) + b2 + 0.5f ), dGrößeA[ doa ].x );
+        for( int x = xStart; x < xEnd; x++ )
+            alphaPixelP( fc[ x + y * größe.x ], farbe );
+    }
+}
+
+void Bild::drawFlatDreieckTexturAlpha( int y1, int y2, double m1, double b1, double m2, double b2, double tx1, double ty1, double tx2, double ty2,
+                                       double tx_1o, double ty_1o, double tx_2o, double ty_2o, double txf, double tyf, Bild &textur )
+{
+    const double yStart = max( y1, dPosA[ doa ].y );
+    const double yEnd = min( y2, dGrößeA[ doa ].y );
+    double tx_1 = tx1 + tx_1o * ( yStart - y1 ), ty_1 = ty1 + ty_1o * ( yStart - y1 ), tx_2 = tx2 + tx_2o * ( yStart - y1 ), ty_2 = ty2 + ty_2o * ( yStart - y1 );
+    for( double y = yStart; y < yEnd; y++, tx_1 += tx_1o, ty_1 += ty_1o, tx_2 += tx_2o, ty_2 += ty_2o )
+    {
+        const double xStart = m1 * y + b1;
+        const double xEnd = m2 * y + b2;
+        drawLinieHTexturAlpha( Vec2< double >( xStart, y ), xEnd - xStart, Vec2< double >( tx_1, ty_1 ), Vec2< double >( tx_2, ty_2 ), txf, tyf, textur );
+    }
+}
+
+void Bild::drawLinieHTextur( Vec2< double > p, double län, Vec2< double > ta, Vec2< double > tb, double txo, double tyo, Bild &textur ) // zeichnet eine horizontale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawLinieHTexturAlpha( p, län, ta, tb, txo, tyo, textur );
+        return;
+    }
+    if( län < 0 )
+    {
+        p.x += län;
+        län = -län;
+        ta.Swap( tb );
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    if( p.y < dpy || p.y >= dgy )
+        return;
+    double off = 0;
+    if( p.x < dpx )
+    {
+        off = dpx - p.x;
+        län -= dpx - p.x;
+        if( län <= 0 )
+            return;
+        p.x = dpx;
+    }
+    if( p.x + län >= dgx )
+    {
+        län -= p.x - dgx + län;
+        if( län <= 0 )
+            return;
+    }
+    int br = größe.x;
+    int *fc = this->fc + (int)( p.x + (int)p.y * br );
+    double x = ta.x + txo * off, y = ta.y + tyo * off;
+    int *buffer = textur.getBuffer();
+    int txtBr = textur.getBreite();
+    for( int i = 0; i < län; ++i, ++fc )
+    {
+        *fc = buffer[ (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * txtBr ) ];
+        x += txo, y += tyo;
+    }
+    rend = 1;
+}
+
+void Bild::drawLinieHTexturAlpha( Vec2< double > p, double län, Vec2< double > ta, Vec2< double > tb, double txo, double tyo, Bild &textur ) // zeichnet eine horizontale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( län < 0 )
+    {
+        p.x += län;
+        län = -län;
+        ta.Swap( tb );
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    if( p.y < dpy || p.y >= dgy )
+        return;
+    double off = 0;
+    if( p.x < dpx )
+    {
+        off = dpx - p.x;
+        län -= dpx - p.x;
+        if( län <= 0 )
+            return;
+        p.x = dpx;
+    }
+    if( p.x + län >= dgx )
+    {
+        län -= p.x - dgx + län;
+        if( län <= 0 )
+            return;
+    }
+    int br = größe.x;
+    int *fc = this->fc + (int)( p.x + (int)p.y * br );
+    double x = ta.x + txo * off, y = ta.y + tyo * off;
+    int *buffer = textur.getBuffer();
+    int txtBr = textur.getBreite();
+    int f;
+    for( int i = 0; i < län; ++i, ++fc )
+    {
+        f = buffer[ (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * txtBr ) ];
+        if( alpha[ alphaAnzahl ] )
+        {
+            unsigned char *cf = (unsigned char*)&f;
+            cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+        }
+        alphaPixelP( *fc, f );
+        x += txo, y += tyo;
+    }
+    rend = 1;
+}
+
+// nicht constant
+
+// Wird dieser Flag gesetzt, so wird beim Alpha Blending wenn die vorheriege Farbe 0 ist nur die neue mit ihrem Alpha Wert kopiert.
+// Das ist sinnvoll für die Verwendung im 3DBildschirm, wo das Gezeichnette Bild später mittels Alpha Blending angezeigt wird
+void Bild::setAlpha3D( bool erlaubt )
+{
+    alpha3D = erlaubt;
+}
+
+void Bild::setAlpha( unsigned char alpha ) // setzt die Transparenz der nachfolgenden Zeichnunge
+{
+    int last = this->alpha[ alphaAnzahl ];
+    ++alphaAnzahl;
+    assert( alphaAnzahl < 1000 );
+    this->alpha[ alphaAnzahl ] = ( 255 - alpha ) > last ? ( 255 - alpha ) : last;
+}
+
+void Bild::releaseAlpha() // Löscht alpha
+{
+    --alphaAnzahl;
+}
+
+void Bild::setPixelBuffer( int *buffer, bool deleteBuffer, int breite, int höhe ) // setzt den Zeiger auf die Pixel des Bildes
+{
+    if( delFc )
+        delete[]fc;
+    fc = buffer;
+    delFc = deleteBuffer;
+    größe.x = breite;
+    größe.y = höhe;
+    rend = 1;
+}
+
+void Bild::neuBild( int breite, int höhe, int füllFarbe )
+{
+    if( fc && delFc )
+        delete[] fc;
+    größe.x = breite;
+    größe.y = höhe;
+    fc = new int[ größe.x * größe.y ];
+    setFarbe( füllFarbe );
+    drawOff[ 0 ].x = 0;
+    drawOff[ 0 ].y = 0;
+    dPosA[ 0 ].x = 0;
+    dPosA[ 0 ].y = 0;
+    dGrößeA[ 0 ] = größe;
+    alphaAnzahl = 0;
+    alpha[ 0 ] = 0;
+    doa = 0;
+    rend = 1;
+}
+
+void Bild::setFarbe( int f )
+{
+    if( ( f & 0xFF ) == ( ( f >> 8 ) & 0xFF ) && ( f & 0xFF ) == ( ( f >> 16 ) & 0xFF ) && ( f & 0xFF ) == ( ( f >> 24 ) & 0xFF ) )
+        memset( fc, f, größe.x * größe.y * 4 );
+    else
+    {
+        for( int *i = fc, *end = i + größe.x * größe.y; i < end; i++ )
+            *i = f;
+    }
+}
+
+void Bild::füllRegion( int x, int y, int b, int h, int ff )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaRegion( x, y, b, h, ff );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + b < dpx || y + h < dpy || x > dgx || y > dgy )
+        return;
+    if( x < dpx )
+    {
+        b -= dpx - x;
+        x = dpx;
+    }
+    if( y < dpy )
+    {
+        h -= dpy - y;
+        y = dpy;
+    }
+    b = ( x + b ) >= dgx ? ( dgx - x ) : b;
+    h = ( y + h ) >= dgy ? ( dgy - y ) : h;
+    int *pixel = fc + y * größe.x + x;
+    int *rowEnd = pixel + b;
+    for( int i = 0; i < h; pixel += größe.x - b, ++i, rowEnd += größe.x )
+    {
+        for( ; pixel < rowEnd; ++pixel )
+            *pixel = ff;
+    }
+    rend = 1;
+}
+
+void Bild::alphaRegion( int x, int y, int b, int h, int ff )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + b < dpx || y + h < dpy || x > dgx || y > dgy )
+        return;
+    if( x < dpx )
+    {
+        b -= dpx - x;
+        x = dpx;
+    }
+    if( y < dpy )
+    {
+        h -= dpy - y;
+        y = dpy;
+    }
+    b = ( x + b ) >= dgx ? ( dgx - x ) : b;
+    h = ( y + h ) >= dgy ? ( dgy - y ) : h;
+    if( alpha[ alphaAnzahl ] )
+    {
+        unsigned char *cf = (unsigned char*)&ff;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    int *pixel = fc + y * größe.x + x;
+    int *rowEnd = pixel + b;
+    int alpha = ( ( ff >> 24 ) & 0xFF );
+    int na = ( 0x100 - alpha );
+    int i1 = ( alpha * ( ff & 0xFF00FF ) ) >> 8;
+    int i2 = ( alpha * ( ff & 0x00FF00 ) ) >> 8;
+    for( int i = 0; i < h; pixel += größe.x - b, ++i, rowEnd += größe.x )
+    {
+        for( ; pixel < rowEnd; ++pixel )
+        {
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( ( *pixel & 0xFF000000 ) ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * ff;
+        }
+    }
+    rend = 1;
+}
+
+void Bild::alphaPixel( int i, int f )
+{
+    if( !alpha[ alphaAnzahl ] )
+        alphaPixelP( fc[ i ], f );
+    if( alpha[ alphaAnzahl ] < 0xFF )
+    {
+        unsigned char *cf = (unsigned char*)&f;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+        alphaPixelP( fc[ i ], f );
+        rend = 1;
+    }
+}
+
+void Bild::alphaPixel( int x, int y, int f )
+{
+    if( !alpha[ alphaAnzahl ] )
+        alphaPixelP( fc[ x + y * größe.x ], f );
+    if( alpha[ alphaAnzahl ] < 0xFF )
+    {
+        unsigned char *cf = (unsigned char*)&f;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+        alphaPixelP( fc[ x + y * größe.x ], f );
+        rend = 1;
+    }
+}
+
+void Bild::alphaPixelDP( int x, int y, int f )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    if( x < dpx || y < dpy || x > dgx || y > dgy )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        unsigned char *cf = (unsigned char*)&f;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    alphaPixelP( fc[ x + y * größe.x ], f );
+}
+
+void Bild::alphaPixelDP( int i, int f )
+{
+    int x = i % größe.x;
+    int y = i / größe.x;
+    alphaPixelDP( x, y, f );
+}
+
+void Bild::setPixelDP( int x, int y, int f )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaPixelDP( x, y, f );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    if( x < dpx || y < dpy || x > dgx || y > dgy )
+        return;
+    fc[ x + y * größe.x ] = f;
+}
+
+void Bild::setPixelDP( int i, int f )
+{
+    int x = i % größe.x;
+    int y = i / größe.x;
+    setPixelDP( x, y, f );
+}
+
+void Bild::drawLinieH( int x, int y, int län, int f ) // zeichnet eine horizontale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawLinieHAlpha( x, y, län, f );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( y < dpy || y >= dgy )
+        return;
+    if( x < dpx )
+    {
+        län -= dpx - x;
+        if( län <= 0 )
+            return;
+        x = dpx;
+    }
+    if( x + län >= dgx )
+    {
+        län -= x - dgx + län;
+        if( län <= 0 )
+            return;
+    }
+    int br = größe.x;
+    int *fc = this->fc + x + y * br;
+    int pval = län < 0 ? -1 : 1;
+    län = län > 0 ? län : -län;
+    for( int i = 0; i < län; ++i, fc += pval )
+        *fc = f;
+    rend = 1;
+}
+
+void Bild::drawLinieV( int x, int y, int län, int f ) // zeichnet eine vertikale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawLinieVAlpha( x, y, län, f );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x < dpx || x >= dgx )
+        return;
+    if( y < dpy )
+    {
+        län -= dpy - y;
+        if( län <= 0 )
+            return;
+        y = dpy;
+    }
+    if( y + län >= dgy )
+    {
+        län -= y - dgy + län;
+        if( län < 0 )
+            return;
+    }
+    int br = größe.x;
+    int *fc = this->fc + x + y * br;
+    int pval = län < 0 ? -br : br;
+    län = län > 0 ? län : -län;
+    for( int i = 0; i < län; ++i, fc += pval )
+        *fc = f;
+    rend = 1;
+}
+
+void Bild::drawLinieHAlpha( int x, int y, int län, int f ) // zeichnet eine horizontale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( y < dpy || y >= dgy )
+        return;
+    if( x < dpx )
+    {
+        län -= dpx - x;
+        if( län <= 0 )
+            return;
+        x = dpx;
+    }
+    if( x + län >= dgx )
+    {
+        län -= x - dgx + län;
+        if( län <= 0 )
+            return;
+    }
+    int br = größe.x;
+    int pval = län < 0 ? -1 : 1;
+    län = län > 0 ? län : -län;
+    int end = 0;
+    if( alpha[ alphaAnzahl ] )
+    {
+        unsigned char *cf = (unsigned char*)&f;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    int alpha = ( ( f >> 24 ) & 0xFF );
+    int na = ( 0x100 - alpha );
+    int i1 = ( alpha * ( f & 0xFF00FF ) ) >> 8;
+    int i2 = ( alpha * ( f & 0x00FF00 ) ) >> 8;
+    for( int i = x + y * br; end < län; ++end, i += pval )
+    {
+        fc[ i ] = ( ( ( ( ( na * ( fc[ i ] & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                    ( ( ( ( na * ( fc[ i ] & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                    ( ( fc[ i ] & 0xFF000000 ) ) ) * ( fc[ i ] != 0 || !alpha3D ) | ( fc[ i ] == 0 && alpha3D ) * f;
+    }
+    rend = 1;
+}
+
+void Bild::drawLinieVAlpha( int x, int y, int län, int f ) // zeichnet eine vertikale Linie
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x < dpx || x >= dgx )
+        return;
+    if( y < dpy )
+    {
+        län -= dpy - y;
+        if( län <= 0 )
+            return;
+        y = dpy;
+    }
+    if( y + län >= dgy )
+    {
+        län -= y - dgy + län;
+        if( län < 0 )
+            return;
+    }
+    int br = größe.x;
+    int pval = län < 0 ? -br : br;
+    län = län > 0 ? län : -län;
+    int end = 0;
+    if( alpha[ alphaAnzahl ] )
+    {
+        unsigned char *cf = (unsigned char*)&f;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    int alpha = ( ( f >> 24 ) & 0xFF );
+    int na = ( 0x100 - alpha );
+    int i1 = ( alpha * ( f & 0xFF00FF ) ) >> 8;
+    int i2 = ( alpha * ( f & 0x00FF00 ) ) >> 8;
+    for( int i = x + y * br; end < län; ++end, i += pval )
+    {
+        fc[ i ] = ( ( ( ( ( na * ( fc[ i ] & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                    ( ( ( ( na * ( fc[ i ] & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                    ( fc[ i ] & 0xFF000000 ) ) * ( fc[ i ] != 0 || !alpha3D ) | ( fc[ i ] == 0 && alpha3D ) * f;
+    }
+    rend = 1;
+}
+
+void Bild::drawLinie( Punkt a, Punkt b, int fc ) // zeichnet eine Linie von Punkt( x1, y1 ) nach Punke( x2, y2 )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawLinieAlpha( a, b, fc );
+        return;
+    }
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    char outCode1 = getOutCode( a );
+    char outCode2 = getOutCode( b );
+    bool ok = 0;
+    while( 1 )
+    {
+        int xMax = dGrößeA[ doa ].x - 1;
+        int yMax = dGrößeA[ doa ].y - 1;
+        if( !( outCode1 | outCode2 ) )
+        {
+            ok = 1;
+            break;
+        }
+        else if( outCode1 & outCode2 )
+            break;
+        else
+        {
+            int x, y;
+            char outCodeOut = outCode1 ? outCode1 : outCode2;
+            if( outCodeOut & 8 )
+            {
+                x = (int)( a.x + ( b.x - a.x ) * ( yMax - a.y ) / ( b.y - a.y ) + 0.5 );
+                y = yMax;
+            }
+            else if( outCodeOut & 4 )
+            {
+                x = (int)( a.x + ( b.x - a.x ) * ( dPosA[ doa ].y - a.y ) / ( b.y - a.y ) + 0.5 );
+                y = dPosA[ doa ].y;
+            }
+            else if( outCodeOut & 2 )
+            {
+                y = (int)( a.y + ( b.y - a.y ) * ( xMax - a.x ) / ( b.x - a.x ) + 0.5 );
+                x = xMax;
+            }
+            else if( outCodeOut & 1 )
+            {
+                y = (int)( a.y + ( b.y - a.y ) * ( dPosA[ doa ].x - a.x ) / ( b.x - a.x ) + 0.5 );
+                x = dPosA[ doa ].x;
+            }
+            if( outCodeOut == outCode1 )
+            {
+                a.x = x;
+                a.y = y;
+                outCode1 = getOutCode( a );
+            }
+            else
+            {
+                b.x = x;
+                b.y = y;
+                outCode2 = getOutCode( b );
+            }
+        }
+    }
+    if( ok )
+    {
+        int xlän = b.x - a.x, axlän = abs( xlän );
+        int ylän = b.y - a.y, aylän = abs( ylän );
+        double xf = (double)xlän / ( aylän ? aylän : 1 );
+        double yf = (double)ylän / ( axlän ? axlän : 1 );
+        if( axlän > aylän )
+            xf = xf < 0 ? -1 : 1;
+        else
+            yf = yf < 0 ? -1 : 1;
+        double x = (double)a.x, y = (double)a.y;
+        int maxP = (int)( sqrt( xlän * xlän + ylän * ylän ) + 0.5 );
+        int count = 0;
+        while( !( (int)( x + 0.5 ) == b.x && (int)( y + 0.5 ) == b.y ) && count < maxP )
+        {
+            ++count;
+            this->fc[ (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * größe.x ) ] = fc;
+            x += xf, y += yf;
+        }
+        rend = 1;
+    }
+}
+
+void Bild::drawLinieAlpha( Punkt a, Punkt b, int fc )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    char outCode1 = getOutCode( a );
+    char outCode2 = getOutCode( b );
+    bool ok = 0;
+    while( 1 )
+    {
+        int xMax = dGrößeA[ doa ].x - 1;
+        int yMax = dGrößeA[ doa ].y - 1;
+        if( !( outCode1 | outCode2 ) )
+        {
+            ok = 1;
+            break;
+        }
+        else if( outCode1 & outCode2 )
+            break;
+        else
+        {
+            int x, y;
+            char outCodeOut = outCode1 ? outCode1 : outCode2;
+            if( outCodeOut & 8 )
+            {
+                x = (int)( a.x + ( b.x - a.x ) * ( yMax - a.y ) / ( b.y - a.y ) + 0.5 );
+                y = yMax;
+            }
+            else if( outCodeOut & 4 )
+            {
+                x = (int)( a.x + ( b.x - a.x ) * ( dPosA[ doa ].y - a.y ) / ( b.y - a.y ) + 0.5 );
+                y = dPosA[ doa ].y;
+            }
+            else if( outCodeOut & 2 )
+            {
+                y = (int)( a.y + ( b.y - a.y ) * ( xMax - a.x ) / ( b.x - a.x ) + 0.5 );
+                x = xMax;
+            }
+            else if( outCodeOut & 1 )
+            {
+                y = (int)( a.y + ( b.y - a.y ) * ( dPosA[ doa ].x - a.x ) / ( b.x - a.x ) + 0.5 );
+                x = dPosA[ doa ].x;
+            }
+            if( outCodeOut == outCode1 )
+            {
+                a.x = x;
+                a.y = y;
+                outCode1 = getOutCode( a );
+            }
+            else
+            {
+                b.x = x;
+                b.y = y;
+                outCode2 = getOutCode( b );
+            }
+        }
+    }
+    if( ok )
+    {
+        int xlän = b.x - a.x, axlän = abs( xlän );
+        int ylän = b.y - a.y, aylän = abs( ylän );
+        double xf = (double)xlän / ( aylän ? aylän : 1 );
+        double yf = (double)ylän / ( axlän ? axlän : 1 );
+        if( axlän > aylän )
+            xf = xf < 0 ? -1 : 1;
+        else
+            yf = yf < 0 ? -1 : 1;
+        double x = (double)a.x, y = (double)a.y;
+        if( alpha[ alphaAnzahl ] )
+        {
+            unsigned char *cf = (unsigned char*)&fc;
+            cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+        }
+        int maxP = (int)( sqrt( xlän * xlän + ylän * ylän ) + 0.5 );
+        int count = 0;
+        int alpha = ( ( fc >> 24 ) & 0xFF );
+        int na = ( 0x100 - alpha );
+        int i1 = ( alpha * ( fc & 0xFF00FF ) ) >> 8;
+        int i2 = ( alpha * ( fc & 0x00FF00 ) ) >> 8;
+        while( !( (int)( x + 0.5 ) == b.x && (int)( y + 0.5 ) == b.y ) && count < maxP )
+        {
+            ++count;
+            int &pixel = this->fc[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * größe.x ];
+            pixel = ( ( ( ( ( na * ( pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                      ( ( ( ( na * ( pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                      ( pixel & 0xFF000000 ) ) * ( pixel != 0 || !alpha3D ) | ( pixel == 0 && alpha3D ) * fc;
+            x += xf, y += yf;
+        }
+        rend = 1;
+    }
+}
+
+void Bild::füllKreis( int xOff, int yOff, int r, int fc ) // zeichnet einen Kreis um Punkt( xOff, yOff ) mit radius r
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    for( int i = r; i > 0; i-- )
+        drawKreis( xOff, yOff, i, fc );
+}
+
+void Bild::drawKreis( int xOff, int yOff, int r, int fc ) // zeichnet einen Kreis um Punkt( xOff, yOff ) mit radius r
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawKreisAlpha( xOff, yOff, r, fc );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    xOff += drawOff[ doa ].x;
+    yOff += drawOff[ doa ].y;
+    if( xOff + r < dpx || xOff - r >= dgx || yOff + r < dpy || yOff - r >= dgy )
+        return;
+    for( int a = 0; a < r; ++a )
+    {
+        int b = (int)( sqrt( (long)( r * r - a * a ) ) + 0.5 );
+        if( xOff + a < dgx && xOff + a > dpx && yOff + b < dgy && yOff + b > dpy )
+            this->fc[ xOff + a + ( yOff + b ) * größe.x ] = fc;
+        if( xOff - a < dgx && xOff - a > dpx && yOff + b < dgy && yOff + b > dpy )
+            this->fc[ xOff - a + ( yOff + b ) * größe.x ] = fc;
+        if( xOff + a < dgx && xOff + a > dpx && yOff - b < dgy && yOff - b > dpy )
+            this->fc[ xOff + a + ( yOff - b ) * größe.x ] = fc;
+        if( xOff - a < dgx && xOff - a > dpx && yOff - b < dgy && yOff - b > dpy )
+            this->fc[ xOff - a + ( yOff - b ) * größe.x ] = fc;
+        if( xOff + b < dgx && xOff + b > dpx && yOff + a < dgy && yOff + a > dpy )
+            this->fc[ xOff + b + ( yOff + a ) * größe.x ] = fc;
+        if( xOff - b < dgx && xOff - b > dpx && yOff + a < dgy && yOff + a > dpy )
+            this->fc[ xOff - b + ( yOff + a ) * größe.x ] = fc;
+        if( xOff + b < dgx && xOff + b > dpx && yOff - a < dgy && yOff - a > dpy )
+            this->fc[ xOff + b + ( yOff - a ) * größe.x ] = fc;
+        if( xOff - b < dgx && xOff - b > dpx && yOff - a < dgy && yOff - a > dpy )
+            this->fc[ xOff - b + ( yOff - a ) * größe.x ] = fc;
+    }
+    rend = 1;
+}
+
+void Bild::drawKreisAlpha( int xOff, int yOff, int r, int fc )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    xOff += drawOff[ doa ].x;
+    yOff += drawOff[ doa ].y;
+    if( xOff + r < dpx || xOff - r >= dgx || yOff + r < dpy || yOff - r >= dgy )
+        return;
+    if( alpha[ alphaAnzahl ] < 0xFF )
+    {
+        unsigned char *cf = (unsigned char*)&fc;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    int alpha = ( ( fc >> 24 ) & 0xFF );
+    int na = ( 0x100 - alpha );
+    int i1 = ( alpha * ( fc & 0xFF00FF ) ) >> 8;
+    int i2 = ( alpha * ( fc & 0x00FF00 ) ) >> 8;
+    for( int a = 0; a < r; ++a )
+    {
+        int b = (int)( sqrt( (long)( r * r - a * a ) ) + 0.5 );
+        int *pixel = 0;
+        if( xOff + a < dgx && xOff + a > dpx && yOff + b < dgy && yOff + b > dpy )
+        {
+            pixel = &this->fc[ xOff + a + ( yOff + b ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff - a < dgx && xOff - a > dpx && yOff + b < dgy && yOff + b > dpy )
+        {
+            pixel = &this->fc[ xOff - a + ( yOff + b ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff + a < dgx && xOff + a > dpx && yOff - b < dgy && yOff - b > dpy )
+        {
+            pixel = &this->fc[ xOff + a + ( yOff - b ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff - a < dgx && xOff - a > dpx && yOff - b < dgy && yOff - b > dpy )
+        {
+            pixel = &this->fc[ xOff - a + ( yOff - b ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff + b < dgx && xOff + b > dpx && yOff + a < dgy && yOff + a > dpy )
+        {
+            pixel = &this->fc[ xOff + b + ( yOff + a ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff - b < dgx && xOff - b > dpx && yOff + a < dgy && yOff + a > dpy )
+        {
+            pixel = &this->fc[ xOff - b + ( yOff + a ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff + b < dgx && xOff + b > dpx && yOff - a < dgy && yOff - a > dpy )
+        {
+            pixel = &this->fc[ xOff + b + ( yOff - a ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+        if( xOff - b < dgx && xOff - b > dpx && yOff - a < dgy && yOff - a > dpy )
+        {
+            pixel = &this->fc[ xOff - b + ( yOff - a ) * größe.x ];
+            *pixel = ( ( ( ( ( na * ( *pixel & 0xFF00FF ) ) >> 8 ) + i1 ) & 0xFF00FF ) |
+                       ( ( ( ( na * ( *pixel & 0x00FF00 ) ) >> 8 ) + i2 ) & 0x00FF00 ) |
+                       ( *pixel & 0xFF000000 ) ) * ( *pixel != 0 || !alpha3D ) | ( *pixel == 0 && alpha3D ) * fc;
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawBild( int x, int y, int br, int hö, Bild &zBild ) // zeichet zBild
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaBild( x, y, br, hö, zBild );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int xx, ygr, ygr2;
+    for( int yy = yst2; yy < dgy; ++yy )
+    {
+        ygr = yy * größe.x;
+        ygr2 = ( yy - yst2 + yst ) * bb;
+        for( xx = xst2; xx < dgx; ++xx )
+            fc[ xx + ygr ] = ff[ ( xx - xst2 + xst ) + ygr2 ];
+    }
+    rend = 1;
+}
+
+void Bild::alphaBild( int x, int y, int br, int hö, Bild &zBild )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    if( !alpha[ alphaAnzahl ] )
+    {
+        int xx, ygr, ygr2;
+        for( int yy = yst2; yy < dgy; ++yy )
+        {
+            ygr = yy * größe.x;
+            ygr2 = ( yy - yst2 + yst ) * bb;
+            for( xx = xst2; xx < dgx; ++xx )
+                alphaPixelP( fc[ xx + ygr ], ff[ ( xx - xst2 + xst ) + ygr2 ] );
+        }
+    }
+    else
+    {
+        int xx, ygr, ygr2;
+        for( int yy = yst2; yy < dgy; ++yy )
+        {
+            ygr = yy * größe.x;
+            ygr2 = ( yy - yst2 + yst ) * bb;
+            for( xx = xst2; xx < dgx; ++xx )
+            {
+                int fc = ff[ ( xx - xst2 + xst ) + ygr2 ];
+                unsigned char *cf = (unsigned char*)&fc;
+                cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+                alphaPixelP( this->fc[ xx + ygr ], fc );
+            }
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawBild90( int x, int y, int br, int hö, Bild &zBild ) // Zeichnet ein um 90 Grad nach rchts gedrehtes Bild
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaBild90( x, y, br, hö, zBild );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + hö < dpx || y + br < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + hö, dgx );
+    dgy = minInt( y + br, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int yy, xbb;
+    for( int xx = xst2; xx < dgx; ++xx )
+    {
+        xbb = ( zBild.getHöhe() - ( xx - xst2 + xst + 1 ) ) * bb;
+        for( yy = yst2; yy < dgy; ++yy )
+            fc[ xx + yy * größe.x ] = ff[ ( yy - yst2 + yst ) + xbb ];
+    }
+    rend = 1;
+}
+
+void Bild::alphaBild90( int x, int y, int br, int hö, Bild &zBild )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + hö < dpx || y + br < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + hö, dgx );
+    dgy = minInt( y + br, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    if( !alpha[ alphaAnzahl ] )
+    {
+        int yy, xbb;
+        for( int xx = xst2; xx < dgx; ++xx )
+        {
+            xbb = ( zBild.getHöhe() - ( xx - xst2 + xst + 1 ) ) * bb;
+            for( yy = yst2; yy < dgy; ++yy )
+                alphaPixelP( xx, yy, ff[ ( yy - yst2 + yst ) + xbb ] );
+        }
+    }
+    else
+    {
+        int yy, xbb;
+        for( int xx = xst2; xx < dgx; ++xx )
+        {
+            xbb = ( zBild.getHöhe() - ( xx - xst2 + xst + 1 ) ) * bb;
+            for( yy = yst2; yy < dgy; ++yy )
+            {
+                int fc = ff[ ( yy - yst2 + yst ) + xbb ];
+                unsigned char *cf = (unsigned char*)&fc;
+                cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+                alphaPixelP( xx, yy, fc );
+            }
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawBild180( int x, int y, int br, int hö, Bild &zBild ) // Zeichnet ein um 180 Grad nach rchts gedrehtes Bild
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaBild180( x, y, br, hö, zBild );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int xx, ygr, ybb;
+    for( int yy = yst2; yy < dgy; ++yy )
+    {
+        ygr = yy * größe.x;
+        ybb = ( zBild.getHöhe() - ( yy - yst2 + yst + 1 ) ) * bb;
+        for( xx = xst2; xx < dgx; ++xx )
+            fc[ xx + ygr ] = ff[ ( bb - ( xx - xst2 + xst + 1 ) ) + ybb ];
+    }
+    rend = 1;
+}
+
+void Bild::alphaBild180( int x, int y, int br, int hö, Bild &zBild )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    if( !alpha[ alphaAnzahl ] )
+    {
+        int xx, ygr, ybb;
+        for( int yy = yst2; yy < dgy; ++yy )
+        {
+            ygr = yy * größe.x;
+            ybb = ( zBild.getHöhe() - ( yy - yst2 + yst + 1 ) ) * bb;
+            for( xx = xst2; xx < dgx; ++xx )
+                alphaPixelP( fc[ xx + ygr ], ff[ ( bb - ( xx - xst2 + xst + 1 ) ) + ybb ] );
+        }
+    }
+    else
+    {
+        int xx, ygr, ybb;
+        for( int yy = yst2; yy < dgy; ++yy )
+        {
+            ygr = yy * größe.x;
+            ybb = ( zBild.getHöhe() - ( yy - yst2 + yst + 1 ) ) * bb;
+            for( xx = xst2; xx < dgx; ++xx )
+            {
+                int fc = ff[ ( bb - ( xx - xst2 + xst + 1 ) ) + ybb ];
+                unsigned char *cf = (unsigned char*)&fc;
+                cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+                alphaPixelP( this->fc[ xx + ygr ], fc );
+            }
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawBild270( int x, int y, int br, int hö, Bild &zBild ) // Zeichnet ein um 270 Grad nach rchts gedrehtes Bild
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaBild270( x, y, br, hö, zBild );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + hö < dpx || y + br < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getHöhe() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + hö, dgx );
+    dgy = minInt( y + br, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int yy, xbb;
+    for( int xx = xst2; xx < dgx; ++xx )
+    {
+        xbb = ( xx - xst2 + xst ) * bb;
+        for( yy = yst2; yy < dgy; ++yy )
+            fc[ xx + yy * größe.x ] = ff[ ( bb - ( yy - yst2 + yst + 1 ) ) + xbb ];
+    }
+    rend = 1;
+}
+
+void Bild::alphaBild270( int x, int y, int br, int hö, Bild &zBild )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + hö < dpx || y + br < dpy || x > dgx || y > dgy )
+        return;
+    br = minInt( br, zBild.getBreite() );
+    hö = minInt( hö, zBild.getBreite() );
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + hö, dgx );
+    dgy = minInt( y + br, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    if( !alpha[ alphaAnzahl ] )
+    {
+        int yy, xbb;
+        for( int xx = xst2; xx < dgx; ++xx )
+        {
+            xbb = ( xx - xst2 + xst ) * bb;
+            for( yy = yst2; yy < dgy; ++yy )
+                alphaPixelP( xx, yy, ff[ ( bb - ( yy - yst2 + yst + 1 ) ) + xbb ] );
+        }
+    }
+    else
+    {
+        int yy, xbb;
+        for( int xx = xst2; xx < dgx; ++xx )
+        {
+            xbb = ( xx - xst2 + xst ) * bb;
+            for( yy = yst2; yy < dgy; ++yy )
+            {
+                int fc = ff[ ( bb - ( yy - yst2 + yst + 1 ) ) + xbb ];
+                unsigned char *cf = (unsigned char*)&fc;
+                cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+                alphaPixelP( xx, yy, fc );
+            }
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawBildSkall( int x, int y, int br, int hö, Bild &zBild ) // zeichet zBild Skalliert
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        alphaBildSkall( x, y, br, hö, zBild );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    double xo = zBild.getBreite() / (double)br;
+    double yo = zBild.getHöhe() / (double)hö;
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int xx, ygr, ygr2;
+    double xb = 0, yb = yst * yo;
+    for( int yy = yst2; yy < dgy; ++yy, yb += yo )
+    {
+        ygr = yy * größe.x;
+        ygr2 = (int)( ( yy - yst2 + yst ) * yo ) * bb;
+        for( xx = xst2, xb = xst * xo; xx < dgx; ++xx, xb += xo )
+            fc[ xx + ygr ] = ff[ (int)xb + ygr2 ];
+    }
+    rend = 1;
+}
+
+void Bild::alphaBildSkall( int x, int y, int br, int hö, Bild &zBild )
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    x += drawOff[ doa ].x;
+    y += drawOff[ doa ].y;
+    if( x + br < dpx || y + hö < dpy || x > dgx || y > dgy )
+        return;
+    double xo = zBild.getBreite() / (double)br;
+    double yo = zBild.getHöhe() / (double)hö;
+    int xst = maxInt( dpx - x, 0 );
+    int yst = maxInt( dpy - y, 0 );
+    int xst2 = maxInt( x, dpx );
+    int yst2 = maxInt( y, dpy );
+    dgx = minInt( x + br, dgx );
+    dgy = minInt( y + hö, dgy );
+    int bb = zBild.getBreite();
+    int *ff = zBild.getBuffer();
+    int xx, ygr, ygr2;
+    double xb = 0;
+    for( int yy = yst2; yy < dgy; ++yy )
+    {
+        ygr = yy * größe.x;
+        ygr2 = (int)( ( yy - yst2 + yst ) * yo ) * bb;
+        for( xx = xst2, xb = xst * xo; xx < dgx; ++xx, xb += xo )
+        {
+            int f = ff[ (int)xb + ygr2 ];
+            unsigned char *cf = (unsigned char*)&f;
+            cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+            alphaPixelP( fc[ xx + ygr ], f );
+        }
+    }
+    rend = 1;
+}
+
+void Bild::drawDreieck( Punkt a, Punkt b, Punkt c, int farbe ) // füllt eine Dreieck aus
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawDreieckAlpha( a, b, c, farbe );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    c += drawOff[ doa ];
+    if( ( a.x < dpx && b.x < dpx && c.x < dpx ) || ( a.y < dpy && b.y < dpy && c.y < dpy ) ||
+        ( a.x > dgx && b.x > dgx && c.x > dgx ) || ( a.y > dgy && b.y > dgy && c.y > dgy ) )
+        return;
+    if( b.y < a.y )
+        a.Swap( b );
+    if( c.y < b.y )
+        b.Swap( c );
+    if( b.y < a.y )
+        a.Swap( b );
+    if( a.y == b.y )
+    {
+        if( b.x < a.x )
+            a.Swap( b );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        const float m3 = (float)( b.x - c.x ) / ( b.y - c.y );
+        float b2 = a.x - m2 * a.y;
+        float b3 = b.x - m3 * b.y;
+        drawFlatDreieck( b.y, c.y, m2, b2, m3, b3, farbe );
+    }
+    else if( b.y == c.y )
+    {
+        if( c.x < b.x )
+            b.Swap( c );
+        const float m1 = (float)( a.x - b.x ) / ( a.y - b.y );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        float b1 = a.x - m1 * a.y;
+        float b2 = a.x - m2 * a.y;
+        drawFlatDreieck( a.y, b.y, m1, b1, m2, b2, farbe );
+    }
+    else
+    {
+        const float m1 = (float)( a.x - b.x ) / ( a.y - b.y );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        const float m3 = (float)( b.x - c.x ) / ( b.y - c.y );
+        float b1 = a.x - m1 * a.y;
+        float b2 = a.x - m2 * a.y;
+        float b3 = b.x - m3 * b.y;
+        const float qx = m2 * b.y + b2;
+        if( qx < b.x )
+        {
+            drawFlatDreieck( a.y, b.y, m2, b2, m1, b1, farbe );
+            drawFlatDreieck( b.y, c.y, m2, b2, m3, b3, farbe );
+        }
+        else
+        {
+            drawFlatDreieck( a.y, b.y, m1, b1, m2, b2, farbe );
+            drawFlatDreieck( b.y, c.y, m3, b3, m2, b2, farbe );
+        }
+    }
+}
+
+void Bild::drawDreieckTextur( Punkt a, Punkt b, Punkt c, Punkt ta, Punkt tb, Punkt tc, Bild &textur ) // füllt eine Dreieck aus
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        drawDreieckTexturAlpha( a, b, c, ta, tb, tc, textur );
+        return;
+    }
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    c += drawOff[ doa ];
+    if( ( a.x < dpx && b.x < dpx && c.x < dpx ) || ( a.y < dpy && b.y < dpy && c.y < dpy ) ||
+        ( a.x > dgx && b.x > dgx && c.x > dgx ) || ( a.y > dgy && b.y > dgy && c.y > dgy ) )
+        return;
+    if( b.y < a.y )
+    {
+        a.Swap( b );
+        ta.Swap( tb );
+    }
+    if( c.y < b.y )
+    {
+        b.Swap( c );
+        tb.Swap( tc );
+    }
+    if( b.y < a.y )
+    {
+        a.Swap( b );
+        ta.Swap( tb );
+    }
+    const double m1 = (double)( a.x - b.x ) / ( a.y - b.y );
+    const double m2 = (double)( a.x - c.x ) / ( a.y - c.y );
+    const double m3 = (double)( b.x - c.x ) / ( b.y - c.y );
+    double b1 = a.x - m1 * a.y;
+    double b2 = a.x - m2 * a.y;
+    double b3 = b.x - m3 * b.y;
+    const double qx = m2 * b.y + b2;
+    if( qx < b.x )
+    {
+        double tx1o, ty1o, tx2o, ty2o;
+        if( c.y - a.y )
+        {
+            tx1o = (double)( tc.x - ta.x ) / ( c.y - a.y );
+            ty1o = (double)( tc.y - ta.y ) / ( c.y - a.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        if( b.y - a.y )
+        {
+            tx2o = (double)( tb.x - ta.x ) / ( b.y - a.y );
+            ty2o = (double)( tb.y - ta.y ) / ( b.y - a.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        Vec2< double > q( ta.x + tx1o * ( b.y - a.y ), ta.y + ty1o * ( b.y - a.y ) );
+        double txf, tyf;
+        if( b.x - qx )
+        {
+            txf = ( tb.x - q.x ) / ( b.x - qx );
+            tyf = ( tb.y - q.y ) / ( b.x - qx );
+        }
+        else
+        {
+            txf = 0;
+            tyf = 0;
+        }
+        drawFlatDreieckTextur( a.y, b.y, m2, b2, m1, b1, ta.x, ta.y, ta.x, ta.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+        if( c.y - b.y )
+        {
+            tx2o = (double)( tc.x - tb.x ) / ( c.y - b.y );
+            ty2o = (double)( tc.y - tb.y ) / ( c.y - b.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        drawFlatDreieckTextur( b.y, c.y, m2, b2, m3, b3, q.x, q.y, tb.x, tb.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+    }
+    else
+    {
+        double tx1o, ty1o, tx2o, ty2o;
+        if( b.y - a.y )
+        {
+            tx1o = (double)( tb.x - ta.x ) / ( b.y - a.y );
+            ty1o = (double)( tb.y - ta.y ) / ( b.y - a.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        if( c.y - a.y )
+        {
+            tx2o = (double)( tc.x - ta.x ) / ( c.y - a.y );
+            ty2o = (double)( tc.y - ta.y ) / ( c.y - a.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        Vec2< double > q( ta.x + tx2o * ( b.y - a.y ), ta.y + ty2o * ( b.y - a.y ) );
+        double txf, tyf;
+        if( qx - b.x )
+        {
+            txf = ( q.x - tb.x ) / ( qx - b.x );
+            tyf = ( q.y - tb.y ) / ( qx - b.x );
+        }
+        else
+        {
+            txf = 0;
+            tyf = 0;
+        }
+        drawFlatDreieckTextur( a.y, b.y, m1, b1, m2, b2, ta.x, ta.y, ta.x, ta.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+        if( c.y - b.y )
+        {
+            tx1o = (double)( tc.x - tb.x ) / ( c.y - b.y );
+            ty1o = (double)( tc.y - tb.y ) / ( c.y - b.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        drawFlatDreieckTextur( b.y, c.y, m3, b3, m2, b2, tb.x, tb.y, q.x, q.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+    }
+}
+
+void Bild::drawDreieckAlpha( Punkt a, Punkt b, Punkt c, int farbe ) // füllt eine Dreieck aus
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    c += drawOff[ doa ];
+    if( ( a.x < dpx && b.x < dpx && c.x < dpx ) || ( a.y < dpy && b.y < dpy && c.y < dpy ) ||
+        ( a.x > dgx && b.x > dgx && c.x > dgx ) || ( a.y > dgy && b.y > dgy && c.y > dgy ) )
+        return;
+    if( alpha[ alphaAnzahl ] )
+    {
+        unsigned char *cf = (unsigned char*)&farbe;
+        cf[ 3 ] = ( cf[ 3 ] > alpha[ alphaAnzahl ] ) * ( cf[ 3 ] - alpha[ alphaAnzahl ] );
+    }
+    if( b.y < a.y )
+        a.Swap( b );
+    if( c.y < b.y )
+        b.Swap( c );
+    if( b.y < a.y )
+        a.Swap( b );
+    if( a.y == b.y )
+    {
+        if( b.x < a.x )
+            a.Swap( b );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        const float m3 = (float)( b.x - c.x ) / ( b.y - c.y );
+        float b2 = a.x - m2 * a.y;
+        float b3 = b.x - m3 * b.y;
+        drawFlatDreieckAlpha( b.y, c.y, m2, b2, m3, b3, farbe );
+    }
+    else if( b.y == c.y )
+    {
+        if( c.x < b.x )
+            b.Swap( c );
+        const float m1 = (float)( a.x - b.x ) / ( a.y - b.y );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        float b1 = a.x - m1 * a.y;
+        float b2 = a.x - m2 * a.y;
+        drawFlatDreieckAlpha( a.y, b.y, m1, b1, m2, b2, farbe );
+    }
+    else
+    {
+        const float m1 = (float)( a.x - b.x ) / ( a.y - b.y );
+        const float m2 = (float)( a.x - c.x ) / ( a.y - c.y );
+        const float m3 = (float)( b.x - c.x ) / ( b.y - c.y );
+        float b1 = a.x - m1 * a.y;
+        float b2 = a.x - m2 * a.y;
+        float b3 = b.x - m3 * b.y;
+        const float qx = m2 * b.y + b2;
+        if( qx < b.x )
+        {
+            drawFlatDreieckAlpha( a.y, b.y, m2, b2, m1, b1, farbe );
+            drawFlatDreieckAlpha( b.y, c.y, m2, b2, m3, b3, farbe );
+        }
+        else
+        {
+            drawFlatDreieckAlpha( a.y, b.y, m1, b1, m2, b2, farbe );
+            drawFlatDreieckAlpha( b.y, c.y, m3, b3, m2, b2, farbe );
+        }
+    }
+}
+
+void Bild::drawDreieckTexturAlpha( Punkt a, Punkt b, Punkt c, Punkt ta, Punkt tb, Punkt tc, Bild &textur ) // füllt eine Dreieck aus
+{
+    if( alpha[ alphaAnzahl ] == 0xFF )
+        return;
+    int dpx = dPosA[ doa ].x;
+    int dpy = dPosA[ doa ].y;
+    int dgx = dGrößeA[ doa ].x;
+    int dgy = dGrößeA[ doa ].y;
+    a += drawOff[ doa ];
+    b += drawOff[ doa ];
+    c += drawOff[ doa ];
+    if( ( a.x < dpx && b.x < dpx && c.x < dpx ) || ( a.y < dpy && b.y < dpy && c.y < dpy ) ||
+        ( a.x > dgx && b.x > dgx && c.x > dgx ) || ( a.y > dgy && b.y > dgy && c.y > dgy ) )
+        return;
+    if( b.y < a.y )
+    {
+        a.Swap( b );
+        ta.Swap( tb );
+    }
+    if( c.y < b.y )
+    {
+        b.Swap( c );
+        tb.Swap( tc );
+    }
+    if( b.y < a.y )
+    {
+        a.Swap( b );
+        ta.Swap( tb );
+    }
+    const double m1 = (double)( a.x - b.x ) / ( a.y - b.y );
+    const double m2 = (double)( a.x - c.x ) / ( a.y - c.y );
+    const double m3 = (double)( b.x - c.x ) / ( b.y - c.y );
+    double b1 = a.x - m1 * a.y;
+    double b2 = a.x - m2 * a.y;
+    double b3 = b.x - m3 * b.y;
+    const double qx = m2 * b.y + b2;
+    if( qx < b.x )
+    {
+        double tx1o, ty1o, tx2o, ty2o;
+        if( c.y - a.y )
+        {
+            tx1o = (double)( tc.x - ta.x ) / ( c.y - a.y );
+            ty1o = (double)( tc.y - ta.y ) / ( c.y - a.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        if( b.y - a.y )
+        {
+            tx2o = (double)( tb.x - ta.x ) / ( b.y - a.y );
+            ty2o = (double)( tb.y - ta.y ) / ( b.y - a.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        Vec2< double > q( ta.x + tx1o * ( b.y - a.y ), ta.y + ty1o * ( b.y - a.y ) );
+        double txf, tyf;
+        if( b.x - qx )
+        {
+            txf = ( tb.x - q.x ) / ( b.x - qx );
+            tyf = ( tb.y - q.y ) / ( b.x - qx );
+        }
+        else
+        {
+            txf = 0;
+            tyf = 0;
+        }
+        drawFlatDreieckTexturAlpha( a.y, b.y, m2, b2, m1, b1, ta.x, ta.y, ta.x, ta.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+        if( c.y - b.y )
+        {
+            tx2o = (double)( tc.x - tb.x ) / ( c.y - b.y );
+            ty2o = (double)( tc.y - tb.y ) / ( c.y - b.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        drawFlatDreieckTexturAlpha( b.y, c.y, m2, b2, m3, b3, q.x, q.y, tb.x, tb.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+    }
+    else
+    {
+        double tx1o, ty1o, tx2o, ty2o;
+        if( b.y - a.y )
+        {
+            tx1o = (double)( tb.x - ta.x ) / ( b.y - a.y );
+            ty1o = (double)( tb.y - ta.y ) / ( b.y - a.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        if( c.y - a.y )
+        {
+            tx2o = (double)( tc.x - ta.x ) / ( c.y - a.y );
+            ty2o = (double)( tc.y - ta.y ) / ( c.y - a.y );
+        }
+        else
+        {
+            tx2o = 0;
+            ty2o = 0;
+        }
+        Vec2< double > q( ta.x + tx2o * ( b.y - a.y ), ta.y + ty2o * ( b.y - a.y ) );
+        double txf, tyf;
+        if( qx - b.x )
+        {
+            txf = ( q.x - tb.x ) / ( qx - b.x );
+            tyf = ( q.y - tb.y ) / ( qx - b.x );
+        }
+        else
+        {
+            txf = 0;
+            tyf = 0;
+        }
+        drawFlatDreieckTexturAlpha( a.y, b.y, m1, b1, m2, b2, ta.x, ta.y, ta.x, ta.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+        if( c.y - b.y )
+        {
+            tx1o = (double)( tc.x - tb.x ) / ( c.y - b.y );
+            ty1o = (double)( tc.y - tb.y ) / ( c.y - b.y );
+        }
+        else
+        {
+            tx1o = 0;
+            ty1o = 0;
+        }
+        drawFlatDreieckTexturAlpha( b.y, c.y, m3, b3, m2, b2, tb.x, tb.y, q.x, q.y, tx1o, ty1o, tx2o, ty2o, txf, tyf, textur );
+    }
+}
+
+bool Bild::setDrawOptions( const Punkt &pos, const Punkt &gr ) // setzt die Drawoptionen
+{
+    int dx = drawOff[ doa ].x, dy = drawOff[ doa ].y;
+    int xx = dPosA[ doa ].x, yy = dPosA[ doa ].y;
+    int bb = dGrößeA[ doa ].x, hh = dGrößeA[ doa ].y;
+    if( dx + pos.x + gr.x < 0 || dy + pos.y + gr.y < 0 || dx + pos.x >= größe.x || dy + pos.y >= größe.y )
+        return 0;
+    if( pos.x + gr.x + dx < xx || pos.y + gr.y + dy < yy || dx + pos.x >= bb || dy + pos.y >= hh )
+        return 0;
+    ++doa;
+    assert( doa < 2000 );
+    dPosA[ doa ].x = maxInt( pos.x + dx, xx );
+    dPosA[ doa ].y = maxInt( pos.y + dy, yy );
+    dGrößeA[ doa ].x = minInt( pos.x + gr.x + dx, bb );
+    dGrößeA[ doa ].y = minInt( pos.y + gr.y + dy, hh );
+    drawOff[ doa ].x = dx + pos.x;
+    drawOff[ doa ].y = dy + pos.y;
+    return 1;
+}
+
+bool Bild::setDrawOptions( int x, int y, int br, int hö )
+{
+    int dx = drawOff[ doa ].x, dy = drawOff[ doa ].y;
+    int xx = dPosA[ doa ].x, yy = dPosA[ doa ].y;
+    int bb = dGrößeA[ doa ].x, hh = dGrößeA[ doa ].y;
+    if( dx + x + br < 0 || dy + y + hö < 0 || dx + x >= größe.x || dy + y >= größe.y )
+        return 0;
+    if( x + br + dx < xx || y + hö + dy < yy || dx + x >= bb || dy + y >= hh )
+        return 0;
+    ++doa;
+    assert( doa < 2000 );
+    dPosA[ doa ].x = maxInt( x + dx, xx );
+    dPosA[ doa ].y = maxInt( y + dy, yy );
+    dGrößeA[ doa ].x = minInt( x + br + dx, bb );
+    dGrößeA[ doa ].y = minInt( y + hö + dy, hh );
+    drawOff[ doa ].x = dx + x;
+    drawOff[ doa ].y = dy + y;
+    return 1;
+}
+
+bool Bild::setDrawOptionsErzwingen( const Punkt &pos, const Punkt &gr ) // setzt die Drawoptionen
+{
+    int dx = drawOff[ doa ].x, dy = drawOff[ doa ].y;
+    if( dx + pos.x + gr.x < 0 || dy + pos.y + gr.y < 0 || dx + pos.x >= größe.x || dy + pos.y >= größe.y )
+        return 0;
+    ++doa;
+    assert( doa < 2000 );
+    dPosA[ doa ].x = maxInt( pos.x + dx, 0 );
+    dPosA[ doa ].y = maxInt( pos.y + dy, 0 );
+    dGrößeA[ doa ].x = minInt( pos.x + gr.x + dx, größe.x );
+    dGrößeA[ doa ].y = minInt( pos.y + gr.y + dy, größe.y );
+    drawOff[ doa ].x = dx + pos.x;
+    drawOff[ doa ].y = dy + pos.y;
+    return 1;
+}
+
+bool Bild::setDrawOptionsErzwingen( int x, int y, int br, int hö ) // setzt die Drawoptionen
+{
+    int dx = drawOff[ doa ].x, dy = drawOff[ doa ].y;
+    if( dx + x + br < 0 || dy + y + hö < 0 || dx + x >= größe.x || dy + y >= größe.y )
+        return 0;
+    ++doa;
+    assert( doa < 2000 );
+    dPosA[ doa ].x = maxInt( x + dx, 0 );
+    dPosA[ doa ].y = maxInt( y + dy, 0 );
+    dGrößeA[ doa ].x = minInt( x + br + dx, größe.x );
+    dGrößeA[ doa ].y = minInt( y + hö + dy, größe.y );
+    drawOff[ doa ].x = dx + x;
+    drawOff[ doa ].y = dy + y;
+    return 1;
+}
+
+void Bild::addScrollOffset( int xOff, int yOff ) // setzt ScrollOffset
+{
+    drawOff[ doa ].x -= xOff;
+    drawOff[ doa ].y -= yOff;
+}
+
+void Bild::releaseDrawOptions() // setzt die Drawoptionen zurück
+{
+    --doa;
+}
+
+bool Bild::getRend()
+{
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+// constant 
+int *Bild::getBuffer()const // gibt buffer zurück
+{
+    return fc;
+}
+
+int Bild::getPixel( int x, int y ) const
+{
+    if( x < 0 || y < 0 || x >= größe.x || y >= größe.y )
+        return 0;
+    return fc[ x + y * größe.x ];
+}
+
+const Punkt &Bild::getGröße() const // gibt die Größe zurück
+{
+    return größe;
+}
+
+int Bild::getBreite() const // gibt die Breite zurück
+{
+    return größe.x;
+}
+
+int Bild::getHöhe() const // gibt die Höhe zurück
+{
+    return größe.y;
+}
+
+unsigned char Bild::getAlpha() const // gibt den Alpha wert zurück
+{
+    return 255 - alpha[ alphaAnzahl ];
+}
+
+const Punkt &Bild::getDrawPos() const
+{
+    return dPosA[ doa ];
+}
+
+const Punkt &Bild::getDrawGr() const
+{
+    return dGrößeA[ doa ];
+}
+
+const Punkt &Bild::getDrawOff() const
+{
+    return drawOff[ doa ];
+}
+
+// Reference Counting 
+Bild *Bild::getThis()
+{
+    ++ref;
+    return this;
+}
+
+Bild *Bild::release()
+{
+    --ref;
+    if( ref < 1 )
+        delete this;
+    return 0;
+}
+
+
+#ifdef WIN32
+// Inhalt der BildO Klasse aus Bild.h
+// Konstruktor 
+BildO::BildO()
+    : ZeichnungHintergrund(),
+    bild( 0 ),
+    ref( 1 )
+{
+    style = 0;
+    Mak = _ret1ME;
+}
+
+// Destruktor 
+BildO::~BildO()
+{
+    if( bild )
+        bild->release();
+}
+
+// nicht constant 
+void BildO::setBildZ( Bild *b ) // setzt das Bild
+{
+    if( bild )
+        bild->release();
+    bild = b;
+    if( !vertikalScrollBar )
+        vertikalScrollBar = new VScrollBar();
+    if( !horizontalScrollBar )
+        horizontalScrollBar = new HScrollBar();
+    horizontalScrollBar->getScrollData()->maxBreite = b->getBreite();
+    vertikalScrollBar->getScrollData()->maxHöhe = b->getHöhe();
+    rend = 1;
+}
+
+void BildO::setBild( Bild *b )
+{
+    if( !bild )
+        bild = new Bild();
+    bild->neuBild( b->getBreite(), b->getHöhe(), 0 );
+    bild->drawBild( 0, 0, b->getBreite(), b->getHöhe(), *b );
+    if( !vertikalScrollBar )
+        vertikalScrollBar = new VScrollBar();
+    if( !horizontalScrollBar )
+        horizontalScrollBar = new HScrollBar();
+    horizontalScrollBar->getScrollData()->maxBreite = b->getBreite();
+    vertikalScrollBar->getScrollData()->maxHöhe = b->getHöhe();
+    b->release();
+    rend = 1;
+}
+
+bool BildO::tick( double tickVal ) // tick
+{
+    return __super::tick( tickVal );
+}
+
+void BildO::doMausEreignis( MausEreignis &me ) // ruft Mak auf
+{
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( hatStyle( Style::Sichtbar ) )
+    {
+        if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+        {
+            if( me.id != ME_Betritt && me.id != ME_Verlässt )
+            {
+                lockZeichnung();
+                int rbr = 0;
+                if( hatStyle( Style::Rahmen ) && rahmen )
+                    rbr = rahmen->getRBreite();
+                bool vs = hatStyle( Style::VScroll ) && vertikalScrollBar;
+                bool hs = hatStyle( Style::HScroll ) && horizontalScrollBar;
+                if( vs )
+                {
+                    if( hs )
+                        horizontalScrollBar->doMausMessage( rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, me );
+                    vertikalScrollBar->doMausMessage( gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me );
+                }
+                else if( hs )
+                    horizontalScrollBar->doMausMessage( rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, me );
+                unlockZeichnung();
+                if( vs || hs )
+                    me.verarbeitet = 1;
+            }
+        }
+    }
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void BildO::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+    if( hatStyle( Style::Sichtbar ) )
+    {
+        __super::render( zRObj );
+        lockZeichnung();
+        if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+        {
+            unlockZeichnung();
+            return;
+        }
+        if( bild )
+        {
+            int x = 0;
+            int y = 0;
+            int br = innenGröße.x;
+            int hö = innenGröße.y;
+            if( !( vertikalScrollBar && hatStyle( Style::VScroll ) ) && !( horizontalScrollBar && hatStyle( Style::HScroll ) ) )
+            {
+                if( hatStyle( Style::Alpha ) )
+                    zRObj.alphaBild( x, y, br, hö, *bild );
+                else
+                    zRObj.drawBild( x, y, br, hö, *bild );
+            }
+            else
+            {
+                if( !zRObj.setDrawOptions( x, y, br, hö ) )
+                {
+                    zRObj.releaseDrawOptions();
+                    unlockZeichnung();
+                    return;
+                }
+                if( hatStyle( Style::Alpha ) )
+                    zRObj.alphaBild( -horizontalScrollBar->getScrollData()->anzeigeBeginn, -vertikalScrollBar->getScrollData()->anzeigeBeginn, bild->getBreite(), bild->getHöhe(), *bild );
+                else
+                    zRObj.drawBild( -horizontalScrollBar->getScrollData()->anzeigeBeginn, -vertikalScrollBar->getScrollData()->anzeigeBeginn, bild->getBreite(), bild->getHöhe(), *bild );
+                zRObj.releaseDrawOptions();
+            }
+        }
+        zRObj.releaseDrawOptions();
+        unlockZeichnung();
+    }
+}
+
+// constant 
+Bild *BildO::getBild() const // gibt das Bild zurück
+{
+    if( bild )
+        return bild->getThis();
+    return 0;
+}
+
+Bild *BildO::zBild() const
+{
+    return bild;
+}
+
+Zeichnung *BildO::dublizieren() const // erstellt eine Kopie des Zeichnungs
+{
+    BildO *obj = new BildO();
+    obj->setPosition( pos );
+    obj->setGröße( gr );
+    obj->setMausEreignisParameter( makParam );
+    obj->setTastaturEreignisParameter( takParam );
+    obj->setMausEreignis( Mak );
+    obj->setTastaturEreignis( Tak );
+    if( toolTip )
+        obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+    obj->setStyle( style );
+    obj->setHintergrundFarbe( hintergrundFarbe );
+    if( hintergrundFeld )
+        obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+    if( rahmen )
+        obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+    if( hintergrundBild )
+        obj->setHintergrundBild( hintergrundBild->getThis() );
+    if( bild )
+        obj->setBild( bild->getThis() );
+    obj->setStyle( style );
+    return obj;
+}
+
+// Reference Counting 
+BildO *BildO::getThis()
+{
+    ++ref;
+    return this;
+}
+
+BildO *BildO::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+Bild *Framework::ladeBild( char *pfad, Text *zError )
+{
+    Text p = pfad;
+    Text *txt = p.getTeilText( p.positionVon( '.', p.anzahlVon( '.' ) - 1 ) );
+    if( !( txt->istGleich( ".bmp" ) || txt->istGleich( ".jpg" ) || txt->istGleich( ".gif" ) || txt->istGleich( ".png" ) ) )
+    {
+        zError->setText( "Die Angegebene Datei ist keine gueltige Bilddatei!" );
+        txt->release();
+        return 0;
+    }
+    txt->release();
+    wchar_t *name = new wchar_t[ p.getLänge() + 1 ];
+    for( int i = 0; i < p.getLänge(); i++ )
+        name[ i ] = (wchar_t)p.getText()[ i ];
+    name[ p.getLänge() ] = '\0';
+
+    Gdiplus::Bitmap bitmap( name );
+    Gdiplus::Color pix;
+    delete[]name;
+
+    Bild *ret = new Bild();
+    ret->neuBild( bitmap.GetWidth(), bitmap.GetHeight(), 0 );
+    int *buff = ret->getBuffer();
+    for( unsigned int i = 0; i < bitmap.GetWidth() * bitmap.GetHeight(); i++ )
+    {
+        bitmap.GetPixel( i % bitmap.GetWidth(), i / bitmap.GetWidth(), &pix );
+        buff[ i ] = pix.GetValue();
+    }
+    return ret;
+}
+
+#endif

+ 157 - 0
Bild.h

@@ -0,0 +1,157 @@
+#ifndef Bild_H
+#define Bild_H
+
+#include "Array.h"
+#ifdef WIN32
+#include "Zeichnung.h"
+#else
+#include "Punkt.h"
+#endif
+
+namespace Framework
+{
+	class Bild; // aus dieser Datei
+#ifdef WIN32
+	class VScrollBar; // Scroll.h
+	class HScrollBar; // Scroll.h
+	struct VScrollData; // Scroll.h
+	struct HScrollData; // Scroll.h
+	class LRahmen; // Rahmen.h
+	struct MausEreignis; // Mausereignis.h
+	class BildO; // aus dieser Datei
+    class Text; // Text.h
+#endif
+
+	class Bild
+	{
+	private:
+		int *fc;
+		bool delFc;
+		Punkt größe;
+		int ref;
+		Punkt *drawOff;
+		Punkt *dPosA;
+		Punkt *dGrößeA;
+		int doa;
+		unsigned char *alpha;
+		int alphaAnzahl;
+		bool rend;
+        bool alpha3D;
+		// privat
+		inline void alphaPixelP( int x, int y, int f );
+		inline void alphaPixelP( int &fc, int f );
+		inline char getOutCode( Punkt& p ) const;
+		void drawFlatDreieck( int y1, int y2, float m1, float b1, float m2, float b2, int farbe );
+		void drawFlatDreieckTextur( int y1, int y2, double m1, double b1, double m2, double b2, double tx1, double ty1, double tx2, double ty2,
+									double tx_1o, double ty_1o, double tx_2o, double ty_2o, double txf, double tyf, Bild &textur );
+		void drawFlatDreieckAlpha( int y1, int y2, float m1, float b1, float m2, float b2, int farbe );
+		void drawFlatDreieckTexturAlpha( int y1, int y2, double m1, double b1, double m2, double b2, double tx1, double ty1, double tx2, double ty2,
+										 double tx_1o, double ty_1o, double tx_2o, double ty_2o, double txf, double tyf, Bild &textur );
+		void drawLinieHTextur( Vec2< double > p, double län, Vec2< double > ta, Vec2< double > tb, double txo, double tyo, Bild &textur );
+		void drawLinieHTexturAlpha( Vec2< double > p, double län, Vec2< double > ta, Vec2< double > tb, double txo, double tyo, Bild &textur );
+	
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Bild( bool options = 0 );
+		// Destruktor 
+		__declspec( dllexport ) ~Bild(); 
+        // Wird dieser Flag gesetzt, so wird beim Alpha Blending wenn die vorheriege Farbe 0 ist nur die neue mit ihrem Alpha Wert kopiert.
+        // Das ist sinnvoll für die Verwendung im 3DBildschirm, wo das Gezeichnette Bild später mittels Alpha Blending angezeigt wird
+        __declspec( dllexport ) void setAlpha3D( bool erlaubt );
+ 		__declspec( dllexport ) void setAlpha( unsigned char alpha ); // setzt die Transparenz der nachfolgenden Zeichnunge
+		__declspec( dllexport ) void releaseAlpha(); // Löscht alpha
+		__declspec( dllexport ) void setPixelBuffer( int *buffer, bool deleteBuffer, int breite, int höhe ); // setzt den Zeiger auf die Pixel des Bildes
+		__declspec( dllexport ) void neuBild( int breite, int höhe, int füllFarbe ); // erzeugt ein neues Bild mit der Hintergrundfarbe füllFarbe
+		__declspec( dllexport ) void alphaPixel( int x, int y, int f );
+		__declspec( dllexport ) void alphaPixel( int i, int f );
+		__declspec( dllexport ) void alphaPixelDP( int x, int y, int f );
+		__declspec( dllexport ) void alphaPixelDP( int i, int f );
+		__declspec( dllexport ) void setPixelDP( int x, int y, int f );
+		__declspec( dllexport ) void setPixelDP( int i, int f );
+		__declspec( dllexport ) void setFarbe( int f );
+		__declspec( dllexport ) void füllRegion( int x, int y, int b, int h, int fc );
+		__declspec( dllexport ) void alphaRegion( int x, int y, int b, int h, int fc );
+		__declspec( dllexport ) void drawLinieH( int x, int y, int län, int fc ); // zeichnet eine horizontale Linie
+		__declspec( dllexport ) void drawLinieV( int x, int y, int län, int fc ); // zeichnet eine vertikale Linie
+		__declspec( dllexport ) void drawLinieHAlpha( int x, int y, int län, int fc ); // zeichnet eine horizontale Linie
+		__declspec( dllexport ) void drawLinieVAlpha( int x, int y, int län, int fc ); // zeichnet eine vertikale Linie
+		__declspec( dllexport ) void drawLinie( Punkt a, Punkt b, int fc ); // zeichnet eine Linie von Punkt( x1, y1 ) nach Punke( x2, y2 )
+		__declspec( dllexport ) void drawLinieAlpha( Punkt a, Punkt b, int fc );
+        __declspec( dllexport ) void füllKreis( int xOff, int yOff, int r, int fc ); // zeichnet einen Kreis um Punkt( xOff, yOff ) mit radius r
+		__declspec( dllexport ) void drawKreis( int xOff, int yOff, int r, int fc ); // zeichnet einen Kreis um Punkt( xOff, yOff ) mit radius r
+		__declspec( dllexport ) void drawKreisAlpha( int xOff, int yOff, int r, int fc );
+		__declspec( dllexport ) void drawBild( int x, int y, int br, int hö, Bild &zBild ); // zeichet zBild
+		__declspec( dllexport ) void alphaBild( int x, int y, int br, int hö, Bild &zBild );
+		__declspec( dllexport ) void drawBild90( int x, int y, int br, int hö, Bild &zBild ); // Zeichnet ein um 90 Grad nach rchts gedrehtes Bild
+		__declspec( dllexport ) void alphaBild90( int x, int y, int br, int hö, Bild &zBild );
+		__declspec( dllexport ) void drawBild180( int x, int y, int br, int hö, Bild &zBild ); // Zeichnet ein um 180 Grad nach rchts gedrehtes Bild
+		__declspec( dllexport ) void alphaBild180( int x, int y, int br, int hö, Bild &zBild );
+		__declspec( dllexport ) void drawBild270( int x, int y, int br, int hö, Bild &zBild ); // Zeichnet ein um 270 Grad nach rchts gedrehtes Bild
+		__declspec( dllexport ) void alphaBild270( int x, int y, int br, int hö, Bild &zBild );
+		__declspec( dllexport ) void drawBildSkall( int x, int y, int br, int hö, Bild &zBild ); // zeichet zBild Skalliert
+		__declspec( dllexport ) void alphaBildSkall( int x, int y, int br, int hö, Bild &zBild );
+		__declspec( dllexport ) void drawDreieck( Punkt a, Punkt b, Punkt c, int farbe ); // füllt eine Dreieck aus
+		__declspec( dllexport ) void drawDreieckTextur( Punkt a, Punkt b, Punkt c, Punkt ta, Punkt tb, Punkt tc, Bild &textur );
+		__declspec( dllexport ) void drawDreieckAlpha( Punkt a, Punkt b, Punkt c, int farbe );
+		__declspec( dllexport ) void drawDreieckTexturAlpha( Punkt a, Punkt b, Punkt c, Punkt ta, Punkt tb, Punkt tc, Bild &textur );
+		__declspec( dllexport ) bool setDrawOptions( const Punkt &pos, const Punkt &gr ); // setzt die Drawoptionen
+		__declspec( dllexport ) bool setDrawOptions( int x, int y, int br, int hö );
+		__declspec( dllexport ) bool setDrawOptionsErzwingen( const Punkt &pos, const Punkt &gr ); // setzt die Drawoptionen
+		__declspec( dllexport ) bool setDrawOptionsErzwingen( int x, int y, int br, int hö ); // setzt die Drawoptionen
+		__declspec( dllexport ) void addScrollOffset( int xOff, int yOff ); // setzt ScrollOffset
+		__declspec( dllexport ) void releaseDrawOptions(); // setzt die Drawoptionen zurück
+		__declspec( dllexport ) bool getRend();
+		// constant 
+		__declspec( dllexport ) int *getBuffer()const; // gibt buffer zurück
+		__declspec( dllexport ) int getPixel( int x, int y ) const; // gibt die Farbe des Pixels(x, y) zurück
+		__declspec( dllexport ) const Punkt &getGröße() const; // gibt die Größe zurück
+		__declspec( dllexport ) int getBreite() const; // gibt die Breite zurück
+		__declspec( dllexport ) int getHöhe() const; // gibt die Höhe zurück
+		__declspec( dllexport ) unsigned char getAlpha() const; // gibt den Alpha wert zurück
+		__declspec( dllexport ) const Punkt &getDrawPos() const;
+		__declspec( dllexport ) const Punkt &getDrawGr() const;
+		__declspec( dllexport ) const Punkt &getDrawOff() const;
+		// Reference Counting 
+		__declspec( dllexport ) Bild *getThis();
+		__declspec( dllexport ) Bild *release();
+	};
+#ifdef WIN32
+
+	class BildO : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 Alpha = 0x1000;
+
+            const static __int64 normal = HScroll | Sichtbar | Erlaubt | Rahmen | VScroll;
+        };
+	private:
+		Bild *bild;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) BildO();
+		// Destruktor 
+		__declspec( dllexport ) ~BildO();
+		// nicht constant 
+		__declspec( dllexport ) void setBildZ( Bild *b ); // setzt das Bild
+		__declspec( dllexport ) void setBild( Bild *b );
+		__declspec( dllexport ) bool tick( double tickVal ) override; // tick
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override; // ruft Mak auf
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) Bild *getBild() const; // gibt das Bild zurück
+		__declspec( dllexport ) Bild *zBild() const;
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // erstellt eine Kopie des Zeichnungs
+		// Reference Counting 
+		__declspec( dllexport ) BildO *getThis();
+		__declspec( dllexport ) BildO *release();
+	};
+
+    __declspec( dllexport ) Bild *ladeBild( char *pfad, Text *zError );
+#endif
+}
+#endif

+ 1076 - 0
Bildschirm.cpp

@@ -0,0 +1,1076 @@
+#include "Bildschirm.h"
+#include "Bild.h"
+#include "Fenster.h"
+#include "Text.h"
+#include "Zeichnung.h"
+#include "Globals.h"
+#include "Zeit.h"
+#include "ToolTip.h"
+#include "MausEreignis.h"
+#include <iostream>
+#include <DirectXMath.h>
+#include <D3Dcompiler.h>
+#include "Datei.h"
+#include "DefaultShader.h"
+#include "comdef.h"
+#include "Zeichnung3D.h"
+#include "Shader.h"
+#include "Kam3D.h"
+#include "Render3D.h"
+#include "Mat3.h"
+#include "DXBuffer.h"
+#include "Model3D.h"
+#include "Textur.h"
+#include <d3d11.h>
+#include <d3d9.h>
+
+using namespace Framework;
+
+// Inhalt der Bildschirmklass aus Bildschirm.h
+// Konstruktor 
+Bildschirm::Bildschirm( WFenster *f )
+    : fenster( f ),
+    renderB( new Bild( 1 ) ),
+    ref( 1 ),
+    members( new ZeichnungArray() ),
+    füllFarbe( 0xFF000000 ),
+    deckFarbe( 0 ),
+    onTop( 0 ),
+    renderOnTop( 0 ),
+    renderZeichnungen( 1 ),
+    vollbild( 0 ),
+    rendering( 0 ),
+    renderZeit( new ZeitMesser() ),
+    backBufferGröße( 0, 0 ),
+    tips( new RCArray< ToolTip >() ),
+    tipAnzahl( 0 ),
+    testRend( 1 ),
+    füll( 1 ),
+    rend( 0 )
+{
+    InitializeCriticalSection( &cs );
+}
+
+// Destruktor 
+Bildschirm::~Bildschirm()
+{
+    lock();
+    if( renderB )
+        renderB->release();
+    if( fenster )
+        fenster->release();
+    delete members;
+    tipAnzahl = 0;
+    tips->release();
+    renderZeit->release();
+    unlock();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht konstant 
+void Bildschirm::lock()
+{
+    EnterCriticalSection( &cs );
+}
+
+void Bildschirm::unlock()
+{
+    LeaveCriticalSection( &cs );
+}
+
+void Bildschirm::setFüll( bool f )
+{
+    füll = f;
+}
+
+void Bildschirm::setTestRend( bool tr ) // legt fest, ob vo rendern auf updates geprüft werden soll
+{
+    testRend = tr;
+}
+
+void Bildschirm::setRenderZeichnungen( bool rO ) // legt fest, ob die Zeichnunge gerendert werden
+{
+    lock();
+    renderZeichnungen = rO;
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::setOnTop( bool onTop ) // legt fest, ob das onTop Zeichnung gerendert wid
+{
+    renderOnTop = onTop;
+    rend = 1;
+}
+
+void Bildschirm::setOnTopZeichnung( Zeichnung *obj ) // setzt das OnTop Zeichnung
+{
+    lock();
+    onTop = obj;
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::setdeckFarbe( int f ) // setzt die deckFarbe
+{
+    deckFarbe = f;
+    rend = 1;
+}
+
+void Bildschirm::addMember( Zeichnung *obj ) // Fügt ein Zeichnung hinzu
+{
+    lock();
+    members->addZeichnung( obj );
+    members->updateIndex( 0 );
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::removeMember( Zeichnung *obj ) // Entfernt ein Zeichnung
+{
+    lock();
+    members->removeZeichnung( obj );
+    members->updateIndex( 0 );
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::setFüllFarbe( int f ) // setzt die Fill Farbe
+{
+    füllFarbe = f;
+    rend = 1;
+}
+
+void Bildschirm::setVollbild( bool vollbild ) // setzt vollbild
+{
+    lock();
+    this->vollbild = vollbild;
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::tick( double tickval )
+{
+    lock();
+    if( !renderOnTop )
+    {
+        for( int i = 0; i < tipAnzahl; ++i )
+            rend |= tips->z( i )->tick( tickval );
+        rend |= members->tick( tickval );
+    }
+    else if( onTop )
+    {
+        rend |= onTop->tick( tickval );
+        for( int i = 0; i < tipAnzahl; ++i )
+            rend |= tips->z( i )->tick( tickval );
+    }
+    unlock();
+}
+
+void Bildschirm::setBackBufferGröße( int breite, int höhe ) // setzt die Größe des Backbuffers
+{
+    lock();
+    backBufferGröße.x = breite;
+    backBufferGröße.y = höhe;
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::setBackBufferGröße( Punkt &größe )
+{
+    lock();
+    backBufferGröße = größe;
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm::doMausEreignis( MausEreignis &me ) // sendet maus Ereignis
+{
+    int fBr = backBufferGröße.x;
+    int fHö = backBufferGröße.y;
+    if( fenster )
+    {
+        fBr = fenster->getKörperBreite();
+        fHö = fenster->getKörperHöhe();
+    }
+    me.mx = (int)( me.mx * backBufferGröße.x / (double)fBr + 0.5 );
+    me.my = (int)( me.my * backBufferGröße.y / (double)fHö + 0.5 );
+    lock();
+    if( !renderOnTop )
+    {
+        for( int i = 0; i < tipAnzahl; ++i )
+            tips->z( i )->doMausEreignis( me );
+        members->sendMausAll( me );
+    }
+    else if( onTop )
+    {
+        onTop->doMausEreignis( me );
+        for( int i = 0; i < tipAnzahl; ++i )
+            tips->z( i )->doMausEreignis( me );
+    }
+    unlock();
+}
+
+void Bildschirm::doTastaturEreignis( TastaturEreignis &te ) // sendet tastatur Ereignis
+{
+    lock();
+    if( !renderOnTop )
+        members->sendTastaturAll( te );
+    else if( onTop )
+        onTop->doTastaturEreignis( te );
+    unlock();
+}
+
+void Bildschirm::addToolTip( ToolTip *tip ) // fügt ToolTip hinzu
+{
+    lock();
+    tips->add( tip, tipAnzahl );
+    ++tipAnzahl;
+    rend = 1;
+    unlock();
+}
+
+bool Bildschirm::removeToolTip( ToolTip *zTip ) // entfernt ToolTip
+{
+    lock();
+    bool gefunden = 0;
+    for( int i = 0; i < tipAnzahl; ++i )
+    {
+        ToolTip *tmp = tips->z( i );
+        if( tmp == zTip )
+        {
+            tips->lösche( i );
+            --tipAnzahl;
+            gefunden = 1;
+            rend = 1;
+            break;
+        }
+    }
+    unlock();
+    return gefunden;
+}
+
+// constant 
+Bild *Bildschirm::getRenderBild() const
+{
+    return renderB->getThis();
+}
+
+Bild *Bildschirm::zRenderBild() const
+{
+    return renderB;
+}
+
+ZeichnungArray *Bildschirm::getMembers() const // gibt die Zeichnunge zurück
+{
+    return members;
+}
+
+int Bildschirm::getFüllFarbe() const // gibt die Füll Farbe zurück
+{
+    return füllFarbe;
+}
+
+bool Bildschirm::istVolbild() const // gibt zurück, ob vollbild an ist
+{
+    return vollbild;
+}
+
+const Punkt &Bildschirm::getBackBufferGröße() const // gibt die Größe des Backbuffers zurück
+{
+    return backBufferGröße;
+}
+
+void Bildschirm::warteAufRendern() const // wartet auf die render Funktion
+{
+    while( rendering )
+    {
+        if( !rendering )
+            return;
+    }
+}
+
+double Bildschirm::getRenderZeit() const // gibt zurück wie viele Sekunden das Rendern dauert
+{
+    return renderZeit->getSekunden();
+}
+
+// Reference Counting 
+Bildschirm *Bildschirm::getThis()
+{
+    ++ref;
+    return this;
+}
+
+Bildschirm *Bildschirm::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+int MonitorEnum( HMONITOR m, HDC dc, LPRECT r, LPARAM p )
+{
+    Monitor *mon = new Monitor();
+    mon->existiert = 1;
+    mon->x = r->left;
+    mon->y = r->top;
+    mon->breite = r->right - r->left;
+    mon->höhe = r->bottom - r->top;
+    ( ( Array< Monitor* >* )p )->add( mon );
+    return 1;
+}
+
+Monitor Framework::getMonitor( int id )
+{
+    if( id < 0 )
+    {
+        Monitor m;
+        m.existiert = 0;
+        return m;
+    }
+    Array< Monitor* > *monitore = new Array< Monitor* >();
+    EnumDisplayMonitors( 0, 0, (MONITORENUMPROC)MonitorEnum, (LPARAM)monitore );
+    if( id >= monitore->getEintragAnzahl() )
+    {
+        for( int i = 0; monitore->get( i ); ++i )
+            delete monitore->get( i );
+        delete monitore;
+        Monitor m;
+        m.existiert = 0;
+        return m;
+    }
+    Monitor m = *monitore->get( id );
+    int anz = monitore->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+        delete monitore->get( i );
+    delete monitore;
+    return m;
+}
+
+// Bildschirm2D
+// Konstruktor 
+Bildschirm2D::Bildschirm2D( WFenster *fenster )
+    : Bildschirm( fenster ),
+    pDirect3D( 0 ),
+    pDevice( 0 ),
+    pBackBuffer( 0 ),
+    backRect( new D3DLOCKED_RECT() )
+{}
+
+// Destruktor 
+Bildschirm2D::~Bildschirm2D()
+{
+    cleanUpDirectX();
+    delete backRect;
+}
+
+// private
+void Bildschirm2D::cleanUpDirectX()
+{
+    backRect->pBits = NULL;
+    if( pDevice )
+    {
+        pDevice->Release();
+        pDevice = NULL;
+    }
+    if( pDirect3D )
+    {
+        pDirect3D->Release();
+        pDirect3D = NULL;
+    }
+    if( pBackBuffer )
+    {
+        pBackBuffer->Release();
+        pBackBuffer = NULL;
+    }
+}
+
+// nicht constant 
+void Bildschirm2D::update() // aktualisiert directX
+{
+    lock();
+    HRESULT result;
+
+    cleanUpDirectX();
+
+    pDirect3D = Direct3DCreate9( D3D_SDK_VERSION );
+
+    D3DPRESENT_PARAMETERS d3dpp;
+    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
+    d3dpp.Windowed = !vollbild;
+    d3dpp.hDeviceWindow = fenster->getFensterHandle();
+    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
+    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+    d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+    if( !backBufferGröße.x || !backBufferGröße.y )
+        backBufferGröße = fenster->getKörperGröße();
+    d3dpp.BackBufferHeight = backBufferGröße.y;
+    d3dpp.BackBufferWidth = backBufferGröße.x;
+    if( renderB )
+        renderB->release();
+    renderB = new Bild( 1 );
+    renderB->neuBild( backBufferGröße.x, backBufferGröße.y, füllFarbe );
+
+    result = pDirect3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, fenster->getFensterHandle(),
+                                      D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &d3dpp, &pDevice );
+    if( pDevice )
+        result = pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm2D::render() // Zeichnet das Bild
+{
+    if( !rend && testRend )
+        return;
+    rendering = 1;
+    int count = 0;
+    if( renderB && pDevice )
+    {
+        lock();
+        renderZeit->messungStart();
+        if( füll )
+            renderB->setFarbe( füllFarbe );
+        if( renderZeichnungen )
+        {
+            if( renderOnTop && deckFarbe && ( deckFarbe & ( füllFarbe | 0xFF000000 ) ) == deckFarbe )
+            {
+                renderB->setAlpha( 255 - (unsigned char)( deckFarbe >> 24 ) );
+                members->render( *renderB ); // zeichnen nach zwischenbuffer
+                renderB->releaseAlpha();
+            }
+            else
+            {
+                members->render( *renderB ); // zeichnen nach zwischenbuffer
+                if( renderOnTop && deckFarbe )
+                    renderB->alphaRegion( 0, 0, renderB->getBreite(), renderB->getHöhe(), deckFarbe );
+            }
+            for( int i = 0; i < tipAnzahl; ++i )
+                tips->z( i )->render( *renderB );
+        }
+        if( renderOnTop && onTop )
+            onTop->render( *renderB );
+        Bild *tmp = renderB->getThis();
+        unlock();
+        // Beginne Bild 
+        HRESULT result;
+        if( !füllFarbe )
+            result = pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 0.0f, 0 );
+        result = pBackBuffer->LockRect( backRect, 0, 0 );
+        // kopieren zum Bildschrirm 
+        int *bgBuff = tmp->getBuffer();
+        int tmpBr = sizeof( D3DCOLOR )* tmp->getBreite();
+        for( int y = 0, pitch = 0, bry = 0; y < tmp->getHöhe(); ++y, pitch += backRect->Pitch, bry += tmp->getBreite() )
+            memcpy( &( (BYTE *)backRect->pBits )[ pitch ], (void*)&( bgBuff[ bry ] ), tmpBr );
+        // Beende Bild 
+        result = pBackBuffer->UnlockRect();
+        tmp->release();
+        result = pDevice->Present( 0, 0, 0, 0 );
+        renderZeit->messungEnde();
+        if( result != S_OK )
+        {
+            ++count;
+            update();
+        }
+        else if( count )
+            --count;
+    }
+    if( !pDevice )
+    {
+        ++count;
+        update();
+    }
+    if( count > 10 )
+    {
+        WMessageBox( fenster ? fenster->getFensterHandle() : 0, new Text( "Fehler" ), new Text( "Es ist ein Fehler beim rendern aufgetreten." ), MB_ICONERROR );
+        count = 0;
+    }
+    rendering = 0;
+    rend = 0;
+}
+
+Bildschirm *Bildschirm2D::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Bildschirm3D
+// Konstruktor 
+Bildschirm3D::Bildschirm3D( WFenster *fenster )
+    : Bildschirm( fenster ),
+    d3d11Device( 0 ),
+    d3d11Context( 0 ),
+    d3d11SpawChain( 0 ),
+    frameworkTextur( 0 ),
+    vertexBuffer( 0 ),
+    indexBuffer( 0 ),
+    vertexShader( 0 ),
+    pixelShader( 0 ),
+    sampleState( 0 ),
+    rtview( 0 ),
+    dsView( 0 ),
+    depthStencilBuffer( 0 ),
+    depthStencilState( 0 ),
+    depthDisabledStencilState( 0 ),
+    blendStateAlphaBlend( 0 ),
+    kameras( new RCArray< Kam3D >() ),
+    rend3D( 0 ),
+    vp( 0 ),
+    renderObj( new Render3D() )
+{}
+
+// Destruktor 
+Bildschirm3D::~Bildschirm3D()
+{
+    kameras->release();
+    renderObj->release();
+    cleanUpDirectX();
+}
+
+// private
+void Bildschirm3D::cleanUpDirectX()
+{
+    if( d3d11Device )
+    {
+        d3d11Device->Release();
+        d3d11Device = NULL;
+    }
+    if( d3d11Context )
+    {
+        d3d11Context->Release();
+        d3d11Context = NULL;
+    }
+    if( d3d11SpawChain )
+    {
+        d3d11SpawChain->Release();
+        d3d11SpawChain = NULL;
+    }
+    if( frameworkTextur )
+    {
+        frameworkTextur->release();
+        frameworkTextur = NULL;
+    }
+    if( vertexBuffer )
+    {
+        vertexBuffer->release();
+        vertexBuffer = NULL;
+    }
+    if( indexBuffer )
+    {
+        indexBuffer->release();
+        indexBuffer = NULL;
+    }
+    if( pixelShader )
+    {
+        pixelShader->release();
+        pixelShader = NULL;
+    }
+    if( vertexShader )
+    {
+        vertexShader->release();
+        vertexShader = NULL;
+    }
+    if( sampleState )
+    {
+        sampleState->Release();
+        sampleState = NULL;
+    }
+    if( rtview )
+    {
+        rtview->Release();
+        rtview = NULL;
+    }
+    if( dsView )
+    {
+        dsView->Release();
+        dsView = NULL;
+    }
+    if( depthStencilBuffer )
+    {
+        depthStencilBuffer->Release();
+        depthStencilBuffer = NULL;
+    }
+    if( depthStencilState )
+    {
+        depthStencilState->Release();
+        depthStencilState = NULL;
+    }
+    if( depthDisabledStencilState )
+    {
+        depthDisabledStencilState->Release();
+        depthDisabledStencilState = NULL;
+    }
+    if( blendStateAlphaBlend )
+    {
+        blendStateAlphaBlend->Release();
+        blendStateAlphaBlend = NULL;
+    }
+    delete vp;
+    vp = 0;
+}
+
+// nicht constant 
+void Bildschirm3D::addKamera( Kam3D *obj ) // Fügt ein Zeichnung hinzu
+{
+    lock();
+    kameras->add( obj );
+    rend3D = 1;
+    unlock();
+}
+
+void Bildschirm3D::removeKamera( Kam3D *zObj ) // Entfernt ein Zeichnung
+{
+    lock();
+    for( int i = 0; kameras->z( i ); i++ )
+    {
+        if( kameras->z( i ) == zObj )
+        {
+            kameras->lösche( i );
+            break;
+        }
+    }
+    rend3D = 1;
+    unlock();
+}
+
+void Bildschirm3D::update() // aktualisiert directX
+{
+    lock();
+    HRESULT result;
+    cleanUpDirectX();
+    //--------------------------------------------------------------------
+    // Create Device
+
+    // create a struct to hold information about the swap chain
+    DXGI_SWAP_CHAIN_DESC scd;
+
+    // clear out the struct for use
+    ZeroMemory( &scd, sizeof( DXGI_SWAP_CHAIN_DESC ) );
+
+    // fill the swap chain description struct
+    scd.BufferCount = 1;                                           // one back buffer
+    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;             // how swap chain is to be used
+    scd.OutputWindow = fenster ? fenster->getFensterHandle() : 0;  // the window to be used
+    scd.SampleDesc.Count = 1;
+    // Set the scan line ordering and scaling to unspecified.
+    scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+    scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+    scd.Windowed = !vollbild;
+    if( !backBufferGröße.x || !backBufferGröße.y )
+        backBufferGröße = fenster ? fenster->getKörperGröße() : Punkt( 0, 0 );
+    scd.BufferDesc.Width = backBufferGröße.x;
+    scd.BufferDesc.Height = backBufferGröße.y;                 // windowed/full-screen mode
+    scd.BufferDesc.RefreshRate.Denominator = 1;
+    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;       // use 32-bit color
+                                                              // Discard the back buffer contents after presenting.
+    scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+    if( renderB )
+        renderB->release();
+    renderB = new Bild( 1 );
+    renderB->setAlpha3D( 1 );
+    renderB->neuBild( backBufferGröße.x, backBufferGröße.y, füllFarbe );
+
+    D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
+    D3D_FEATURE_LEVEL support = D3D_FEATURE_LEVEL_11_0;
+    // create a device, device context and swap chain using the information in the scd struct
+    UINT flag = 0;
+#ifdef _DEBUG
+    flag |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+    result = D3D11CreateDeviceAndSwapChain( NULL,
+                                            D3D_DRIVER_TYPE_HARDWARE,
+                                            NULL,
+                                            flag,
+                                            &featureLevel,
+                                            1,
+                                            D3D11_SDK_VERSION,
+                                            &scd,
+                                            &d3d11SpawChain,
+                                            &d3d11Device,
+                                            &support,
+                                            &d3d11Context );
+
+    ID3D11Texture2D *backBufferPtr;
+    // Get the pointer to the back buffer.
+    result = d3d11SpawChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&backBufferPtr );
+    // Create the render target view with the back buffer pointer.
+    result = d3d11Device->CreateRenderTargetView( backBufferPtr, NULL, &rtview );
+    // Release pointer to the back buffer as we no longer need it.
+    backBufferPtr->Release();
+    // Initialize the description of the depth buffer.
+    D3D11_TEXTURE2D_DESC depthBufferDesc;
+    ZeroMemory( &depthBufferDesc, sizeof( depthBufferDesc ) );
+    // Set up the description of the depth buffer.
+    depthBufferDesc.Width = backBufferGröße.x;
+    depthBufferDesc.Height = backBufferGröße.y;
+    depthBufferDesc.MipLevels = 1;
+    depthBufferDesc.ArraySize = 1;
+    depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+    depthBufferDesc.SampleDesc.Count = 1;
+    depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
+    depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+    // Create the texture for the depth buffer using the filled out description.
+    result = d3d11Device->CreateTexture2D( &depthBufferDesc, NULL, &depthStencilBuffer );
+
+    // Initialize the description of the stencil state.
+    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
+    ZeroMemory( &depthStencilDesc, sizeof( depthStencilDesc ) );
+
+    // Set up the description of the stencil state.
+    depthStencilDesc.DepthEnable = true;
+    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+    depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
+    depthStencilDesc.StencilEnable = true;
+    depthStencilDesc.StencilReadMask = 0xFF;
+    depthStencilDesc.StencilWriteMask = 0xFF;
+    // Stencil operations if pixel is front-facing.
+    depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+    depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+    depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+    // Stencil operations if pixel is back-facing.
+    depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+    depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+    depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+    depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+    // Create the depth stencil state.
+    result = d3d11Device->CreateDepthStencilState( &depthStencilDesc, &depthStencilState );
+
+    d3d11Context->OMSetDepthStencilState( depthStencilState, 1 );
+
+    // Initialize the depth stencil view.
+    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
+    ZeroMemory( &depthStencilViewDesc, sizeof( depthStencilViewDesc ) );
+
+    // Set up the depth stencil view description.
+    depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+    depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+
+    // Create the depth stencil view.
+    result = d3d11Device->CreateDepthStencilView( depthStencilBuffer, &depthStencilViewDesc, &dsView );
+
+    d3d11Context->OMSetRenderTargets( 1, &rtview, dsView );
+
+    vp = new D3D11_VIEWPORT();
+    memset( vp, 0, sizeof( D3D11_VIEWPORT ) );
+    vp->Width = (float)backBufferGröße.x;
+    vp->Height = (float)backBufferGröße.y;
+    vp->MinDepth = 0.0f;
+    vp->MaxDepth = 1.0f;
+    vp->TopLeftX = 0.0f;
+    vp->TopLeftY = 0.0f;
+
+    d3d11Context->RSSetViewports( 1, vp );
+
+    D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
+    // Clear the second depth stencil state before setting the parameters.
+    ZeroMemory( &depthDisabledStencilDesc, sizeof( depthDisabledStencilDesc ) );
+    
+    // Now create a second depth stencil state which turns off the Z buffer for 2D rendering.  The only difference is 
+    // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state.
+    depthDisabledStencilDesc.DepthEnable = false;
+    depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+    depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
+    depthDisabledStencilDesc.StencilEnable = true;
+    depthDisabledStencilDesc.StencilReadMask = 0xFF;
+    depthDisabledStencilDesc.StencilWriteMask = 0xFF;
+    depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+    depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+    depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+    depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+    depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+    depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+    depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+    depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+    
+    // Create the state using the device.
+    result = d3d11Device->CreateDepthStencilState( &depthDisabledStencilDesc, &depthDisabledStencilState );
+
+    //-------------------------------------------------
+    // Shaders
+    Text shader;
+    getVertexShader( shader );
+    vertexShader = new VertexShader();
+    vertexShader->setShaderCode( &shader );
+    vertexShader->compile( d3d11Device, "TextureVertexShader", "5_0" );
+
+    getPixelShader( shader );
+    pixelShader = new PixelShader();
+    pixelShader->setShaderCode( &shader );
+    pixelShader->compile( d3d11Device, "TexturePixelShader", "5_0" );
+
+    D3D11_INPUT_ELEMENT_DESC polygonLayout[ 2 ];
+    // Create the vertex input layout description.
+    // This setup needs to match the VertexType stucture in the ModelClass and in the shader.
+    polygonLayout[ 0 ].SemanticName = "POSITION";
+    polygonLayout[ 0 ].SemanticIndex = 0;
+    polygonLayout[ 0 ].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+    polygonLayout[ 0 ].InputSlot = 0;
+    polygonLayout[ 0 ].AlignedByteOffset = 0;
+    polygonLayout[ 0 ].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+    polygonLayout[ 0 ].InstanceDataStepRate = 0;
+
+    polygonLayout[ 1 ].SemanticName = "TEXCOORD";
+    polygonLayout[ 1 ].SemanticIndex = 0;
+    polygonLayout[ 1 ].Format = DXGI_FORMAT_R32G32_FLOAT;
+    polygonLayout[ 1 ].InputSlot = 0;
+    polygonLayout[ 1 ].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
+    polygonLayout[ 1 ].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+    polygonLayout[ 1 ].InstanceDataStepRate = 0;
+
+    vertexShader->erstelleInputLayout( d3d11Device, polygonLayout, 2 );
+    vertexShader->erstelleConstBuffer( d3d11Device, sizeof( Mat4< float > ) * 3, 0 );
+
+    // Create a texture sampler state description.
+    D3D11_SAMPLER_DESC samplerDesc;
+    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
+    samplerDesc.MipLODBias = 0.0f;
+    samplerDesc.MaxAnisotropy = 1;
+    samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
+    samplerDesc.BorderColor[ 0 ] = 0;
+    samplerDesc.BorderColor[ 1 ] = 0;
+    samplerDesc.BorderColor[ 2 ] = 0;
+    samplerDesc.BorderColor[ 3 ] = 0;
+    samplerDesc.MinLOD = 0;
+    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+
+    // Create the texture sampler state.
+    result = d3d11Device->CreateSamplerState( &samplerDesc, &sampleState );
+
+    //---------------------------------------------------------------
+    // Framework Backbuffer Texture
+
+
+    unsigned long indices[ 6 ];
+    Vertex3D vertices[ 6 ];
+
+    // Load the index array with data.
+    for( int i = 0; i < 6; i++ )
+    {
+        indices[ i ] = i;
+    }
+    vertexBuffer = new DXVertexBuffer( sizeof( Vertex3D ) );
+    vertexBuffer->setLänge( sizeof( vertices ) );
+    vertexBuffer->setData( vertices );
+
+    indexBuffer = new DXIndexBuffer( sizeof( int ) );
+    indexBuffer->setLänge( sizeof( int ) * 6 );
+    indexBuffer->setData( indices );
+
+    frameworkTextur = new Textur();
+    frameworkTextur->setBildZ( renderB->getThis() );
+
+    float left, right, top, bottom;
+    // Calculate the screen coordinates of the left side of the bitmap.
+    left = (float)( ( backBufferGröße.x / 2.0 ) * -1 );
+
+    // Calculate the screen coordinates of the right side of the bitmap.
+    right = left + (float)backBufferGröße.x;
+
+    // Calculate the screen coordinates of the top of the bitmap.
+    top = (float)( backBufferGröße.y / 2.0 );
+
+    // Calculate the screen coordinates of the bottom of the bitmap.
+    bottom = top - (float)backBufferGröße.y;
+
+    // Load the vertex array with data.
+    // First triangle.
+    vertices[ 0 ].pos = Vec3< float >( left, top, 0.0f );  // Top left.
+    vertices[ 0 ].tPos = Vec2< float >( 0.0f, 0.0f );
+
+    vertices[ 1 ].pos = Vec3< float >( right, bottom, 0.0f );  // Bottom right.
+    vertices[ 1 ].tPos = Vec2< float >( 1.0f, 1.0f );
+
+    vertices[ 2 ].pos = Vec3< float >( left, bottom, 0.0f );  // Bottom left.
+    vertices[ 2 ].tPos = Vec2< float >( 0.0f, 1.0f );
+
+    // Second triangle.
+    vertices[ 3 ].pos = Vec3< float >( left, top, 0.0f );  // Top left.
+    vertices[ 3 ].tPos = Vec2< float >( 0.0f, 0.0f );
+
+    vertices[ 4 ].pos = Vec3< float >( right, top, 0.0f );  // Top right.
+    vertices[ 4 ].tPos = Vec2< float >( 1.0f, 0.0f );
+
+    vertices[ 5 ].pos = Vec3< float >( right, bottom, 0.0f );  // Bottom right.
+    vertices[ 5 ].tPos = Vec2< float >( 1.0f, 1.0f );
+
+
+    D3D11_BLEND_DESC blendState;
+    ZeroMemory( &blendState, sizeof( D3D11_BLEND_DESC ) );
+    blendState.AlphaToCoverageEnable = false;
+    blendState.IndependentBlendEnable = false;
+    blendState.RenderTarget[ 0 ].BlendEnable = true;
+    blendState.RenderTarget[ 0 ].SrcBlend = D3D11_BLEND_SRC_ALPHA;
+    blendState.RenderTarget[ 0 ].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+    blendState.RenderTarget[ 0 ].BlendOp = D3D11_BLEND_OP_ADD;
+    blendState.RenderTarget[ 0 ].SrcBlendAlpha = D3D11_BLEND_ZERO;
+    blendState.RenderTarget[ 0 ].DestBlendAlpha = D3D11_BLEND_ONE;
+    blendState.RenderTarget[ 0 ].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+    blendState.RenderTarget[ 0 ].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
+
+    d3d11Device->CreateBlendState( &blendState, &blendStateAlphaBlend );
+    d3d11Context->OMSetBlendState( blendStateAlphaBlend, 0, 0xFFFFFFFF );
+
+    // Setup Render Objekt
+    if( renderObj )
+        renderObj->release();
+    renderObj = new Render3D();
+    d3d11Device->AddRef();
+    renderObj->setDevice( d3d11Device );
+    d3d11Context->AddRef();
+    renderObj->setContext( d3d11Context );
+
+    renderObj->benutzeShader( VERTEX, vertexShader->getThis() );
+    d3d11Context->PSSetSamplers( 0, 1, &sampleState );
+    renderObj->benutzeShader( PIXEL, pixelShader->getThis() );
+
+    vertexBuffer->copieren( renderObj );
+    indexBuffer->copieren( renderObj );
+
+    rend = 1;
+    unlock();
+}
+
+void Bildschirm3D::tick( double tickval )
+{
+    lock();
+    __super::tick( tickval );
+    for( auto i = kameras->getArray(); i.set; i++ )
+        rend3D |= i.var->tick( tickval );
+    unlock();
+}
+
+void Bildschirm3D::doMausEreignis( MausEreignis &me ) // sendet maus Ereignis
+{
+    lock();
+    __super::doMausEreignis( me );
+    for( int i = kameras->getEintragAnzahl() - 1; i >= 0; i-- )
+        kameras->z( i )->doMausEreignis( me );
+    unlock();
+}
+
+void Bildschirm3D::doTastaturEreignis( TastaturEreignis &te ) // sendet tastatur Ereignis
+{
+    lock();
+    __super::doTastaturEreignis( te );
+    for( int i = kameras->getEintragAnzahl() - 1; i >= 0; i-- )
+        kameras->z( i )->doTastaturEreignis( te );
+    unlock();
+}
+
+void Bildschirm3D::render() // Zeichnet das Bild
+{
+    if( !rend && !rend3D && testRend )
+        return;
+    rendering = 1;
+    int count = 0;
+    if( renderB && d3d11Device )
+    {
+        lock();
+        renderZeit->messungStart();
+        float color[ 4 ];
+        // Setup the color to clear the buffer to.
+        color[ 0 ] = ( ( füllFarbe >> 16 ) & 0xFF ) / 255.f; // R
+        color[ 1 ] = ( ( füllFarbe >> 8 ) & 0xFF ) / 255.f; // G
+        color[ 2 ] = ( füllFarbe & 0xFF ) / 255.f; // B
+        color[ 3 ] = ( ( füllFarbe >> 24 ) & 0xFF ) / 255.f; // A
+        // Clear the back buffer.
+        if( rend3D || !testRend || rend )
+        {
+            d3d11Context->ClearRenderTargetView( rtview, color );
+            // Clear the depth buffer.
+            d3d11Context->ClearDepthStencilView( dsView, D3D11_CLEAR_DEPTH, 1, 0 );
+            // Bind the render target view and depth stencil buffer to the output render pipeline.
+            d3d11Context->OMSetRenderTargets( 1, &rtview, dsView );
+
+            // Set the depth stencil state.
+            d3d11Context->OMSetDepthStencilState( depthStencilState, 1 );
+
+            for( auto i = kameras->getArray(); i.set; i++ )
+                i.var->render( renderObj );
+        }
+        // Set the depth stencil state.
+        d3d11Context->OMSetDepthStencilState( depthDisabledStencilState, 1 );
+
+        if( rend || !testRend )
+        {
+            if( füll )
+                renderB->setFarbe( füllFarbe );
+            if( renderZeichnungen )
+            {
+                if( renderOnTop && deckFarbe && ( deckFarbe & ( füllFarbe | 0xFF000000 ) ) == deckFarbe )
+                {
+                    renderB->setAlpha( 255 - (unsigned char)( deckFarbe >> 24 ) );
+                    members->render( *renderB ); // zeichnen nach zwischenbuffer
+                    renderB->releaseAlpha();
+                }
+                else
+                {
+                    members->render( *renderB ); // zeichnen nach zwischenbuffer
+                    if( renderOnTop && deckFarbe )
+                        renderB->alphaRegion( 0, 0, renderB->getBreite(), renderB->getHöhe(), deckFarbe );
+                }
+                for( int i = 0; i < tipAnzahl; ++i )
+                    tips->z( i )->render( *renderB );
+            }
+            if( renderOnTop && onTop )
+                onTop->render( *renderB );
+        }
+        unlock();
+        // Beginne Bild 
+        HRESULT result;
+
+        if( rend || !testRend )
+            frameworkTextur->updateTextur( renderObj );
+
+        d3d11Context->RSSetViewports( 1, vp );
+
+        Mat4< float > welt = welt.identity();
+        float screenAspect = (float)backBufferGröße.x / (float)backBufferGröße.y;
+        renderObj->setKameraMatrix( welt.translation( Vec3< float >( 0.f, 0.f, backBufferGröße.y * 1.2075f ) ), welt.projektion( DirectX::XM_PI / 4.0f, screenAspect, 0.1f, 10000.f ), Vec3< float >( 0.f, 0.f, backBufferGröße.y * 1.2075f ) );
+        renderObj->beginnModel( welt, vertexBuffer, -1 );
+        renderObj->draw( indexBuffer, frameworkTextur );
+
+        result = d3d11SpawChain->Present( 0, 0 );
+        renderZeit->messungEnde();
+#ifdef _DEBUG
+        std::cout << renderZeit->getSekunden() << "\n";
+#endif
+        if( result != S_OK )
+        {
+            ++count;
+            update();
+        }
+        else if( count )
+            --count;
+    }
+    if( !d3d11Device )
+    {
+        ++count;
+        update();
+    }
+    if( count > 10 )
+    {
+        WMessageBox( fenster ? fenster->getFensterHandle() : 0, new Text( "Fehler" ), new Text( "Es ist ein Fehler beim rendern aufgetreten." ), MB_ICONERROR );
+        count = 0;
+    }
+    rendering = 0;
+    rend = 0;
+}
+
+// Reference Counting 
+Bildschirm *Bildschirm3D::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 188 - 0
Bildschirm.h

@@ -0,0 +1,188 @@
+#ifndef Bildschirm_H
+#define Bildschirm_H
+
+#include "Array.h"
+#include "Punkt.h"
+
+// DirectX 11 Types
+
+struct ID3D11Device;
+struct ID3D11DeviceContext;
+struct IDXGISwapChain;
+struct ID3D11Texture2D;
+struct ID3D11SamplerState;
+struct ID3D11ShaderResourceView;
+struct ID3D11RenderTargetView;
+struct ID3D11DepthStencilView;
+struct ID3D11DepthStencilState;
+struct ID3D11RasterizerState;
+struct ID3D11BlendState;
+struct D3D11_VIEWPORT;
+
+// DirectX 9 Types
+
+struct IDirect3D9;
+struct IDirect3DDevice9;
+struct IDirect3DSurface9;
+struct _D3DLOCKED_RECT;
+
+namespace Framework
+{
+    class Bild; // Bild.h
+    class WFenster; // Fenster.h
+    class Bildschirm; // aus dieser Datei
+    class ZeichnungArray; // Zeichnung.h
+    class Zeichnung3DArray; // Zeichnung3D.h
+    class Zeichnung; // Zeichnung.h
+    class Zeichnung3D; // Zeichnung3D.h
+    class ZeitMesser; // Zeit.h
+    struct MausEreignis; // MausEreignis.h
+    struct TastaturEreignis; // TastaturEreignis.h
+    class ToolTip; // Tooltip.h
+    class PixelShader; // Shader.h
+    class VertexShader; // Shader.h
+    class Kam3D; // Kam3D.h
+    class Render3D; // Render3D.h
+    class DXVertexBuffer; // DXBuffer.h
+    class DXIndexBuffer; // DXBuffer.h
+    class Textur; // Textur.h
+
+    struct Monitor
+    {
+        int x, y, breite, höhe;
+        bool existiert;
+    };
+
+    //Diese Klasse wird das Bild auf dem Bildschirm verwalten
+    class Bildschirm
+    {
+    protected:
+        WFenster *fenster;
+        Bild *renderB;
+        int ref;
+        ZeichnungArray *members;
+        int füllFarbe;
+        int deckFarbe;
+        Zeichnung *onTop;
+        bool renderOnTop;
+        bool renderZeichnungen;
+        bool vollbild;
+        bool rendering;
+        ZeitMesser *renderZeit;
+        Punkt backBufferGröße;
+        CRITICAL_SECTION cs;
+        RCArray< ToolTip > *tips;
+        int tipAnzahl;
+        bool testRend;
+        bool füll;
+        bool rend;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) Bildschirm( WFenster *fenster );
+        // Destruktor 
+        __declspec( dllexport ) ~Bildschirm();
+        // nicht constant 
+        __declspec( dllexport ) virtual void lock();
+        __declspec( dllexport ) virtual void unlock();
+        __declspec( dllexport ) virtual void setFüll( bool f );
+        __declspec( dllexport ) virtual void update() = 0; // aktualisiert directX
+        __declspec( dllexport ) virtual void setTestRend( bool tr ); // legt fest, ob vo rendern auf updates geprüft werden soll
+        __declspec( dllexport ) virtual void setRenderZeichnungen( bool rO ); // legt fest, ob die Zeichnunge gerendert werden
+        __declspec( dllexport ) virtual void setOnTop( bool onTop ); // legt fest, ob das onTop Zeichnung gerendert wid
+        __declspec( dllexport ) virtual void setOnTopZeichnung( Zeichnung *obj ); // setzt das OnTop Zeichnung
+        __declspec( dllexport ) virtual void setdeckFarbe( int f ); // setzt die deckFarbe
+        __declspec( dllexport ) virtual void addMember( Zeichnung *obj ); // Fügt ein Zeichnung hinzu
+        __declspec( dllexport ) virtual void removeMember( Zeichnung *obj ); // Entfernt ein Zeichnung
+        __declspec( dllexport ) virtual void render() = 0; // Zeichnet das Bild
+        __declspec( dllexport ) virtual void setFüllFarbe( int f ); // setzt die Fill Farbe
+        __declspec( dllexport ) virtual void setVollbild( bool fullscreen ); // setzt vollbild
+        __declspec( dllexport ) virtual void tick( double tickval );
+        __declspec( dllexport ) virtual void setBackBufferGröße( int breite, int höhe ); // setzt die Größe des Backbuffers
+        __declspec( dllexport ) virtual void setBackBufferGröße( Punkt &größe );
+        __declspec( dllexport ) virtual void doMausEreignis( MausEreignis &me ); // sendet maus Ereignis
+        __declspec( dllexport ) virtual void doTastaturEreignis( TastaturEreignis &te ); // sendet tastatur Ereignis
+        __declspec( dllexport ) virtual void addToolTip( ToolTip *tip ); // fügt ToolTip hinzu
+        __declspec( dllexport ) virtual bool removeToolTip( ToolTip *zTip ); // entfernt ToolTip
+        // constant 
+        __declspec( dllexport ) virtual Bild *getRenderBild() const; // Gibt das RendezRObj zurück
+        __declspec( dllexport ) virtual Bild *zRenderBild() const;
+        __declspec( dllexport ) virtual ZeichnungArray *getMembers() const; // gibt die Zeichnunge zurück
+        __declspec( dllexport ) virtual int getFüllFarbe() const; // gibt die Füll Farbe zurück
+        __declspec( dllexport ) virtual bool istVolbild() const; // gibt zurück, ob vollbild an ist
+        __declspec( dllexport ) virtual const Punkt &getBackBufferGröße() const; // gibt die Größe des Backbuffers zurück
+        __declspec( dllexport ) virtual void warteAufRendern() const; // wartet auf die render Funktion
+        __declspec( dllexport ) virtual double getRenderZeit() const; // gibt zurück wie viele Sekunden das Rendern dauert
+        // Reference Counting 
+        __declspec( dllexport ) virtual Bildschirm *getThis();
+        __declspec( dllexport ) virtual Bildschirm *release();
+    };
+
+    class Bildschirm2D : public Bildschirm
+    {
+    private:
+        IDirect3D9			*pDirect3D;
+        IDirect3DDevice9	*pDevice;
+        IDirect3DSurface9	*pBackBuffer;
+        _D3DLOCKED_RECT		*backRect;
+
+        void cleanUpDirectX();
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) Bildschirm2D( WFenster *fenster );
+        // Destruktor 
+        __declspec( dllexport ) ~Bildschirm2D();
+        // nicht constant 
+        __declspec( dllexport ) virtual void update(); // aktualisiert directX
+        __declspec( dllexport ) virtual void render(); // Zeichnet das Bild
+        // Reference Counting 
+        __declspec( dllexport ) virtual Bildschirm *release();
+    };
+
+    class Bildschirm3D : public Bildschirm
+    {
+    private:
+        ID3D11Device *d3d11Device;
+        ID3D11DeviceContext *d3d11Context;
+        IDXGISwapChain *d3d11SpawChain;
+        DXVertexBuffer *vertexBuffer;
+        DXIndexBuffer *indexBuffer;
+        Textur *frameworkTextur;
+        ID3D11SamplerState* sampleState;
+        ID3D11RenderTargetView *rtview;
+        ID3D11DepthStencilView *dsView;
+        ID3D11Texture2D *depthStencilBuffer;
+        ID3D11DepthStencilState *depthStencilState;
+        ID3D11DepthStencilState *depthDisabledStencilState;
+        ID3D11BlendState *blendStateAlphaBlend;
+        RCArray< Kam3D > *kameras;
+        PixelShader *pixelShader;
+        VertexShader *vertexShader;
+        Render3D *renderObj;
+        D3D11_VIEWPORT *vp;
+        bool rend3D;
+
+        void cleanUpDirectX();
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) Bildschirm3D( WFenster *fenster );
+        // Destruktor 
+        __declspec( dllexport ) ~Bildschirm3D();
+        // nicht constant 
+        __declspec( dllexport ) void addKamera( Kam3D *obj ); // Fügt eine Kamera hinzu
+        __declspec( dllexport ) void removeKamera( Kam3D *zObj ); // Entfernt eine Kamera
+        __declspec( dllexport ) void tick( double tickval );
+        __declspec( dllexport ) void doMausEreignis( MausEreignis &me ); // sendet maus Ereignis
+        __declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ); // sendet tastatur Ereignis
+        __declspec( dllexport ) void update(); // aktualisiert directX
+        __declspec( dllexport ) void render(); // Zeichnet das Bild
+        // Reference Counting  
+        __declspec( dllexport ) Bildschirm *release();
+    };
+
+    __declspec( dllexport ) Monitor getMonitor( int id );
+}
+
+#endif

+ 270 - 0
Cube.cpp

@@ -0,0 +1,270 @@
+#include "Cube.h"
+#include "DXBuffer.h"
+#include "Textur.h"
+#include "Globals.h"
+#include "Model3DList.h"
+#include "TexturList.h"
+
+using namespace Framework;
+
+// Inhalt der Cube Klasse
+
+// Konstruktor
+//  size: Die Größe des Würfels
+Cube::Cube( float size )
+    : Model3D()
+{
+    for( int i = 0; i < 6; i++ )
+        texturUpdate[ i ] = 0;
+
+    if( m3dRegister->hatModel( Standart3DTypes::würfel ) )
+        model = m3dRegister->getModel( Standart3DTypes::würfel );
+    else
+    {
+        model = new Model3DData();
+        m3dRegister->addModel( model->getThis(), Standart3DTypes::würfel );
+        float stdSize = 100;
+        float left, right, top, bottom;
+        // Calculate the screen coordinates of the left side of the bitmap.
+        left = (float)( ( stdSize / 2.0 ) * -1 );
+        // Calculate the screen coordinates of the right side of the bitmap.
+        right = left + (float)stdSize;
+        // Calculate the screen coordinates of the top of the bitmap.
+        top = (float)( stdSize / 2.0 );
+        // Calculate the screen coordinates of the bottom of the bitmap.
+        bottom = top - (float)stdSize;
+        float front = -stdSize / 2;
+        float back = front + stdSize;
+
+        Vertex3D *vertecies = new Vertex3D[ 24 ];
+        vertecies[ 0 ].pos = Vec3<float >( left, top, front );
+        vertecies[ 0 ].tPos = Vec2< float >( 0.f, 0.f );
+        vertecies[ 1 ].pos = Vec3<float >( right, top, front );
+        vertecies[ 1 ].tPos = Vec2< float >( 1.f, 0.f );
+        vertecies[ 2 ].pos = Vec3<float >( left, bottom, front );
+        vertecies[ 2 ].tPos = Vec2< float >( 0.f, 1.f );
+        vertecies[ 3 ].pos = Vec3<float >( right, bottom, front );
+        vertecies[ 3 ].tPos = Vec2< float >( 1.f, 1.f );
+        vertecies[ 4 ].pos = Vec3<float >( left, top, back );
+        vertecies[ 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
+        vertecies[ 5 ].pos = Vec3<float >( right, top, back );
+        vertecies[ 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
+        vertecies[ 6 ].pos = Vec3<float >( left, bottom, back );
+        vertecies[ 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
+        vertecies[ 7 ].pos = Vec3<float >( right, bottom, back );
+        vertecies[ 7 ].tPos = Vec2< float >( 1.0f, 1.0f );
+
+        vertecies[ 8 ].pos = Vec3<float >( left, top, front );
+        vertecies[ 8 ].tPos = Vec2< float >( 1.f, 0.f );
+        vertecies[ 9 ].pos = Vec3<float >( right, top, front );
+        vertecies[ 9 ].tPos = Vec2< float >( 0.f, 0.f );
+        vertecies[ 10 ].pos = Vec3<float >( left, bottom, front );
+        vertecies[ 10 ].tPos = Vec2< float >( 1.f, 1.f );
+        vertecies[ 11 ].pos = Vec3<float >( right, bottom, front );
+        vertecies[ 11 ].tPos = Vec2< float >( 0.f, 1.f );
+        vertecies[ 12 ].pos = Vec3<float >( left, top, back );
+        vertecies[ 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
+        vertecies[ 13 ].pos = Vec3<float >( right, top, back );
+        vertecies[ 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
+        vertecies[ 14 ].pos = Vec3<float >( left, bottom, back );
+        vertecies[ 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
+        vertecies[ 15 ].pos = Vec3<float >( right, bottom, back );
+        vertecies[ 15 ].tPos = Vec2< float >( 1.0f, 1.0f );
+
+        vertecies[ 16 ].pos = Vec3<float >( left, top, front );
+        vertecies[ 16 ].tPos = Vec2< float >( 0.f, 1.f );
+        vertecies[ 17 ].pos = Vec3<float >( right, top, front );
+        vertecies[ 17 ].tPos = Vec2< float >( 1.f, 1.f );
+        vertecies[ 18 ].pos = Vec3<float >( left, bottom, front );
+        vertecies[ 18 ].tPos = Vec2< float >( 0.f, 0.f );
+        vertecies[ 19 ].pos = Vec3<float >( right, bottom, front );
+        vertecies[ 19 ].tPos = Vec2< float >( 1.f, 0.f );
+        vertecies[ 20 ].pos = Vec3<float >( left, top, back );
+        vertecies[ 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
+        vertecies[ 21 ].pos = Vec3<float >( right, top, back );
+        vertecies[ 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
+        vertecies[ 22 ].pos = Vec3<float >( left, bottom, back );
+        vertecies[ 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
+        vertecies[ 23 ].pos = Vec3<float >( right, bottom, back );
+        vertecies[ 23 ].tPos = Vec2< float >( 1.0f, 1.0f );
+
+        model->setVertecies( vertecies, 24 );
+
+        // front side
+        Polygon3D *p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 0;
+        p->indexList[ 1 ] = 3;
+        p->indexList[ 2 ] = 2;
+        p->indexList[ 3 ] = 0;
+        p->indexList[ 4 ] = 1;
+        p->indexList[ 5 ] = 3;
+        model->addPolygon( p );
+        // back side
+        p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 4;
+        p->indexList[ 1 ] = 6;
+        p->indexList[ 2 ] = 7;
+        p->indexList[ 3 ] = 4;
+        p->indexList[ 4 ] = 7;
+        p->indexList[ 5 ] = 5;
+        model->addPolygon( p );
+        // right side
+        p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 1 + 8;
+        p->indexList[ 1 ] = 7 + 8;
+        p->indexList[ 2 ] = 3 + 8;
+        p->indexList[ 3 ] = 1 + 8;
+        p->indexList[ 4 ] = 5 + 8;
+        p->indexList[ 5 ] = 7 + 8;
+        model->addPolygon( p );
+        // left side
+        p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 0 + 8;
+        p->indexList[ 1 ] = 2 + 8;
+        p->indexList[ 2 ] = 6 + 8;
+        p->indexList[ 3 ] = 0 + 8;
+        p->indexList[ 4 ] = 6 + 8;
+        p->indexList[ 5 ] = 4 + 8;
+        model->addPolygon( p );
+        // top side
+        p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 4 + 16;
+        p->indexList[ 1 ] = 1 + 16;
+        p->indexList[ 2 ] = 0 + 16;
+        p->indexList[ 3 ] = 4 + 16;
+        p->indexList[ 4 ] = 5 + 16;
+        p->indexList[ 5 ] = 1 + 16;
+        model->addPolygon( p );
+        // down side
+        p = new Polygon3D();
+        p->indexAnz = 6;
+        p->indexList = new int[ p->indexAnz ];
+        p->indexBuffer->setLänge( p->indexAnz * 4 );
+        p->indexBuffer->setData( p->indexList );
+        p->indexList[ 0 ] = 6 + 16;
+        p->indexList[ 1 ] = 2 + 16;
+        p->indexList[ 2 ] = 3 + 16;
+        p->indexList[ 3 ] = 6 + 16;
+        p->indexList[ 4 ] = 3 + 16;
+        p->indexList[ 5 ] = 7 + 16;
+        model->addPolygon( p );
+    }
+
+    textur = new Model3DTextur();
+}
+
+// Destruktor
+Cube::~Cube()
+{
+}
+
+// Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
+//  textur: Die Textur als Bild
+void Cube::setTextur( Bild *textur )
+{
+    Textur *t = new Textur();
+    t->setBildZ( textur );
+    this->textur->setPolygonTextur( LINKS, t->getThis() );
+    this->textur->setPolygonTextur( OBEN, t->getThis() );
+    this->textur->setPolygonTextur( RECHTS, t->getThis() );
+    this->textur->setPolygonTextur( UNTEN, t->getThis() );
+    this->textur->setPolygonTextur( VORNE, t->getThis() );
+    this->textur->setPolygonTextur( HINTEN, t );
+    for( int i = 0; i < 6; i++ )
+        texturUpdate[ i ] = 1;
+    rend = 1;
+}
+
+// Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
+//  id: Die id der Textur. Sie muss im Textur Register des Frameworks registriert sein
+void Cube::setTextur( int id )
+{
+    Textur *t = texturRegister->getTextur( id );
+    if( !t )
+        return;
+    this->textur->setPolygonTextur( LINKS, t->getThis() );
+    this->textur->setPolygonTextur( OBEN, t->getThis() );
+    this->textur->setPolygonTextur( RECHTS, t->getThis() );
+    this->textur->setPolygonTextur( UNTEN, t->getThis() );
+    this->textur->setPolygonTextur( VORNE, t->getThis() );
+    this->textur->setPolygonTextur( HINTEN, t );
+    for( int i = 0; i < 6; i++ )
+        texturUpdate[ i ] = 1;
+    rend = 1;
+}
+
+// Setzt die Textur von einer bestimmten Seite des Würfels
+//  textur: Die Textur als Bild
+//  s: Die Seite, die gesetzt werden soll
+void Cube::setTextur( Bild *textur, CubeSeite s )
+{
+    Textur *t = new Textur();
+    t->setBildZ( textur );
+    this->textur->setPolygonTextur( s, t );
+    texturUpdate[ s ] = 1;
+    rend = 1;
+}
+
+// Setzt die Textur von einer bestimmten Seite des Würfels
+//  id: Die id der Textur. Sie muss im Textur Register des Frameworks registriert sein
+//  s: Die Seite, die gesetzt werden soll
+void Cube::setTextur( int id, CubeSeite s )
+{
+    Textur *t = texturRegister->getTextur( id );
+    if( !t )
+        return;
+    this->textur->setPolygonTextur( s, t );
+    texturUpdate[ s ] = 1;
+    rend = 1;
+}
+
+// Zeichnet den Würfel
+//  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+void Cube::render( Render3D *zRObj )
+{
+    Array< Textur* > tmp;
+    for( int i = 0; i < 6; i++ )
+    {
+        if( texturUpdate[ i ] )
+        {
+            Textur *t = textur->zPolygonTextur( i );
+            if( tmp.getWertIndex( t ) < 0 )
+            {
+                //t->updateTextur( zRObj );
+                tmp.add( t );
+            }
+            texturUpdate[ i ] = 0;
+        }
+    }
+    __super::render( zRObj );
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Model3D *Cube::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 52 - 0
Cube.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include "Model3D.h"
+
+namespace Framework
+{
+    class Bild;
+
+    enum CubeSeite
+    {
+        VORNE, 
+        HINTEN, 
+        RECHTS, 
+        LINKS, 
+        OBEN, 
+        UNTEN
+    };
+
+    // Ein Model eines Würfels
+    class Cube : public Model3D
+    {
+    private:
+        bool texturUpdate[ 6 ];
+
+    public:
+        // Konstruktor
+        //  size: Die Größe des Würfels
+        __declspec( dllexport ) Cube( float size );
+        // Destruktor
+        __declspec( dllexport ) ~Cube();
+        // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
+        //  textur: Die Textur als Bild
+        __declspec( dllexport ) void setTextur( Bild *textur );
+        // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
+        //  id: Die id der Textur. Sie muss im Textur Register des Frameworks registriert sein
+        __declspec( dllexport ) void setTextur( int id );
+        // Setzt die Textur von einer bestimmten Seite des Würfels
+        //  textur: Die Textur als Bild
+        //  s: Die Seite, die gesetzt werden soll
+        __declspec( dllexport ) void setTextur( Bild *textur, CubeSeite s );
+        // Setzt die Textur von einer bestimmten Seite des Würfels
+        //  id: Die id der Textur. Sie muss im Textur Register des Frameworks registriert sein
+        //  s: Die Seite, die gesetzt werden soll
+        __declspec( dllexport ) void setTextur( int id, CubeSeite s );
+        // Zeichnet den Würfel
+        //  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+        __declspec( dllexport ) void render( Render3D *zRObj ) override;
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Model3D *release() override;
+    };
+}

+ 166 - 0
DXBuffer.cpp

@@ -0,0 +1,166 @@
+#include "DXBuffer.h"
+#include "Render3D.h"
+#include <iostream>
+#include <d3d11.h>
+
+using namespace Framework;
+
+// Inhalt der DXBuffer Klasse
+
+// Konstruktor
+//  bind: Der verwendungszweck des Buffers. Beispiel: D3D11_BIND_INDEX_BUFFER, D3D11_BIND_VERTEX_BUFFER.
+//  eLän: Länge eines einzelnen Elements in Bytes
+DXBuffer::DXBuffer( D3D11_BIND_FLAG bind, int eLän )
+{
+    buffer = 0;
+    bf = bind;
+    data = 0;
+    geändert = 0;
+    län = 0;
+    altLän = 0;
+    elLän = eLän;
+    ref = 1;
+}
+
+// Destruktor
+DXBuffer::~DXBuffer()
+{
+    if( buffer )
+        buffer->Release();
+}
+
+// Setzt den geändert fläg, so das beim nächsten auruf von 'kopieren' die daten neu kopiert werden
+void DXBuffer::setGeändert()
+{
+    geändert = 1;
+}
+
+// Ändert die länge des Buffers beim nächsten aufruf von 'kopieren'
+//  län: Die Länge in Bytes
+void DXBuffer::setLänge( int län )
+{
+    this->län = län;
+    geändert = 1;
+}
+
+// Legt fest, was beim nächsten aufruf von 'kopieren' kopiert wird
+//  data: Ein zeiger auf die Daten
+void DXBuffer::setData( void *data )
+{
+    this->data = data;
+    geändert = 1;
+}
+
+// Kopiert die Daten in den Buffer, fals sie sich verändert haben
+//  zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird
+void DXBuffer::copieren( Render3D *zRObj )
+{
+    if( !geändert || !län || !data )
+        return;
+    if( län != altLän )
+    {
+        if( buffer )
+            buffer->Release();
+        buffer = 0;
+    }
+    if( !buffer )
+    {
+        D3D11_BUFFER_DESC desk;
+        memset( &desk, 0, sizeof( desk ) );
+        desk.Usage = D3D11_USAGE_DYNAMIC;
+        desk.ByteWidth = län;
+        desk.BindFlags = bf;
+        desk.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+
+        D3D11_SUBRESOURCE_DATA ini;
+        memset( &ini, 0, sizeof( ini ) );
+        ini.pSysMem = data;
+
+        zRObj->zDevice()->CreateBuffer( &desk, &ini, &buffer );
+        altLän = län;
+    }
+    else if( geändert )
+    {
+        D3D11_MAPPED_SUBRESOURCE map;
+        zRObj->zContext()->Map( buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map );
+        memcpy( map.pData, data, län );
+        zRObj->zContext()->Unmap( buffer, 0 );
+        geändert = 0;
+    }
+}
+
+// Gibt die Länge eines Elementes in bytes zurück
+int DXBuffer::getElementLänge() const
+{
+    return elLän;
+}
+
+// Gibt den Buffer zurück
+ID3D11Buffer *DXBuffer::zBuffer() const
+{
+    return buffer;
+}
+
+// Gibt die Anzahl der Elemente im Buffer zurück
+int DXBuffer::getElementAnzahl() const
+{
+    return altLän / elLän;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+DXBuffer *DXBuffer::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+DXBuffer *DXBuffer::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der DXVertexBuffer Klasse
+
+// Konstruktor
+// eSize: Die Länge eines Elementes in Bytes
+DXVertexBuffer::DXVertexBuffer( int eSize )
+    : DXBuffer( D3D11_BIND_VERTEX_BUFFER, eSize )
+{
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+DXBuffer *DXVertexBuffer::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der DXIndexBuffer Klasse
+
+// Konstruktor
+// eSize: Die Länge eines Elementes in Bytes
+DXIndexBuffer::DXIndexBuffer( int eSize )
+    : DXBuffer( D3D11_BIND_INDEX_BUFFER, eSize )
+{
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+DXBuffer *DXIndexBuffer::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 79 - 0
DXBuffer.h

@@ -0,0 +1,79 @@
+#pragma once
+
+#include "Betriebssystem.h"
+
+struct ID3D11Buffer;
+enum D3D11_BIND_FLAG;
+
+namespace Framework
+{
+    class Render3D;
+
+    class DXBuffer
+    {
+    private:
+        ID3D11Buffer *buffer;
+        D3D11_BIND_FLAG bf;
+        void *data;
+        bool geändert;
+        int län;
+        int altLän;
+        int elLän;
+
+    protected:
+        int ref;
+
+    public:
+        // Konstruktor
+        //  bind: Der verwendungszweck des Buffers. Beispiel: D3D11_BIND_INDEX_BUFFER, D3D11_BIND_VERTEX_BUFFER.
+        //  eLän: Länge eines einzelnen Elements in Bytes
+        __declspec( dllexport ) DXBuffer( D3D11_BIND_FLAG bind, int eLän );
+        // Destruktor
+        __declspec( dllexport ) ~DXBuffer();
+        // Setzt den geändert fläg, so das beim nächsten auruf von 'kopieren' die daten neu kopiert werden
+        __declspec( dllexport ) void setGeändert();
+        // Ändert die länge des Buffers beim nächsten aufruf von 'kopieren'
+        //  län: Die Länge in Bytes
+        __declspec( dllexport ) void setLänge( int län );
+        // Legt fest, was beim nächsten aufruf von 'kopieren' kopiert wird
+        //  data: Ein zeiger auf die Daten
+        __declspec( dllexport ) void setData( void *data );
+        // Kopiert die Daten in den Buffer, fals sie sich verändert haben
+        //  zRObj: Das Objekt, mit dem die Grafikkarte angesprochen wird
+        __declspec( dllexport ) void copieren( Render3D *zRObj );
+        // Gibt die Länge eines Elementes in bytes zurück
+        __declspec( dllexport ) int getElementLänge() const;
+        // Gibt den Buffer zurück
+        __declspec( dllexport ) ID3D11Buffer *zBuffer() const;
+        // Gibt die Anzahl der Elemente im Buffer zurück
+        __declspec( dllexport ) int getElementAnzahl() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) DXBuffer *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) virtual DXBuffer *release();
+    };
+
+    class DXVertexBuffer : public DXBuffer
+    {
+    public:
+        // Konstruktor
+        // eSize: Die Länge eines Elementes in Bytes
+        __declspec( dllexport ) DXVertexBuffer( int eSize );
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) virtual DXBuffer *release();
+    };
+
+    class DXIndexBuffer : public DXBuffer
+    {
+    public:
+        // Konstruktor
+        // eSize: Die Länge eines Elementes in Bytes
+        __declspec( dllexport ) DXIndexBuffer( int eSize );
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) virtual DXBuffer *release();
+    };
+}

+ 806 - 0
Datei.cpp

@@ -0,0 +1,806 @@
+#include "Datei.h"
+#include "Text.h"
+#include "Zeit.h"
+#ifdef WIN32
+#include <direct.h>
+#include <Shlwapi.h>
+#pragma comment(lib, "Shlwapi.lib")
+#else
+#include <dirent.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#endif
+
+using namespace Framework;
+
+// Inhalt der Datei Klasse aus Datei.h
+// Konstruktor 
+Datei::Datei()
+    : ref( 1 ),
+    stream( 0 ),
+    pfad( 0 ),
+    gr( 0 ),
+    tmpLByte( 0 ),
+    tmpLBPos( 7 ),
+    tmpSByte( 0 ),
+    tmpSBPos( -1 )
+{}
+
+// Destruktor 
+Datei::~Datei()
+{
+    if( stream )
+        delete stream;
+    if( pfad )
+        pfad->release();
+}
+
+// nicht constant 
+void Datei::setDatei( const char *pfad ) // setzt die Datei
+{
+    if( istOffen() )
+        schließen();
+    if( !this->pfad )
+        this->pfad = new Text();
+    this->pfad->setText( pfad );
+    gr = 0;
+}
+
+void Datei::setDatei( Text *pfad )
+{
+    if( istOffen() )
+        schließen();
+    if( !this->pfad )
+        this->pfad = new Text();
+    this->pfad->setText( pfad );
+    gr = 0;
+}
+
+bool Datei::umbenennen( const char *pfad ) // benennt die Datei um und verschiebt sie eventuell
+{
+    if( !pfad )
+        return 0;
+    if( DateiUmbenennen( this->pfad->getText(), pfad ) )
+    {
+        this->pfad->setText( pfad );
+        return 1;
+    }
+    return 0;
+}
+
+bool Datei::umbenennen( Text *pfad )
+{
+    if( !this->pfad )
+    {
+        pfad->release();
+        return 0;
+    }
+    if( DateiUmbenennen( this->pfad->getText(), pfad->getText() ) )
+    {
+        this->pfad->setText( pfad );
+        return 1;
+    }
+    pfad->release();
+    return 0;
+}
+
+bool Datei::löschen() // löscht die Datei
+{
+    if( !pfad )
+        return 0;
+    return DateiLöschen( pfad->getThis() );
+}
+
+bool Datei::erstellen() // erstellt die Datei
+{
+    if( !pfad )
+        return 0;
+    return DateiPfadErstellen( pfad->getThis() );
+}
+
+bool Datei::öffnen( int style ) // öffnet die Datei
+{
+    if( !pfad )
+        return 0;
+    if( stream )
+        delete stream;
+    stream = new std::fstream();
+    std::ios_base::openmode om = std::ios::binary;
+    if( ( style | Style::lesen ) == style )
+        om |= std::ios::in;
+    if( ( style | Style::schreiben ) == style )
+        om |= std::ios::out;
+    stream->open( pfad->getText(), om );
+    if( ( style | Style::ende ) == style )
+    {
+        if( ( style | Style::lesen ) == style )
+            stream->seekg( 0, std::ios::end );
+        if( ( style | Style::schreiben ) == style )
+            stream->seekp( 0, std::ios::end );
+    }
+    if( !stream->is_open() || !stream->good() )
+    {
+        delete stream;
+        stream = 0;
+        return 0;
+    }
+    tmpLBPos = 7;
+    tmpSBPos = -1;
+    return 1;
+}
+
+void Datei::setLPosition( __int64 pos, bool ende ) // setzt die Leseposition
+{
+    if( !pfad )
+        return;
+    if( stream )
+    {
+        if( ende )
+            stream->seekg( pos, std::ios::end );
+        else
+            stream->seekg( pos, std::ios::beg );
+    }
+    tmpLBPos = 7;
+}
+
+void Datei::setSPosition( __int64 pos, bool ende ) // setzt die Schreibeposition
+{
+    if( !pfad )
+        return;
+    if( stream )
+    {
+        if( ende )
+            stream->seekp( pos, std::ios::end );
+        else
+            stream->seekp( pos, std::ios::beg );
+    }
+    tmpSBPos = -1;
+}
+
+void Datei::schreibe( char *bytes, int län ) // schreibt bytes in datei
+{
+    if( !pfad || !stream )
+        return;
+    if( tmpSBPos >= 0 )
+    {
+        tmpSBPos = -1;
+        stream->write( &tmpSByte, 1 );
+        tmpSByte = 0;
+    }
+    stream->write( bytes, län );
+}
+
+void Datei::lese( char *bytes, int län ) // ließt bytes aus datei
+{
+    if( !pfad )
+        return;
+    if( stream )
+        stream->read( bytes, län );
+    tmpLBPos = 7;
+    tmpSBPos = -1;
+}
+
+Text *Datei::leseZeile() // ließt eine zeile
+{
+    if( !pfad | !stream )
+        return 0;
+    if( istEnde() )
+        return 0;
+    Text *ret = new Text( "" );
+    __int64 län = getGröße();
+    for( char c = 0; c != '\n' && stream->tellg() < län; )
+    {
+        stream->read( &c, 1 );
+        if( c )
+            ret->anhängen( (const char*)&c, 1 );
+    }
+    tmpSBPos = 7;
+    tmpSBPos = -1;
+    return ret;
+}
+
+void Datei::schließen() // schließt die Datei
+{
+    if( !pfad || !stream )
+        return;
+    if( tmpSBPos >= 0 )
+        stream->write( &tmpSByte, 1 );
+    stream->close();
+    delete stream;
+    stream = 0;
+}
+
+#ifdef WIN32
+bool Datei::setLetzteÄnderung( Zeit *zeit ) // setzt das änderungsdatum der Datei
+{
+    if( !pfad )
+    {
+        zeit->release();
+        return 0;
+    }
+    HANDLE hFile = CreateFile( pfad->getText(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
+    if( hFile == INVALID_HANDLE_VALUE )
+    {
+        zeit->release();
+        return 0;
+    }
+    FILETIME ftCreate, ftAccess, ftWrite;
+    if( !GetFileTime( hFile, &ftCreate, &ftAccess, &ftWrite ) )
+    {
+        CloseHandle( hFile );
+        zeit->release();
+        return 0;
+    }
+    SYSTEMTIME stUTC, stLocal;
+    stLocal.wMilliseconds = 0;
+    stLocal.wSecond = zeit->zUhrzeit()->getSekunde();
+    stLocal.wMinute = zeit->zUhrzeit()->getMinute();
+    stLocal.wHour = zeit->zUhrzeit()->getStunde();
+    stLocal.wDay = zeit->zDatum()->getTag();
+    stLocal.wMonth = zeit->zDatum()->getMonat();
+    stLocal.wYear = zeit->zDatum()->getJahr();
+    zeit->release();
+    if( !TzSpecificLocalTimeToSystemTime( NULL, &stLocal, &stUTC ) )
+    {
+        CloseHandle( hFile );
+        return 0;
+    }
+    if( !SystemTimeToFileTime( &stUTC, &ftWrite ) )
+    {
+        CloseHandle( hFile );
+        return 0;
+    }
+    if( !SetFileTime( hFile, &ftCreate, &ftAccess, &ftWrite ) )
+    {
+        CloseHandle( hFile );
+        return 0;
+    }
+    CloseHandle( hFile );
+    return 1;
+}
+#endif
+
+bool Datei::getNextBit( bool &bit ) // Datei Bitweise auslesen
+{
+    if( !pfad || !stream )
+        return 0;
+    if( tmpLBPos == 7 )
+    {
+        tmpLBPos = -1;
+        stream->read( &tmpLByte, 1 );
+    }
+    tmpLBPos++;
+    bit = ( tmpLByte >> ( 7 - tmpLBPos ) ) & 1;
+    return 1;
+}
+
+bool Datei::setNextBit( bool bit ) // Datei Bitweise speichern
+{
+    if( !pfad || !stream )
+        return 0;
+    tmpSBPos++;
+    tmpSByte |= ( (char)bit << ( 7 - tmpSBPos ) ) & ( 1 << ( 7 - tmpSBPos ) );
+    if( tmpSBPos == 7 )
+    {
+        tmpSBPos = -1;
+        stream->write( &tmpSByte, 1 );
+        tmpSByte = 0;
+    }
+    return 1;
+}
+
+// constant 
+bool Datei::istOrdner() const // prüft, ob die Datei ein Ordner ist
+{
+    if( !pfad )
+        return 0;
+    return DateiIstVerzeichnis( pfad->getThis() );
+}
+
+bool Datei::istOffen() const // prüft, ob die Datei geöffnet ist
+{
+    if( !pfad )
+        return 0;
+    if( stream )
+        return stream->is_open() && stream->good();
+    return 0;
+}
+
+int Datei::getUnterdateiAnzahl() const // gibt die Anzahl der unterdateien an
+{
+#ifdef WIN32
+    if( !pfad )
+        return 0;
+    if( !DateiIstVerzeichnis( pfad->getThis() ) )
+        return 0;
+    int ret = 0;
+    HANDLE fHandle;
+    WIN32_FIND_DATA wfd;
+    Text stxt = pfad->getText();
+    stxt.ersetzen( '/', '\\' );
+    if( stxt.positionVon( '\\' ) == stxt.getLänge() - 1 )
+        stxt.anhängen( "*" );
+    else
+        stxt.anhängen( "\\*" );
+    fHandle = FindFirstFile( stxt.getText(), &wfd );
+    FindNextFile( fHandle, &wfd );
+    while( FindNextFile( fHandle, &wfd ) )
+        ++ret;
+    FindClose( fHandle );
+    return ret;
+#else
+    if( !pfad )
+        return 0;
+    if( !DateiIstVerzeichnis( pfad->getThis( ) ) )
+        return 0;
+    int ret = 0;
+    Text stxt = pfad->getText( );
+    stxt.ersetzen( '\\', '/' );
+    if( stxt.positionVon( '/' ) == stxt.getLaenge( ) - 1 )
+        stxt.loeschen( stxt.getLaenge( ) - 1 );
+    DIR *hdir;
+    hdir = opendir( stxt.getText( ) );
+    for( dirent *entry = readdir( hdir ); entry; entry = readdir( hdir ) )
+    {
+        if( entry && entry->d_name[ 0 ] != '.' )
+            ++ret;
+    }
+    closedir( hdir );
+    return ret;
+#endif
+}
+
+RCArray< Text > *Datei::getDateiListe() const // gibt eine Liste mit unterdateien zurück
+{
+#ifdef WIN32
+    if( !pfad )
+        return 0;
+    if( !DateiIstVerzeichnis( pfad->getThis() ) )
+        return 0;
+    HANDLE fHandle;
+    WIN32_FIND_DATA wfd;
+    Text stxt = pfad->getText();
+    stxt.ersetzen( '/', '\\' );
+    if( stxt.positionVon( '\\' ) == stxt.getLänge() - 1 )
+        stxt.anhängen( "*" );
+    else
+        stxt.anhängen( "\\*" );
+    fHandle = FindFirstFile( stxt.getText(), &wfd );
+    FindNextFile( fHandle, &wfd );
+    RCArray< Text > *ret = new RCArray< Text >();
+    int count = 0;
+    while( FindNextFile( fHandle, &wfd ) )
+    {
+        Text *txt = new Text( wfd.cFileName );
+        ret->add( txt, count );
+        ++count;
+    }
+    FindClose( fHandle );
+    return ret;
+#else
+    if( !pfad )
+        return 0;
+    if( !DateiIstVerzeichnis( pfad->getThis() ) )
+        return 0;
+    Text stxt = pfad->getText();
+    stxt.ersetzen( '\\', '/' );
+    if( stxt.positionVon( '/' ) == stxt.getLaenge() - 1 )
+        stxt.loeschen( stxt.getLaenge() - 1 );
+    DIR *hdir;
+    hdir = opendir( stxt.getText() );
+    if( hdir )
+    {
+        RCArray< Text > *ret = new RCArray< Text >();
+        int count = 0;
+        for( dirent *entry = readdir( hdir ); entry; entry = readdir( hdir ) )
+        {
+            if( entry && entry->d_name[ 0 ] != '.' )
+            {
+                ret->add( new Text( entry->d_name ), count );
+                ++count;
+            }
+        }
+        closedir( hdir );
+        return ret;
+    }
+    return 0;
+#endif
+}
+
+__int64 Datei::getGröße() const // gibt die Größe der Datei zurück
+{
+    if( !pfad )
+        return 0;
+    if( gr )
+        return gr;
+    if( !stream || !istOffen() )
+    {
+        std::fstream *stream = new std::fstream();
+        stream->open( pfad->getText(), std::ios::binary | std::ios::in );
+        __int64 tmp = stream->tellg();
+        stream->seekg( 0, std::ios::end );
+        __int64 ret = stream->tellg();
+        stream->seekg( tmp, std::ios::beg );
+        stream->close();
+        delete stream;
+        __int64 *größe = (__int64*)&gr;
+        *größe = ret;
+        return ret;
+    }
+    __int64 tmp = stream->tellg();
+    stream->seekg( 0, std::ios::end );
+    __int64 ret = stream->tellg();
+    stream->seekg( tmp, std::ios::beg );
+    __int64 *größe = (__int64*)&gr;
+    *größe = ret;
+    return ret;
+}
+
+Zeit *Datei::getLetzteÄnderung() const // gibt das Datum der letzten Änderung
+{
+    if( !pfad )
+        return 0;
+#ifdef WIN32
+    HANDLE hFile = CreateFile( pfad->getText(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
+    if( hFile == INVALID_HANDLE_VALUE )
+        return 0;
+    FILETIME ftCreate, ftAccess, ftWrite;
+    SYSTEMTIME stUTC, stLocal;
+    if( !GetFileTime( hFile, &ftCreate, &ftAccess, &ftWrite ) )
+    {
+        CloseHandle( hFile );
+        return 0;
+    }
+    CloseHandle( hFile );
+    if( !FileTimeToSystemTime( &ftWrite, &stUTC ) )
+        return 0;
+    if( !SystemTimeToTzSpecificLocalTime( NULL, &stUTC, &stLocal ) )
+        return 0;
+    Zeit *ret = new Zeit();
+    ret->setZeit( stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond );
+    return ret;
+#else
+    struct stat attrib;
+    stat(pfad->getText(), &attrib);
+    tm *clock = gmtime(&(attrib.st_mtime));
+    Zeit *ret = new Zeit();
+    ret->setZeit( clock->tm_year + 1900, clock->tm_mon + 1, clock->tm_mday, clock->tm_hour, clock->tm_min, clock->tm_sec );
+    return ret;
+#endif
+}
+
+bool Datei::existiert() const // prüft, ob die Datei existiert
+{
+    if( !pfad )
+        return 0;
+    return DateiExistiert( pfad->getThis() );
+}
+
+__int64 Datei::getLPosition() const // gibt die Leseposition zurück
+{
+    if( !stream )
+        return 0;
+    return stream->tellg();
+}
+
+__int64 Datei::getSPosition() const // gibt die Schreibeposition zurück
+{
+    if( !stream )
+        return 0;
+    return stream->tellp();
+}
+
+bool Datei::istEnde() const // prüft, ob die Datei zu ende ist
+{
+    if( !stream || stream->tellg() < 0 )
+        return 1;
+    __int64 i = getGröße();
+    return stream->tellg() >= i;
+}
+
+Text *Datei::getPfad() const // gibt den Dateipfad zurück
+{
+    return pfad ? pfad->getThis() : 0;
+}
+
+Text *Datei::zPfad() const
+{
+    return pfad;
+}
+
+// Reference Counting 
+Datei *Datei::getThis()
+{
+    ++ref;
+    return this;
+}
+
+Datei *Datei::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Datei Funktionen
+void Framework::GetFreePfad( Text *zPfad ) // Sucht einen unbenutzten Dateinamen
+{
+    Text txt = zPfad->getText();
+    for( int i = 0; DateiExistiert( txt ); i++ )
+    {
+        txt = zPfad->getText();
+        txt.anhängen( i );
+    }
+    zPfad->setText( txt );
+}
+
+bool Framework::DateiPfadErstellen( Text *pfad ) // Erstellt eine Datei in dem Pfad
+{
+    bool ret = DateiPfadErstellen( pfad->getText() );
+    pfad->release();
+    return ret;
+}
+
+bool Framework::DateiLöschen( Text *pfad ) // Löscht die angegebene Datei
+{
+    bool ret = DateiLöschen( pfad->getText() );
+    pfad->release();
+    return ret;
+}
+
+bool Framework::DateiUmbenennen( Text *pfad_alt, Text *pfad_neu ) // Benennt die Datei um
+{
+    bool ret = DateiUmbenennen( pfad_alt->getText(), pfad_neu->getText() );
+    pfad_alt->release();
+    pfad_neu->release();
+    return ret;
+}
+
+bool Framework::DateiExistiert( Text *pfad ) // Prüft, ob Datei existiert
+{
+    bool ret = DateiExistiert( pfad->getText() );
+    pfad->release();
+    return ret;
+}
+
+bool Framework::DateiIstVerzeichnis( Text *pfad ) // prüft, ob pfad ein Verzeichnis ist
+{
+    bool ret = DateiIstVerzeichnis( pfad->getText() );
+    pfad->release();
+    return ret;
+}
+
+bool Framework::DateiPfadErstellen( const char *pfad ) // Erstellt eine Datei in dem Pfad
+{
+    Text pf = pfad;
+    bool erst = 1;
+#ifdef WIN32
+    pf.ersetzen( "//", "\\" ); // Pfadangaben korrigieren
+    pf.ersetzen( "/", "\\" );
+    for( int i = 0; i < pf.anzahlVon( "\\" ); ++i ) // Jeden ordner erstellen wenn er nicht existiert
+    {
+        Text *t = pf.getTeilText( 0, pf.positionVon( "\\", i ) );
+        if( !t || !t->getLänge() )
+        {
+            if( t )
+                t->release();
+            continue;
+        }
+        if( !DateiExistiert( t->getThis() ) )
+#pragma warning(suppress: 6031)
+            _mkdir( t->getText() );
+        t->release();
+        if( pf.positionVon( "\\", i ) == pf.getLänge() - 1 )
+            erst = 0;
+    }
+#else
+    pf.ersetzen( "\\", "/" ); // Pfadangaben korrigieren
+    for( int i = 0; i < pf.anzahlVon( "/" ); ++i ) // Jeden ordner erstellen wenn er nicht existiert
+    {
+        Text *t = pf.getTeilText( 0, pf.positionVon( "/", i ) );
+        if( !t || !t->getLänge() )
+        {
+            if( t )
+                t->release();
+            continue;
+        }
+        if( !DateiExistiert( t->getThis() ) )
+            mkdir( t->getText(), 0777 );
+        t->release();
+        if( pf.positionVon( "\\", i ) == pf.getLänge() - 1 )
+            erst = 0;
+    }
+#endif
+    if( erst )
+    {
+        std::ofstream f( pf, std::ios::binary ); // Datei erstellen
+        f.close();
+    }
+    return DateiExistiert( pf );
+}
+
+bool Framework::DateiLöschen( const char *pfad ) // Löscht die angegebene Datei
+{
+    Text pfa = pfad;
+#ifdef WIN32
+    pfa.ersetzen( '\\', '/' );
+    bool ret = 0;
+    // prüfen ob Datei existiert
+    if( !DateiIstVerzeichnis( pfa.getThis() ) )
+        ret = DeleteFile( pfa.getText() ) == 1; // Datei löschen
+    else
+    {
+        ret = 1;
+        Datei *dat = new Datei();
+        dat->setDatei( pfa.getThis() );
+        int anz = dat->getUnterdateiAnzahl();
+        RCArray< Text > *liste = dat->getDateiListe();
+        for( int i = 0; i < anz; ++i )
+        {
+            Text *pf = new Text( pfa.getText() );
+            if( pf->getText()[ pf->getLänge() - 1 ] != '/' )
+                pf->anhängen( "/" );
+            pf->anhängen( liste->get( i ) );
+            if( ret )
+                ret = DateiLöschen( pf );
+            else
+                DateiLöschen( pf );
+        }
+        liste->release();
+        dat->release();
+        if( ret )
+            ret = RemoveDirectory( pfa.getText() ) == 1;
+        else
+            RemoveDirectory( pfa.getText() );
+    }
+    return ret;
+#else
+    pfa.ersetzen( '\\', '/' );
+    bool ret = 0;
+    // pruefen ob Datei existiert
+    if( !DateiIstVerzeichnis( pfa.getThis() ) )
+        ret = std::remove( pfa.getText() ) == 0; // Datei loeschen
+    else
+    {
+        ret = 1;
+        Datei *dat = new Datei();
+        dat->setDatei( pfa.getThis() );
+        int anz = dat->getUnterdateiAnzahl();
+        RCArray< Text > *liste = dat->getDateiListe();
+        for( int i = 0; i < anz; ++i )
+        {
+            Text *pf = new Text( pfa.getText() );
+            if( pf->getText()[ pf->getLaenge() - 1 ] != '/' )
+                pf->anhaengen( "/" );
+            pf->anhaengen( liste->get( i ) );
+            if( ret )
+                ret = DateiLoeschen( pf );
+            else
+                DateiLoeschen( pf );
+        }
+        liste->release();
+        dat->release();
+        if( ret )
+            ret = std::remove( pfa.getText() ) == 0;
+        else
+            std::remove( pfa.getText() );
+    }
+    return ret;
+#endif
+}
+
+bool Framework::DateiUmbenennen( const char *pfad_alt, const char *pfad_neu ) // Benennt die Datei um
+{
+#ifdef WIN32
+    if( pfad_alt && pfad_neu && DateiExistiert( pfad_alt ) )
+    {
+        bool ret = 1;
+        if( DateiIstVerzeichnis( pfad_alt ) )
+        {
+            if( !DateiExistiert( pfad_neu ) )
+            {
+                Text tmp = pfad_neu;
+                tmp += "/a";
+                DateiPfadErstellen( tmp );
+                DateiLöschen( tmp );
+            }
+            Datei d;
+            d.setDatei( pfad_alt );
+            RCArray< Text > *list = d.getDateiListe();
+            int anz = list->getEintragAnzahl();
+            for( int i = 0; i < anz; i++ )
+            {
+                Text pf = pfad_neu;
+                pf += "/";
+                pf += list->z( i )->getText();
+                Text pf_a = pfad_alt;
+                pf_a += "/";
+                pf_a += list->z( i )->getText();
+                ret |= DateiUmbenennen( pf_a, pf );
+            }
+            d.löschen();
+        }
+        else
+        {
+            if( DateiExistiert( pfad_neu ) )
+                return 0;
+        }
+        ret |= MoveFile( pfad_alt, pfad_neu ) == 1; // Datei umbenennen
+        return ret;
+    }
+    return 0;
+#else
+    if( pfad_alt && pfad_neu && DateiExistiert( pfad_alt ) )
+    {
+        bool ret = 1;
+        if( DateiIstVerzeichnis( pfad_alt ) )
+        {
+            if( !DateiExistiert( pfad_neu ) )
+            {
+                Text tmp = pfad_neu;
+                tmp += "/a";
+                DateiPfadErstellen( tmp );
+                DateiLöschen( tmp );
+            }
+            Datei d;
+            d.setDatei( pfad_alt );
+            RCArray< Text > *list = d.getDateiListe();
+            int anz = list->getEintragAnzahl();
+            for( int i = 0; i < anz; i++ )
+            {
+                Text pf = pfad_neu;
+                pf += "/";
+                pf += list->z( i )->getText();
+                Text pf_a = pfad_alt;
+                pf_a += "/";
+                pf_a += list->z( i )->getText();
+                ret |= DateiUmbenennen( pf_a, pf );
+            }
+            d.löschen();
+        }
+        else
+        {
+            if( DateiExistiert( pfad_neu ) )
+                return 0;
+        }
+        ret |= rename( pfad_alt, pfad_neu ) == 1; // Datei umbenennen
+        return ret;
+    }
+    return 0;
+#endif
+}
+
+bool Framework::DateiExistiert( const char *pfad ) // Prüft, ob Datei existiert
+{
+#ifdef WIN32
+    bool ret = PathFileExists( pfad ) != 0;
+    return ret;
+#else
+    std::ifstream file( pfad );
+    if( file.good() )
+        return 1;
+    return 0;
+#endif
+        }
+
+bool Framework::DateiIstVerzeichnis( const char *pfad ) // prüft, ob pfad ein Verzeichnis ist
+{
+#ifdef WIN32
+    WIN32_FIND_DATA wfd;
+    HANDLE handle = FindFirstFile( pfad, &wfd );
+    if( handle == INVALID_HANDLE_VALUE )
+        return 0;
+    FindClose( handle );
+    return ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0;
+#else
+    std::ifstream file( pfad );
+    if( file.good() )
+    {
+        std::ifstream file2( pfad, std::ios::out );
+        if( !file2.good() )
+            return 1;
+    }
+    return 0;
+#endif
+}

+ 190 - 0
Datei.h

@@ -0,0 +1,190 @@
+#ifndef Datei_H
+#define Datei_H
+
+#include "Array.h"
+#include <fstream>
+
+namespace Framework
+{
+	class Text; // Text.h
+	class Zeit; // Zeit.h
+	class Datei; // aus dieser Datei
+
+    // Ließt und schreibt in eine Datei
+	class Datei
+	{
+    public:
+        class Style
+        {
+        public:
+            const static int lesen = 0x01; // datei wird zum lesen geöffnet
+            const static int schreiben = 0x02; // datei wirt zum schreiben geöffnet
+            const static int ende = 0x04; // setzt dateizeiger ans Ende der Datei
+        };
+	private:
+		int ref;
+		std::fstream *stream;
+		Text *pfad;
+		__int64 gr;
+		char tmpLByte;
+		char tmpLBPos;
+		char tmpSByte;
+		char tmpSBPos;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Datei();
+		// Destruktor 
+		__declspec( dllexport ) ~Datei();
+		// Setzt den Pfad zur Datei
+        //  pfad: Der Pfad
+		__declspec( dllexport ) void setDatei( const char *pfad );
+        // Setzt den Pfad zur Datei
+        //  pfad: Der Pfad
+		__declspec( dllexport ) void setDatei( Text *pfad );
+        // Benennt die Datei um oder verschiebt sie
+        //  pfad: Der neue Pfad zur Datei. Wenn sich nur der Name ändert, wird sie nur umbenannt
+        //  return: 1, wenn das umbenennen erfolgreich war. 0, sonst
+		__declspec( dllexport ) bool umbenennen( const char *pfad );
+        // Benennt die Datei um oder verschiebt sie
+        //  pfad: Der neue Pfad zur Datei. Wenn sich nur der Name ändert, wird sie nur umbenannt
+        //  return: 1, wenn das umbenennen erfolgreich war. 0, sonst
+		__declspec( dllexport ) bool umbenennen( Text *pfad );
+        // Löscht die Datei
+        //  return: 1, wenn das löschen erfolgreich war. 0 sonst
+		__declspec( dllexport ) bool löschen();
+        // Erstellt die Datei neu. Wenn im Pfad Ordner vorkommen, die nicht existieren, so werden sie erstellt
+        //  return 1: wenn das erstellen erfolgreich war. 0, sonst
+		__declspec( dllexport ) bool erstellen();
+        // Öffnet die Datei
+        //  style: Legt fest, ob die Datei zum lesen und/oder schreiben geöffnet wird. Alle Elemente aus Datei::Style:: sin möglich
+        //  return 1: wenn die datei erfolgreich geöffnet werden konnte. 0 sonnst
+		__declspec( dllexport ) bool öffnen( int style );
+        // Setzt die Position des Bytes, das als nächstes gelesen werden soll
+        //  pos: Der Index des Bytes
+        //  ende: 1, wenn der Index vom ende der Datei zählt. 0, wenn der Index vom Beginn der Datei zählt
+		__declspec( dllexport ) void setLPosition( __int64 pos, bool ende );
+        // Setzt die Position des Bytes, das als nächstes überschrieben wird
+        //  pos: Der Index des Bytes
+        //  ende: 1, wenn der Index vom ende der Datei zählt. 0, wenn der Index vom Beginn der Datei zählt
+		__declspec( dllexport ) void setSPosition( __int64 pos, bool ende );
+        // Schreibt in die Datei
+        //  bytes: Ein Array von bytes, die geschrieben werden sollen.
+        //  län: Wie viele Bytes in die Datei geschrieben werden sollen
+		__declspec( dllexport ) void schreibe( char *bytes, int län );
+        // Ließt aus der Datei
+        //  bytes: Ein Array, der mit Bytes aus der Datei gefüllt werden soll
+        //  län: Wie viele Bytes aus der Datei gelesen werden sollen
+        __declspec( dllexport ) void lese( char *bytes, int län );
+        // Ließt die nächste zeile der Datei ein
+        //  return: Die gelesene Zeile als Text mit zeilenumbruch
+		__declspec( dllexport ) Text *leseZeile();
+        // Schließt die datei
+		__declspec( dllexport ) void schließen();
+#ifdef WIN32
+        // Setzt den Zeitpunkt der letzten Änderung der Datei (nur für Windows)
+        //  zeit: den Zeitpunkt der letzten Änderung
+        //  return: 1, wenn der Zeitpunkt gesetzt wurde. 0 sonst
+		__declspec( dllexport ) bool setLetzteÄnderung( Zeit *zeit );
+#endif
+        // Ließt das nächste Bit aus der Datei
+        //  bit: Eine Referenz auf deinen bool, in dem das Bit gespeichert wird
+        //  return 1, falls das lesen erfolgreich war. 0, sonst
+		__declspec( dllexport ) bool getNextBit( bool &bit );
+        // Speichert ein einzelnes Bit in der Datei
+        //  bit: Das bit, welches gespeichert werden soll
+        //  return 1, falls das speichern erfolgreich war
+		__declspec( dllexport ) bool setNextBit( bool bit );
+		// Prüft, ob die Datei ein Verzeichnis ist
+        //  return 1, falls die Datei ein Verzeichnis ist. 0, sonst
+		__declspec( dllexport ) bool istOrdner() const;
+        // Prüft, ob die Datei bereits geöffnet wurde
+        //  return: 1, wenn die Datei geöffnet ist. 0 sonnst
+		__declspec( dllexport ) bool istOffen() const;
+        // Gibt die Anzahl an Unterdateien von dem Verzeichnis zurück
+        //  return: 0, falls die Datei kein Verzeichnis ist. Sonst die Anzahl der Unterdateien
+        __declspec( dllexport ) int getUnterdateiAnzahl() const;
+        // Gibt eine Liste mit unterdateien zurück
+        //  return 0, falls die Datei kein Verzeichnis ist. Eine Liste mit den Namen der Unterdateien
+		__declspec( dllexport ) RCArray< Text > *getDateiListe() const;
+        // Gibt die Größe der Datei zurück
+        // return -1, falls die Datei ein Verzeichnis ist oder ein Fehler auftrat. Sonst die größe der Datei
+		__declspec( dllexport ) __int64 getGröße() const;
+        // Gibt den Zeitpunkt der letzten änderung zurück
+        //  return: 0, falls ein Fehler aufgetreten ist. Der Zeitpunkt der letzten Änderung sonst
+		__declspec( dllexport ) Zeit *getLetzteÄnderung() const;
+        // Prüft, ob die Datei existiert
+        //  return: 1, falls die Datei existiert. 0 sonnst
+		__declspec( dllexport ) bool existiert() const;
+        // Gibt den Index des Bytes aus der Datei zurück, welches als nächstes gelesen werden würde
+        // return -1, falls ein Fehler aufgetreten ist. Sonst die Position des Lesezeigers
+        __declspec( dllexport ) __int64 getLPosition() const;
+        // Gibt den Index des Bytes aus der Datei zurück, welches als nächstes überschrieben werden würde
+        // return -1, falls ein Fehler aufgetreten ist. Sonst die Position des Schreibzeigers
+		__declspec( dllexport ) __int64 getSPosition() const;
+        // Prüft, ob die Datei vollständig gelesen wurde
+        //  return 1, wenn die Datei vollständig gelesen wurde. 0, sonst
+		__declspec( dllexport ) bool istEnde() const;
+        // Gibt den Pfad zur Datei zurück
+		__declspec( dllexport ) Text *getPfad() const;
+        // Gibt den Pfad zur Datei ohne erhöhten Reference Counter zurück
+		__declspec( dllexport ) Text *zPfad() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) Datei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) Datei *release();
+	};
+
+	// Datei Funktionen
+
+    // Sucht einen unbenutzten Dateinamen
+    //  zPfad: Ein Zeiger zu dem Pfad, in dem ein unbenutzter Dateiname gefunden werden soll. Ohne erhöhten Reference Counter.
+    //          Wird auch als rückgabewert benutzt
+	__declspec( dllexport ) void GetFreePfad( Text *zPfad );
+    // Erstellt den vollständigen Pfad mit Datei
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, falls das erstellen erfolgreich war.
+	__declspec( dllexport ) bool DateiPfadErstellen( Text* pfad );
+    // Löscht die angegebene Datei
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, falls die Datei gelöscht wurde
+	__declspec( dllexport ) bool DateiLöschen( Text *pfad );
+    // Benennt eine Datei um oder verschiebt sie
+    //  pfad_alt: Der Pfad zur Datei, die umbenannt werden soll.
+    //  pfad_neu: Der neue Pfad zur Datei. Wenn sich nur der Name ändert, wird sie nur umbenannt
+    //  return: 1, wenn das umbenennen erfolgreich war. 0, sonst
+	__declspec( dllexport ) bool DateiUmbenennen( Text *pfad_alt, Text *pfad_neu );
+    // Prüft, ob Datei existiert
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, wenn die Datei existiert. 0, wenn die Datei nicht gefunden wurde
+    __declspec( dllexport ) bool DateiExistiert( Text *pfad );
+    // prüft, ob pfad ein Verzeichnis ist
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, wenn die Datei ein Verzeichnis ist. 0 sonst
+	__declspec( dllexport ) bool DateiIstVerzeichnis( Text *pfad );
+    // Erstellt den vollständigen Pfad mit Datei
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, falls das erstellen erfolgreich war.
+	__declspec( dllexport ) bool DateiPfadErstellen( const char *pfad );
+    // Löscht die angegebene Datei
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, falls die Datei gelöscht wurde
+	__declspec( dllexport ) bool DateiLöschen( const char *pfad );
+    // Benennt eine Datei um oder verschiebt sie
+    //  pfad_alt: Der Pfad zur Datei, die umbenannt werden soll.
+    //  pfad_neu: Der neue Pfad zur Datei. Wenn sich nur der Name ändert, wird sie nur umbenannt
+    //  return: 1, wenn das umbenennen erfolgreich war. 0, sonst
+	__declspec( dllexport ) bool DateiUmbenennen( const char *pfad_alt, const char *pfad_neu );
+    // Prüft, ob Datei existiert
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, wenn die Datei existiert. 0, wenn die Datei nicht gefunden wurde
+	__declspec( dllexport ) bool DateiExistiert( const char *pfad );
+    // prüft, ob pfad ein Verzeichnis ist
+    //  pfad: Der Pfad zur Datei
+    //  return: 1, wenn die Datei ein Verzeichnis ist. 0 sonst
+	__declspec( dllexport ) bool DateiIstVerzeichnis( const char *pfad );
+}
+
+#endif

+ 274 - 0
DateiDialog.cpp

@@ -0,0 +1,274 @@
+#include "DateiDialog.h"
+#include "Text.h"
+#include <ShObjIdl.h>
+#pragma comment( lib, "Ole32.lib" )
+#pragma comment( linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"" )	
+
+void Framework::InitDialog()
+{
+    CoInitialize( 0 );
+}
+
+using namespace Framework;
+
+// Inhalt der DateiDialog Klasse aus DateiDialog.h
+// Konstruktor
+DateiDialog::DateiDialog()
+{
+    typeName = new RCArray< Text >();
+    type = new RCArray< Text >();
+    fileIndex = 1;
+    ref = 1;
+}
+
+// Destruktor
+DateiDialog::~DateiDialog()
+{
+    typeName->release();
+    type->release();
+}
+
+// nicht constant
+void DateiDialog::löscheDateiTypen()
+{
+    typeName->leeren();
+    type->leeren();
+}
+
+void DateiDialog::addDateiTyp( char *name, char *typ )
+{
+    addDateiTyp( new Text( name ), new Text( typ ) );
+}
+
+void DateiDialog::addDateiTyp( Text *name, Text *typ )
+{
+    typeName->add( name );
+    type->add( typ );
+}
+
+void DateiDialog::setDateiTypAuswahl( int i )
+{
+    fileIndex = i + 1;
+}
+
+// constant
+Text *DateiDialog::anzeigen( bool open ) const
+{
+    IFileDialog *pfd = NULL;
+    CoInitialize( NULL );
+    HRESULT hr = 0;
+    if( open )
+    {
+        CoCreateInstance( CLSID_FileOpenDialog,
+                          NULL,
+                          CLSCTX_INPROC_SERVER,
+                          IID_PPV_ARGS( &pfd ) );
+    }
+    else
+    {
+        CoCreateInstance( CLSID_FileSaveDialog,
+                          NULL,
+                          CLSCTX_INPROC_SERVER,
+                          IID_PPV_ARGS( &pfd ) );
+    }
+    if( SUCCEEDED( hr ) )
+    {
+        DWORD dwFlags;
+        hr = pfd->GetOptions( &dwFlags );
+        if( SUCCEEDED( hr ) )
+        {
+            hr = pfd->SetOptions( dwFlags | FOS_FORCEFILESYSTEM );
+            if( SUCCEEDED( hr ) )
+            {
+                int anz = type->getEintragAnzahl();
+                COMDLG_FILTERSPEC *c_rgSaveTypes = 0;
+                if( !anz )
+                {
+                    c_rgSaveTypes = new COMDLG_FILTERSPEC[ 1 ];
+                    c_rgSaveTypes[ 0 ] = { L"Alle Dateien", L"*.*" };
+                    anz = 1;
+                }
+                else
+                {
+                    c_rgSaveTypes = new COMDLG_FILTERSPEC[ anz ];
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        wchar_t *n = new wchar_t[ typeName->z( i )->getLänge() + 1 ];
+#pragma warning( disable : 4996 )
+                        mbstowcs( n, typeName->z( i )->getText(), typeName->z( i )->getLänge() + 1 );
+                        wchar_t *t = new wchar_t[ type->z( i )->getLänge() + 1 ];
+#pragma warning( disable : 4996 )
+                        mbstowcs( t, type->z( i )->getText(), type->z( i )->getLänge() + 1 );
+                        c_rgSaveTypes[ i ].pszName = n;
+                        c_rgSaveTypes[ i ].pszSpec = t;
+                    }
+                }
+                hr = pfd->SetFileTypes( anz, c_rgSaveTypes );
+                if( SUCCEEDED( hr ) )
+                {
+                    hr = pfd->SetFileTypeIndex( fileIndex );
+                    if( SUCCEEDED( hr ) )
+                    {
+                        Text txt = "";
+                        for( int i = 0; i < anz; i++ )
+                        {
+                            if( !type->z( i )->hat( ".*" ) )
+                            {
+                                txt.anhängen( type->z( i )->getTeilText( type->z( i )->positionVon( "." ) + 1 ) );
+                                txt += ";";
+                            }
+                        }
+                        if( txt.getLänge() > 0 )
+                            txt.löschen( txt.getLänge() - 1 );
+                        wchar_t *defEnd = new wchar_t[ txt.getLänge() + 1 ];
+#pragma warning( disable : 4996 )
+                        mbstowcs( defEnd, txt, txt.getLänge() + 1 );
+                        hr = pfd->SetDefaultExtension( defEnd );
+                        if( SUCCEEDED( hr ) )
+                        {
+                            hr = pfd->Show( NULL );
+                            if( SUCCEEDED( hr ) )
+                            {
+                                IShellItem *psiResult;
+                                hr = pfd->GetResult( &psiResult );
+                                if( SUCCEEDED( hr ) )
+                                {
+                                    PWSTR pszFilePath = NULL;
+                                    hr = psiResult->GetDisplayName( SIGDN_FILESYSPATH,
+                                                                    &pszFilePath );
+                                    if( SUCCEEDED( hr ) )
+                                    {
+                                        char *txt = new char[ wcslen( pszFilePath ) + 1 ];
+#pragma warning( disable : 4996 )
+                                        wcstombs( txt, pszFilePath, wcslen( pszFilePath ) + 1 );
+                                        Text *ret = new Text( txt );
+                                        delete[] txt;
+                                        psiResult->Release();
+                                        delete[] defEnd;
+                                        for( int i = 0; i < anz; i++ )
+                                        {
+                                            delete[] c_rgSaveTypes[ i ].pszName;
+                                            delete[] c_rgSaveTypes[ i ].pszSpec;
+                                        }
+                                        delete[] c_rgSaveTypes;
+                                        pfd->Release();
+                                        return ret;
+                                    }
+                                    psiResult->Release();
+                                }
+                            }
+                        }
+                        delete[] defEnd;
+                    }
+                }
+                for( int i = 0; i < anz; i++ )
+                {
+                    delete[] c_rgSaveTypes[ i ].pszName;
+                    delete[] c_rgSaveTypes[ i ].pszSpec;
+                }
+                delete[] c_rgSaveTypes;
+            }
+        }
+        pfd->Release();
+    }
+    return 0;
+}
+
+// Reference Counting
+DateiDialog *DateiDialog::getThis()
+{
+    ref++;
+    return this;
+}
+
+DateiDialog *DateiDialog::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der DateiDialogTh Klasse aus DateiDialog.h
+// Konstruktor
+DateiDialogTh::DateiDialogTh()
+{
+    dialog = new DateiDialog();
+    ret = 0;
+    öffnen = 0;
+    ref = 1;
+}
+
+// Destruktor
+DateiDialogTh::~DateiDialogTh()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    dialog->release();
+    if( ret )
+        ret->release();
+}
+
+// nicht constant
+void DateiDialogTh::setÖffnen( bool b )
+{
+    öffnen = b;
+}
+
+void DateiDialogTh::löscheDateiTypen()
+{
+    dialog->löscheDateiTypen();
+}
+
+void DateiDialogTh::addDateiTyp( char *name, char *typ )
+{
+    dialog->addDateiTyp( name, typ );
+}
+
+void DateiDialogTh::addDateiTyp( Text *name, Text *typ )
+{
+    dialog->addDateiTyp( name, typ );
+}
+
+void DateiDialogTh::setDateiTypAuswahl( int i )
+{
+    dialog->setDateiTypAuswahl( i );
+}
+
+void DateiDialogTh::thread()
+{
+    if( ret )
+        ret = ret->release();
+    ret = dialog->anzeigen( öffnen );
+}
+
+// constant
+Text *DateiDialogTh::getPfad() const
+{
+    return ret ? ret->getThis() : 0;
+}
+
+Text *DateiDialogTh::zPfad() const
+{
+    return ret;
+}
+
+// Refernece Counting
+DateiDialogTh *DateiDialogTh::getThis()
+{
+    ref++;
+    return this;
+}
+
+DateiDialogTh *DateiDialogTh::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 100 - 0
DateiDialog.h

@@ -0,0 +1,100 @@
+#ifndef DateiDialog_H
+#define DateiDialog_H
+
+#include "Array.h"
+#include "Thread.h"
+
+namespace Framework
+{
+    class Text; // Text.h
+
+    void InitDialog();
+
+    // Erstellt einen Datei öffnen/speichern Dialog
+    class DateiDialog
+    {
+    private:
+        RCArray< Text > *typeName;
+        RCArray< Text > *type;
+        int fileIndex;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) DateiDialog();
+        // Destruktor
+        __declspec( dllexport ) ~DateiDialog();
+        // Löscht die Liste mit zugelassenen Dateitypen
+        __declspec( dllexport ) void löscheDateiTypen();
+        // Fügt einen zugelassenen Dateityp hinzu
+        //  name: Der Name des Dateitypes. Ist für den Nutzer in der Select Box sichtbar
+        //  typ: Der Dateityp, der ausgewählt werden darf
+        __declspec( dllexport ) void addDateiTyp( char *name, char *typ );
+        // Fügt einen zugelassenen Dateityp hinzu
+        //  name: Der Name des Dateitypes. Ist für den Nutzer in der Select Box sichtbar
+        //  typ: Der Dateityp, der ausgewählt werden darf
+        __declspec( dllexport ) void addDateiTyp( Text *name, Text *typ );
+        // Setzt den zu Beginn ausgewählten Dateityp
+        //  i: Der Index des Dateityps. Der, der als erstes hinzugefügt wurde, hat den Index 0.
+        __declspec( dllexport ) void setDateiTypAuswahl( int i );
+        // Zeigt den Dateidialog an
+        //  open: true, wenn der Dialog zum öffnen dienen soll. false zum Speichern
+        //  return: Den Pfad zur ausgewählten Datei
+        __declspec( dllexport ) Text *anzeigen( bool open ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) DateiDialog *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) DateiDialog *release();
+    };
+
+    // Verwaltet einen Datei öffnen/speichern Dialog ohne zu warten
+    class DateiDialogTh : public Thread
+    {
+    private:
+        DateiDialog *dialog;
+        Text *ret;
+        bool öffnen;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) DateiDialogTh();
+        // Destruktor
+        __declspec( dllexport ) ~DateiDialogTh();
+        // Legt fest, ob der Dialog zum öffnen oder speichern ist
+        //  b: 1, wenn er zum öfnen ist. 0, wenn er zum speichern ist
+        __declspec( dllexport ) void setÖffnen( bool b );
+        // Löscht die liste mit erlaubten Dateitypen
+        __declspec( dllexport ) void löscheDateiTypen();
+        // Fügt einen zugelassenen Dateityp hinzu
+        //  name: Der Name des Dateitypes. Ist für den Nutzer in der Select Box sichtbar
+        //  typ: Der Dateityp, der ausgewählt werden darf
+        __declspec( dllexport ) void addDateiTyp( char *name, char *typ );
+        // Fügt einen zugelassenen Dateityp hinzu
+        //  name: Der Name des Dateitypes. Ist für den Nutzer in der Select Box sichtbar
+        //  typ: Der Dateityp, der ausgewählt werden darf
+        __declspec( dllexport ) void addDateiTyp( Text *name, Text *typ );
+        // Setzt den zu Beginn ausgewählten Dateityp
+        //  i: Der Index des Dateityps. Der, der als erstes hinzugefügt wurde, hat den Index 0.
+        __declspec( dllexport ) void setDateiTypAuswahl( int i );
+        // Diese Funktion wird von der Klasse selbst aufgerufen.
+        // Benutze die start Funktion um den Dialog anzuzeigen
+        __declspec( dllexport ) void thread() override;
+        // Gibt den Pfad zur Datei zurück.
+        // Funktioniert erst, nachdem der Thread beendet wurde
+        __declspec( dllexport ) Text *getPfad() const;
+        // Gibt den Pfad zur Datei ohne erhöhten Reference Counter zurück.
+        // Funktioniert erst, nachdem der Thread beendet wurde
+        __declspec( dllexport ) Text *zPfad() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) DateiDialogTh *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) DateiDialogTh *release();
+    };
+};
+
+#endif

+ 3207 - 0
DateiSystem.cpp

@@ -0,0 +1,3207 @@
+//---Include---
+#include "DateiSystem.h"
+#include "Bild.h"
+#include "Text.h"
+#include <iostream>
+#ifdef WIN32
+#include "Fenster.h"
+#include "Schrift.h"
+#include "Fortschritt.h"
+#include "Globals.h"
+#endif
+#include "Datei.h"
+
+using namespace Framework;
+// LTDB Dateivormat 
+// Inhalt der LTDBPixel Klasse aus Dateisystem.h
+// Konstruktor 
+LTDBPixel::LTDBPixel( LTDBPixel *davor )
+	: davor( davor ),
+	  index( 0 ),
+	  iR( 0 ),
+	  iG( 0 ),
+	  iB( 0 ),
+	  iA( 0 ),
+	  miR( 8 ),
+	  miG( 8 ),
+	  miB( 8 ),
+	  miA( 8 ),
+	  maxIndex( 1 ),
+	  änder( 0 ),
+	  änderR( 0 ),
+	  änderG( 0 ),
+	  änderB( 0 ),
+	  änderA( 0 ),
+	  komp( 0 ),
+	  R( 0 ),
+	  G( 0 ),
+	  B( 0 ),
+	  A( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+LTDBPixel::~LTDBPixel()
+{
+	if( davor )
+		davor->release();
+}
+
+// nicht constant 
+bool LTDBPixel::addBitZuFarbe( unsigned char bit ) // Fügt den Farbwerten ein Bit hinzu
+{
+	if( änderR && iR != miR ) // Das Bit gehört zu Rot
+	{
+		R |= ( ( bit & 0x1 ) ) << ( 7 - komp - iR );
+		++iR;
+	}
+	else if( änderG && iG != miG ) // Das Bit gehört zu Grün
+	{
+		G |= ( ( bit & 0x1 ) ) << ( 7 - komp - iG );
+		++iG;
+	}
+	else if( änderB && iB != miB ) // Das Bit gehört zu Blau
+	{
+		B |= ( ( bit & 0x1 ) ) << ( 7 - komp - iB );
+		++iB;
+	}
+	else if( änderA && iA != miA ) // Das Bit gehört zu Alpha
+	{
+		A |= ( ( bit & 0x1 ) ) << ( 7 - komp - iA );
+		++iA;
+	}
+	else // Das Bit gehört zum nächsten Pixel
+		return false;
+	return true;
+}
+
+char LTDBPixel::addByte( char byte, char begin ) // gibt ende des Pixels zurück, -1 wenn nicht zu ende
+{
+	if( begin >= 8 || begin < 0 )
+		return -1;
+	for( int i = begin; i < 8; ++i )
+	{
+		switch( index )
+		{
+		case 0:
+			// Das erste Bit eines Pixels speichert, ob sich an der Komprimierung etwas änderte
+			änder = (bool)( ( byte >> ( 7 - i ) ) & 0x1 );
+			if( !änder ) // Ändert sich nichts an der Komprimierung, so werden die Werte vom vorherigen Pixel übernommen
+			{
+				if( !davor ) // Die Datei ist beschädigt ( Der erste Pixel kann nicht von dem davor Übernemen )
+				{
+#ifdef WIN32
+					MessageBox( NULL, "Fehler, die Bilddatei ist beschädigt", "Fehler", MB_ICONERROR );
+#endif
+					exit( 0 );
+				}
+				änderR = davor->getÄnderR();
+				änderG = davor->getÄnderG();
+				änderB = davor->getÄnderB();
+				änderA = davor->getÄnderA();
+				komp = davor->getKomp();
+				miR -= komp, miG -= komp, miB -= komp, miA -= komp;
+				if( !änderR )
+					R = davor->getR();
+				if( !änderG )
+					G = davor->getG();
+				if( !änderB )
+					B = davor->getB();
+				if( !änderA )
+					A = davor->getA();
+				maxIndex += ( änderR + änderG + änderB + änderA ) * ( 8 - komp ); // Bestimmung der Länge
+				// des Pixels in Bits. Jede Farbe hat von grund auf 8 Bits, durch komprimierung kanns kleiner sein
+			}
+			else
+				maxIndex += 7; // Da der Pixel nicht die Werte des vorherigen übernimmt, wird er um 7 Bits größer
+			break;
+		case 1: // Das zweite Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				änderR = (bool)( ( byte >> ( 7 - i ) ) & 0x1 );
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 2: // Das dritte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				änderG = (bool)( ( byte >> ( 7 - i ) ) & 0x1 );
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 3: // Das vierte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				änderB = (bool)( ( byte >> ( 7 - i ) ) & 0x1 );
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 4: // Das fünfte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				änderA = (bool)( ( byte >> ( 7 - i ) ) & 0x1 );
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 5: // Das sechste Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & 0x1 ) << 2;
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 6: // Das siebte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & 0x1 ) << 1;
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 7: // Das achte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 7 Komprimierungsbits
+			{
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & 0x1 );
+				// Das war das letzte Komprimierungsbit
+				// Komprimierung auswerten 
+				miR -= komp, miG -= komp, miB -= komp, miA -= komp;
+				if( !änderR )
+					R = davor->getR();
+				if( !änderG )
+					G = davor->getG();
+				if( !änderB )
+					B = davor->getB();
+				if( !änderA )
+					A = davor->getA();
+				maxIndex += ( änderR + änderG + änderB + änderA ) * ( 8 - komp ); // Bitlänge des Pixels
+			}
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		default: // Die restlichen Bits speichern alle die Farbwerte des Pixels
+			if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+				return i;
+			break;
+		}
+		++index;
+		if( index >= maxIndex )
+		{
+			if( davor )
+			{
+				if( änderR )
+					R = davor->getR() + R;
+				if( änderG )
+					G = davor->getG() + G;
+				if( änderB )
+					B = davor->getB() + B;
+				if( änderA )
+					A = davor->getA() + A;
+				davor = davor->release();
+			}
+			return i + 1;
+		}
+	}
+	return -1;
+}
+
+void LTDBPixel::setFarbe( int f ) // setzt die Farbe des Pixels
+{   // Da diese Funktion aufgerufen wird, möchte man die Klasse nun zum speichern verwenden
+	// Werte zurücksetzen, fals mit der Klasse schon geladen oder gespeichert wurde
+	index = 0, maxIndex = 1;
+	änder = 0, änderR = 0, änderG = 0, änderB = 0, änderA = 0, komp = 0;
+	iR = 0, iG = 0, iB = 0, iA = 0;
+	miR = 8, miG = 8, miB = 8, miA = 8;
+	// Farbwerte setzen
+	R = (unsigned char)( f >> 16 );
+	G = (unsigned char)( f >> 8 );
+	B = (unsigned char)f;
+	A = (unsigned char)( f >> 24 );
+}
+
+void LTDBPixel::komprimieren() // Komprimiert den Pixel
+{
+	maxIndex = 1;
+	if( !davor )
+	{// Das ist der erste Pixel
+		änder = 1;
+		änderR = 1;
+		änderG = 1;
+		änderB = 1;
+		änderA = 1;
+		maxIndex += 7;
+		miR = getBits( R );
+		miG = getBits( G );
+		miB = getBits( B );
+		miA = getBits( A );
+	}
+	else
+	{ // Es wird die differenz zum vorrigen Pixel gespeichert
+		miR = getBits( R - davor->getR() );
+		miG = getBits( G - davor->getG() );
+		miB = getBits( B - davor->getB() );
+		miA = getBits( A - davor->getA() );
+		änderR = R != davor->getR();
+		änderG = G != davor->getG();
+		änderB = B != davor->getB();
+		änderA = A != davor->getA();
+	}// Prüfen ob sich etwas ändert
+	if( !miR && änderR )
+		++miR;
+	if( !miG && änderG )
+		++miG;
+	if( !miB && änderB )
+		++miB;
+	if( !miA && änderA )
+		++miA;
+	int k = ( miR > miG ? miR : miG );
+	k = ( k > miB ? k : miB );
+	k = ( k > miA ? k : miA );
+	miR = k, miG = k, miB = k, miA = k;
+	komp = 8 - k;
+	maxIndex += ( änderR + änderG + änderB + änderA ) * ( k );
+	if( davor )
+	{
+		if( änderR != davor->getÄnderR() ||
+			änderG != davor->getÄnderG() ||
+			änderB != davor->getÄnderB() ||
+			änderA != davor->getÄnderA() ||
+			komp != davor->getKomp() )
+		{ // Es ändert sich etwas
+			änder = 1;
+			maxIndex += 7;
+		}
+		else
+		{ // Es ändert sich nichts
+			änder = 0;
+		}
+	}
+}
+
+bool LTDBPixel::getNextFarbeBit( char &byte, int i ) // Speichert das nächste Farbbit in byte
+{
+	unsigned char RR = R;
+	unsigned char GG = G;
+	unsigned char BB = B;
+	unsigned char AA = A;
+	if( davor )
+	{
+		RR -= davor->getR();
+		GG -= davor->getG();
+		BB -= davor->getB();
+		AA -= davor->getA();
+	}
+	if( änderR && iR != miR ) // Das Bit gehört zu Rot
+	{
+		byte |= ( ( RR >> ( 7 - komp - iR ) ) & 0x1 ) << ( 7 - i );
+		++iR;
+	}
+	else if( änderG && iG != miG ) // Das Bit gehört zu Grün
+	{
+		byte |= ( ( GG >> ( 7 - komp - iG ) ) & 0x1 ) << ( 7 - i );
+		++iG;
+	}
+	else if( änderB && iB != miB ) // Das Bit gehört zu Blau
+	{
+		byte |= ( ( BB >> ( 7 - komp - iB ) ) & 0x1 ) << ( 7 - i );
+		++iB;
+	}
+	else if( änderA && iA != miA ) // Das Bit gehört zu Alpha
+	{
+		byte |= ( ( AA >> ( 7 - komp - iA ) ) & 0x1 ) << ( 7 - i );
+		++iA;
+	}
+	else // Der Pixel ist bereits zu ende
+		return false;
+	return true;
+}
+
+char LTDBPixel::getNextByte( char &byte, int begin ) // Gibt die nächsten Bits Zurück, -1 wenn der Pixel nicht zu ende ist
+{
+	// bbegin gibt an wohin in die byte-variable geschrieben werden soll
+	// die Funktion gibt das ende des Pixels in der byte-variable zurück
+	// -1 heißt, dass der Pixel nicht zu ende ist
+	for( int i = begin; i < 8; ++i )
+	{
+		switch( index )
+		{
+		case 0: // Das erste Bit des Pixels speichert, ob sich etwas an der Komprimierung ändert
+			byte |= ( (int)änder & 0x1 ) << ( 7 - i );
+			break;
+		case 1: // Das zweite Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( (int)änderR & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 2: // Das dritte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( (int)änderG & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 3: // Das vierte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( (int)änderB & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 4: // Das fünfte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( (int)änderA & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 5: // Das sechste Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( ( komp >> 2 ) & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 6: // Das siebte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( ( komp >> 1 ) & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 7: // Das sechste Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( komp & 0x1 ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		default: // Die restlichen Bits speichern die Farbe des Pixels
+			if( !getNextFarbeBit( byte, i ) )
+				return i;
+			break;
+		}
+		++index;
+		if( index >= maxIndex )
+		{
+			if( davor )
+				davor = davor->release();
+			return i + 1;
+		}
+	}
+	return -1;
+}
+
+// constant 
+int LTDBPixel::zuFarbe() const // gibt den Pixel als Farbe zurück
+{
+	return ( ( (int)R << 16 ) | ( (int)G << 8 ) | (int)B | ( (int)A << 24 ) );
+}
+
+bool LTDBPixel::getÄnderR() const
+{
+	return änderR;
+}
+
+bool LTDBPixel::getÄnderG() const
+{
+	return änderG;
+}
+
+bool LTDBPixel::getÄnderB() const
+{
+	return änderB;
+}
+
+bool LTDBPixel::getÄnderA() const
+{
+	return änderA;
+}
+
+unsigned char LTDBPixel::getKomp() const
+{
+	return komp;
+}
+
+unsigned char LTDBPixel::getR() const // gibt Rot zurück 
+{
+	return R;
+}
+
+unsigned char LTDBPixel::getG() const // gibt Grün zurück
+{
+	return G;
+}
+
+unsigned char LTDBPixel::getB() const // gibt Blau zurück
+{
+	return B;
+}
+
+unsigned char LTDBPixel::getA() const // gibt Alpha zurück
+{
+	return A;
+}
+
+// Reference Counting 
+LTDBPixel *LTDBPixel::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDBPixel *LTDBPixel::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDBDateiKopf Klasse aus Dateisystem.h
+// konstructor
+LTDBDateiKopf::LTDBDateiKopf()
+	: bilder( new RCArray< Text >() ),
+	  pos( new Array< __int64 >() ),
+	  bAnzahl( 0 ),
+	  ref( 1 )
+{
+}
+
+// destructor 
+LTDBDateiKopf::~LTDBDateiKopf()
+{
+	bilder->release();
+	pos->release();
+}
+
+// nicht constant 
+void LTDBDateiKopf::removeBild( int i )
+{
+	if( i >= bAnzahl )
+		return;
+	bilder->lösche( i );
+	pos->lösche( i );
+	--bAnzahl;
+}
+
+void LTDBDateiKopf::removeBild( Text *txt )
+{
+	int i = -1;
+	for( int ii = 0; ii < bAnzahl; ++ii )
+	{
+		Text *b = bilder->z( ii );
+		if( b->istGleich( txt->getText() ) )
+		{
+			i = ii;
+			break;
+		}
+	}
+	txt->release();
+	if( i == -1 )
+		return;
+	bilder->lösche( i );
+	pos->lösche( i );
+	--bAnzahl;
+}
+
+void LTDBDateiKopf::addBild( Text *txt )
+{
+	bilder->add( txt, bAnzahl );
+	pos->add( 0, bAnzahl );
+	++bAnzahl;
+}
+
+void LTDBDateiKopf::setBildPos( int i, __int64 pos )
+{
+	this->pos->set( pos, i );
+}
+
+void LTDBDateiKopf::setBildPos( Text *txt, __int64 pos )
+{
+	int i = -1;
+	for( int ii = 0; ii < bAnzahl; ++ii )
+	{
+		Text *b = bilder->z( ii );
+		if( b->istGleich( txt->getText() ) )
+		{
+			i = ii;
+			break;
+		}
+	}
+	txt->release();
+	if( i == -1 )
+		return;
+	this->pos->set( pos, i );
+}
+
+void LTDBDateiKopf::laden( FBalken *f, std::ifstream *inF )
+{
+	if( inF->is_open() && inF->good() )
+	{
+		char b = 0;
+		inF->read( &b, 1 );
+		bAnzahl = b << 8;
+		inF->read( &b, 1 );
+		bAnzahl |= b & 0xFF;
+#ifdef WIN32
+		if( f )
+		{
+			f->reset();
+			f->setAktionAnzahl( bAnzahl );
+		}
+#endif
+		bilder->leeren();
+		pos->leeren();
+		for( int i = 0; i < bAnzahl; ++i )
+		{
+			LTDBKopf *kpf = new LTDBKopf();
+			kpf->laden( inF ); // bildname und halbe datei position
+			bilder->set( kpf->getTitel(), i ); // setzt titel
+			Punkt gr = kpf->getGröße();
+			kpf->release();
+			char p[ 5 ];
+			inF->read( (char *)p, 5 ); // andere hälfte der Dateiposition
+			unsigned __int64 position = ( ( (__int64)gr.x << 52 ) & 0xFFF0000000000000 ) |
+										( ( (__int64)gr.y << 40 ) & 0xFFF0000000000 ) |
+										( ( (__int64)p[ 0 ] << 32 ) & 0xFF00000000 ) |
+										( ( (__int64)p[ 1 ] << 24 ) & 0xFF000000 ) |
+										( ( (__int64)p[ 2 ] << 16 ) & 0xFF0000 ) |
+										( ( (__int64)p[ 3 ] << 8 ) & 0xFF00 ) |
+										( (__int64)p[ 4 ] & 0xFF );
+			pos->set( position, i ); // setzt position
+#ifdef WIN32
+			if( f )
+				f->aktionPlus();
+#endif
+		}
+	}
+}
+
+// constant
+void LTDBDateiKopf::speichern( std::ofstream *outF ) const
+{
+	if( outF->is_open() && outF->good() )
+	{
+		char b = bAnzahl >> 8;
+		outF->write( &b, 1 );
+		b = (char)bAnzahl;
+		outF->write( &b, 1 );
+		for( int i = 0; i < bAnzahl; ++i )
+		{
+			LTDBKopf *kpf = new LTDBKopf();
+			__int64 position = pos->get( i );
+			kpf->Init( bilder->get( i ), Punkt( position >> 52, position >> 40 ) );
+			kpf->speichern( outF );
+			kpf->release();
+			char p[] = { (char)( position >> 32 ), (char)( position >> 24 ), (char)( position >> 16 ), (char)( position >> 8 ), (char)( position ) };
+			outF->write( (char *)p, 5 );
+		}
+	}
+}
+
+Text *LTDBDateiKopf::getBild( int i ) const
+{
+	return bilder->get( i );
+}
+
+Text *LTDBDateiKopf::zBild( int i ) const
+{
+	return bilder->z( i );
+}
+
+__int64 LTDBDateiKopf::getBildPosition( Text *txt ) const
+{
+	int i = -1;
+	for( int ii = 0; ii < bAnzahl; ++ii )
+	{
+		Text *b = bilder->z( ii );
+		if( b->istGleich( txt->getText() ) )
+		{
+			i = ii;
+			break;
+		}
+	}
+	txt->release();
+	if( i == -1 )
+		return -1;
+	return pos->get( i );
+}
+
+__int64 LTDBDateiKopf::getBildPosition( int index ) const
+{
+	return pos->get( index );
+}
+
+int LTDBDateiKopf::getBildIndex( Text *txt ) const
+{
+	int i = -1;
+	for( int ii = 0; ii < bAnzahl; ++ii )
+	{
+		Text *b = bilder->z( ii );
+		if( b->istGleich( txt->getText() ) )
+		{
+			i = ii;
+			break;
+		}
+	}
+	txt->release();
+	return i;
+}
+
+int LTDBDateiKopf::getbAnzahl() const
+{
+	return bAnzahl;
+}
+
+RCArray< Text > *LTDBDateiKopf::zBildListe() const
+{
+	return bilder;
+}
+
+// Reference Counting 
+LTDBDateiKopf *LTDBDateiKopf::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDBDateiKopf *LTDBDateiKopf::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDBKopf Klasse aus DateiSystem.h
+// Konstruktor 
+LTDBKopf::LTDBKopf()
+	: ref( 1 )
+{
+}
+
+// nicht constant 
+void LTDBKopf::laden( std::ifstream *f ) // Lät die Daten aus einer Datei
+{
+	if( f->is_open() )
+	{
+		a = 0;
+		b = 0;
+		c = 0;
+		char aa = 0;
+		f->read( &aa, 1 );
+		int tl = ( aa >> 4 ) & Bits( 4 );
+		int BitAnzahl = 4 + tl * 5 + 24;
+		f->seekg( -1, std::ios::cur );
+		int Bytes = BitAnzahl / 8;
+		if( ( (float)BitAnzahl / 8.0f ) != Bytes )
+			++Bytes;
+		char byte = 0;
+		for( int i = 0; i < Bytes; ++i )
+		{
+			f->read( &byte, 1 );
+			setBits( i * 8, i * 8 + 8, byte );
+		}
+	}
+}
+
+int LTDBKopf::Init( Text *t, const Punkt &g ) // Befüllt die Daten
+{
+	a = 0;
+	b = 0;
+	c = 0;
+	int tl = t->getLänge();
+	if( tl > 15 )
+		tl = 15;
+	char *titel = new char[ tl ];
+	int übersp = 0;
+	for( int i = 0; i < tl; ++i )
+	{
+		titel[ i - übersp ] = t->getText()[ i ];
+		if( titel[ i - übersp ] > 96 && titel[ i - übersp ] < 123 )
+			titel[ i - übersp ] -= 96;
+		else if( titel[ i - übersp ] > 64 && titel[ i - übersp ] < 91 )
+			titel[ i - übersp ] -= 64;
+		else if( titel[ i - übersp ] == 'ü' || titel[ i - übersp ] == 'Ü' )
+			titel[ i - übersp ] = 27;
+		else if( titel[ i - übersp ] == 'ö' || titel[ i - übersp ] == 'Ö' )
+			titel[ i - übersp ] = 28;
+		else if( titel[ i - übersp ] == 'ä' || titel[ i - übersp ] == 'Ä' )
+			titel[ i - übersp ] = 29;
+		else if( titel[ i - übersp ] == 'ß' )
+			titel[ i - übersp ] = 30;
+		else if( titel[ i - übersp ] == '.' )
+			titel[ i - übersp ] = 31;
+		else
+			++übersp;
+	}
+	a = (__int64)( ( tl - übersp ) & Bits( 4 ) ) << 60;
+	int BeginBit = 4;
+	for( int i = 0; i < tl - übersp; ++i )
+	{
+		BeginBit += 5;
+		switch( i )
+		{
+		case 0:
+			a |= (__int64)( titel[ i ] & 31 ) << 55; // ersten Buchstaben speichern
+			break;
+		case 1:
+			a |= (__int64)( titel[ i ] & 31 ) << 50; // zweiten Buchstaben speichern
+			break;
+		case 2:
+			a |= (__int64)( titel[ i ] & 31 ) << 45; // dritten Buchstaben speichern
+			break;
+		case 3:
+			a |= (__int64)( titel[ i ] & 31 ) << 40; // vierten Buchstaben speichern
+			break;
+		case 4:
+			a |= (__int64)( titel[ i ] & 31 ) << 35; // fünften Buchstaben speichern
+			break;
+		case 5:
+			a |= (__int64)( titel[ i ] & 31 ) << 30; // sechsten Buchstaben speichern
+			break;
+		case 6:
+			a |= (__int64)( titel[ i ] & 31 ) << 25; // siebten Buchstaben speichern
+			break;
+		case 7:
+			a |= (__int64)( titel[ i ] & 31 ) << 20; // achten Buchstaben speichern
+			break;
+		case 8:
+			a |= (__int64)( titel[ i ] & 31 ) << 15; // neunten Buchstaben speichern
+			break;
+		case 9:
+			a |= (__int64)( titel[ i ] & 31 ) << 10; // zenten Buchstaben speichern
+			break;
+		case 10:
+			a |= (__int64)( titel[ i ] & 31 ) << 5; // elften Buchstaben speichern
+			break;
+		case 11:
+			a |= (__int64)( titel[ i ] & 31 ); // zwölften Buchstaben speichern
+			break;
+		case 12:
+			b |= (__int32)( titel[ i ] & 31 ) << 27; // dreizenten Buchstaben speichern
+			break;
+		case 13:
+			b |= (__int32)( titel[ i ] & 31 ) << 22; // vierzenten Buchstaben speichern
+			break;
+		case 14:
+			b |= (__int32)( titel[ i ] & 31 ) << 17; // fünfzenten Buchstaben speichern
+			break;
+		}
+	}
+	__int16 grx = g.x & Bits( 12 );
+	__int16 gry = g.y & Bits( 12 );
+	int EndBit = BeginBit + 24;
+	setBits( BeginBit, EndBit - 12, grx );
+	setBits( BeginBit + 12, EndBit, gry );
+	t->release();
+	delete[]titel;
+	return übersp;
+}
+
+void LTDBKopf::setBits( int BeginBit, int EndBit, __int16 bits )
+{
+	if( EndBit - BeginBit > 16 )
+		EndBit = BeginBit + 16;
+	if( BeginBit < 64 )
+	{
+		if( EndBit < 64 )
+		{
+			a |= ( (__int64)bits & Bits( EndBit - BeginBit ) ) << ( ( 64 - BeginBit ) - ( EndBit - BeginBit ) );
+		}
+		else
+		{
+			a |= ( ( (__int64)bits >> ( EndBit - 64 ) ) & Bits( 64 - BeginBit ) );
+			b |= ( (__int32)bits & Bits( EndBit - 64 ) ) << ( 32 - ( EndBit - 64 ) );
+		}
+	}
+	else
+	{
+		if( BeginBit < 96 )
+		{
+			if( EndBit < 96 )
+			{
+				b |= ( (__int32)bits & Bits( EndBit - BeginBit ) ) << ( ( 96 - BeginBit ) - ( EndBit - BeginBit ) );
+			}
+			else
+			{
+				b |= ( ( (__int32)bits >> ( EndBit - 96 ) ) & Bits( 96 - BeginBit ) );
+				c |= ( ( (__int8)bits & Bits( EndBit - 96 ) ) << ( 8 - ( EndBit - 96 ) ) );
+			}
+		}
+		else
+		{
+			c |= ( ( (__int8)bits & Bits( EndBit - BeginBit ) ) << ( 8 - ( EndBit - BeginBit ) ) );
+		}
+	}
+}
+
+// constant 
+void LTDBKopf::speichern( std::ofstream *f ) const // Speichert die Daten in eine Datei
+{
+	if( f->is_open() )
+	{
+		int bits = 4/*Titellänge*/ + getTitelLänge() * 5/*Titel*/ + 24/*Bildgröße*/;
+		int bytes = bits / 8; // Bytelänge des Dateikopfes
+		if( ( (float)bits / 8.0f ) != bytes )
+			++bytes;
+		char c = 0;
+		for( int i = 0; i < bytes; ++i )
+		{
+			c = (char)getBits( i * 8, i * 8 + 8 );
+			f->write( &c, 1 );
+		}
+	}
+}
+
+int LTDBKopf::getTitelLänge() const // gibt die länge des Bildnamens zurück
+{
+	return a >> 60 & Bits( 4 ); // Die Länge des Titels wird in den ersten 4 Bits der Tatei gespeichert
+}
+
+Text *LTDBKopf::getTitel() const // gibt den Namen des Bildes zurück
+{
+	Text *ret = new Text( "" );
+	char c[ 2 ];
+	c[ 1 ] = '\0';
+	int l = getTitelLänge();
+	for( int i = 0; i < l; ++i )
+	{
+		c[ 0 ] = 0;
+		switch( i )
+		{
+		case 0:
+			c[ 0 ] = ( a >> 55 ) & 31; // ersten Buchstaben holen
+			break;
+		case 1:
+			c[ 0 ] = ( a >> 50 ) & 31; // zweiten Buchstaben holen
+			break;
+		case 2:
+			c[ 0 ] = ( a >> 45 ) & 31; // dritten Buchstaben holen
+			break;
+		case 3:
+			c[ 0 ] = ( a >> 40 ) & 31; // vierten Buchstaben holen
+			break;
+		case 4:
+			c[ 0 ] = ( a >> 35 ) & 31; // fünften Buchstaben holen
+			break;
+		case 5:
+			c[ 0 ] = ( a >> 30 ) & 31; // sechsten Buchstaben holen
+			break;
+		case 6:
+			c[ 0 ] = ( a >> 25 ) & 31; // siebten Buchstaben holen
+			break;
+		case 7:
+			c[ 0 ] = ( a >> 20 ) & 31; // achten Buchstaben holen
+			break;
+		case 8:
+			c[ 0 ] = ( a >> 15 ) & 31; // neunten Buchstaben holen
+			break;
+		case 9:
+			c[ 0 ] = ( a >> 10 ) & 31; // zenten Buchstaben holen
+			break;
+		case 10:
+			c[ 0 ] = ( a >> 5 ) & 31; // elften Buchstaben holen
+			break;
+		case 11:
+			c[ 0 ] = a & 31; // zwölften Buchstaben holen
+			break;
+		case 12:
+			c[ 0 ] = ( b >> 27 ) & 31; // dreizenten Buchstaben holen
+			break;
+		case 13:
+			c[ 0 ] = ( b >> 22 ) & 31; // vierzenten Buchstaben holen
+			break;
+		case 14:
+			c[ 0 ] = ( b >> 17 ) & 31; // fünfzenten Buchstaben holen
+			break;
+		}
+		if( c[ 0 ] == 27 )
+			c[ 0 ] = 'ü';
+		else if( c[ 0 ] == 28 )
+			c[ 0 ] = 'ö';
+		else if( c[ 0 ] == 29 )
+			c[ 0 ] = 'ä';
+		else if( c[ 0 ] == 30 )
+			c[ 0 ] = 'ß';
+		else if( c[ 0 ] == 31 )
+			c[ 0 ] = '.';
+		else
+			c[ 0 ] += 96;
+		ret->anhängen( c );
+	}
+	return ret;
+}
+
+Punkt LTDBKopf::getGröße() const // gibt die Größe des Bildes zurück
+{
+	int BeginBit = 4/*Titellänge*/ + getTitelLänge() * 5/*Titel*/;
+	int EndBit = BeginBit + 24;
+	__int16 grx = getBits( BeginBit, EndBit - 12 );
+	__int16 gry = getBits( BeginBit + 12, EndBit );
+	return Punkt( (int)( grx & Bits( 12 ) ), (int)( gry & Bits( 12 ) ) );
+}
+
+__int16 LTDBKopf::getBits( int begin, int ende )const // gibt die Bits von begin bis ende zurück( ohne ende );
+{
+	if( ende < begin )
+		return 0;
+	if( ende - begin > 16 )
+		ende = begin + 16;
+	__int16 ret = 0;
+	if( begin < 64 )
+	{
+		if( ende < 64 )
+		{
+			ret = (__int16)( a >> ( ( 64 - begin ) - ( ende - begin ) ) & Bits( ende - begin ) );
+		}
+		else
+		{
+			ret = (__int16)( ( a & Bits( 64 - begin ) ) << ( ende - 64 ) );
+			ret |= (__int16)( ( b >> ( 32 - ( ende - 64 ) ) ) & Bits( ende - 64 ) );
+		}
+	}
+	else
+	{
+		if( begin < 96 )
+		{
+			if( ende < 96 )
+			{
+				ret = (__int16)( b >> ( ( 96 - begin ) - ( ende - begin ) ) & Bits( ende - begin ) );
+			}
+			else
+			{
+				ret = (__int16)( ( b & Bits( 96 - begin ) ) << ( ende - 96 ) );
+				ret |= (__int16)( ( c >> ( 8 - ( ende - 96 ) ) ) & Bits( ende - 96 ) );
+			}
+		}
+		else
+		{
+			ret = (__int16)( c >> ( ( 104 - begin ) - ( ende - begin ) ) & Bits( ende - begin ) );
+		}
+	}
+	return ret;
+}
+
+// Reference Counting 
+LTDBKopf *LTDBKopf::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDBKopf *LTDBKopf::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDBKörper Klasse aus Dateisystem.h
+// Konstruktor 
+LTDBKörper::LTDBKörper()
+	: gr( 0, 0 ),
+	  b( new Bild() ),
+	  ref( 1 )
+{
+}
+
+LTDBKörper::LTDBKörper( LTDBKopf *k ) // ruft Init auf
+	: gr( 0, 0 ),
+	  b( new Bild() ),
+	  ref( 1 )
+{
+	init( k );
+}
+
+// Destruktor 
+LTDBKörper::~LTDBKörper()
+{
+	b->release();
+}
+
+// nicht constant
+void LTDBKörper::init( LTDBKopf k ) // Initialisiert, wird vor dem laden benötigt 
+{
+	gr = k.getGröße();
+	int l = k.getTitelLänge();
+	l = 4 + l * 5 + 24;
+	dateiLänge = ( l / 8.0 == l ) ? ( l / 8 ) : ( l / 8 + 1 );
+}
+
+void LTDBKörper::init( LTDBKopf *k ) // Initialisiert, wird vor dem laden benötigt
+{
+	gr = k->getGröße();
+	int l = k->getTitelLänge();
+	l = 4 + l * 5 + 24;
+	dateiLänge = ( l / 8.0 == l ) ? ( l / 8 ) : ( l / 8 + 1 );
+	k->release();
+}
+
+void LTDBKörper::laden( FBalken *zF, std::ifstream *inF ) // läd das Bild
+{
+	b->neuBild( gr.x, gr.y, 0xFF000000 ); // neues Bild erstellen
+	int *buff = b->getBuffer();
+	int breite = b->getBreite();
+	char byte = 0;
+	int index = 0;
+	LTDBPixel *davor = 0; // zuletzt geladener Pixel
+	LTDBPixel *dieser = new LTDBPixel( 0 ); // momentan zu ladener Pixel
+	int begin = 0; // Pixelbegin, endposition in der byte variable
+#ifdef WIN32
+	if( zF )
+	{
+		zF->reset();
+		zF->setAktionAnzahl( gr.x * gr.y );
+	}
+#endif
+	while( index < gr.x * gr.y ) // für jeden Pixel
+	{
+		if( !dieser ) // wenn es nicht der erste Pixel ist
+			dieser = new LTDBPixel( davor->getThis() );
+		int ende = -1;
+		while( ende < 0 ) // Pixel laden
+		{
+			if( begin == 0 )
+				inF->read( &byte, 1 );
+			ende = dieser->addByte( byte, begin ); // byte auswerten
+			begin = 0;
+		}
+		begin = ende;
+		if( begin == 8 )
+			begin = 0;
+		buff[ ( index % gr.x ) + ( index / gr.x ) * breite ] = dieser->zuFarbe();
+		if( davor )
+			davor = davor->release();
+		davor = dieser->getThis();
+		dieser = dieser->release();
+		++index;
+#ifdef WIN32
+		if( zF )
+			zF->aktionPlus();
+#endif
+	}
+	if( davor )
+		davor = davor->release();
+}
+
+void LTDBKörper::setBild( Bild *b ) // setzt das zu speichernde Bild
+{
+	this->b->release();
+	this->b = b;
+}
+
+// constant 
+void LTDBKörper::speichern( FBalken *zF, std::ofstream *outF ) const // speichert Bild
+{
+	if( outF->is_open() )
+	{
+		LTDBPixel *letzter = 0; // Letzter gespeicherter Pixel
+		LTDBPixel *dieser = new LTDBPixel( 0 ); // Der momentan zu speichernde Pixel
+		int begin = 0, ende = 0; // Pixelbeginn, endposition in der byte variable
+		char byte = 0; // Der nächste byte der Datei
+		bool w = 0;
+#ifdef WIN32
+		if( zF )
+		{
+			zF->reset();
+			zF->setAktionAnzahl( gr.x * gr.y );
+		}
+#endif
+		int *pBuff = b->getBuffer();
+		for( int i = 0; i < gr.x * gr.y; ++i ) // für jeden Pixel
+		{
+			if( !dieser ) // wenn es nicht der erste Pixel ist
+				dieser = new LTDBPixel( letzter->getThis() );
+			dieser->setFarbe( pBuff[ i ] ); // Farbe des Pixels setzen
+			dieser->komprimieren(); // Pixel komprimieren
+			ende = -1;
+			while( ende < 0 ) // byte befüllen
+			{
+				ende = dieser->getNextByte( byte, begin );
+				begin = 0;
+				w = 0;
+				if( ende == -1 || ende == 8 ) // byte speichern
+				{
+					outF->write( &byte, 1 );
+					w = 1;
+					byte = 0;
+				}
+			} // Pixel fertig
+			begin = ende;
+			if( begin == 8 )
+				begin = 0;
+			if( letzter )
+				letzter->release();
+			letzter = dieser->getThis(); // dieser wird zu letzter
+			dieser = dieser->release();
+#ifdef WIN32
+			if( zF )
+				zF->aktionPlus();
+#endif
+		}
+		if( letzter )
+			letzter = letzter->release();
+		if( !w )
+		{
+			outF->write( &byte, 1 ); // Das letzte byte speichern
+		}
+		outF->flush(); // dateistream speichern
+	}
+}
+
+Bild *LTDBKörper::getBild() const // gibt das geladene Bild zurück
+{
+	return b->getThis();
+}
+
+const Punkt &LTDBKörper::getGröße() const // gibt die größe des Bildes zurück
+{
+	return gr;
+}
+
+// Reference Counting
+LTDBKörper *LTDBKörper::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDBKörper *LTDBKörper::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+
+// Inhalt det LTDBDatei Klasse aus Dateisystem.h
+// Konstruktor 
+LTDBDatei::LTDBDatei()
+	: pfad( new Text() ),
+	  datKpf( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+LTDBDatei::~LTDBDatei()
+{
+	if( pfad )
+		pfad->release();
+	if( datKpf )
+		datKpf->release();
+}
+
+// nicht constant 
+void LTDBDatei::setDatei( Text *pfad ) // Setzt den Pfad zur Datei
+{ // Werte der eventuellen vorherigen Datei löschen
+	if( datKpf )
+		datKpf = datKpf->release();
+	// Pfad setzen
+	this->pfad->setText( pfad->getThis() );
+	pfad->release();
+}
+
+void LTDBDatei::erstellen() // Erstellt die Datei
+{
+	DateiPfadErstellen( pfad->getThis() );
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary );
+	int i = 0;
+	outF->write( (char *)&i, 2 );
+	delete outF;
+}
+
+void LTDBDatei::leseDaten( FBalken *f ) // Die Klasse ließt alle Bilder kurz ein, und merkt sich, an welcher stelle in der Datei was ist
+{ // Diese Funktion wird ein wenig Zeit in Anspruch nemen, dafüraber danach die anderen schneller machen
+	if( DateiExistiert( pfad->getThis() ) )
+	{
+		if( datKpf )
+			datKpf->release();
+		datKpf = new LTDBDateiKopf();
+		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+		datKpf->laden( f, inF );
+		delete inF;
+	}
+}
+
+void LTDBDatei::löschen() // Löscht die Datei
+{
+	if( DateiExistiert( pfad->getThis() ) )
+	{
+		DateiLöschen( pfad->getThis() );
+		if( datKpf )
+			datKpf->release();
+	}
+}
+
+void LTDBDatei::löschen( FBalken *f, Text *name ) // Löscht ein Bild aus der Datei
+{
+	if( DateiExistiert( pfad->getThis() ) && name )
+	{
+		if( !datKpf )
+			leseDaten( 0 ); // Daten einlesen
+		// Prüfen, ob Datei nicht vorhanden
+		if( !datKpf )
+		{
+			name->release();
+			return;
+		}
+		int index = datKpf->getBildIndex( name->getThis() );
+		if( index == -1 ) // das bild existiert nicht
+		{
+			name->release();
+			return;
+		}
+		// Zwischenspeicherpfad ermitteln
+		Text *pf_tmp = new Text( pfad->getText() );
+		char c = '0';
+		pf_tmp->anhängen( "0" );
+		for( int i = 0; DateiExistiert( pf_tmp->getThis() ); ++i )
+		{
+			c = '0' + ( i % 10 );
+			if( ( i % 10 ) == 0 )
+				pf_tmp->anhängen( "$" );
+			pf_tmp->ersetzen( pf_tmp->anzahlVon( '0' - ( ( i - 1 ) % 10 ) ) - 1, '0' - ( ( i - 1 ) % 10 ), c );
+		}
+		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // Alte Datei öffnen
+		inF->seekg( 0, std::ios::end );
+		__int64 Datlän = inF->tellg();
+		inF->seekg( 0, std::ios::beg );
+		std::ofstream *outF = new std::ofstream( pf_tmp->getText(), std::ios::binary ); // Neue Datei öffnen
+		if( inF->is_open() && outF->is_open() )
+		{
+			__int64 position = datKpf->getBildPosition( index );
+			datKpf->removeBild( index );
+			datKpf->speichern( outF );
+			LTDBDateiKopf *kpf_tmp = new LTDBDateiKopf();
+			kpf_tmp->laden( 0, inF );
+			kpf_tmp->release();
+			char byte = 0;
+			__int64 pos_minus = inF->tellg() - outF->tellp();
+			for( int i = 0; i < index; ++i )
+				datKpf->setBildPos( i, datKpf->getBildPosition( i ) - pos_minus );
+			// Bytes bis zur Datei kopieren
+			for( __int64 i = inF->tellg(); i < position; ++i )
+			{
+				inF->read( &byte, 1 );
+				outF->write( &byte, 1 );
+			} // zu löschendes Bild überspringen
+			LTDBKopf *delkpf = new LTDBKopf();
+			delkpf->laden( inF );
+			LTDBKörper *delkpr = new LTDBKörper( delkpf->getThis() );
+			delkpr->laden( f, inF );
+			delkpf = delkpf->release();
+			delkpr = delkpr->release(); // restliche bytes kopieren
+			pos_minus = inF->tellg() - outF->tellp();
+			for( __int64 i = (__int64)inF->tellg(); i < Datlän; ++i )
+			{
+				inF->read( &byte, 1 );
+				outF->write( &byte, 1 );
+			}
+			for( int i = index; i < datKpf->getbAnzahl(); ++i )
+				datKpf->setBildPos( i, datKpf->getBildPosition( i ) - pos_minus );
+			outF->seekp( 0, std::ios::beg );
+			datKpf->speichern( outF );
+			inF->close();
+			outF->close();
+			DateiLöschen( pfad->getThis() );
+			DateiUmbenennen( pf_tmp->getThis(), pfad->getThis() );
+		}
+		delete inF;
+		delete outF;
+		pf_tmp = pf_tmp->release();
+	}
+	if( name )
+		name = name->release();
+}
+
+Bild *LTDBDatei::laden( FBalken *f, Text *name ) // Läd ein Bild aus der Datei
+{
+	if( name )
+	{
+		if( !DateiExistiert( pfad->getThis() ) )
+		{
+			name->release();
+			return 0;
+		}
+		if( !datKpf )
+			leseDaten( 0 );
+		LTDBKopf *k_tmp = new LTDBKopf();
+		k_tmp->Init( name->getThis(), Punkt( 0, 0 ) );
+		int index = datKpf->getBildIndex( k_tmp->getTitel() );
+		k_tmp->release();
+		if( index == -1 )
+		{ // Fehlermeldung 
+			Text *fehler = new Text( "Das Bild " );
+			fehler->anhängen( name );
+			fehler->anhängen( " wurde nicht in der Datei\n" );
+			fehler->anhängen( pfad->getThis() );
+			fehler->anhängen( " gefunden!" );
+            std::cout << fehler << "\n";
+			return 0;
+		}
+		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+		// Begin der zu ladenden Datei ermitteln
+		__int64 position = datKpf->getBildPosition( index );
+		inF->seekg( position, std::ios::beg );
+		LTDBKopf *kpf = new LTDBKopf();
+		kpf->laden( inF );
+		Text *t = kpf->getTitel();
+		if( !t->istGleich( name->getThis() ) )
+		{ // Fehlermeldung 
+			t->release();
+			kpf->release();
+			inF->close();
+			delete inF;
+			Text *fehler = new Text( "Die Datei " );
+			fehler->anhängen( pfad );
+			fehler->anhängen( " ist ist keine gültige LTDB Datei!" );
+#ifdef WIN32
+			WMessageBox( 0, new Text( "Fehler" ), fehler, MB_ICONERROR );
+#endif
+			name->release();
+			return 0;
+		}
+		t->release();
+		LTDBKörper *kpr = new LTDBKörper( kpf->getThis() );
+		kpr->laden( f, inF ); // Bild laden
+		Bild *ret = kpr->getBild();
+		kpr->release();
+		kpf->release();
+		inF->close();
+		delete inF;
+		name->release();
+		return ret;
+	}
+	return 0;
+}
+
+int LTDBDatei::speichern( FBalken *f, Bild *bild, Text *name ) // Speichert ein Bild in die Datei
+{
+	int warn = -1;
+	if( name && bild )
+	{
+		if( DateiExistiert( pfad->getThis() ) )
+		{
+			if( !datKpf )
+				leseDaten( 0 );
+			int index = datKpf->getBildIndex( name->getThis() );
+			if( index == -1 )
+			{
+				warn = 0;
+				LTDBKopf *kpf = new LTDBKopf();
+				warn = kpf->Init( name->getThis(), bild->getGröße() );
+				if( datKpf->getBildIndex( kpf->getTitel() ) != -1 )
+				{
+					std::cout << "Es existiert bereits ein Bild mit diesem Namen!\n";
+					bild->release();
+					name->release();
+					kpf->release();
+					return -1;
+				}
+				// zwischendateipfad suchen
+				Text *pf_tmp = new Text( pfad->getText() );
+				char c = '0';
+				pf_tmp->anhängen( "0" );
+				for( int i = 0; DateiExistiert( pf_tmp->getThis() ); ++i )
+				{
+					c = '0' + ( i % 10 );
+					if( ( i % 10 ) == 0 )
+						pf_tmp->anhängen( "$" );
+					pf_tmp->ersetzen( pf_tmp->anzahlVon( '0' - ( ( i - 1 ) % 10 ) ) - 1, '0' - ( ( i - 1 ) % 10 ), c );
+				}
+				std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+				inF->seekg( 0, std::ios::end );
+				__int64 datLen = inF->tellg();
+				inF->seekg( 0, std::ios::beg );
+				std::ofstream *outF = new std::ofstream( pf_tmp->getText(), std::ios::binary );
+				datKpf->addBild( kpf->getTitel() );
+				index = datKpf->getBildIndex( kpf->getTitel() );
+				datKpf->speichern( outF );
+				LTDBDateiKopf *kpf_tmp = new LTDBDateiKopf();
+				kpf_tmp->laden( 0, inF );
+				kpf_tmp->release();
+				__int64 pos_plus = outF->tellp() - inF->tellg();
+				for( int i = 0; i < index; ++i )
+					datKpf->setBildPos( i, datKpf->getBildPosition( i ) + pos_plus );
+				datKpf->setBildPos( index, datLen + pos_plus );
+				outF->seekp( 0, std::ios::beg );
+				datKpf->speichern( outF );
+				char byte = 0;
+				for( __int64 i = inF->tellg(); i < datLen; ++i )
+				{
+					inF->read( &byte, 1 );
+					outF->write( &byte, 1 );
+				}
+				kpf->speichern( outF ); // Bild Kopf speichern
+				LTDBKörper *kpr = new LTDBKörper( kpf->getThis() );
+				kpr->setBild( bild->getThis() );
+				kpr->speichern( f, outF ); // Bild speichern
+				kpf->release();
+				kpr->release();
+				inF->close();
+				outF->close();
+				delete inF;
+				delete outF;
+				DateiLöschen( pfad->getThis() );
+				DateiUmbenennen( pf_tmp, pfad->getThis() );
+			}
+		}
+	}
+	if( name )
+		name->release();
+	if( bild )
+		bild->release();
+	return warn;
+}
+
+RCArray< Text > *LTDBDatei::zBildListe() // Listet alle Bilder in der datei auf
+{
+	if( !datKpf )
+		leseDaten( 0 );
+	if( datKpf )
+		return datKpf->zBildListe();
+	return 0;
+}
+
+// constant 
+Text *LTDBDatei::getPfad() const // Gibt den Pfad zur Datei zurück
+{
+	return pfad->getThis();
+}
+
+int LTDBDatei::getBildAnzahl() const
+{
+	if( !datKpf )
+		return 0;
+	return datKpf->getbAnzahl();
+}
+
+bool LTDBDatei::istOffen() const // Prüft, ob die Datei geöffnet ist
+{
+	if( !pfad )
+		return 0;
+	return DateiExistiert( pfad->getThis() );
+}
+
+// Reference Counting
+LTDBDatei *LTDBDatei::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDBDatei *LTDBDatei::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+#ifdef WIN32
+// LTDS Dateivormat 
+// Inhalt der LTDSPixel Klasse aus DateiSystem.h
+// Konstruktor 
+LTDSPixel::LTDSPixel( LTDSPixel *davor )
+	: ref( 1 ),
+	  index( 0 ),
+	  iA( 0 ),
+	  miA( 8 ),
+	  maxIndex( 1 ),
+	  änder( 0 ),
+	  änderA( 0 ),
+	  komp( 0 ),
+	  alpha( 0 ),
+	  davor( davor )
+{
+}
+
+// Destruktor 
+LTDSPixel::~LTDSPixel()
+{
+	if( davor )
+		davor->release();
+}
+
+// nicht constant 
+// zum Laden gedacht 
+bool LTDSPixel::addBitZuFarbe( unsigned char bit )
+{
+	if( änderA && iA != miA ) // Das Bit gehört zu Alpha
+	{
+		alpha |= ( ( bit & Bits( 1 ) ) ) << ( 7 - komp - iA );
+		++iA;
+	}
+	else // Das Bit gehört zum nächsten Pixel
+		return false;
+	return true;
+}
+
+char LTDSPixel::addByte( char byte, char begin ) // gibt ende des Pixels zurück, -1 wenn nicht zu ende
+{
+	if( begin >= 8 || begin < 0 )
+		return -1;
+	for( int i = begin; i < 8; ++i )
+	{
+		switch( index )
+		{
+		case 0:
+			// Das erste Bit eines Pixels speichert, ob sich an der Komprimierung etwas änderte
+			änder = ( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) == 1;
+			if( !änder ) // Ändert sich nichts an der Komprimierung, so werden die Werte vom vorherigen Pixel übernommen
+			{
+				if( !davor ) // Die Datei ist beschädigt ( Der erste Pixel kann nicht von dem davor Übernemen )
+				{
+					MessageBox( NULL, "Fehler, die Bilddatei ist beschädigt", "Fehler", MB_ICONERROR );
+					exit( 0 );
+				}
+				änderA = davor->getÄnderA();
+				komp = davor->getKomp();
+				miA -= komp;
+				if( !änderA )
+					alpha = davor->getA();
+				maxIndex += änderA * ( 8 - komp ); // Bestimmung der Länge
+				// des Pixels in Bits. Jede Farbe hat von grund auf 8 Bits, durch komprimierung kanns kleiner sein
+			}
+			else
+				maxIndex += 4; // Da der Pixel nicht die Werte des vorherigen übernimmt, wird er um 4 Bits größer
+			break;
+		case 1: // Das zweite Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 4 Komprimierungsbits
+				änderA = ( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) == 1;
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 2: // Das sechste Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 4 Komprimierungsbits
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) << 2;
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 3: // Das siebte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 4 Komprimierungsbits
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) ) << 1;
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		case 4: // Das achte Bit eines Pixels speichert entweder die Komprimierungsart, oder schon die Farbe
+			if( änder ) // Das Bit gehört zu den 4 Komprimierungsbits
+			{
+				komp |= (unsigned char)( ( byte >> ( 7 - i ) ) & Bits( 1 ) );
+				// Das war das letzte Komprimierungsbit
+				// Komprimierung auswerten 
+				miA -= komp;
+				if( !änderA )
+					alpha = davor->getA();
+				maxIndex += änderA * ( 8 - komp ); // Bitlänge des Pixels
+			}
+			else
+			{
+				if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+					return i;
+			}
+			break;
+		default: // Die restlichen Bits speichern alle die Farbwerte des Pixels
+			if( !addBitZuFarbe( byte >> ( 7 - i ) ) ) // Das Bit gehört zur Farbe
+				return i;
+			break;
+		}
+		++index;
+		if( index >= maxIndex )
+		{
+			if( davor )
+			{
+				if( änderA )
+					alpha = davor->getA() + alpha;
+				davor = davor->release();
+			}
+			return i + 1;
+		}
+	}
+	return -1;
+}
+
+// zum speichern gedacht 
+void LTDSPixel::setAlpha( unsigned char alpha ) // setzt die Farbe des Pixels
+{
+	this->alpha = alpha;
+}
+
+void LTDSPixel::Komp() // Komprimiert den Pixel
+{
+	maxIndex = 1;
+	if( !davor )
+	{// Das ist der erste Pixel
+		änder = 1;
+		änderA = 1;
+		maxIndex += 4;
+		miA = getBits( alpha );
+	}
+	else
+	{ // Es wird die differenz zum vorrigen Pixel gespeichert
+		miA = getBits( alpha - davor->getA() );
+		if( alpha != davor->getA() )
+			änderA = 1;
+		else
+			änderA = 0;
+	}// Prüfen ob sich etwas ändert
+	if( !miA && änderA )
+		++miA;
+	komp = 8 - miA;
+	maxIndex += änderA * miA;
+	if( davor )
+	{
+		if( änderA != davor->getÄnderA() ||
+			komp != davor->getKomp() )
+		{ // Es ändert sich etwas
+			änder = 1;
+			maxIndex += 4;
+		}
+		else
+		{ // Es ändert sich nichts
+			änder = 0;
+		}
+	}
+}
+
+bool LTDSPixel::getNextFarbeBit( char &byte, int i )
+{
+	unsigned char AA = alpha;
+	if( davor )
+	{
+		AA -= davor->getA();
+	}
+	if( änderA && iA != miA ) // Das Bit gehört zu Alpha
+	{
+		byte |= ( ( AA >> ( 7 - komp - iA ) ) & Bits( 1 ) ) << ( 7 - i );
+		++iA;
+	}
+	else // Der Pixel ist bereits zu ende
+		return false;
+	return true;
+}
+
+char LTDSPixel::getNextByte( char &byte, int bbegin ) // Gibt die nächsten Bits Zurück, -1 wenn der Pixel nicht zu ende ist
+{
+	// bbegin gibt an wohin in die byte-variable geschrieben werden soll
+	// die Funktion gibt das ende des Pixels in der byte-variable zurück
+	// -1 heißt, dass der Pixel nicht zu ende ist
+	for( int i = bbegin; i < 8; ++i )
+	{
+		switch( index )
+		{
+		case 0: // Das erste Bit des Pixels speichert, ob sich etwas an der Komprimierung ändert
+			byte |= ( (int)änder & Bits( 1 ) ) << ( 7 - i );
+			break;
+		case 1: // Das zweite Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( (int)änderA & Bits( 1 ) ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 2: // Das zweite Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( ( komp >> 2 ) & Bits( 1 ) ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 3: // Das dritte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( ( komp >> 1 ) & Bits( 1 ) ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		case 4: // Das vierte Bit des Pixels speichert entweder schon die Farbe oder die Komprimierung
+			if( änder ) // Komprimierung
+				byte |= ( komp & Bits( 1 ) ) << ( 7 - i );
+			else // Farbe
+			{
+				if( !getNextFarbeBit( byte, i ) )
+					return i;
+			}
+			break;
+		default: // Die restlichen Bits speichern die Farbe des Pixels
+			if( !getNextFarbeBit( byte, i ) )
+				return i;
+			break;
+		}
+		++index;
+		if( index >= maxIndex )
+		{
+			if( davor )
+				davor = davor->release();
+			return i + 1;
+		}
+	}
+	return -1;
+}
+
+// constant 
+unsigned char LTDSPixel::getKomp() const // hat sich die Komprimierung geändert
+{
+	return komp;
+}
+
+bool LTDSPixel::getÄnderA() const // gibt zurück, ob sich der alphawert ändert
+{
+	return änderA;
+}
+
+unsigned char LTDSPixel::getA() const // gibt Alpha zurück
+{
+	return alpha;
+}
+
+// Reference Counting 
+LTDSPixel *LTDSPixel::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSPixel *LTDSPixel::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDSDateiKopf Klasse aus Dateisystem.h
+// Konstruktor 
+LTDSDateiKopf::LTDSDateiKopf()
+	: ref( 1 ),
+	  sganzahl( 0 ),
+	  gr( 0 ),
+	  pos( 0 )
+{
+}
+
+// Destruktor 
+LTDSDateiKopf::~LTDSDateiKopf()
+{
+	delete[]gr;
+	delete[]pos;
+}
+
+// nicht constant 
+void LTDSDateiKopf::laden( std::ifstream *inF ) // Lät aus inF
+{
+	if( inF->good() && inF->is_open() )
+	{
+		inF->read( (char *)&sganzahl, 1 );
+		delete[]gr;
+		delete[]pos;
+		gr = new unsigned char[ sganzahl + 1 ];
+		pos = new int[ sganzahl + 1 ];
+		gr[ sganzahl ] = 0;
+		pos[ sganzahl ] = 0;
+		for( int i = 0; i < sganzahl; ++i )
+		{
+			inF->read( (char*)&gr[ i ], 1 );
+			inF->read( (char*)&pos[ i ], 4 );
+		}
+	}
+}
+
+void LTDSDateiKopf::addSG( char sg ) // Schriftgröße hinzufügen
+{
+	++sganzahl;
+	unsigned char *gr_tmp = gr;
+	int *pos_tmp = pos;
+	gr = new unsigned char[ sganzahl + 1 ];
+	pos = new int[ sganzahl + 1 ];
+	gr[ sganzahl ] = 0;
+	pos[ sganzahl ] = 0;
+	if( sganzahl - 1 > 0 )
+	{
+		memcpy( gr, gr_tmp, 1 * ( sganzahl - 1 ) );
+		memcpy( pos, pos_tmp, 4 * ( sganzahl - 1 ) );
+	}
+	delete[]gr_tmp;
+	delete[]pos_tmp;
+	pos[ sganzahl - 1 ] = 0;
+	gr[ sganzahl - 1 ] = sg;
+}
+
+void LTDSDateiKopf::removeSG( char sg ) // Schriftgröße entfernen
+{
+	bool hatsg = 0;
+	int sgpos = 0;
+	for( int i = 0; i < sganzahl; ++i )
+	{
+		hatsg = gr[ i ] == sg;
+		sgpos = i;
+		if( hatsg )
+			break;
+	}
+	if( hatsg )
+	{
+		--sganzahl;
+		unsigned char *gr_tmp = gr;
+		int *pos_tmp = pos;
+		gr = new unsigned char[ sganzahl + 1 ];
+		pos = new int[ sganzahl + 1 ];
+		gr[ sganzahl ] = 0;
+		pos[ sganzahl ] = 0;
+		for( int i = 0; i < sgpos; ++i )
+		{
+			gr[ i ] = gr_tmp[ i ];
+			pos[ i ] = pos_tmp[ i ];
+		}
+		for( int i = sgpos + 1; i < sganzahl; ++i )
+		{
+			gr[ i - 1 ] = gr_tmp[ i ];
+			pos[ i - 1 ] = pos_tmp[ i ];
+		}
+		delete[]gr_tmp;
+		delete[]pos_tmp;
+	}
+}
+
+// constant 
+void LTDSDateiKopf::speichern( std::ofstream *outF ) const // Speichert nach outF
+{
+	if( outF->is_open() && outF->good() )
+	{
+		outF->write( (char*)&sganzahl, 1 );
+		for( int i = 0; i < sganzahl; ++i )
+		{
+			outF->write( (char*)&gr[ i ], 1 );
+			outF->write( (char*)&pos[ i ], 4 );
+		}
+	}
+}
+
+unsigned char *LTDSDateiKopf::getSchriftGrößeList() const // gibt eine Liste mit gespeicherten Schriftgrößen zurück
+{
+	return gr;
+}
+
+int *LTDSDateiKopf::getPositionList() const // gibt eine Positionsliste der gespeicherten Schriftgrößen zurück
+{
+	return pos;
+}
+
+int LTDSDateiKopf::getSchriftGrößeAnzahl() const // gibt die Anzahl der gespeicherten Schriftgrößen zurück
+{
+	return sganzahl;
+}
+
+// Reference Counting 
+LTDSDateiKopf *LTDSDateiKopf::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSDateiKopf *LTDSDateiKopf::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDSSchriftKopf Klasse aus Dateisystem.h
+// Konstruktor 
+LTDSSchriftKopf::LTDSSchriftKopf()
+	: ref( 1 ),
+	  schriftGröße( 0 ),
+	  zeichen( 0 ),
+	  pos( 0 ),
+	  zeichenAnzahl( 0 )
+{
+}
+
+// Destruktor 
+LTDSSchriftKopf::~LTDSSchriftKopf()
+{
+	delete[]pos;
+	delete[]zeichen;
+}
+
+// nicht constant 
+void LTDSSchriftKopf::laden( std::ifstream *inF ) // läht von inF
+{
+	if( inF->good() && inF->is_open() )
+	{
+		inF->read( (char*)&schriftGröße, 1 );
+		inF->read( (char*)&zeichenAnzahl, 1 );
+		delete[]pos;
+		delete[]zeichen;
+		zeichen = new unsigned char[ zeichenAnzahl ];
+		pos = new int[ zeichenAnzahl + 1 ];
+		for( int i = 0; i < zeichenAnzahl; ++i )
+		{
+			inF->read( (char*)&zeichen[ i ], 1 );
+			inF->read( (char*)&pos[ i ], 4 );
+		}
+		pos[ zeichenAnzahl ] = 0;
+	}
+}
+
+void LTDSSchriftKopf::setSchriftgröße( unsigned char gr ) // setze schriftgröße
+{
+	schriftGröße = gr;
+}
+
+void LTDSSchriftKopf::setZeichenAlphabet( Alphabet *alphabet ) // setzt die Zeichen von alphabet
+{
+	int count = 0;
+	for( int i = 0; i < 256; ++i )
+	{
+		Buchstabe *zeich = alphabet->zBuchstabe( i );
+		if( zeich )
+			++count;
+	}
+	delete[]zeichen;
+	delete[]pos;
+	zeichen = new unsigned char[ count ];
+	pos = new int[ count + 1 ];
+	pos[ count ] = 0;
+	zeichenAnzahl = count;
+	count = 0;
+	for( int i = 0; i < 256; ++i )
+	{
+		Buchstabe *zeich = alphabet->getBuchstabe( i );
+		if( zeich )
+		{
+			zeichen[ count ] = i;
+			pos[ count ] = 0;
+			++count;
+			zeich->release();
+		}
+	}
+	schriftGröße = alphabet->getSchriftgröße();
+	alphabet->release();
+}
+
+void LTDSSchriftKopf::addZeichen( unsigned char zeichen ) // Zeichen hinzufügen
+{
+	++zeichenAnzahl;
+	unsigned char *zeichen_tmp = this->zeichen;
+	int *pos_tmp = pos;
+	this->zeichen = new unsigned char[ zeichenAnzahl ];
+	pos = new int[ zeichenAnzahl + 1 ];
+	if( zeichenAnzahl - 1 > 0 )
+	{
+		memcpy( this->zeichen, zeichen_tmp, 1 * ( zeichenAnzahl - 1 ) );
+		memcpy( pos, pos_tmp, 4 * ( zeichenAnzahl - 1 ) );
+	}
+	delete[]zeichen_tmp;
+	delete[]pos_tmp;
+	this->zeichen[ zeichenAnzahl - 1 ] = zeichen;
+	pos[ zeichenAnzahl - 1 ] = 0;
+	pos[ zeichenAnzahl ] = 0;
+}
+
+void LTDSSchriftKopf::removeZeichen( unsigned char zeich ) // Zeichen entfernen
+{
+	bool hatZ = 0;
+	int zPos = 0;
+	for( int i = 0; i < zeichenAnzahl; ++i )
+	{
+		hatZ = zeichen[ i ] == zeich;
+		zPos = i;
+		if( hatZ )
+			break;
+	}
+	if( hatZ )
+	{
+		--zeichenAnzahl;
+		unsigned char *zeichen_tmp = zeichen;
+		int *pos_tmp = pos;
+		zeichen = new unsigned char[ zeichenAnzahl ];
+		pos = new int[ zeichenAnzahl + 1 ];
+		for( int i = 0; i < zPos; ++i )
+		{
+			zeichen[ i ] = zeichen_tmp[ i ];
+			pos[ i ] = pos_tmp[ i ];
+		}
+		for( int i = zPos + 1; i <= zeichenAnzahl; ++i )
+		{
+			zeichen[ i - 1 ] = zeichen_tmp[ i ];
+			pos[ i - 1 ] = pos_tmp[ i ];
+		}
+		pos[ zeichenAnzahl ] = 0;
+		delete[]zeichen_tmp;
+		delete[]pos_tmp;
+	}
+}
+
+// constant 
+void LTDSSchriftKopf::speichern( std::ofstream *outF ) const // speichert nach outF
+{
+	if( outF->good() && outF->is_open() )
+	{
+		outF->write( (char*)&schriftGröße, 1 );
+		outF->write( (char*)&zeichenAnzahl, 1 );
+		for( int i = 0; i < zeichenAnzahl; ++i )
+		{
+			outF->write( (char*)&zeichen[ i ], 1 );
+			outF->write( (char*)&pos[ i ], 4 );
+		}
+	}
+}
+
+unsigned char LTDSSchriftKopf::getSchriftGröße() const // gibt die Schriftgröße zurück
+{
+	return schriftGröße;
+}
+
+unsigned char LTDSSchriftKopf::getZeichenAnzahl() const // gibt die Zeichenanzahl zurück
+{
+	return zeichenAnzahl;
+}
+
+int *LTDSSchriftKopf::getPositionen() const // gibt die Zeichenpositionen zurück
+{
+	return pos;
+}
+
+unsigned char *LTDSSchriftKopf::getZeichen() const // gibt die zeichen zurück
+{
+	return zeichen;
+}
+
+// Reference Counting 
+LTDSSchriftKopf *LTDSSchriftKopf::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSSchriftKopf *LTDSSchriftKopf::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDSBuchstabenKopf Klasse aus Dateisystem.h
+// Konstruktor 
+LTDSBuchstabenKopf::LTDSBuchstabenKopf()
+	: ref( 1 ),
+	  zeichen( 0 ),
+	  größe( 0, 0 )
+{
+}
+
+// nicht constant 
+void LTDSBuchstabenKopf::laden( std::ifstream *inF ) // lät aus inF
+{
+	if( inF->good() && inF->is_open() )
+	{
+		inF->read( (char*)&zeichen, 1 );
+		inF->read( (char*)&größe.x, 1 );
+		inF->read( (char*)&größe.y, 1 );
+	}
+}
+
+void LTDSBuchstabenKopf::init( unsigned char zeichen, const Punkt &größe ) // initialisierung( für speichern )
+{
+	this->zeichen = zeichen;
+	this->größe = größe;
+}
+
+void LTDSBuchstabenKopf::init( unsigned char zeichen, int br, int hö )
+{
+	this->zeichen = zeichen;
+	größe.x = br, größe.y = hö;
+}
+
+// constant 
+void LTDSBuchstabenKopf::speichern( std::ofstream *outF ) const // speichertn nach outF
+{
+	if( outF->good() && outF->is_open() )
+	{
+		outF->write( (char*)&zeichen, 1 );
+		outF->write( (char*)&größe.x, 1 );
+		outF->write( (char*)&größe.y, 1 );
+	}
+}
+
+unsigned char LTDSBuchstabenKopf::getZeichen() const // gibt das Zeichen zurück
+{
+	return zeichen;
+}
+
+int LTDSBuchstabenKopf::getBreite() const // gibt die Breite zurück
+{
+	return größe.x;
+}
+
+int LTDSBuchstabenKopf::getHöhe() const // gibt die höhe zurück
+{
+	return größe.y;
+}
+
+const Punkt &LTDSBuchstabenKopf::getGröße() const // gibt die Größe zurück
+{
+	return größe;
+}
+
+// Reference Counting 
+LTDSBuchstabenKopf *LTDSBuchstabenKopf::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSBuchstabenKopf *LTDSBuchstabenKopf::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDSBuchstabenKörper Klasse aus Dateisystem.h
+// Konstruktor 
+LTDSBuchstabenKörper::LTDSBuchstabenKörper( LTDSBuchstabenKopf *kopf )
+	: ref( 1 ),
+	größe( kopf->getGröße() ),
+	zeichen( kopf->getZeichen() ),
+	buchstabe( new Buchstabe() )
+{
+	buchstabe->NeuBuchstabe( größe );
+	kopf->release();
+}
+
+// Destruktor 
+LTDSBuchstabenKörper::~LTDSBuchstabenKörper()
+{
+	if( buchstabe )
+		buchstabe->release();
+}
+
+// nicht constant 
+void LTDSBuchstabenKörper::setBuchstabe( Buchstabe *zeichen ) // setzt den Buchstaben
+{
+	if( buchstabe )
+		buchstabe->release();
+	buchstabe = zeichen;
+}
+
+void LTDSBuchstabenKörper::laden( std::ifstream *inF ) // Läht aus inF
+{
+	if( inF->good() && inF->is_open() )
+	{
+		LTDSPixel *vorher = 0;
+		LTDSPixel *jetzt = new LTDSPixel( vorher );
+		char byte = 0;
+		int beg = 0;
+		int ende = -1;
+		for( int i = 0; i < größe.x * größe.y; ++i )
+		{
+			if( !jetzt ) // wenn es nicht der erste Pixel ist
+				jetzt = new LTDSPixel( vorher->getThis() );
+			int ende = -1;
+			while( ende < 0 ) // Pixel laden
+			{
+				if( beg == 0 )
+					inF->read( &byte, 1 );
+				ende = jetzt->addByte( byte, beg ); // byte auswerten
+				beg = 0;
+			}
+			beg = ende;
+			if( beg == 8 )
+				beg = 0;
+			if( buchstabe )
+				buchstabe->setPixel( i, jetzt->getA() );
+			if( vorher )
+				vorher = vorher->release();
+			vorher = jetzt->getThis();
+			jetzt = jetzt->release();
+		}
+		if( vorher )
+			vorher->release();
+		if( jetzt )
+			jetzt->release();
+	}
+}
+
+// constant 
+void LTDSBuchstabenKörper::speichern( std::ofstream *outF ) const // speichert nach outF
+{
+	if( outF->good() && outF->is_open() )
+	{
+		LTDSPixel *vorher = 0; // Letzter gespeicherter Pixel
+		LTDSPixel *jetzt = new LTDSPixel( 0 ); // Der momentan zu speichernde Pixel
+		int begin = 0, ende = 0; // Pixelbeginn, endposition in der byte variable
+		char byte = 0; // Der nächste byte der Datei
+		bool w = 0;
+		unsigned char *alphaBuff = buchstabe->getBuff();
+		for( int i = 0; i < größe.x * größe.y; ++i ) // für jeden Pixel
+		{
+			if( !jetzt ) // wenn es nicht der erste Pixel ist
+				jetzt = new LTDSPixel( vorher->getThis() );
+			jetzt->setAlpha( alphaBuff[ i ] ); // Farbe des Pixels setzen
+			jetzt->Komp(); // Pixel komprimieren
+			ende = -1;
+			while( ende < 0 ) // byte befüllen
+			{
+				ende = jetzt->getNextByte( byte, begin );
+				begin = 0;
+				w = 0;
+				if( ende == -1 || ende == 8 ) // byte speichern
+				{
+					outF->write( &byte, 1 );
+					w = 1;
+					byte = 0;
+				}
+			} // Pixel fertig
+			begin = ende;
+			if( begin == 8 )
+				begin = 0;
+			if( vorher )
+				vorher->release();
+			vorher = jetzt->getThis(); // dieser wird zu letzter
+			jetzt = jetzt->release();
+		}
+		if( vorher )
+			vorher = vorher->release();
+		if( !w )
+		{
+			outF->write( &byte, 1 ); // Das letzte byte speichern
+		}
+		outF->flush(); // dateistream speichern
+	}
+}
+
+Buchstabe *LTDSBuchstabenKörper::getBuchstabe() const // gibt den Buchstaben zurück
+{
+	return buchstabe->getThis();
+}
+
+unsigned char LTDSBuchstabenKörper::getZeichen() const // gibt das Zeichen zurück
+{
+	return zeichen;
+}
+
+// Reference Counting 
+LTDSBuchstabenKörper *LTDSBuchstabenKörper::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSBuchstabenKörper *LTDSBuchstabenKörper::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der LTDSDatei Klasse aus DAteisystem.h
+// Konstruktor 
+LTDSDatei::LTDSDatei()
+	: ref( 1 ),
+	  pfad( new Text() ),
+	  dateiKopf( 0 )
+{
+}
+
+// Destruktor 
+LTDSDatei::~LTDSDatei()
+{
+	if( dateiKopf )
+		dateiKopf->release();
+	pfad->release();
+}
+
+// nicht constant 
+void LTDSDatei::setPfad( Text *txt ) // setzt den Pfad zur Datei
+{
+	if( dateiKopf )
+		dateiKopf = dateiKopf->release();
+	pfad->setText( txt->getText() );
+	txt->release();
+}
+
+void LTDSDatei::leseDaten() // ließt den Dateikopf
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return;
+	if( dateiKopf )
+		dateiKopf->release();
+	dateiKopf = new LTDSDateiKopf();
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+	dateiKopf->laden( inF );
+	inF->close();
+	delete inF;
+}
+
+void LTDSDatei::addSchriftgröße( Alphabet *alphabet ) // fügt eine Schriftgröße hinzu
+{
+	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob die Datei existiert
+		return;
+	if( !dateiKopf ) // prüfen, ob der Dateikopf schon gelesen wurde
+		leseDaten();
+	int sgröße = alphabet->getSchriftgröße(); // Schriftgröße die hinzugefügt werden soll
+	unsigned char *sglist = dateiKopf->getSchriftGrößeList(); // Liste von bereits vorhandenen Schriftgrößen
+	unsigned char sganzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der bereits vorhandenen Schriftgrößen
+	for( int i = 0; i < sganzahl; ++i ) // prüfen, ob die Schriftgröße bereits existiert
+	{
+		if( sglist[ i ] == sgröße )
+		{
+			alphabet->release();
+			return;
+		}
+	}
+	dateiKopf->addSG( sgröße ); // Schriftgröße dem Dateikopf hinzufügen
+	int *sgPosList = dateiKopf->getPositionList(); // Liste mit positionen der Schriftgrößen
+	sglist = dateiKopf->getSchriftGrößeList(); // Liste von bereits vorhandenen Schriftgrößen
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
+	pfad->anhängen( "0" );
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
+	dateiKopf->speichern( outF ); // Dateikopf in neue datei speichern
+	inF->seekg( 1 + 5 * sganzahl, std::ios::beg ); // Position der ersten Schriftgröße in der alten Datei
+	for( int i = 0; i < sganzahl; ++i ) // Buchstabenpositionen aller Schriftgrößen aktualisieren
+	{
+		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
+		sgKpf_tmp->laden( inF ); // aus alter Datei laden
+		int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
+		unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
+		for( int i1 = 0; i1 < zeichA_tmp; ++i1 )
+			zeichP_tmp[ i1 ] += 5; // Buchstabenpositionen aktualisieren
+		sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
+		int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
+		int endByte = sgPosList[ i + 1 ];
+		if( !endByte )
+		{
+			inF->seekg( 0, std::ios::end );
+			endByte = (int)inF->tellg();
+			inF->seekg( beginByte, std::ios::beg );
+		}
+		char byte;
+		for( int i1 = beginByte; i1 < endByte; ++i1 ) // Kopiervorgang
+		{
+			inF->read( &byte, 1 );
+			outF->write( &byte, 1 );
+		}
+		sgKpf_tmp->release();
+	}
+	inF->close(); // Alte datei schließen
+	sgPosList[ sganzahl ] = (int)outF->tellp();
+	outF->seekp( 0, std::ios::beg );
+	for( int i = 0; i < sganzahl; ++i ) // Positionen im Dateikopf aktualisieren
+		sgPosList[ i ] += 5;
+	dateiKopf->speichern( outF ); // aktualisierter Dateikopf speichern
+	outF->seekp( sgPosList[ sganzahl ], std::ios::beg );
+	LTDSSchriftKopf *sgkopf = new LTDSSchriftKopf(); // Kopf der neuen Schriftgröße
+	sgkopf->setZeichenAlphabet( alphabet->getThis() ); // Kopf der Schriftgröße initialisieren
+	sgkopf->speichern( outF ); // Kopf der Schriftgröße speichern
+	int *BuchstabenPosList = sgkopf->getPositionen(); // positionen der verschiedenen Zeichen in der Datei( nuch 0 )
+	int count = 0;
+	for( int i = 0; i < 256; ++i )
+	{
+		Buchstabe *zeich = alphabet->getBuchstabe( i );
+		if( zeich )
+		{
+			BuchstabenPosList[ count ] = (int)outF->tellp(); // position des Zeichens setzen
+			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf
+			zeichKpf->init( i, zeich->getBreite(), zeich->getHöhe() );
+			zeichKpf->speichern( outF ); // Zeichenkopf speichern
+			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Zeichenkörper
+			zeichKpf->release();
+			zeichKörp->setBuchstabe( zeich->getThis() );
+			zeichKörp->speichern( outF ); // Zeichenkörper speichern
+			zeich->release();
+			++count;
+		}
+	}
+	outF->seekp( sgPosList[ sganzahl ], std::ios::beg );
+	sgkopf->speichern( outF ); // aktualisierter Schriftgrößen Kopf speichern
+	outF->close();
+	Text *pfad2 = new Text();
+	pfad2->setText( pfad->getText() );
+	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
+	DateiLöschen( pfad->getThis() ); // Alte datei Löschen
+	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei nach alte umbenennen
+	pfad2->release(); // Speicher freigeben
+	sgkopf->release();
+	delete inF;
+	delete outF;
+	alphabet->release();
+}
+
+void LTDSDatei::addBuchstabe( int gr, Buchstabe *zeich, unsigned char zeichen ) // Fügt einer Schriftgröße einen Buchstaben hinzu
+{
+	if( !DateiExistiert( pfad->getThis() ) ) // prüfen ob Datei existiert
+	{
+		zeich->release();
+		return;
+	}
+	if( !dateiKopf ) // prüfen, ob der DAteikopf geladen wurde
+		leseDaten();
+	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen aus der Datei
+	int *sgPosList = dateiKopf->getPositionList(); // Liste mit Schriftgrößen positionen aus Datei
+	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl von Schriftgrößen aus der Datei
+	int sgNum = -1;
+	for( int i = 0; i < sgAnzahl; ++i ) // Position der richtigen Schriftgröße ermitteln
+	{
+		if( sgList[ i ] == gr )
+		{
+			sgNum = i;
+			break;
+		}
+	}
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // Alte Datei
+	pfad->anhängen( "0" );
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // Neue Datei
+	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
+	if( sgNum == -1 ) // Die Schriftgröße existiert noch nicht und wird erstellt
+	{
+		dateiKopf->addSG( gr ); // Schriftgröße dem Dateikopf hinzufügen
+		sgPosList = dateiKopf->getPositionList();
+		sgList = dateiKopf->getSchriftGrößeList();
+		dateiKopf->speichern( outF ); // Dateikopf speichern
+		inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg ); // Position der ersten Schriftgröße in der alten Datei
+		for( int i = 0; i < sgAnzahl; ++i ) // Buchstabenpositionen aller Schriftgrößen aktualisieren
+		{
+			LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
+			sgKpf_tmp->laden( inF ); // aus alter Datei laden
+			int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
+			unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
+			for( int i1 = 0; i1 < zeichA_tmp; ++i1 )
+				zeichP_tmp[ i1 ] += 5; // Buchstabenpositionen aktualisieren
+			sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
+			int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
+			int endByte = sgPosList[ i + 1 ];
+			if( i + 1 >= sgAnzahl )
+			{
+				inF->seekg( 0, std::ios::end );
+				endByte = (int)inF->tellg();
+				inF->seekg( beginByte, std::ios::beg );
+			}
+			char byte;
+			for( int i1 = beginByte; i1 < endByte; ++i1 ) // Kopiervorgang
+			{
+				inF->read( &byte, 1 );
+				outF->write( &byte, 1 );
+			}
+			sgKpf_tmp->release();
+		}
+		sgPosList[ sgAnzahl ] = (int)outF->tellp();
+		outF->seekp( 0, std::ios::beg );
+		for( int i = 0; i < sgAnzahl; ++i ) // Positionen im Dateikopf aktualisieren
+			sgPosList[ i ] += 5;
+		dateiKopf->speichern( outF ); // aktualisierter Dateikopf speichern
+		outF->seekp( sgPosList[ sgAnzahl ], std::ios::beg );
+		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf initialisiern
+		sgKpf->setSchriftgröße( gr );
+		sgKpf->addZeichen( zeichen );
+		sgKpf->getPositionen()[ 0 ] = (int)outF->tellp() + 7;
+		sgKpf->speichern( outF ); // Schriftgröße Kopf speichern
+		sgKpf->release();
+		LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Buchstabenkopf
+		zeichKpf->init( zeichen, zeich->getGröße() );
+		zeichKpf->speichern( outF ); // Buchstabenkopf speichern
+		LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Buchstabenkörper
+		zeichKpf->release();
+		zeichKörp->setBuchstabe( zeich->getThis() );
+		zeichKörp->speichern( outF ); // Buchstabenkörper speichern
+		zeichKörp->release();
+	}
+	else
+	{
+		dateiKopf->speichern( outF ); // Dateikopf speichern
+		int beginByte = 1 + 5 * sgAnzahl; // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
+		int endByte = sgPosList[ sgNum ];
+		char byte;
+		for( int i1 = beginByte; i1 < endByte; ++i1 ) // Kopiervorgang bis zur angegebenen größe
+		{
+			inF->read( &byte, 1 );
+			outF->write( &byte, 1 );
+		}
+		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf(); // Schriftgröße Kopf
+		sgKpf->laden( inF );
+		for( int i = 0; i < sgKpf->getZeichenAnzahl(); ++i )
+			sgKpf->getPositionen()[ i ] += 5;
+		sgKpf->addZeichen( zeichen );
+		int indexPlus = 5;
+		int zeichenPos = sgPosList[ sgNum + 1 ]; // position des neuen Zeichens
+		if( sgNum + 1 >= sgAnzahl )
+		{
+			int tmp = (int)inF->tellg();
+			inF->seekg( 0, std::ios::end );
+			zeichenPos = (int)inF->tellg();
+			inF->seekg( tmp, std::ios::beg );
+		}
+		zeichenPos += indexPlus;
+		sgKpf->getPositionen()[ sgKpf->getZeichenAnzahl() - 1 ] = zeichenPos;
+		sgKpf->speichern( outF ); // Schriftgröße Kopf speichern
+		sgKpf->release();
+		for( int i = (int)inF->tellg() + indexPlus; i < zeichenPos; ++i ) // Kopiervorgang bis zum Zeichenbeginn
+		{
+			inF->read( &byte, 1 );
+			outF->write( &byte, 1 );
+		}
+		LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf(); // Zeichenkopf
+		zeichKpf->init( zeichen, zeich->getGröße() );
+		zeichKpf->speichern( outF ); // Zeichenkopf speichern
+		LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() ); // Zeichenkörper
+		zeichKpf->release();
+		zeichKörp->setBuchstabe( zeich->getThis() );
+		zeichKörp->speichern( outF ); // Zeichenkörper speichern
+		zeichKörp->release();
+		int nowPos = (int)outF->tellp();
+		indexPlus += nowPos - zeichenPos;
+		for( int i = sgNum + 1; i < sgAnzahl; ++i ) // Dateikopf aktualisieren
+			sgPosList[ i ] += indexPlus;
+		outF->seekp( 0, std::ios::beg );
+		dateiKopf->speichern( outF ); // Dateikopf speichern
+		outF->seekp( nowPos, std::ios::beg );
+		for( int i = sgNum + 1; i < sgAnzahl; ++i ) // Restliche Schriftgrößen aktualisieren
+		{
+			LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
+			sgKpf_tmp->laden( inF ); // aus alter Datei laden
+			int *zeichP_tmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen der Schriftgröße
+			unsigned char zeichA_tmp = sgKpf_tmp->getZeichenAnzahl(); // Anzahl von Zeichen der Schriftgröße
+			for( int i1 = 0; i1 < zeichA_tmp; ++i1 )
+				zeichP_tmp[ i1 ] += indexPlus; // Buchstabenpositionen aktualisieren
+			sgKpf_tmp->speichern( outF ); // Schriftgröße Kopf in neue Datei speichern
+			int beginByte = (int)inF->tellg(); // Die restlichen bytes bis zur nächsten Schriftgröße in neue Datei kopieren
+			int endByte = sgPosList[ i + 1 ];
+			if( i + 1 >= sgAnzahl )
+			{
+				inF->seekg( 0, std::ios::end );
+				endByte = (int)inF->tellg();
+				inF->seekg( beginByte, std::ios::beg );
+			}
+			char byte;
+			for( int i1 = beginByte; i1 < endByte; ++i1 ) // Kopiervorgang
+			{
+				inF->read( &byte, 1 );
+				outF->write( &byte, 1 );
+			}
+			sgKpf_tmp->release();
+		}
+	}
+	inF->close();
+	outF->close();
+	Text *pfad2 = new Text( pfad->getText() );
+	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
+	DateiLöschen( pfad->getThis() ); // Alte Datei löschen
+	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // Neue Datei in alte umbenennen
+	pfad2->release();// Speicher freigeben
+	delete inF;
+	delete outF;
+	zeich->release();
+}
+
+void LTDSDatei::löscheSchrifrGröße( int gr ) // Löscht eine Schriftgröße aus der Datei
+{
+	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob Datei existiert
+		return;
+	if( !dateiKopf ) // prüfen, ob der Dateikopf geladen wurde
+		leseDaten();
+	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen
+	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen
+	int sgNum = -1;
+	for( int i = 0; i < sgAnzahl; ++i ) // zu löschende Schriftgröße suchen
+	{
+		if( sgList[ i ] == gr )
+		{
+			sgNum = i;
+			break;
+		}
+	}
+	if( sgNum == -1 ) // Die Schriftgröße ist nicht vorhanden
+		return;
+	int *sgPosList = dateiKopf->getPositionList();  // Liste von Positionen der Schriftgrößen
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
+	pfad->anhängen( "0" );
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
+	outF->seekp( 1 + 5 * ( sgAnzahl - 1 ), std::ios::beg );
+	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
+	for( int i = 0; i < sgNum; ++i ) // Schriftgrößen vor der zu löschenden Schriftgröße aktualisieren
+	{
+		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
+		sgKpf_tmp->laden( inF ); // Schriftgrößen Kopf laden
+		int *zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen
+		unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl
+		for( int i1 = 0; i1 < zeichATmp; ++i1 ) // Position der Zeichen um 5 bytes zurücksetzen
+			zeichPosLTmp[ i1 ] -= 5;
+		sgKpf_tmp->speichern( outF ); // speichern in Neue Datei
+		char byte = 0;
+		for( int i1 = (int)inF->tellg(); i1 < sgPosList[ i + 1 ]; ++i1 ) // Den Körper des Zeichens Kopieren
+		{
+			inF->read( &byte, 1 );
+			outF->write( &byte, 1 );
+		}
+		sgKpf_tmp->release();
+	}
+	int indexMinus = 5 + sgPosList[ sgNum + 1 ] - (int)inF->tellg();
+	inF->seekg( sgPosList[ sgNum + 1 ], std::ios::beg );
+	for( int i = sgNum + 1; i < sgAnzahl; ++i ) // Die Schriftgröße nach der zu löschenden Schriftgröße
+	{
+		LTDSSchriftKopf *sgKpf_tmp = new LTDSSchriftKopf(); // Schriftgrößen Kopf
+		sgKpf_tmp->laden( inF ); // Schriftgrößen Kopf laden
+		int *zeichPosLTmp = sgKpf_tmp->getPositionen(); // Zeichenpositionen
+		unsigned char zeichATmp = sgKpf_tmp->getZeichenAnzahl(); // Zeichenanzahl
+		for( int i1 = 0; i1 < zeichATmp; ++i1 ) // Position der Zeichen aktualisieren
+			zeichPosLTmp[ i1 ] -= indexMinus;
+		sgKpf_tmp->speichern( outF ); // speichern in Neue Datei
+		char byte = 0;
+		int BeginByte = (int)inF->tellg();
+		int EndByte = sgPosList[ i + 1 ];
+		if( !EndByte )
+		{
+			inF->seekg( 0, std::ios::end );
+			EndByte = (int)inF->tellg();
+			inF->seekg( BeginByte, std::ios::beg );
+		}
+		for( int i1 = BeginByte; i1 < EndByte; ++i1 ) // Den Körper des Zeichens Kopieren
+		{
+			inF->read( &byte, 1 );
+			outF->write( &byte, 1 );
+		}
+	}
+	for( int i = 0; i < sgNum; ++i ) // Dateikopf aktualisieren
+		sgPosList[ i ] -= 5;
+	for( int i = sgNum + 1; i < sgAnzahl; ++i )
+		sgPosList[ i ] -= indexMinus;
+	dateiKopf->removeSG( gr );
+	outF->seekp( 0, std::ios::beg );
+	dateiKopf->speichern( outF ); // Dateikopf speichern
+	inF->close();
+	outF->close();
+	Text *pfad2 = new Text( pfad->getText() );
+	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
+	DateiLöschen( pfad->getThis() ); // alte Datei löschen
+	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei zu alter umbenennen
+	pfad2->release();
+	delete inF;
+	delete outF;
+}
+
+void LTDSDatei::löscheBuchstabe( int gr, unsigned char zeichen ) // Löscht einen Buchstaben aus der Datei
+{
+	if( !DateiExistiert( pfad->getThis() ) ) // prüfen, ob die Datei existiert
+		return;
+	if( !dateiKopf ) // prüfen, ob der Dateikopf gelesen wurde
+		leseDaten();
+	unsigned char *sgList = dateiKopf->getSchriftGrößeList(); // Liste mit Schriftgrößen
+	unsigned char sgAnzahl = dateiKopf->getSchriftGrößeAnzahl(); // Anzahl der Schriftgrößen
+	int *sgPosList = dateiKopf->getPositionList(); // Liste mit Positionen der Schriftgrößen
+	int sgNum = -1;
+	for( int i = 0; i < sgAnzahl; ++i ) // Schriftgröße suchen
+	{
+		if( sgList[ i ] == gr )
+		{
+			sgNum = i;
+			break;
+		}
+	}
+	if( sgNum == -1 ) // Schriftgröße nicht gefunden
+		return;
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary ); // alte Datei
+	pfad->anhängen( "0" );
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary ); // neue Datei
+	int indexMinus = 0;
+	inF->seekg( 1 + 5 * sgAnzahl, std::ios::beg );
+	dateiKopf->speichern( outF ); // DateiKopf peichern
+	for( int i = 0; i < sgAnzahl; ++i )
+	{
+		LTDSSchriftKopf *sgKopf = new LTDSSchriftKopf(); // Schriftkopf
+		sgKopf->laden( inF ); // Schriftkopf laden
+		unsigned char sgZeichAnzahl = sgKopf->getZeichenAnzahl(); // Zeichenanzahl
+		unsigned char *sgZeichenList = sgKopf->getZeichen(); // Zeichen Liste
+		int *sgZPosList = sgKopf->getPositionen(); // Positions Liste
+		if( i == sgNum ) // Zeichen befindet sich in dieser Schriftgröße
+		{
+			int sgZNum = -1;
+			for( int i1 = 0; i1 < sgZeichAnzahl; ++i1 ) // Zeichen suchen
+			{
+				if( sgZeichenList[ i1 ] == zeichen )
+				{
+					sgZNum = i1;
+					break;
+				}
+			}
+			if( sgZNum == -1 ) // Zeichen nicht gefunden
+			{
+				sgKopf->release();
+				inF->close();
+				outF->close();
+				delete inF;
+				delete outF;
+				DateiLöschen( pfad->getThis() );
+				pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
+				return; // abbruch
+			}
+			outF->seekp( 2 + 5 * ( sgZeichAnzahl - 1 ), std::ios::cur );
+			indexMinus += 5;
+			for( int i1 = 0; i1 < sgZNum; ++i1 ) // Zeichen vor dem zu löschenden Zeichen
+			{
+				char byte = 0;
+				for( int i2 = sgZPosList[ i1 ]; i2 < sgZPosList[ i1 + 1 ]; ++i2 ) // Kopieren
+				{
+					inF->read( &byte, 1 );
+					outF->write( &byte, 1 );
+				}
+				sgZPosList[ i1 ] -= indexMinus; // Schriftgröße Kopf aktualisieren
+			}
+			if( !sgZPosList[ sgZNum + 1 ] )
+			{
+				int endByte = sgPosList[ i + 1 ];
+				if( !endByte )
+				{
+					int beginByte = (int)inF->tellg();
+					inF->seekg( 0, std::ios::end );
+					endByte = (int)inF->tellg();
+					inF->seekg( beginByte, std::ios::beg );
+				}
+				indexMinus += endByte - sgZPosList[ sgZNum ];
+			}
+			else
+			    indexMinus += sgZPosList[ sgZNum + 1 ] - sgZPosList[ sgZNum ];
+			if( sgZNum + 1 < sgZeichAnzahl )
+				inF->seekg( sgZPosList[ sgZNum + 1 ], std::ios::beg );
+			for( int i1 = sgZNum + 1; i1 < sgZeichAnzahl; ++i1 ) // Zeichen nach dem gelöschten Zeichen
+			{
+				int beginByte = (int)inF->tellg();
+				int endByte = sgZPosList[ i1 + 1 ];
+				if( !endByte )
+				{
+					inF->seekg( 0, std::ios::end );
+					endByte = (int)inF->tellg();
+					inF->seekg( beginByte, std::ios::beg );
+				}
+				char byte = 0;
+				for( int i2 = beginByte; i2 < endByte; ++i2 ) // Kopieren
+				{
+					inF->read( &byte, 1 );
+					outF->write( &byte, 1 );
+				}
+				sgZPosList[ i1 ] -= indexMinus; // Schriftgröße Kopf aktualisieren
+			}
+			sgKopf->removeZeichen( zeichen );
+		}
+		else
+		{
+			for( int i1 = 0; i1 < sgZeichAnzahl; ++i1 ) // Schriftgröße Kopf aktualisieren
+				sgZPosList[ i ] -= indexMinus;
+			sgKopf->speichern( outF ); // Schriftgröße Kopf speichern
+			int beginByte = (int)inF->tellg();
+			int endByte = sgPosList[ i + 1 ];
+			if( !endByte )
+			{
+				inF->seekg( 0, std::ios::end );
+				endByte = (int)inF->tellg();
+				inF->seekg( beginByte, std::ios::beg );
+			}
+			char byte;
+			for( int i1 = beginByte; i1 < endByte; ++i1 ) // Kopieren
+			{
+				inF->read( &byte, 1 );
+				outF->write( &byte, 1 );
+			}
+			sgPosList[ i ] -= indexMinus;
+		}
+		outF->seekp( sgPosList[ i ], std::ios::beg );
+		sgKopf->speichern( outF ); // Schriftgröße Kopf speichern
+		outF->seekp( sgPosList[ i + 1 ], std::ios::beg );
+		sgKopf->release();
+	}
+	inF->close();
+	outF->close();
+	Text *pfad2 = new Text( pfad->getText() );
+	pfad->löschen( pfad->getLänge() - 1, pfad->getLänge() );
+	DateiLöschen( pfad->getThis() ); // alte Datei löschen
+	DateiUmbenennen( pfad2->getThis(), pfad->getThis() ); // neue Datei nach alte umbenennen
+	pfad2->release(); // Speicher freigeben
+	delete inF;
+	delete outF;
+}
+
+void LTDSDatei::löscheDatei() // Löscht die gesamte Datei
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return;
+	if( !dateiKopf )
+		leseDaten();
+	DateiLöschen( pfad->getThis() );
+}
+
+void LTDSDatei::erstelleDatei() // erstellt die Datei
+{
+	DateiPfadErstellen( pfad->getThis() );
+	if( dateiKopf )
+		dateiKopf->release();
+	dateiKopf = new LTDSDateiKopf();
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary );
+	dateiKopf->speichern( outF );
+	outF->close();
+	delete outF;
+}
+
+void LTDSDatei::speicherSchrift( Schrift *schrift ) // Speichert die übergebene Schrift
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+	{
+		schrift->release();
+		return;
+	}
+	löscheDatei();
+	if( dateiKopf )
+		dateiKopf->release();
+	dateiKopf = new LTDSDateiKopf();
+	for( int i = 0; i < schrift->getAlphabetAnzahl(); ++i )
+	{
+		Alphabet *alp = schrift->getAlphabetI( i );
+		if( alp )
+		{
+			dateiKopf->addSG( alp->getSchriftgröße() );
+			alp->release();
+		}
+	}
+	std::ofstream *outF = new std::ofstream( pfad->getText(), std::ios::binary );
+	dateiKopf->speichern( outF );
+	for( int i = 0; i < schrift->getAlphabetAnzahl(); ++i )
+	{
+		dateiKopf->getPositionList()[ i ] = (int)outF->tellp();
+		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
+		sgKpf->setZeichenAlphabet( schrift->getAlphabetI( i ) );
+		sgKpf->speichern( outF );
+		Alphabet *alp = schrift->getAlphabetI( i );
+		for( int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); ++i1 )
+		{
+			sgKpf->getPositionen()[ i1 ] = (int)outF->tellp();
+			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf();
+			Buchstabe *zeichen = alp->getBuchstabe( sgKpf->getZeichen()[ i1 ] );
+			zeichKpf->init( sgKpf->getZeichen()[ i1 ], zeichen->getBreite(), zeichen->getHöhe() );
+			zeichKpf->speichern( outF );
+			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() );
+			zeichKörp->setBuchstabe( zeichen->getThis() );
+			zeichKörp->speichern( outF );
+			zeichKörp->release();
+			zeichen->release();
+			zeichKpf->release();
+		}
+		alp->release();
+		int p = (int)outF->tellp();
+		outF->seekp( dateiKopf->getPositionList()[ i ], std::ios::beg );
+		sgKpf->speichern( outF );
+		outF->seekp( p, std::ios::beg );
+		sgKpf->release();
+	}
+	outF->seekp( 0, std::ios::beg );
+	dateiKopf->speichern( outF );
+	outF->close();
+	delete outF;
+	schrift->release();
+}
+
+// constant 
+Schrift *LTDSDatei::ladeSchrift() // gibt die geladene Schrift zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	Schrift *ret = new Schrift();
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+	inF->seekg( dateiKopf->getPositionList()[ 0 ], std::ios::beg );
+	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i )
+	{
+		LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
+		sgKpf->laden( inF );
+		Alphabet *alphabet = new Alphabet();
+		alphabet->setSchriftgröße( sgKpf->getSchriftGröße() );
+		alphabet->setDrawSchriftgröße( sgKpf->getSchriftGröße() );
+		for( int i1 = 0; i1 < sgKpf->getZeichenAnzahl(); ++i1 )
+		{
+			LTDSBuchstabenKopf *zeichKpf = new LTDSBuchstabenKopf();
+			zeichKpf->laden( inF );
+			LTDSBuchstabenKörper *zeichKörp = new LTDSBuchstabenKörper( zeichKpf->getThis() );
+			zeichKörp->laden( inF );
+			alphabet->setBuchstabe( zeichKpf->getZeichen(), zeichKörp->getBuchstabe() );
+			zeichKörp->release();
+			zeichKpf->release();
+		}
+		ret->addAlphabet( alphabet->getThis() );
+		alphabet->release();
+		sgKpf->release();
+	}
+	inF->close();
+	delete inF;
+	return ret;
+}
+
+Alphabet *LTDSDatei::ladeAlphabet( int schriftgröße ) // gibt eine geladene Schrift nur mit der angegebenen Schriftgröße zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	Alphabet *ret = 0;
+	int sgNum = -1;
+	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i )
+	{
+		if( dateiKopf->getSchriftGrößeList()[ i ] == schriftgröße )
+		{
+			sgNum = i;
+			break;
+		}
+	}
+	if( sgNum == -1 )
+		return 0;
+	ret = new Alphabet();
+	ret->NeuAlphabet();
+	ret->setSchriftgröße( schriftgröße );
+	ret->setDrawSchriftgröße( schriftgröße );
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+	inF->seekg( dateiKopf->getPositionList()[ sgNum ], std::ios::beg );
+	LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
+	sgKpf->laden( inF );
+	for( int i = 0; i < sgKpf->getZeichenAnzahl(); ++i )
+	{
+		LTDSBuchstabenKopf *sgZKpf = new LTDSBuchstabenKopf();
+		sgZKpf->laden( inF );
+		LTDSBuchstabenKörper *sgZKörp = new LTDSBuchstabenKörper( sgZKpf->getThis() );
+		sgZKörp->laden( inF );
+		ret->setBuchstabe( sgZKpf->getZeichen(), sgZKörp->getBuchstabe() );
+		sgZKörp->release();
+		sgZKpf->release();
+	}
+	sgKpf->release();
+	inF->close();
+	delete inF;
+	return ret;
+}
+
+Buchstabe *LTDSDatei::ladeBuchstabe( int schriftgröße, unsigned char zeichen )// Läd einen bestimmten Buchstaben
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	Buchstabe *ret = 0;
+	int sgNum = -1;
+	for( int i = 0; i < dateiKopf->getSchriftGrößeAnzahl(); ++i )
+	{
+		if( dateiKopf->getSchriftGrößeList()[ i ] == schriftgröße )
+		{
+			sgNum = i;
+			break;
+		}
+	}
+	if( sgNum == -1 )
+		return 0;
+	std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+	inF->seekg( dateiKopf->getPositionList()[ sgNum ], std::ios::beg );
+	LTDSSchriftKopf *sgKpf = new LTDSSchriftKopf();
+	sgKpf->laden( inF );
+	int sgZNum = -1;
+	for( int i = 0; i < sgKpf->getZeichenAnzahl(); ++i )
+	{
+		if( sgKpf->getZeichen()[ i ] == zeichen )
+		{
+			sgZNum = i;
+			break;
+		}
+	}
+	if( sgZNum != -1 )
+	{
+		inF->seekg( sgKpf->getPositionen()[ sgZNum ], std::ios::beg );
+		LTDSBuchstabenKopf *sgZKpf = new LTDSBuchstabenKopf();
+		sgZKpf->laden( inF );
+		LTDSBuchstabenKörper *sgZKörp = new LTDSBuchstabenKörper( sgZKpf->getThis() );
+		sgZKörp->laden( inF );
+		ret = sgZKörp->getBuchstabe();
+		sgZKörp->release();
+		sgZKpf->release();
+	}
+	sgKpf->release();
+	inF->close();
+	delete inF;
+	if( ret )
+	{
+		ret->setSchriftGröße( schriftgröße );
+		ret->setDrawSchriftGröße( schriftgröße );
+	}
+	return ret;
+}
+
+Text *LTDSDatei::getPfad() const // gibt den Dateipfad zurück
+{
+	return pfad->getThis();
+}
+
+int LTDSDatei::getAnzahlSchriftgrößen() const // gibt die Anzahl der Schriftgrößen aus der Datei zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	return dateiKopf->getSchriftGrößeAnzahl();
+}
+
+unsigned char *LTDSDatei::getSchriftGrößen() const // gibt einen Array von Schriftgrößen zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	return dateiKopf->getSchriftGrößeList();
+}
+
+unsigned char LTDSDatei::getAnzahlBuchstaben( int sg ) // gibt die anzahl gespeicherter Buchstaben einer Schriftgröße zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	int ret = 0;
+	unsigned char *größen = dateiKopf->getSchriftGrößeList();
+	unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl();
+	int grpos = -1;
+	for( int i = 0; i < granzahl; ++i )
+	{
+		if( größen[ i ] == sg )
+		{
+			grpos = i;
+			break;
+		}
+	}
+	if( grpos != -1 )
+	{
+		int *grposlist = dateiKopf->getPositionList();
+		LTDSSchriftKopf *sgkpf = new LTDSSchriftKopf();
+		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+		inF->seekg( grposlist[ grpos ], std::ios::beg );
+		sgkpf->laden( inF );
+		ret = sgkpf->getZeichenAnzahl();
+		sgkpf->release();
+		inF->close();
+		delete inF;
+	}
+	return ret;
+}
+
+unsigned char *LTDSDatei::getBuchstaben( int sg ) // gibt einen Array von Buchstaben einer Schriftgröße zurück
+{
+	if( !DateiExistiert( pfad->getThis() ) )
+		return 0;
+	if( !dateiKopf )
+		return 0;
+	unsigned char *ret = 0;
+	unsigned char *größen = dateiKopf->getSchriftGrößeList();
+	unsigned char granzahl = dateiKopf->getSchriftGrößeAnzahl();
+	int grpos = -1;
+	for( int i = 0; i < granzahl; ++i )
+	{
+		if( größen[ i ] == sg )
+		{
+			grpos = i;
+			break;
+		}
+	}
+	if( grpos != -1 )
+	{
+		int *grposlist = dateiKopf->getPositionList();
+		LTDSSchriftKopf *sgkpf = new LTDSSchriftKopf();
+		std::ifstream *inF = new std::ifstream( pfad->getText(), std::ios::binary );
+		inF->seekg( grposlist[ grpos ], std::ios::beg );
+		sgkpf->laden( inF );
+		int anz = sgkpf->getZeichenAnzahl();
+		ret = new unsigned char[ anz ];
+		for( int i = 0; i < anz; ++i )
+			ret[ i ] = sgkpf->getZeichen()[ i ];
+		sgkpf->release();
+		inF->close();
+		delete inF;
+	}
+	return ret;
+}
+
+// Reference Counting 
+LTDSDatei *LTDSDatei::getThis()
+{
+	++ref;
+	return this;
+}
+
+LTDSDatei *LTDSDatei::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+#endif
+// Bit Funktionen
+int Framework::Bits( int a ) // gibt 1-bits in gewinschter anzahl zurück
+{
+	int ret = 0;
+	for( int i = 0; i < a; ++i )
+	{
+		ret <<= 1;
+		++ret;
+	}
+	return ret;
+}
+
+int Framework::getBits( char c ) // gibt zurück, wie viele Bits c benötigt
+{
+	int ret = 0;
+	for( int i = 0; ( c & (char)Bits( i ) ) != c; ++i )
+		++ret;
+	return ret;
+}

+ 639 - 0
DateiSystem.h

@@ -0,0 +1,639 @@
+#ifndef DateiSystem_H
+#define DateiSystem_H
+
+#include <fstream>
+#include "Array.h"
+#include "Punkt.h"
+
+namespace Framework
+{
+	class Bild; // Bild.h
+	class Text; // Text.h
+#ifdef WIN32
+	class Buchstabe; // Schrift.h
+	class Alphabet; // Schrift.h
+	class Schrift; // Schrift.h
+	class FBalken; // Fortschritt.h
+#else
+#define FBalken int
+#endif
+	class LTDBPixel; // aus dieser Datei
+	class LTDBKopf; // aus dieser Datei
+	class LTDBKörper; // aus dieser Datei
+	class LTDBDatei; // aus dieser Datei
+	class LTDSPixel; // aus dieser Datei
+#ifdef WIN32
+	class LTDSDateiKopf; // aus dieser Datei
+	class LTDSSchriftKopf; // aus dieser Datei
+	class LTDSBuchstabenKopf; // aus dieser Datei
+	class LTDSBuchstabenKörper; // aus dieser Datei
+	class LTDSDatei; // aus dieser Datei
+#endif
+
+	// LTDB Dateivormat --- Dient zum speichern von mehreren Bildern in einer Datei.
+
+    // Dient zum Speichern und Laden eines einzelnen Pixels aus einem Bild im LTDB Dateiformat
+	class LTDBPixel // Pixel einer LTDB Datei
+	{
+	private:
+		LTDBPixel *davor; // Letzter Pixel
+		char index; // Bitlänge des Pixels
+		char iR, iG, iB, iA;
+		char miR, miG, miB, miA;
+		char maxIndex; // Länge des Pixels
+		bool änder : 1; // Verändert sich etwas an den volgenden 5 Variablen
+		bool änderR : 1; // Ändert sich Rot
+		bool änderG : 1; // Ändert sich Grün
+		bool änderB : 1; // Ändert sich Blau
+		bool änderA : 1; // Ändert sich Alpha
+		unsigned char komp : 3; // Komprimierung der Farbwerte
+		unsigned char R; // Rot
+		unsigned char G; // Grün
+		unsigned char B; // Blau
+		unsigned char A; // Alpha
+		bool addBitZuFarbe( unsigned char bit ); // Fügt den Farbwerten ein Bit hinzu
+		bool getNextFarbeBit( char &byte, int i ); // Speichert das nächste Farbbit in byte
+		int ref;
+
+	public:
+		// Konstruktor
+        //  davor: Der Pixel, der Vorher geladen wurde. 0, falls dieß der Erste Pixel ist
+		__declspec( dllexport ) LTDBPixel( LTDBPixel *davor );
+		// Destruktor 
+		__declspec( dllexport ) ~LTDBPixel();
+		// zum Laden gedacht. Fügt dem Pixel einiege bits hinzu
+        //  byte: Das zuletzt aus der Datei gelesene Byte
+        //  begin: Der Index des ersten Bits im byte, wo der Pixel beginnt
+        //  return: Der Index des Bits im Byte, wo der Pixel aufgehöhrt hat. -1, falls der Pixel am ende Des Bytes noch nicht zuende ist
+		__declspec( dllexport ) char addByte( char byte, char begin );
+		// zum speichern gedacht. Setzt die Farbe, die im Pixel gespeichert werden soll
+        //  f: Die zu speichernde Farbe
+		__declspec( dllexport ) void setFarbe( int f );
+        // Komprimiert den Pixel. Muss vor dem Speichern aufgerufen werden.
+		__declspec( dllexport ) void komprimieren();
+        // Gibt ein Teil der Bits zurück, die den Pixel representieren
+        //  byte: Eine Referens auf das Byte, dass als nächstes gespeichert werden soll
+        //  begin: Der Index des ersten Bits im zu speichernden Byte, wo der Pixel gespeichert werden soll
+        //  return: Der Index des Bits im zu speichernden Byte, wo der Pixel aufhöhrt. -1, falls der Pixel im nächsten Byte fortgesetzt werden muss
+		__declspec( dllexport ) char getNextByte( char &byte, int begin );
+        // Gibt den Farbwert des Pixels zurück
+		__declspec( dllexport ) int zuFarbe() const;
+        // Gibt zurück, ob sich der Anteil an Rot in der Farbe im Vergleich zum Pixel davor geändert hat
+		__declspec( dllexport ) bool getÄnderR() const;
+        // Gibt zurück, ob sich der Anteil an Grün in der Farbe im Vergleich zum Pixel davor geändert hat
+		__declspec( dllexport ) bool getÄnderG() const;
+        // Gibt zurück, ob sich der Anteil an Blau in der Farbe im Vergleich zum Pixel davor geändert hat
+		__declspec( dllexport ) bool getÄnderB() const;
+        // Gibt zurück, ob sich der Anteil an Alpha in der Farbe im Vergleich zum Pixel davor geändert hat
+		__declspec( dllexport ) bool getÄnderA() const;
+        // Gibt die Komprimierung des Pixels zurück
+		__declspec( dllexport ) unsigned char getKomp() const;
+        // Gibt den Anteil an Rot in der Farbe des Pixels zurück
+		__declspec( dllexport ) unsigned char getR() const;
+        // Gibt den Anteil an Grün in der Farbe des Pixels zurück
+		__declspec( dllexport ) unsigned char getG() const;
+        // Gibt den Anteil an Blau in der Farbe des Pixels zurück
+		__declspec( dllexport ) unsigned char getB() const;
+        // Gibt den Anteil an Alpha in der Farbe des Pixels zurück
+		__declspec( dllexport ) unsigned char getA() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDBPixel *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDBPixel *release();
+	};
+
+    // Der Kopf des LTDB Dateiformates. Hier werden informationen über alle Abgespeicherten Bilder verwaltet
+	class LTDBDateiKopf
+	{
+	private:
+		RCArray< Text > *bilder;
+		Array< __int64 > *pos;
+		int bAnzahl;
+		int ref;
+
+	public:
+		// konstructor
+		__declspec( dllexport ) LTDBDateiKopf();
+		// destructor 
+		__declspec( dllexport ) ~LTDBDateiKopf();
+		// Entfernt ein Bild aus dem Dateikopf
+        //  i: Der Index des Bildes, welches entfernt werden soll
+		__declspec( dllexport ) void removeBild( int i );
+        // Entfernt ein Bild aus dem Dateikopf
+        //  txt: Der Name des Bildes, welches entfernt werden soll
+		__declspec( dllexport ) void removeBild( Text *txt );
+        // Fügt dem Dateikopf ein Bild hinzu
+        //  txt: Der Name des Bildes.
+		__declspec( dllexport ) void addBild( Text *txt );
+        // Legt den Index des Bytes aus der Datei fest, wo das Bild anfängt
+        //  i: Der index Des Bildes
+        //  pos: Die Position des Bildes in der Datei
+		__declspec( dllexport ) void setBildPos( int i, __int64 pos );
+        // Legt den Index des Bytes aus der Datei fest, wo das Bild anfängt
+        //  txt: Der Name Des Bildes
+        //  pos: Die Position des Bildes in der Datei
+		__declspec( dllexport ) void setBildPos( Text *txt, __int64 pos );
+        // Lädt den Dateikopf einer LTDB Datei
+        //  f: Ein Zeiger auf einen Fortschrittsbalken, der zum Laden verwendet werden soll. Kann 0 sein.
+        //  inF: Der geöffnete ifstream der LTDB Datei, bei dem die Leseposition bereits auf das erste Byte des Dateiopfes zeigt.
+		__declspec( dllexport ) void laden( FBalken *f, std::ifstream *inF );
+		// Speichert den Dateikopf in einer LTDB Datei
+        //  outF: Der geöffnete ofstream der LTDB Datei, bei dem die Schreibposition bereits auf das erste Byte des Dateikopfes zeigt.
+		__declspec( dllexport ) void speichern( std::ofstream *outF ) const;
+        // Gibt den Namen eines bestimmten Bildes zurück
+        //  i: Der Index des Bildes, dessen Namen zurückgegeben werden soll
+        //  return: Der Name des bildes
+		__declspec( dllexport ) Text *getBild( int i ) const;
+        // Gibt den Namen eines bestimmten Bildes zurück
+        //  i: Der Index des Bildes, dessen Namen zurückgegeben werden soll
+        //  return: Der Name des bildes ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zBild( int i ) const;
+        // Gibt den Index des Ersten Bytes eines Bildes in der Datei zurück
+        //  txt: Der Name des Bildes, dessen Beginn gefunden werden soll
+        //  return: -1, falls das Bild nicht gefunden wurde.
+		__declspec( dllexport ) __int64 getBildPosition( Text *txt ) const;
+        // Gibt den Index des Ersten Bytes eines Bildes in der Datei zurück
+        // Fals der Index nicht existiert wird die Exception std::out_of_range geworfen.
+        //  indes: Der Indes des Bildes, dessen Beginn gefunden werden soll
+		__declspec( dllexport ) __int64 getBildPosition( int index ) const;
+        // Gibt den Index eines Bestimmten Bildes zurück
+        //  txt: Der Name des Bildes
+        //  return: -1, falls das Bild nicht gefunden wurde
+		__declspec( dllexport ) int getBildIndex( Text *txt ) const;
+        // Gibt die Anzahl der Bilder in der Datei zurück
+		__declspec( dllexport ) int getbAnzahl() const;
+        // Gibt eine Liste mit Bildern in der Datei ohne erhöhten Reference Counter zurück.
+        // Die Liste sollte nicht verändert werden
+		__declspec( dllexport ) RCArray< Text > *zBildListe() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDBDateiKopf *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDBDateiKopf *release();
+	};
+
+    // Die im LTDB Dateikopf gespeicherten Informationen für ein einzelnes Bild
+	class LTDBKopf
+	{
+	private:
+		__int64 a; // Det LTDB Dateikopf ist maximal 104 Bits lang
+		__int32 b; // - bis zu 75 Bits für den Titel
+		__int8 c;  // - 12 Bits für breite
+		int ref;   // - 12 Bits för höhe
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDBKopf();
+		// Lähdt die Informationen über ein Bild
+        //  f: Der geöffnette und an die richtiege Stelle zeigende ifstream der LTDB Datei
+		__declspec( dllexport ) void laden( std::ifstream *f );
+        // Setzt die Informationen die gespeichert werden sollen
+        //  titel: Der Titel des Bildes
+        //  größe: Die Größe des Bildes
+        //  return: Die Anzahl der Buchstaben aus dem Titel, die im LTDB Dateiformat nicht gespeichert werden können. Erlaubt ist nur a-z und A-Z und ä ü ö ß und Ä Ü Ö und .
+        // Alle großbuchstaben im Titel werden in Kleinbuchstaben umgewandelt
+		__declspec( dllexport ) int Init( Text *titel, const Punkt &größe );
+        // Lähd informationen aus geladenen Bits. Wird von der laden( std::ifstream ) Funktion verwendet.
+        //  BeginBit: Der Index des ersten Bits, welches ausgewertet werden soll
+        //  EndBit: Der Index des letzten Bits, welches nichtmehr ausgewertet werden soll
+        //  bits: Die Bits, von denen alle von BeginBit bis EndBit ausgewertet werden sollen
+        // Insgesamt müssen 104 Bits gesetzt werden. Hierauf bezihen sich BeginBit und EndBit
+		__declspec( dllexport ) void setBits( int BeginBit, int EndBit, __int16 bits );
+		// Speichert die Informationen in eine Datei
+        //  f: Der geöffnete und an die richtiege Stelle zeigende ofstream der LTDB Datei
+		__declspec( dllexport ) void speichern( std::ofstream *f ) const;
+        // Gibt die Länge des Titels zurück
+		__declspec( dllexport ) int getTitelLänge() const;
+        // Gibt den Titel des Bildes zurück
+		__declspec( dllexport ) Text *getTitel() const;
+        // Gibt die Größe des Bildes zurück
+		__declspec( dllexport ) Punkt getGröße() const;
+        // Gibt die nächsten zu speichernden Bits zurück
+        //  begin: Der Index des ersten Bits, in das gespeichert werden soll
+        //  end: Der Index des letzten Bits, in das gespeichert werden soll
+        //  return: 16 Bits, in denen die Informationen zwischen begin und end stehen
+        // Insgesamt müssen 104 Bits gelesen werden. Hierauf bezihen sich BeginBit und EndBit
+		__declspec( dllexport ) __int16 getBits( int begin, int end )const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDBKopf *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDBKopf *release();
+	};
+
+    // Verwaltet die Pixeldaten eines einzelnen Bildes einer LTDB Datei
+	class LTDBKörper
+	{
+	private:
+		Punkt gr;
+		Bild *b;
+		int dateiLänge;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDBKörper();
+        // Konstruktor
+        //  k: Der LTDB Kopf des Bildes, der Informationen über die Größe des Bildes enthält
+		__declspec( dllexport ) LTDBKörper( LTDBKopf *k );
+		// Destruktor 
+		__declspec( dllexport ) ~LTDBKörper();
+		// Setzt die Informationen über die Größe des Bildes. Wird zum Laden benötigt.
+        //  k: Der LTDB Kopf des Bildes
+		__declspec( dllexport ) void init( LTDBKopf k );
+		// Setzt die Informationen über die Größe des Bildes. Wird zum Laden benötigt.
+        //  k: Der LTDB Kopf des Bildes
+		__declspec( dllexport ) void init( LTDBKopf *k );
+        // Lädt die Pixeldaten aus der Datei
+        //  zF: Ein Fortschrittsbalken, der 0 sein kann
+        //  inF: Der geöffnete und an die richtiege Stelle zeigende ifstream der LTDB Datei
+		__declspec( dllexport ) void laden( FBalken *zF, std::ifstream *inF );
+        // Setzt das Bild, welches gespeichert werden soll
+        //  b: Das zu speichernde Bild
+		__declspec( dllexport ) void setBild( Bild *b );
+		// Speichert die Pixeldaten des Bildes in einer LTDB Datei
+        //  zF: Ein Fortschrittsbalken, der 0 sein kann
+        //  outF: Der geöffnete und an die richtiege Stelle zeigende ofstream der LTDB Datei
+		__declspec( dllexport ) void speichern( FBalken *zF, std::ofstream *outF ) const;
+        // Gibt das geladene Bild zurück
+		__declspec( dllexport ) Bild *getBild() const;
+        // Gibt die Größe des Bildes zurück
+        __declspec( dllexport ) const Punkt &getGröße() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDBKörper *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDBKörper *release();
+	};
+
+    // Verwaltet eine LTDB Datei
+	class LTDBDatei
+	{
+	private:
+		Text *pfad;
+		LTDBDateiKopf *datKpf;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDBDatei();
+		// Destruktor 
+		__declspec( dllexport ) ~LTDBDatei();
+		// Setzt den Pfad zu Datei
+        //  pfad: Der Pfad
+		__declspec( dllexport ) void setDatei( Text *pfad );
+        // Erstellt eine neue LTDB Datei
+		__declspec( dllexport ) void erstellen();
+        // Ließt grundlegende Informationen aus der Datei.
+        // Wird benötigt, bevor mit der Datei gearbeitet wird
+        //  zF: Ein Fortschrittsbalken, der 0 sein kann
+		__declspec( dllexport ) void leseDaten( FBalken *zF );
+        // Löscht die LTDB Datei
+		__declspec( dllexport ) void löschen();
+        // Löscht ein Bild aus der LTDB Datei
+        //  zF: Ein Fortschrittsbalken der 0 sein kann
+        //  name: Der Name des zu löschenden Bildes
+		__declspec( dllexport ) void löschen( FBalken *zF, Text *name );
+        // Lädt ein Bild aus der LTDB Datei
+        //  zF: Ein Fortschrittsbalken, der 0 sein kann
+        //  name: Der Name des Bildes, welches geladen werden soll
+        //  return: Das geladene Bild. 0, falls das Bild nicht gefunden wurde
+		__declspec( dllexport ) Bild *laden( FBalken *zF, Text *name );
+        // Speichert ein neues Bild in der LTDB Datei
+        //  zF: Ein Fortscrittsbalken, der 0 sein kann
+        //  bild: Das Bild, welches gelöscht werden soll
+        //  name: Der Name, unter dem das Bild gespeichert werden soll
+        //  return: Anzahl der Warnungen, die beim Konvertieren des Namens in einen gültigen Namen aufgetreten sind. -1, falls bereis ein Bild mit dem selben Namen existiert
+		__declspec( dllexport ) int speichern( FBalken *zF, Bild *bild, Text *name );
+        // Gibt eine Liste mit gespeicherten Bildern zurück
+        // Die Liste sollte nicht verändert werden
+		__declspec( dllexport ) RCArray< Text > *zBildListe();
+		// Gibt den Pfad zur LTDB Datei zurück
+		__declspec( dllexport ) Text *getPfad() const;
+        // Gibt die Anzahl der Bilder in der LTDB Datei zurück
+		__declspec( dllexport ) int getBildAnzahl() const;
+        // Prüft, ob die LTDB Datei existiert
+		__declspec( dllexport ) bool istOffen() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDBDatei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDBDatei *release();
+	};
+
+#ifdef WIN32
+	// LTDS Dateivormat --- Dient zum speichern von Schriftarten
+
+    // Verwaltet einen einzelnen Pixel von einem Buchstaben
+	class LTDSPixel
+	{
+	private:
+		int ref;
+		char index;
+		char iA;
+		char miA;
+		char maxIndex; // Länge des Pixels
+		bool änder;
+		bool änderA;
+		unsigned char komp : 3; // Komprimierung der Farbwerte
+		unsigned char alpha;
+		LTDSPixel *davor;
+		bool addBitZuFarbe( unsigned char bit ); // Fügt den Farbwerten ein Bit hinzu
+		bool getNextFarbeBit( char &byte, int i ); // Speichert das nächste Farbbit in byte
+
+	public:
+		// Konstruktor
+        //  davor: Der Pixel, der vor diesem geladen wurde. 0, fals dieß der erste Pixel ist
+		__declspec( dllexport ) LTDSPixel( LTDSPixel *davor );
+		// Destruktor 
+		__declspec( dllexport ) ~LTDSPixel();
+		// Fügt dem Pixel einiege geladene Bits hinzu. Zum Laden gedacht.
+        //  byte: Das letzte aus der Datei geladene Byte.
+        //  begin: Der Index des ersten Bits im Byte, wo der Pixel beginnt
+        //  return: Der Index des Letzten Bits in Byte, wo der Pixel aufhöhrt. -1, falls der Pixel im nächsten Byte weitergeht
+		__declspec( dllexport ) char addByte( char byte, char begin );
+		// Setzt den Alpha Wert des Pixels. Zum speichern gedacht.
+        //  alpha: Der Alpha Wert des Pixels.
+		__declspec( dllexport ) void setAlpha( unsigned char alpha );
+        // Komprimiert den Pixel. Muss vor dem Speichern aufgerufen werden.
+		__declspec( dllexport ) void Komp();
+        // Gibt ein Teil der Bits zurück, die den Pixel representieren
+        //  byte: Eine Referens auf das Byte, dass als nächstes gespeichert werden soll
+        //  begin: Der Index des ersten Bits im zu speichernden Byte, wo der Pixel gespeichert werden soll
+        //  return: Der Index des Bits im zu speichernden Byte, wo der Pixel aufhöhrt. -1, falls der Pixel im nächsten Byte fortgesetzt werden muss
+		__declspec( dllexport ) char getNextByte( char &byte, int bbegin );
+        // Gibt die Komprimierung des Pixels zurück
+		__declspec( dllexport ) unsigned char getKomp() const;
+        // Gibt zurück, ob sich der Alpha Wert im Vergleich zu dem Pixel davor geändert hat
+		__declspec( dllexport ) bool getÄnderA() const;
+        // Gibt den Alpha Wert des Pixels zurück
+		__declspec( dllexport ) unsigned char getA() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSPixel *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSPixel *release();
+	};
+
+    // Verwaltet den Kopf einer LTDS Datei. Er enthält Informationen über die in der Datei gespeicherten Schriftgrößen
+	class LTDSDateiKopf
+	{
+	private:
+		int ref;
+		unsigned char sganzahl;
+		unsigned char *gr;
+		int *pos;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDSDateiKopf();
+		// Destruktor 
+		__declspec( dllexport ) ~LTDSDateiKopf();
+		// Lädt den Kopf aus der LTDS Datei
+        //  inF: Der geöffnete und an die richtige Stelle zeigende ifstream der LTDS Datei
+		__declspec( dllexport ) void laden( std::ifstream *inF );
+        // Fügt eine Schriftgröße hinzu
+        //  sg: Die Schriftgröße, die hinzugefügt werden soll
+		__declspec( dllexport ) void addSG( char sg );
+        // Löscht eine Schriftgröße
+        //  sg: Die Schriftgröße, die gelöscht werden soll
+		__declspec( dllexport ) void removeSG( char sg );
+        // Speichert den LTDS Kopf in der Datei
+        //  outF: Der geöffnete und an die richtiege Stelle zeigende ofstream der LTDS Datei
+		__declspec( dllexport ) void speichern( std::ofstream *outF ) const;
+        // Gibt einen Array von gespeicherten Schriftgrößen zurück
+        // Der Array sollte nicht verädert werden
+		__declspec( dllexport ) unsigned char *getSchriftGrößeList() const;
+        // Gibt einen Array mit positionen der ersten Bytes für jede Schriftgröße aus der Datei zurück
+        __declspec( dllexport ) int *getPositionList() const;
+        // Gibt die Anzahl der gespeicherten Schriftgrößen zurück
+		__declspec( dllexport ) int getSchriftGrößeAnzahl() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSDateiKopf *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSDateiKopf *release();
+	};
+
+    // Der Kopf einer Schriftgröße. Enthält Informationen über die gespeicherten Zeichen
+	class LTDSSchriftKopf
+	{
+	private:
+		int ref;
+		unsigned char schriftGröße;
+		unsigned char *zeichen;
+		int *pos;
+		unsigned char zeichenAnzahl;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDSSchriftKopf();
+		// Destruktor 
+		__declspec( dllexport ) ~LTDSSchriftKopf();
+		// Lädt den Kopf einer Schriftgröße aus der Datei
+        //  inF: Der geöffnete und an de richtiege Stelle zeigende ifstream der LTDS Datei
+		__declspec( dllexport ) void laden( std::ifstream *inF );
+        // Setzt die Schriftgröße. Zum speichern gedacht
+        //  gr: Die Schriftgröße
+		__declspec( dllexport ) void setSchriftgröße( unsigned char gr );
+        // Setzt das Alphabet, welches in der Schriftgröße gespeichert werden soll
+        //  alphabet: Das Alphabet, welches alle zu speichernden Zeichen in der Schriftgröße enthält
+		__declspec( dllexport ) void setZeichenAlphabet( Alphabet *alphabet );
+        // Fügt der Schriftgröße ein Zeichen hinzu, welches gespeichert werden soll
+        //  zeichen: Der ASCII code des Zeichens, welches hinzugefügt werden soll
+		__declspec( dllexport ) void addZeichen( unsigned char zeichen );
+        // Löscht ein Zeichen aus der Schriftgröße
+        //  zeich: Der ASCII code des Zeichens, welches gelöscht werden soll
+        __declspec( dllexport ) void removeZeichen( unsigned char zeich );
+		// Speichert den Kopf der Schriftgröße in der LTDS Datei
+        //  outF: Der geöffnete und an die richtiege Stelle zeigende ofstream der LTDS Datei
+		__declspec( dllexport ) void speichern( std::ofstream *outF ) const;
+        // Gibt die Schriftgröße zurück, zu der dieser Kopf gehöhrt
+		__declspec( dllexport ) unsigned char getSchriftGröße() const;
+        // Gibt die Anzahl der in der Schriftgröße gespeicherten Zeichen zurück
+		__declspec( dllexport ) unsigned char getZeichenAnzahl() const;
+        // Gibt einen Array mit den Positionen der ersten Bytes von den gespeicherten Zeichen aus der LTDS Datei zurück 
+		__declspec( dllexport ) int *getPositionen() const;
+        // Gibt einen Array mit den ASCII codes der Gespeicherten Zeichen zurück
+		__declspec( dllexport ) unsigned char *getZeichen() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSSchriftKopf *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSSchriftKopf *release();
+	};
+
+    // Der Kopf eines einzelnen Zeichens aus der LTDS Datei. Enthält informationen über die Pixelgröße des Zeichens
+	class LTDSBuchstabenKopf
+	{
+	private:
+		int ref;
+		unsigned char zeichen;
+		Punkt größe;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDSBuchstabenKopf();
+		// Lädt die Daten aus der LTDS Datei
+        //  inF: Der geöffnete und an die richtiege Stelle zeigende ifstream der LTDS Datei
+		__declspec( dllexport ) void laden( std::ifstream *inF );
+        // Setzt die Daten, die gespeichert werden sollen.
+        //  zeichen: Der ASCII code des Zeichens
+        //  größe: Die Größe des Zeichens in Pixeln
+		__declspec( dllexport ) void init( unsigned char zeichen, const Punkt &größe );
+        // Setzt die Daten, die gespeichert werden sollen.
+        //  zeichen: Der ASCII code des Zeichens
+        //  br: Die Breite des Zeichens in Pixeln
+        //  hö: Die Höhe des Zeichens in Pixeln
+		__declspec( dllexport ) void init( unsigned char zeichen, int br, int hö );
+		// Speichert die Daten in der LTDS Datei
+        //  outF: Der geöffnete und auf die richtiege Stelle zeigende ofstream der LTDS Datei
+		__declspec( dllexport ) void speichern( std::ofstream *outF ) const;
+        // Gibt den ASCII code des Zeichens zurück
+		__declspec( dllexport ) unsigned char getZeichen() const;
+        // Gibt die Breite des Zeichens in Pixeln zurück
+		__declspec( dllexport ) int getBreite() const;
+        // Gibt die Höhe des Zeichens in Pixeln zurück
+        __declspec( dllexport ) int getHöhe() const;
+        // Gib t die Größe des Zeichens in Pixeln zurück
+        __declspec( dllexport ) const Punkt &getGröße() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSBuchstabenKopf *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSBuchstabenKopf *release();
+	};
+
+    // Verwaltet die Pixeldaten eines Zeichens
+	class LTDSBuchstabenKörper
+	{
+	private:
+		int ref;
+		Punkt größe;
+		unsigned char zeichen;
+		Buchstabe *buchstabe;
+
+	public:
+		// Konstruktor
+        //  kopf: Der Kopf des Zeichens
+		__declspec( dllexport ) LTDSBuchstabenKörper( LTDSBuchstabenKopf *kopf );
+		// Destruktor 
+		__declspec( dllexport ) ~LTDSBuchstabenKörper();
+		// Setzt den Buchstaben, der gespeichert werden soll
+        //  zeichen: Der zu speichernde Buchstabe
+		__declspec( dllexport ) void setBuchstabe( Buchstabe *zeichen );
+        // Lädt die Pixel aus der LTDS Datei
+        //  inF: Der geöffnete und auf die richtiege Stelle zeigende ifstream der LTDS Datei
+		__declspec( dllexport ) void laden( std::ifstream *inF );
+		// Speichert die Pixel in die LTDS Datei
+        //  outF: der geöffnete und an die richtiege Stelle zeigende ofstream der LTDS Datei
+		__declspec( dllexport ) void speichern( std::ofstream *outF ) const;
+        // Gibt den geladenen Buchstaben zurück
+		__declspec( dllexport ) Buchstabe *getBuchstabe() const;
+        // Gibt den ASCII code des Buchstabens zurück
+		__declspec( dllexport ) unsigned char getZeichen() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSBuchstabenKörper *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSBuchstabenKörper *release();
+	};
+
+    // Verwaltet eine LTDS Datei
+	class LTDSDatei
+	{
+	private:
+		int ref;
+		Text *pfad;
+		LTDSDateiKopf *dateiKopf;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LTDSDatei();
+		// Destruktor 
+		__declspec( dllexport ) ~LTDSDatei();
+		// Setzt den Pfad zur Datei
+        //  txt: Der Pfad
+		__declspec( dllexport ) void setPfad( Text *txt );
+        // Lädt wichtiege Informationen aus der Datei. Muss vor dem Verwenden der Datei aufgerufen werden
+		__declspec( dllexport ) void leseDaten();
+        // Fügt der Datei eine Schriftgröße hinzu, fals diese noch nicht existiert
+        //  alphabet: Das Alphabet, welches die Zeichen in der gewünschten Schriftgrö0e enthält
+		__declspec( dllexport ) void addSchriftgröße( Alphabet *alphabet );
+        // Fügt einer Schriftgröße einen Buchstaben hinzu
+        //  gr: Die Schriftgröße des Buchstabens
+        //  zeich: Der Buchstabe, der gespeichert werden soll
+        //  zeichen: Der ASCII code des Buchstabens
+		__declspec( dllexport ) void addBuchstabe( int gr, Buchstabe *zeich, unsigned char zeichen );
+        // Löscht eine bestimmte Schriftgröße aus der Datei
+        //  gr: Die Schriftgröße, die entfernt werden soll
+		__declspec( dllexport ) void löscheSchrifrGröße( int gr );
+        // Löscht einen Buchstaben aus einer Schriftgröße
+        //  gr: Die Schriftgröße, aus der der Buchstabe entfernt werden soll
+        //  zeichen: Der ASCII code des Zeichens, welches gelöscht werden soll
+		__declspec( dllexport ) void löscheBuchstabe( int gr, unsigned char zeichen );
+        // Löscht die LTDS Datei
+		__declspec( dllexport ) void löscheDatei();
+        // Erstellt die LTDS Datei
+        __declspec( dllexport ) void erstelleDatei();
+        // Speichert eine gesammte Schrift in der Datei
+        //  schrift: Die schrift, die gespeichert werden soll
+		__declspec( dllexport ) void speicherSchrift( Schrift *schrift );
+		// Lädt die gesammte Schrift aus der Datei
+        //  return: Die geladene Schrift. 0, falls ein Fehler beim Laden aufgetreten ist
+		__declspec( dllexport ) Schrift *ladeSchrift();
+        // Lädt eine einzelne Schriftgröße aus der Datei
+        //  schriftgröße: Die zu ladende Schriftgröße
+        //  return: Ein Alphabet mit den Zeichen in der Schriftgröße. 0, falls die Schriftgröße nicht gefunden wurde
+		__declspec( dllexport ) Alphabet *ladeAlphabet( int schriftgröße ); 
+        // Lädt ein bestimmtes Zeichen einer bestimmten Schriftgröße
+        //  schriftgröße: Die Schriftgröße, zu dem das Zeichen gehört
+        //  zeichen: Der ASCII code des zu ladenden Zeichens
+        //  return: Der geladene Buchstabe. 0, falls das Zeichen nicht gefunden wurde.
+		__declspec( dllexport ) Buchstabe *ladeBuchstabe( int schriftgröße, unsigned char zeichen );
+        // Gibt den Pfad zur LTDS Datei zurück
+		__declspec( dllexport ) Text *getPfad() const;
+        // Gibt die Anzahl der gespeicherten Schriftgrößen zurück
+		__declspec( dllexport ) int getAnzahlSchriftgrößen() const;
+        // Gibt einen Array mit den gespeicherten Schriftgrößen zurück
+        // Der Array sollte nicht verändert werden
+		__declspec( dllexport ) unsigned char *getSchriftGrößen() const;
+        // Gibt die Anzahl an gespeicherten Zeichen in einer Schriftgröße zurück
+        //  sg: Die Schriftgröße, von der die Anzahl der ZEichen ermittelt werden soll
+        //  return: Die Anzahl der Zeichen.
+		__declspec( dllexport ) unsigned char getAnzahlBuchstaben( int sg );
+        // Gibt einen Array mit Buchstaben einer bestimmten Schriftgröße zurück
+        //  sg: Die Schriftgröße
+        //  return: Der Array mit den ASCII codes der Zeichen. 0, falls die Schriftgröße nicht gefunden wurde.
+		__declspec( dllexport ) unsigned char *getBuchstaben( int sg );
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) LTDSDatei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) LTDSDatei *release();
+	};
+#endif
+	// Bit Funktionen 
+
+    // gibt 1-bits in gewinschter anzahl zurück.
+    //  a: Die Anzahl der Bits, die 1 sein sollen
+    //  return: 32 Bits, wobei die einser Bits von rechts beginnen
+	__declspec( dllexport ) int Bits( int a );
+    // Gibt zurück, wie viele Bits benötigt werden um eine Zahl darzustellen
+    //  c: Die Zahl, die dargestellt werden soll
+    //  return: Die Anzahl der benötigten Bits
+	__declspec( dllexport ) int getBits( char c );
+}
+#endif

+ 104 - 0
DefaultShader.h

@@ -0,0 +1,104 @@
+#pragma once
+
+#include "Text.h"
+namespace Framework
+{
+    // Gibt einen simplen Vertex Shader zurück
+    //  ret: Eine Reference auf ein Text objekt, in dem der Shader gespeichert werden soll
+    void getVertexShader( Text &ret )
+    {
+        ret = "////////////////////////////////////////////////////////////////////////////////         \n\
+        // Filename: texture.vs                                                                         \n\
+        ////////////////////////////////////////////////////////////////////////////////                \n\
+                                                                                                        \n\
+                                                                                                        \n\
+        /////////////                                                                                   \n\
+        // GLOBALS //                                                                                   \n\
+        /////////////                                                                                   \n\
+        cbuffer MatrixBuffer                                                                            \n\
+        {                                                                                               \n\
+            matrix worldMatrix;                                                                         \n\
+            matrix viewMatrix;                                                                          \n\
+            matrix projectionMatrix;                                                                    \n\
+        };                                                                                              \n\
+                                                                                                        \n\
+                                                                                                        \n\
+        //////////////                                                                                  \n\
+        // TYPEDEFS //                                                                                  \n\
+        //////////////                                                                                  \n\
+        struct VertexInputType                                                                          \n\
+        {                                                                                               \n\
+            float4 position : POSITION;                                                                 \n\
+            float2 tex : TEXCOORD0;                                                                     \n\
+        };                                                                                              \n\
+                                                                                                        \n\
+        struct PixelInputType                                                                           \n\
+        {                                                                                               \n\
+            float4 position : SV_POSITION;                                                              \n\
+            float2 tex : TEXCOORD0;                                                                     \n\
+        };                                                                                              \n\
+                                                                                                        \n\
+                                                                                                        \n\
+        ////////////////////////////////////////////////////////////////////////////////                \n\
+        // Vertex Shader                                                                                \n\
+        ////////////////////////////////////////////////////////////////////////////////                \n\
+        PixelInputType TextureVertexShader( VertexInputType input )                                     \n\
+        {                                                                                               \n\
+            //return input;                                                                             \n\
+            PixelInputType output;                                                                      \n\
+                                                                                                        \n\
+            // Change the position vector to be 4 units for proper matrix calculations.                 \n\
+            input.position.w = 1.0f;                                                                    \n\
+                                                                                                        \n\
+            // Store the texture coordinates for the pixel shader.                                      \n\
+            output.tex = input.tex;                                                                     \n\
+                                                                                                        \n\
+            // Calculate the position of the vertex against the world, view, and projection matrices.   \n\
+            output.position = input.position;                                                           \n\
+            output.position = mul( input.position, worldMatrix );                                       \n\
+            output.position = mul( output.position, viewMatrix );                                       \n\
+            output.position = mul( output.position, projectionMatrix );                                 \n\
+                                                                                                        \n\
+            return output;                                                                              \n\
+        }";
+    }
+
+
+    // Gibt einen simplen Pixel Shader zurück
+    //  ret: Eine Reference auf ein Text objekt, in dem der Shader gespeichert werden soll
+    void getPixelShader( Text &ret )
+    {
+        ret = "////////////////////////////////////////////////////////////////////////////////                  \n\
+        // Filename: texture.ps                                                                                  \n\
+        ////////////////////////////////////////////////////////////////////////////////                         \n\
+                                                                                                                 \n\
+                                                                                                                 \n\
+        /////////////                                                                                            \n\
+        // GLOBALS //                                                                                            \n\
+        /////////////                                                                                            \n\
+        Texture2D shaderTexture;                                                                                 \n\
+        SamplerState SampleType;                                                                                 \n\
+                                                                                                                 \n\
+                                                                                                                 \n\
+        //////////////                                                                                           \n\
+        // TYPEDEFS //                                                                                           \n\
+        //////////////                                                                                           \n\
+        struct PixelInputType                                                                                    \n\
+        {                                                                                                        \n\
+            float4 position : SV_POSITION;                                                                       \n\
+            float2 tex : TEXCOORD0;                                                                              \n\
+        };                                                                                                       \n\
+                                                                                                                 \n\
+                                                                                                                 \n\
+        ////////////////////////////////////////////////////////////////////////////////                         \n\
+        // Pixel Shader                                                                                          \n\
+        ////////////////////////////////////////////////////////////////////////////////                         \n\
+        float4 TexturePixelShader( PixelInputType input ) : SV_TARGET                                            \n\
+        {                                                                                                        \n\
+            //return float4( 0.5, 0.5, 0.5, 0.5 );                                                               \n\
+            // Sample the pixel color from the texture using the sampler at this texture coordinate location.    \n\
+            float4 textureColor = shaderTexture.Sample( SampleType, input.tex );                                 \n\
+            return textureColor;                                                                                 \n\
+        }";
+    }
+}

+ 2019 - 0
Diagramm.cpp

@@ -0,0 +1,2019 @@
+#include "Diagramm.h"
+#include "Text.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include "Rahmen.h"
+#include "Schrift.h"
+#include "Scroll.h"
+#include "MausEreignis.h"
+#include "ToolTip.h"
+#include <math.h>
+
+using namespace Framework;
+
+// Inhalt der SLDiag Klasse aus Diagramm.h
+// Konstruktor 
+SLDiag::SLDiag()
+    : ZeichnungHintergrund(),
+    gF( 0xFF000000 ),
+    lFarbe( new Array< int >() ),
+    lName( new RCArray< Text >() ),
+    ph( new RCArray< Array< int > >() ),
+    pb( new RCArray< Array< int > >() ),
+    lastValue( new Array< int >() ),
+    schrift( 0 ),
+    gitterGr( 0, 0 ),
+    lines( 0 ),
+    ref( 1 )
+{
+    style = 0;
+}
+
+// Destruktor 
+SLDiag::~SLDiag()
+{
+    lFarbe->release();
+    lName->release();
+    ph->release();
+    pb->release();
+    lastValue->release();
+    if( schrift )
+        schrift->release();
+}
+
+// nicht constant 
+void SLDiag::setSchriftZ( Schrift *schrift ) // setzt die Schrift
+{
+    if( this->schrift )
+        this->schrift->release();
+    this->schrift = schrift;
+    rend = 1;
+}
+
+void SLDiag::setGGröße( Punkt &gr ) // setzt die Größe des Gitters
+{
+    gitterGr = gr;
+    rend = 1;
+}
+
+void SLDiag::setGFarbe( int f ) // setzt die Gitter Farbe
+{
+    gF = f;
+    rend = 1;
+}
+
+void SLDiag::addLinie( const char *name ) // fügt eine Linie hinzu
+{
+    addLinie( new Text( name ) );
+    rend = 1;
+}
+
+void SLDiag::addLinie( Text *txt )
+{
+    lFarbe->add( 0xFFFFFFFF, lines );
+    lName->add( txt, lines );
+    ph->add( new Array< int >(), lines );
+    pb->add( new Array< int >(), lines );
+    int rbr = rahmen && hatStyle( Style::Rahmen ) ? rahmen->getRBreite() : 0;
+    pb->z( lines )->set( gr.x - rbr * 2, 0 );
+    ++lines;
+    rend = 1;
+}
+
+void SLDiag::setLFarbe( int lNum, int f ) // setzt die Linienfarbe
+{
+    lFarbe->set( f, lNum );
+    rend = 1;
+}
+
+void SLDiag::addPunkt( int lNum, int x, int h ) // fügt einen Punkt hinzu
+{
+    Array< int > *ph_tmp = ph->z( lNum );
+    Array< int > *pb_tmp = pb->z( lNum );
+    if( ph_tmp && pb_tmp )
+    {
+        int i = pb_tmp->get( 0 );
+        i -= x;
+        if( i >= 0 )
+            pb_tmp->set( i, 0 );
+        while( i < 0 )
+        {
+            ph_tmp->lösche( 0 );
+            pb_tmp->lösche( 0 );
+            if( !pb_tmp->getEintragAnzahl() || !ph_tmp->getEintragAnzahl() )
+                break;
+            int ii = -i;
+            i = pb_tmp->get( 0 );
+            i -= ii;
+            pb_tmp->set( i, 0 );
+        }
+        pb_tmp->add( x );
+        ph_tmp->add( h );
+        lastValue->set( h, lNum );
+    }
+    rend = 1;
+}
+
+void SLDiag::removeLinie( int lNum ) // entfernt eine Linie
+{
+    lFarbe->lösche( lNum );
+    lName->lösche( lNum );
+    ph->lösche( lNum );
+    pb->lösche( lNum );
+    --lines;
+    rend = 1;
+}
+
+void SLDiag::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+    if( hatStyle( Style::Sichtbar ) )
+    {
+        lockZeichnung();
+        löscheStyle( Style::VScroll | Style::HScroll );
+        __super::render( zRObj );
+        if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+        {
+            unlockZeichnung();
+            return;
+        }
+        int hv = getHöchstValue();
+        hv = hv ? hv : 1;
+        double yFaktor = innenGröße.y / hv;
+        if( hatStyle( Style::Gitter ) )
+        {
+            double ghö = gitterGr.y * yFaktor;
+            int yo = innenGröße.y - 1;
+            int bo = innenGröße.x, ho = innenGröße.y;
+            int maxBr = (int)( (double)innenGröße.x / gitterGr.x + 0.5 );
+            int maxHö = ghö ? (int)( innenGröße.y / ghö + 0.5 ) : 0;
+            if( hatStyle( Style::HAlpha ) )
+            {
+                for( int i = 0; i < maxBr; ++i )
+                    zRObj.drawLinieVAlpha( gitterGr.x * i, 0, ho, gF );
+                for( int i = 0; i < maxHö; ++i )
+                    zRObj.drawLinieHAlpha( 0, (int)( yo - ghö * i + 0.5 ), bo, gF );
+            }
+            else
+            {
+                for( int i = 0; i < maxBr; ++i )
+                    zRObj.drawLinieV( gitterGr.x * i, 0, ho, gF );
+                for( int i = 0; i < maxHö; ++i )
+                    zRObj.drawLinieH( 0, (int)( yo - ghö * i + 0.5 ), bo, gF );
+            }
+        }
+        for( int i = 0; i < lines; ++i )
+        {
+            int f_tmp = lFarbe->hat( i ) ? lFarbe->get( i ) : 0;
+            Text *n_tmp = lName->z( i );
+            Array< int > *ph_tmp = ph->z( i );
+            Array< int > *pb_tmp = pb->z( i );
+            if( hatStyle( Style::LinienName ) && schrift && n_tmp )
+            {
+                schrift->setSchriftGröße( 12 );
+                schrift->setDrawPosition( 5, 5 + 15 * i );
+                Text rtxt = n_tmp->getText();
+                rtxt += ": ";
+                rtxt += lastValue->get( i );
+                schrift->renderText( &rtxt, zRObj, f_tmp );
+            }
+            if( ph_tmp && pb_tmp )
+            {
+                int lastX = 0;
+                int lastY = innenGröße.y - 1;
+                int ph_anz = ph_tmp->getEintragAnzahl();
+                int pb_anz = pb_tmp->getEintragAnzahl();
+                for( int ii = 0; ii < ph_anz && ii < pb_anz; ++ii )
+                {
+                    if( !ph_tmp || !pb_tmp )
+                        break;
+                    int xpos = lastX + pb_tmp->get( ii );
+                    int ypos = innenGröße.y - (int)( ph_tmp->get( ii ) * yFaktor + 0.5 ) - 1;
+                    if( ypos == -1 )
+                        ++ypos;
+                    if( ypos < 0 || xpos < 0 )
+                        break;
+                    if( hatStyle( Style::HAlpha ) )
+                        zRObj.drawLinieAlpha( Punkt( lastX, lastY ), Punkt( xpos, ypos ), f_tmp );
+                    else
+                        zRObj.drawLinie( Punkt( lastX, lastY ), Punkt( xpos, ypos ), f_tmp );
+                    lastX = xpos;
+                    lastY = ypos;
+                }
+            }
+        }
+        zRObj.releaseDrawOptions();
+        unlockZeichnung();
+    }
+}
+
+// constant
+Schrift *SLDiag::getSchrift() const // gibt die Schrift zurück
+{
+    if( schrift )
+        return schrift->getThis();
+    return 0;
+}
+
+Schrift *SLDiag::zSchrift() const
+{
+    return schrift;
+}
+
+const Punkt &SLDiag::getGGröße() const // gibt die Gitter Größe zurück
+{
+    return gitterGr;
+}
+
+int SLDiag::getGFarbe() const // gibt die Gitter Farbe zurück
+{
+    return gF;
+}
+
+int SLDiag::getLinienNummer( const char *name ) const // gibt die Linien Nummer zurück
+{
+    for( int i = 0; i < lines; ++i )
+    {
+        if( lName->z( i )->istGleich( name ) )
+            return i;
+    }
+    return -1;
+}
+
+int SLDiag::getLinienNummer( Text *name ) const
+{
+    for( int i = 0; i < lines; ++i )
+    {
+        if( lName->z( i )->istGleich( name->getText() ) )
+        {
+            name->release();
+            return i;
+        }
+    }
+    name->release();
+    return -1;
+}
+
+Text *SLDiag::getLinienName( int lNum ) const // gibt den Linien Namen zurück
+{
+    return lName->get( lNum );
+}
+
+Text *SLDiag::zLinienNamen( int lNum ) const
+{
+    return lName->z( lNum );
+}
+
+int SLDiag::getHöchstValue() const // gibt den Höchsten Wert zurück
+{
+    int ret = 0;
+    for( int i = 0; i < lines; ++i )
+    {
+        int tmp = getHöchstValue( i );
+        ret = ret >= tmp ? ret : tmp;
+    }
+    return ret;
+}
+
+int SLDiag::getHöchstValue( int lNum ) const
+{
+    int ret = 0;
+    Array< int > *tmp = ph->z( lNum );
+    int anz = tmp->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+        ret = ret >= tmp->get( i ) ? ret : tmp->get( i );
+    return ret;
+}
+
+int SLDiag::getMedian( int lNum ) const // gibt den durchschnittswert zurück
+{
+    int count;
+    int all = 0;
+    Array< int > *tmp = ph->z( lNum );
+    int anz = tmp->getEintragAnzahl();
+    for( count = 1; count <= anz; ++count )
+        all += tmp->get( count - 1 );
+    return (int)( (double)all / count + 0.5 );
+}
+
+int SLDiag::getLAnzahl() const // gibt die Linien Anzahl zurück
+{
+    return lines;
+}
+
+int SLDiag::getLastValue( int lNum ) const // gibt den letzten Wert zurück
+{
+    return lastValue->get( lNum );
+}
+
+// Reference Counting 
+SLDiag *SLDiag::getThis()
+{
+    ++ref;
+    return this;
+}
+
+SLDiag *SLDiag::release()
+{
+    --ref;
+    if( ref == 0 )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der DiagWert Struktur aus Diagramm.h
+// Konstruktor
+DiagWert::DiagWert()
+    : style( 0 ),
+    farbe( 0xFFFFFFFF ),
+    hintergrund( 0 ),
+    name( new Text() ),
+    punkte( new Array< DiagPunkt* > ),
+    ref( 1 )
+{}
+
+// Destruktor
+DiagWert::~DiagWert()
+{
+    name->release();
+    int anz = punkte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( punkte->hat( i ) )
+            delete punkte->get( i );
+    }
+    punkte->release();
+}
+
+// Referenc Counting
+DiagWert *DiagWert::getThis()
+{
+    ++ref;
+    return this;
+}
+
+DiagWert *DiagWert::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der DiagDaten Struktur aus Diagramm.h
+// Konstruktor
+DiagDaten::DiagDaten()
+    : style( 0 ),
+    rasterDicke( 0 ),
+    rasterBreite( 0 ),
+    rasterHöhe( 0 ),
+    rasterFarbe( 0 ),
+    hIntervallFarbe( 0xFFFFFFFF ),
+    vIntervallFarbe( 0xFFFFFFFF ),
+    hIntervallName( new Text() ),
+    vIntervallName( new Text() ),
+    hIntervallTexte( new RCArray< Text > ),
+    vIntervallTexte( new RCArray< Text > ),
+    hIntervallWerte( new Array< double > ),
+    vIntervallWerte( new Array< double > ),
+    hIntervallBreite( 0 ),
+    vIntervallHöhe( 0 ),
+    werte( new RCArray< DiagWert >() ),
+    ref( 1 )
+{}
+
+// Destruktor
+DiagDaten::~DiagDaten()
+{
+    hIntervallName->release();
+    vIntervallName->release();
+    hIntervallWerte->release();
+    vIntervallWerte->release();
+    hIntervallTexte->release();
+    vIntervallTexte->release();
+    werte->release();
+}
+
+// Referenc Counting
+DiagDaten *DiagDaten::getThis()
+{
+    ++ref;
+    return this;
+}
+
+DiagDaten *DiagDaten::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der BaseDiag Klasse aus Diagramm.h
+// Konstruktor
+BaseDiag::BaseDiag( CRITICAL_SECTION *lock )
+    : daten( new DiagDaten() ),
+    ref( 1 ),
+    changed( 0 ),
+    lock( lock )
+{}
+
+// Destruktor
+BaseDiag::~BaseDiag()
+{
+    if( daten )
+        daten->release();
+}
+
+// nicht constant
+void BaseDiag::setDiagDatenZ( DiagDaten *dd ) // Setzt einen Zeiger auf die Daten des Diagramms
+{
+    EnterCriticalSection( lock );
+    if( daten )
+        daten->release();
+    daten = dd;
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::setDiagDaten( DiagDaten *dd ) // Kopiert die Daten eines Diagramms
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    daten->style = dd->style;
+    daten->rasterBreite = dd->rasterBreite;
+    daten->rasterHöhe = dd->rasterHöhe;
+    daten->rasterFarbe = dd->rasterFarbe;
+    daten->hIntervallFarbe = dd->hIntervallFarbe;
+    daten->vIntervallFarbe = dd->vIntervallFarbe;
+    daten->hIntervallName->setText( *dd->hIntervallName );
+    daten->vIntervallName->setText( *dd->vIntervallName );
+    int anz = dd->hIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( dd->hIntervallWerte->hat( i ) )
+            daten->hIntervallWerte->set( dd->hIntervallWerte->get( i ), i );
+    }
+    anz = dd->vIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( dd->vIntervallWerte->hat( i ) )
+            daten->vIntervallWerte->set( dd->vIntervallWerte->get( i ), i );
+    }
+    daten->hIntervallBreite = dd->hIntervallBreite;
+    daten->vIntervallHöhe = dd->vIntervallHöhe;
+    anz = dd->werte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        DiagWert *tmp = dd->werte->z( i );
+        if( tmp )
+        {
+            DiagWert *w = new DiagWert();
+            w->style = tmp->style;
+            w->farbe = tmp->farbe;
+            w->hintergrund = tmp->hintergrund;
+            w->name->setText( tmp->name->getText() );
+            int anz = tmp->punkte->getEintragAnzahl();
+            for( int j = 0; j < anz; ++j )
+            {
+                if( tmp->punkte->hat( j ) )
+                {
+                    DiagPunkt *p = new DiagPunkt();
+                    p->hIntervall = tmp->punkte->get( j )->hIntervall;
+                    p->vIntervall = tmp->punkte->get( j )->vIntervall;
+                    w->punkte->set( p, j );
+                }
+            }
+            daten->werte->set( w, i );
+        }
+    }
+    dd->release();
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::setRasterDicke( int d ) // Rasterdicke setzen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->rasterDicke != d )
+        changed = 1;
+    daten->rasterDicke = d;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setRasterBreite( int br ) // Rasterbreite setzen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->rasterBreite != br )
+        changed = 1;
+    daten->rasterBreite = br;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setRasterHöhe( int hö ) // Rasterhöhe setzen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->rasterHöhe != hö )
+        changed = 1;
+    daten->rasterHöhe = hö;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setRasterFarbe( int f ) // Rasterfarbe setzen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->rasterFarbe != f )
+        changed = 1;
+    daten->rasterFarbe = f;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setHIntervallBreite( double br ) // Intervall Breite
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    daten->hIntervallBreite = br;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setVIntervallHöhe( double hö ) // Intervall Höhe
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    daten->vIntervallHöhe = hö;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setHIntervallFarbe( int f ) // Farbe des Horizontalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->hIntervallFarbe != f )
+        changed = 1;
+    daten->hIntervallFarbe = f;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setVIntervallFarbe( int f ) // Farbe des Vertikalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->vIntervallFarbe != f )
+        changed = 1;
+    daten->vIntervallFarbe = f;
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setHIntervallName( char *name ) // Setzt den Namen des Horizontalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->hIntervallName )
+        daten->hIntervallName = new Text();
+    if( !daten->hIntervallName->istGleich( name ) )
+        changed = 1;
+    daten->hIntervallName->setText( name );
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setHIntervallName( Text *name )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->hIntervallName )
+        daten->hIntervallName = new Text();
+    if( !daten->hIntervallName->istGleich( *name ) )
+        changed = 1;
+    daten->hIntervallName->setText( name );
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setVIntervallName( char *name ) // Setzt den Namen des Vertikalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->vIntervallName )
+        daten->vIntervallName = new Text();
+    if( !daten->vIntervallName->istGleich( name ) )
+        changed = 1;
+    daten->vIntervallName->setText( name );
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::setVIntervallName( Text *name )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->vIntervallName )
+        daten->vIntervallName = new Text();
+    if( !daten->vIntervallName->istGleich( *name ) )
+        changed = 1;
+    daten->vIntervallName->setText( name );
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::addHIntervallText( double hIntervall, char *text ) // Text eines Horizontalen Intervalls hinzufügen
+{
+    setHIntervallText( hIntervall, text );
+}
+
+void BaseDiag::addHIntervallText( double hIntervall, Text *text )
+{
+    setHIntervallText( hIntervall, *text );
+    text->release();
+}
+
+void BaseDiag::setHIntervallTextZ( double hIntervall, Text *text ) // Setzt den Text eines Horizontalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->hIntervallWerte )
+        daten->hIntervallWerte = new Array< double >();
+    if( !daten->hIntervallTexte )
+        daten->hIntervallTexte = new RCArray< Text >();
+    int anz = daten->hIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->hIntervallWerte->hat( i ) && daten->hIntervallWerte->get( i ) == hIntervall )
+        {
+            daten->hIntervallTexte->set( text, i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    daten->hIntervallWerte->set( hIntervall, anz );
+    daten->hIntervallTexte->set( text, anz );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::setHIntervallText( double hIntervall, Text *text )
+{
+    setHIntervallText( hIntervall, *text );
+    text->release();
+}
+
+void BaseDiag::setHIntervallText( double hIntervall, char *text )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->hIntervallWerte )
+        daten->hIntervallWerte = new Array< double >();
+    if( !daten->hIntervallTexte )
+        daten->hIntervallTexte = new RCArray< Text >();
+    int anz = daten->hIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->hIntervallWerte->hat( i ) && daten->hIntervallWerte->get( i ) == hIntervall )
+        {
+            if( !daten->hIntervallTexte->z( i ) )
+                daten->hIntervallTexte->set( new Text( text ), i );
+            else
+                daten->hIntervallTexte->z( i )->setText( text );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    daten->hIntervallWerte->set( hIntervall, anz );
+    daten->hIntervallTexte->set( new Text( text ), anz );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::löscheHIntervallText( double hIntervall ) // Text eines Horizontalen Intervalls entfernen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->hIntervallWerte )
+        daten->hIntervallWerte = new Array< double >();
+    if( !daten->hIntervallTexte )
+        daten->hIntervallTexte = new RCArray< Text >();
+    int anz = daten->hIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->hIntervallWerte->hat( i ) && daten->hIntervallWerte->get( i ) == hIntervall )
+        {
+            daten->hIntervallTexte->lösche( i );
+            daten->hIntervallWerte->lösche( i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::addVIntervallText( double vIntervall, char *text ) // Text eines Vertikalen Intervalls hinzufügen
+{
+    setVIntervallText( vIntervall, text );
+}
+
+void BaseDiag::addVIntervallText( double vIntervall, Text *text )
+{
+    setVIntervallText( vIntervall, *text );
+    text->release();
+}
+
+void BaseDiag::setVIntervallTextZ( double vIntervall, Text *text ) // Setzt den Text eines Vertikalen Intervalls
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->vIntervallWerte )
+        daten->vIntervallWerte = new Array< double >();
+    if( !daten->vIntervallTexte )
+        daten->vIntervallTexte = new RCArray< Text >();
+    int anz = daten->vIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->vIntervallWerte->hat( i ) && daten->vIntervallWerte->get( i ) == vIntervall )
+        {
+            daten->vIntervallTexte->set( text, i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    daten->vIntervallWerte->set( vIntervall, anz );
+    daten->vIntervallTexte->set( text, anz );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::setVIntervallText( double vIntervall, Text *text )
+{
+    setVIntervallText( vIntervall, *text );
+    text->release();
+}
+
+void BaseDiag::setVIntervallText( double vIntervall, char *text )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->vIntervallWerte )
+        daten->vIntervallWerte = new Array< double >();
+    if( !daten->vIntervallTexte )
+        daten->vIntervallTexte = new RCArray< Text >();
+    int anz = daten->vIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->vIntervallWerte->hat( i ) && daten->vIntervallWerte->get( i ) == vIntervall )
+        {
+            if( !daten->vIntervallTexte->z( i ) )
+                daten->vIntervallTexte->set( new Text( text ), i );
+            else
+                daten->vIntervallTexte->z( i )->setText( text );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    daten->vIntervallWerte->set( vIntervall, anz );
+    daten->vIntervallTexte->set( new Text( text ), anz );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::löscheVIntervallText( double vIntervall ) // Text eines Vertikalen Intervalls entfernen
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->vIntervallWerte )
+        daten->vIntervallWerte = new Array< double >();
+    if( !daten->vIntervallTexte )
+        daten->vIntervallTexte = new RCArray< Text >();
+    int anz = daten->vIntervallWerte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->vIntervallWerte->hat( i ) && daten->vIntervallWerte->get( i ) == vIntervall )
+        {
+            daten->vIntervallTexte->lösche( i );
+            daten->vIntervallWerte->lösche( i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::addWertZ( DiagWert *w ) // Fügt einen Wert hinzu
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    daten->werte->add( w );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addWert( DiagWert *w )
+{
+    EnterCriticalSection( lock );
+    DiagWert *tmp = new DiagWert();
+    tmp->style = w->style;
+    tmp->farbe = w->farbe;
+    tmp->hintergrund = w->hintergrund;
+    tmp->name->setText( *w->name );
+    int anz = w->punkte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( w->punkte->hat( i ) )
+        {
+            DiagPunkt *p = new DiagPunkt();
+            p->hIntervall = w->punkte->get( i )->hIntervall;
+            p->vIntervall = w->punkte->get( i )->vIntervall;
+            tmp->punkte->set( p, i );
+        }
+    }
+    w->release();
+    addWertZ( tmp );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addWert( const char *name )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    DiagWert *w = new DiagWert();
+    w->name->setText( name );
+    daten->werte->add( w );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addWert( Text *txt )
+{
+    addWert( *txt );
+    txt->release();
+}
+
+void BaseDiag::setWertFarbe( int wNum, int f ) // setzt die Farbe eines Wertes
+{
+    if( wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    daten->werte->z( wNum )->farbe = f;
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addPunktZ( int wNum, DiagPunkt *p ) // fügt einem Wert einen Punkt hinzu
+{
+    if( wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    daten->werte->z( wNum )->punkte->add( p );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addPunkt( int wNum, DiagPunkt *p )
+{
+    if( wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    DiagPunkt *tmp = new DiagPunkt();
+    tmp->hIntervall = p->hIntervall;
+    tmp->vIntervall = p->vIntervall;
+    daten->werte->z( wNum )->punkte->add( tmp );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::addPunkt( int wNum, double hI, double vI )
+{
+    if( wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    DiagPunkt *tmp = new DiagPunkt();
+    tmp->hIntervall = hI;
+    tmp->vIntervall = vI;
+    daten->werte->z( wNum )->punkte->add( tmp );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+// Ändert einen vorhandenen Punkt eines Wertes
+void BaseDiag::setPunktZ( int wNum, double hI, DiagPunkt *p )
+{
+    setPunktZ( wNum, getDiagPunktPos( wNum, hI ), p );
+}
+
+void BaseDiag::setPunkt( int wNum, double hI, DiagPunkt *p )
+{
+    setPunkt( wNum, getDiagPunktPos( wNum, hI ), p->hIntervall, p->vIntervall );
+}
+
+void BaseDiag::setPunkt( int wNum, double hI, double h, double v )
+{
+    setPunkt( wNum, getDiagPunktPos( wNum, hI ), h, v );
+}
+
+void BaseDiag::setPunktZ( int wNum, int pNum, DiagPunkt *p )
+{
+    if( pNum < 0 || wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    if( daten->werte->z( wNum )->punkte->hat( pNum ) )
+        delete daten->werte->z( wNum )->punkte->get( pNum );
+    daten->werte->z( wNum )->punkte->set( p, pNum );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::setPunkt( int wNum, int pNum, DiagPunkt *p )
+{
+    if( pNum < 0 || wNum < 0 )
+        return;
+    setPunkt( wNum, pNum, p->hIntervall, p->vIntervall );
+}
+
+void BaseDiag::setPunkt( int wNum, int pNum, double h, double v )
+{
+    if( pNum < 0 || wNum < 0 )
+        return;
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    if( !daten->werte->z( wNum )->punkte->hat( pNum ) )
+        daten->werte->z( wNum )->punkte->set( new DiagPunkt(), pNum );
+    daten->werte->z( wNum )->punkte->get( pNum )->hIntervall = h;
+    daten->werte->z( wNum )->punkte->get( pNum )->vIntervall = v;
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+// Löscht einen vorhandenen Punkt
+void BaseDiag::löschePunkt( int wNum, double hI )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    int anz = daten->werte->z( wNum )->punkte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->werte->z( wNum )->punkte->hat( i ) && daten->werte->z( wNum )->punkte->get( i )->hIntervall == hI )
+        {
+            delete daten->werte->z( wNum )->punkte->get( i );
+            daten->werte->z( wNum )->punkte->lösche( i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::löschePunkt( int wNum, int pNum )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( !daten->werte->z( wNum )->punkte )
+        daten->werte->z( wNum )->punkte = new Array< DiagPunkt* >();
+    if( daten->werte->z( wNum )->punkte->hat( pNum ) )
+    {
+        delete daten->werte->z( wNum )->punkte->get( pNum );
+        daten->werte->z( wNum )->punkte->lösche( pNum );
+        changed = 1;
+    }
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::removeWert( int wNum ) // entfernt einen Wert
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    daten->werte->lösche( wNum );
+    LeaveCriticalSection( lock );
+    changed = 1;
+}
+
+void BaseDiag::removeWert( char *name )
+{
+    EnterCriticalSection( lock );
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte )
+        daten->werte = new RCArray< DiagWert >();
+    int anz = daten->werte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        DiagWert *tmp = daten->werte->z( i );
+        if( tmp && tmp->name && tmp->name->istGleich( name ) )
+        {
+            daten->werte->lösche( i );
+            LeaveCriticalSection( lock );
+            changed = 1;
+            return;
+        }
+    }
+    LeaveCriticalSection( lock );
+}
+
+void BaseDiag::removeWert( Text *name )
+{
+    removeWert( name->getText() );
+    name->release();
+}
+
+void BaseDiag::addDatenStyle( int style ) // Setzt den Style der Daten
+{
+    if( !daten )
+        daten = new DiagDaten();
+    if( ( daten->style | style ) != daten->style )
+        changed = 1;
+    daten->style |= style;
+}
+
+void BaseDiag::setDatenStyle( int style )
+{
+    if( !daten )
+        daten = new DiagDaten();
+    if( daten->style != style )
+        changed = 1;
+    daten->style = style;
+}
+
+void BaseDiag::setDatenStyle( int style, bool addRemove )
+{
+    if( addRemove )
+        addDatenStyle( style );
+    else
+        löscheDatenStyle( style );
+}
+
+void BaseDiag::löscheDatenStyle( int style )
+{
+    if( !daten )
+        daten = new DiagDaten();
+    if( ( daten->style & ~style ) != daten->style )
+        changed = 1;
+    daten->style &= ~style;
+}
+
+void BaseDiag::addWertStyle( int wNum, int style ) // Setzt den Style eines Wertes
+{
+    if( wNum < 0 )
+        return;
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( ( daten->werte->z( wNum )->style | style ) != daten->werte->z( wNum )->style )
+        changed = 1;
+    daten->werte->z( wNum )->style |= style;
+}
+
+void BaseDiag::setWertStyle( int wNum, int style )
+{
+    if( wNum < 0 )
+        return;
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( daten->werte->z( wNum )->style != style )
+        changed = 1;
+    daten->werte->z( wNum )->style = style;
+}
+
+void BaseDiag::setWertStyle( int wNum, int style, bool addRemove )
+{
+    if( wNum < 0 )
+        return;
+    if( addRemove )
+        addWertStyle( wNum, style );
+    else
+        löscheWertStyle( wNum, style );
+}
+
+void BaseDiag::löscheWertStyle( int wNum, int style )
+{
+    if( wNum < 0 )
+        return;
+    if( !daten )
+        daten = new DiagDaten();
+    if( !daten->werte->z( wNum ) )
+        daten->werte->set( new DiagWert(), wNum );
+    if( ( daten->werte->z( wNum )->style & ~style ) != daten->werte->z( wNum )->style )
+        changed = 1;
+    daten->werte->z( wNum )->style &= ~style;
+}
+
+// constant
+DiagDaten *BaseDiag::getDiagDaten() const // Gibt die Daten des Diagramms zurück
+{
+    return daten ? daten->getThis() : 0;
+}
+
+DiagDaten *BaseDiag::zDiagDaten() const
+{
+    return daten;
+}
+
+DiagWert *BaseDiag::getDiagWert( int wNum ) const // Gibt die Daten eines Wertes zurück
+{
+    return ( daten && daten->werte ) ? daten->werte->get( wNum ) : 0;
+}
+
+DiagWert *BaseDiag::zDiagWert( int wNum ) const
+{
+    return ( daten && daten->werte ) ? daten->werte->z( wNum ) : 0;
+}
+
+DiagWert *BaseDiag::getDiagWert( char *name ) const
+{
+    return getDiagWert( getDiagWertPos( name ) );
+}
+
+DiagWert *BaseDiag::zDiagWert( char *name ) const
+{
+    return zDiagWert( getDiagWertPos( name ) );
+}
+
+int BaseDiag::getDiagWertPos( char *name ) const // Gibt die Position eines Wertes zurück
+{
+    if( !daten || !daten->werte )
+        return -1;
+    int anz = daten->werte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->werte->z( i ) && daten->werte->z( i )->name && daten->werte->z( i )->name->istGleich( name ) )
+            return i;
+    }
+    return -1;
+}
+
+int BaseDiag::getDiagPunktPos( int wNum, double hI ) const // Gibt die Position eines Punktes von einem Wert zurück
+{
+    if( !daten || !daten->werte || !daten->werte->z( wNum ) || !daten->werte->z( wNum )->punkte )
+        return -1;
+    int anz = daten->werte->z( wNum )->punkte->getEintragAnzahl();
+    for( int i = 0; i < anz; ++i )
+    {
+        if( daten->werte->z( wNum )->punkte->hat( i ) && daten->werte->z( wNum )->punkte->get( i )->hIntervall == hI )
+            return i;
+    }
+    return -1;
+}
+
+int BaseDiag::getDiagPunktPos( char *wName, double hI ) const
+{
+    return getDiagPunktPos( getDiagWertPos( wName ), hI );
+}
+
+bool BaseDiag::hatDatenStyle( int style ) const // Prüft den Style der Daten
+{
+    if( !daten )
+        return 0;
+    return ( daten->style | style ) == daten->style;
+}
+
+bool BaseDiag::hatDatenStyleNicht( int style ) const
+{
+    if( !daten )
+        return 1;
+    return ( daten->style | style ) != daten->style;
+}
+
+bool BaseDiag::hatWertStyle( int wNum, int style ) const // Prüft den Style eines Wertes
+{
+    if( !daten || !daten->werte || !daten->werte->z( wNum ) )
+        return 0;
+    return ( daten->werte->z( wNum )->style | style ) == daten->werte->z( wNum )->style;
+}
+
+bool BaseDiag::hatWertStyleNicht( int wNum, int style ) const
+{
+    if( !daten || !daten->werte || !daten->werte->z( wNum ) )
+        return 1;
+    return ( daten->werte->z( wNum )->style | style ) != daten->werte->z( wNum )->style;
+}
+
+// Reference Counting
+BaseDiag *BaseDiag::getThis()
+{
+    ++ref;
+    return this;
+}
+
+BaseDiag *BaseDiag::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Inhalt der LDiag Klasse aus Diagramm.h
+// Konstruktor
+LDiag::LDiag()
+    : ZeichnungHintergrund(),
+    BaseDiag( &cs ),
+    schrift( 0 ),
+    dRam( new LRahmen() ),
+    dBgF( 0 ),
+    dBgB( 0 ),
+    dAf( new AlphaFeld() ),
+    vIntervallRB( new Bild() ),
+    hIntervallRB( new Bild() ),
+    schriftGr( 12 )
+{
+    vertikalScrollBar = new VScrollBar();
+    horizontalScrollBar = new HScrollBar();
+}
+
+// Destruktor
+LDiag::~LDiag()
+{
+    if( schrift )
+        schrift->release();
+    if( dRam )
+        dRam->release();
+    if( dBgB )
+        dBgB->release();
+    if( dAf )
+        dAf->release();
+    if( vIntervallRB )
+        vIntervallRB->release();
+    if( hIntervallRB )
+        hIntervallRB->release();
+}
+
+// nicht constant
+void LDiag::setSchriftZ( Schrift *schrift ) // Setzt die Schrift
+{
+    lockZeichnung();
+    if( this->schrift )
+        this->schrift->release();
+    this->schrift = schrift;
+    rend = 1;
+    unlockZeichnung();
+}
+
+void LDiag::setSchriftGröße( int gr )
+{
+    lockZeichnung();
+    if( schriftGr != gr )
+        rend = 1;
+    schriftGr = gr;
+    unlockZeichnung();
+}
+
+void LDiag::setDatenRahmenZ( LRahmen *ram ) // Setzt den inneren Rahmen um das eigentliche Diagramm
+{
+    lockZeichnung();
+    if( dRam )
+        dRam->release();
+    dRam = ram;
+    unlockZeichnung();
+    rend = 1;
+}
+
+void LDiag::setDatenRahmen( LRahmen *ram )
+{
+    lockZeichnung();
+    if( !dRam )
+        dRam = new LRahmen();
+    dRam->setAlpha( ram->hatAlpha() );
+    dRam->setFarbe( ram->getFarbe() );
+    dRam->setRamenBreite( ram->getRBreite() );
+    unlockZeichnung();
+    ram->release();
+    rend = 1;
+}
+
+void LDiag::setDatenRahmenBreite( int br )
+{
+    lockZeichnung();
+    if( !dRam )
+        dRam = new LRahmen();
+    if( dRam->getRBreite() != br )
+        rend = 1;
+    dRam->setRamenBreite( br );
+    unlockZeichnung();
+}
+
+void LDiag::setDatenRahmenFarbe( int f )
+{
+    lockZeichnung();
+    if( !dRam )
+        dRam = new LRahmen();
+    dRam->setFarbe( f );
+    unlockZeichnung();
+    rend = 1;
+}
+
+void LDiag::setDatenHintergrundFarbe( int f ) // Setzt den Hintergrund des eigentlichen Diagramms
+{
+    dBgF = f;
+    rend = 1;
+}
+
+void LDiag::setDatenHintergrundBildZ( Bild *b )
+{
+    lockZeichnung();
+    if( dBgB )
+        dBgB->release();
+    dBgB = b;
+    unlockZeichnung();
+    rend = 1;
+}
+
+void LDiag::setDatenHintergrundBild( Bild *b )
+{
+    lockZeichnung();
+    if( !dBgB )
+        dBgB = new Bild();
+    dBgB->neuBild( b->getBreite(), b->getHöhe(), 0 );
+    dBgB->drawBild( 0, 0, b->getBreite(), b->getHöhe(), *b );
+    unlockZeichnung();
+    b->release();
+    rend = 1;
+}
+
+void LDiag::setDatenAlphaFeldZ( AlphaFeld *af ) // Setzt das AlphaFeld des eigentlichen Diagramms
+{
+    lockZeichnung();
+    if( dAf )
+        dAf->release();
+    dAf = af;
+    unlockZeichnung();
+    rend = 1;
+}
+
+void LDiag::setDatenAlphaFeld( AlphaFeld *af )
+{
+    lockZeichnung();
+    if( !dAf )
+        dAf = new AlphaFeld();
+    dAf->setFarbe( af->getFarbe() );
+    dAf->setStärke( af->getStärke() );
+    unlockZeichnung();
+    af->release();
+    rend = 1;
+}
+
+void LDiag::setDatenAlphaFeldFarbe( int f )
+{
+    lockZeichnung();
+    if( !dAf )
+        dAf = new AlphaFeld();
+    dAf->setFarbe( f );
+    unlockZeichnung();
+    rend = 1;
+}
+
+void LDiag::setDatenAlphaFeldStärke( int st )
+{
+    lockZeichnung();
+    if( !dAf )
+        dAf = new AlphaFeld();
+    if( dAf->getStärke() != st )
+        rend = 1;
+    dAf->setStärke( st );
+    unlockZeichnung();
+}
+
+void LDiag::doMausEreignis( MausEreignis &me )
+{
+    bool nmakc = !me.verarbeitet;
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        mausIn = 1;
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( hatDatenStyle( DiagDaten::Style::Sichtbar ) && ( hatStyle( Style::HScroll ) || hatStyle( Style::VScroll ) ) )
+    {
+        if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+        {
+            if( me.id != ME_Betritt && me.id != ME_Verlässt )
+            {
+                lockZeichnung();
+                int rbr = 0;
+                if( hatStyle( Style::Rahmen ) && rahmen )
+                    rbr = rahmen->getRBreite();
+                bool vs = hatStyle( Style::VScroll ) && vertikalScrollBar;
+                bool hs = hatStyle( Style::HScroll ) && horizontalScrollBar;
+                if( vs )
+                {
+                    if( hs )
+                        horizontalScrollBar->doMausMessage( rbr, gr.y - rbr - 15, gr.x - rbr * 2 - 15, 15, me );
+                    vertikalScrollBar->doMausMessage( gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me );
+                }
+                else if( hs )
+                    horizontalScrollBar->doMausMessage( rbr, gr.y - rbr - 15, gr.x - rbr * 2, 15, me );
+                unlockZeichnung();
+            }
+            me.verarbeitet = 1;
+        }
+    }
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void LDiag::render( Bild &zRObj )
+{
+    if( !hatDatenStyle( DiagDaten::Style::Sichtbar ) )
+        return;
+    __super::render( zRObj );
+    if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+        return;
+    lockZeichnung();
+    int dgy = 0;
+    int dgbr = innenGröße.x;
+    int dghö = innenGröße.y;
+    int vIAnz = 0;
+    int hIAnz = 0;
+    if( daten )
+    { // Auto werte berechnen
+        vIAnz = daten->vIntervallWerte ? daten->vIntervallWerte->getEintragAnzahl() : 0;
+        hIAnz = daten->hIntervallWerte ? daten->hIntervallWerte->getEintragAnzahl() : 0;
+        if( daten->vIntervallWerte && hatDatenStyle( DiagDaten::Style::AutoIntervallHöhe ) )
+        {
+            double maxW = 0;
+            for( int i = 0; i < vIAnz; ++i )
+            {
+                if( daten->vIntervallWerte->hat( i ) && daten->vIntervallWerte->get( i ) > maxW )
+                    maxW = daten->vIntervallWerte->get( i );
+            }
+            if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                daten->vIntervallHöhe = maxW ? ( vertikalScrollBar->getScroll() / maxW ) : 0;
+            else
+                daten->vIntervallHöhe = maxW ? ( vIntervallRB->getBreite() / maxW ) : 0;
+        }
+        if( hatDatenStyle( DiagDaten::Style::AutoRasterHöhe ) )
+            daten->rasterHöhe = daten->vIntervallHöhe;
+        if( daten->hIntervallWerte && hatDatenStyle( DiagDaten::Style::AutoIntervallBreite ) )
+        {
+            double maxW = 0;
+            for( int i = 0; i < vIAnz; ++i )
+            {
+                if( daten->hIntervallWerte->hat( i ) && daten->hIntervallWerte->get( i ) > maxW )
+                    maxW = daten->hIntervallWerte->get( i );
+            }
+            if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                daten->hIntervallBreite = maxW ? ( horizontalScrollBar->getScroll() / maxW ) : 0;
+            else
+                daten->hIntervallBreite = maxW ? ( hIntervallRB->getBreite() / maxW ) : 0;
+        }
+        if( hatDatenStyle( DiagDaten::Style::AutoRasterBreite ) )
+            daten->rasterBreite = daten->hIntervallBreite;
+    }
+    if( hatDatenStyle( DiagDaten::Style::VIntervall ) && schrift && schriftGr && daten )
+    { // Rendern des vertikalen Intervalls
+        int vIRBbr = innenGröße.y;
+        if( hatDatenStyle( DiagDaten::Style::HIntervall ) && daten->hIntervallFarbe )
+            vIRBbr -= schriftGr + 2;
+        if( vIRBbr > 0 )
+        {
+            if( vIntervallRB->getBreite() != vIRBbr || vIntervallRB->getHöhe() != schriftGr + 2 )
+                vIntervallRB->neuBild( vIRBbr, schriftGr + 2, 0 );
+            else
+                vIntervallRB->füllRegion( 0, 0, vIRBbr, schriftGr + 2, 0 );
+            schrift->lock();
+            schrift->setSchriftGröße( schriftGr );
+            if( daten->vIntervallWerte )
+            {
+                int *rf = new int[ vIAnz ];
+                int anz = 0;
+                bool *fertig = new bool[ vIAnz ];
+                ZeroMemory( fertig, vIAnz );
+                for( int i = 0; i < vIAnz; ++i )
+                {
+                    double min = 0;
+                    int mI = -1;
+                    for( int j = 0; j < vIAnz; ++j )
+                    {
+                        if( !fertig[ j ] && daten->vIntervallWerte->hat( j ) && ( daten->vIntervallWerte->get( j ) < min || mI < 0 ) )
+                        {
+                            mI = j;
+                            min = daten->vIntervallWerte->get( j );
+                        }
+                    }
+                    if( mI < 0 )
+                        break;
+                    rf[ anz ] = mI;
+                    ++anz;
+                    fertig[ mI ] = 1;
+                }
+                delete[] fertig;
+                Text txt;
+                int xPos = 0;
+                if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                    xPos -= vertikalScrollBar->getScroll();
+                int rWeite = xPos - 10;
+                for( int i = anz - 1; i >= 0; --i )
+                {
+                    txt = "";
+                    if( hatDatenStyle( DiagDaten::Style::VIntervallTexte ) && daten->vIntervallTexte && daten->vIntervallTexte->z( rf[ i ] ) )
+                        txt = daten->vIntervallTexte->z( rf[ i ] )->getText();
+                    else if( hatDatenStyleNicht( DiagDaten::Style::VIntervallTexte ) || !daten->vIntervallWerte )
+                        txt = daten->vIntervallWerte->get( rf[ i ] );
+                    xPos = (int)( daten->vIntervallWerte->get( rf[ i ] ) * daten->vIntervallHöhe );
+                    xPos = ( vertikalScrollBar && hatStyle( Style::VScroll ) ? vertikalScrollBar->getScroll() : vIntervallRB->getBreite() ) - xPos;
+                    if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                        xPos -= vertikalScrollBar->getScroll();
+                    int br = schrift->getTextBreite( &txt );
+                    if( xPos + br > vIntervallRB->getBreite() && vIntervallRB->getBreite() - br >= rWeite + 10 )
+                        xPos = vIntervallRB->getBreite() - br;
+                    if( xPos >= rWeite + 10 )
+                    {
+                        schrift->setDrawPosition( xPos, 1 );
+                        schrift->renderText( &txt, *vIntervallRB, daten->vIntervallFarbe );
+                        rWeite = xPos + br + 10;
+                    }
+                }
+                delete[] rf;
+            }
+            if( daten->vIntervallName )
+            {
+                int vinbr = schrift->getTextBreite( daten->vIntervallName );
+                int vinx = vIntervallRB->getBreite() / 2 - vinbr / 2;
+                vIntervallRB->füllRegion( vinx - 5, 1, vinbr + 10, schriftGr, 0 );
+                schrift->setDrawPosition( vinx, 1 );
+                schrift->renderText( daten->vIntervallName, *vIntervallRB, daten->vIntervallFarbe );
+            }
+            schrift->unlock();
+            if( hatDatenStyle( DiagDaten::Style::HIntervall ) && daten->hIntervallFarbe )
+                zRObj.alphaBild90( innenGröße.x - vIntervallRB->getHöhe(), schriftGr + 2, vIntervallRB->getBreite(), vIntervallRB->getHöhe(), *vIntervallRB );
+            else
+                zRObj.alphaBild90( innenGröße.x - vIntervallRB->getHöhe(), 0, vIntervallRB->getBreite(), vIntervallRB->getHöhe(), *vIntervallRB );
+            dgbr -= vIntervallRB->getHöhe();
+        }
+    }
+    if( hatDatenStyle( DiagDaten::Style::HIntervall ) && schrift && schriftGr && daten )
+    { // Rendern des horizontalen Intervalls
+        int hIRBbr = innenGröße.x;
+        if( hatDatenStyle( DiagDaten::Style::VIntervall ) && daten->vIntervallFarbe )
+            hIRBbr -= schriftGr + 2;
+        if( hIRBbr > 0 )
+        {
+            if( hIntervallRB->getBreite() != hIRBbr || hIntervallRB->getHöhe() != schriftGr + 2 )
+                hIntervallRB->neuBild( hIRBbr, schriftGr + 2, 0 );
+            else
+                hIntervallRB->füllRegion( 0, 0, hIRBbr, schriftGr + 2, 0 );
+            schrift->lock();
+            schrift->setSchriftGröße( schriftGr );
+            if( daten->hIntervallWerte )
+            {
+                int *rf = new int[ hIAnz ];
+                int anz = 0;
+                bool *fertig = new bool[ hIAnz ];
+                ZeroMemory( fertig, hIAnz );
+                for( int i = 0; i < hIAnz; ++i )
+                {
+                    double min = 0;
+                    int mI = -1;
+                    for( int j = 0; j < hIAnz; ++j )
+                    {
+                        if( !fertig[ j ] && daten->hIntervallWerte->hat( j ) && ( daten->hIntervallWerte->get( j ) < min || mI < 0 ) )
+                        {
+                            mI = j;
+                            min = daten->hIntervallWerte->get( j );
+                        }
+                    }
+                    if( mI < 0 )
+                        break;
+                    rf[ anz ] = mI;
+                    ++anz;
+                    fertig[ mI ] = 1;
+                }
+                delete[] fertig;
+                Text txt;
+                int xPos = 0;
+                if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                    xPos -= horizontalScrollBar->getScroll();
+                int rWeite = xPos - 10;
+                for( int i = 0; i < anz; ++i )
+                {
+                    txt = "";
+                    if( hatDatenStyle( DiagDaten::Style::HIntervallTexte ) && daten->hIntervallTexte && daten->hIntervallTexte->z( rf[ i ] ) )
+                        txt = daten->hIntervallTexte->z( rf[ i ] )->getText();
+                    else if( hatDatenStyleNicht( DiagDaten::Style::HIntervallTexte ) || !daten->hIntervallWerte )
+                        txt = daten->hIntervallWerte->get( rf[ i ] );
+                    xPos = (int)( daten->hIntervallWerte->get( rf[ i ] ) * daten->hIntervallBreite );
+                    if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                        xPos -= horizontalScrollBar->getScroll();
+                    int br = schrift->getTextBreite( &txt );
+                    if( xPos + br > hIntervallRB->getBreite() && hIntervallRB->getBreite() - br >= rWeite + 10 )
+                        xPos = hIntervallRB->getBreite() - br;
+                    if( xPos >= rWeite + 10 )
+                    {
+                        schrift->setDrawPosition( xPos, 1 );
+                        schrift->renderText( &txt, *hIntervallRB, daten->hIntervallFarbe );
+                        rWeite = xPos + br + 10;
+                    }
+                }
+                delete[] rf;
+            }
+            if( daten->hIntervallName )
+            {
+                int hinbr = schrift->getTextBreite( daten->hIntervallName );
+                int hinx = hIntervallRB->getBreite() / 2 - hinbr / 2;
+                hIntervallRB->füllRegion( hinx - 5, 1, hinbr + 10, schriftGr, 0 );
+                schrift->setDrawPosition( hinx, 1 );
+                schrift->renderText( daten->hIntervallName, *hIntervallRB, daten->hIntervallFarbe );
+            }
+            schrift->unlock();
+            zRObj.alphaBild( 0, 0, hIntervallRB->getBreite(), hIntervallRB->getHöhe(), *hIntervallRB );
+            dghö -= hIntervallRB->getHöhe();
+            dgy += hIntervallRB->getHöhe();
+        }
+    }
+    if( !zRObj.setDrawOptions( 0, dgy, dgbr, dghö ) )
+    {
+        zRObj.releaseDrawOptions();
+        unlockZeichnung();
+        return;
+    }
+    dgy = 0;
+    int dgrbr = 0;
+    if( hatStyle( Style::DatenRahmen ) && dRam )
+    {
+        dRam->setGröße( dgbr, dghö );
+        dRam->render( zRObj );
+        dgrbr = dRam->getRBreite();
+    }
+    if( !zRObj.setDrawOptions( dgrbr, dgrbr, dgbr - dgrbr * 2, dghö - dgrbr * 2 ) )
+    {
+        zRObj.releaseDrawOptions();
+        zRObj.releaseDrawOptions();
+        unlockZeichnung();
+        return;
+    }
+    if( hatStyle( Style::DatenHintergrund ) )
+    {
+        if( hatStyle( Style::DatenHAlpha ) )
+            zRObj.alphaRegion( 0, 0, dgbr - dgrbr * 2, dghö - dgrbr * 2, dBgF );
+        else
+            zRObj.füllRegion( 0, 0, dgbr - dgrbr * 2, dghö - dgrbr * 2, dBgF );
+        if( hatStyle( Style::DatenHBild ) && dBgB )
+        {
+            if( hatStyle( Style::DatenHAlpha ) )
+                zRObj.alphaBild( 0, 0, dgbr - dgrbr * 2, dghö - dgrbr * 2, *dBgB );
+            else
+                zRObj.drawBild( 0, 0, dgbr - dgrbr * 2, dghö - dgrbr * 2, *dBgB );
+        }
+    }
+    if( hatStyle( Style::DatenBuffered ) && dAf )
+    {
+        dAf->setGröße( dgbr - dgrbr * 2, dghö - dgrbr * 2 );
+        dAf->render( zRObj );
+    }
+    if( hatDatenStyle( DiagDaten::Style::Raster ) && daten && daten->rasterDicke && daten->rasterBreite && daten->rasterHöhe )
+    { // Raster
+        int maxBr = dgbr;
+        if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+            maxBr = horizontalScrollBar->getScroll();
+        int maxHö = dghö;
+        if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+            maxHö = vertikalScrollBar->getScroll();
+        for( double x = horizontalScrollBar && hatStyle( Style::HScroll ) ? -horizontalScrollBar->getScroll() : 0; x < maxBr; x += daten->rasterBreite )
+        {
+            for( int i = 0; i < daten->rasterDicke; ++i )
+            {
+                if( hatDatenStyle( DiagDaten::Style::RasterAlpha ) )
+                    zRObj.drawLinieVAlpha( (int)( x + i ), dgy + dgrbr, dghö - dgrbr * 2, daten->rasterFarbe );
+                else
+                    zRObj.drawLinieV( (int)( x + i ), dgy + dgrbr, dghö - dgrbr * 2, daten->rasterFarbe );
+            }
+        }
+        for( double y = maxHö; y > ( vertikalScrollBar && hatStyle( Style::VScroll ) ? -vertikalScrollBar->getScroll() : 0 ); y -= daten->rasterHöhe )
+        {
+            for( int i = 0; i < daten->rasterDicke; ++i )
+            {
+                if( hatDatenStyle( DiagDaten::Style::RasterAlpha ) )
+                    zRObj.drawLinieHAlpha( 0, (int)( y + i ), dgbr - dgrbr * 2, daten->rasterFarbe );
+                else
+                    zRObj.drawLinieH( 0, (int)( y + i ), dgbr - dgrbr * 2, daten->rasterFarbe );
+            }
+        }
+    }
+    if( daten && daten->werte && daten->werte->getEintragAnzahl() && daten->hIntervallBreite && daten->vIntervallHöhe )
+    { // Werte
+        int wAnz = daten->werte->getEintragAnzahl();
+        for( int i = 0; i < wAnz; ++i )
+        {
+            DiagWert *wert = daten->werte->z( i );
+            if( wert && hatWertStyle( i, DiagWert::Style::Sichtbar ) && wert->punkte && wert->punkte->getEintragAnzahl() )
+            {
+                int pAnz = wert->punkte->getEintragAnzahl();
+                int *rf = new int[ pAnz ];
+                bool *fertig = new bool[ pAnz ];
+                int anz = 0;
+                ZeroMemory( fertig, pAnz );
+                for( int j = 0; j < pAnz; ++j )
+                {
+                    double min = -1;
+                    int p = -1;
+                    for( int pi = 0; pi < pAnz; ++pi )
+                    {
+                        if( wert->punkte->hat( pi ) && !fertig[ pi ] && ( p < 0 || wert->punkte->get( pi )->hIntervall < min ) )
+                        {
+                            min = wert->punkte->get( pi )->hIntervall;
+                            p = pi;
+                        }
+                    }
+                    if( p < 0 )
+                        break;
+                    rf[ anz ] = p;
+                    fertig[ p ] = 1;
+                    ++anz;
+                }
+                delete[] fertig;
+                int rpx = horizontalScrollBar && hatStyle( Style::HScroll ) ? -horizontalScrollBar->getScroll() : 0;
+                int rpy = vertikalScrollBar && hatStyle( Style::VScroll ) ? -vertikalScrollBar->getScroll() : 0;
+                rpy += dgy;
+                int dgmhö = vertikalScrollBar && hatStyle( Style::VScroll ) ? dgy + vertikalScrollBar->getScrollData()->maxHöhe + dgrbr : dgy + dghö - dgrbr;
+                if( hatWertStyle( i, DiagWert::Style::Hintergrund ) )
+                {
+                    DiagPunkt *vorher = 0;
+                    DiagPunkt *jetzt = 0;
+                    for( int j = 0; j < anz; ++j )
+                    {
+                        jetzt = wert->punkte->get( rf[ j ] );
+                        if( jetzt && vorher )
+                        {
+                            int ax = (int)( rpx + vorher->hIntervall * daten->hIntervallBreite );
+                            int ay = (int)( dgmhö - vorher->vIntervall * daten->vIntervallHöhe );
+                            int bx = (int)( rpx + jetzt->hIntervall * daten->hIntervallBreite );
+                            int by = (int)( dgmhö - jetzt->vIntervall * daten->vIntervallHöhe );
+                            if( ax >= bx )
+                            {
+                                vorher = jetzt;
+                                continue;
+                            }
+                            if( !( ax > dgbr - dgrbr || bx < 0 || ( ay > dgy + dghö - dgrbr && by > dgy + dghö - dgrbr ) ) )
+                            {
+                                double yf = (double)( by - ay ) / ( bx - ax );
+                                double y = (double)ay;
+                                ax = ax < 0 ? 0 : ax;
+                                bx = bx > dgbr - dgrbr ? dgbr - dgrbr : bx;
+                                if( hatWertStyle( i, DiagWert::Style::HAlpha ) )
+                                {
+                                    for( int x = ax; x < bx; x++, y += yf )
+                                        zRObj.drawLinieVAlpha( x, (int)( y + 0.5 ), dgmhö - (int)( y + 0.5 ), wert->hintergrund );
+                                }
+                                else
+                                {
+                                    for( int x = ax; x < bx; x++, y += yf )
+                                        zRObj.drawLinieV( x, (int)( y + 0.5 ), dgmhö - (int)( y + 0.5 ), wert->hintergrund );
+                                }
+                                if( hatWertStyle( i, DiagWert::Style::Alpha ) )
+                                    zRObj.drawLinieAlpha( Punkt( ax, ay ), Punkt( bx, by ), wert->farbe );
+                                else
+                                    zRObj.drawLinie( Punkt( ax, ay ), Punkt( bx, by ), wert->farbe );
+                            }
+                        }
+                        vorher = jetzt;
+                    }
+                }
+                else
+                {
+                    DiagPunkt *vorher = 0;
+                    DiagPunkt *jetzt = 0;
+                    for( int j = 0; j < anz; ++j )
+                    {
+                        jetzt = wert->punkte->get( rf[ j ] );
+                        if( jetzt && vorher )
+                        {
+                            if( hatWertStyle( i, DiagWert::Style::Alpha ) )
+                                zRObj.drawLinieAlpha( Punkt( (int)( rpx + vorher->hIntervall * daten->hIntervallBreite ), (int)( dgmhö - vorher->vIntervall * daten->vIntervallHöhe ) ),
+                                                      Punkt( (int)( rpx + jetzt->hIntervall * daten->hIntervallBreite ), (int)( dgmhö - jetzt->vIntervall * daten->vIntervallHöhe ) ), wert->farbe );
+                            else
+                                zRObj.drawLinie( Punkt( (int)( rpx + vorher->hIntervall * daten->hIntervallBreite ), (int)( dgmhö - vorher->vIntervall * daten->vIntervallHöhe ) ),
+                                                 Punkt( (int)( rpx + jetzt->hIntervall * daten->hIntervallBreite ), (int)( dgmhö - jetzt->vIntervall * daten->vIntervallHöhe ) ), wert->farbe );
+                        }
+                        vorher = jetzt;
+                    }
+                }
+                delete[] rf;
+            }
+        }
+    }
+    if( daten && daten->werte && daten->werte->getEintragAnzahl() && schrift && schriftGr )
+    {
+        int wAnz = daten->werte->getEintragAnzahl();
+        int rx = 5;
+        int ry = 5;
+        schrift->lock();
+        schrift->setSchriftGröße( schriftGr );
+        for( int i = 0; i < wAnz; ++i )
+        {
+            DiagWert *w = daten->werte->z( i );
+            if( w && w->name && hatWertStyle( i, DiagWert::Style::Name ) && hatWertStyle( i, DiagWert::Style::Sichtbar ) )
+            {
+                int br = schrift->getTextBreite( w->name );
+                zRObj.alphaRegion( rx, ry, br, schriftGr, 0xA0000000 );
+                schrift->setDrawPosition( rx, ry );
+                schrift->renderText( w->name, zRObj, w->farbe );
+                ry += 15;
+            }
+        }
+        schrift->unlock();
+    }
+    zRObj.releaseDrawOptions();
+    zRObj.releaseDrawOptions();
+    zRObj.releaseDrawOptions();
+    unlockZeichnung();
+}
+
+// constant
+Schrift *LDiag::getSchrift() const // Gibt die Schrift zurück
+{
+    return schrift ? schrift->getThis() : 0;
+}
+
+Schrift *LDiag::zSchrift() const
+{
+    return schrift;
+}
+
+LRahmen *LDiag::getDatenRahmen() const // Gibt den inneren Rahmen um das eigentliche Diagramm zurück
+{
+    return dRam ? dRam->getThis() : 0;
+}
+
+LRahmen *LDiag::zDatenRahmen() const
+{
+    return dRam;
+}
+
+int LDiag::getDatenRahmenFarbe() const
+{
+    return dRam ? dRam->getFarbe() : 0;
+}
+
+int LDiag::getDatenRahmenBreite() const
+{
+    return dRam ? dRam->getRBreite() : 0;
+}
+
+int LDiag::getDatenHintergrundFarbe() const // Gibt den Hintergrund des eigentlichen Diagramms zurück
+{
+    return dBgF;
+}
+
+Bild *LDiag::getDatenHintergrundBild() const
+{
+    return dBgB ? dBgB->getThis() : 0;
+}
+
+Bild *LDiag::zDatenHintergrundBild() const
+{
+    return dBgB;
+}
+
+AlphaFeld *LDiag::getDatenAlphaFeld() const // Gibt das AlphaFeld des eigentlichen Diagramms zurück
+{
+    return dAf ? dAf->getThis() : 0;
+}
+
+AlphaFeld *LDiag::zDatenAlphaFeld() const
+{
+    return dAf;
+}
+
+int LDiag::getDatenAlphaFeldFarbe() const
+{
+    return dAf ? dAf->getFarbe() : 0;
+}
+
+int LDiag::getDatenAlphaFeldStärke() const
+{
+    return dAf ? dAf->getStärke() : 0;
+}
+
+// Reference Counting
+BaseDiag *LDiag::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 383 - 0
Diagramm.h

@@ -0,0 +1,383 @@
+#ifndef Diagramm_H
+#define Diagramm_H
+
+#include "Zeichnung.h"
+#include "Array.h"
+
+namespace Framework
+{
+    class LRahmen; // Rahmen.h
+    class AlphaFeld; // AlphaFeld.h
+    class Text; // Text.h
+    class Schrift; // Schrift.h
+    class HScrollBar; // Scroll.h
+    class VScrollBar; // Scroll.h
+    class SLDiag; // aus dieser Datei
+    class LDiag; // aus dieser Datei
+
+    class SLDiag : public ZeichnungHintergrund
+    {
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 Gitter = 0x01000;
+            const static __int64 LinienName = 0x02000;
+
+            const static __int64 normal = Sichtbar | Hintergrund | Rahmen | Gitter | LinienName;
+        };
+    private:
+        int gF;
+        Array< int > *lFarbe;
+        RCArray< Text > *lName;
+        RCArray< Array< int > > *ph;
+        RCArray< Array< int > > *pb;
+        Array< int > *lastValue;
+        Schrift *schrift;
+        Punkt gitterGr;
+        int lines;
+        int ref;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) SLDiag();
+        // Destruktor 
+        __declspec( dllexport ) ~SLDiag();
+        // nicht constant 
+        __declspec( dllexport ) void setSchriftZ( Schrift *schrift ); // setzt die Schrift
+        __declspec( dllexport ) void setGGröße( Punkt &gr ); // setzt die Größe des Gitters
+        __declspec( dllexport ) void setGFarbe( int f ); // setzt die Gitter Farbe
+        __declspec( dllexport ) void addLinie( const char *name ); // fügt eine Linie hinzu
+        __declspec( dllexport ) void addLinie( Text *txt );
+        __declspec( dllexport ) void setLFarbe( int lNum, int f ); // setzt die Linienfarbe
+        __declspec( dllexport ) void addPunkt( int lNum, int x, int h ); // fügt einen Punkt hinzu
+        __declspec( dllexport ) void removeLinie( int lNum ); // entfernt eine Linie
+        __declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+        // constant
+        __declspec( dllexport ) Schrift *getSchrift() const; // gibt die Schrift zurück
+        __declspec( dllexport ) Schrift *zSchrift() const;
+        __declspec( dllexport ) const Punkt &getGGröße() const; // gibt die Gitter Größe zurück
+        __declspec( dllexport ) int getGFarbe() const; // gibt die Gitter Farbe zurück
+        __declspec( dllexport ) int getLinienNummer( const char *name ) const; // gibt die Linien Nummer zurück
+        __declspec( dllexport ) int getLinienNummer( Text *name ) const;
+        __declspec( dllexport ) Text *getLinienName( int lNum ) const; // gibt den Linien Namen zurück
+        __declspec( dllexport ) Text *zLinienNamen( int lNum ) const;
+        __declspec( dllexport ) int getHöchstValue() const; // gibt den Höchsten Wert zurück
+        __declspec( dllexport ) int getHöchstValue( int lNum ) const;
+        __declspec( dllexport ) int getMedian( int lNum ) const; // gibt den durchschnittswert zurück
+        __declspec( dllexport ) int getLAnzahl() const; // gibt die Linien Anzahl zurück
+        __declspec( dllexport ) int getLastValue( int lNum ) const; // gibt den letzten Wert zurück
+        // Reference Counting 
+        __declspec( dllexport ) SLDiag *getThis();
+        __declspec( dllexport ) SLDiag *release();
+    };
+
+    // Punkt eines Wertes eines Diagramms
+    struct DiagPunkt
+    {
+        // Position des Punktes auf dem Horizontalen Intervall des Diagramms
+        double hIntervall;
+        // Position des punktes auf dem Vertikalen Intervall des Diagramms
+        double vIntervall;
+    };
+
+    // Wert der in einem Diagramm visualisiert wird
+    struct DiagWert
+    {
+        // Style eines Diagramm Wertes
+        class Style
+        {
+        public:
+            const static int Sichtbar = 0x01;
+            const static int Alpha = 0x02;
+            const static int Hintergrund = 0x04;
+            const static int HAlpha = 0x08;
+            const static int Name = 0x10;
+        };
+        // Style des Wertes
+        int style;
+        // Farbe des Wertes
+        int farbe;
+        // Hintergrundfarbe des Wertes
+        int hintergrund;
+        // Name des Wertes
+        Text *name;
+        // Punkte des Wertes
+        Array< DiagPunkt* > *punkte;
+
+        // Konstruktor
+        __declspec( dllexport ) DiagWert();
+        // Destruktor
+        __declspec( dllexport ) ~DiagWert();
+        // Referenc Counting
+        __declspec( dllexport ) DiagWert *getThis();
+        __declspec( dllexport ) DiagWert *release();
+
+    private:
+        // Reference Counting
+        int ref;
+    };
+
+    // Daten für ein Diagramm
+    struct DiagDaten
+    {
+        class Style
+        {
+        public:
+            const static int Sichtbar = 0x0001;
+            const static int Raster = 0x0002;
+            const static int RasterAlpha = 0x0004;
+            const static int AutoIntervallHöhe = 0x0008;
+            const static int AutoIntervallBreite = 0x0010;
+            const static int HIntervall = 0x0020;
+            const static int VIntervall = 0x0040;
+            const static int HIntervallTexte = 0x0200;
+            const static int VIntervallTexte = 0x0400;
+            const static int AutoRasterBreite = 0x0800;
+            const static int AutoRasterHöhe = 0x1000;
+
+            const static int intervalle = 0x0060;
+            const static int intervallTexte = 0x0600;
+            const static int autoRaster = 0x1802;
+            const static int autoIntervall = 0x0018;
+        };
+        // Style eines Diagramms
+        int style;
+        // Breite einer Rasterlinie
+        int rasterDicke;
+        // Breite eines Rasterkästchens
+        double rasterBreite;
+        // Höhe eines Rasterkästchens
+        double rasterHöhe;
+        // Farbe des Rasters
+        int rasterFarbe;
+        // Schriftfarbe des Horizontalen Intervalls
+        int hIntervallFarbe;
+        // Schriftfarbe des Vertikalen Intervalls
+        int vIntervallFarbe;
+        // Name des Horizontalen Intervalls
+        Text *hIntervallName;
+        // Name des Vertikalen Intervalls
+        Text *vIntervallName;
+        // Anzeigen des Horizontalen Intervalls
+        RCArray< Text > *hIntervallTexte;
+        // Anzeigen des Vertikalen Intervalls
+        RCArray< Text > *vIntervallTexte;
+        // einzelne Horizontale Intervalle
+        Array< double > *hIntervallWerte;
+        // einzelne Vertikale Intervalle
+        Array< double > *vIntervallWerte;
+        // Breite des Wertes 1 in Pixeln bei dem horizontalen Intervall ( wird durch das setzen von AutoIntervallBreite überschrieben )
+        double hIntervallBreite;
+        // Höhe des Wertes 1 in Pixeln bei dem vertikalen Intervall ( wird durch das setzen von AutoIntervallHöhe überschrieben )
+        double vIntervallHöhe;
+        // Werte, die in dem Diagramm visualisiert werden
+        RCArray< DiagWert > *werte;
+
+        // Konstruktor
+        __declspec( dllexport ) DiagDaten();
+        // Destruktor
+        __declspec( dllexport ) ~DiagDaten();
+        // Referenc Counting
+        __declspec( dllexport ) DiagDaten *getThis();
+        __declspec( dllexport ) DiagDaten *release();
+
+    private:
+        // Reference Counting
+        int ref;
+    };
+
+    // Basisklasse der verschiedenen Diagramm Arten
+    class BaseDiag
+    {
+    protected:
+        DiagDaten *daten;
+        bool changed;
+        CRITICAL_SECTION *lock;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) BaseDiag( CRITICAL_SECTION *lock );
+        // Destruktor
+        __declspec( dllexport ) ~BaseDiag();
+        // nicht constant
+        // Setzt einen Zeiger auf die Daten des Diagramms
+        __declspec( dllexport ) void setDiagDatenZ( DiagDaten *dd );
+        // Kopiert die Daten eines Diagramms
+        __declspec( dllexport ) void setDiagDaten( DiagDaten *dd );
+        // Rasterdicke setzen
+        __declspec( dllexport ) void setRasterDicke( int d );
+        // Rasterbreite setzen
+        __declspec( dllexport ) void setRasterBreite( int br );
+        // Rasterhöhe setzen
+        __declspec( dllexport ) void setRasterHöhe( int hö );
+        // Rasterfarbe setzen
+        __declspec( dllexport ) void setRasterFarbe( int f );
+        // Intervall Breite
+        __declspec( dllexport ) void setHIntervallBreite( double br );
+        // Intervall Höhe
+        __declspec( dllexport ) void setVIntervallHöhe( double hö );
+        // Farbe des Horizontalen Intervalls
+        __declspec( dllexport ) void setHIntervallFarbe( int f );
+        // Farbe des Vertikalen Intervalls
+        __declspec( dllexport ) void setVIntervallFarbe( int f );
+        // Setzt den Namen des Horizontalen Intervalls
+        __declspec( dllexport ) void setHIntervallName( char *name );
+        __declspec( dllexport ) void setHIntervallName( Text *name );
+        // Setzt den Namen des Vertikalen Intervalls
+        __declspec( dllexport ) void setVIntervallName( char *name );
+        __declspec( dllexport ) void setVIntervallName( Text *name );
+        // Text eines Horizontalen Intervalls hinzufügen
+        __declspec( dllexport ) void addHIntervallText( double hIntervall, char *text );
+        __declspec( dllexport ) void addHIntervallText( double hIntervall, Text *text );
+        // Setzt den Text eines Horizontalen Intervalls
+        __declspec( dllexport ) void setHIntervallTextZ( double hIntervall, Text *text );
+        __declspec( dllexport ) void setHIntervallText( double hIntervall, Text *text );
+        __declspec( dllexport ) void setHIntervallText( double hIntervall, char *text );
+        // Text eines Horizontalen Intervalls entfernen
+        __declspec( dllexport ) void löscheHIntervallText( double hIntervall );
+        // Text eines Vertikalen Intervalls hinzufügen
+        __declspec( dllexport ) void addVIntervallText( double vIntervall, char *text );
+        __declspec( dllexport ) void addVIntervallText( double vIntervall, Text *text );
+        // Setzt den Text eines Vertikalen Intervalls
+        __declspec( dllexport ) void setVIntervallTextZ( double vIntervall, Text *text );
+        __declspec( dllexport ) void setVIntervallText( double vIntervall, Text *text );
+        __declspec( dllexport ) void setVIntervallText( double vIntervall, char *text );
+        // Text eines Vertikalen Intervalls entfernen
+        __declspec( dllexport ) void löscheVIntervallText( double vIntervall );
+        // Fügt einen Wert hinzu
+        __declspec( dllexport ) void addWertZ( DiagWert *w );
+        __declspec( dllexport ) void addWert( DiagWert *w );
+        __declspec( dllexport ) void addWert( const char *name );
+        __declspec( dllexport ) void addWert( Text *txt );
+        // setzt die Farbe eines Wertes
+        __declspec( dllexport ) void setWertFarbe( int wNum, int fc );
+        // fügt einem Wert einen Punkt hinzu
+        __declspec( dllexport ) void addPunktZ( int wNum, DiagPunkt *p );
+        __declspec( dllexport ) void addPunkt( int wNum, DiagPunkt *p );
+        __declspec( dllexport ) void addPunkt( int wNum, double hI, double vI );
+        // Ändert einen vorhandenen Punkt eines Wertes
+        __declspec( dllexport ) void setPunktZ( int wNum, double hI, DiagPunkt *p );
+        __declspec( dllexport ) void setPunkt( int wNum, double hI, DiagPunkt *p );
+        __declspec( dllexport ) void setPunkt( int wNum, double hI, double h, double v );
+        __declspec( dllexport ) void setPunktZ( int wNum, int pNum, DiagPunkt *p );
+        __declspec( dllexport ) void setPunkt( int wNum, int pNum, DiagPunkt *p );
+        __declspec( dllexport ) void setPunkt( int wNum, int pNum, double h, double v );
+        // Löscht einen vorhandenen Punkt
+        __declspec( dllexport ) void löschePunkt( int wNum, double hI );
+        __declspec( dllexport ) void löschePunkt( int wNum, int pNum );
+        // entfernt einen Wert
+        __declspec( dllexport ) void removeWert( int wNum );
+        __declspec( dllexport ) void removeWert( char *name );
+        __declspec( dllexport ) void removeWert( Text *name );
+        // Setzt den Style der Daten
+        __declspec( dllexport ) void addDatenStyle( int style );
+        __declspec( dllexport ) void setDatenStyle( int style );
+        __declspec( dllexport ) void setDatenStyle( int style, bool addRemove );
+        __declspec( dllexport ) void löscheDatenStyle( int style );
+        // Setzt den Style eines Wertes
+        __declspec( dllexport ) void addWertStyle( int wNum, int style );
+        __declspec( dllexport ) void setWertStyle( int wNum, int style );
+        __declspec( dllexport ) void setWertStyle( int wNum, int style, bool addRemove );
+        __declspec( dllexport ) void löscheWertStyle( int wNum, int style );
+        // constant
+        // Gibt die Daten des Diagramms zurück
+        __declspec( dllexport ) DiagDaten *getDiagDaten() const;
+        __declspec( dllexport ) DiagDaten *zDiagDaten() const;
+        // Gibt die Daten eines Wertes zurück
+        __declspec( dllexport ) DiagWert *getDiagWert( int wNum ) const;
+        __declspec( dllexport ) DiagWert *zDiagWert( int wNum ) const;
+        __declspec( dllexport ) DiagWert *getDiagWert( char *name ) const;
+        __declspec( dllexport ) DiagWert *zDiagWert( char *name ) const;
+        // Gibt die Position eines Wertes zurück
+        __declspec( dllexport ) int getDiagWertPos( char *name ) const;
+        // Gibt die Position eines Punktes von einem Wert zurück
+        __declspec( dllexport ) int getDiagPunktPos( int wNum, double hI ) const;
+        __declspec( dllexport ) int getDiagPunktPos( char *wName, double hI ) const;
+        // Prüft den Style der Daten
+        __declspec( dllexport ) inline bool hatDatenStyle( int style ) const;
+        __declspec( dllexport ) inline bool hatDatenStyleNicht( int style ) const;
+        // Prüft den Style eines Wertes
+        __declspec( dllexport ) inline bool hatWertStyle( int wNum, int style ) const;
+        __declspec( dllexport ) inline bool hatWertStyleNicht( int wNum, int style ) const;
+        // Reference Counting
+        __declspec( dllexport ) BaseDiag *getThis();
+        __declspec( dllexport ) virtual BaseDiag *release();
+    };
+
+    // Linien Diagramm
+    class LDiag : public ZeichnungHintergrund, public BaseDiag
+    {
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 DatenRahmen = 0x0001000;
+            const static __int64 DatenHintergrund = 0x02000;
+            const static __int64 DatenHAlpha = 0x04000;
+            const static __int64 DatenHBild = 0x008000;
+            const static __int64 DatenBuffered = 0x010000;
+
+            const static __int64 scroll = VScroll | HScroll;
+            const static __int64 normal = Hintergrund | scroll | DatenRahmen;
+        };
+    private:
+        Schrift *schrift;
+        LRahmen *dRam;
+        int dBgF;
+        Bild *dBgB;
+        AlphaFeld *dAf;
+        Bild *vIntervallRB;
+        Bild *hIntervallRB;
+        int schriftGr;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) LDiag();
+        // Destruktor
+        __declspec( dllexport ) ~LDiag();
+        // nicht constant
+        // Setzt die Schrift
+        __declspec( dllexport ) void setSchriftZ( Schrift *schrift );
+        __declspec( dllexport ) void setSchriftGröße( int gr );
+        // Setzt den inneren Rahmen um das eigentliche Diagramm
+        __declspec( dllexport ) void setDatenRahmenZ( LRahmen *ram );
+        __declspec( dllexport ) void setDatenRahmen( LRahmen *ram );
+        __declspec( dllexport ) void setDatenRahmenBreite( int br );
+        __declspec( dllexport ) void setDatenRahmenFarbe( int fc );
+        // Setzt den Hintergrund des eigentlichen Diagramms
+        __declspec( dllexport ) void setDatenHintergrundFarbe( int fc );
+        __declspec( dllexport ) void setDatenHintergrundBildZ( Bild *b );
+        __declspec( dllexport ) void setDatenHintergrundBild( Bild *b );
+        // Setzt das AlphaFeld des eigentlichen Diagramms
+        __declspec( dllexport ) void setDatenAlphaFeldZ( AlphaFeld *af );
+        __declspec( dllexport ) void setDatenAlphaFeld( AlphaFeld *af );
+        __declspec( dllexport ) void setDatenAlphaFeldFarbe( int fc );
+        __declspec( dllexport ) void setDatenAlphaFeldStärke( int st );
+        __declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+        __declspec( dllexport ) void render( Bild &zRObj ) override;
+        // constant
+        // Gibt die Schrift zurück
+        __declspec( dllexport ) Schrift *getSchrift() const;
+        __declspec( dllexport ) Schrift *zSchrift() const;
+        // Gibt den inneren Rahmen um das eigentliche Diagramm zurück
+        __declspec( dllexport ) LRahmen *getDatenRahmen() const;
+        __declspec( dllexport ) LRahmen *zDatenRahmen() const;
+        __declspec( dllexport ) int getDatenRahmenFarbe() const;
+        __declspec( dllexport ) int getDatenRahmenBreite() const;
+        // Gibt den Hintergrund des eigentlichen Diagramms zurück
+        __declspec( dllexport ) int getDatenHintergrundFarbe() const;
+        __declspec( dllexport ) Bild *getDatenHintergrundBild() const;
+        __declspec( dllexport ) Bild *zDatenHintergrundBild() const;
+        // Gibt das AlphaFeld des eigentlichen Diagramms zurück
+        __declspec( dllexport ) AlphaFeld *getDatenAlphaFeld() const;
+        __declspec( dllexport ) AlphaFeld *zDatenAlphaFeld() const;
+        __declspec( dllexport ) int getDatenAlphaFeldFarbe() const;
+        __declspec( dllexport ) int getDatenAlphaFeldStärke() const;
+        // Reference Counting
+        __declspec( dllexport ) BaseDiag *release() override;
+    };
+}
+
+#endif

+ 115 - 0
DreieckListe.h

@@ -0,0 +1,115 @@
+#ifndef DreieckListe_H
+#define DreieckListe_H
+
+#include "Punkt.h"
+#include "Array.h"
+
+namespace Framework
+{
+	template< typename T >
+	struct DreieckPunkt
+	{
+		T *punkt;
+		Punkt *textur;
+        // Konstruktor
+        DreieckPunkt( T *punkt, Punkt *textur )
+        {
+            this->punkt = punkt;
+            this->textur = textur;
+        }
+		// Destruktor
+		~DreieckPunkt()
+		{
+			delete punkt;
+			delete textur;
+		}
+	};
+
+	template< typename T >
+	class DreieckListe
+	{
+	private:
+		Array< DreieckPunkt< T >* > *punkte;
+		int ref;
+
+	public:
+		// Konstruktor
+		DreieckListe()
+		{
+			ref = 1;
+			punkte = new Array< DreieckPunkt< T >* >();
+		}
+
+		// Destruktor
+		~DreieckListe()
+		{
+			int anz = punkte->getEintragAnzahl();
+			for( int i = 0; i < anz; i++ )
+				delete punkte->get( i );
+			punkte->release();
+		}
+
+		// nicht constant
+		void addPunkt( T *p, Punkt *textur )
+		{
+			punkte->add( new DreieckPunkt< T >( p, textur ) );
+		}
+
+		void löscheLetztenPunkt()
+		{
+			int i = punkte->getEintragAnzahl() - 1;
+			if( !punkte->hat( i ) )
+				return;
+			delete punkte->get( i );
+			punkte->lösche( i );
+		}
+
+		void lehren()
+		{
+			int anz = punkte->getEintragAnzahl();
+			for( int i = 0; i < anz; i++ )
+				delete punkte->get( i );
+			punkte->leeren();
+		}
+
+		// constant
+		int getDreieckAnzahl() const
+		{
+			return punkte->getEintragAnzahl() - 2;
+		}
+
+		bool hatTextur() const
+		{
+			int anz = punkte->getEintragAnzahl();
+			bool ret = 1;
+			for( int i = 0; i < anz; i++ )
+			{
+				if( punkte->hat( i ) )
+				    ret &= punkte->get( i )->textur;
+			}
+			return ret;
+		}
+
+		Array< DreieckPunkt< T >* > *zListe() const
+		{
+			return punkte;
+		}
+
+		// Reference Counting
+		DreieckListe *getThis()
+		{
+			ref++;
+			return this;
+		}
+
+		DreieckListe *release()
+		{
+			ref--;
+			if( !ref )
+				delete this;
+			return 0;
+		}
+	};
+}
+
+#endif

+ 2473 - 0
Fenster.cpp

@@ -0,0 +1,2473 @@
+#include "Fenster.h"
+#include "Text.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Bildschirm.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include "Rahmen.h"
+#include "TextFeld.h"
+#include "Scroll.h"
+#include "Maus.h"
+#include "ToolTip.h"
+#include "Globals.h"
+
+using namespace Framework;
+
+// Fensterklasse erzeugen
+WNDCLASS Framework::F_Normal( HINSTANCE hInst )// Erzeugen einer normalen Fensterklasse
+{
+	WNDCLASS ret;
+	ret.cbClsExtra = 0;
+	ret.cbWndExtra = 0;
+	ret.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
+	ret.hCursor = LoadCursor( NULL, IDC_ARROW );
+	ret.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+	ret.hInstance = hInst;
+	ret.lpszMenuName = "";
+	ret.lpfnWndProc = WindowProc;
+	ret.style = CS_HREDRAW | CS_VREDRAW;
+	return ret;
+}
+
+WNDCLASSEX Framework::F_NormalEx( HINSTANCE hInst )
+{
+	WNDCLASSEX ret;
+	ret.cbSize = sizeof( WNDCLASSEX );
+	ret.cbClsExtra = 0;
+	ret.cbWndExtra = 0;
+	ret.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
+	ret.hCursor = LoadCursor( NULL, IDC_ARROW );
+	ret.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+	ret.hInstance = hInst;
+	ret.lpszMenuName = "";
+	ret.lpfnWndProc = WindowProc;
+	ret.style = CS_HREDRAW | CS_VREDRAW;
+	ret.hIconSm = 0;
+	return ret;
+}
+
+// WinAPI
+LRESULT CALLBACK Framework::WindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
+{
+	if( msgExit )
+		return ( DefWindowProc( hwnd, message, wparam, lparam ) );
+	switch( message )
+	{
+		// Maus Zeiger 
+	case WM_SETCURSOR:
+		MausZeiger.update();
+		return 0;
+		// Fenster 
+	case WM_SIZE:
+		if( wparam == SIZE_RESTORED )
+			WFensterA.sendRestoreMessage( hwnd );
+		break;
+		// Schließen 
+	case WM_CLOSE:
+		if( WFensterA.sendVSchließMessage( hwnd ) )
+			return 0;
+		else
+			break;
+	case WM_DESTROY:
+		if( WFensterA.sendNSchließMessage( hwnd ) )
+			return 0;
+		else
+			break;
+		// Maus 
+	case WM_LBUTTONDOWN: // Linksklick
+		if( 1 )
+		{
+			MausStand[ M_Links ] = 1;
+			MausEreignis me = { ME_PLinks, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_RBUTTONDOWN: // Rechtsklick
+		if( 1 )
+		{
+			MausStand[ M_Rechts ] = 1;
+			MausEreignis me = { ME_PRechts, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MBUTTONDOWN: // Mittelklick
+		if( 1 )
+		{
+			MausStand[ M_Mitte ] = 1;
+			MausEreignis me = { ME_PMitte, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_LBUTTONUP: // Linksrelease
+		if( 1 )
+		{
+			MausStand[ M_Links ] = 0;
+			MausEreignis me = { ME_RLinks, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_RBUTTONUP: // Rechtsrelease
+		if( 1 )
+		{
+			MausStand[ M_Rechts ] = 0;
+			MausEreignis me = { ME_RRechts, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MBUTTONUP: // Mittelrelease
+		if( 1 )
+		{
+			MausStand[ M_Mitte ] = 0;
+			MausEreignis me = { ME_RMitte, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_LBUTTONDBLCLK: // Linksdoppelklick
+		if( 1 )
+		{
+			MausEreignis me = { ME_DKLinks, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_RBUTTONDBLCLK: // Rechtsdoppelklick
+		if( 1 )
+		{
+			MausEreignis me = { ME_DKRechts, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MBUTTONDBLCLK: // Mitteldoppelklick
+		if( 1 )
+		{
+			MausEreignis me = { ME_DKMitte, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MOUSEHOVER: // Maus betritt Fenster
+		if( 1 )
+		{
+			MausTrack = 1;
+			MausEreignis me = { ME_Betritt, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MOUSELEAVE: // Maus verlässt Fenster
+		if( 1 )
+		{
+			MausTrack = 1;
+			MausEreignis me = { ME_Verlässt, (int)LOWORD( lparam ), (int)HIWORD( lparam ), 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MOUSEMOVE: // Maus wird bewegt
+		if( 1 )
+		{
+			if( mausPos.x == (int)LOWORD( lparam ) && mausPos.y == (int)HIWORD( lparam ) )
+				break;
+			mausPos.x = (int)LOWORD( lparam );
+			mausPos.y = (int)HIWORD( lparam );
+			if( MausTrack )
+			{
+				TRACKMOUSEEVENT lptme;
+				lptme.cbSize = sizeof( TRACKMOUSEEVENT );
+				lptme.dwFlags = TME_HOVER | TME_LEAVE;
+				lptme.dwHoverTime = 0;
+				lptme.hwndTrack = hwnd;
+				TrackMouseEvent( &lptme );
+				MausTrack = 0;
+			}
+			MausEreignis me = { ME_Bewegung, mausPos.x, mausPos.y, 0, 0, 0 };
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+	case WM_MOUSEWHEEL: // Maus scroll
+		if( 1 )
+		{
+			MausEreignis me = { 0, mausPos.x, mausPos.y, 0, 0, 0 };
+			if( (int)(short)HIWORD( wparam ) < 0 )
+				me.id = !getTastenStand( T_Shift ) ? ME_DScroll : ME_RScroll;
+			else
+				me.id = !getTastenStand( T_Shift ) ? ME_UScroll : ME_LScroll;
+			me.rmx = me.mx;
+			me.rmy = me.my;
+			WFensterA.sendMausMessage( hwnd, me );
+			break;
+		}
+		// Tastatur 
+	case WM_KEYDOWN:
+		if( 1 )
+		{
+			TastaturEreignis te = { TE_Press, VirtualZuChar( (int)wparam ), 0 };
+			if( te.taste == T_Alt_Gr )
+				TastenStand[ T_Strg ] = 0;
+			TastenStand[ te.taste ] = 1;
+			WFensterA.sendTastaturMessage( hwnd, te );
+			break;
+		} // Taste wird gedrückt
+	case WM_KEYUP:
+		if( 1 )
+		{
+			TastaturEreignis te = { TE_Release, VirtualZuChar( (int)wparam ), 0 };
+			TastenStand[ te.taste ] = 0;
+			WFensterA.sendTastaturMessage( hwnd, te );
+			break;
+		} // Taste wird losgelassen
+	}
+	return ( DefWindowProc( hwnd, message, wparam, lparam ) );
+}
+
+void Framework::StartNachrichtenSchleife()
+{
+	MSG msg;
+	while( GetMessage( &msg, NULL, 0, 0 ) > 0 && !msgExit )
+	{
+		if( !msgExit )
+		{
+			TranslateMessage( &msg );
+			DispatchMessage( &msg );
+		}
+	}
+	msgExit = 0;
+}
+
+void Framework::StopNachrichtenSchleife( HWND hwnd )
+{
+	msgExit = 1;
+	PostMessage( hwnd, WM_MOUSELEAVE, 0, 0 );
+}
+
+unsigned char Framework::VirtualZuChar( int Virtual )
+{
+	UINT vk = MapVirtualKey( Virtual, 2 );
+	if( !vk )
+	{
+		switch( Virtual )
+		{
+		case VK_CAPITAL:
+			return T_Caps_Lock;
+		case VK_SHIFT:
+			return T_Shift;
+		case VK_CONTROL:
+			return T_Strg;
+		case VK_F1:
+			return T_F1;
+		case VK_F2:
+			return T_F2;
+		case VK_F3:
+			return T_F3;
+		case VK_F4:
+			return T_F4;
+		case VK_F5:
+			return T_F5;
+		case VK_F6:
+			return T_F6;
+		case VK_F7:
+			return T_F7;
+		case VK_F8:
+			return T_F8;
+		case VK_F9:
+			return T_F9;
+		case VK_F10:
+			return T_F10;
+		case VK_F11:
+			return T_F11;
+		case VK_F12:
+			return T_F12;
+		case VK_PAUSE:
+			return T_Pause;
+		case VK_SNAPSHOT:
+			return T_Druck;
+		case VK_INSERT:
+			return T_Einfg;
+		case VK_DELETE:
+			return T_Entf;
+		case VK_LEFT:
+			return T_Links;
+		case VK_UP:
+			return T_Oben;
+		case VK_RIGHT:
+			return T_Rechts;
+		case VK_DOWN:
+			return T_Unten;
+		case VK_MENU:
+			return T_Alt_Gr;
+		case VK_NUMLOCK:
+			return T_Num;
+		case VK_HOME:
+			return T_Pos1;
+		case VK_PRIOR:
+			return T_BildO;
+		case VK_NEXT:
+			return T_BildU;
+		case VK_END:
+			return T_Ende;
+		case VK_TAB:
+			return T_Tab;
+		}
+	}
+	if( vk == VK_TAB )
+		return T_Tab;
+	char ret = (char)(short)LOWORD( vk );
+	short SHIFT = GetKeyState( VK_SHIFT );
+	short CAPSLOCK = GetKeyState( VK_CAPITAL );
+	short ALTGR = TastenStand[ T_Alt_Gr ];
+	if( ALTGR )
+	{
+		switch( ret )
+		{
+		case 'q':
+			return '@';
+		case 'Q':
+			return '@';
+		case '<':
+			return '|';
+		case '>':
+			return '|';
+		case '7':
+			return '{';
+		case '/':
+			return '{';
+		case '8':
+			return '[';
+		case '(':
+			return '[';
+		case '9':
+			return ']';
+		case ')':
+			return ']';
+		case '0':
+			return '}';
+		case '=':
+			return '}';
+		case 'ß':
+			return '\\';
+		case '?':
+			return '\\';
+		case '+':
+			return '~';
+		case '*':
+			return '~';
+		case 'e':
+			return '€';
+		case 'E':
+			return '€';
+		case 'm':
+			return 'µ';
+		case 'M':
+			return 'µ';
+		case '2':
+			return '²';
+		case '"':
+			return '²';
+		case '3':
+			return '³';
+		case '§':
+			return '³';
+		}
+	}
+	SHIFT = HIWORD( SHIFT );
+	CAPSLOCK = LOWORD( CAPSLOCK );
+	bool up = 0;
+	if( SHIFT && !CAPSLOCK )
+		up = 1;
+	if( CAPSLOCK && !SHIFT )
+		up = 1;
+	ret = KleinOrGroß( ret, up );
+	return ret;
+}
+
+// Inhalt der WFenster Klasse aus Fenster.h
+// Konstruktor 
+WFenster::WFenster()
+	: hWnd( 0 ),
+	  style( 0 ),
+	  makParam( 0 ),
+	  sakParam( 0 ),
+	  takParam( 0 ),
+	  MausAktion( 0 ),
+	  VSchließAktion( 0 ),
+	  NSchließAktion( 0 ),
+	  TastaturAktion( 0 ),
+	  screen( 0 ),
+	  mx( -1 ),
+	  my( -1 ),
+	  verschiebbar( 0 ),
+	  ref( 1 ),
+	  rahmen( 0 ),
+	  bitmap( 0 ),
+	  hdc( 0 )
+{
+	WFensterA.addFenster( this );
+}
+
+WFenster::WFenster( HWND hwnd )
+	: WFenster()
+{
+	hWnd = hwnd;
+}
+
+// Destruktor 
+WFenster::~WFenster()
+{
+	if( WFensterA.removeFenster( this ) )
+	{
+		WFensterA.del();
+	}
+	if( hWnd )
+		DestroyWindow( hWnd );
+	if( screen )
+		screen->release();
+}
+
+// nicht constant 
+void WFenster::erstellen( int style, WNDCLASS wc ) // Erstellt ein Fenster in Windows
+{
+	if( !GetClassInfo( wc.hInstance, wc.lpszClassName, &wc ) )
+	{
+#pragma warning(suppress: 6102)
+		if( !RegisterClass( &wc ) ) // Register Fensterklasse
+		{
+			MessageBox( hWnd, "Fehler beim Registrieren der Fensterklasse!", "Error", MB_ICONERROR ); // Fehlermeldung bei Fehler
+			return;
+		}
+	}
+
+	hWnd = CreateWindow( wc.lpszClassName, wc.lpszClassName, style, 0, 0, 0, 0, 0, 0, wc.hInstance, 0 ); // Fenster Erstellen
+
+	if( hWnd == 0 )
+	{
+		MessageBox( hWnd, "Fehler beim erstellen des Fensters!", "Error", MB_ICONERROR ); // Fehlermeldung bei Fehler
+		return;
+	}
+	this->style = style;
+}
+
+void WFenster::erstellenEx( int exStyle, int style, WNDCLASSEX wc ) // Das Fenster Erstellen
+{
+	if( !GetClassInfoEx( wc.hInstance, wc.lpszClassName, &wc ) )
+	{
+#pragma warning(suppress: 6102)
+		if( !RegisterClassEx( &wc ) ) // Register Fensterklasse
+		{
+			MessageBox( hWnd, "Fehler beim Registrieren der Fensterklasse!", "Error", MB_ICONERROR ); // Fehlermeldung bei Fehler
+			return;
+		}
+	}
+
+	hWnd = CreateWindowEx( exStyle, wc.lpszClassName, wc.lpszClassName, style, 0, 0, 0, 0, 0, 0, wc.hInstance, 0 ); // Fenster Erstellen
+
+	if( hWnd == 0 )
+	{
+		MessageBox( hWnd, "Fehler beim erstellen des Fensters!", "Error", MB_ICONERROR ); // Fehlermeldung bei Fehler
+		return;
+	}
+	this->style = style;
+}
+
+void WFenster::setAnzeigeModus( int mod )// Fenster Anzeigen
+{
+	if( rahmen )
+	{
+		if( mod == 2 )
+			ShowWindow( rahmen, 0 );
+		else
+			ShowWindow( rahmen, mod );
+	}
+	ShowWindow( hWnd, mod );
+}
+
+bool WFenster::setFokus() // Setzt den Fokus auf das Fenster
+{
+	DWORD dwCurrentThread = GetCurrentThreadId();
+	DWORD dwFGThread = GetWindowThreadProcessId( GetForegroundWindow(), NULL );
+	AttachThreadInput( dwCurrentThread, dwFGThread, TRUE );
+	SetFocus( hWnd );
+	AttachThreadInput( dwCurrentThread, dwFGThread, FALSE );
+	SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
+	SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
+	return GetFocus() == hWnd;
+}
+
+void WFenster::setPosition( Punkt &p )// Fenster Position
+{
+	RECT r;
+	GetWindowRect( hWnd, &r ); // Vorherige Position herausfinden
+	RECT res;
+	res.left = p.x, res.top = p.y, res.right = r.right - r.left, res.bottom = r.bottom - r.top;
+	AdjustWindowRect( &res, style, 0 );
+	if( res.top < 0 )
+	{
+		res.bottom -= res.top;
+		res.top = 0;
+	}
+	if( res.left < 0 )
+	{
+		res.right -= res.left;
+		res.left = 0;
+	}
+	SetWindowPos( hWnd, 0, res.left, res.top, res.right, res.bottom, 0 ); // Position ändern
+}
+
+void WFenster::setGröße( Punkt &g )// Fenster Größe
+{
+	RECT r;
+	GetWindowRect( hWnd, &r ); // vorherige Größe herausfinden
+	RECT res;
+	res.left = r.left, res.top = r.top, res.right = g.x, res.bottom = g.y;
+	AdjustWindowRect( &res, style, 0 );
+	if( res.top < 0 )
+	{
+		res.bottom -= res.top;
+		res.top = 0;
+	}
+	if( res.left < 0 )
+	{
+		res.right -= res.left;
+		res.left = 0;
+	}
+	SetWindowPos( hWnd, 0, res.left, res.top, res.right, res.bottom, 0 ); // Größe ändern
+}
+
+void WFenster::setGröße( int breite, int höhe )
+{
+	RECT r;
+	GetWindowRect( hWnd, &r ); // vorherige Größe herausfinden
+	RECT res;
+	res.left = r.left, res.top = r.top, res.right = breite, res.bottom = höhe;
+	AdjustWindowRect( &res, style, 0 );
+	if( res.top < 0 )
+	{
+		res.bottom -= res.top;
+		res.top = 0;
+	}
+	if( res.left < 0 )
+	{
+		res.right -= res.left;
+		res.left = 0;
+	}
+	SetWindowPos( hWnd, 0, res.left, res.top, res.right, res.bottom, 0 ); // Größe ändern
+}
+
+void WFenster::setBounds( Punkt &p, Punkt &g ) // setzt größe und Position
+{
+	SetWindowPos( hWnd, 0, p.x, p.y, g.x, g.y, 0 ); // Größe und Position ändern
+}
+
+void WFenster::setBildschirm( Bildschirm *screen )
+{
+	if( this->screen )
+		this->screen->release();
+	this->screen = screen;
+}
+
+void WFenster::zerstören()
+{
+	DestroyWindow( hWnd );
+	if( rahmen )
+		DestroyWindow( rahmen );
+	if( bitmap )
+		DeleteObject( bitmap );
+	if( hdc )
+		DeleteDC( hdc );
+}
+
+void WFenster::doMausAktion( MausEreignis &me )
+{
+	if( !MausAktion || !MausAktion( makParam, this, me ) )
+		return;
+	if( screen && me.id != ME_Betritt && me.id != ME_Verlässt )
+	{
+		screen->doMausEreignis( me );
+		if( !me.verarbeitet && verschiebbar )
+		{
+			if( mx != -1 && my != -1 ) // verschieben
+			{
+				RECT r;
+				if( rahmen )
+				{
+					GetWindowRect( rahmen, &r );
+					r.right -= r.left, r.bottom -= r.top;
+					r.left += me.mx - mx;
+					r.top += me.my - my;
+					SetWindowPos( rahmen, 0, r.left, r.top, r.right, r.bottom, 0 ); // Position setzen
+				}
+				GetWindowRect( hWnd, &r ); // Vorherige Position herausfinden
+				r.right -= r.left, r.bottom -= r.top; // Position updaten
+				r.left += me.mx - mx;
+				r.top += me.my - my;
+				SetWindowPos( hWnd, 0, r.left, r.top, r.right, r.bottom, 0 ); // Position setzen
+
+			}
+			else if( me.id == ME_PLinks ) // verschieben starten
+				mx = me.mx, my = me.my;
+			if( me.id == ME_RLinks ) // verschieben beenden
+				mx = -1, my = -1;
+			me.verarbeitet = 1;
+		}
+	}
+}
+
+void WFenster::doVSchließAktion()
+{
+	if( !VSchließAktion )
+		return;
+	VSchließAktion( sakParam, this );
+}
+
+void WFenster::doNSchließAktion()
+{
+	if( !NSchließAktion )
+		return;
+	NSchließAktion( sakParam, this );
+}
+
+void WFenster::doTastaturAktion( TastaturEreignis &te )
+{
+	if( !TastaturAktion || !TastaturAktion( takParam, this, te ) )
+		return;
+	if( screen )
+		screen->doTastaturEreignis( te );
+}
+
+void WFenster::doRestoreMessage() // macht den Rahmen sichtbar
+{
+	if( rahmen )
+		ShowWindow( rahmen, 1 );
+	ShowWindow( hWnd, 1 );
+}
+
+void WFenster::setMausEreignisParameter( void *p ) // setzt den Parameter vom Maus Ereignis
+{
+	makParam = p;
+}
+
+void WFenster::setSchließEreignisParameter( void *p ) // setzt den Parameter vom Schließ Ereignis
+{
+	sakParam = p;
+}
+
+void WFenster::setTastaturEreignisParameter( void *p ) // setzt den Parameter vom Tastatur Ereignis
+{
+	takParam = p;
+}
+
+void WFenster::setMausAktion( bool( *MausAk )( void *, void *, MausEreignis ) )
+{
+	MausAktion = MausAk;
+}
+
+void WFenster::setVSchließAktion( void( *vSchließAk )( void *, void * ) )
+{
+	VSchließAktion = vSchließAk;
+}
+
+void WFenster::setNSchließAktion( void( *nSchließAk )( void *, void * ) )
+{
+	NSchließAktion = nSchließAk;
+}
+
+void WFenster::setTastaturAktion( bool( *TastaturAk )( void *, void *, TastaturEreignis ) )
+{
+	TastaturAktion = TastaturAk;
+}
+
+void WFenster::setFensterHandle( HWND hWnd ) // setzt das operationsfenster
+{
+	this->hWnd = hWnd;
+}
+
+void WFenster::setVerschiebbar( bool verschiebbar ) // legt fest, ob das Fenster durch ziehen mit Maus verschoben werden kann
+{
+	this->verschiebbar = verschiebbar;
+}
+
+void WFenster::ladeRahmenFenster( Bild *zBild, HINSTANCE hinst ) // setzt einen Transpatenten Rahmen um das Fenster
+{
+	if( !zBild )
+		return;
+	// Fenster erstellen
+	WNDCLASSEX wcl = { 0 };
+	wcl.cbSize = sizeof( wcl );
+	wcl.style = CS_HREDRAW | CS_VREDRAW;
+	wcl.lpfnWndProc = WindowProc;
+	wcl.cbClsExtra = 0;
+	wcl.cbWndExtra = 0;
+	wcl.hInstance = hinst;
+	wcl.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+	wcl.hCursor = LoadCursor( NULL, IDC_ARROW );
+	wcl.hbrBackground = NULL;
+	wcl.lpszMenuName = NULL;
+	wcl.lpszClassName = TEXT( "LayeredWindowClass" );
+	wcl.hIconSm = NULL;
+
+	// Bitmap erstellen
+	hdc = CreateCompatibleDC( NULL );
+	if( !hdc )
+		return;
+	BITMAPINFO info;
+	info.bmiHeader.biSize = sizeof( info.bmiHeader );
+	info.bmiHeader.biBitCount = 32;
+	info.bmiHeader.biWidth = zBild->getBreite();
+	info.bmiHeader.biHeight = -zBild->getHöhe();
+	info.bmiHeader.biCompression = BI_RGB;
+	info.bmiHeader.biPlanes = 1;
+	unsigned char *pPixels = 0;
+	bitmap = CreateDIBSection( hdc, &info, DIB_RGB_COLORS, (void**)&pPixels, 0, 0 );
+	if( !bitmap )
+		DeleteDC( hdc );
+	GdiFlush();
+	// bitmap füllen
+	int pitch = ( ( zBild->getBreite() * 32 + 31 ) & ~31 ) >> 3;
+	unsigned char *pRow = 0;
+	int *buffer = zBild->getBuffer();
+	for( int i = 0; i < zBild->getHöhe(); ++i )
+	{
+		pRow = &pPixels[ i * pitch ];
+		for( int i2 = 0; i2 < zBild->getBreite(); ++i2 )
+		{
+			pRow[ i2 * 4 ] = (unsigned char)( ( buffer[ i2 + i * zBild->getBreite() ] >> 16 ) & 0xFF );
+			pRow[ i2 * 4 + 1 ] = (unsigned char)( ( buffer[ i2 + i * zBild->getBreite() ] >> 8 ) & 0xFF );
+			pRow[ i2 * 4 + 2 ] = (unsigned char)( ( buffer[ i2 + i * zBild->getBreite() ] ) & 0xFF );
+			pRow[ i2 * 4 + 3 ] = (unsigned char)( ( buffer[ i2 + i * zBild->getBreite() ] >> 24 ) & 0xFF );
+		}
+	}
+	// alpha berechnen
+	unsigned char *pPixel = 0;
+	if( zBild->getBreite() * 4 == pitch )
+	{
+		int i = 0;
+		int totalBytes = zBild->getBreite() * zBild->getHöhe() * 4;
+
+		for( i = 0; i < totalBytes; i += 4 )
+		{
+			pPixel = &pPixels[ i ];
+			pPixel[ 0 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+			pPixel[ 1 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+			pPixel[ 2 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+		}
+	}
+	else
+	{
+		int x = 0;
+		int y = 0;
+
+		for( y = 0; y < zBild->getHöhe(); ++y )
+		{
+			for( x = 0; x < zBild->getBreite(); ++x )
+			{
+				pPixel = &pPixels[ ( y * pitch ) + ( x * 4 ) ];
+				pPixel[ 0 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+				pPixel[ 1 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+				pPixel[ 2 ] *= (unsigned char)( (float)pPixel[ 3 ] / 255.0f );
+			}
+		}
+	}
+	// Fenster erstellen fortsetzen
+	if( RegisterClassEx( &wcl ) )
+	{
+		rahmen = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_LAYERED,
+								 wcl.lpszClassName,
+								 TEXT( "Transparentes Fenster" ),
+								 WS_POPUP,
+								 0,
+								 0,
+								 zBild->getBreite(),
+								 zBild->getHöhe(),
+								 0,
+								 0,
+								 wcl.hInstance,
+								 0
+								 );
+		if( rahmen )
+		{
+			// zeichnen
+			HDC h = 0;
+			if( ( h = GetDC( rahmen ) ) && bitmap )
+			{
+				HGDIOBJ hPrevObj = NULL;
+				POINT ptDest = { 0, 0 };
+				POINT ptSrc = { 0, 0 };
+				SIZE client = { zBild->getBreite(), zBild->getHöhe() };
+				BLENDFUNCTION blendFunc = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+
+				hPrevObj = SelectObject( hdc, bitmap );
+				ClientToScreen( rahmen, &ptDest );
+
+				UpdateLayeredWindow( rahmen, h, &ptDest, &client, hdc, &ptSrc, 0, &blendFunc, ULW_ALPHA );
+
+				SelectObject( hdc, hPrevObj );
+				ReleaseDC( rahmen, h );
+			}
+			UpdateWindow( rahmen );
+			Punkt pos = getPosition() + ( getGröße() - zBild->getGröße() ) / 2;
+			SetWindowPos( rahmen, 0, pos.x, pos.y, zBild->getBreite(), zBild->getHöhe(), 0 );
+		}
+	}
+}
+
+// constant 
+Punkt WFenster::getPosition() const // gibt die Position zurück
+{
+	RECT r;
+	GetWindowRect( hWnd, &r ); // Position herausfinden
+	return{ r.left, r.top };
+}
+
+Punkt WFenster::getKörperPosition() const // gibt die Fenster Körperposition zurück
+{
+	RECT r;
+	GetClientRect( hWnd, &r ); // Position herausfinden
+	return{ r.left, r.top };
+}
+
+Punkt WFenster::getGröße() const // gibt die Größe zurück
+{
+	RECT r;
+	GetWindowRect( hWnd, &r ); // Größe herausfinden
+	return{ r.right - r.left, r.bottom - r.top };
+}
+
+Punkt WFenster::getKörperGröße() const // gibt die Fenster Körpergröße zurück
+{
+	RECT r;
+	GetClientRect( hWnd, &r ); // Größe herausfinden
+	return{ r.right - r.left, r.bottom - r.top };
+}
+
+int WFenster::getKörperBreite() const // gibt die Fenster Körperbreite zurück
+{
+	RECT r;
+	GetClientRect( hWnd, &r ); // Größe herausfinden
+	return r.right;
+}
+
+int WFenster::getKörperHöhe() const // gibt die Fenster Körperhöhe zurück
+{
+	RECT r;
+	GetClientRect( hWnd, &r ); // Größe herausfinden
+	return r.bottom;
+}
+
+HWND WFenster::getFensterHandle() const // gibt ein Handle zum Fenster zurück
+{
+	return hWnd;
+}
+
+bool WFenster::hatMausAktion() const
+{
+	return MausAktion != 0;
+}
+
+bool WFenster::hatVSchließAktion() const
+{
+	return VSchließAktion != 0;
+}
+
+bool WFenster::hatNSchließAktion() const
+{
+	return NSchließAktion != 0;
+}
+
+bool WFenster::hatTastaturAktion() const
+{
+	return TastaturAktion != 0;
+}
+
+Bildschirm *WFenster::getBildschirm() const
+{
+	if( !screen )
+		return 0;
+	return screen->getThis();
+}
+
+Bildschirm *WFenster::zBildschirm() const
+{
+	return screen;
+}
+
+bool WFenster::istVerschiebbar() const // prüft, ob das Fenster durch ziehen mit Maus verschoben werden kann
+{
+	return verschiebbar;
+}
+
+// Reference Counting
+WFenster *WFenster::getThis()
+{
+	++ref;
+	return this;
+}
+
+WFenster *WFenster::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der WFensterArray Klasse aus Fenster.h
+// Konstruktor 
+WFensterArray::WFensterArray()
+	: next( 0 ),
+	  This( 0 )
+{
+}
+
+// Destruktor 
+WFensterArray::~WFensterArray()
+{
+	if( next )
+		delete next;
+}
+
+// add und remove 
+bool WFensterArray::addFenster( WFenster *fenster )
+{
+	if( fenster == This )
+		return 0;
+	if( !This )
+	{
+		This = fenster;
+		return 1;
+	}
+	if( !next )
+		next = new WFensterArray();
+	return next->addFenster( fenster );
+}
+
+bool WFensterArray::removeFenster( WFenster *fenster )
+{
+	if( fenster == This )
+		return 1;
+	if( !next )
+		return 0;
+	if( next->removeFenster( fenster ) )
+	{
+		WFensterArray *tmp = next->getNext();
+		next->setNext0();
+		delete next;
+		next = tmp;
+	}
+	return 0;
+}
+
+WFensterArray *WFensterArray::getNext()
+{
+	return next;
+}
+
+void WFensterArray::setNext0()
+{
+	next = 0;
+}
+
+void WFensterArray::del()
+{
+	if( next )
+	{
+		This = next->getThis();
+		WFensterArray *tmp = next->getNext();
+		next->setNext0();
+		delete next;
+		next = tmp;
+	}
+	else
+		This = 0;
+}
+
+// Messages 
+bool WFensterArray::sendVSchließMessage( HWND hwnd )
+{
+	if( !This )
+		return 0;
+	bool ret = 0;
+	if( This->getFensterHandle() == hwnd && This->hatVSchließAktion() )
+	{
+		This->doVSchließAktion();
+		ret = 1;
+	}
+	if( !next )
+		return ret;
+	return ret | next->sendVSchließMessage( hwnd );
+}
+
+bool WFensterArray::sendNSchließMessage( HWND hwnd )
+{
+	if( !This )
+		return 0;
+	bool ret = 0;
+	if( This->getFensterHandle() == hwnd && This->hatNSchließAktion() )
+	{
+		This->doNSchließAktion();
+		ret = 1;
+	}
+	if( !next )
+		return ret;
+	return ret | next->sendNSchließMessage( hwnd );
+}
+
+bool WFensterArray::sendMausMessage( HWND hwnd, MausEreignis &me )
+{
+	if( !This )
+		return 0;
+	bool ret = 0;
+	if( This->getFensterHandle() == hwnd && This->hatMausAktion() )
+	{
+		This->doMausAktion( me );
+		ret = 1;
+	}
+	if( !next )
+		return ret;
+	return ret | next->sendMausMessage( hwnd, me );
+}
+
+bool WFensterArray::sendTastaturMessage( HWND hwnd, TastaturEreignis &te )
+{
+	if( !This )
+		return 0;
+	bool ret = 0;
+	if( This->getFensterHandle() == hwnd && This->hatTastaturAktion() )
+	{
+		This->doTastaturAktion( te );
+		ret = 1;
+	}
+	if( !next )
+		return ret;
+	return ret | next->sendTastaturMessage( hwnd, te );
+}
+
+bool WFensterArray::sendRestoreMessage( HWND hwnd )
+{
+	if( !This )
+		return 0;
+	bool ret = 0;
+	if( This->getFensterHandle() == hwnd && This->hatMausAktion() )
+	{
+		This->doRestoreMessage();
+		ret = 1;
+	}
+	if( !next )
+		return ret;
+	return ret | next->sendRestoreMessage( hwnd );
+}
+
+WFenster *WFensterArray::getThis()
+{
+	return This;
+}
+
+// WMessageBox
+void Framework::WMessageBox( HWND hWnd, Text *titel, Text *meldung, UINT style )
+{
+	MessageBox( hWnd, meldung->getText(), titel->getText(), style ); // Message Box
+	titel->release();
+	meldung->release();
+}
+
+// Inhalt der Fenster Klasse aus Fenster.h
+// Konstruktor 
+Fenster::Fenster()
+	: Zeichnung(),
+	schließenMe( 0 ),
+	schließenMeParam( 0 ),
+	rahmen( 0 ),
+	titel( 0 ),
+	members( 0 ),
+	bgKörperFarbe( 0xFF000000 ),
+	bgKörperBild( 0 ),
+	körperBuffer( 0 ),
+	bgSchließFarbe( 0xFF000000 ),
+	bgSchließBild( 0 ),
+	schließBuffer( 0 ),
+	schließKlickBuffer( 0 ),
+	vScroll( 0 ),
+	hScroll( 0 ),
+	kMin( 0, 0 ),
+	kMax( 0, 0 ),
+	schließKlick( 0 ),
+	klick( 0 ),
+	mx( 0 ),
+	my( 0 ),
+	ref( 1 )
+{
+    style = 0;
+	this->setMausEreignis( _ret1ME );
+	this->setTastaturEreignis( _ret1TE );
+	min = Punkt( 0, 0 ), max = Punkt( 0, 0 );
+}
+
+// Destruktor 
+Fenster::~Fenster()
+{
+	if( rahmen )
+		rahmen->release();
+	if( titel )
+		titel->release();
+	if( members )
+		delete members;
+	if( körperBuffer )
+		körperBuffer->release();
+	if( bgKörperBild )
+		bgKörperBild->release();
+	if( bgSchließBild )
+		bgSchließBild->release();
+	if( schließBuffer )
+		schließBuffer->release();
+	if( schließKlickBuffer )
+		schließKlickBuffer->release();
+	if( vScroll )
+		vScroll->release();
+	if( hScroll )
+		hScroll->release();
+}
+
+// nicht const 
+// -- Rahmen -- 
+void Fenster::setRahmenZ( LRahmen *ram ) // setzt den rahmen
+{
+	if( rahmen )
+		rahmen->release();
+	rahmen = ram;
+	rend = 1;
+}
+
+void Fenster::setRFarbe( int f ) // setzt die Rahmen Farbe
+{
+	if( !rahmen )
+		rahmen = new LRahmen();
+	rahmen->setFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setRBreite( int br ) // setzt die Breite des Rahmens
+{
+	if( !rahmen )
+		rahmen = new LRahmen();
+	rahmen->setRamenBreite( br );
+	rend = 1;
+}
+
+// -- Titel -- 
+void Fenster::setTitel( Text *txt ) // setzt den Titel
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setText( txt );
+	rend = 1;
+}
+
+void Fenster::setTitelZ( Text *txt )
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setTextZ( txt );
+	rend = 1;
+}
+
+void Fenster::setTitel( const char *txt )
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setText( txt );
+	rend = 1;
+}
+
+void Fenster::setTTextFeldZ( TextFeld *tf ) // setzt das Titel TextFeld
+{
+	if( titel )
+		titel->release();
+	titel = tf;
+	rend = 1;
+}
+
+// -- Schrift -- 
+void Fenster::setTSchriftZ( Schrift *schrift ) // setzt die Titel Schrift
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setSchriftZ( schrift );
+	rend = 1;
+}
+
+void Fenster::setTSFarbe( int f ) // setzt die Titel Schrift Farbe
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setSchriftFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setTSGröße( int gr ) // setzt die Titel Schrift Größe
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setSchriftGröße( gr );
+	rend = 1;
+}
+
+// -- Titel Hintergrund -- 
+void Fenster::setTBgFarbe( int f ) // setzt Titel Hintergrund farbe
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setHintergrundFarbe( f );
+	rend = 1;
+}
+
+// -- Titel AlphaFeld -- 
+void Fenster::setTAlphaFeldZ( AlphaFeld *af ) // setzt das Titel AlphaFeld
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setAlphaFeldZ( af );
+	rend = 1;
+}
+
+void Fenster::setTAfFarbe( int f ) // setzt die Titel AlphFeld Farbe
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setAlphaFeldFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setTAfStärke( int st ) // setzt die Stärke des Titel AlphaFeldes
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setAlphaFeldStärke( st );
+	rend = 1;
+}
+
+// -- Titel Hintergrund Bild -- 
+void Fenster::setTBgBild( Bild *b ) // setzt das Titel Hintergrund Bild
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setHintergrundBild( b );
+	rend = 1;
+}
+
+void Fenster::setTBgBildZ( Bild *b )
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setHintergrundBildZ( b );
+	rend = 1;
+}
+
+// -- Titel Rahmen -- 
+void Fenster::setTRahmenZ( LRahmen *ram ) // set Titel Rahmen
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setLinienRahmenZ( ram );
+	rend = 1;
+}
+
+void Fenster::setTRFarbe( int f ) // setzt die Titel Rahmen Farbe
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setLinienRahmenFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setTRBreite( int br ) // setzt die Titel Rahmen Breite
+{
+	if( !titel )
+		titel = new TextFeld();
+	titel->setLinienRahmenBreite( br );
+	rend = 1;
+}
+
+// -- Körper Hintergrund -- 
+void Fenster::setKBgFarbe( int f ) // setzt die Körper Hintergrund Farbe
+{
+	bgKörperFarbe = f;
+	rend = 1;
+}
+
+// -- Körper Hintergrund Bild -- 
+void Fenster::setKBgBild( Bild *b ) // setzt das Körper Hintergrund Bild
+{
+	if( !bgKörperBild )
+		bgKörperBild = new Bild();
+	bgKörperBild->neuBild( b->getBreite(), b->getHöhe(), 0 );
+	int *buff1 = bgKörperBild->getBuffer();
+	int *buff2 = b->getBuffer();
+	int gr = bgKörperBild->getBreite() * bgKörperBild->getHöhe();
+	for( int i = 0; i < gr; ++i )
+		buff1[ i ] = buff2[ i ];
+	b->release();
+	rend = 1;
+}
+
+void Fenster::setKBgBildZ( Bild *b )
+{
+	if( bgKörperBild )
+		bgKörperBild->release();
+	bgKörperBild = b;
+	rend = 1;
+}
+
+// -- Körper AlphaFeld -- 
+void Fenster::setKAlphaFeldZ( AlphaFeld *af ) // setzt das Körper AlphaFeld
+{
+	if( körperBuffer )
+		körperBuffer->release();
+	körperBuffer = af;
+	rend = 1;
+}
+
+void Fenster::setKAfFarbe( int f ) // setzt Körper AlphaFeld Farbe
+{
+	if( !körperBuffer )
+		körperBuffer = new AlphaFeld();
+	körperBuffer->setFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setKAfStärke( int st ) // setzt die Stärke des Körper AlphaFeldes
+{
+	if( !körperBuffer )
+		körperBuffer = new AlphaFeld();
+	körperBuffer->setStärke( st );
+	rend = 1;
+}
+
+// -- Schließen --
+void Fenster::setSchließenMeParam( void *param )
+{
+	schließenMeParam = param;
+}
+
+void Fenster::setSchließenMe( bool( *schließenMe )( void *, void *, MausEreignis ) ) // setzt das Schließen Mausereignis
+{
+	this->schließenMe = schließenMe;
+}
+
+// -- Schließen Hintergrund -- 
+void Fenster::setSBgFarbe( int f ) // setzt die Schließ Hintergrund Farbe
+{
+	bgSchließFarbe = f;
+	rend = 1;
+}
+
+// -- Schließen Hintergrund Bild -- 
+void Fenster::setSBgBild( Bild *b ) // setzt das Schließ Hintergrund Bild
+{
+	if( !bgSchließBild )
+		bgSchließBild = new Bild();
+	bgSchließBild->neuBild( b->getBreite(), b->getHöhe(), 0 );
+	int *buff1 = bgSchließBild->getBuffer();
+	int *buff2 = b->getBuffer();
+	int gr = bgSchließBild->getBreite() * bgSchließBild->getHöhe();
+	for( int i = 0; i < gr; ++i )
+		buff1[ i ] = buff2[ i ];
+	b->release();
+	rend = 1;
+}
+
+void Fenster::setSBgBildZ( Bild *b )
+{
+	if( bgSchließBild )
+		bgSchließBild->release();
+	bgSchließBild = b;
+	rend = 1;
+}
+
+// -- Schließen AlphaFeld -- 
+void Fenster::setSAlphaFeldZ( AlphaFeld *af ) // setzt das Schließ AlphaFeld
+{
+	if( schließBuffer )
+		schließBuffer->release();
+	schließBuffer = af;
+	rend = 1;
+}
+
+void Fenster::setSAfFarbe( int f ) // setzt die Farbe des Schließ AlphaFeldes
+{
+	if( !schließBuffer )
+		schließBuffer = new AlphaFeld();
+	schließBuffer->setFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setSAfStärke( int st ) // setzt die Stärke des Schließ AlphaFeldes
+{
+	if( !schließBuffer )
+		schließBuffer = new AlphaFeld();
+	schließBuffer->setStärke( st );
+	rend = 1;
+}
+
+// -- Schließen Klick AlphaFeld -- 
+void Fenster::setSKAlphaFeldZ( AlphaFeld *af ) // setzt das Schließ klick AlphaFeld
+{
+	if( schließKlickBuffer )
+		schließKlickBuffer->release();
+	schließKlickBuffer = af;
+	rend = 1;
+}
+
+void Fenster::setSKAfFarbe( int f ) // setzt die Farbe des Schließ klick AlphaFeldes
+{
+	if( !schließKlickBuffer )
+		schließKlickBuffer = new AlphaFeld();
+	schließKlickBuffer->setFarbe( f );
+	rend = 1;
+}
+
+void Fenster::setSKAfStärke( int st ) // setzt die Stärke des Schließ klick AlphaFeldes
+{
+	if( !schließKlickBuffer )
+		schließKlickBuffer = new AlphaFeld();
+	schließKlickBuffer->setStärke( st );
+	rend = 1;
+}
+
+// -- min max -- 
+void Fenster::setMin( int mx, int my ) // setzt die Mindest Fenster Größe
+{
+	min.x = mx;
+	min.y = my;
+}
+
+void Fenster::setMin( const Punkt &min )
+{
+	this->min = min;
+}
+
+void Fenster::setMax( int mx, int my ) // setzt die Maximale Fenster Größe
+{
+	max.x = mx;
+	max.y = my;
+}
+
+void Fenster::setMax( const Punkt &max )
+{
+	this->max = max;
+}
+
+void Fenster::setKMin( int mx, int my ) // setzt die Mindest Körper Größe
+{
+	kMin.x = mx;
+	kMin.y = my;
+}
+
+void Fenster::setKMin( const Punkt &min )
+{
+	kMin = min;
+}
+
+void Fenster::setKMax( int mx, int my ) // setzt die Maximale Körper Größe
+{
+	kMax.x = mx;
+	kMax.y = my;
+}
+
+void Fenster::setKMax( const Punkt &max )
+{
+	kMax = max;
+}
+
+// -- scroll -- 
+void Fenster::setHScrollBarZ( HScrollBar *hScroll ) // setzt die Horizontale Scroll Bar
+{
+	if( this->hScroll )
+		this->hScroll->release();
+	this->hScroll = hScroll;
+	rend = 1;
+}
+
+void Fenster::setVScrollBarZ( VScrollBar *vScroll ) // setzt die Vertikale Scroll BAr
+{
+	if( this->vScroll )
+		this->vScroll->release();
+	this->vScroll = vScroll;
+	rend = 1;
+}
+
+void Fenster::setHSBMax( int max ) // setzt das Scroll Maximum
+{
+	if( !hScroll )
+		hScroll = new HScrollBar();
+	int rbr = 0;
+	if( hatStyle( Style::Rahmen ) && rahmen )
+		rbr = rahmen->getRBreite();
+	int vsh = 0;
+	if( hatStyle( Style::VScroll ) && vScroll )
+		vsh = 15;
+	hScroll->update( max, gr.x - rbr * 2 - vsh );
+	rend = 1;
+}
+
+void Fenster::setVSBMax( int max )
+{
+	if( !vScroll )
+		vScroll = new VScrollBar();
+	int rbr = 0;
+	int th = 0;
+	if( hatStyle( Style::Rahmen ) && rahmen )
+		rbr = rahmen->getRBreite();
+	if( hatStyle( Style::Titel ) && titel )
+		th = titel->getHöhe();
+	int hsh = 0;
+	if( hatStyle( Style::HScroll ) && hScroll )
+		hsh = 15;
+	vScroll->update( max, gr.y - rbr * 2 - th - hsh );
+	rend = 1;
+}
+
+void Fenster::setHSBScroll( int scroll ) // setzt die momentane Scroll Position
+{
+	if( !hScroll )
+		hScroll = new HScrollBar();
+	hScroll->scroll( scroll );
+	rend = 1;
+}
+
+void Fenster::setVSBScroll( int scroll )
+{
+	if( !vScroll )
+		vScroll = new VScrollBar();
+	vScroll->scroll( scroll );
+	rend = 1;
+}
+
+// -- Members -- 
+void Fenster::addMember( Zeichnung *obj ) // fügt einen Member hinzu
+{
+	if( !members )
+		members = new ZeichnungArray();
+	members->addZeichnung( obj );
+	members->updateIndex( 0 );
+	rend = 1;
+}
+
+void Fenster::removeMember( Zeichnung *obj ) // entfernt einen Member
+{
+	if( !members )
+		return;
+	members->removeZeichnung( obj );
+	members->updateIndex( 0 );
+	rend = 1;
+}
+
+// -- Messages -- 
+bool Fenster::tick( double tickval ) // tick
+{
+	if( members && hatStyle( Style::Sichtbar ) )
+		rend |= members->tick( tickval );
+	else if( members )
+		members->tick( tickval );
+	if( vScroll && hatStyle( Style::VScroll ) )
+		rend |= vScroll->getRend();
+	if( hScroll && hatStyle( Style::HScroll ) )
+		rend |= hScroll->getRend();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Fenster::doMausEreignis( MausEreignis &me )
+{
+    bool nmakc = !me.verarbeitet;
+	if( me.verarbeitet || ( me.mx < pos.x || me.mx > pos.x + gr.x || me.my < pos.y || me.my > pos.y + gr.y ) )
+	{
+		if( mausIn )
+		{
+			mausIn = 0;
+			MausEreignis me2;
+			me2.id = ME_Verlässt;
+			me2.mx = me.mx;
+			me2.my = me.my;
+			me2.verarbeitet = 0;
+			doMausEreignis( me2 );
+			return;
+		}
+	}
+	else if( !mausIn && me.id != ME_Verlässt )
+	{
+		mausIn = 1;
+		MausEreignis me2;
+		me2.id = ME_Betritt;
+		me2.mx = me.mx;
+		me2.my = me.my;
+		me2.verarbeitet = 0;
+		doMausEreignis( me2 );
+	}
+	if( hatStyle( Style::Sichtbar ) )
+	{
+		bool mvtmp = me.verarbeitet;
+		if( !Mak )
+			return;
+		if( hatStyleNicht( Style::Erlaubt ) )
+			me.verarbeitet = 1;
+		bool mpr = 0;
+		me.mx -= pos.x;
+		me.my -= pos.y;
+		int rbr = 0;
+		if( hatStyle( Style::Rahmen ) && rahmen )
+			rbr = rahmen->getRBreite();
+		int th = 0;
+		if( hatStyle( Style::Titel ) && titel )
+			th = titel->getHöhe();
+		bool hSc = hatStyle( Style::HScroll ) && hScroll;
+		bool vSc = hatStyle( Style::VScroll ) && vScroll;
+		if( !me.verarbeitet && me.id == ME_Bewegung && klick )
+		{
+			if( hatStyle( Style::Beweglich ) || hatStyle( Style::HöheÄnderbar ) || hatStyle( Style::BreiteÄnderbar ) || hatStyle( Style::TitelHöheÄnderbar ) )
+			{
+				if( Mak( makParam, this, me ) )
+				{
+					mpr = 1;
+					bool ret1 = 0;
+					bool mset = 0;
+					int schö = 0;
+					int scbr = 0;
+					if( hSc )
+					{
+						schö = 15;
+						scbr = 40;
+					}
+					if( vSc )
+					{
+						scbr += 15;
+						schö = 40;
+					}
+					bool minXb, maxXb, minYb, maxYb;
+					bool kMinXb, kMaxXb, kMinYb, kMaxYb;
+					minXb = hatStyle( Style::MinBr );
+					maxXb = hatStyle( Style::MaxBr );
+					minYb = hatStyle( Style::MinHö );
+					maxYb = hatStyle( Style::MaxHö );
+					kMinXb = hatStyle( Style::Körper_minBr );
+					kMaxXb = hatStyle( Style::Körper_maxBr );
+					kMinYb = hatStyle( Style::Körper_minHö );
+					kMaxYb = hatStyle( Style::Körper_maxHö );
+					int fMinBr = rbr * 2 + scbr;
+					if( minXb )
+						fMinBr = fMinBr < min.x ? min.x : fMinBr;
+					if( kMinXb )
+						fMinBr = fMinBr < ( rbr * 2 + kMin.x + scbr ) ? ( rbr * 2 + kMin.x + scbr ) : fMinBr;
+					int fMinHö = rbr * 2 + th + schö;
+					if( minYb )
+						fMinHö = fMinHö < min.y ? min.y : fMinHö;
+					if( kMinYb )
+						fMinHö = fMinHö < ( rbr * 2 + kMin.y + th + schö ) ? ( rbr * 2 + kMin.y + th + schö ) : fMinHö;
+					int fMaxBr = 0;
+					if( maxXb )
+						fMaxBr = max.x;
+					if( kMaxXb )
+						fMaxBr = fMaxBr < ( rbr * 2 + kMax.x + scbr ) ? ( rbr * 2 + kMax.x + scbr ) : fMaxBr;
+					int fMaxHö = 0;
+					if( maxYb )
+						fMaxHö = max.y;
+					if( kMaxYb )
+						fMaxHö = fMaxHö < ( rbr * 2 + kMax.y + th + schö ) ? ( rbr * 2 + kMax.y + th + schö ) : fMaxHö;
+					minXb |= kMinXb, maxXb |= kMaxXb, minYb |= kMinYb, maxYb |= kMaxYb;
+					if( hatStyle( Style::HöheÄnderbar ) )
+					{
+						if( mx > -5 && mx < gr.x + 5 && my > -5 && my < rbr )
+						{
+							pos.y -= my - me.my;
+							gr.y += my - me.my;
+							if( gr.y < fMinHö )
+							{
+								pos.y += fMinHö - gr.y;
+								gr.y = fMinHö;
+							}
+							else if( maxYb && gr.y > fMaxHö )
+							{
+								pos.y += gr.y - fMaxHö;
+								gr.y = fMaxHö;
+							}
+							else if( vSc )
+								vScroll->getScrollData()->anzeigeHöhe = gr.y;
+							rend = 1;
+							ret1 = 1;
+						}
+						else if( mx > -5 && mx < gr.x + 5 && my > gr.y - rbr && my < gr.y + 5 )
+						{
+							gr.y += me.my - my;
+							if( gr.y < fMinHö )
+								gr.y = fMinHö;
+							else if( maxYb && gr.y > fMaxHö )
+								gr.y = fMaxHö;
+							else
+							{
+								mset = 1;
+								if( vSc )
+									vScroll->getScrollData()->anzeigeHöhe = gr.y;
+							}
+							rend = 1;
+							ret1 = 1;
+						}
+					}
+					if( hatStyle( Style::BreiteÄnderbar ) )
+					{
+						if( mx > -5 && mx < rbr && my > -5 && my < gr.y + 5 )
+						{
+							pos.x -= mx - me.mx;
+							gr.x += mx - me.mx;
+							if( gr.x < fMinBr )
+							{
+								pos.x += fMinBr - gr.x;
+								gr.x = fMinBr;
+							}
+							else if( maxXb && gr.x > fMaxBr )
+							{
+								pos.x += gr.x - fMaxBr;
+								gr.x = fMaxBr;
+							}
+							else if( hSc )
+								hScroll->getScrollData()->anzeigeBreite = gr.x;
+							rend = 1;
+							ret1 = 1;
+						}
+						else if( mx > gr.x - rbr && mx < gr.x + 5 && my > -5 && my < gr.y + 5 )
+						{
+							gr.x += me.mx - mx;
+							if( gr.x < rbr * 2 + fMinBr )
+								gr.x = rbr * 2 + fMinBr;
+							else if( maxXb && gr.x > fMaxBr )
+								gr.x = fMaxBr;
+							else
+							{
+								mset = 1;
+								if( hSc )
+									hScroll->getScrollData()->anzeigeBreite = gr.x;
+							}
+							rend = 1;
+							ret1 = 1;
+						}
+					}
+					if( hatStyle( Style::TitelHöheÄnderbar ) && titel && mx > -5 && mx < gr.x + 5 && my < rbr + th + 5 && my > rbr + th )
+					{
+						int maxTh = gr.y - rbr * 2 - schö;
+						if( kMaxYb )
+							maxTh = maxTh < ( gr.x - rbr * 2 - kMin.y ) ? maxTh : ( gr.x - rbr * 2 - kMin.y );
+						if( hatStyle( Style::Schließbar ) )
+							maxTh = ( gr.x - th - 5 - rbr * 2 - me.my + my ) < 0 ? th : maxTh;
+						titel->setGröße( titel->getBreite(), titel->getHöhe() + me.my - my );
+						if( titel->getHöhe() > maxTh )
+							titel->setGröße( titel->getBreite(), maxTh );
+						else if( titel->getHöhe() < 5 )
+							titel->setGröße( titel->getBreite(), 5 );
+						else
+							mset = 1;
+						rend = 1;
+						ret1 = 1;
+					}
+					if( ret1 )
+					{
+						if( mset )
+							mx = me.mx, my = me.my;
+						me.verarbeitet = 1;
+					}
+					if( hatStyle( Style::Beweglich ) && mx > rbr && mx < gr.x - th - rbr && my > rbr && my < rbr + th )
+					{
+						pos.x += me.mx - mx;
+						pos.y += me.my - my;
+						rend = 1;
+						ret1 = 1;
+					}
+					if( ret1 )
+						me.verarbeitet = 1;
+				}
+			}
+		}
+		bool inside = me.mx >= 0 && me.mx <= gr.x && me.my >= 0 && me.my <= gr.y;
+		if( mpr || me.verarbeitet || ( !inside || Mak( makParam, this, me ) ) )
+		{
+			if( me.id == ME_RLinks )
+			{
+				if( schließKlick )
+					rend = 1;
+				schließKlick = 0, klick = 0;
+				mx = -1, my = -1;
+			}
+			if( me.id == ME_Verlässt )
+			{
+				if( schließKlick != 0 )
+					rend = 1;
+				schließKlick = 0, klick = 0;
+				mx = -1, my = -1;
+			}
+			if( !me.verarbeitet )
+			{
+				if( me.id == ME_PLinks )
+				{
+					klick = 1;
+					mx = me.mx, my = me.my;
+				}
+				if( hatStyle( Style::Schließbar ) && me.my <= th + rbr && me.mx >= gr.x + rbr - th && me.my >= rbr && me.mx <= gr.x - rbr )
+				{
+					if( !schließenMe || schließenMe( schließenMeParam, this, me ) )
+					{
+						if( me.id == ME_PLinks )
+						{
+							schließKlick = 1;
+							rend = 1;
+						}
+						if( !schließKlick && MausStand[ M_Links ] )
+						{
+							schließKlick = 1;
+							rend = 1;
+						}
+						me.verarbeitet = 1;
+					}
+				}
+				else if( schließKlick )
+				{
+					schließKlick = 0;
+					rend = 1;
+				}
+			}
+			if( members && me.id != ME_Betritt && me.id != ME_Verlässt )
+			{
+				if( vSc )
+				{
+					vScroll->doMausMessage( gr.x - rbr - 16, rbr + th, 15, gr.y - rbr * 2 - th - 1, me );
+					if( hSc )
+						hScroll->doMausMessage( rbr, gr.y - rbr - 16, gr.x - rbr * 2 - 16, 15, me );
+				}
+				else
+				if( hSc )
+					hScroll->doMausMessage( rbr, gr.y - rbr - 16, gr.x - rbr * 2 - 1, 15, me );
+				me.mx -= rbr;
+				me.my -= rbr + th;
+				if( hatStyle( Style::VScroll ) && vScroll )
+					me.my += vScroll->getScrollData()->anzeigeBeginn;
+				if( hatStyle( Style::HScroll ) && hScroll )
+					me.mx += hScroll->getScrollData()->anzeigeBeginn;
+				members->sendMausAll( me );
+				me.mx += rbr;
+				me.my += rbr + th;
+				if( hatStyle( Style::VScroll ) && vScroll )
+					me.my -= vScroll->getScrollData()->anzeigeBeginn;
+				if( hatStyle( Style::HScroll ) && hScroll )
+					me.mx -= hScroll->getScrollData()->anzeigeBeginn;
+			}
+			if( inside && hatStyleNicht( Style::METransparenz ) )
+				me.verarbeitet = 1;
+		}
+        if( nmakc && me.verarbeitet && nMak )
+            me.verarbeitet = nMak( nmakParam, this, me );
+		me.mx += pos.x;
+		me.my += pos.y;
+		if( hatStyleNicht( Style::Erlaubt ) )
+			me.verarbeitet = mvtmp;
+	}
+	else if( members )
+	{
+		MausEreignis me;
+		me.verarbeitet = 1;
+		me.id = 0;
+		me.mx = -1000000;
+		me.my = -1000000;
+		members->sendMausAll( me );
+	}
+}
+
+void Fenster::doTastaturEreignis( TastaturEreignis &te )
+{
+    bool ntakc = !te.verarbeitet;
+	if( hatStyle( Style::Sichtbar ) )
+	{
+		if( te.verarbeitet )
+		{
+			if( members )
+				members->sendTastaturAll( te );
+		}
+		else
+		{
+			if( Tak && Tak( takParam, this, te ) )
+			{
+				if( members )
+					members->sendTastaturAll( te );
+			}
+		}
+	}
+    if( ntakc && te.verarbeitet && nTak )
+        te.verarbeitet = nTak( ntakParam, this, te );
+}
+
+// -- Render -- 
+void Fenster::render( Bild &zRObj ) // zeichent nach zRObj
+{
+	if( hatStyle( Style::Sichtbar ) )
+	{
+		lockZeichnung();
+		if( !zRObj.setDrawOptions( pos, gr ) )
+		{
+			unlockZeichnung();
+			return;
+		}
+        __super::render( zRObj );
+		int rbr = 0;
+		if( hatStyle( Style::Rahmen ) && rahmen )
+		{
+			rahmen->setGröße( gr );
+			rahmen->render( zRObj );
+			rbr = rahmen->getRBreite();
+		}
+		int th = 0;
+		if( hatStyle( Style::Titel ) && titel )
+		{
+			titel->setStyle( TextFeld::Style::Hintergrund, hatStyle( Style::TitelHintergrund ) );
+			titel->setStyle( TextFeld::Style::HAlpha, hatStyle( Style::TitelHAlpha ) );
+			titel->setStyle( TextFeld::Style::HBild, hatStyle( Style::TitelHBild ) );
+			titel->setStyle( TextFeld::Style::Buffered, hatStyle( Style::TitelBuffered ) );
+			th = titel->getHöhe();
+			if( !zRObj.setDrawOptions( rbr, rbr, gr.x - rbr * 2, th ) )
+			{
+				zRObj.releaseDrawOptions();
+				unlockZeichnung();
+				return;
+			}
+			int sbr = 0;
+			if( hatStyle( Style::Schließbar ) )
+			{
+				sbr = th;
+				if( hatStyle( Style::SchließHintergrund ) )
+				{
+					if( hatStyle( Style::SchließHAlpha ) )
+						zRObj.alphaRegion( gr.x - th - rbr * 2, 0, th, th, bgSchließFarbe );
+					else
+						zRObj.füllRegion( gr.x - th - rbr * 2, 0, th, th, bgSchließFarbe );
+					if( hatStyle( Style::SchließHBild ) && bgSchließBild )
+					{
+						if( hatStyle( Style::SchließHAlpha ) )
+							zRObj.alphaBild( gr.x - th - rbr * 2, 0, th, th, *bgSchließBild );
+						else
+							zRObj.drawBild( gr.x - th - rbr * 2, 0, th, th, *bgSchließBild );
+					}
+				}
+				if( !hatStyle( Style::SchließHBild ) || !bgSchließBild )
+				{
+					zRObj.drawLinie( Punkt( gr.x - th - rbr * 2, 0 ), Punkt( gr.x - rbr * 2, th ), 0xFFFFFFFF );
+					zRObj.drawLinie( Punkt( gr.x - rbr * 2, 0 ), Punkt( gr.x - th - rbr * 2, th ), 0xFFFFFFFF );
+				}
+				if( hatStyle( Style::SchließBuffer ) && schließBuffer )
+				{
+					schließBuffer->setPosition( gr.x - th - rbr * 2, 0 );
+					schließBuffer->setGröße( th, th );
+					schließBuffer->render( zRObj );
+				}
+				if( hatStyle( Style::SchließKlickBuffer ) && schließKlickBuffer && schließKlick )
+				{
+					schließKlickBuffer->setPosition( gr.x - th - rbr * 2, 0 );
+					schließKlickBuffer->setGröße( th, th );
+					schließKlickBuffer->render( zRObj );
+				}
+			}
+			titel->setGröße( gr.x - rbr * 2 - sbr, th );
+			titel->render( zRObj );
+			zRObj.releaseDrawOptions();
+		}
+		bool vSc = hatStyle( Style::VScroll ) && vScroll;
+		bool hSc = hatStyle( Style::HScroll ) && hScroll;
+		if( vSc )
+		{
+			vScroll->render( gr.x - rbr - 16, rbr + th, 15, gr.y - rbr * 2 - th - 1, zRObj );
+			if( hSc )
+				hScroll->render( rbr, gr.y - rbr - 16, gr.x - rbr * 2 - 16, 15, zRObj );
+		}
+		else
+		if( hSc )
+			hScroll->render( rbr, gr.y - rbr - 16, gr.x - rbr * 2 - 1, 15, zRObj );
+		int x = rbr;
+		int y = rbr + th;
+		int br = gr.x - rbr * 2;
+		int hö = gr.y - rbr * 2 - th;
+		if( vSc )
+			br -= 16;
+		if( hSc )
+			hö -= 16;
+		if( !zRObj.setDrawOptions( x, y, br, hö ) )
+		{
+			zRObj.releaseDrawOptions();
+			unlockZeichnung();
+			return;
+		}
+		if( hatStyle( Style::KörperHintergrund ) )
+		{
+			if( hatStyle( Style::KörperHAlpha ) )
+				zRObj.alphaRegion( 0, 0, br, hö, bgKörperFarbe );
+			else
+				zRObj.füllRegion( 0, 0, br, hö, bgKörperFarbe );
+			if( hatStyle( Style::KörperHBild ) && bgKörperBild )
+			{
+				int *bgBuff = bgKörperBild->getBuffer();
+				int bgBr = bgKörperBild->getBreite();
+				if( hatStyle( Style::KörperHAlpha ) )
+					zRObj.alphaBild( 0, 0, br, hö, *bgKörperBild );
+				else
+					zRObj.drawBild( 0, 0, br, hö, *bgKörperBild );
+			}
+		}
+		if( hatStyle( Style::KörperBuffered ) && körperBuffer )
+		{
+			körperBuffer->setGröße( br, hö );
+			körperBuffer->render( zRObj );
+		}
+		if( members )
+		{
+			if( !vSc && !hSc )
+				members->render( zRObj );
+			else
+			{
+				VScrollData *vsd = 0;
+				HScrollData *hsd = 0;
+				if( vSc )
+					vsd = vScroll->getScrollData();
+				if( hSc )
+					hsd = hScroll->getScrollData();
+				zRObj.addScrollOffset( hsd ? hsd->anzeigeBeginn : 0, vsd ? vsd->anzeigeBeginn : 0 );
+				members->render( zRObj );
+			}
+		}
+		zRObj.releaseDrawOptions();
+		zRObj.releaseDrawOptions();
+		unlockZeichnung();
+	}
+}
+
+// constant 
+// -- Rahmen -- 
+LRahmen *Fenster::getRahmen() const // gibt den Rahmen zurück
+{
+	if( !rahmen )
+		return 0;
+	return rahmen->getThis();
+}
+
+LRahmen *Fenster::zRahmen() const
+{
+	return rahmen;
+}
+
+int Fenster::getRFarbe() const // gibt die Farbe des Rahmens zurück
+{
+	if( !rahmen )
+		return 0;
+	return rahmen->getFarbe();
+}
+
+int Fenster::getRBreite() const // gibt die breite des Rahmens zurück
+{
+	if( !rahmen )
+		return 0;
+	return rahmen->getRBreite();
+}
+
+// -- Titel  -- 
+Text *Fenster::getTitel() const // gibt den Titel zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getText();
+}
+
+Text *Fenster::zTitel() const
+{
+	if( !titel )
+		return 0;
+	return titel->zText();
+}
+
+TextFeld *Fenster::getTTextFeld() const // gibt das Titel TextFeld zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getThis();
+}
+
+TextFeld *Fenster::zTTextFeld() const
+{
+	return titel;
+}
+
+// -- Titel Schrift -- 
+Schrift *Fenster::getTSchrift() const // gibt die Titel Schrift zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getSchrift();
+}
+
+Schrift *Fenster::zTSchrift() const
+{
+	if( !titel )
+		return 0;
+	return titel->zSchrift();
+}
+
+int Fenster::getTSFarbe() const // gibt die Titel Schrift Farbe zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getSchriftFarbe();
+}
+
+int Fenster::getTSGröße() const // gibt die Titel Schrift Größe zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getSchriftGröße();
+}
+
+// -- Titel Hintergrund -- 
+int Fenster::getTBgFarbe() const // gibt die Titel Hintergrund Farbe zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getHintergrundFarbe();
+}
+
+// -- Titel AlphaFeld -- 
+AlphaFeld *Fenster::getTAlphaFeld() const // gibt das Titel AlphaFeld zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getAlphaFeld();
+}
+
+AlphaFeld *Fenster::zTAlphaFeld() const
+{
+	if( !titel )
+		return 0;
+	return titel->zAlphaFeld();
+}
+
+int Fenster::getTAfFarbe() const // gibt die Farbe des Titel AlphaFeldes zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getAlphaFeldFarbe();
+}
+
+int Fenster::getTAfStärke() const // gibt die Stärke des TitelAlphaFeldes zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getAlphaFeldStärke();
+}
+
+// -- Titel Hintergrund Bild -- 
+Bild *Fenster::getTBgBild() const // gibt das Titel Hintergrund Bild zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getHintergrundBild();
+}
+
+Bild *Fenster::zTBgBild() const
+{
+	if( !titel )
+		return 0;
+	return titel->zHintergrundBild();
+}
+
+// -- Titel Rahmen -- 
+LRahmen *Fenster::getTRahmen() const // gibt den Titel Rahmen zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getLinienRahmen();
+}
+
+LRahmen *Fenster::zTRahmen() const
+{
+	if( !titel )
+		return 0;
+	return titel->zLinienRahmen();
+}
+
+int Fenster::getTRFarbe() const // gibt die Farbe des Titel Rahmens zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getLinienRahmenFarbe();
+}
+
+int Fenster::getTRBreite() const // gibt die Breite des Titel Rahmens zurück
+{
+	if( !titel )
+		return 0;
+	return titel->getLinienRahmenBreite();
+}
+
+// -- Körper Hintergrund -- 
+int Fenster::getKBgFarbe() const // gibt die Körper Hintergrund Farbe zurück
+{
+	return bgKörperFarbe;
+}
+
+// -- Körper Hintergrund Bild -- 
+Bild *Fenster::getKBgBild() const // gibt das Körper Hintergrund Bild zurück
+{
+	if( !bgKörperBild )
+		return 0;
+	return bgKörperBild->getThis();
+}
+
+Bild *Fenster::zKBgBild() const
+{
+	return bgKörperBild;
+}
+
+// -- Körper AlphaFeld -- 
+AlphaFeld *Fenster::getKAlphaFeld() const // gibt das Körper AlphaFeld zurück
+{
+	if( !körperBuffer )
+		return 0;
+	return körperBuffer->getThis();
+}
+
+AlphaFeld *Fenster::zKAlphaFeld() const
+{
+	return körperBuffer;
+}
+
+int Fenster::getKAfFarbe() const // gibt die Farbe des Körper AlphaFeldes zurück
+{
+	if( !körperBuffer )
+		return 0;
+	return körperBuffer->getFarbe();
+}
+
+int Fenster::getKAfStärke() const // gibt die Stärke des Körper AlphaFeldes zurück
+{
+	if( !körperBuffer )
+		return 0;
+	return körperBuffer->getStärke();
+}
+
+// -- Schließen Hintergrund -- 
+int Fenster::getSBgFarbe() const // gibt die Schließ Hintergrund Farbe zurück
+{
+	return bgSchließFarbe;
+}
+
+// -- Schließen Hintergrund Bild -- 
+Bild *Fenster::getSBgBild() const // gibt das Schließ Hintergrund Bild zurück
+{
+	if( !bgSchließBild )
+		return 0;
+	return bgSchließBild->getThis();
+}
+
+Bild *Fenster::zSBgBild() const
+{
+	return bgSchließBild;
+}
+
+// -- Schließen AlphaFeld -- 
+AlphaFeld *Fenster::getSAlphaFeld() const // gibt das Schließ AlphaFeld zurück
+{
+	if( !schließBuffer )
+		return 0;
+	return schließBuffer->getThis();
+}
+
+AlphaFeld *Fenster::zSAlphaFeld() const
+{
+	return schließBuffer;
+}
+
+int Fenster::getSAfFarbe() const // gibt die Farbe des Schließ AlphaFeldes zurück
+{
+	if( !schließBuffer )
+		return 0;
+	return schließBuffer->getFarbe();
+}
+
+int Fenster::getSAfStärke() const // gibt die Stärke des Schließ AlphaFeldes zurück
+{
+	if( !schließBuffer )
+		return 0;
+	return schließBuffer->getStärke();
+}
+
+// -- Schließen Klick AlphaFeld -- 
+AlphaFeld *Fenster::getSKAlphaFeld() const // gibt das Schließ Klick AlphaFeld zurück
+{
+	if( !schließKlickBuffer )
+		return 0;
+	return schließKlickBuffer->getThis();
+}
+
+AlphaFeld *Fenster::zSKAlphaFeld() const
+{
+	return schließKlickBuffer;
+}
+
+int Fenster::getSKAfFarbe() const // gibt die Farbe des Schließ Klick AlphaFeldes zurück
+{
+	if( !schließKlickBuffer )
+		return 0;
+	return schließKlickBuffer->getFarbe();
+}
+
+int Fenster::getSKAfStärke() const // gibt die Stärke des Schließ Klick AlphaFeldes zurück
+{
+	if( !schließKlickBuffer )
+		return 0;
+	return schließKlickBuffer->getStärke();
+}
+
+// -- min max -- 
+const Punkt &Fenster::getMin() const // gibt die minimale Fenstergröße zurück
+{
+	return min;
+}
+
+const Punkt &Fenster::getMax() const // gibt die maximale Fenstergröße zurück
+{
+	return max;
+}
+
+const Punkt &Fenster::getKMin() const // gibt die minimale Fenstergröße zurück
+{
+	return kMin;
+}
+
+const Punkt &Fenster::getKMax() const // gibt die maximale Fenstergröße zurück
+{
+	return kMax;
+}
+
+// -- scroll -- 
+VScrollBar *Fenster::getVScrollBar() const // gibt die Vertikale Scroll Bar zurück
+{
+	if( !vScroll )
+		return 0;
+	return vScroll->getThis();
+}
+
+VScrollBar *Fenster::zVScrollBar() const
+{
+	return vScroll;
+}
+
+HScrollBar *Fenster::getHScrollBar() const // gibt die Horizontale Scroll Bar zurück
+{
+	if( !hScroll )
+		return 0;
+	return hScroll->getThis();
+}
+
+HScrollBar *Fenster::zHScrollBar() const
+{
+	return hScroll;
+}
+
+// -- Members -- 
+ZeichnungArray *Fenster::getMembers() const // gibt die Members zurück
+{
+	return members;
+}
+
+// -- Kopie --
+Zeichnung *Fenster::dublizieren() const // Erzeugt eine Kopie des Fensters
+{
+	Fenster *ret = new Fenster();
+	ret->setPosition( pos );
+	ret->setGröße( gr );
+	ret->setMausEreignisParameter( makParam );
+	ret->setTastaturEreignisParameter( takParam );
+	ret->setMausEreignis( Mak );
+	ret->setTastaturEreignis( Tak );
+	if( toolTip )
+		ret->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	ret->setStyle( style );
+	ret->setSchließenMeParam( schließenMeParam );
+	ret->setSchließenMe( schließenMe );
+	if( rahmen )
+	{
+		ret->setRBreite( rahmen->getRBreite() );
+		ret->setRFarbe( rahmen->getFarbe() );
+	}
+	if( titel )
+		ret->setTTextFeldZ( (TextFeld*)titel->dublizieren() );
+	ret->setKBgFarbe( bgKörperFarbe );
+	if( bgKörperBild )
+		ret->setKBgBild( bgKörperBild->getThis() );
+	if( körperBuffer )
+	{
+		ret->setKAfFarbe( körperBuffer->getFarbe() );
+		ret->setKAfStärke( körperBuffer->getStärke() );
+	}
+	ret->setSBgFarbe( bgSchließFarbe );
+	if( bgSchließBild )
+		ret->setSBgBild( bgSchließBild->getThis() );
+	if( schließBuffer )
+	{
+		ret->setSAfFarbe( schließBuffer->getFarbe() );
+		ret->setSAfStärke( schließBuffer->getStärke() );
+	}
+	if( schließKlickBuffer )
+	{
+		ret->setSKAfFarbe( schließKlickBuffer->getFarbe() );
+		ret->setSKAfStärke( schließKlickBuffer->getStärke() );
+	}
+	if( vScroll )
+	{
+		ret->setVSBMax( vScroll->getScrollData()->maxHöhe );
+		ret->setVSBScroll( vScroll->getScrollData()->anzeigeBeginn );
+	}
+	if( hScroll )
+	{
+		ret->setHSBMax( hScroll->getScrollData()->maxBreite );
+		ret->setHSBScroll( hScroll->getScrollData()->anzeigeBeginn );
+	}
+	ret->setMin( min );
+	ret->setMax( max );
+	ret->setKMin( kMin );
+	ret->setKMax( kMax );
+	return ret;
+}
+
+// Reference Counting 
+Fenster *Fenster::getThis()
+{
+	++ref;
+	return this;
+}
+
+Fenster *Fenster::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}

+ 357 - 0
Fenster.h

@@ -0,0 +1,357 @@
+#ifndef Fenster_H
+#define Fenster_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class VScrollBar; // Scroll.h
+	class HScrollBar; // Scroll.h
+	class TextFeld; // TextFeld.h
+	class LRahmen; // Rahmen.h
+	class Bildschirm; // Bildschirm.h
+	class AlphaFeld; // AlphaFeld.h
+	class Schrift; // Schrift.h
+	class Text; // Text.h
+	class Bild; // Bild.h
+	class WFenster; // aus dieser Datei
+	class WFensterArray; // aus dieser Datei
+	class Fenster; // aus dieser Datei
+
+	// Erzeugen einer normalen Fensterklasse
+	__declspec( dllexport ) WNDCLASS F_Normal( HINSTANCE hInst );
+	__declspec( dllexport ) WNDCLASSEX F_NormalEx( HINSTANCE hInst );
+
+	__declspec( dllexport ) LRESULT CALLBACK WindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
+	__declspec( dllexport ) void StartNachrichtenSchleife();
+	__declspec( dllexport ) void StopNachrichtenSchleife( HWND hwnd );
+
+	__declspec( dllexport ) unsigned char VirtualZuChar( int Virtual );
+	// Klasse für ein Fenster in Windows
+	class WFenster
+	{
+	private:
+		HWND hWnd; // Handel zum Fenster
+		int style;
+		void *makParam;
+		void *sakParam;
+		void *takParam;
+		bool( *MausAktion )( void *, void *, MausEreignis );
+		void( *VSchließAktion )( void *, void * );
+		void( *NSchließAktion )( void *, void * );
+		bool( *TastaturAktion )( void *, void *, TastaturEreignis );
+		Bildschirm *screen;
+		int mx, my;
+		bool verschiebbar;
+		int ref;
+		HWND rahmen;
+		HBITMAP bitmap;
+		HDC hdc;
+
+	public:
+		//--Konstruktor--
+		__declspec( dllexport ) WFenster();
+		__declspec( dllexport ) WFenster( HWND hWnd );
+		//--Destruktor--
+		__declspec( dllexport ) ~WFenster();
+		// nicht constant
+		__declspec( dllexport ) void erstellen( int style, WNDCLASS wc ); // Das Fenster Erstellen
+		__declspec( dllexport ) void erstellenEx( int exStyle, int style, WNDCLASSEX wc ); // Das Fenster Erstellen
+		__declspec( dllexport ) void setAnzeigeModus( int mod ); // Zeigt das Fenster im übergebenen Modus an
+		__declspec( dllexport ) bool setFokus(); // Setzt den Fokus auf das Fenster
+		__declspec( dllexport ) void setPosition( Punkt &pos ); // Bildschirmposition des Fensters setzen
+		__declspec( dllexport ) void setGröße( Punkt &größe ); // Die größe des Fensters setzen
+		__declspec( dllexport ) void setGröße( int breite, int höhe );
+		__declspec( dllexport ) void setBounds( Punkt &pos, Punkt &größe ); // Größe und Porition in einem
+		__declspec( dllexport ) void setBildschirm( Bildschirm *screen );
+		__declspec( dllexport ) void zerstören(); // Zerstört das Fenster
+		__declspec( dllexport ) void doMausAktion( MausEreignis &me ); // ruft MausAktion auf
+		__declspec( dllexport ) void doVSchließAktion(); // ruft VSchließAktion auf
+		__declspec( dllexport ) void doNSchließAktion(); // ruft NSchließAktion auf
+		__declspec( dllexport ) void doTastaturAktion( TastaturEreignis &et ); // ruft TastaturAktion auf
+		__declspec( dllexport ) void doRestoreMessage(); // macht den Rahmen sichtbar
+		__declspec( dllexport ) void setMausEreignisParameter( void *p ); // setzt den Parameter vom Maus Ereignis
+		__declspec( dllexport ) void setSchließEreignisParameter( void *p ); // setzt den Parameter vom Schließ Ereignis
+		__declspec( dllexport ) void setTastaturEreignisParameter( void *p ); // setzt den Parameter vom Tastatur Ereignis
+		__declspec( dllexport ) void setMausAktion( bool( *MausAk )( void *, void *, MausEreignis ) ); // setzt das MausEreignis
+		__declspec( dllexport ) void setVSchließAktion( void( *vSchließAk )( void *, void * ) ); // setzt v schließ Aktion
+		__declspec( dllexport ) void setNSchließAktion( void( *nSchließAk )( void *, void * ) ); // setzt n schließ Aktion
+		__declspec( dllexport ) void setTastaturAktion( bool( *TastaturAk )( void *, void *, TastaturEreignis ) ); // setzt das TastaturEreignis
+		__declspec( dllexport ) void setFensterHandle( HWND hWnd ); // setzt das operationsfenster
+		__declspec( dllexport ) void setVerschiebbar( bool verschiebbar ); // legt fest, ob das Fenster durch ziehen mit Maus verschoben werden kann
+		__declspec( dllexport ) void ladeRahmenFenster( Bild *zBild, HINSTANCE hinst ); // setzt einen Transpatenten Rahmen um das Fenster
+		// constant
+		__declspec( dllexport ) HWND getFensterHandle() const; // gibt das Fenster Handle zurück
+		__declspec( dllexport ) Punkt getPosition() const; // gibt die Fensterposition zurück
+		__declspec( dllexport ) Punkt getKörperPosition() const; // gibt die Fenster Körperposition zurück
+		__declspec( dllexport ) Punkt getGröße() const; // gibt die Fenstergröße zurück
+		__declspec( dllexport ) Punkt getKörperGröße() const; // gibt die Fenster Körpergröße zurück
+		__declspec( dllexport ) int getKörperBreite() const; // gibt die Fenster Körperbreite zurück
+		__declspec( dllexport ) int getKörperHöhe() const; // gibt die Fenster Körperhöhe zurück
+		__declspec( dllexport ) bool hatMausAktion() const; // Prüft, ob eine Aktion bei MausEreignis festgelegt wurde
+		__declspec( dllexport ) bool hatVSchließAktion() const; // Prüft, ob eine Aktion vor Fensterschließen festgelegt wurde
+		__declspec( dllexport ) bool hatNSchließAktion() const; // Prüft, ob eine Aktion nach Fensterschließen festgelegt wurde
+		__declspec( dllexport ) bool hatTastaturAktion() const; // Prüft, ob eine Aktion bei TastaturEreignis festgelegt wurde
+		__declspec( dllexport ) Bildschirm *getBildschirm() const;
+		__declspec( dllexport ) Bildschirm *zBildschirm() const;
+		__declspec( dllexport ) bool istVerschiebbar() const; // prüft, ob das Fenster durch ziehen mit Maus verschoben werden kann
+		// Reference Counting
+		__declspec( dllexport ) WFenster *getThis();
+		__declspec( dllexport ) WFenster *release();
+	};
+
+	// Verwaltung der WFenster im Framework
+	class WFensterArray
+	{
+	private:
+		WFensterArray *next;
+		WFenster *This;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) WFensterArray();
+		// Destruktor 
+		__declspec( dllexport ) ~WFensterArray();
+		// add und remove 
+		__declspec( dllexport ) bool addFenster( WFenster *fenster );
+		__declspec( dllexport ) bool removeFenster( WFenster *fenster );
+		__declspec( dllexport ) WFensterArray* getNext();
+		__declspec( dllexport ) void setNext0();
+		__declspec( dllexport ) void del();
+		// Messages 
+		__declspec( dllexport ) bool sendVSchließMessage( HWND hWnd );
+		__declspec( dllexport ) bool sendNSchließMessage( HWND hwnd );
+		__declspec( dllexport ) bool sendMausMessage( HWND hWnd, MausEreignis &me );
+		__declspec( dllexport ) bool sendTastaturMessage( HWND hwnd, TastaturEreignis &te );
+		__declspec( dllexport ) bool sendRestoreMessage( HWND hwnd );
+		__declspec( dllexport ) WFenster *getThis();
+	};
+
+	// WMessageBox
+	__declspec( dllexport ) void WMessageBox( HWND hWnd, Text *titel, Text *meldung, UINT style );
+
+	// Fenster Klasse im Programm
+	class Fenster : public Zeichnung
+	{
+    public:
+        class Style : public Zeichnung::Style
+        {
+        public:
+            const static __int64 KörperHintergrund = 0x000000008;
+            const static __int64 KörperHAlpha = 0x000000010;
+            const static __int64 KörperHBild = 0x000000020;
+            const static __int64 KörperBuffered = 0x000000040;
+            const static __int64 Titel = 0x000000080;
+            const static __int64 TitelHintergrund = 0x000000100;
+            const static __int64 TitelHAlpha = 0x000000200;
+            const static __int64 TitelHBild = 0x000000400;
+            const static __int64 TitelBuffered = 0x000000800;
+            const static __int64 Schließbar = 0x000001000;
+            const static __int64 SchließHintergrund = 0x000002000;
+            const static __int64 SchließHAlpha = 0x000004000;
+            const static __int64 SchließHBild = 0x000008000;
+            const static __int64 SchließBuffer = 0x000010000;
+            const static __int64 SchließKlickBuffer = 0x000020000;
+            const static __int64 Beweglich = 0x000040000;
+            const static __int64 BreiteÄnderbar = 0x000080000;
+            const static __int64 HöheÄnderbar = 0x000100000;
+            const static __int64 TitelHöheÄnderbar = 0x000200000;
+            const static __int64 MinBr = 0x000400000;
+            const static __int64 MaxBr = 0x000800000;
+            const static __int64 MinHö = 0x001000000;
+            const static __int64 MaxHö = 0x002000000;
+            const static __int64 Körper_minBr = 0x004000000;
+            const static __int64 Körper_maxBr = 0x008000000;
+            const static __int64 Körper_minHö = 0x010000000;
+            const static __int64 Körper_maxHö = 0x020000000;
+            const static __int64 VScroll = 0x040000000;
+            const static __int64 HScroll = 0x080000000;
+            const static __int64 METransparenz = 0x100000000;
+            const static __int64 Rahmen = 0x200000000;
+
+            const static __int64 min_max = MinHö | MaxHö | MaxBr | MaxHö;
+            const static __int64 körper_min_max = Körper_minBr | Körper_maxBr | Körper_minHö | Körper_maxBr;
+            const static __int64 scroll = VScroll | HScroll;
+            const static __int64 nichtfixiert = TitelHöheÄnderbar | HöheÄnderbar | BreiteÄnderbar | Beweglich;
+
+            const static __int64 normal = Sichtbar | Erlaubt | Rahmen | Titel | TitelBuffered | Schließbar | SchließHBild | SchließKlickBuffer | Beweglich;
+        };
+	private:
+		bool( *schließenMe )( void *, void *, MausEreignis );
+		void *schließenMeParam;
+		LRahmen *rahmen;
+		TextFeld *titel;
+		ZeichnungArray *members;
+		int bgKörperFarbe;
+		Bild *bgKörperBild;
+		AlphaFeld *körperBuffer;
+		int bgSchließFarbe;
+		Bild *bgSchließBild;
+		AlphaFeld *schließBuffer;
+		AlphaFeld *schließKlickBuffer;
+		VScrollBar *vScroll;
+		HScrollBar *hScroll;
+		Punkt min, max;
+		Punkt kMin, kMax;
+		bool schließKlick, klick;
+		int mx, my;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Fenster();
+		// Destruktor 
+		__declspec( dllexport ) ~Fenster();
+		// nicht const 
+		// -- Rahmen -- 
+		__declspec( dllexport ) void setRahmenZ( LRahmen *ram ); // setzt den rahmen
+		__declspec( dllexport ) void setRFarbe( int f ); // setzt die Rahmen Farbe
+		__declspec( dllexport ) void setRBreite( int br ); // setzt die Breite des Rahmens
+		// -- Titel -- 
+		__declspec( dllexport ) void setTitel( Text *txt ); // setzt den Titel
+		__declspec( dllexport ) void setTitelZ( Text *txt );
+		__declspec( dllexport ) void setTitel( const char *txt );
+		__declspec( dllexport ) void setTTextFeldZ( TextFeld *tf ); // setzt das Titel TextFeld
+		// -- Schrift -- 
+		__declspec( dllexport ) void setTSchriftZ( Schrift *schrift ); // setzt die Titel Schrift
+		__declspec( dllexport ) void setTSFarbe( int f ); // setzt die Titel Schrift Farbe
+		__declspec( dllexport ) void setTSGröße( int gr ); // setzt die Titel Schrift Größe
+		// -- Titel Hintergrund -- 
+		__declspec( dllexport ) void setTBgFarbe( int f ); // setzt Titel Hintergrund farbe
+		// -- Titel AlphaFeld -- 
+		__declspec( dllexport ) void setTAlphaFeldZ( AlphaFeld *af ); // setzt das Titel AlphaFeld
+		__declspec( dllexport ) void setTAfFarbe( int f ); // setzt die Titel AlphFeld Farbe
+		__declspec( dllexport ) void setTAfStärke( int st ); // setzt die Stärke des Titel AlphaFeldes
+		// -- Titel Hintergrund Bild -- 
+		__declspec( dllexport ) void setTBgBild( Bild *b ); // setzt das Titel Hintergrund Bild
+		__declspec( dllexport ) void setTBgBildZ( Bild *b );
+		// -- Titel Rahmen -- 
+		__declspec( dllexport ) void setTRahmenZ( LRahmen *ram ); // set Titel Rahmen
+		__declspec( dllexport ) void setTRFarbe( int f ); // setzt die Titel Rahmen Farbe
+		__declspec( dllexport ) void setTRBreite( int br ); // setzt die Titel Rahmen Breite
+		// -- Körper Hintergrund -- 
+		__declspec( dllexport ) void setKBgFarbe( int f ); // setzt die Körper Hintergrund Farbe
+		// -- Körper Hintergrund Bild -- 
+		__declspec( dllexport ) void setKBgBild( Bild *b ); // setzt das Körper Hintergrund Bild
+		__declspec( dllexport ) void setKBgBildZ( Bild *b );
+		// -- Körper AlphaFeld -- 
+		__declspec( dllexport ) void setKAlphaFeldZ( AlphaFeld *af ); // setzt das Körper AlphaFeld
+		__declspec( dllexport ) void setKAfFarbe( int f ); // setzt Körper AlphaFeld Farbe
+		__declspec( dllexport ) void setKAfStärke( int st ); // setzt die Stärke des Körper AlphaFeldes
+		// -- Schließen --
+		__declspec( dllexport ) void setSchließenMeParam( void *param );
+		__declspec( dllexport ) void setSchließenMe( bool( *schließenMe )( void *, void *, MausEreignis ) ); // setzt das Schließen Mausereignis
+		// -- Schließen Hintergrund -- 
+		__declspec( dllexport ) void setSBgFarbe( int f ); // setzt die Schließ Hintergrund Farbe
+		// -- Schließen Hintergrund Bild -- 
+		__declspec( dllexport ) void setSBgBild( Bild *b ); // setzt das Schließ Hintergrund Bild
+		__declspec( dllexport ) void setSBgBildZ( Bild *b );
+		// -- Schließen AlphaFeld -- 
+		__declspec( dllexport ) void setSAlphaFeldZ( AlphaFeld *af ); // setzt das Schließ AlphaFeld
+		__declspec( dllexport ) void setSAfFarbe( int f ); // setzt die Farbe des Schließ AlphaFeldes
+		__declspec( dllexport ) void setSAfStärke( int st ); // setzt die Stärke des Schließ AlphaFeldes
+		// -- Schließen Klick AlphaFeld -- 
+		__declspec( dllexport ) void setSKAlphaFeldZ( AlphaFeld *af ); // setzt das Schließ klick AlphaFeld
+		__declspec( dllexport ) void setSKAfFarbe( int f ); // setzt die Farbe des Schließ klick AlphaFeldes
+		__declspec( dllexport ) void setSKAfStärke( int st ); // setzt die Stärke des Schließ klick AlphaFeldes
+		// -- min max -- 
+		__declspec( dllexport ) void setMin( int mx, int my ); // setzt die Mindest Fenster Größe
+		__declspec( dllexport ) void setMin( const Punkt &min );
+		__declspec( dllexport ) void setMax( int mx, int my ); // setzt die Maximale Fenster Größe
+		__declspec( dllexport ) void setMax( const Punkt &max );
+		__declspec( dllexport ) void setKMin( int mx, int my ); // setzt die Mindest Körper Größe
+		__declspec( dllexport ) void setKMin( const Punkt &min );
+		__declspec( dllexport ) void setKMax( int mx, int my ); // setzt die Maximale Körper Größe
+		__declspec( dllexport ) void setKMax( const Punkt &max );
+		// -- scroll -- 
+		__declspec( dllexport ) void setHScrollBarZ( HScrollBar *hScroll ); // setzt die Horizontale Scroll Bar
+		__declspec( dllexport ) void setVScrollBarZ( VScrollBar *vScroll ); // setzt die Vertikale Scroll BAr
+		__declspec( dllexport ) void setHSBMax( int max ); // setzt das Scroll Maximum
+		__declspec( dllexport ) void setVSBMax( int max );
+		__declspec( dllexport ) void setHSBScroll( int scroll ); // setzt die momentane Scroll Position
+		__declspec( dllexport ) void setVSBScroll( int scroll );
+		// -- Members -- 
+		__declspec( dllexport ) void addMember( Zeichnung *zOobj ); // fügt einen Member hinzu
+		__declspec( dllexport ) void removeMember( Zeichnung *zObj ); // entfernt einen Member
+		// -- Messages -- 
+		__declspec( dllexport ) bool tick( double tickval ) override; // tick
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+		__declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ) override;
+		// -- Render -- 
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichent nach zRObj
+		// constant 
+		// -- Rahmen -- 
+		__declspec( dllexport ) LRahmen *getRahmen() const; // gibt den Rahmen zurück
+		__declspec( dllexport ) LRahmen *zRahmen() const;
+		__declspec( dllexport ) int getRFarbe() const; // gibt die Farbe des Rahmens zurück
+		__declspec( dllexport ) int getRBreite() const; // gibt die breite des Rahmens zurück
+		// -- Titel  -- 
+		__declspec( dllexport ) Text *getTitel() const; // gibt den Titel zurück
+		__declspec( dllexport ) Text *zTitel() const;
+		__declspec( dllexport ) TextFeld *getTTextFeld() const; // gibt das Titel TextFeld zurück
+		__declspec( dllexport ) TextFeld *zTTextFeld() const;
+		// -- Titel Schrift -- 
+		__declspec( dllexport ) Schrift *getTSchrift() const; // gibt die Titel Schrift zurück
+		__declspec( dllexport ) Schrift *zTSchrift() const;
+		__declspec( dllexport ) int getTSFarbe() const; // gibt die Titel Schrift Farbe zurück
+		__declspec( dllexport ) int getTSGröße() const; // gibt die Titel Schrift Größe zurück
+		// -- Titel Hintergrund -- 
+		__declspec( dllexport ) int getTBgFarbe() const; // gibt die Titel Hintergrund Farbe zurück
+		// -- Titel AlphaFeld -- 
+		__declspec( dllexport ) AlphaFeld *getTAlphaFeld() const; // gibt das Titel AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zTAlphaFeld() const;
+		__declspec( dllexport ) int getTAfFarbe() const; // gibt die Farbe des Titel AlphaFeldes zurück
+		__declspec( dllexport ) int getTAfStärke() const; // gibt die Stärke des TitelAlphaFeldes zurück
+		// -- Titel Hintergrund Bild -- 
+		__declspec( dllexport ) Bild *getTBgBild() const; // gibt das Titel Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zTBgBild() const;
+		// -- Titel Rahmen -- 
+		__declspec( dllexport ) LRahmen *getTRahmen() const; // gibt den Titel Rahmen zurück
+		__declspec( dllexport ) LRahmen *zTRahmen() const;
+		__declspec( dllexport ) int getTRFarbe() const; // gibt die Farbe des Titel Rahmens zurück
+		__declspec( dllexport ) int getTRBreite() const; // gibt die Breite des Titel Rahmens zurück
+		// -- Körper Hintergrund -- 
+		__declspec( dllexport ) int getKBgFarbe() const; // gibt die Körper Hintergrund Farbe zurück
+		// -- Körper Hintergrund Bild -- 
+		__declspec( dllexport ) Bild *getKBgBild() const; // gibt das Körper Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zKBgBild() const;
+		// -- Körper AlphaFeld -- 
+		__declspec( dllexport ) AlphaFeld *getKAlphaFeld() const; // gibt das Körper AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zKAlphaFeld() const;
+		__declspec( dllexport ) int getKAfFarbe() const; // gibt die Farbe des Körper AlphaFeldes zurück
+		__declspec( dllexport ) int getKAfStärke() const; // gibt die Stärke des Körper AlphaFeldes zurück
+		// -- Schließen Hintergrund -- 
+		__declspec( dllexport ) int getSBgFarbe() const; // gibt die Schließ Hintergrund Farbe zurück
+		// -- Schließen Hintergrund Bild -- 
+		__declspec( dllexport ) Bild *getSBgBild() const; // gibt das Schließ Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zSBgBild() const;
+		// -- Schließen AlphaFeld -- 
+		__declspec( dllexport ) AlphaFeld *getSAlphaFeld() const; // gibt das Schließ AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zSAlphaFeld() const;
+		__declspec( dllexport ) int getSAfFarbe() const; // gibt die Farbe des Schließ AlphaFeldes zurück
+		__declspec( dllexport ) int getSAfStärke() const; // gibt die Stärke des Schließ AlphaFeldes zurück
+		// -- Schließen Klick AlphaFeld -- 
+		__declspec( dllexport ) AlphaFeld *getSKAlphaFeld() const; // gibt das Schließ Klick AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zSKAlphaFeld() const;
+		__declspec( dllexport ) int getSKAfFarbe() const; // gibt die Farbe des Schließ Klick AlphaFeldes zurück
+		__declspec( dllexport ) int getSKAfStärke() const; // gibt die Stärke des Schließ Klick AlphaFeldes zurück
+		// -- min max -- 
+		__declspec( dllexport ) const Punkt &getMin() const; // gibt die minimale Fenstergröße zurück
+		__declspec( dllexport ) const Punkt &getMax() const; // gibt die maximale Fenstergröße zurück
+		__declspec( dllexport ) const Punkt &getKMin() const; // gibt die minimale Fenstergröße zurück
+		__declspec( dllexport ) const Punkt &getKMax() const; // gibt die maximale Fenstergröße zurück
+		// -- scroll -- 
+		__declspec( dllexport ) VScrollBar *getVScrollBar() const; // gibt die Vertikale Scroll Bar zurück
+		__declspec( dllexport ) VScrollBar *zVScrollBar() const;
+		__declspec( dllexport ) HScrollBar *getHScrollBar() const; // gibt die Horizontale Scroll Bar zurück
+		__declspec( dllexport ) HScrollBar *zHScrollBar() const;
+		// -- Members -- 
+		__declspec( dllexport ) ZeichnungArray *getMembers() const; // gibt die Members zurück
+		// -- Kopie --
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Erzeugt eine Kopie des Fensters
+		// Reference Counting 
+		__declspec( dllexport ) Fenster *getThis();
+		__declspec( dllexport ) Fenster *release();
+	};
+}
+#endif

+ 333 - 0
Fortschritt.cpp

@@ -0,0 +1,333 @@
+#include "Fortschritt.h"
+
+#include "Rahmen.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include "Schrift.h"
+#include "Scroll.h"
+#include "Text.h"
+
+using namespace Framework;
+
+// Inhalt der FBalken Klasse aus Fortschritt.h 
+// Konstruktor 
+FBalken::FBalken()
+	: ZeichnungHintergrund(),
+	  maxAk( 0 ),
+	  ak( 0 ),
+	  fRahmen( 0 ),
+	  fBuffer( 0 ),
+	  fBgF( 0xFF000000 ),
+	  fBgBild( 0 ),
+	  schrift( 0 ),
+	  schriftFarbe( 0 ),
+	  schriftGröße( 0 ),
+	  ref( 1 )
+{
+    style = 0;
+}
+
+// Destructor 
+FBalken::~FBalken()
+{
+	if( rahmen )
+		rahmen->release();
+	if( fRahmen )
+		fRahmen->release();
+	if( fBuffer )
+		fBuffer->release();
+	if( fBgBild )
+		fBgBild->release();
+	if( schrift )
+		schrift->release();
+}
+
+// nicht constant 
+void FBalken::setAktionAnzahl( __int64 ak ) // setzt die anzahl der Aktionen
+{
+	maxAk = ak;
+	rend = 1;
+}
+
+void FBalken::aktionPlus() // eine Aktion ist fertig
+{
+	++ak;
+	if( ak > maxAk )
+		ak = maxAk;
+	rend = 1;
+}
+
+void FBalken::aktionPlus( __int64 aktionen ) // mehrere Aktionen sind fertig
+{
+	ak += aktionen;
+	if( ak > maxAk )
+		ak = maxAk;
+	rend = 1;
+}
+
+void FBalken::reset() // setzt die fertigen Aktionen zurück
+{
+	ak = 0;
+	rend = 1;
+}
+
+void FBalken::setFRahmenZ( LRahmen *ram ) // setzt einen Zeiger zum Fertig Rahmen
+{
+	if( fRahmen )
+		fRahmen->release();
+	fRahmen = ram;
+	rend = 1;
+}
+
+void FBalken::setFRFarbe( int f ) // setzt die Fertig Rahmen Farbe
+{
+	if( !fRahmen )
+		fRahmen = new LRahmen();
+	fRahmen->setFarbe( f );
+	rend = 1;
+}
+
+void FBalken::setFRBreite( int br ) // setzt die Fertig Rahmen Breite
+{
+	if( !fRahmen )
+		fRahmen = new LRahmen();
+	fRahmen->setRamenBreite( br );
+	rend = 1;
+}
+
+void FBalken::setFAlphaFeldZ( AlphaFeld *af ) // setzt einen Zeiger zum Fertig Alpha Feld
+{
+	if( fBuffer )
+		fBuffer->release();
+	fBuffer = af;
+	rend = 1;
+}
+
+void FBalken::setFAFFarbe( int f ) // setzt die Fertig Alpha Feld Farbe
+{
+	if( !fBuffer )
+		fBuffer = new AlphaFeld();
+	fBuffer->setFarbe( f );
+	rend = 1;
+}
+
+void FBalken::setFAFStärke( int st ) // setzt die Stärke des Fertig Alpha Feldes
+{
+	if( !fBuffer )
+		fBuffer = new AlphaFeld();
+	fBuffer->setStärke( st );
+	rend = 1;
+}
+
+void FBalken::setFBgFarbe( int f ) // setzt einen Zeiger zur Fertig Hintergrund Farbe
+{
+	fBgF = f;
+	rend = 1;
+}
+
+void FBalken::setFBgBildZ( Bild *b ) // setzt das Fertig Hintergrund Bild
+{
+	if( fBgBild )
+		fBgBild->release();
+	fBgBild = b;
+	rend = 1;
+}
+
+void FBalken::setFBgBild( Bild *b ) // kopiert in das Fertig Hintergrund Bild
+{
+	if( !fBgBild )
+		fBgBild = new Bild();
+	fBgBild->neuBild( b->getBreite(), b->getHöhe(), 0 );
+	fBgBild->drawBild( 0, 0, b->getBreite(), b->getHöhe(), *b );
+	b->release();
+	rend = 1;
+}
+
+void FBalken::setSchriftZ( Schrift *s ) // setzt die Schrift
+{
+	if( schrift )
+		schrift->release();
+	schrift = s;
+	rend = 1;
+}
+
+void FBalken::setSFarbe( int f ) // setzt die Schrift Farbe
+{
+	schriftFarbe = f;
+	rend = 1;
+}
+
+void FBalken::setSGröße( unsigned char gr ) // setzt die Schrift größe
+{
+	schriftGröße = gr;
+	rend = 1;
+}
+
+void FBalken::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+	if( !hatStyle( Style::Sichtbar ) )
+		return;
+	lockZeichnung();
+    löscheStyle( Style::VScroll | Style::HScroll );
+    __super::render( zRObj );
+	if( !zRObj.setDrawOptions( pos, gr ) )
+	{
+		unlockZeichnung();
+		return;
+	}
+	int xx = 0;
+	int yy = 0;
+	int b = gr.x;
+	int h = gr.y;
+	if( hatStyle( Style::L_R ) )
+		b = (int)( ( gr.x / 100.0 ) * getProzent() );
+	else if( hatStyle( Style::R_L ) )
+	{
+		b = (int)( ( gr.x / 100.0 ) * getProzent() );
+		xx -= b;
+	}
+	else if( hatStyle( Style::O_U ) )
+		h = (int)( ( gr.y / 100.0 ) * getProzent() );
+	else if( hatStyle( Style::U_O ) )
+	{
+		h = (int)( ( gr.y / 100.0 ) * getProzent() );
+		yy -= h;
+	}
+	if( maxAk == 0 )
+		b = 0, h = 0;
+	if( !zRObj.setDrawOptions( xx, yy, b, h ) )
+	{
+		zRObj.releaseDrawOptions();
+		unlockZeichnung();
+		return;
+	}
+    int rbr = 0;
+	if( hatStyle( Style::FRahmen ) && fRahmen )
+	{
+		fRahmen->setGröße( b, h );
+		fRahmen->render( zRObj );
+		rbr = fRahmen->getRBreite();
+	}
+	if( hatStyle( Style::FFarbe ) )
+	{
+		if( hatStyle( Style::FAlpha ) )
+			zRObj.alphaRegion( rbr, rbr, b - rbr * 2, h - rbr * 2, fBgF );
+		else
+			zRObj.füllRegion( rbr, rbr, b - rbr * 2, h - rbr * 2, fBgF );
+	}
+	if( hatStyle( Style::FBild ) && fBgBild )
+	{
+		if( hatStyle( Style::FAlpha ) )
+			zRObj.alphaBildSkall( rbr, rbr, b - rbr * 2, h - rbr * 2, *fBgBild );
+		else
+			zRObj.drawBildSkall( rbr, rbr, b - rbr * 2, h - rbr * 2, *fBgBild );
+	}
+	if( hatStyle( Style::FBuffered ) && fBuffer )
+	{
+		fBuffer->setGröße( b - rbr * 2, h - rbr * 2 );
+		fBuffer->render( zRObj );
+	}
+	zRObj.releaseDrawOptions();
+	if( hatStyle( Style::Prozent ) && schrift )
+	{
+		schrift->setSchriftGröße( schriftGröße );
+		Text txt;
+		txt.anhängen( (int)getProzent() );
+		txt.anhängen( "%" );
+		schrift->setDrawPosition( rbr + ( gr.x - rbr * 2 ) / 2 - schrift->getTextBreite( &txt ) / 2, rbr + ( gr.y - rbr * 2 ) / 2 - schrift->getTextHöhe( &txt ) / 2 );
+		schrift->renderText( &txt, zRObj, schriftFarbe );
+	}
+	zRObj.releaseDrawOptions();
+	unlockZeichnung();
+}
+
+// constant 
+__int64 FBalken::getAktionAnzahl() const // gibt die Anzahl der Aktionen zurück
+{
+	return maxAk;
+}
+
+double FBalken::getProzent() const // gibt die momentane Prozentzahl zurück
+{
+	if( !maxAk )
+		return 0;
+	return ak / ( maxAk / 100.0 );
+}
+
+__int64 FBalken::getAktion() const // gibt die fertigen Aktionen zurück
+{
+	return ak;
+}
+
+LRahmen *FBalken::getFRahmen() const // gibt den Fertig Rahmen zurück
+{
+	if( fRahmen )
+		return fRahmen->getThis();
+	return 0;
+}
+
+LRahmen *FBalken::zFRahmen() const
+{
+	return fRahmen;
+}
+
+AlphaFeld *FBalken::getFAlphaFeld() const // gibt das Fertig Alpha Feld zurück
+{
+	if( fBuffer )
+		return fBuffer->getThis();
+	return 0;
+}
+
+AlphaFeld *FBalken::zFAlphaFeld() const
+{
+	return fBuffer;
+}
+
+int FBalken::getFBgFarbe() const // gibt die Fertig Hintergrund Farbe zurück
+{
+	return fBgF;
+}
+
+Bild *FBalken::getFBgBild() const // gibt das Fertig Hintergrund Bild zurück
+{
+	if( fBgBild )
+		return fBgBild->getThis();
+	return 0;
+}
+
+Bild *FBalken::zFBgBild() const
+{
+	return fBgBild;
+}
+
+Schrift *FBalken::getSchrift() const // gibt die Schrift zurück
+{
+	if( schrift )
+		return schrift->getThis();
+	return 0;
+}
+
+Schrift *FBalken::zSchrift() const
+{
+	return schrift;
+}
+
+int FBalken::getSFarbe() const // gibt die Schrift Farbe zurück
+{
+	return schriftFarbe;
+}
+
+// Reference Counting 
+FBalken *FBalken::getThis()
+{
+	++ref;
+	return this;
+}
+
+FBalken *FBalken::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}

+ 90 - 0
Fortschritt.h

@@ -0,0 +1,90 @@
+#ifndef Fortschritt_H
+#define Fortschritt_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class LRahmen; // Rahmen.h
+	class AlphaFeld; // AlphaFeld.h
+	class Bild; // Bild.h
+	class Schrift; // Schrift.h
+	class FBalken; // aus dieser Datei
+
+	class FBalken : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 Prozent = 0x001000;
+
+            const static __int64 FRahmen = 0x002000;
+            const static __int64 FFarbe = 0x004000;
+            const static __int64 FBild = 0x008000;
+            const static __int64 FAlpha = 0x10000;
+            const static __int64 FBuffered = 0x20000;
+
+            const static __int64 L_R = 0x0100000;
+            const static __int64 R_L = 0x0200000;
+            const static __int64 U_O = 0x0400000;
+            const static __int64 O_U = 0x0800000;
+
+            const static __int64 normal = Sichtbar | Rahmen | Hintergrund | HBild | FRahmen | FBild | L_R | Prozent;
+        };
+	private:
+		__int64 maxAk;
+		__int64 ak;
+		LRahmen *fRahmen;
+		AlphaFeld *fBuffer;
+		int fBgF;
+		Bild *fBgBild;
+		Schrift *schrift;
+		int schriftFarbe;
+		unsigned char schriftGröße;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) FBalken();
+		// Destructor 
+		__declspec( dllexport ) ~FBalken();
+		// nicht constant 
+		__declspec( dllexport ) void setAktionAnzahl( __int64 ak ); // setzt die anzahl der Aktionen
+		__declspec( dllexport ) void aktionPlus(); // eine Aktion ist fertig
+		__declspec( dllexport ) void aktionPlus( __int64 aktionen ); // mehrere Aktionen sind fertig
+		__declspec( dllexport ) void reset(); // setzt die fertigen Aktionen zurück
+		__declspec( dllexport ) void setFRahmenZ( LRahmen *ram ); // setzt einen Zeiger zum Fertig Rahmen
+		__declspec( dllexport ) void setFRFarbe( int f ); // setzt die Fertig Rahmen Farbe
+		__declspec( dllexport ) void setFRBreite( int br ); // setzt die Fertig Rahmen Breite
+		__declspec( dllexport ) void setFAlphaFeldZ( AlphaFeld *af ); // setzt einen Zeiger zum Fertig Alpha Feld
+		__declspec( dllexport ) void setFAFFarbe( int f ); // setzt die Fertig Alpha Feld Farbe
+		__declspec( dllexport ) void setFAFStärke( int st ); // setzt die Stärke des Fertig Alpha Feldes
+		__declspec( dllexport ) void setFBgFarbe( int f ); // setzt einen Zeiger zur Fertig Hintergrund Farbe
+		__declspec( dllexport ) void setFBgBildZ( Bild *b ); // setzt das Fertig Hintergrund Bild
+		__declspec( dllexport ) void setFBgBild( Bild *b ); // kopiert in das Fertig Hintergrund Bild
+		__declspec( dllexport ) void setSchriftZ( Schrift *b ); // setzt die Schrift
+		__declspec( dllexport ) void setSFarbe( int f ); // setzt die Schrift Farbe
+		__declspec( dllexport ) void setSGröße( unsigned char gr ); // setzt die Schrift größe
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) __int64 getAktionAnzahl() const; // gibt die Anzahl der Aktionen zurück
+		__declspec( dllexport ) double getProzent() const; // gibt die momentane Prozentzahl zurück
+		__declspec( dllexport ) __int64 getAktion() const; // gibt die fertigen Aktionen zurück
+		__declspec( dllexport ) LRahmen *getFRahmen() const; // gibt den Fertig Rahmen zurück
+		__declspec( dllexport ) LRahmen *zFRahmen() const;
+		__declspec( dllexport ) AlphaFeld *getFAlphaFeld() const; // gibt das Fertig Alpha Feld zurück
+		__declspec( dllexport ) AlphaFeld *zFAlphaFeld() const;
+		__declspec( dllexport ) int getFBgFarbe() const; // gibt die Fertig Hintergrund Farbe zurück
+		__declspec( dllexport ) Bild *getFBgBild() const; // gibt das Fertig Hintergrund Bild zurück
+		__declspec( dllexport ) Bild *zFBgBild() const;
+		__declspec( dllexport ) Schrift *getSchrift() const; // gibt die Schrift zurück
+		__declspec( dllexport ) Schrift *zSchrift() const;
+		__declspec( dllexport ) int getSFarbe() const; // gibt die Schrift Farbe zurück
+		// Reference Counting 
+		__declspec( dllexport ) FBalken *getThis();
+		__declspec( dllexport ) FBalken *release();
+	};
+}
+
+#endif

+ 28 - 0
Framework.sln

@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Framework", "Framework.vcxproj", "{C67E1D50-8FED-42FC-9538-1818297CF817}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Debug|Win32.Build.0 = Debug|Win32
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Debug|x64.ActiveCfg = Debug|x64
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Debug|x64.Build.0 = Debug|x64
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Release|Win32.ActiveCfg = Release|Win32
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Release|Win32.Build.0 = Release|Win32
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Release|x64.ActiveCfg = Release|x64
+		{C67E1D50-8FED-42FC-9538-1818297CF817}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 352 - 0
Framework.vcxproj

@@ -0,0 +1,352 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C67E1D50-8FED-42FC-9538-1818297CF817}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>Framework</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <ReferencePath>C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(ReferencePath)</ReferencePath>
+    <SourcePath>$(SourcePath)</SourcePath>
+    <IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;DXSDK_DIR)include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(DXSDK_DIR)lib\x86;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <ReferencePath>$(ReferencePath)</ReferencePath>
+    <SourcePath>$(SourcePath)</SourcePath>
+    <IncludePath>$(IncludePath)</IncludePath>
+    <LibraryPath>$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(IncludePath)</IncludePath>
+    <ReferencePath>$(ReferencePath)</ReferencePath>
+    <LibraryPath>$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(IncludePath)</IncludePath>
+    <ReferencePath>$(ReferencePath)</ReferencePath>
+    <LibraryPath>$(LibraryPath)</LibraryPath>
+    <SourcePath>$(SourcePath)</SourcePath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FRAMEWORK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>dxerr.lib;dxguid.lib;d3dx9.lib;d3dx10.lib;d3d9.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;FRAMEWORK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <BrowseInformation>true</BrowseInformation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>d3dcompiler.lib;d3d9.lib;d3d11.lib;DXGI.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Main Server\Main Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Register Server\Register Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Patch Server\Patch Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Login Server\Login Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Information Server\Information Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Chat Server\Chat Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\DatenbankServer\DatenbankServer\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Anmeldung Server\Anmeldung Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Spiel Server\Spiel Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Erhaltung Server\Erhaltung Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Shop Server\Shop Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\Historie Server\Historie Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Server\News Server\News Server\framework.dll"
+copy "x64\Debug\Framework.dll" "..\Test\Test\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Klient\Start\Start\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Klient\patcher\patcher\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\Klient\Icon\Icon\framework.dll"
+copy "x64\Debug\Framework.dll" "..\..\Spiele Platform\SMP\SMP\framework.dll"
+copy "x64\Debug\Framework.dll" "..\LTDB Konverter\LTDB Konverter\framework.dll"
+copy "x64\Debug\Framework.dll" "..\GSL Konverter\GSL Konverter\framework.dll"</Command>
+      <Outputs>kopiere Dateien...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <Bscmake>
+      <PreserveSbr>true</PreserveSbr>
+    </Bscmake>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>Full</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FRAMEWORK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>d3dcompiler.lib;d3d9.lib;d3d11.lib;DXGI.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "Release\Framework.dll" "..\..\Spiele Platform\Server\Fertig\x32\dlls\framework.dll"
+copy "Release\Framework.dll" "..\..\Spiele Platform\Klient\Fertig\x32\framework.dll"
+copy "Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x32\framework.dll"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopiere...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>Full</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FRAMEWORK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BrowseInformation>true</BrowseInformation>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>d3dcompiler.lib;d3d9.lib;d3d11.lib;DXGI.lib;dxguid.lib;winmm.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "x64\Release\Framework.dll" "..\..\Spiele Platform\Server\Fertig\x64\dlls\framework.dll"
+copy "x64\Release\Framework.dll" "..\..\Spiele Platform\Klient\Fertig\x64\framework.dll"
+copy "x64\Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x64\framework.dll"</Command>
+      <Outputs>kopiere...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <Bscmake>
+      <PreserveSbr>true</PreserveSbr>
+    </Bscmake>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="AlphaFeld.h" />
+    <ClInclude Include="Animation.h" />
+    <ClInclude Include="Animation3D.h" />
+    <ClInclude Include="Array.h" />
+    <ClInclude Include="AuswahlBox.h" />
+    <ClInclude Include="Bild.h" />
+    <ClInclude Include="Bildschirm.h" />
+    <ClInclude Include="Cube.h" />
+    <ClInclude Include="DXBuffer.h" />
+    <ClInclude Include="Datei.h" />
+    <ClInclude Include="DateiDialog.h" />
+    <ClInclude Include="DateiSystem.h" />
+    <ClInclude Include="DefaultShader.h" />
+    <ClInclude Include="Diagramm.h" />
+    <ClInclude Include="DreieckListe.h" />
+    <ClInclude Include="Fenster.h" />
+    <ClInclude Include="Fortschritt.h" />
+    <ClInclude Include="FrameworkMath.h" />
+    <ClInclude Include="Globals.h" />
+    <ClInclude Include="InitDatei.h" />
+    <ClInclude Include="Kam2D.h" />
+    <ClInclude Include="Kam3D.h" />
+    <ClInclude Include="Knopf.h" />
+    <ClInclude Include="KSGTDatei.h" />
+    <ClInclude Include="Liste.h" />
+    <ClInclude Include="M2Datei.h" />
+    <ClInclude Include="M3Datei.h" />
+    <ClInclude Include="main.h" />
+    <ClInclude Include="Mat3.h" />
+    <ClInclude Include="Mat4.h" />
+    <ClInclude Include="Maus.h" />
+    <ClInclude Include="MausEreignis.h" />
+    <ClInclude Include="Model2D.h" />
+    <ClInclude Include="M2DVorschau.h" />
+    <ClInclude Include="Model3D.h" />
+    <ClInclude Include="Model3DList.h" />
+    <ClInclude Include="ObjectRegister.h" />
+    <ClInclude Include="Render3D.h" />
+    <ClInclude Include="Shader.h" />
+    <ClInclude Include="Textur.h" />
+    <ClInclude Include="TexturList.h" />
+    <ClInclude Include="Vec4.h" />
+    <ClInclude Include="Welt3D.h" />
+    <ClInclude Include="Zeichnung.h" />
+    <ClInclude Include="Prozess.h" />
+    <ClInclude Include="Punkt.h" />
+    <ClInclude Include="Rahmen.h" />
+    <ClInclude Include="RenderThread.h" />
+    <ClInclude Include="Schluessel.h" />
+    <ClInclude Include="Schrift.h" />
+    <ClInclude Include="Scroll.h" />
+    <ClInclude Include="Tabelle.h" />
+    <ClInclude Include="TastaturEreignis.h" />
+    <ClInclude Include="Text.h" />
+    <ClInclude Include="TextFeld.h" />
+    <ClInclude Include="Thread.h" />
+    <ClInclude Include="ToolTip.h" />
+    <ClInclude Include="Betriebssystem.h" />
+    <ClInclude Include="Vec2.h" />
+    <ClInclude Include="Vec3.h" />
+    <ClInclude Include="Welt2D.h" />
+    <ClInclude Include="Zeichnung3D.h" />
+    <ClInclude Include="Zeit.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="AlphaFeld.cpp" />
+    <ClCompile Include="Animation.cpp" />
+    <ClCompile Include="AuswahlBox.cpp" />
+    <ClCompile Include="Bild.cpp" />
+    <ClCompile Include="Bildschirm.cpp" />
+    <ClCompile Include="Cube.cpp" />
+    <ClCompile Include="Datei.cpp" />
+    <ClCompile Include="DateiDialog.cpp" />
+    <ClCompile Include="DateiSystem.cpp" />
+    <ClCompile Include="Diagramm.cpp" />
+    <ClCompile Include="DXBuffer.cpp" />
+    <ClCompile Include="Fenster.cpp" />
+    <ClCompile Include="Fortschritt.cpp" />
+    <ClCompile Include="Global.cpp" />
+    <ClCompile Include="InitDatei.cpp" />
+    <ClCompile Include="Kam2D.cpp" />
+    <ClCompile Include="Kam3D.cpp" />
+    <ClCompile Include="Knopf.cpp" />
+    <ClCompile Include="KSGTDatei.cpp" />
+    <ClCompile Include="Liste.cpp" />
+    <ClCompile Include="M2Datei.cpp" />
+    <ClCompile Include="M2DVorschau.cpp" />
+    <ClCompile Include="M3Datei.cpp" />
+    <ClCompile Include="Maus.cpp" />
+    <ClCompile Include="MausEreignis.cpp" />
+    <ClCompile Include="Model2D.cpp" />
+    <ClCompile Include="Model3D.cpp" />
+    <ClCompile Include="Model3DList.cpp" />
+    <ClCompile Include="Render3D.cpp" />
+    <ClCompile Include="Shader.cpp" />
+    <ClCompile Include="Textur.cpp" />
+    <ClCompile Include="TexturList.cpp" />
+    <ClCompile Include="Welt3D.cpp" />
+    <ClCompile Include="Zeichnung3D.cpp" />
+    <ClCompile Include="Zeichnung.cpp" />
+    <ClCompile Include="Prozess.cpp" />
+    <ClCompile Include="Punkt.cpp" />
+    <ClCompile Include="Rahmen.cpp" />
+    <ClCompile Include="RenderThread.cpp" />
+    <ClCompile Include="Schluessel.cpp" />
+    <ClCompile Include="Schrift.cpp" />
+    <ClCompile Include="Scroll.cpp" />
+    <ClCompile Include="Tabelle.cpp" />
+    <ClCompile Include="TastaturEreignis.cpp" />
+    <ClCompile Include="Text.cpp" />
+    <ClCompile Include="TextFeld.cpp" />
+    <ClCompile Include="Thread.cpp" />
+    <ClCompile Include="ToolTip.cpp" />
+    <ClCompile Include="Welt2D.cpp" />
+    <ClCompile Include="Zeit.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="TestShader.hlsl">
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0</ShaderModel>
+      <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compute</ShaderType>
+      <ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0</ShaderModel>
+      <FileType>Document</FileType>
+    </None>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 422 - 0
Framework.vcxproj.filters

@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Ressourcendateien">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="Headerdateien\Framework">
+      <UniqueIdentifier>{ebc032cb-0fe8-4712-8cba-6f8cf72c9e6e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Objekte">
+      <UniqueIdentifier>{c85aabf4-2e43-4a74-90bc-2d92b7bf3259}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\OS">
+      <UniqueIdentifier>{446e41c7-ea7d-4519-9cd1-1238232b08f8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Grafik">
+      <UniqueIdentifier>{d87f71ae-4946-4766-a9e3-e93f41e7f079}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Grafik\3D">
+      <UniqueIdentifier>{c3d8b482-b58f-48c6-9945-797f38a60fcf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Grafik\2D">
+      <UniqueIdentifier>{98ccc730-0ee3-4075-bfba-8998571c99e5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Grafik\DX">
+      <UniqueIdentifier>{cbb56eda-8286-4f8b-9a06-47b5af838106}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework">
+      <UniqueIdentifier>{c35d3344-6ec8-4fa4-b32c-1976b6520a35}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\OS">
+      <UniqueIdentifier>{d5fa078e-3896-4292-a26d-67a78fed965a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Objekte">
+      <UniqueIdentifier>{446facfc-5180-4e05-a2ff-c5c0287705d2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Grafik">
+      <UniqueIdentifier>{8af2e4df-a840-42d3-a393-5d6b4bf7d569}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Grafik\2D">
+      <UniqueIdentifier>{849a8e90-f586-4537-8265-3b69a810dd5d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Grafik\DX">
+      <UniqueIdentifier>{4f762c9c-38af-494e-81a5-7a8fff22d551}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\OS\Datei">
+      <UniqueIdentifier>{fbd720d3-b19c-4501-b4dd-600cdbbea72d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\OS\Datei">
+      <UniqueIdentifier>{3ce6b48b-5906-41a0-b86b-2cce0876825b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Grafik\4D">
+      <UniqueIdentifier>{638c4ef2-2ea4-4d4f-872a-f2012f97a696}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headerdateien\Framework\Objekte3D">
+      <UniqueIdentifier>{28760380-5f68-43aa-87ae-353d20cad63d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Objekte3D">
+      <UniqueIdentifier>{867266da-c3c0-4633-8374-989d2b60863c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien\Framework\Grafik\3D">
+      <UniqueIdentifier>{6b73527a-d839-4081-a7b5-7e1d79b67cbd}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Model2D.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="Vec2.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="Vec3.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Mat3.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Animation.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="AlphaFeld.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Knopf.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Fenster.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Fortschritt.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Liste.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Diagramm.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Rahmen.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Tabelle.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="TextFeld.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="ToolTip.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Scroll.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Bildschirm.h">
+      <Filter>Headerdateien\Framework\Grafik\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="Betriebssystem.h">
+      <Filter>Headerdateien\Framework\OS</Filter>
+    </ClInclude>
+    <ClInclude Include="AuswahlBox.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="Prozess.h">
+      <Filter>Headerdateien\Framework\OS</Filter>
+    </ClInclude>
+    <ClInclude Include="Thread.h">
+      <Filter>Headerdateien\Framework\OS</Filter>
+    </ClInclude>
+    <ClInclude Include="Bild.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="RenderThread.h">
+      <Filter>Headerdateien\Framework\Grafik\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="MausEreignis.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="TastaturEreignis.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Array.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Maus.h">
+      <Filter>Headerdateien\Framework\OS</Filter>
+    </ClInclude>
+    <ClInclude Include="Schluessel.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Schrift.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Text.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Punkt.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Globals.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="FrameworkMath.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="main.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Zeit.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Datei.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="DateiSystem.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="InitDatei.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="KSGTDatei.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="M2Datei.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="DateiDialog.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="Welt2D.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="Kam2D.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="M2DVorschau.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="ObjectRegister.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
+    <ClInclude Include="Zeichnung.h">
+      <Filter>Headerdateien\Framework\Objekte</Filter>
+    </ClInclude>
+    <ClInclude Include="DefaultShader.h">
+      <Filter>Headerdateien\Framework\Grafik\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="M3Datei.h">
+      <Filter>Headerdateien\Framework\OS\Datei</Filter>
+    </ClInclude>
+    <ClInclude Include="Model3D.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Zeichnung3D.h">
+      <Filter>Headerdateien\Framework\Objekte3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Mat4.h">
+      <Filter>Headerdateien\Framework\Grafik\4D</Filter>
+    </ClInclude>
+    <ClInclude Include="Shader.h">
+      <Filter>Headerdateien\Framework\Grafik\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="Kam3D.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="DreieckListe.h">
+      <Filter>Headerdateien\Framework\Grafik\2D</Filter>
+    </ClInclude>
+    <ClInclude Include="Welt3D.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Render3D.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Textur.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="DXBuffer.h">
+      <Filter>Headerdateien\Framework\Grafik\DX</Filter>
+    </ClInclude>
+    <ClInclude Include="Cube.h">
+      <Filter>Headerdateien\Framework\Objekte3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Model3DList.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Vec4.h">
+      <Filter>Headerdateien\Framework\Grafik\4D</Filter>
+    </ClInclude>
+    <ClInclude Include="TexturList.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+    <ClInclude Include="Animation3D.h">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Maus.cpp">
+      <Filter>Quelldateien\Framework\OS</Filter>
+    </ClCompile>
+    <ClCompile Include="Prozess.cpp">
+      <Filter>Quelldateien\Framework\OS</Filter>
+    </ClCompile>
+    <ClCompile Include="Thread.cpp">
+      <Filter>Quelldateien\Framework\OS</Filter>
+    </ClCompile>
+    <ClCompile Include="AlphaFeld.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="AuswahlBox.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Diagramm.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Fenster.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Fortschritt.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Knopf.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Liste.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Rahmen.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Scroll.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Tabelle.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="TextFeld.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="ToolTip.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Animation.cpp">
+      <Filter>Quelldateien\Framework\Grafik\2D</Filter>
+    </ClCompile>
+    <ClCompile Include="Bild.cpp">
+      <Filter>Quelldateien\Framework\Grafik\2D</Filter>
+    </ClCompile>
+    <ClCompile Include="Bildschirm.cpp">
+      <Filter>Quelldateien\Framework\Grafik\DX</Filter>
+    </ClCompile>
+    <ClCompile Include="RenderThread.cpp">
+      <Filter>Quelldateien\Framework\Grafik\DX</Filter>
+    </ClCompile>
+    <ClCompile Include="Global.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="MausEreignis.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Model2D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\2D</Filter>
+    </ClCompile>
+    <ClCompile Include="Punkt.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Schluessel.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Schrift.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="TastaturEreignis.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Text.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Zeit.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
+    <ClCompile Include="Datei.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="DateiSystem.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="InitDatei.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="KSGTDatei.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="M2Datei.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="DateiDialog.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="Welt2D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\2D</Filter>
+    </ClCompile>
+    <ClCompile Include="Kam2D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\2D</Filter>
+    </ClCompile>
+    <ClCompile Include="M2DVorschau.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="Zeichnung.cpp">
+      <Filter>Quelldateien\Framework\Objekte</Filter>
+    </ClCompile>
+    <ClCompile Include="M3Datei.cpp">
+      <Filter>Quelldateien\Framework\OS\Datei</Filter>
+    </ClCompile>
+    <ClCompile Include="Zeichnung3D.cpp">
+      <Filter>Quelldateien\Framework\Objekte3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Shader.cpp">
+      <Filter>Quelldateien\Framework\Grafik\DX</Filter>
+    </ClCompile>
+    <ClCompile Include="Welt3D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Render3D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Kam3D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Textur.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Model3D.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="DXBuffer.cpp">
+      <Filter>Quelldateien\Framework\Grafik\DX</Filter>
+    </ClCompile>
+    <ClCompile Include="Cube.cpp">
+      <Filter>Quelldateien\Framework\Objekte3D</Filter>
+    </ClCompile>
+    <ClCompile Include="Model3DList.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+    <ClCompile Include="TexturList.cpp">
+      <Filter>Quelldateien\Framework\Grafik\3D</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="TestShader.hlsl">
+      <Filter>Headerdateien\Framework\Grafik\3D</Filter>
+    </None>
+  </ItemGroup>
+</Project>

+ 37 - 0
FrameworkMath.h

@@ -0,0 +1,37 @@
+#ifndef FrameworkMath_H
+#define FrameworkMath_H
+
+#include <math.h>
+#include "Betriebssystem.h"
+
+#define PI 3.14159265
+
+// Gibt die größere Zahl zurück ohne if zu verwenden
+// Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
+//  a: Eine der beiden Zahlen
+//  b: Eine der beiden Zahlen
+inline int maxInt( int a, int b )
+{
+	return ( ( ( a - b ) >> 16 ) & b ) | ( ~( ( a - b ) >> 16 ) & a );
+}
+
+// Gibt die kleinere Zahl zurück ohne if zu verwenden
+// Funktioniert nur, wenn die Zahlen nicht mehr als 16 bits verwenden
+//  a: Eine der beiden Zahlen
+//  b: Eine der beiden Zahlen
+inline int minInt( int a, int b )
+{
+	return ( ( ( a - b ) >> 16 ) & a ) | ( ~( ( a - b ) >> 16 ) & b );
+}
+
+// Gibt den positiven Wert eines Zeichnunges zurück.
+// Klappt nur, wenn der - operator definiert ist
+template< typename T>
+inline T abs( T t )
+{
+    if( t < 0 )
+        return -t;
+    return t;
+}
+
+#endif

+ 84 - 0
Global.cpp

@@ -0,0 +1,84 @@
+#ifdef WIN32
+
+#include <Windows.h>
+#include <GdiPlus.h>
+#pragma comment( lib, "gdiplus.lib" )
+
+#endif
+#define Global
+#include "Fenster.h"
+#include "Maus.h"
+#include "Globals.h"
+#include "Thread.h"
+#include "Model3DList.h"
+#include "TexturList.h"
+
+void Framework::initFramework()
+{
+    if( istInitialisiert )
+        return;
+    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+    ULONG_PTR gdiplusToken;
+    Gdiplus::GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, 0 );
+	msgExit = 0;
+	MausTrack = 1;
+	for( int i = 0; i < 255; ++i )
+		TastenStand[ i ] = 0;
+	for( int i = 0; i < 3; ++i )
+		MausStand[ i ] = 0;
+    thRegister = new ThreadRegister();
+    Model3DList::init();
+    m3dRegister = new Model3DList();
+    TexturList::init();
+    texturRegister = new TexturList();
+	istInitialisiert = 1;
+}
+
+void Framework::releaseFramework()
+{
+	if( !istInitialisiert )
+		return;
+    delete thRegister;
+    m3dRegister->release();
+    Model3DList::destroy();
+    texturRegister->release();
+    TexturList::destroy();
+	istInitialisiert = 0;
+}
+
+const Framework::Punkt &Framework::getMausPos()
+{
+	return mausPos;
+}
+
+bool Framework::getMausStand( int taste )
+{
+	return MausStand[ taste ];
+}
+
+void Framework::setTastenStand( unsigned char taste, bool st )
+{
+	TastenStand[ taste ] = st;
+}
+
+bool Framework::getTastenStand( unsigned char taste )
+{
+	return TastenStand[ taste ];
+}
+
+bool Framework::istThreadOk( Thread *t )
+{
+    return thRegister->isThread( t );
+}
+
+// Gibt das Model3DData Register des Frameworks ohne erhöhten reference Counter zurück
+Framework::Model3DList *Framework::zM3DRegister()
+{
+    return m3dRegister;
+}
+
+// Gibt das Textur Register des Frameworks ohne erhöhten reference Counter zurück
+Framework::TexturList *Framework::zTexturRegister()
+{
+    return texturRegister;
+}

+ 62 - 0
Globals.h

@@ -0,0 +1,62 @@
+#ifndef Globals_H
+#define Globals_H
+
+#include "Punkt.h"
+
+#ifndef Global
+#define Global extern
+#endif
+
+namespace Framework
+{
+	class Maus; // Maus.h
+	class WFensterArray; // Fenster.h
+    class Thread; // Thread.h
+    class ThreadRegister; // Thread.h
+    class Model3DList; // Model3DList.h
+    class TexturList; // TexturList.h
+
+	Global WFensterArray WFensterA;
+	Global bool MausTrack;
+	Global bool MausStand[ 3 ];
+	Global bool TastenStand[ 255 ];
+	Global Maus MausZeiger;
+	Global bool istInitialisiert;
+	Global bool msgExit;
+	Global Punkt mausPos;
+    Global ThreadRegister *thRegister;
+    Global Model3DList *m3dRegister;
+    Global TexturList *texturRegister;
+
+    // Gibt die Koordinaten der Maus auf dem Bildschirm zurück
+	__declspec( dllexport ) const Punkt &getMausPos();
+    // Gibt zurück, ob eine Taste der Maus momentan gedrückt wird
+    //  taste: Die Taste, die geprüft werden soll
+    // Beispiel: getMausStand( M_Links ); (Benötigt include <MausEreignis.h>
+	__declspec( dllexport ) bool getMausStand( int taste );
+    // Gibt zurück, ob eine Taste auf der tastatur momentan gedrückt wird
+    //  taste: Die Taste, die überprüft werden soll
+    // Beispiel: getTastenStand( T_Enter ); (Benötogt include <TastaturEreignis.h>
+	__declspec( dllexport ) bool getTastenStand( unsigned char taste );
+    // Legt fest, ob eine Taste auf der tastatur momentan gedrückt wird
+    // Der Tastenstand wird vom Framework selbst verwaltet und muss nicht mit dieser Funktion gesetzt werden
+    //  taste: Die Taste, deren Status gesetzt werden soll
+    //  st: Ob die Taste momentan gedrückt wird. (true), wenn ja. (false) sonnst.
+	__declspec( dllexport ) void setTastenStand( unsigned char taste, bool st );
+    // Initialisiert das Framework
+    // Wird in der (WinMain) des Frameworks automatisch aufgerufen
+	__declspec( dllexport ) void initFramework();
+    // Gibt den duch (initFramework) benutzten Arbeitsspeicher wieder frei
+    // Wird in der (WinMain) des Frameworks automatisch aufgerufen
+	__declspec( dllexport ) void releaseFramework();
+    // Überprüft, ob ein bestimmter Zeiger auf ein Gültiges Thread Objekt zeigt
+    //  t: Der zeiger, der überprüft werden soll
+    //  return: 1, falls der Zeiger in Ordnung ist. 0, falls der Zeiger auf kein existentes Thread Objekt zeigt
+    __declspec( dllexport ) bool istThreadOk( Thread *t );
+    // Gibt das Model3DData Register des Frameworks ohne erhöhten reference Counter zurück
+    __declspec( dllexport ) Model3DList *zM3DRegister();
+    // Gibt das Textur Register des Frameworks ohne erhöhten reference Counter zurück
+    __declspec( dllexport ) TexturList *zTexturRegister();
+}
+
+#endif

+ 408 - 0
InitDatei.cpp

@@ -0,0 +1,408 @@
+#include "InitDatei.h"
+#include "Text.h"
+#include "Datei.h"
+
+using namespace Framework;
+
+// Inhalt der InitDatei Klasse aus InitDatei.h
+// Konstruktor
+InitDatei::InitDatei()
+	: pfad( new Text() ),
+	  feldAnzahl( 0 ),
+	  name( new RCArray< Text >() ),
+	  wert( new RCArray< Text >() ),
+	  ref( 1 )
+{
+}
+
+InitDatei::InitDatei( Text *pfad )
+	: pfad( new Text() ),
+	feldAnzahl( 0 ),
+	name( new RCArray< Text >() ),
+	wert( new RCArray< Text >() ),
+	ref( 1 )
+{
+	setPfad( pfad );
+}
+
+InitDatei::InitDatei( const char *pfad )
+	: pfad( new Text() ),
+	feldAnzahl( 0 ),
+	name( new RCArray< Text >() ),
+	wert( new RCArray< Text >() ),
+	ref( 1 )
+{
+	setPfad( pfad );
+}
+
+// Destruktor
+InitDatei::~InitDatei()
+{
+	pfad->release();
+	name->release();
+	wert->release();
+}
+
+// nicht constant
+void InitDatei::setPfad( Text *pfad )
+{
+	this->pfad->setText( pfad );
+}
+
+void InitDatei::setPfad( const char *pfad )
+{
+	this->pfad->setText( pfad );
+}
+
+bool InitDatei::laden()
+{
+	Datei *dat = new Datei();
+	dat->setDatei( pfad->getText() );
+	if( !dat->öffnen( Datei::Style::lesen ) )
+	{
+		dat->release();
+		return 0;
+	}
+	löscheAlle();
+	Text *zeile = dat->leseZeile();
+	for( int i = 0; zeile; ++i )
+	{
+		zeile->löschen( "\r\n" );
+		zeile->löschen( "\n" );
+		Text *n = zeile->getTeilText( 0, zeile->positionVon( '=' ) );
+		Text *w = zeile->getTeilText( zeile->positionVon( '=' ) + 1 );
+		name->set( n, i );
+		wert->set( w, i );
+		zeile->release();
+		zeile = dat->leseZeile();
+		feldAnzahl = i + 1;
+	}
+	dat->schließen();
+	dat->release();
+	return 1;
+}
+
+bool InitDatei::addWert( Text *name, Text *wert )
+{
+	if( !wertExistiert( name->getText() ) )
+	{
+		this->name->set( new Text( name->getText() ), feldAnzahl );
+		this->wert->set( new Text( wert->getText() ), feldAnzahl );
+		++feldAnzahl;
+		name->release();
+		wert->release();
+		return 1;
+	}
+	name->release();
+	wert->release();
+	return 0;
+}
+
+bool InitDatei::addWert( const char *name, const char *wert )
+{
+	if( !wertExistiert( name ) )
+	{
+		this->name->set( new Text( name ), feldAnzahl );
+		this->wert->set( new Text( wert ), feldAnzahl );
+		++feldAnzahl;
+		return 1;
+	}
+	return 0;
+}
+
+bool InitDatei::setWert( Text *name, Text *wert )
+{
+	if( !wertExistiert( name->getText() ) )
+	{
+		name->release();
+		wert->release();
+		return 0;
+	}
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			this->wert->z( i )->setText( wert->getText() );
+			name->release();
+			wert->release();
+			return 1;
+		}
+	}
+	name->release();
+	wert->release();
+	return 0;
+}
+
+bool InitDatei::setWert( const char *name, const char *wert )
+{
+	if( !wertExistiert( name ) )
+		return 0;
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+		{
+			this->wert->z( i )->setText( wert );
+			return 1;
+		}
+	}
+	return 0;
+}
+
+bool InitDatei::setWert( int num, Text *wert )
+{
+	if( num >= feldAnzahl )
+	{
+		wert->release();
+		return 0;
+	}
+	this->wert->z( num )->setText( wert->getText() );
+	wert->release();
+	return 1;
+}
+
+bool InitDatei::setWert( int num, const char *wert )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	this->wert->z( num )->setText( wert );
+	return 1;
+}
+
+bool InitDatei::löscheWert( Text *name )
+{
+	if( !wertExistiert( name->getText() ) )
+	{
+		name->release();
+		return 0;
+	}
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			this->name->lösche( i );
+			this->wert->lösche( i );
+			--feldAnzahl;
+			name->release();
+			return 1;
+		}
+	}
+	name->release();
+	return 0;
+}
+
+bool InitDatei::löscheWert( const char *name )
+{
+	if( !wertExistiert( name ) )
+		return 0;
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+		{
+			this->name->lösche( i );
+			this->wert->lösche( i );
+			--feldAnzahl;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+bool InitDatei::löscheWert( int num )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	this->name->lösche( num );
+	this->wert->lösche( num );
+	--feldAnzahl;
+	return 1;
+}
+
+void InitDatei::löscheAlle()
+{
+	for( ; feldAnzahl > 0; --feldAnzahl )
+	{
+		this->name->lösche( 0 );
+		this->wert->lösche( 0 );
+	}
+}
+
+bool InitDatei::speichern()
+{
+	Datei *dat = new Datei();
+	dat->setDatei( pfad->getText() );
+	if( !dat->existiert() )
+		dat->erstellen();
+	if( !dat->öffnen( Datei::Style::schreiben ) )
+	{
+		dat->release();
+		return 0;
+	}
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		Text *zeile = new Text( "" );
+		zeile->anhängen( name->z( i )->getText() );
+		zeile->anhängen( "=" );
+		zeile->anhängen( wert->z( i )->getText() );
+		zeile->anhängen( "\n" );
+		dat->schreibe( zeile->getText(), zeile->getLänge() );
+		zeile->release();
+	}
+	dat->schließen();
+	dat->release();
+	return 1;
+}
+
+// constant
+int InitDatei::getWertAnzahl() const
+{
+	return feldAnzahl;
+}
+
+bool InitDatei::wertExistiert( Text *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			name->release();
+			return 1;
+		}
+	}
+	name->release();
+	return 0;
+}
+
+bool InitDatei::wertExistiert( const char *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+			return 1;
+	}
+	return 0;
+}
+
+int InitDatei::getWertNummer( Text *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			name->release();
+			return i;
+		}
+	}
+	name->release();
+	return -1;
+}
+
+int InitDatei::getWertNummer( const char *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+			return i;
+	}
+	return -1;
+}
+
+Text *InitDatei::getWert( Text *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			name->release();
+			return wert->get( i );
+		}
+	}
+	name->release();
+	return 0;
+}
+
+Text *InitDatei::getWert( const char *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+			return wert->get( i );
+	}
+	return 0;
+}
+
+Text *InitDatei::getWert( int num )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	return wert->get( num );
+}
+
+Text *InitDatei::zWert( Text *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name->getText() ) )
+		{
+			name->release();
+			return wert->z( i );
+		}
+	}
+	name->release();
+	return 0;
+}
+
+Text *InitDatei::zWert( const char *name )
+{
+	for( int i = 0; i < feldAnzahl; ++i )
+	{
+		if( this->name->z( i )->istGleich( name ) )
+			return wert->z( i );
+	}
+	return 0;
+}
+
+Text *InitDatei::zWert( int num )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	return wert->z( num );
+}
+
+Text *InitDatei::getName( int num )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	return name->get( num );
+}
+
+Text *InitDatei::zName( int num )
+{
+	if( num >= feldAnzahl )
+		return 0;
+	return name->z( num );
+}
+
+Text *InitDatei::getPfad() const
+{
+	return pfad->getThis();
+}
+
+Text *InitDatei::zPfad() const
+{
+	return pfad;
+}
+
+// reference Counting
+InitDatei *InitDatei::getThis()
+{
+	++ref;
+	return this;
+}
+
+InitDatei *InitDatei::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 150 - 0
InitDatei.h

@@ -0,0 +1,150 @@
+#ifndef InitDatei_H
+#define InitDatei_H
+
+#include "Array.h"
+
+namespace Framework
+{
+	class Text; // Text.h
+
+    // Verwaltet Initialisierungsdateien in denen Bestimmte Variablen im Format name=Wert gespeichert sind
+	class InitDatei
+	{
+	private:
+		Text *pfad;
+		int feldAnzahl;
+		RCArray< Text > *name;
+		RCArray< Text > *wert;
+		int ref;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) InitDatei();
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) InitDatei( Text *pfad );
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) InitDatei( const char *pfad );
+		// Destruktor
+		__declspec( dllexport ) ~InitDatei();
+		// Setzt den Pfad zur Datei
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) void setPfad( Text *pfad );
+        // Setzt den Pfad zur Datei
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) void setPfad( const char *pfad );
+        // Lähdt die Werte aus der Datei
+        //  return: 1, falls das Laden erfolgreich war. 0, wenn ein fehler aufgetreten ist.
+		__declspec( dllexport ) bool laden();
+        // Fügt der Datei einen Wert hinzu
+        //  name: Der Name des Wertes
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert erfolgreich hinzugefügt wurde
+		__declspec( dllexport ) bool addWert( Text *name, Text *wert );
+        // Fügt der Datei einen Wert hinzu
+        //  name: Der Name des Wertes
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert erfolgreich hinzugefügt wurde
+		__declspec( dllexport ) bool addWert( const char *name, const char *wert );
+        // Ändert einen bestimmten Wert
+        //  name: Der Name des Wertes
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich geändert werden konnte
+		__declspec( dllexport ) bool setWert( Text *name, Text *wert );
+        // Ändert einen bestimmten Wert
+        //  name: Der Name des Wertes
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich geändert werden konnte
+		__declspec( dllexport ) bool setWert( const char *name, const char *wert );
+        // Ändert einen bestimmten Wert
+        //  num: Der Index des Wertes der geändert werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich geändert werden konnte
+		__declspec( dllexport ) bool setWert( int num, Text *wert );
+        // Ändert einen bestimmten Wert
+        //  num: Der Index des Wertes der geändert werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich geändert werden konnte
+		__declspec( dllexport ) bool setWert( int num, const char *wert );
+        // Löscht einen bestimmten Wert
+        //  name: Der Name des Wertes, der gelöscht werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich gelöscht werden konnte
+		__declspec( dllexport ) bool löscheWert( Text *name );
+        // Löscht einen bestimmten Wert
+        //  name: Der Name des Wertes, der gelöscht werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich gelöscht werden konnte
+		__declspec( dllexport ) bool löscheWert( const char *name );
+        // Löscht einen bestimmten Wert
+        //  num: Der Index des Wertes der gelöscht werden soll
+        //  return: 1, falls der Wert vorhanden war und erfolgreich gelöscht werden konnte
+		__declspec( dllexport ) bool löscheWert( int num );
+        // Löscht alle Werte aus der Datei
+		__declspec( dllexport ) void löscheAlle();
+        // Speichert alle Werte in der Datei
+        //  return: 1, falls das Speichern erfolgreich war
+		__declspec( dllexport ) bool speichern();
+		// Gibt die Anzahl der gespeicherten Werte zurück
+		__declspec( dllexport ) int getWertAnzahl() const;
+        // Überprüft, ob ein bestimmter Wert existiert
+        //  name: Der Name, nach dem gesucht werden soll
+        //  return: 1, falls der Wert gefunden wurde
+		__declspec( dllexport ) bool wertExistiert( Text *name );
+        // Überprüft, ob ein bestimmter Wert existiert
+        //  name: Der Name, nach dem gesucht werden soll
+        //  return: 1, falls der Wert gefunden wurde
+		__declspec( dllexport ) bool wertExistiert( const char *name );
+        // Gibt den Index eines Bestimmten Wertes zurück
+        //  name: Der Name des Wertes, nach dem gesucht werden soll
+        //  return: -1, falls der Wert nicht gefunden wurde. Der Index des Wertes.
+		__declspec( dllexport ) int getWertNummer( Text *name );
+        // Gibt den Index eines Bestimmten Wertes zurück
+        //  name: Der Name des Wertes, nach dem gesucht werden soll
+        //  return: -1, falls der Wert nicht gefunden wurde. Der Index des Wertes.
+		__declspec( dllexport ) int getWertNummer( const char *name );
+        // Gibt einen bestimmten Wert zurück
+        //  name: Der Name des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde.
+		__declspec( dllexport ) Text *getWert( Text *name );
+        // Gibt einen bestimmten Wert zurück
+        //  name: Der Name des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde.
+		__declspec( dllexport ) Text *getWert( const char *name );
+        // Gibt einen bestimmten Wert zurück
+        //  num: Der Index des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde.
+		__declspec( dllexport ) Text *getWert( int num );
+        // Gibt einen bestimmten Wert zurück
+        //  name: Der Name des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde. Der Wert ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zWert( Text *name );
+        // Gibt einen bestimmten Wert zurück
+        //  name: Der Name des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde. Der Wert ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zWert( const char *name );
+        // Gibt einen bestimmten Wert zurück
+        //  num: Der Index des Wertes, der zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde. Der Wert ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zWert( int num );
+        // Gibt den Namen eines bestimmten Wertes zurück
+        //  num: Der Index des Wertes, dessen Namen zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde.
+		__declspec( dllexport ) Text *getName( int num );
+        // Gibt den Namen eines bestimmten Wertes zurück
+        //  num: Der Index des Wertes, dessen Namen zurückgegeben werden soll
+        //  return: 0, falls der Wert nicht gefunden wurde. Der Name ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zName( int num );
+        // Gibt den Pfad zur Datei zurück
+		__declspec( dllexport ) Text *getPfad() const;
+        // Gibt den Pfad zur Datei ohne erhöhten Reference Counter zurück
+		__declspec( dllexport ) Text *zPfad() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) InitDatei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) InitDatei *release();
+	};
+}
+
+#endif

+ 310 - 0
KSGTDatei.cpp

@@ -0,0 +1,310 @@
+#include "KSGTDatei.h"
+#include "Text.h"
+#include "Datei.h"
+
+using namespace Framework;
+
+// Inhalt der KSGTDatei Klasse aus KSGTDatei.h
+// Konstruktor
+KSGTDatei::KSGTDatei()
+	: pfad( new Text() ),
+	  data( new RCArray< RCArray< Text > >() ),
+	  ref( 1 )
+{
+}
+
+KSGTDatei::KSGTDatei( const char *pfad )
+	: pfad( new Text() ),
+	  data( new RCArray< RCArray< Text > >() ),
+	  ref( 1 )
+{
+	setPfad( pfad );
+}
+
+KSGTDatei::KSGTDatei( Text *pfad )
+	: pfad( new Text() ),
+	  data( new RCArray< RCArray< Text > >() ),
+	  ref( 1 )
+{
+	setPfad( pfad );
+}
+
+// Destruktor
+KSGTDatei::~KSGTDatei()
+{
+	pfad->release();
+	data->release();
+}
+
+// nicht constant
+void KSGTDatei::setPfad( const char *pfad )
+{
+	this->pfad->setText( pfad );
+}
+
+void KSGTDatei::setPfad( Text *pfad )
+{
+	this->pfad->setText( pfad );
+}
+
+bool KSGTDatei::laden()
+{
+	std::ifstream inf;
+	inf.open( pfad->getText(), std::ios::binary );
+	if( !inf.good() || !inf.is_open() )
+		return 0;
+	data->leeren();
+	inf.seekg( 0, std::ios::end );
+	__int64 gr = inf.tellg();
+	__int64 pos = 0;
+	int zeilenPos = 0;
+	int feldPos = 0;
+	while( pos < gr )
+	{
+		inf.seekg( pos, std::ios::beg );
+		char c = 1;
+		int län = 0;
+		do
+		{
+			inf.read( &c, 1 );
+			++län;
+		}
+		while( c != 0 && c != '\n' && pos + län < gr );
+		if( pos + län == gr )
+			++län;
+		inf.seekg( pos, std::ios::beg );
+		char *v = new char[ län ];
+		v[ län - 1 ] = 0;
+		if( län > 1 )
+			inf.read( v, län - 1 );
+		pos += län;
+		if( län > 1 && !data->z( zeilenPos ) )
+			data->set( new RCArray< Text >, zeilenPos );
+		if( !data->z( zeilenPos )->z( feldPos ) )
+			data->z( zeilenPos )->set( new Text(), feldPos );
+		data->z( zeilenPos )->z( feldPos )->setText( v );
+		delete[] v;
+		if( c == 0 )
+			++feldPos;
+		else if( c == '\n' )
+		{
+			++zeilenPos;
+			feldPos = 0;
+		}
+		else
+			break;
+	}
+	inf.close();
+	return 1;
+}
+
+bool KSGTDatei::addZeile( int feldAnzahl, RCArray< Text > *zWert )
+{
+	int pos = getZeilenAnzahl();
+	data->set( new RCArray< Text >(), pos );
+	for( int i = 0; i < feldAnzahl; ++i )
+		data->z( pos )->set( new Text( zWert->z( i )->getText() ), i );
+	return 1;
+}
+
+bool KSGTDatei::setZeile( int zeile, int feldAnzahl, RCArray< Text > *zWert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	data->set( new RCArray< Text >(), zeile );
+	for( int i = 0; i < feldAnzahl; ++i )
+		data->z( zeile )->set( new Text( zWert->z( i )->getText() ), i );
+	return 1;
+}
+
+bool KSGTDatei::löscheZeile( int zeile )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	data->lösche( zeile );
+	return 1;
+}
+
+bool KSGTDatei::addFeld( int zeile, int pos, Text *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+	{
+		wert->release();
+		return 0;
+	}
+	int fA = getFeldAnzahl( zeile );
+	if( pos > fA )
+	{
+		wert->release();
+		return 0;
+	}
+	data->z( zeile )->add( new Text( wert->getText() ), pos );
+	wert->release();
+	return 1;
+}
+
+bool KSGTDatei::addFeld( int zeile, int pos, const char *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	if( pos > fA )
+		return 0;
+	data->z( zeile )->add( new Text( wert ), pos );
+	return 1;
+}
+
+bool KSGTDatei::addFeld( int zeile, Text *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+	{
+		wert->release();
+		return 0;
+	}
+	int fA = getFeldAnzahl( zeile );
+	data->z( zeile )->set( new Text( wert->getText() ), fA );
+	wert->release();
+	return 1;
+}
+
+bool KSGTDatei::addFeld( int zeile, const char *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	data->z( zeile )->set( new Text( wert ), fA );
+	return 1;
+}
+
+bool KSGTDatei::setFeld( int zeile, int feld, Text *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+	{
+		wert->release();
+		return 0;
+	}
+	int fA = getFeldAnzahl( zeile );
+	if( feld >= fA )
+	{
+		wert->release();
+		return 0;
+	}
+	data->z( zeile )->set( new Text( wert->getText() ), feld );
+	wert->release();
+	return 1;
+}
+
+bool KSGTDatei::setFeld( int zeile, int feld, const char *wert )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	if( feld >= fA )
+		return 0;
+	data->z( zeile )->set( new Text( wert ), feld );
+	return 1;
+}
+
+bool KSGTDatei::löscheFeld( int zeile, int feld )
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	if( feld >= fA )
+		return 0;
+	data->z( zeile )->lösche( feld );
+	return 1;
+}
+
+bool KSGTDatei::speichern()
+{
+	if( !pfad->getLänge() )
+		return 0;
+	if( !DateiExistiert( pfad->getText() ) )
+		DateiPfadErstellen( pfad->getText() );
+	std::ofstream of( pfad->getText(), std::ios::binary );
+	if( !of.good() || !of.is_open() )
+		return 0;
+	int zA = getZeilenAnzahl();
+	for( int z = 0; z < zA; ++z )
+	{
+		if( z )
+			of.write( "\n", 1 );
+		int fA = getFeldAnzahl( z );
+		for( int f = 0; f < fA; ++f )
+		{
+			if( f )
+				of.write( "\0", 1 );
+			if( data->z( z ) && data->z( z )->z( f ) )
+				of.write( data->z( z )->z( f )->getText(), data->z( z )->z( f )->getLänge() );
+		}
+	}
+	of.close();
+	return 1;
+}
+
+// constant
+int KSGTDatei::getZeilenAnzahl() const
+{
+	int ret = 0;
+	while( data->z( ret ) )
+		++ret;
+	return ret;
+}
+
+int KSGTDatei::getFeldAnzahl( int zeile ) const
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int ret = 0;
+	while( data->z( zeile )->z( ret ) )
+		++ret;
+	return ret;
+}
+
+Text *KSGTDatei::getFeld( int zeile, int feld ) const
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	if( feld >= fA )
+		return 0;
+	return data->z( zeile )->get( feld );
+}
+
+Text *KSGTDatei::zFeld( int zeile, int feld ) const
+{
+	int zA = getZeilenAnzahl();
+	if( zeile >= zA )
+		return 0;
+	int fA = getFeldAnzahl( zeile );
+	if( feld >= fA )
+		return 0;
+	return data->z( zeile )->z( feld );
+}
+
+// Reference Counting
+KSGTDatei *KSGTDatei::getThis()
+{
+	++ref;
+	return this;
+}
+
+KSGTDatei *KSGTDatei::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 119 - 0
KSGTDatei.h

@@ -0,0 +1,119 @@
+#ifndef KSGTDatei_H
+#define KSGTDatei_H
+
+#include "Array.h"
+
+namespace Framework
+{
+	class Text;
+
+    // Verwaltet eine Datei in der Daten tabellarisch abgespeichert werden
+	class KSGTDatei
+	{
+	private:
+		Text *pfad;
+		RCArray< RCArray< Text > > *data;
+		int ref;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) KSGTDatei();
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) KSGTDatei( const char *pfad );
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+        __declspec( dllexport ) KSGTDatei( Text *pfad );
+		// Destruktor
+		__declspec( dllexport ) ~KSGTDatei();
+		// Setzt den Pfad zur Datei
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) void setPfad( const char *pfad );
+        // Setzt den Pfad zur Datei
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) void setPfad( Text *pfad );
+        // lähdt alle Daten aus der angegebenen Datei
+        //  return: 1, falls das laden erfolgreich war. 0, wenn ein Fehler beim laden aufgetreten ist
+		__declspec( dllexport ) bool laden();
+        // Fügt eine Zeile zur Tabelle hinzu
+        //  feldAnzahl: Die Anzahl der Felder in der Zeile
+        //  zWert: Einen Zeiger auf die Werte in der Zeile ohne erhöhten Reference Counter
+        //  return: 1, wenn kein Fehler aufgetreten ist
+		__declspec( dllexport ) bool addZeile( int feldAnzahl, RCArray< Text > *zWert );
+        // Ersetzt eine existierende Zeile
+        //  zeile: Der Index der Zeile, die ersetzt werden soll
+        //  feldAnzahl: Die Anzahl der Felder in der Zeile
+        //  zWert: Einen Zeiger auf die Werte in der Zeile ohne erhöhten Reference Counter
+        //  return: 1, wenn die Zeile existierte und ersetzt wurde. 0, wenn die angegebene Zeile nicht existierte
+		__declspec( dllexport ) bool setZeile( int zeile, int feldAnzahl, RCArray< Text > *zWert );
+        // Löscht eine Zeile
+        //  zeile: Der Index der Zeile, die gelöscht werden soll
+        //  return: 1, wenn die Zeile gelöscht wurde. 0, wenn die Zeile nicht gefunden wurde
+		__declspec( dllexport ) bool löscheZeile( int zeile );
+        // Fügt einer Bestimmten Zeile einen Wert hinzu
+        //  zeile: Der Index der Zeile, der ein Wert hinzugefügt werden soll
+        //  pos: Die Position in der Zeile, an der der Wert hinzugefügt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich hinzugefügt wurde. 0, falls die Zeile nicht existiert, oder pos zu groß ist
+		__declspec( dllexport ) bool addFeld( int zeile, int pos, Text *wert );
+        // Fügt einer Bestimmten Zeile einen Wert hinzu
+        //  zeile: Der Index der Zeile, der ein Wert hinzugefügt werden soll
+        //  pos: Die Position in der Zeile, an der der Wert hinzugefügt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich hinzugefügt wurde. 0, falls die Zeile nicht existiert, oder pos zu groß ist
+		__declspec( dllexport ) bool addFeld( int zeile, int pos, const char *wert );
+        // Fügt einer Bestimmten Zeile am Ende einen Wert hinzu
+        //  zeile: Der Index der Zeile, der ein Wert hinzugefügt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich hinzugefügt wurde. 0, falls die Zeile nicht existiert
+		__declspec( dllexport ) bool addFeld( int zeile, Text *wert );
+        // Fügt einer Bestimmten Zeile am Ende einen Wert hinzu
+        //  zeile: Der Index der Zeile, der ein Wert hinzugefügt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich hinzugefügt wurde. 0, falls die Zeile nicht existiert
+		__declspec( dllexport ) bool addFeld( int zeile, const char *wert );
+        // Setzt einen Bestimmten Wert in einer Zeile
+        //  zeile: Der Index der Zeile, in der ein Wert verändert werden soll
+        //  feld: Die Position in der Zeile, an der der Wert gesetzt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich ersetzt wurde. 0, falls die Zeile oder der Wert nicht existiert
+		__declspec( dllexport ) bool setFeld( int zeile, int feld, Text *wert );
+        // Setzt einen Bestimmten Wert in einer Zeile
+        //  zeile: Der Index der Zeile, in der ein Wert verändert werden soll
+        //  feld: Die Position in der Zeile, an der der Wert gesetzt werden soll
+        //  wert: Der Wert, der gespeichert werden soll
+        //  return: 1, falls Der Wert erfolgreich ersetzt wurde. 0, falls die Zeile oder der Wert nicht existiert
+		__declspec( dllexport ) bool setFeld( int zeile, int feld, const char *wert );
+        // Entfernt einen bestimmten Wert
+        //  zeile: Der Index der Zeile, aus der ein Wert gelöscht werden soll
+        //  feld: Die Position in der Zeile, an der der Wert gelöscht werden soll
+        //  return: 1, falls Der Wert erfolgreich gelöscht wurde. 0, falls die Zeile oder der Wert nicht existiert
+		__declspec( dllexport ) bool löscheFeld( int zeile, int feld );
+        // Speichert die Tabelle in der Datei
+        //  return: 1, falls die Tabbelle erfolgreich gespeichert wurde
+		__declspec( dllexport ) bool speichern();
+		// Gibt die Anzahl der Zeilen zurück
+		__declspec( dllexport ) int getZeilenAnzahl() const;
+        // Gibt die Anzahl der Werte (Spalten) in einer Zeile zurück
+        //  zeile: Der Index der Zeile, von der die Anzahl Werte ermittelt werden soll
+		__declspec( dllexport ) int getFeldAnzahl( int zeile ) const;
+        // Gibt einen bestimmten gespeicherten Wert zurück
+        //  zeile: Der Index der Zeile, in der der Wert gespeichert wird
+        //  feld: Der Index des Wertes in der Zeile
+        //  return: Den gespeicherten Wert mit erhöhtem Reference Counter
+		__declspec( dllexport ) Text *getFeld( int zeile, int feld ) const;
+        // Gibt einen bestimmten gespeicherten Wert zurück
+        //  zeile: Der Index der Zeile, in der der Wert gespeichert wird
+        //  feld: Der Index des Wertes in der Zeile
+        //  return: Den gespeicherten Wert ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zFeld( int zeile, int feld ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) KSGTDatei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) KSGTDatei *release();
+	};
+}
+
+#endif

+ 310 - 0
Kam2D.cpp

@@ -0,0 +1,310 @@
+#include "Kam2D.h"
+#include "Bild.h"
+#include "Welt2D.h"
+#include "MausEreignis.h"
+#include "ToolTip.h"
+#include "TastaturEreignis.h"
+#include "Globals.h"
+
+using namespace Framework;
+
+// Inhalt der Kam2D Klasse aus Kam2D.h
+// Konstruktor
+Kam2D::Kam2D()
+{
+    welt = 0;
+    wGr.x = 0;
+    wGr.y = 0;
+    maxWGr.x = 0;
+    maxWGr.y = 0;
+    wPos.x = 0;
+    wPos.y = 0;
+    animations = new Array< KamAnimation* >();
+    ref = 1;
+}
+
+// Destruktor
+Kam2D::~Kam2D()
+{
+    if( welt )
+        welt->release();
+    animations->release();
+}
+
+// nicht constant
+void Kam2D::setWelt( Welt2D *welt )
+{
+    if( this->welt )
+        this->welt->release();
+    this->welt = welt;
+}
+
+void Kam2D::setMaxWeltGröße( int br, int hö )
+{
+    maxWGr.x = br;
+    maxWGr.y = hö;
+}
+
+void Kam2D::setWeltGröße( int x, int y, int sek )
+{
+    animations->add( new KamAnimation{ WeltGröße, (double)x, (double)y, (double)sek } );
+}
+
+void Kam2D::scrollIn( int scroll, int sek )
+{
+    animations->add( new KamAnimation{ ScrollIn, (double)scroll, 0, (double)sek } );
+}
+
+void Kam2D::scrollOut( int scroll, int sek )
+{
+    animations->add( new KamAnimation{ ScrollOut, (double)scroll, 0, (double)sek } );
+}
+
+void Kam2D::moveKam( int x, int y, int sek )
+{
+    animations->add( new KamAnimation{ MoveKam, (double)x, (double)y, (double)sek } );
+}
+
+void Kam2D::finishAnimation()
+{
+    while( animations->getEintragAnzahl() > 0 )
+    {
+        KamAnimation *a = animations->get( 0 );
+        switch( a->typ )
+        {
+        case WeltGröße:
+            wGr.x = a->w1;
+            wGr.y = a->w2;
+            break;
+        case ScrollIn:
+        {
+            double tmp = wGr.x;
+            wGr.x -= a->w1;
+            wGr.y -= ( wGr.y * a->w1 ) / tmp;
+            break;
+        }
+        case ScrollOut:
+        {
+            double tmp = wGr.x;
+            wGr.x += a->w1;
+            wGr.y += ( wGr.y * a->w1 ) / tmp;
+            break;
+        }
+        case MoveKam:
+            wPos.x = a->w1;
+            wPos.y = a->w1;
+            break;
+        }
+        animations->lösche( 0 );
+        delete a;
+    }
+}
+
+void Kam2D::clearAnimation()
+{
+    while( animations->getEintragAnzahl() > 0 )
+    {
+        delete animations->get( 0 );
+        animations->lösche( 0 );
+    }
+}
+
+bool Kam2D::tick( double t )
+{
+    int num = 0;
+    for( auto i = animations->getArray(); i.set; i++ )
+    {
+        double time = t;
+        switch( i.var->typ )
+        {
+        case WeltGröße:
+            if( i.var->sek < t )
+                time = i.var->sek;
+            wGr.x += ( i.var->w1 - wGr.x ) * time;
+            wGr.y = ( i.var->w2 - wGr.y ) * time;
+            break;
+        case ScrollIn:
+        {
+            double tmp = wGr.x;
+            wGr.x -= i.var->w1 * time;
+            wGr.y -= ( wGr.y * i.var->w1 * time ) / tmp;
+            break;
+        }
+        case ScrollOut:
+        {
+            double tmp = wGr.x;
+            wGr.x += i.var->w1 * time;
+            wGr.y += ( wGr.y * i.var->w1 * time ) / tmp;
+            break;
+        }
+        case MoveKam:
+            wPos.x += ( i.var->w1 - wPos.x ) * time;
+            wPos.y += ( i.var->w1 - wPos.y ) * time;
+            break;
+        }
+        i.var->sek -= time;
+        if( i.var->sek == 0 )
+        {
+            delete i.var;
+            animations->lösche( num );
+            num--;
+        }
+        num++;
+        rend = 1;
+    }
+    if( hatStyle( Style::MAUS_MOVE ) )
+    {
+        if( mausPos.x > 0 && mausPos.y < 30 )
+            wPos.x -= 50 * t;
+        if( mausPos.x > gr.x - 30 && mausPos.x < gr.x )
+            wPos.x += 50 * t;
+        if( mausPos.y > 0 && mausPos.y < 30 )
+            wPos.y -= 50 * t;
+        if( mausPos.y > gr.y - 30 && mausPos.y < gr.y )
+            wPos.y += 50 * t;
+    }
+    if( hatStyle( Style::TASTATUR_MOVE ) )
+    {
+        if( getTastenStand( T_Links ) )
+            wPos.x -= 50 * t;
+        if( getTastenStand( T_Rechts ) )
+            wPos.x += 50 * t;
+        if( getTastenStand( T_Oben ) )
+            wPos.y -= 50 * t;
+        if( getTastenStand( T_Unten ) )
+            wPos.y += 50 * t;
+    }
+    if( welt && hatStyle( Style::WELT_TICK ) )
+        rend |= welt->tick( t );
+    else
+        rend |= welt->tick( 0 );
+    return __super::tick( t );
+}
+
+void Kam2D::doMausEreignis( MausEreignis &me )
+{
+    if( me.verarbeitet || ( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+        }
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak && Mak( makParam, this, me ) )
+    {
+        if( welt && hatStyle( Style::WELT_EREIGNISSE ) )
+        {
+            int tmpx = me.mx;
+            int tmpy = me.my;
+            me.mx = (int)( wPos.x + me.mx * ( wGr.x / gr.x ) );
+            me.my = (int)( wPos.y + me.my * ( wGr.y / gr.y ) );
+            welt->doMausEreignis( me );
+            me.mx = tmpx;
+            me.my = tmpy;
+        }
+        if( hatStyle( Style::MAUS_MOVE ) )
+        {
+            mausPos.x = me.mx;
+            mausPos.y = me.my;
+        }
+        me.verarbeitet = 1;
+    }
+    if( nMak && me.verarbeitet )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x, me.my += pos.y;
+}
+
+void Kam2D::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( te.verarbeitet )
+        return;
+    if( Tak && Tak( takParam, this, te ) )
+    {
+        if( welt && hatStyle( Style::WELT_EREIGNISSE ) )
+            welt->doTastaturEreignis( te );
+        te.verarbeitet = 1;
+    }
+    if( nTak && te.verarbeitet )
+        te.verarbeitet = nTak( ntakParam, this, te );
+}
+
+void Kam2D::render( Bild &rObj )
+{
+    if( !hatStyle( Style::Sichtbar ) )
+        return;
+    löscheStyle( Style::HScroll | Style::VScroll );
+    __super::render( rObj );
+    if( !rObj.setDrawOptions( innenPosition, innenGröße ) )
+        return;
+    if( welt )
+        welt->render( rObj, (Punkt)wPos, (Punkt)wGr, innenGröße );
+    rObj.releaseDrawOptions();
+}
+
+// constant
+Welt2D *Kam2D::zWelt() const
+{
+    return welt;
+}
+
+Welt2D *Kam2D::getWelt() const
+{
+    return welt ? welt->getThis() : 0;
+}
+
+double Kam2D::getWeltX() const
+{
+    return wPos.x;
+}
+
+double Kam2D::getWeltY() const
+{
+    return wPos.y;
+}
+
+double Kam2D::getWeltBr() const
+{
+    return wGr.x;
+}
+
+double Kam2D::getWeltHö() const
+{
+    return wGr.y;
+}
+
+// Reference Counting
+Kam2D *Kam2D::getThis()
+{
+    ref++;
+    return this;
+}
+
+Kam2D *Kam2D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 78 - 0
Kam2D.h

@@ -0,0 +1,78 @@
+#pragma once
+
+#include "Zeichnung.h"
+#include "Array.h"
+
+namespace Framework
+{
+    class Welt2D; // Welt2D.h
+    struct MausEreignis;
+    struct TastaturEreignis;
+
+    enum KamAnimationTyp
+    {
+        WeltGröße,
+        ScrollIn,
+        ScrollOut,
+        MoveKam
+    };
+
+    struct KamAnimation
+    {
+        KamAnimationTyp typ;
+        double w1;
+        double w2;
+        double sek;
+    };
+
+    class Kam2D : public ZeichnungHintergrund
+    {
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 TASTATUR_MOVE = 0x001000;
+            const static __int64 MAUS_MOVE = 0x002000;
+            const static __int64 WELT_EREIGNISSE = 0x004000;
+            const static __int64 WELT_TICK = 0x008000;
+        };
+
+    private:
+        Welt2D *welt;
+        Vec2< double > wGr;
+        Punkt maxWGr;
+        Vec2< double > wPos;
+        Punkt mausPos;
+        Array< KamAnimation* > *animations;
+        int ref;
+        
+    public:
+        // Konstruktor
+        Kam2D();
+        // Destruktor
+        ~Kam2D();
+        // nicht constant
+        void setWelt( Welt2D *welt );
+        void setMaxWeltGröße( int br, int hö );
+        void setWeltGröße( int x, int y, int sek );
+        void scrollIn( int scroll, int sek );
+        void scrollOut( int scroll, int sek );
+        void moveKam( int x, int y, int sek );
+        void finishAnimation();
+        void clearAnimation();
+        bool tick( double t ) override;
+        void doMausEreignis( MausEreignis &me ) override;
+        void doTastaturEreignis( TastaturEreignis &te ) override;
+        void render( Bild &rObj ) override;
+        // constant
+        Welt2D *zWelt() const;
+        Welt2D *getWelt() const;
+        double getWeltX() const;
+        double getWeltY() const;
+        double getWeltBr() const;
+        double getWeltHö() const;
+        // Reference Counting
+        Kam2D *getThis();
+        Kam2D *release();
+    };
+}

+ 216 - 0
Kam3D.cpp

@@ -0,0 +1,216 @@
+#include "Kam3D.h"
+#include "Welt3D.h"
+#include "Render3D.h"
+#include "Shader.h"
+#include "TastaturEreignis.h"
+#include "Globals.h"
+#include <d3d11.h>
+#include <DirectXMath.h>
+
+using namespace Framework;
+
+// Inhalt der Kam3D Klasse
+// Konstruktor
+Kam3D::Kam3D()
+{
+    öffnungswinkel = (float)PI / 4;
+    minZ = 0.1f;
+    maxZ = 5000;
+    pos = Vec3< float >( 0, 0, -1000 );
+    rotX = 0;
+    rotY = 0;
+    rotZ = 0;
+
+    viewport = new D3D11_VIEWPORT();
+    viewport->TopLeftY = 0;
+    viewport->TopLeftX = 0;
+    viewport->MinDepth = 0.f;
+    viewport->MaxDepth = 1.f;
+    viewport->Width = 200;
+    viewport->Height = 200;
+
+    welt = 0;
+
+    ref = 1;
+
+    updateMatrix();
+}
+
+// Destruktor
+Kam3D::~Kam3D()
+{
+    if( welt )
+        welt->release();
+    delete viewport;
+}
+
+// private
+
+// Aktualisiert die view und projektion matrizen
+void Kam3D::updateMatrix()
+{
+    view = view.rotationX( -rotX ) * view.rotationY( -rotY ) * view.rotationZ( -rotZ ) * view.translation( Vec3< float >( -pos.x, -pos.y, -pos.z ) );
+    proj = proj.projektion( öffnungswinkel, viewport->Width / viewport->Height, minZ, maxZ );
+}
+
+// Setzt die Position der Kamera in der 3D Welt
+void Kam3D::setPosition( Vec3< float > pos )
+{
+    this->pos = pos;
+    updateMatrix();
+}
+
+// zoomt heran, indem sich die Kamera etwas auf das Blickziel zubewegt
+//  val: Die länge der Strecke um die sich die Kamera bewegen soll
+void Kam3D::scrollIn( float val )
+{
+    Vec3< float > n( 0, 0, 1 );
+    Mat4< float > tmp = tmp.rotationY( rotY ) * tmp.rotationX( rotX ) * tmp.rotationZ( rotZ );
+    n = tmp * n * val;
+    pos += n;
+}
+
+// zppmt heraus, indem sich die Kamera etwas von dem Blockziel entfernt
+//  val: Die länge der Strecke um die sich die Kamera bewegen soll
+void Kam3D::scrollOut( float val )
+{
+    Vec3< float > n( 0, 0, 1 );
+    Mat4< float > tmp = tmp.rotationY( rotY ) * tmp.rotationX( rotX ) * tmp.rotationZ( rotZ );
+    n = tmp * n * val;
+    pos -= n;
+}
+
+// Richtet die Kamera so aus, dass sie genau auf einen bestimmten Punkt zeigt
+//  ziel: Der Punkt, auf den die Kamera zeigen soll
+void Kam3D::setAusrichtung( Vec3< float > ziel )
+{
+
+}
+
+// Setzt die Position des Bildes auf dem Bildschirm
+//  p: Ein Punkt mit x und y Koordinaten in Pixeln
+void Kam3D::setBildschirmPosition( Punkt p )
+{
+    viewport->TopLeftX = (float)p.x;
+    viewport->TopLeftY = (float)p.y;
+}
+
+// Setzt die Position des Bildes auf dem Bildschirm
+//  x: Die x Koordinate in Pixeln
+//  y: Die y Koordinate in Pixeln
+void Kam3D::setBildschirmPosition( int x, int y )
+{
+    viewport->TopLeftX = (float)x;
+    viewport->TopLeftY = (float)y;
+}
+
+// Setzt die Größe des Bildes auf dem Bildschirm
+//  p: Ein Punkt, mit x als Breite und y als Höhe in Pixlen
+void Kam3D::setBildschirmGröße( Punkt p )
+{
+    viewport->Width = (float)p.x;
+    viewport->Height = (float)p.y;
+    updateMatrix();
+}
+
+// Setzt die Größe des Bildes auf dem Bildschirm
+//  br: Die Breite in Pixeln
+//  hö: Die Höhe in Pixeln
+void Kam3D::setBildschirmGröße( int br, int hö )
+{
+    viewport->Width = (float)br;
+    viewport->Height = (float)hö;
+    updateMatrix();
+}
+
+// Setzt die Welt, die gezeichnet werden soll
+//  w: Die Welt
+void Kam3D::setWelt( Welt3D *w )
+{
+    if( welt )
+        welt->release();
+    welt = w;
+}
+
+// Verarbeitet die vergangene Zeit
+//  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+//  return: true, wenn sich das Bild neu gezeichnet werden muss, false sonnst.
+bool Kam3D::tick( double tv )
+{
+    if( getTastenStand( T_Oben ) )
+        rotX -= (float)tv;
+    if( getTastenStand( T_Unten ) )
+        rotX += (float)tv;
+    if( getTastenStand( T_Links ) )
+        rotY -= (float)tv;
+    if( getTastenStand( T_Rechts ) )
+        rotY += (float)tv;
+    Vec3< float > n( 0, 0, 1 );
+    Vec3< float > n2( 1, 0, 0 );
+    Vec3< float > n3( 0, 1, 0 );
+    Mat4< float > tmp = tmp.rotationY( rotY ) * tmp.rotationX( rotX );
+    n = tmp * n;
+    n = n * (float)tv * 60;
+    n2 = tmp * n2;
+    n2 = n2 * (float)tv * 60;
+    n3 = tmp * n3;
+    n3 = n3 * (float)tv * 60;
+    if( getTastenStand( 'w' ) )
+        pos += n;
+    if( getTastenStand( 's' ) )
+        pos -= n;
+    if( getTastenStand( 'd' ) )
+        pos += n2;
+    if( getTastenStand( 'a' ) )
+        pos -= n2;
+    if( getTastenStand( ' ' ) )
+        pos += n3;
+    if( getTastenStand( T_Shift ) )
+        pos -= n3;
+    updateMatrix();
+    if( welt )
+        return welt->tick( tv );
+    return 0;
+}
+
+// Verarbeitet ein Mausereignis
+//  me: Das Mausereignis, das verarbeitet werden soll
+void Kam3D::doMausEreignis( MausEreignis &me )
+{
+
+}
+
+// Verarbeitet ein Tastaturereignis
+//  te: das Tastaturereignis, das verarbeitet werden soll
+void Kam3D::doTastaturEreignis( TastaturEreignis &te )
+{
+
+}
+
+// Zeichnet den Auschnitt der Welt, den die Kamera filmt
+//  zRObj: Das Render Objekt, mit dem gezeichnet werden soll
+void Kam3D::render( Render3D *zRObj )
+{
+    zRObj->zContext()->RSSetViewports( 1, viewport );
+    zRObj->setKameraMatrix( view, proj, pos );
+    if( welt )
+        welt->render( zRObj );
+}
+
+// Erhöht den Reference Counter um 1
+//  Return: Ein zeiger auf diesen Shader
+Kam3D *Kam3D::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+//  Return: 0
+Kam3D *Kam3D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 90 - 0
Kam3D.h

@@ -0,0 +1,90 @@
+#pragma once
+
+#include "Mat4.h"
+#include "Zeichnung3D.h"
+#include "Punkt.h"
+
+// DirectX 11 Types
+
+struct D3D11_VIEWPORT;
+
+namespace Framework
+{
+    class Render3D; // Render3D.h
+    class Welt3D; // Welt3D.h
+
+    class Kam3D
+    {
+    private:
+        Mat4< float > view;
+        Mat4< float > proj;
+
+        float öffnungswinkel;
+        float minZ;
+        float maxZ;
+        Vec3< float > pos;
+        float rotX;
+        float rotY;
+        float rotZ;
+
+        D3D11_VIEWPORT *viewport;
+        Welt3D *welt;
+        int ref;
+
+        // Aktualisiert die view und projektion matrizen
+        void updateMatrix();
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Kam3D();
+        // Destruktor
+        __declspec( dllexport ) ~Kam3D();
+        // Setzt die Position der Kamera in der 3D Welt
+        __declspec( dllexport ) void setPosition( Vec3< float > pos );
+        // zoomt heran, indem sich die Kamera etwas auf das Blickziel zubewegt
+        //  val: Die länge der Strecke um die sich die Kamera bewegen soll
+        __declspec( dllexport ) void scrollIn( float val );
+        // zppmt heraus, indem sich die Kamera etwas von dem Blockziel entfernt
+        //  val: Die länge der Strecke um die sich die Kamera bewegen soll
+        __declspec( dllexport ) void scrollOut( float val );
+        // Richtet die Kamera so aus, dass sie genau auf einen bestimmten Punkt zeigt
+        //  ziel: Der Punkt, auf den die Kamera zeigen soll
+        __declspec( dllexport ) void setAusrichtung( Vec3< float > ziel );
+        // Setzt die Position des Bildes auf dem Bildschirm
+        //  p: Ein Punkt mit x und y Koordinaten in Pixeln
+        __declspec( dllexport ) void setBildschirmPosition( Punkt p );
+        // Setzt die Position des Bildes auf dem Bildschirm
+        //  x: Die x Koordinate in Pixeln
+        //  y: Die y Koordinate in Pixeln
+        __declspec( dllexport ) void setBildschirmPosition( int x, int y );
+        // Setzt die Größe des Bildes auf dem Bildschirm
+        //  p: Ein Punkt, mit x als Breite und y als Höhe in Pixlen
+        __declspec( dllexport ) void setBildschirmGröße( Punkt p );
+        // Setzt die Größe des Bildes auf dem Bildschirm
+        //  br: Die Breite in Pixeln
+        //  hö: Die Höhe in Pixeln
+        __declspec( dllexport ) void setBildschirmGröße( int br, int hö );
+        // Setzt die Welt, die gezeichnet werden soll
+        //  w: Die Welt
+        __declspec( dllexport ) void setWelt( Welt3D *w );
+        // Verarbeitet die vergangene Zeit
+        //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+        //  return: true, wenn sich das Bild neu gezeichnet werden muss, false sonnst.
+        __declspec( dllexport ) bool tick( double tv );
+        // Verarbeitet ein Mausereignis
+        //  me: Das Mausereignis, das verarbeitet werden soll
+        __declspec( dllexport ) void doMausEreignis( MausEreignis &me );
+        // Verarbeitet ein Tastaturereignis
+        //  te: das Tastaturereignis, das verarbeitet werden soll
+        __declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te );
+        // Zeichnet den Auschnitt der Welt, den die Kamera filmt
+        //  zRObj: Das Render Objekt, mit dem gezeichnet werden soll
+        __declspec( dllexport ) void render( Render3D *zRObj );
+        // Erhöht den Reference Counter um 1
+        //  Return: Ein zeiger auf diesen Shader
+        __declspec( dllexport ) Kam3D *getThis();
+        // Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+        //  Return: 0
+        __declspec( dllexport ) Kam3D *release();
+    };
+}

+ 872 - 0
Knopf.cpp

@@ -0,0 +1,872 @@
+#include "Knopf.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Bild.h"
+#include "AlphaFeld.h"
+#include "Text.h"
+#include "Schrift.h"
+#include "Rahmen.h"
+#include "Scroll.h"
+#include "Datei.h"
+#include "DateiSystem.h"
+#include "Globals.h"
+#include "ToolTip.h"
+
+using namespace Framework;
+
+// Inhalt der Knopf Klasse aus Knopf.h
+// Konstruktor 
+Knopf::Knopf()
+    : TextFeld(),
+    klickFarbe( 0xFF000000 ),
+    klickBild( 0 ),
+    klickBuffer( 0 ),
+    klickIndex( 0 ),
+    ref( 1 )
+{
+    style = Style::Erlaubt | Style::Buffered | Style::KlickBuffer | Style::Rahmen;
+    this->setMausEreignis( _ret1ME );
+    setSchriftFarbe( 0xFFFFFFFF );
+    setSchriftGröße( 12 );
+    setLinienRahmenBreite( 2 );
+    setLinienRahmenFarbe( 0xFF00FF00 );
+    setAlphaFeldFarbe( 0x5500FF00 );
+    setAlphaFeldStärke( -5 );
+    setKBFarbe( 0xFF000000 );
+    setKBStärke( 20 );
+    addStyle( TextFeld::Style::Center | TextFeld::Style::Mehrfarbig );
+}
+
+// Destruktor 
+Knopf::~Knopf()
+{
+    if( klickBuffer )
+        klickBuffer->release();
+    if( klickBild )
+        klickBild->release();
+}
+
+// nicht constant 
+void Knopf::setKlickFarbe( int fc ) // setzt die Klick Farbe
+{
+    klickFarbe = fc;
+    rend = 1;
+}
+
+void Knopf::setKlickBild( Bild *bild ) // setzt das Klick Bild
+{
+    if( bild )
+    {
+        if( !klickBild )
+            klickBild = new Bild();
+        klickBild->neuBild( bild->getBreite(), bild->getHöhe(), 0 );
+        int *buff1 = klickBild->getBuffer();
+        int *buff2 = bild->getBuffer();
+        for( int i = 0; i < bild->getBreite() * bild->getHöhe(); ++i )
+            buff1[ i ] = buff2[ i ];
+        bild->release();
+        rend = 1;
+    }
+}
+
+void Knopf::setKlickBildZ( Bild *bild ) // setzt einen Zeiger zum Klick Bild
+{
+    if( klickBild )
+        klickBild->release();
+    klickBild = bild;
+    rend = 1;
+}
+
+void Knopf::setKBZ( AlphaFeld *af )
+{
+    if( klickBuffer )
+        klickBuffer->release();
+    klickBuffer = af;
+    rend = 1;
+}
+
+void Knopf::setKBStärke( int st ) // setzt die Stärke des Klick Buffers
+{
+    if( !klickBuffer )
+        klickBuffer = new AlphaFeld();
+    klickBuffer->setStärke( st );
+    rend = 1;
+}
+
+void Knopf::setKBFarbe( int fc ) // setzt die Farbe des Klick Buffers
+{
+    if( !klickBuffer )
+        klickBuffer = new AlphaFeld();
+    klickBuffer->setFarbe( fc );
+    rend = 1;
+}
+
+void Knopf::doMausEreignis( MausEreignis &me ) // Maus Ereignis
+{
+    bool nmakc = !me.verarbeitet;
+    if( hatStyleNicht( Style::Erlaubt ) || hatStyleNicht( Style::Sichtbar ) )
+    {
+        mausIn = 0;
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt && !me.verarbeitet )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    ++ref;
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+    {
+        if( me.id == ME_Betritt )
+        {
+            klickIndex = MausStand[ M_Links ];
+            if( klickIndex )
+                rend = 1;
+        }
+        if( me.id == ME_RLinks || me.id == ME_Verlässt )
+        {
+            if( klickIndex )
+                rend = 1;
+            klickIndex = 0;
+        }
+        if( !me.verarbeitet )
+        {
+            if( me.id == ME_PLinks )
+            {
+                klickIndex = 1;
+                rend = 1;
+            }
+            me.verarbeitet = 1;
+        }
+    }
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x, me.my += pos.y;
+    release();
+}
+
+void Knopf::render( Bild &zRObj ) // zeichenet nach zRObj
+{
+    if( !hatStyle( Style::Sichtbar ) )
+        return;
+    addStyle( TextFeld::Style::Center );
+    löscheStyle( Style::VScroll | Style::HScroll );
+    bool rA = 0;
+    if( !hatStyle( Style::Erlaubt ) )
+    {
+        zRObj.setAlpha( 0x20 );
+        rA = 1;
+    }
+    __super::render( zRObj );
+    if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+    {
+        if( rA )
+            zRObj.releaseAlpha();
+        return;
+    }
+    if( hatStyle( Style::Sichtbar ) && klickIndex == 1 )
+    {
+        if( hatStyle( Style::KlickFarbe ) )
+        {
+            if( hatStyle( Style::KlickAlpha ) )
+                zRObj.alphaRegion( 0, 0, innenGröße.x, innenGröße.y, klickFarbe );
+            else
+                zRObj.füllRegion( 0, 0, innenGröße.x, innenGröße.y, klickFarbe );
+        }
+        if( hatStyle( Style::KlickBild ) && klickBild )
+        {
+            if( hatStyle( Style::KlickAlpha ) )
+                zRObj.alphaBild( 0, 0, innenGröße.x, innenGröße.y, *klickBild );
+            else
+                zRObj.drawBild( 0, 0, innenGröße.x, innenGröße.y, *klickBild );
+        }
+        if( hatStyle( Style::KlickBuffer ) && klickBuffer )
+        {
+            klickBuffer->setGröße( innenGröße.x, innenGröße.y );
+            klickBuffer->render( zRObj );
+        }
+    }
+    if( rA )
+        zRObj.releaseAlpha();
+    zRObj.releaseDrawOptions();
+}
+
+// constant 
+int Knopf::getKlickFarbe() const // gibt getThis der Klick Farbe zurück
+{
+    return klickFarbe;
+}
+
+Bild *Knopf::getKlickBild() const // gibt getThis des Klick Bildes zurück
+{
+    if( !klickBild )
+        return 0;
+    return klickBild->getThis();
+}
+
+Bild *Knopf::zKlickBild() const // gibt einen Zeiger zum Klick Bild zurück
+{
+    return klickBild;
+}
+
+AlphaFeld *Knopf::getKB() const // gibt getThis des Klick Buffers zurück
+{
+    if( !klickBuffer )
+        return 0;
+    return klickBuffer->getThis();
+}
+
+AlphaFeld *Knopf::zKB() const // gibt den Klick Buffer zurück
+{
+    return klickBuffer;
+}
+
+int Knopf::getKBFarbe() const // gibt getThis der Farbe des Klick Buffers zurück
+{
+    if( !klickBuffer )
+        return 0;
+    return klickBuffer->getFarbe();
+}
+
+int Knopf::getKBStärke() const // gibt die Stärke des Klickbuffers zurück
+{
+    if( !klickBuffer )
+        return 0;
+    return klickBuffer->getStärke();
+}
+
+Zeichnung *Knopf::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+    Knopf *obj = new Knopf();
+    obj->setPosition( pos );
+    obj->setGröße( gr );
+    obj->setMausEreignisParameter( makParam );
+    obj->setTastaturEreignisParameter( takParam );
+    obj->setMausEreignis( Mak );
+    obj->setTastaturEreignis( Tak );
+    if( toolTip )
+        obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+    obj->setStyle( style );
+    obj->setSchriftGröße( getSchriftGröße() );
+    if( zSchrift() )
+        obj->setSchriftZ( getSchrift() );
+    if( zText() )
+        obj->setText( zText()->getText() );
+    obj->setHintergrundFarbe( hintergrundFarbe );
+    obj->setSchriftFarbe( getSchriftFarbe() );
+    if( hintergrundFeld )
+        obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+    if( rahmen )
+        obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+    if( hintergrundBild )
+        obj->setHintergrundBild( hintergrundBild->getThis() );
+    if( vertikalScrollBar )
+    {
+        obj->setVertikalKlickScroll( vertikalScrollBar->getKlickScroll() );
+        obj->setVertikalScrollPos( vertikalScrollBar->getScroll() );
+        obj->setVertikalScrollFarbe( vertikalScrollBar->getFarbe(), vertikalScrollBar->getBgFarbe() );
+    }
+    if( horizontalScrollBar )
+    {
+        obj->setHorizontalKlickScroll( horizontalScrollBar->getKlickScroll() );
+        obj->setHorizontalScrollPos( horizontalScrollBar->getScroll() );
+        obj->setHorizontalScrollFarbe( horizontalScrollBar->getFarbe(), horizontalScrollBar->getBgFarbe() );
+    }
+    obj->setSchowChar( getShowChar() );
+    obj->setAuswahl( getFärbungPos(), getCursorPos() );
+    obj->setKlickFarbe( klickFarbe );
+    if( klickBild )
+        obj->setKlickBild( klickBild->getThis() );
+    if( klickBuffer )
+        obj->setKBZ( (AlphaFeld*)klickBuffer->dublizieren() );
+    return obj;
+}
+
+// Reference Counting 
+Knopf *Knopf::getThis()
+{
+    ++ref;
+    return this;
+}
+
+Knopf *Knopf::release()
+{
+    --ref;
+    if( ref == 0 )
+        delete this;
+    return 0;
+}
+
+// Inhalt der KontrollKnopf Klasse aus Knopf.h
+// Konstruktor 
+KontrollKnopf::KontrollKnopf()
+    : ZeichnungHintergrund(),
+    txt( 0 ),
+    sTxt( 0 ),
+    sBgF( 0 ),
+    kBgF( 0 ),
+    sBgB( 0 ),
+    kBgB( 0 ),
+    sAf( 0 ),
+    kAf( 0 ),
+    kasten( 0 ),
+    sKasten( 0 ),
+    schrift( 0 ),
+    sF( 0xFFFFFFFF ),
+    sGr( 12 ),
+    ref( 1 )
+{
+    style = Style::Erlaubt | Style::KlickBuffer;
+    setKAFFarbe( 0x00007500 );
+    setKAFStärke( -30 );
+}
+
+// Destruktor 
+KontrollKnopf::~KontrollKnopf()
+{
+    if( txt )
+        txt->release();
+    if( sTxt )
+        sTxt->release();
+    if( sBgB )
+        sBgB->release();
+    if( kBgB )
+        kBgB->release();
+    if( sAf )
+        sAf->release();
+    if( kAf )
+        kAf->release();
+    if( kasten )
+        kasten->release();
+    if( sKasten )
+        sKasten->release();
+    if( schrift )
+        schrift->release();
+}
+
+// nicht constant 
+void KontrollKnopf::setTextZ( Text *txt ) // setzt den Text
+{
+    if( this->txt )
+        this->txt->release();
+    this->txt = txt;
+    rend = 1;
+}
+
+void KontrollKnopf::setText( Text *txt )
+{
+    if( !this->txt )
+        this->txt = new Text();
+    this->txt->setText( txt->getText() );
+    txt->release();
+    rend = 1;
+}
+
+void KontrollKnopf::setText( const char *txt )
+{
+    if( !this->txt )
+        this->txt = new Text();
+    this->txt->setText( txt );
+    rend = 1;
+}
+
+void KontrollKnopf::setSTextZ( Text *txt ) // setzt den Text bei Selectiert
+{
+    if( sTxt )
+        sTxt->release();
+    sTxt = txt;
+    rend = 1;
+}
+
+void KontrollKnopf::setSText( Text *txt )
+{
+    if( !sTxt )
+        sTxt = new Text();
+    sTxt->setText( txt->getText() );
+    txt->release();
+    rend = 1;
+}
+
+void KontrollKnopf::setSText( const char *txt )
+{
+    if( !sTxt )
+        sTxt = new Text();
+    sTxt->setText( txt );
+    rend = 1;
+}
+
+void KontrollKnopf::setSchriftZ( Schrift *schrift ) // setzt die Schrift
+{
+    if( this->schrift )
+        this->schrift->release();
+    this->schrift = schrift;
+    rend = 1;
+}
+
+void KontrollKnopf::setSFarbe( int f ) // setzt die Schrift Farbe
+{
+    sF = f;
+    rend = 1;
+}
+
+void KontrollKnopf::setSGröße( int gr ) // setzt die Schrift Größe
+{
+    sGr = gr;
+    rend = 1;
+}
+
+void KontrollKnopf::setSBgFarbe( int f ) // setzt die Select Hintergrundfarbe
+{
+    sBgF = f;
+    rend = 1;
+}
+
+void KontrollKnopf::setKBgFarbe( int f ) // setzt die Klick Hintergrundfarbe
+{
+    kBgF = f;
+    rend = 1;
+}
+
+void KontrollKnopf::setSBgBildZ( Bild *b ) // setzt das Select Hintergrundbild
+{
+    if( sBgB )
+        sBgB->release();
+    sBgB = b;
+    rend = 1;
+}
+
+void KontrollKnopf::setSBgBild( Bild *b )
+{
+    if( !sBgB )
+        sBgB = new Bild();
+    sBgB->neuBild( b->getBreite(), b->getHöhe(), 0 );
+    sBgB->drawBild( 0, 0, b->getBreite(), b->getHöhe(), *b );
+    b->release();
+    rend = 1;
+}
+
+void KontrollKnopf::setKBgBildZ( Bild *b ) // setzt das Klick Hintergrundbild
+{
+    if( kBgB )
+        kBgB->release();
+    kBgB = b;
+    rend = 1;
+}
+
+void KontrollKnopf::setKBgBild( Bild *b )
+{
+    if( !kBgB )
+        kBgB = new Bild();
+    kBgB->neuBild( b->getBreite(), b->getHöhe(), 0 );
+    kBgB->drawBild( 0, 0, b->getBreite(), b->getHöhe(), *b );
+    b->release();
+    rend = 1;
+}
+
+void KontrollKnopf::setSAlphaFeldZ( AlphaFeld *af ) // setzt das Select Alpha Feld
+{
+    if( sAf )
+        sAf->release();
+    sAf = af;
+    rend = 1;
+}
+
+void KontrollKnopf::setSAFFarbe( int f ) // setzt die Select Alphafeld Farbe
+{
+    if( !sAf )
+        sAf = new AlphaFeld();
+    sAf->setFarbe( f );
+    rend = 1;
+}
+
+void KontrollKnopf::setSAFStärke( int st ) // setzt die Select AlphaFeld Stärke
+{
+    if( !sAf )
+        sAf = new AlphaFeld();
+    sAf->setStärke( st );
+    rend = 1;
+}
+
+void KontrollKnopf::setKAlphaFeldZ( AlphaFeld *af ) // setzt das Klick Alpha Feld
+{
+    if( kAf )
+        kAf->release();
+    kAf = af;
+    rend = 1;
+}
+
+void KontrollKnopf::setKAFFarbe( int f ) // setzt die Klick Alphafeld Farbe
+{
+    if( !kAf )
+        kAf = new AlphaFeld();
+    kAf->setFarbe( f );
+    rend = 1;
+}
+
+void KontrollKnopf::setKAFStärke( int st ) // setzt die Klick AlphaFeld Stärke
+{
+    if( !kAf )
+        kAf = new AlphaFeld();
+    kAf->setStärke( st );
+    rend = 1;
+}
+
+void KontrollKnopf::loadData( LTDBDatei *dat ) // läht die Systembilder
+{
+    if( DateiExistiert( new Text( "data/normal.ltdb" ) ) && ( !dat || !dat->istOffen() ) )
+    {
+        LTDBDatei *dat = new LTDBDatei();
+        dat->setDatei( new Text( "data/normal.ltdb" ) );
+        dat->leseDaten( 0 );
+        kasten = dat->laden( 0, new Text( "kasten.gif" ) );
+        sKasten = dat->laden( 0, new Text( "skasten.gif" ) );
+        dat->release();
+    }
+    else
+    {
+        kasten = dat->laden( 0, new Text( "kasten.gif" ) );
+        sKasten = dat->laden( 0, new Text( "skasten.gif" ) );
+    }
+    rend = 1;
+}
+
+void KontrollKnopf::loadData( const char *ltdb ) // läht die Systembilder
+{
+    if( DateiExistiert( new Text( ltdb ) ) )
+    {
+        LTDBDatei *dat = new LTDBDatei();
+        dat->setDatei( new Text( ltdb ) );
+        dat->leseDaten( 0 );
+        kasten = dat->laden( 0, new Text( "kasten.gif" ) );
+        sKasten = dat->laden( 0, new Text( "skasten.gif" ) );
+        dat->release();
+        rend = 1;
+    }
+}
+
+void KontrollKnopf::doMausEreignis( MausEreignis &me ) // Nachrichten verarbeitung
+{
+    bool nmakc = !me.verarbeitet;
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        style &= ~Style::MausKlick;
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    if( hatStyleNicht( TextFeld::Style::Erlaubt ) || hatStyleNicht( TextFeld::Style::Sichtbar ) )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+    {
+        if( me.id == ME_Betritt && hatStyle( Style::MausKlick ) != MausStand[ M_Links ] )
+            setStyle( Style::MausKlick, MausStand[ M_Links ] );
+        if( !me.verarbeitet && me.id == ME_PLinks )
+            addStyle( Style::MausKlick );
+        if( me.id == ME_RLinks )
+        {
+            löscheStyle( Style::MausKlick );
+            setStyle( Style::Selected, !hatStyle( Style::Selected ) );
+        }
+        me.verarbeitet = 1;
+    }
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void KontrollKnopf::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+    if( !hatStyle( Style::Sichtbar ) )
+        return;
+    löscheStyle( Style::VScroll | Style::HScroll );
+    __super::render( zRObj );
+    lockZeichnung();
+    if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+    {
+        unlockZeichnung();
+        return;
+    }
+    if( hatStyle( Style::MausKlick ) )
+    {
+        if( hatStyle( Style::KlickFarbe ) )
+        {
+            if( hatStyle( Style::KlickAlpha ) )
+                zRObj.alphaRegion( 0, 0, innenGröße.x, innenGröße.y, kBgF );
+            else
+                zRObj.füllRegion( 0, 0, innenGröße.x, innenGröße.y, kBgF );
+        }
+        if( hatStyle( Style::KlickBild ) && kBgB )
+        {
+            if( hatStyle( Style::KlickAlpha ) )
+                zRObj.alphaBild( 0, 0, innenGröße.x, innenGröße.y, *kBgB );
+            else
+                zRObj.drawBild( 0, 0, innenGröße.x, innenGröße.y, *kBgB );
+        }
+        if( hatStyle( Style::KlickBuffer ) && kAf )
+        {
+            kAf->setGröße( innenGröße.x, innenGröße.y );
+            kAf->render( zRObj );
+        }
+        int kbr = 0;
+        if( hatStyle( Style::Selected ) && sKasten )
+        {
+            if( sTxt && schrift )
+                zRObj.drawBild( 0, ( gr.y / 2 - sKasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - sKasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *sKasten );
+            else
+                zRObj.drawBild( gr.x / 2 - sKasten->getBreite() / 2, ( gr.y / 2 - sKasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - sKasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *sKasten );
+            kbr = sKasten->getBreite();
+            if( sTxt && schrift )
+            {
+                schrift->setSchriftGröße( sGr );
+                schrift->setDrawPosition( kbr + 5, gr.y / 2 - schrift->getTextHöhe( sTxt ) / 2 );
+                schrift->renderText( sTxt, zRObj, sF );
+            }
+        }
+        else if( kasten )
+        {
+            if( txt && schrift )
+                zRObj.drawBild( 0, ( gr.y / 2 - kasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - kasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *kasten );
+            else
+                zRObj.drawBild( gr.x / 2 - kasten->getBreite() / 2, ( gr.y / 2 - kasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - kasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *kasten );
+            kbr = kasten->getBreite();
+            if( txt && schrift )
+            {
+                schrift->setSchriftGröße( sGr );
+                schrift->setDrawPosition( kbr + 5, gr.y / 2 - schrift->getTextHöhe( txt ) / 2 );
+                schrift->renderText( txt, zRObj, sF );
+            }
+        }
+    }
+    else if( hatStyle( Style::Selected ) )
+    {
+        if( hatStyle( Style::SelectFarbe ) )
+        {
+            if( hatStyle( Style::SelectAlpha ) )
+                zRObj.alphaRegion( 0, 0, innenGröße.x, innenGröße.y, sBgF );
+            else
+                zRObj.füllRegion( 0, 0, innenGröße.x, innenGröße.y, sBgF );
+        }
+        if( hatStyle( Style::SelectBild ) && sBgB )
+        {
+            if( hatStyle( Style::SelectAlpha ) )
+                zRObj.alphaBild( 0, 0, innenGröße.x, innenGröße.y, *sBgB );
+            else
+                zRObj.drawBild( 0, 0, innenGröße.x, innenGröße.y, *sBgB );
+        }
+        if( hatStyle( Style::SelectBuffer ) && sAf )
+        {
+            sAf->setGröße( innenGröße.x, innenGröße.y );
+            sAf->render( zRObj );
+        }
+        int kbr = 0;
+        if( sKasten )
+        {
+            if( sTxt && schrift )
+                zRObj.drawBild( 0, ( gr.y / 2 - sKasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - sKasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *sKasten );
+            else
+                zRObj.drawBild( gr.x / 2 - sKasten->getBreite() / 2, ( gr.y / 2 - sKasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - sKasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *sKasten );
+            kbr = sKasten->getBreite();
+        }
+        if( sTxt && schrift )
+        {
+            schrift->setSchriftGröße( sGr );
+            schrift->setDrawPosition( kbr + 5, gr.y / 2 - schrift->getTextHöhe( sTxt ) / 2 );
+            schrift->renderText( sTxt, zRObj, sF );
+        }
+    }
+    else
+    {
+        int kbr = 0;
+        if( kasten )
+        {
+            if( txt && schrift )
+                zRObj.drawBild( 0, ( gr.y / 2 - kasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - kasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *kasten );
+            else
+                zRObj.drawBild( gr.x / 2 - kasten->getBreite() / 2, ( gr.y / 2 - kasten->getHöhe() / 2 ) < 0 ? 0 : ( gr.y / 2 - kasten->getHöhe() / 2 ), innenGröße.x, innenGröße.y, *kasten );
+            kbr = kasten->getBreite();
+        }
+        if( txt && schrift )
+        {
+            schrift->setSchriftGröße( sGr );
+            schrift->setDrawPosition( kbr + 5, gr.y / 2 - schrift->getTextHöhe( txt ) / 2 );
+            schrift->renderText( txt, zRObj, sF );
+        }
+    }
+    zRObj.releaseDrawOptions();
+    unlockZeichnung();
+}
+
+// constant 
+Text *KontrollKnopf::getText() const // gibt den Text zurück
+{
+    return txt ? txt->getThis() : 0;
+}
+
+Text *KontrollKnopf::zText() const
+{
+    return txt;
+}
+
+Text *KontrollKnopf::getSText() const // gibt den Select Text zurück
+{
+    return sTxt ? sTxt->getThis() : 0;
+}
+
+Text *KontrollKnopf::zSText() const
+{
+    return sTxt;
+}
+
+Schrift *KontrollKnopf::getSchrift() const // gibt die Schrift zurück
+{
+    return schrift ? schrift->getThis() : 0;
+}
+
+Schrift *KontrollKnopf::zSchrift() const
+{
+    return schrift;
+}
+
+int KontrollKnopf::getSFarbe() const // gibt die Schrift Farbe zurück
+{
+    return sF;
+}
+
+int KontrollKnopf::getSGröße() const // gibt die Schrift Größe zurück
+{
+    return sGr;
+}
+
+int KontrollKnopf::getSBgFarbe() const// gibt die Select Hintergrundfarbe zurück
+{
+    return sBgF;
+}
+
+int KontrollKnopf::getKBgFarbe() const // gibt die Klick Hintergrundfarbe zurück
+{
+    return kBgF;
+}
+
+Bild *KontrollKnopf::getSBgBild() const // gibt das Select Hintergrundbild zurück
+{
+    return sBgB ? sBgB->getThis() : 0;
+}
+
+Bild *KontrollKnopf::zSBgBild() const
+{
+    return sBgB;
+}
+
+Bild *KontrollKnopf::getKBgBild() const // gibt das Klick Hintergrundbild zurück
+{
+    return kBgB ? kBgB->getThis() : 0;
+}
+
+Bild *KontrollKnopf::zKBgBild() const
+{
+    return kBgB;
+}
+
+AlphaFeld *KontrollKnopf::getSAlphaFeld() const // gibt das Select AlphaFeld zurück
+{
+    return sAf ? sAf->getThis() : 0;
+}
+
+AlphaFeld *KontrollKnopf::zSAlphaFeld() const
+{
+    return sAf;
+}
+
+AlphaFeld *KontrollKnopf::getKAlphaFeld() const // gibt das Klick AlphaFeld zurück
+{
+    if( !kAf )
+        return 0;
+    return kAf->release();
+}
+
+AlphaFeld *KontrollKnopf::zKAlphaFeld() const
+{
+    return kAf;
+}
+
+// Reference Counting 
+KontrollKnopf *KontrollKnopf::getThis()
+{
+    ++ref;
+    return this;
+}
+
+KontrollKnopf *KontrollKnopf::release()
+{
+    --ref;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 164 - 0
Knopf.h

@@ -0,0 +1,164 @@
+#ifndef Knopf_H
+#define Knopf_H
+
+#include "TextFeld.h"
+
+namespace Framework
+{
+	class TextFeld; // TextFeld.h
+	class AlphaFeld; // AlphaFeld.h
+	class Text; // Text.h
+	class Schrift; // Schrift.h
+	class LRahmen; // Rahmen.h
+	class LTDBDatei; // Dateisystem.h
+	class Knopf; // aus dieser Datei
+	class KontrollKnopf; // aus dieser Datei
+
+	class Knopf : public TextFeld
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 MehrfarbigText = 0x0010000;
+            const static __int64 KlickFarbe = 0x0020000;
+            const static __int64 KlickBild = 0x0040000;
+            const static __int64 KlickAlpha = 0x0080000;
+            const static __int64 KlickBuffer = 0x0100000;
+
+            const static __int64 Normal = Sichtbar | Erlaubt | Rahmen | Buffered | MehrfarbigText | KlickBuffer;
+        };
+
+	private:
+		int klickFarbe;
+		Bild *klickBild;
+		AlphaFeld *klickBuffer;
+		int klickIndex;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Knopf();
+		// Destruktor 
+		__declspec( dllexport ) ~Knopf();
+		// nicht constant 
+		__declspec( dllexport ) void setKlickFarbe( int fc ); // setzt die Klick Farbe
+		__declspec( dllexport ) void setKlickBild( Bild *bild ); // setzt das Klick Bild
+		__declspec( dllexport ) void setKlickBildZ( Bild *bild ); // setzt einen Zeiger zum Klick Bild
+		__declspec( dllexport ) void setKBZ( AlphaFeld *af );
+		__declspec( dllexport ) void setKBStärke( int st ); // setzt die Stärke des Klick Buffers
+		__declspec( dllexport ) void setKBFarbe( int fc ); // setzt die Farbe des Klick Buffers
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override; // Maus Ereignis
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichenet nach zRObj
+		// constant 
+		__declspec( dllexport ) int getKlickFarbe() const; // gibt getThis der Klick Farbe zurück
+		__declspec( dllexport ) Bild *getKlickBild() const; // gibt getThis des Klick Bildes zurück
+		__declspec( dllexport ) Bild *zKlickBild() const; // gibt einen Zeiger zum Klick Bild zurück
+		__declspec( dllexport ) AlphaFeld *getKB() const; // gibt getThis des Klick Buffers zurück
+		__declspec( dllexport ) AlphaFeld *zKB() const; // gibt den Klick Buffer zurück
+		__declspec( dllexport ) int getKBFarbe() const; // gibt getThis der Farbe des Klick Buffers zurück
+		__declspec( dllexport ) int getKBStärke() const; // gibt die Stärke des Klickbuffers zurück
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Erzeugt eine Kopie des Zeichnungs
+		// Reference Counting 
+		__declspec( dllexport ) Knopf *getThis();
+		__declspec( dllexport ) Knopf *release();
+	};
+
+	class KontrollKnopf : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 Selected = 0x00080;
+
+            const static __int64 MehrfarbigText = 0x001000;
+            const static __int64 KlickFarbe = 0x002000;
+            const static __int64 KlickBild = 0x004000;
+            const static __int64 KlickAlpha = 0x008000;
+            const static __int64 KlickBuffer = 0x010000;
+            const static __int64 SelectFarbe = 0x020000;
+            const static __int64 SelectBild = 0x040000;
+            const static __int64 SelectAlpha = 0x080000;
+            const static __int64 SelectBuffer = 0x100000;
+            const static __int64 SelectText = 0x200000;
+            const static __int64 MehrzeiligText = 0x400000;
+
+            const static __int64 MausKlick = 0x800000;
+
+            const static __int64 Normal = Sichtbar | Erlaubt | Rahmen | KlickBuffer;
+        };
+
+	private:
+		Text *txt;
+		Text *sTxt;
+		int sBgF;
+		int kBgF;
+		Bild *sBgB;
+		Bild *kBgB;
+		AlphaFeld *sAf;
+		AlphaFeld *kAf;
+		Bild *kasten;
+		Bild *sKasten;
+		Schrift *schrift;
+		int sF;
+		int sGr;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) KontrollKnopf();
+		// Destruktor 
+		__declspec( dllexport ) ~KontrollKnopf();
+		// nicht constant 
+		__declspec( dllexport ) void setTextZ( Text *txt ); // setzt den Text
+		__declspec( dllexport ) void setText( Text *txt );
+		__declspec( dllexport ) void setText( const char *txt );
+		__declspec( dllexport ) void setSTextZ( Text *txt ); // setzt den Text bei Selectiert
+		__declspec( dllexport ) void setSText( Text *txt );
+		__declspec( dllexport ) void setSText( const char *txt );
+		__declspec( dllexport ) void setSchriftZ( Schrift *schrift ); // setzt die Schrift
+		__declspec( dllexport ) void setSFarbe( int f ); // setzt die Schrift Farbe
+		__declspec( dllexport ) void setSGröße( int gr ); // setzt die Schrift Größe
+		__declspec( dllexport ) void setSBgFarbe( int f ); // setzt die Select Hintergrundfarbe
+		__declspec( dllexport ) void setKBgFarbe( int f ); // setzt die Klick Hintergrundfarbe
+		__declspec( dllexport ) void setSBgBildZ( Bild *b ); // setzt das Select Hintergrundbild
+		__declspec( dllexport ) void setSBgBild( Bild *b );
+		__declspec( dllexport ) void setKBgBildZ( Bild *b ); // setzt das Klick Hintergrundbild
+		__declspec( dllexport ) void setKBgBild( Bild *b );
+		__declspec( dllexport ) void setSAlphaFeldZ( AlphaFeld *af ); // setzt das Select Alpha Feld
+		__declspec( dllexport ) void setSAFFarbe( int f ); // setzt die Select Alphafeld Farbe
+		__declspec( dllexport ) void setSAFStärke( int st ); // setzt die Select AlphaFeld Stärke
+		__declspec( dllexport ) void setKAlphaFeldZ( AlphaFeld *af ); // setzt das Klick Alpha Feld
+		__declspec( dllexport ) void setKAFFarbe( int f ); // setzt die Klick Alphafeld Farbe
+		__declspec( dllexport ) void setKAFStärke( int st ); // setzt die Klick AlphaFeld Stärke
+		__declspec( dllexport ) void loadData( LTDBDatei *zDat ); // läht die Systembilder
+		__declspec( dllexport ) void loadData( const char *ltdb );
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override; // Nachrichten verarbeitung
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) Text *getText() const; // gibt den Text zurück
+		__declspec( dllexport ) Text *zText() const;
+		__declspec( dllexport ) Text *getSText() const; // gibt den Select Text zurück
+		__declspec( dllexport ) Text *zSText() const;
+		__declspec( dllexport ) Schrift *getSchrift() const; // gibt die Schrift zurück
+		__declspec( dllexport ) Schrift *zSchrift() const;
+		__declspec( dllexport ) int getSFarbe() const; // gibt die Schrift Farbe zurück
+		__declspec( dllexport ) int getSGröße() const; // gibt die Schrift Größe zurück
+		__declspec( dllexport ) int getSBgFarbe() const;// gibt die Select Hintergrundfarbe zurück
+		__declspec( dllexport ) int getKBgFarbe() const; // gibt die Klick Hintergrundfarbe zurück
+		__declspec( dllexport ) Bild *getSBgBild() const; // gibt das Select Hintergrundbild zurück
+		__declspec( dllexport ) Bild *zSBgBild() const;
+		__declspec( dllexport ) Bild *getKBgBild() const; // gibt das Klick Hintergrundbild zurück
+		__declspec( dllexport ) Bild *zKBgBild() const;
+		__declspec( dllexport ) AlphaFeld *getSAlphaFeld() const; // gibt das Select AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zSAlphaFeld() const;
+		__declspec( dllexport ) AlphaFeld *getKAlphaFeld() const; // gibt das Klick AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zKAlphaFeld() const;
+		// Reference Counting 
+		__declspec( dllexport ) KontrollKnopf *getThis();
+		__declspec( dllexport ) KontrollKnopf *release();
+	};
+}
+
+#endif

+ 1040 - 0
Liste.cpp

@@ -0,0 +1,1040 @@
+#include "Liste.h"
+#include "Array.h"
+#include "Rahmen.h"
+#include "Bild.h"
+#include "AlphaFeld.h"
+#include "TextFeld.h"
+#include "Text.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Scroll.h"
+#include "Globals.h"
+#include "Schrift.h"
+
+using namespace Framework;
+
+// Inhalt der AuswahlListe Klasse aus Liste.h
+// Konstruktor 
+AuswahlListe::AuswahlListe()
+    : ZeichnungHintergrund(),
+    tfListe( 0 ),
+    einträge( 0 ),
+    auswahl( -1 ),
+    ahFarbe( 0xFF000000 ),
+    ahBild( 0 ),
+    aBuffer( 0 ),
+    aRahmen( 0 ),
+    styles( 0 ),
+    ahFarbeListe( 0 ),
+    ahBildListe( 0 ),
+    aBufferListe( 0 ),
+    aRahmenListe( 0 ),
+    schrift( 0 ),
+    ref( 1 )
+{
+    style = 0;
+    this->setMausEreignis( _ret1ME );
+    this->setTastaturEreignis( _ret1TE );
+    ref = 1;
+}
+
+// Destruktor 
+AuswahlListe::~AuswahlListe()
+{
+    if( tfListe )
+        tfListe->release();
+    if( ahBild )
+        ahBild->release();
+    if( aBuffer )
+        aBuffer->release();
+    if( aRahmen )
+        aRahmen->release();
+    if( styles )
+        styles->release();
+    if( ahFarbeListe )
+        ahFarbeListe->release();
+    if( ahBildListe )
+        ahBildListe->release();
+    if( aBufferListe )
+        aBufferListe->release();
+    if( aRahmenListe )
+        aRahmenListe->release();
+    if( schrift )
+        schrift->release();
+}
+
+// nicht constant 
+void AuswahlListe::update() // aktualisiert die Auswahl Liste
+{
+    int rbr = 0;
+    if( rahmen )
+    {
+        rbr = rahmen->getRBreite();
+        rahmen->setPosition( 0, 0 );
+        rahmen->setGröße( gr.x, gr.y );
+    }
+    if( hintergrundFeld )
+    {
+        hintergrundFeld->setPosition( rbr, rbr );
+        hintergrundFeld->setGröße( gr.x - rbr * 2, gr.y - rbr * 2 );
+    }
+    if( hatStyleNicht( Style::MultiStyled ) && tfListe )
+    {
+        bool FeldRahmen = hatStyle( Style::FeldRahmen );
+        bool FeldHintergrund = hatStyle( Style::FeldHintergrund );
+        bool FeldHBild = hatStyle( Style::FeldHBild );
+        bool FeldHAlpha = hatStyle( Style::FeldHAlpha );
+        bool FeldBuffer = hatStyle( Style::FeldBuffer );
+        for( int i = 0; i < einträge; ++i )
+        {
+            TextFeld *tf = tfListe->z( i );
+            tf->setStyle( TextFeld::Style::Rahmen, FeldRahmen );
+            tf->setStyle( TextFeld::Style::Hintergrund, FeldHintergrund );
+            tf->setStyle( TextFeld::Style::HBild, FeldHBild );
+            tf->setStyle( TextFeld::Style::HAlpha, FeldHAlpha );
+            tf->setStyle( TextFeld::Style::Buffered, FeldBuffer );
+            if( schrift )
+                tf->setSchriftZ( schrift->getThis() );
+        }
+    }
+    if( hatStyle( Style::MultiStyled ) && tfListe && styles )
+    {
+        for( int i = 0; i < einträge; ++i )
+        {
+            TextFeld *tf = tfListe->z( i );
+            tf->setStyle( TextFeld::Style::Rahmen, hatMsStyle( i, Style::FeldRahmen ) );
+            tf->setStyle( TextFeld::Style::Hintergrund, hatMsStyle( i, Style::FeldHintergrund ) );
+            tf->setStyle( TextFeld::Style::HBild, hatMsStyle( i, Style::FeldHBild ) );
+            tf->setStyle( TextFeld::Style::HAlpha, hatMsStyle( i, Style::FeldHAlpha ) );
+            tf->setStyle( TextFeld::Style::Buffered, hatMsStyle( i, Style::FeldBuffer ) );
+        }
+    }
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( Text *txt ) // fügt einen Eintrag hinzu
+{
+    TextFeld *tf = new TextFeld();
+    tf->setStyle( TextFeld::Style::Center | TextFeld::Style::Sichtbar | TextFeld::Style::Mehrfarbig | TextFeld::Style::Rahmen );
+    tf->setSchriftFarbe( 0xFFFFFFFF );
+    tf->setLinienRahmenBreite( 1 );
+    tf->setLinienRahmenFarbe( 0xFFFFFFFF );
+    tf->setTextZ( txt );
+    tf->setGröße( 0, 20 );
+    addEintrag( tf );
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( const char *txt )
+{
+    Text *tx = new Text( txt );
+    addEintrag( tx );
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( TextFeld *tf )
+{
+    if( !tfListe )
+        tfListe = new RCArray< TextFeld >();
+    if( schrift && ( !tf->zSchrift() || hatStyleNicht( Style::MultiStyled ) ) )
+        tf->setSchriftZ( schrift->getThis() );
+    tfListe->set( tf, einträge );
+    ++einträge;
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( int pos, Text *txt ) // fügt einen Eintrag bei position pos ein
+{
+    TextFeld *tf = new TextFeld();
+    tf->setStyle( TextFeld::Style::Center | TextFeld::Style::Sichtbar | TextFeld::Style::Mehrfarbig | TextFeld::Style::Rahmen );
+    tf->setSchriftFarbe( 0xFFFFFFFF );
+    tf->setLinienRahmenBreite( 1 );
+    tf->setLinienRahmenFarbe( 0xFFFFFFFF );
+    tf->setTextZ( txt );
+    tf->setGröße( 0, 20 );
+    addEintrag( pos, tf );
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( int pos, const char *txt )
+{
+    Text *tx = new Text( txt );
+    addEintrag( pos, tx );
+    rend = 1;
+}
+
+void AuswahlListe::addEintrag( int pos, TextFeld *tf )
+{
+    if( !tfListe )
+        tfListe = new RCArray< TextFeld >();
+    if( schrift && ( !tf->zSchrift() || hatStyleNicht( Style::MultiStyled ) ) )
+        tf->setSchriftZ( schrift->getThis() );
+    tfListe->add( tf, pos );
+    ++einträge;
+    rend = 1;
+}
+
+void AuswahlListe::setEintrag( int pos, Text *txt ) // ändert den pos - ten Eintrag
+{
+    TextFeld *tf = 0;
+    if( tfListe )
+        tf = tfListe->z( pos );
+    if( !tf )
+    {
+        tf = new TextFeld();
+        tf->setStyle( TextFeld::Style::Center | TextFeld::Style::Sichtbar | TextFeld::Style::Mehrfarbig | TextFeld::Style::Rahmen );
+        tf->setSchriftFarbe( 0xFFFFFFFF );
+        tf->setLinienRahmenFarbe( 0xFFFFFFFF );
+        tf->setLinienRahmenBreite( 1 );
+        tf->setTextZ( txt );
+        tf->setGröße( 0, 20 );
+        setEintrag( pos, tf );
+        rend = 1;
+        return;
+    }
+    tf->setTextZ( txt );
+    rend = 1;
+}
+
+void AuswahlListe::setEintrag( int pos, unsigned char *txt )
+{
+    Text *tx = new Text( (const char*)txt );
+    setEintrag( pos, tx );
+    rend = 1;
+}
+
+void AuswahlListe::setEintrag( int pos, TextFeld *tf )
+{
+    if( !tfListe )
+        tfListe = new RCArray< TextFeld >();
+    if( schrift && ( !tf->zSchrift() || hatStyleNicht( Style::MultiStyled ) ) )
+        tf->setSchriftZ( schrift->getThis() );
+    tfListe->set( tf, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setEintragPos( int vpos, int npos ) // taucht den Eintrag vpos mit dem Eintrag npos
+{
+    if( tfListe )
+    {
+        tfListe->tausch( vpos, npos );
+        if( styles )
+            styles->tausch( vpos, npos );
+        if( ahFarbeListe )
+            ahFarbeListe->tausch( vpos, npos );
+        if( ahBildListe )
+            ahBildListe->tausch( vpos, npos );
+        if( aBufferListe )
+            aBufferListe->tausch( vpos, npos );
+        if( aRahmenListe )
+            aRahmenListe->tausch( vpos, npos );
+        rend = 1;
+    }
+}
+
+void AuswahlListe::löscheEintrag( int pos ) // löscht den Eintrag pos
+{
+    tfListe->lösche( pos );
+    --einträge;
+    rend = 1;
+}
+
+void AuswahlListe::setSchriftZ( Schrift *schrift ) // legt die Schrift der Einträge fest
+{
+    if( this->schrift )
+        this->schrift->release();
+    this->schrift = schrift;
+    rend = 1;
+}
+
+void AuswahlListe::setVScrollZuEintrag( int eintrag ) // scrollt zum Eintrag
+{
+    if( vertikalScrollBar )
+    {
+        if( eintrag < einträge )
+            eintrag = einträge - 1;
+        int y = 0;
+        for( int i = 0; i < eintrag; i++ )
+            y += tfListe->z( i ) ? tfListe->z( i )->getHöhe() : 0;
+        vertikalScrollBar->scroll( y );
+    }
+}
+
+void AuswahlListe::updateVScroll() // scrollt zur Curser Position oder nach Unten
+{
+    if( vertikalScrollBar )
+    {
+        int y = 0;
+        for( int i = 0; i < einträge; i++ )
+            y += tfListe->z( i ) ? tfListe->z( i )->getHöhe() : 0;
+        vertikalScrollBar->update( y, gr.y - ( ( rahmen && hatStyle( TextFeld::Style::Rahmen ) ) ? rahmen->getRBreite() : 0 ) );
+    }
+}
+
+void AuswahlListe::setALRZ( LRahmen *rahmen ) // setzt einen Zeiger zum Auswahl Rahmen (nur ohne MulitStyled)
+{
+    if( aRahmen )
+        aRahmen->release();
+    aRahmen = rahmen;
+    rend = 1;
+}
+
+void AuswahlListe::setALRBreite( int br ) // setzt die Breite des Auswahl Rahmens (nur ohne MultiStyled)
+{
+    if( !aRahmen )
+        aRahmen = new LRahmen();
+    aRahmen->setRamenBreite( br );
+    rend = 1;
+}
+
+void AuswahlListe::setALRFarbe( int fc ) // setzt die Farbe des Auswahl Rahmens (nur ohne MultiStyled)
+{
+    if( !aRahmen )
+        aRahmen = new LRahmen();
+    aRahmen->setFarbe( fc );
+    rend = 1;
+}
+
+void AuswahlListe::setAAFZ( AlphaFeld *buffer ) // setzt einen Zeiger zum Auswahl AlpaFeld (nur ohne MultiStyled)
+{
+    if( aBuffer )
+        aBuffer->release();
+    aBuffer = buffer;
+    rend = 1;
+}
+
+void AuswahlListe::setAAFStärke( int st ) // setzt die Stärke des Auswahl Hintergrund Buffers (nur ohne MultiStyled)
+{
+    if( !aBuffer )
+        aBuffer = new AlphaFeld();
+    aBuffer->setStärke( st );
+    rend = 1;
+}
+
+void AuswahlListe::setAAFFarbe( int fc ) // setzt die Farbe des Auswahl Hintergrund Buffers (nur ohne MultiStyled)
+{
+    if( !aBuffer )
+        aBuffer = new AlphaFeld();
+    aBuffer->setFarbe( fc );
+    rend = 1;
+}
+
+void AuswahlListe::setAHBild( Bild *bild ) // setzt das Auswahl Hintergrund Bild (nur ohne MultiStyled)
+{
+    if( !ahBild )
+        ahBild = new Bild();
+    ahBild->neuBild( bild->getBreite(), bild->getHöhe(), 0 );
+    int *buff1 = ahBild->getBuffer();
+    int *buff2 = bild->getBuffer();
+    for( int i = 0; i < bild->getBreite() * bild->getHöhe(); ++i )
+        buff1[ i ] = buff2[ i ];
+    bild->release();
+    rend = 1;
+}
+
+void AuswahlListe::setAHFarbe( int f ) // setzt einen Zeiger zur Auswahl Hintergrund Farbe (nur ohne MultiStyled)
+{
+    ahFarbe = f;
+    rend = 1;
+}
+
+void AuswahlListe::setAHBildZ( Bild *b ) // setzt einen Zeiger zum Hintergrund Bild (nur ohne MultiStyled)
+{
+    if( ahBild )
+        ahBild->release();
+    ahBild = b;
+    rend = 1;
+}
+
+void AuswahlListe::setALRZ( int pos, LRahmen *rahmen ) // setzt einen Zeiger zum Auswahl Rahmen (nur mit MulitStyled)
+{
+    if( !aRahmenListe )
+        aRahmenListe = new RCArray< LRahmen >();
+    aRahmenListe->set( rahmen, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setALRBreite( int pos, int br ) // setzt die Breite des Auswahl Rahmens (nur mit MultiStyled)
+{
+    if( !aRahmenListe )
+        aRahmenListe = new RCArray< LRahmen >();
+    if( !aRahmenListe->z( pos ) )
+        aRahmenListe->set( new LRahmen(), pos );
+    aRahmenListe->z( pos )->setRamenBreite( br );
+    rend = 1;
+}
+
+void AuswahlListe::setALRFarbe( int pos, int fc ) // setzt die Farbe des Auswahl Rahmens (nur mit MultiStyled)
+{
+    if( !aRahmenListe )
+        aRahmenListe = new RCArray< LRahmen >();
+    if( !aRahmenListe->z( pos ) )
+        aRahmenListe->set( new LRahmen(), pos );
+    aRahmenListe->z( pos )->setFarbe( fc );
+    rend = 1;
+}
+
+void AuswahlListe::setAAFZ( int pos, AlphaFeld *buffer ) // setzt einen Zeiger zum Auswahl AlpaFeld (nur mit MultiStyled)
+{
+    if( !aBufferListe )
+        aBufferListe = new RCArray< AlphaFeld >();
+    aBufferListe->set( buffer, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setAAFStärke( int pos, int st ) // setzt die Stärke des Auswahl Hintergrund Buffers (nur mit MultiStyled)
+{
+    if( !aBufferListe )
+        aBufferListe = new RCArray< AlphaFeld >();
+    if( !aBufferListe->z( pos ) )
+        aBufferListe->set( new AlphaFeld(), pos );
+    aBufferListe->z( pos )->setStärke( st );
+    rend = 1;
+}
+
+void AuswahlListe::setAAFFarbe( int pos, int fc ) // setzt die Farbe des Auswahl Hintergrund Buffers (nur mit MultiStyled)
+{
+    if( !aBufferListe )
+        aBufferListe = new RCArray< AlphaFeld >();
+    if( !aBufferListe->z( pos ) )
+        aBufferListe->set( new AlphaFeld(), pos );
+    aBufferListe->z( pos )->setFarbe( fc );
+    rend = 1;
+}
+
+void AuswahlListe::setAHBild( int pos, Bild *bild ) // setzt das Auswahl Hintergrund Bild (nur mit MultiStyled)
+{
+    if( ahBildListe )
+        ahBildListe = new RCArray< Bild >();
+    if( !ahBildListe->z( pos ) )
+        ahBildListe->set( new Bild(), pos );
+    ahBildListe->z( pos )->neuBild( bild->getBreite(), bild->getHöhe(), 0 );
+    int *buff1 = ahBildListe->z( pos )->getBuffer();
+    int *buff2 = bild->getBuffer();
+    for( int i = 0; i < bild->getBreite() * bild->getHöhe(); ++i )
+        buff1[ i ] = buff2[ i ];
+    bild->release();
+    rend = 1;
+}
+
+void AuswahlListe::setAHFarbe( int pos, int f ) // setzt einen Zeiger zur Auswahl Hintergrund Farbe (nur miz MultiStyled)
+{
+    if( ahFarbeListe )
+        ahFarbeListe = new Array< int >();
+    ahFarbeListe->set( f, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setAHBildZ( int pos, Bild *b ) // setzt einen Zeiger zum Hintergrund Bild (nur mit MultiStyled)
+{
+    if( ahBildListe )
+        ahBildListe = new RCArray< Bild >();
+    ahBildListe->set( b, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setMsStyle( int pos, __int64 style ) // setzt den Style des Eintrags (nur mit MultiStyled)
+{
+    if( !styles )
+        styles = new Array< __int64 >();
+    styles->set( style, pos );
+    rend = 1;
+}
+
+void AuswahlListe::setMsStyle( int pos, __int64 style, bool add_löschen )
+{
+    if( !styles )
+        styles = new Array< __int64 >();
+    if( add_löschen )
+        styles->set( styles->get( pos ) | style, pos );
+    else
+        styles->set( styles->get( pos ) & ~style, pos );
+    rend = 1;
+}
+
+void AuswahlListe::addMsStyle( int pos, __int64 style )
+{
+    if( !styles )
+        styles = new Array< __int64 >();
+    styles->set( styles->get( pos ) | style, pos );
+    rend = 1;
+}
+
+void AuswahlListe::löscheMsStyle( int pos, __int64 style )
+{
+    if( !styles )
+        styles = new Array< __int64 >();
+    styles->set( styles->get( pos ) & ~style, pos );
+    rend = 1;
+}
+
+void AuswahlListe::doMausEreignis( MausEreignis &me )
+{
+    bool nmakc = !me.verarbeitet;
+    if( hatStyleNicht( Style::Sichtbar ) || hatStyleNicht( Style::Erlaubt ) )
+        return;
+    bool removeFokus = 0;
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+        removeFokus = 1;
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        if( removeFokus && me.id == ME_RLinks )
+            löscheStyle( Style::Fokus );
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+    {
+        if( removeFokus && me.id == ME_RLinks )
+            löscheStyle( Style::Fokus );
+        if( !me.verarbeitet && hatStyleNicht( Style::Fokus ) && me.id == ME_RLinks )
+            addStyle( Style::Fokus );
+        if( hatStyle( Style::VScroll ) && vertikalScrollBar )
+        {
+            int rbr = 0;
+            if( rahmen && hatStyle( Style::Rahmen ) )
+                rbr = rahmen->getRBreite();
+            if( ( ( me.mx > gr.x - 15 - rbr ) || me.id == ME_UScroll || me.id == ME_DScroll ) && me.id != ME_Betritt && me.id != ME_Verlässt )
+            {
+                vertikalScrollBar->doMausMessage( gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me );
+                me.verarbeitet = 1;
+            }
+        }
+        if( !me.verarbeitet && me.id == ME_RLinks )
+        {
+            int eintr = getKlickEintrag( me.my );
+            if( eintr >= 0 )
+            {
+                if( hatStyleNicht( Style::MultiSelect ) )
+                {
+                    auswahl = eintr;
+                    rend = 1;
+                }
+                else
+                {
+                    bool shift = TastenStand[ T_Shift ];
+                    bool strg = TastenStand[ T_Strg ];
+                    if( strg )
+                    {
+                        setMsStyle( eintr, Style::Ausgewählt, hatMsStyleNicht( eintr, Style::Ausgewählt ) );
+                        auswahl = eintr;
+                    }
+                    else if( shift && auswahl != -1 )
+                    {
+                        deSelect();
+                        int beg = auswahl, end = eintr;
+                        if( beg > end )
+                        {
+                            int tmp = end;
+                            end = beg;
+                            beg = tmp;
+                        }
+                        for( int i = beg; i <= end; ++i )
+                        {
+                            addMsStyle( i, Style::Ausgewählt );
+                        }
+                    }
+                    else
+                    {
+                        deSelect();
+                        addMsStyle( eintr, Style::Ausgewählt );
+                        auswahl = eintr;
+                    }
+                }
+            }
+            else
+                deSelect();
+        }
+        me.verarbeitet = 1;
+    }
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x, me.my += pos.y;
+}
+
+void AuswahlListe::doTastaturEreignis( TastaturEreignis &te )
+{
+    bool ntakc = !te.verarbeitet;
+    if( hatStyleNicht( Style::Fokus ) || !Tak || te.verarbeitet )
+        return;
+    ++ref;
+    if( Tak( takParam, this, te ) )
+    {
+        if( te.id == TE_Press )
+        {
+            if( hatStyleNicht( Style::MultiSelect ) )
+            {
+                switch( te.taste )
+                {
+                case T_Unten:
+                    ++auswahl;
+                    if( auswahl > einträge )
+                        auswahl = einträge;
+                    rend = 1;
+                    break;
+                case T_Oben:
+                    --auswahl;
+                    if( auswahl < -1 )
+                        auswahl = -1;
+                    rend = 1;
+                    break;
+                }
+            }
+            else
+            {
+                switch( te.taste )
+                {
+                case T_Unten:
+                    deSelect();
+                    ++auswahl;
+                    if( auswahl > einträge )
+                        auswahl = einträge;
+                    if( auswahl >= 0 )
+                        addMsStyle( auswahl, Style::Ausgewählt );
+                    rend = 1;
+                    break;
+                case T_Oben:
+                    deSelect();
+                    --auswahl;
+                    if( auswahl < -1 )
+                        auswahl = -1;
+                    if( auswahl >= 0 )
+                        addMsStyle( auswahl, Style::Ausgewählt );
+                    rend = 1;
+                    break;
+                }
+            }
+        }
+        te.verarbeitet = 1;
+    }
+    --ref;
+    if( ntakc && te.verarbeitet && nTak )
+        te.verarbeitet = nTak( ntakParam, this, te );
+    if( !ref )
+        delete this;
+}
+
+void AuswahlListe::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+    if( !hatStyle( Style::Sichtbar ) )
+        return;
+    löscheStyle( Style::HScroll );
+    __super::render( zRObj );
+    lockZeichnung();
+    if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+    {
+        unlockZeichnung();
+        return;
+    }
+    int rbr = 0;
+    if( rahmen && hatStyle( Style::Rahmen ) )
+        rbr = rahmen->getRBreite();
+    if( tfListe )
+    {
+        einträge = tfListe->getEintragAnzahl();
+        int maxHöhe = 0;
+        int dx = 0, dy = 0;
+        if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+            dy -= vertikalScrollBar->getScroll();
+        int mdy = innenGröße.y + rbr;
+        for( int i = 0; i < einträge; ++i )
+        {
+            TextFeld *tf = tfListe->z( i );
+            if( dy + tf->getHöhe() > mdy && !(vertikalScrollBar && hatStyle( Style::VScroll ) ) )
+                break;
+            tf->setPosition( dx, dy );
+            tf->setGröße( innenGröße.x, tf->getHöhe() );
+            maxHöhe += tf->getHöhe();
+            bool selected = 0;
+            if( hatStyle( Style::MultiSelect ) && styles )
+                selected = hatMsStyle( i, Style::Ausgewählt );
+            else
+                selected = auswahl == i;
+            AlphaFeld *tmpBuffer = 0;
+            bool tmpB = 0;
+            int tmpHFarbe = 0;
+            bool tmpH = 0;
+            Bild *tmpHBild = 0;
+            bool tmpHB = 0;
+            bool tmpHAlpha = 0;
+            LRahmen *tmpRahmen = 0;
+            bool tmpR = 0;
+            if( selected )
+            {
+                if( hatStyleNicht( Style::MultiStyled ) || !styles )
+                {
+                    if( hatStyle( Style::AuswahlBuffer ) && aBuffer )
+                    {
+                        tmpBuffer = tf->getAlphaFeld();
+                        tf->setAlphaFeldZ( aBuffer->getThis() );
+                        tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+                        tf->setStyle( TextFeld::Style::Buffered, hatStyle( Style::AuswahlBuffer ) );
+                    }
+                    if( hatStyle( Style::AuswahlHintergrund ) )
+                    {
+                        tmpH = tf->hatStyle( TextFeld::Style::Hintergrund );
+                        tmpHFarbe = tf->getHintergrundFarbe();
+                        tf->setHintergrundFarbe( ahFarbe );
+                        tf->setStyle( TextFeld::Style::Hintergrund, hatStyle( Style::Hintergrund ) );
+                        if( hatStyle( Style::AuswahlHBild ) && ahBild )
+                        {
+                            tmpHBild = tf->getHintergrundBild();
+                            tf->setHintergrundBildZ( ahBild->getThis() );
+                            tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+                            tf->setStyle( TextFeld::Style::HBild, hatStyle( Style::HBild ) );
+                        }
+                        if( hatStyle( Style::AuswahlHAlpha ) )
+                        {
+                            tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+                            tf->setStyle( TextFeld::Style::HAlpha, hatStyle( Style::AuswahlHAlpha ) );
+                        }
+                    }
+                    if( hatStyle( Style::AuswahlRahmen ) && aRahmen )
+                    {
+                        tmpRahmen = tf->getLinienRahmen();
+                        tf->setLinienRahmenZ( aRahmen->getThis() );
+                        tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+                        tf->setStyle( TextFeld::Style::Rahmen, hatStyle( Style::AuswahlRahmen ) );
+                    }
+                }
+                else
+                {
+                    if( hatMsStyle( i, Style::AuswahlBuffer ) && aBufferListe )
+                    {
+                        tmpBuffer = tf->getAlphaFeld();
+                        tf->setAlphaFeldZ( aBufferListe->get( i ) );
+                        tmpB = tf->hatStyle( TextFeld::Style::Buffered );
+                        tf->setStyle( TextFeld::Style::Buffered, hatMsStyle( i, Style::AuswahlBuffer ) );
+                    }
+                    if( hatMsStyle( i, Style::AuswahlHintergrund ) )
+                    {
+                        tmpH = tf->hatStyle( Style::Hintergrund );
+                        tf->setStyle( TextFeld::Style::Hintergrund, hatMsStyle( i, Style::AuswahlHintergrund ) );
+                        if( ahFarbeListe && ahFarbeListe->hat( i ) )
+                        {
+                            tmpHFarbe = tf->getHintergrundFarbe();
+                            tf->setHintergrundFarbe( ahFarbeListe->get( i ) );
+                        }
+                        if( hatMsStyle( i, Style::AuswahlHBild ) && ahBildListe )
+                        {
+                            tmpHBild = tf->getHintergrundBild();
+                            tf->setHintergrundBildZ( ahBildListe->get( i ) );
+                            tmpHB = tf->hatStyle( TextFeld::Style::HBild );
+                            tf->setStyle( TextFeld::Style::HBild, hatMsStyle( i, Style::HBild ) );
+                        }
+                        if( hatMsStyle( i, Style::AuswahlHAlpha ) )
+                        {
+                            tmpHAlpha = tf->hatStyle( TextFeld::Style::HAlpha );
+                            tf->setStyle( TextFeld::Style::HAlpha, hatMsStyle( i, Style::AuswahlHAlpha ) );
+                        }
+                    }
+                    if( hatMsStyle( i, Style::AuswahlRahmen ) && aRahmenListe )
+                    {
+                        tmpRahmen = tf->getLinienRahmen();
+                        tf->setLinienRahmenZ( aRahmenListe->get( i ) );
+                        tmpR = tf->hatStyle( TextFeld::Style::Rahmen );
+                        tf->setStyle( TextFeld::Style::Rahmen, hatMsStyle( i, Style::AuswahlRahmen ) );
+                    }
+                }
+            }
+            tf->render( zRObj );
+            if( selected )
+            {
+                if( hatStyleNicht( Style::MultiStyled ) || !styles )
+                {
+                    if( hatStyle( Style::AuswahlBuffer ) )
+                    {
+                        tf->setAlphaFeldZ( tmpBuffer );
+                        tf->setStyle( TextFeld::Style::Buffered, tmpB );
+                    }
+                    if( hatStyle( Style::AuswahlHintergrund ) )
+                    {
+                        tf->setHintergrundFarbe( tmpHFarbe );
+                        tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+                        if( hatStyle( Style::AuswahlHBild ) )
+                        {
+                            tf->setHintergrundBildZ( tmpHBild );
+                            tf->setStyle( TextFeld::Style::HBild, tmpHB );
+                        }
+                        if( hatStyle( Style::AuswahlHAlpha ) )
+                            tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+                    }
+                    if( hatStyle( Style::AuswahlRahmen ) )
+                    {
+                        tf->setLinienRahmenZ( tmpRahmen );
+                        tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+                    }
+                }
+                else
+                {
+                    if( hatMsStyle( i, Style::AuswahlBuffer ) && aBufferListe )
+                    {
+                        tf->setAlphaFeldZ( tmpBuffer );
+                        tf->setStyle( TextFeld::Style::Buffered, tmpB );
+                    }
+                    if( hatMsStyle( i, Style::AuswahlHintergrund ) )
+                    {
+                        tf->setStyle( TextFeld::Style::Hintergrund, tmpH );
+                        if( ahFarbeListe && ahFarbeListe->hat( i ) )
+                            tf->setHintergrundFarbe( tmpHFarbe );
+                        if( hatMsStyle( i, Style::AuswahlHBild ) && ahBildListe )
+                        {
+                            tf->setHintergrundBildZ( tmpHBild );
+                            tf->setStyle( TextFeld::Style::HBild, tmpHB );
+                        }
+                        if( hatMsStyle( i, Style::AuswahlHAlpha ) )
+                            tf->setStyle( TextFeld::Style::HAlpha, tmpHAlpha );
+                    }
+                    if( hatMsStyle( i, Style::AuswahlRahmen ) && aRahmenListe )
+                    {
+                        tf->setLinienRahmenZ( tmpRahmen );
+                        tf->setStyle( TextFeld::Style::Rahmen, tmpR );
+                    }
+                }
+            }
+            dy += tf->getHöhe();
+        }
+        if( vertikalScrollBar )
+            vertikalScrollBar->getScrollData()->maxHöhe = maxHöhe;
+    }
+    zRObj.releaseDrawOptions();
+    unlockZeichnung();
+}
+
+int AuswahlListe::getKlickEintrag( int my )
+{
+    if( !tfListe )
+        return -1;
+    einträge = tfListe->getEintragAnzahl();
+    int y = 0;
+    if( hatStyle( Style::VScroll ) && vertikalScrollBar )
+        y -= vertikalScrollBar->getScroll();
+    for( int i = 0; i < einträge; ++i )
+    {
+        y += tfListe->z( i )->getHöhe();
+        if( y > my )
+            return i;
+    }
+    return -1;
+}
+
+void AuswahlListe::setAuswahl( int ausw ) // setzt die Auswahl
+{
+    if( hatStyleNicht( Style::MultiSelect ) )
+        auswahl = ausw;
+    else if( styles )
+    {
+        for( int i = 0; i < einträge; ++i )
+            löscheMsStyle( i, Style::Ausgewählt );
+        addMsStyle( ausw, Style::Ausgewählt );
+    }
+}
+
+void AuswahlListe::deSelect()
+{
+    if( hatStyleNicht( Style::MultiSelect ) )
+        auswahl = -1;
+    else if( styles )
+    {
+        for( int i = 0; i < einträge; ++i )
+        {
+            löscheMsStyle( i, Style::Ausgewählt );
+        }
+    }
+}
+
+// constant 
+int AuswahlListe::getEintragAnzahl() const // gibt die Anzahl der Einträge zurück
+{
+    return einträge;
+}
+
+int AuswahlListe::getAuswahl() const // gibt den ersten ausgewählten Eintrag zurück
+{
+    return auswahl;
+}
+
+int AuswahlListe::getEintragPos( Text *eintragText ) // gibt die Position des eintrages mit dem entsprechenden Textes zurück
+{
+    for( int i = 0; i < einträge; ++i )
+    {
+        if( tfListe->z( i )->zText()->istGleich( eintragText->getText() ) )
+        {
+            eintragText->release();
+            return i;
+        }
+    }
+    return -1;
+}
+
+TextFeld *AuswahlListe::getEintrag( int pos ) const // gibt den pos- ten Eintrag zurück
+{
+    if( !tfListe )
+        return 0;
+    TextFeld *ret = (TextFeld*)tfListe->get( pos );
+    if( ret )
+        return ret->getThis();
+    return 0;
+}
+
+TextFeld *AuswahlListe::zEintrag( int pos ) const
+{
+    if( !tfListe )
+        return 0;
+    return (TextFeld*)tfListe->z( pos );
+}
+
+LRahmen *AuswahlListe::getARahmen() const // gibt den Auswahl Rahmen zurück (ohne MultiStyled)
+{
+    if( aRahmen )
+        return aRahmen->getThis();
+    return 0;
+}
+
+LRahmen *AuswahlListe::zARahmen() const
+{
+    return aRahmen;
+}
+
+int AuswahlListe::getAHFarbe() const // gibt die Auswahl Hintergrund Farbe zurück (ohne MultiStyled)
+{
+    return ahFarbe;
+}
+
+Bild *AuswahlListe::getAHBild() const // gibt das Auswahl Hintergrund Bild zurück (ohne MultiStyled)
+{
+    if( ahBild )
+        return ahBild->getThis();
+    return 0;
+}
+
+Bild *AuswahlListe::zAHBild() const
+{
+    return ahBild;
+}
+
+AlphaFeld *AuswahlListe::getABuffer() const // gibt den Auswahl Buffer zurück (ohne MultiStyled)
+{
+    if( aBuffer )
+        return aBuffer->getThis();
+    return 0;
+}
+
+AlphaFeld *AuswahlListe::zABuffer() const
+{
+    return aBuffer;
+}
+
+LRahmen *AuswahlListe::getARahmen( int pos ) const // gibt den Auswahl Rahmen zurück (mit MultiStyled)
+{
+    LRahmen *ret = 0;
+    if( aRahmenListe )
+        ret = (LRahmen*)aRahmenListe->get( pos );
+    if( ret )
+        return ret->getThis();
+    return 0;
+}
+
+LRahmen *AuswahlListe::zARahmen( int pos ) const
+{
+    LRahmen *ret = 0;
+    if( aRahmenListe )
+        ret = (LRahmen*)aRahmenListe->z( pos );
+    return ret;
+}
+
+int AuswahlListe::getAHFarbe( int pos ) const // gibt die Auswahl Hintergrund Farbe zurück (mit MultiStyled)
+{
+    if( ahFarbeListe && ahFarbeListe->hat( pos ) )
+        return ahFarbeListe->get( pos );
+    return 0;
+}
+
+Bild *AuswahlListe::getAHBild( int pos ) const // gibt das Auswahl Hintergrund Bild zurück (mit MultiStyled)
+{
+    Bild *ret = 0;
+    if( ahBildListe )
+        ret = (Bild*)ahBildListe->get( pos );
+    if( ret )
+        return ret->getThis();
+    return 0;
+}
+
+Bild *AuswahlListe::zAHBild( int pos ) const
+{
+    Bild *ret = 0;
+    if( ahBildListe )
+        ret = (Bild*)ahBildListe->z( pos );
+    return ret;
+}
+
+AlphaFeld *AuswahlListe::getABuffer( int pos ) const // gibt den Auswahl Buffer zurück (mit MultiStyled)
+{
+    AlphaFeld *ret = 0;
+    if( aBufferListe )
+        ret = (AlphaFeld*)aBufferListe->get( pos );
+    if( ret )
+        return ret->getThis();
+    return 0;
+}
+
+AlphaFeld *AuswahlListe::zABuffer( int pos ) const
+{
+    AlphaFeld *ret = 0;
+    if( aBufferListe )
+        ret = (AlphaFeld*)aBufferListe->z( pos );
+    return ret;
+}
+bool AuswahlListe::hatMsStyle( int pos, __int64 style ) const // prüft ob style vorhanden (mit MultiStyled)
+{
+    __int64 st = 0;
+    if( styles )
+        st = styles->get( pos );
+    return ( st | style ) == st;
+}
+
+bool AuswahlListe::hatMsStyleNicht( int pos, __int64 style ) const // prüft obt style nicht vorhanden (mit MultiStyled)
+{
+    __int64 st = 0;
+    if( styles )
+        st = styles->get( pos );
+    return ( st | style ) != st;
+}
+
+// Reference Counting 
+AuswahlListe *AuswahlListe::getThis()
+{
+    ++ref;
+    return this;
+}
+
+AuswahlListe *AuswahlListe::release()
+{
+    --ref;
+    if( ref == 0 )
+        delete this;
+    return 0;
+}

+ 134 - 0
Liste.h

@@ -0,0 +1,134 @@
+#ifndef Liste_H
+#define Liste_H
+
+#include "Zeichnung.h"
+#include "Array.h"
+
+namespace Framework
+{
+	class LRahmen; // Rahmen.h
+	class AlphaFeld; // AlphaFeld.h
+	class Bild; // Bild.h
+	class Text; // Text.h
+	class TextFeld; // TextFeld.h
+	class VScrollBar; // Scroll.h
+	struct TastaturEreignis; // TastaturEreignis.h
+	struct MausEreignis; // MausEreignis.h
+    class Schrift; // Schrift.h
+	class AuswahlListe; // aus dieser datei
+
+	class AuswahlListe : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 FeldRahmen = 0x0001000;
+            const static __int64 FeldHintergrund = 0x0002000;
+            const static __int64 FeldHBild = 0x0004000;
+            const static __int64 FeldHAlpha = 0x0008000;
+            const static __int64 FeldBuffer = 0x0010000;
+            const static __int64 AuswahlHintergrund = 0x0020000;
+            const static __int64 AuswahlHBild = 0x0040000;
+            const static __int64 AuswahlHAlpha = 0x0080000;
+            const static __int64 AuswahlBuffer = 0x0100000;
+            const static __int64 AuswahlRahmen = 0x0200000;
+            const static __int64 MultiStyled = 0x0400000;
+            const static __int64 MultiSelect = 0x0800000;
+            const static __int64 Ausgewählt = 0x1000000;
+
+            const static __int64 Normal = Sichtbar | Erlaubt | Rahmen | FeldHAlpha | FeldHintergrund | FeldRahmen | AuswahlBuffer | AuswahlRahmen;
+        };
+	private:
+		RCArray< TextFeld > *tfListe;
+		int einträge, auswahl;
+		int ahFarbe;
+		Bild *ahBild;
+		AlphaFeld *aBuffer;
+		LRahmen *aRahmen;
+		Array< __int64 > *styles;
+		Array< int > *ahFarbeListe;
+		RCArray< Bild > *ahBildListe;
+		RCArray< AlphaFeld > *aBufferListe;
+		RCArray< LRahmen > *aRahmenListe;
+        Schrift *schrift;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) AuswahlListe();
+		// Destruktor 
+		__declspec( dllexport ) ~AuswahlListe();
+		// nicht constant 
+		__declspec( dllexport ) void update(); // aktualisiert die Auswahl Liste
+		__declspec( dllexport ) void addEintrag( Text *txt ); // fügt einen Eintrag hinzu
+		__declspec( dllexport ) void addEintrag( const char *txt );
+		__declspec( dllexport ) void addEintrag( TextFeld *tf );
+		__declspec( dllexport ) void addEintrag( int pos, Text *txt ); // fügt einen Eintrag bei position pos ein
+		__declspec( dllexport ) void addEintrag( int pos, const char *txt );
+		__declspec( dllexport ) void addEintrag( int pos, TextFeld *tf );
+		__declspec( dllexport ) void setEintrag( int pos, Text *txt ); // ändert den pos - ten Eintrag
+		__declspec( dllexport ) void setEintrag( int pos, unsigned char *txt );
+		__declspec( dllexport ) void setEintrag( int pos, TextFeld *tf );
+		__declspec( dllexport ) void setEintragPos( int vpos, int npos ); // taucht den Eintrag vpos mit dem Eintrag npos
+		__declspec( dllexport ) void löscheEintrag( int pos ); // löscht den Eintrag pos
+        __declspec( dllexport ) void setSchriftZ( Schrift *schrift ); // legt die Schrift der Einträge fest
+        __declspec( dllexport ) void setVScrollZuEintrag( int eintrag ); // scrollt zum Eintrag
+        __declspec( dllexport ) void updateVScroll(); // scrollt zur Curser Position oder nach Unten
+		__declspec( dllexport ) void setALRZ( LRahmen *rahmen ); // setzt einen Zeiger zum Auswahl Rahmen (nur ohne MulitStyled)
+        __declspec( dllexport ) void setALRBreite( int br ); // setzt die Breite des Auswahl Rahmens (nur ohne MultiStyled)
+        __declspec( dllexport ) void setALRFarbe( int fc ); // setzt die Farbe des Auswahl Rahmens (nur ohne MultiStyled)
+		__declspec( dllexport ) void setAAFZ( AlphaFeld *buffer ); // setzt einen Zeiger zum Auswahl AlpaFeld (nur ohne MultiStyled)
+        __declspec( dllexport ) void setAAFStärke( int st ); // setzt die Stärke des Auswahl Hintergrund Buffers (nur ohne MultiStyled)
+        __declspec( dllexport ) void setAAFFarbe( int fc ); // setzt die Farbe des Auswahl Hintergrund Buffers (nur ohne MultiStyled)
+        __declspec( dllexport ) void setAHBild( Bild *bild ); // setzt das Auswahl Hintergrund Bild (nur ohne MultiStyled)
+        __declspec( dllexport ) void setAHBildZ( Bild *bild ); // setzt einen Zeiger zum Auswahl Hintergrund Bild (nur ohne MultiStyled)
+        __declspec( dllexport ) void setAHFarbe( int fc ); // setzt die Auswahl Hintergrundfarbe (nur ohne MultiStyled)
+		__declspec( dllexport ) void setALRZ( int pos, LRahmen *rahmen ); // setzt einen Zeiger zum Auswahl Rahmen (nur mit MulitStyled)
+        __declspec( dllexport ) void setALRBreite( int pos, int br ); // setzt die Breite des Auswahl Rahmens (nur mit MultiStyled)
+        __declspec( dllexport ) void setALRFarbe( int pos, int fc ); // setzt die Farbe des Auswahl Rahmens (nur mit MultiStyled)
+		__declspec( dllexport ) void setAAFZ( int pos, AlphaFeld *buffer ); // setzt einen Zeiger zum Auswahl AlpaFeld (nur mit MultiStyled)
+        __declspec( dllexport ) void setAAFStärke( int pos, int st ); // setzt die Stärke des Auswahl Hintergrund Buffers (nur mit MultiStyled)
+        __declspec( dllexport ) void setAAFFarbe( int pos, int fc ); // setzt die Farbe des Auswahl Hintergrund Buffers (nur mit MultiStyled)
+        __declspec( dllexport ) void setAHBild( int pos, Bild *bild ); // setzt das Auswahl Hintergrund Bild (nur mit MultiStyled)
+        __declspec( dllexport ) void setAHBildZ( int pos, Bild *bild ); // setzt einen Zeiger zum Auswahl Hintergrund Bild (nur mit MultiStyled)
+        __declspec( dllexport ) void setAHFarbe( int pos, int fc ); // setzt die Auswahl Hintergrundfarbe (nur mit MultiStyled)
+		__declspec( dllexport ) void setMsStyle( int pos, __int64 style ); // setzt den Style des Eintrags (nur mit MultiStyled)
+        __declspec( dllexport ) void setMsStyle( int pos, __int64 style, bool add_löschen );
+		__declspec( dllexport ) void addMsStyle( int pos, __int64 style );
+		__declspec( dllexport ) void löscheMsStyle( int pos, __int64 style );
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+		__declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ) override;
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+        __declspec( dllexport ) int getKlickEintrag( int my );
+        __declspec( dllexport ) void setAuswahl( int ausw ); // setzt die Auswahl
+		__declspec( dllexport ) void deSelect(); // deselectiert die Auswahl
+		// constant 
+		__declspec( dllexport ) int getEintragAnzahl() const; // gibt die Anzahl der Einträge zurück
+		__declspec( dllexport ) int getAuswahl() const; // gibt den ersten ausgewählten Eintrag zurück
+		__declspec( dllexport ) int getEintragPos( Text *eintragText ); // gibt die Position des eintrages mit dem entsprechenden Textes zurück
+		__declspec( dllexport ) TextFeld *getEintrag( int pos ) const; // gibt den pos- ten Eintrag zurück
+		__declspec( dllexport ) TextFeld *zEintrag( int pos ) const;
+		__declspec( dllexport ) LRahmen *getARahmen() const; // gibt den Auswahl Rahmen zurück (ohne MultiStyled)
+		__declspec( dllexport ) LRahmen *zARahmen() const;
+		__declspec( dllexport ) int getAHFarbe() const; // gibt die Auswahl Hintergrund Farbe zurück (ohne MultiStyled)
+		__declspec( dllexport ) Bild *getAHBild() const; // gibt das Auswahl Hintergrund Bild zurück (ohne MultiStyled)
+		__declspec( dllexport ) Bild *zAHBild() const;
+		__declspec( dllexport ) AlphaFeld *getABuffer() const; // gibt den Auswahl Buffer zurück (ohne MultiStyled)
+		__declspec( dllexport ) AlphaFeld *zABuffer() const;
+		__declspec( dllexport ) LRahmen *getARahmen( int pos ) const; // gibt den Auswahl Rahmen zurück (mit MultiStyled)
+		__declspec( dllexport ) LRahmen *zARahmen( int pos ) const;
+		__declspec( dllexport ) int getAHFarbe( int pos ) const; // gibt die Auswahl Hintergrund Farbe zurück (mit MultiStyled)
+		__declspec( dllexport ) Bild *getAHBild( int pos ) const; // gibt das Auswahl Hintergrund Bild zurück (mit MultiStyled)
+		__declspec( dllexport ) Bild *zAHBild( int pos ) const;
+		__declspec( dllexport ) AlphaFeld *getABuffer( int pos ) const; // gibt den Auswahl Buffer zurück (mit MultiStyled)
+		__declspec( dllexport ) AlphaFeld *zABuffer( int pos ) const;
+		__declspec( dllexport ) inline bool hatMsStyle( int pos, __int64 style ) const; // prüft ob style vorhanden (mit MultiStyled)
+		__declspec( dllexport ) inline bool hatMsStyleNicht( int pos, __int64 style ) const; // prüft obt style nicht vorhanden (mit MultiStyled)
+		// Reference Counting 
+		__declspec( dllexport ) AuswahlListe *getThis();
+		__declspec( dllexport ) AuswahlListe *release();
+	};
+}
+
+#endif

+ 199 - 0
M2DVorschau.cpp

@@ -0,0 +1,199 @@
+#include "M2DVorschau.h"
+#include "Model2D.h"
+#include "MausEreignis.h"
+#include "Rahmen.h"
+#include "AlphaFeld.h"
+#include "ToolTip.h"
+#include "Globals.h"
+#include "Bild.h"
+
+
+using namespace Framework;
+
+
+// Inhalt der M2DVorschau Klasse aus M2DVorschau.h
+// Konstruktor
+M2DVorschau::M2DVorschau()
+    : ZeichnungHintergrund()
+{
+    mdl = 0;
+    mx = -1;
+    my = -1;
+    ref = 1;
+}
+
+// Destruktor
+M2DVorschau::~M2DVorschau()
+{
+    if( mdl )
+        mdl->release();
+    if( ram )
+        ram->release();
+    if( af )
+        af->release();
+}
+
+// nicht constant
+void M2DVorschau::setModel2DZ( Model2D *mdl )
+{
+    if( this->mdl )
+        this->mdl->release();
+    this->mdl = mdl;
+    rend = 1;
+}
+
+void M2DVorschau::setModel2D( Model2DData *mdl )
+{
+    if( !this->mdl )
+        this->mdl = new Model2D();
+    this->mdl->setModel( mdl );
+    rend = 1;
+}
+
+void M2DVorschau::doMausEreignis( MausEreignis &me )
+{
+    if( hatStyleNicht( Style::Erlaubt ) || hatStyleNicht( Style::Sichtbar ) )
+    {
+        mausIn = 0;
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( me.verarbeitet || ( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+        }
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak && Mak( makParam, this, me ) )
+    {
+        if( hatStyle( Style::UsrScale ) )
+        {
+            if( mdl && me.id == ME_UScroll )
+                mdl->addGröße( 0.01f );
+            if( mdl && me.id == ME_DScroll )
+                mdl->addGröße( -0.01f );
+        }
+        if( me.id == ME_RLinks || me.id == ME_RRechts || me.id == ME_Verlässt )
+        {
+            mx = -1;
+            my = -1;
+        }
+        if( mdl && me.id == ME_Bewegung )
+        {
+            if( mx != -1 && my != -1 )
+            {
+                if( getMausStand( M_Links ) && hatStyle( Style::UsrMove ) )
+                    mdl->setPosition( mdl->getPosition() + Punkt( me.mx - mx, me.my - my ) );
+                if( getMausStand( M_Rechts ) && hatStyle( Style::UsrRot ) )
+                {
+                    if( me.mx > gr.x / 2 )
+                        mdl->addDrehung( 0.01f * ( me.my - my ) );
+                    else
+                        mdl->addDrehung( -0.01f * ( me.my - my ) );
+                    if( me.my > gr.y / 2 )
+                        mdl->addDrehung( -0.01f * ( me.mx - mx ) );
+                    else
+                        mdl->addDrehung( 0.01f * ( me.mx - mx ) );
+                }
+                mx = me.mx;
+                my = me.my;
+            }
+        }
+        if( me.id == ME_PLinks || me.id == ME_PRechts )
+        {
+            mx = me.mx;
+            my = me.my;
+        }
+        if( nMak && me.verarbeitet )
+            me.verarbeitet = nMak( nmakParam, this, me );
+    }
+    me.mx += pos.x, me.my += pos.y;
+}
+
+bool M2DVorschau::tick( double tv )
+{
+    rend |= mdl ? mdl->tick( tv ) : 0;
+    rend |= af ? af->tick( tv ) : 0;
+    rend |= ram ? ram->tick( tv ) : 0;
+    return __super::tick( tv );
+}
+
+void M2DVorschau::render( Bild &rb )
+{
+    löscheStyle( Style::VScroll | Style::HScroll );
+    if( hatStyleNicht( Style::Sichtbar ) )
+        return;
+    __super::render( rb );
+    if( !rb.setDrawOptions( innenPosition, innenGröße ) )
+        return;
+    if( mdl )
+    {
+        int rbr = rahmen && hatStyle( Style::Rahmen ) ? rahmen->getRBreite() : 0;
+        rb.addScrollOffset( -gr.x / 2 + rbr, -gr.y / 2 + rbr );
+        mdl->render( rb );
+    }
+    rb.releaseDrawOptions();
+}
+
+// constant
+Model2D *M2DVorschau::zModel() const
+{
+    return mdl;
+}
+
+Model2D *M2DVorschau::getModel() const
+{
+    return mdl ? mdl->getThis() : 0;
+}
+
+Zeichnung *M2DVorschau::dublizieren() const
+{
+    M2DVorschau *ret = new M2DVorschau();
+    if( mdl )
+        ret->setModel2D( mdl->getModel() );
+    if( rahmen )
+        ret->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+    if( hintergrundFeld )
+        ret->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+    ret->setHintergrundFarbe( bgF );
+    return ret;
+}
+
+// Reference counting
+M2DVorschau *M2DVorschau::getThis()
+{
+    ref++;
+    return this;
+}
+
+M2DVorschau *M2DVorschau::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 52 - 0
M2DVorschau.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+    class Model2D; // Model2D.h
+    class Model2DData; // Model2D.h
+    class LRahmen; // Rahmen.h
+    class AlphaFeld; // AlphaFeld.h
+    struct MausEreignis; // MausEreignis.h
+
+    class M2DVorschau : public ZeichnungHintergrund
+    {
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 UsrScale = 0x001000;
+            const static __int64 UsrMove = 0x002000;
+            const static __int64 UsrRot = 0x004000;
+        };
+
+    private:
+        Model2D *mdl;
+        LRahmen *ram;
+        AlphaFeld *af;
+        int bgF;
+        int mx;
+        int my;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) M2DVorschau();
+        // Destruktor
+        __declspec( dllexport ) ~M2DVorschau();
+        // nicht constant
+        __declspec( dllexport ) void setModel2DZ( Model2D *mdl );
+        __declspec( dllexport ) void setModel2D( Model2DData *mdl );
+        __declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+        __declspec( dllexport ) bool tick( double tv ) override;
+        __declspec( dllexport ) void render( Bild &rb ) override;
+        // constant
+        __declspec( dllexport ) Model2D *zModel() const;
+        __declspec( dllexport ) Model2D *getModel() const;
+        __declspec( dllexport ) Zeichnung *dublizieren() const override;
+        // Reference counting
+        __declspec( dllexport ) M2DVorschau *getThis();
+        __declspec( dllexport ) M2DVorschau *release();
+    };
+}

+ 381 - 0
M2Datei.cpp

@@ -0,0 +1,381 @@
+#include "M2Datei.h"
+#include "Text.h"
+#include "Datei.h"
+#include "Model2D.h"
+
+using namespace Framework;
+
+// Inhalt der M2Datei Klasse aus M2Datei.h
+// Konstruktor
+M2Datei::M2Datei()
+{
+	pfad = new Text();
+	modelName = new RCArray< Text >();
+	modelPos = new Array< __int64 >();
+	ref = 1;
+}
+
+M2Datei::M2Datei( const char *pfad )
+{
+	this->pfad = new Text( pfad );
+	modelName = new RCArray< Text >();
+	modelPos = new Array< __int64 >();
+	ref = 1;
+}
+
+M2Datei::M2Datei( Text *pfad )
+{
+	this->pfad = pfad;
+	modelName = new RCArray< Text >();
+	modelPos = new Array< __int64 >();
+	ref = 1;
+}
+
+// Destruktor
+M2Datei::~M2Datei()
+{
+	pfad->release();
+	modelName->release();
+	modelPos->release();
+}
+
+// nicht constant
+void M2Datei::setPfad( const char *pfad )
+{
+	this->pfad->setText( pfad );
+}
+
+void M2Datei::setPfadZ( Text *pfad )
+{
+	if( this->pfad )
+		this->pfad->release();
+	this->pfad = pfad;
+}
+
+void M2Datei::leseDaten()
+{
+	Datei d;
+	d.setDatei( pfad->getText() );
+	d.öffnen( Datei::Style::lesen );
+	char anz = 0;
+	d.lese( &anz, 1 );
+	modelName->leeren();
+	modelPos->leeren();
+	for( int i = 0; i < anz; i++ )
+	{
+		char län = 0;
+		d.lese( &län, 1 );
+		char *txt = new char[ län + 1 ];
+		d.lese( txt, län );
+		txt[ (int)län ] = 0;
+		modelName->set( new Text( txt ), i );
+		delete[] txt;
+		__int64 pos = 0;
+		d.lese( (char*)&pos, 8 );
+		modelPos->set( pos, i );
+	}
+	d.schließen();
+}
+
+bool M2Datei::saveModel( Model2DData *zMdr, Text *name )
+{
+	bool ret = saveModel( zMdr, name->getText() );
+	name->release();
+	return ret;
+}
+
+bool M2Datei::saveModel( Model2DData *zMdr, const char *name )
+{
+	int anz = modelName->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( modelName->z( i )->istGleich( name ) )
+		{
+			if( !löscheModel( name ) )
+				return 0;
+			break;
+		}
+	}
+	anz = modelName->getEintragAnzahl();
+	Datei d;
+	d.setDatei( pfad->getText() );
+	d.öffnen( Datei::Style::lesen );
+	Datei neu;
+	neu.setDatei( pfad->getText() );
+	neu.zPfad()->anhängen( "0" );
+	while( neu.existiert() )
+		neu.zPfad()->anhängen( "0" );
+	if( !neu.öffnen( Datei::Style::schreiben ) )
+	{
+		if( d.istOffen() )
+			d.schließen();
+		return 0;
+	}
+	modelName->add( new Text( name ) );
+	int offs = textLänge( name ) + 9;
+	for( int i = 0; i < anz; i++ )
+		modelPos->set( modelPos->get( i ) + offs, i );
+	if( d.getGröße() < 0 )
+		modelPos->add( offs + 1 );
+	else
+		modelPos->add( d.getGröße() + offs );
+	anz++;
+	char tmp = (char)anz;
+	neu.schreibe( &tmp, 1 );
+	for( int i = 0; i < anz; i++ )
+	{
+		char län = (char)modelName->z( i )->getLänge();
+		neu.schreibe( &län, 1 );
+		neu.schreibe( modelName->z( i )->getText(), län );
+		__int64 pos = modelPos->get( i );
+		neu.schreibe( (char*)&pos, 8 );
+	}
+	if( d.existiert() )
+	{
+		d.setLPosition( modelPos->get( 0 ) - offs, 0 );
+		__int64 dl = d.getGröße() - d.getLPosition();
+		char bytes[ 2048 ];
+		while( dl )
+		{
+			int l = dl > 2048 ? 2048 : (int)dl;
+			d.lese( bytes, l );
+			neu.schreibe( bytes, l );
+			dl -= l;
+		}
+	}
+	d.schließen();
+	char pAnz = zMdr->polygons->getEintragAnzahl();
+	neu.schreibe( &pAnz, 1 );
+	for( int p = 0; p < pAnz; p++ )
+	{
+		int vAnz = zMdr->polygons->get( p ).vertex->getEintragAnzahl();
+		char textur = 1;
+		for( int i = 0; i < vAnz; i++ )
+			textur &= (char)zMdr->polygons->get( p ).tKordinaten->hat( i );
+		neu.schreibe( &textur, 1 );
+		neu.schreibe( (char*)&vAnz, 4 );
+		for( int i = 0; i < vAnz; i++ )
+		{
+			float v = zMdr->polygons->get( p ).vertex->get( i ).x;
+			neu.schreibe( (char*)&v, 4 );
+			v = zMdr->polygons->get( p ).vertex->get( i ).y;
+			neu.schreibe( (char*)&v, 4 );
+			if( textur )
+			{
+				int t = zMdr->polygons->get( p ).tKordinaten->get( i ).x;
+				neu.schreibe( (char*)&t, 4 );
+				t = zMdr->polygons->get( p ).tKordinaten->get( i ).y;
+				neu.schreibe( (char*)&t, 4 );
+			}
+		}
+	}
+	d.löschen();
+	neu.schließen();
+	neu.umbenennen( pfad->getText() );
+	leseDaten();
+	return 1;
+}
+
+bool M2Datei::löscheModel( Text *name )
+{
+	bool ret = löscheModel( name->getText() );
+	name->release();
+	return ret;
+}
+
+bool M2Datei::löscheModel( const char *name )
+{
+	int anz = modelName->getEintragAnzahl();
+	int p = -1;
+	for( int i = 0; i < anz; i++ )
+	{
+		if( modelName->z( i )->istGleich( name ) )
+		{
+			p = i;
+			break;
+		}
+	}
+	if( p < 0 )
+		return 0;
+	Datei d;
+	d.setDatei( pfad->getText() );
+	if( !d.öffnen( Datei::Style::lesen ) )
+		return 0;
+	Datei neu;
+	neu.setDatei( pfad->getText() );
+	neu.zPfad()->anhängen( "0" );
+	while( neu.existiert() )
+		neu.zPfad()->anhängen( "0" );
+	if( !neu.öffnen( Datei::Style::schreiben ) )
+	{
+		if( d.istOffen() )
+			d.schließen();
+		return 0;
+	}
+	char nAnz = (char)anz - 1;
+	neu.schreibe( &nAnz, 1 );
+	int offs = modelName->z( p )->getLänge() + 9;
+	__int64 startP = 0, endP = 0, start2P = 0;
+	for( int i = 0; i < anz; i++ )
+	{
+		char nLän = (char)modelName->z( i )->getLänge();
+		char *n = modelName->z( i )->getText();
+		__int64 pos = modelPos->get( i );
+		if( !startP )
+			startP = pos;
+		if( i == p + 1 )
+			start2P = pos;
+		if( i == p )
+		{
+			if( !endP )
+				endP = pos;
+			if( i < anz - 1 )
+				offs += (int)( modelPos->get( i + 1 ) - pos );
+		}
+		if( i != p )
+		{
+			pos -= offs;
+			neu.schreibe( &nLän, 1 );
+			neu.schreibe( n, nLän );
+			neu.schreibe( (char*)&pos, 8 );
+		}
+	}
+	if( d.istOffen() )
+	{
+		d.setLPosition( startP, 0 );
+		__int64 bLän = endP - startP;
+		char bytes[ 2048 ];
+		while( bLän > 0 )
+		{
+			int l = 2048 > bLän ? (int)bLän : 2048;
+			d.lese( bytes, l );
+			neu.schreibe( bytes, l );
+			bLän -= l;
+		}
+		if( start2P )
+		{
+			d.setLPosition( start2P, 0 );
+			bLän = d.getGröße() - start2P;
+			while( bLän > 0 )
+			{
+				int l = 2048 > bLän ? (int)bLän : 2048;
+				d.lese( bytes, l );
+				neu.schreibe( bytes, l );
+				bLän -= l;
+			}
+		}
+		d.schließen();
+	}
+	d.löschen();
+	neu.schließen();
+	neu.umbenennen( pfad->getText() );
+	leseDaten();
+	return 1;
+}
+
+// constant
+Model2DData *M2Datei::ladeModel( Text *name ) const
+{
+	Model2DData *ret = ladeModel( name->getText() );
+	name->release();
+	return ret;
+}
+
+Model2DData *M2Datei::ladeModel( const char *name ) const
+{
+	Datei d;
+	d.setDatei( pfad->getText() );
+	if( !d.öffnen( Datei::Style::lesen ) )
+		return 0;
+	int anz = modelName->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( modelName->z( i )->istGleich( name ) )
+		{
+			d.setLPosition( modelPos->get( i ), 0 );
+			break;
+		}
+	}
+	if( !d.getLPosition() )
+	{
+		d.schließen();
+		return 0;
+	}
+	char pAnz = 0;
+	d.lese( &pAnz, 1 );
+	Array< Polygon2D > *polygons = new Array< Polygon2D >();
+	for( int p = 0; p < pAnz; p++ )
+	{
+		char textur = 0;
+		d.lese( &textur, 1 );
+		int vAnz = 0;
+		d.lese( (char*)&vAnz, 4 );
+		if( polygons->hat( p ) )
+		{
+			if( polygons->get( p ).vertex )
+				polygons->get( p ).vertex->release();
+			if( polygons->get( p ).tKordinaten )
+				polygons->get( p ).tKordinaten->release();
+		}
+		Polygon2D polygon;
+		polygon.vertex = new Array< Vertex >();
+		if( textur )
+			polygon.tKordinaten = new Array< Punkt >();
+		else
+			polygon.tKordinaten = 0;
+		for( int v = 0; v < vAnz; v++ )
+		{
+			Vertex p;
+			d.lese( (char*)&p.x, 4 );
+			d.lese( (char*)&p.y, 4 );
+			polygon.vertex->add( p );
+			if( textur )
+			{
+				Punkt tp;
+				d.lese( (char*)&tp.x, 4 );
+				d.lese( (char*)&tp.y, 4 );
+				polygon.tKordinaten->add( tp );
+			}
+		}
+		polygons->add( polygon );
+	}
+	d.schließen();
+	Model2DData *ret = new Model2DData();
+	ret->erstelleModell( polygons );
+	return ret;
+}
+
+bool M2Datei::hatModel( const char *name ) const
+{
+	int anz = modelName->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( modelName->z( i )->istGleich( name ) )
+			return 1;
+	}
+	return 0;
+}
+
+int M2Datei::getModelAnzahl() const
+{
+	return modelName->getEintragAnzahl();
+}
+
+Text *M2Datei::zModelName( int i ) const
+{
+	return modelName->z( i );
+}
+
+// Reference Counting
+M2Datei *M2Datei::getThis()
+{
+	++ref;
+	return this;
+}
+
+M2Datei *M2Datei::release()
+{
+	if( !--ref )
+		delete this;
+	return 0;
+}

+ 85 - 0
M2Datei.h

@@ -0,0 +1,85 @@
+#ifndef M2Datei_H
+#define M2Datei_H
+
+#include "Array.h"
+
+namespace Framework
+{
+	class Model2DData; // Model2D.h
+	class Text; // Text.h
+
+    // Diese Klasse verwaltet das Framework eigenen Dateivormat für 2D Modell Daten
+    // Es können mehrere 2D Modell Daten in einer Datei gespeichert werden
+	class M2Datei
+	{
+	private:
+		Text *pfad;
+		RCArray< Text > *modelName;
+		Array< __int64 > *modelPos;
+		int ref;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) M2Datei();
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) M2Datei( const char *pfad );
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+		__declspec( dllexport ) M2Datei( Text *pfad );
+		// Destruktor
+		__declspec( dllexport ) ~M2Datei();
+		// Setzt den Pfad zur Datei
+        //  pfad: Pfad zur Datei
+		__declspec( dllexport ) void setPfad( const char *pfad );
+        // Setzt einen Zeiger auf den Pfad zur Datei
+        //  pfad: Zeiger auf den Pfad zur Datei
+		__declspec( dllexport ) void setPfadZ( Text *pfad );
+        // Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung benötigt werden
+		__declspec( dllexport ) void leseDaten();
+        // Speichert 2D Modell Daten in der Datei
+        //  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+        //  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+        //  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+		__declspec( dllexport ) bool saveModel( Model2DData *zMdr, Text *name );
+        // Speichert 2D Modell Daten in der Datei
+        //  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+        //  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+        //  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+		__declspec( dllexport ) bool saveModel( Model2DData *zMdr, const char *name );
+        // Löscht ein 2D Modell aus der Datei
+        //  name: Der Name des Modells
+        //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+		__declspec( dllexport ) bool löscheModel( Text *name );
+        // Löscht ein 2D Modell aus der Datei
+        //  name: Der Name des Modells
+        //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+		__declspec( dllexport ) bool löscheModel( const char *name );
+		// Lähd ein 2D Modell aus der Datei
+        //  name: Der name des zu ladenden Modells
+        //  return: Die geladenen Daten
+		__declspec( dllexport ) Model2DData *ladeModel( Text *name ) const;
+        // Lähd ein 2D Modell aus der Datei
+        //  name: Der name des zu ladenden Modells
+        //  return: Die geladenen Daten
+		__declspec( dllexport ) Model2DData *ladeModel( const char *name ) const;
+        // überprft, ob ein bestimmtes 2D Modell in der Datei existiert
+        //  name: Der Name des zu suchenden 2D Modells
+        //  return: 1, wenn das Modell gefunden wurde. 0 sonst
+		__declspec( dllexport ) bool hatModel( const char *name ) const;
+        // ügibt die Anzahl der gespeicherten Modelle zurück
+		__declspec( dllexport ) int getModelAnzahl() const;
+        // Gibt den Namen eines Bestimmten Modells zurück
+        //  i: Der Index des Modells
+        //  return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
+		__declspec( dllexport ) Text *zModelName( int i ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) M2Datei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) M2Datei *release();
+	};
+}
+
+#endif

+ 251 - 0
M3Datei.cpp

@@ -0,0 +1,251 @@
+#include "M3Datei.h"
+#include "Datei.h"
+
+using namespace Framework;
+
+// Inhalt der M3Datei Klasse
+// Konstruktor
+M3Datei::M3Datei()
+{
+    modelName = 0;
+    modelPos = 0;
+}
+
+// Konstruktor
+//  pfad: Der Pfad zur Datei
+M3Datei::M3Datei( const char *pfad )
+    : M3Datei()
+{
+    this->pfad = pfad;
+}
+
+// Konstruktor
+//  pfad: Der Pfad zur Datei
+M3Datei::M3Datei( Text *pfad )
+    : M3Datei( pfad->getText() )
+{
+    pfad->release();
+}
+
+// Destruktor
+M3Datei::~M3Datei()
+{
+    if( modelName )
+        modelName->release();
+    if( modelPos )
+        modelPos->release();
+}
+
+// Setzt den Pfad zur Datei
+
+//  pfad: Pfad zur Datei
+void M3Datei::setPfad( const char *pfad )
+{
+    this->pfad = pfad;
+    if( modelName )
+        modelName = modelName->release();
+    if( modelPos )
+        modelPos = modelPos->release();
+}
+
+// Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung benötigt werden
+void M3Datei::leseDaten()
+{
+    if( modelName )
+        modelName = modelName->release();
+    if( modelPos )
+        modelPos = modelPos->release();
+    modelName = new RCArray< Text >();
+    modelPos = new Array< __int64 >();
+    Datei d;
+    d.setDatei( pfad );
+    if( !d.öffnen( Datei::Style::lesen ) )
+        return;
+    unsigned char anz = 0;
+    d.lese( (char*)&anz, 1 );
+    for( int i = 0; i < anz; i++ )
+    {
+        char län = 0;
+        d.lese( &län, 1 );
+        char *n = new char[ län + 1 ];
+        n[ län ] = 0;
+        d.lese( n, län );
+        modelName->add( new Text( n ) );
+        delete[] n;
+        __int64 p = 0;
+        d.lese( (char*)&p, 8 );
+        modelPos->add( p );
+    }
+    d.schließen();
+}
+
+// Speichert 3D Modell Daten in der Datei
+//  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+//  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+//  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+bool M3Datei::saveModel( Model3DData *zMdr, Text *name )
+{
+    bool ret = saveModel( zMdr, name->getText() );
+    name->release();
+    return ret;
+}
+
+// Speichert 3D Modell Daten in der Datei
+//  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+//  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+//  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+bool M3Datei::saveModel( Model3DData *zMdr, const char *name )
+{
+    if( !modelName || !pfad.getLänge() )
+        return 0;
+    if( hatModel( name ) && !löscheModel( name ) )
+        return 0;
+    int anz = modelName->getEintragAnzahl();
+    anz = modelName->getEintragAnzahl();
+    Datei d;
+    d.setDatei( pfad );
+    if( !d.öffnen( Datei::Style::lesen ) )
+        return 0;
+    Datei neu;
+    neu.setDatei( pfad );
+    neu.zPfad()->anhängen( "0" );
+    while( neu.existiert() )
+        neu.zPfad()->anhängen( "0" );
+    if( !neu.öffnen( Datei::Style::schreiben ) )
+    {
+        if( d.istOffen() )
+            d.schließen();
+        return 0;
+    }
+    modelName->add( new Text( name ) );
+    int offs = textLänge( name ) + 9;
+    for( int i = 0; i < anz; i++ )
+        modelPos->set( modelPos->get( i ) + offs, i );
+    if( d.getGröße() < 0 )
+        modelPos->add( offs + 1 );
+    else
+        modelPos->add( d.getGröße() + offs );
+    anz++;
+    char tmp = (char)anz;
+    neu.schreibe( &tmp, 1 );
+    for( int i = 0; i < anz; i++ )
+    {
+        char län = (char)modelName->z( i )->getLänge();
+        neu.schreibe( &län, 1 );
+        neu.schreibe( modelName->z( i )->getText(), län );
+        __int64 pos = modelPos->get( i );
+        neu.schreibe( (char*)&pos, 8 );
+    }
+    if( d.existiert() )
+    {
+        d.setLPosition( modelPos->get( 0 ) - offs, 0 );
+        __int64 dl = d.getGröße() - d.getLPosition();
+        char bytes[ 2048 ];
+        while( dl )
+        {
+            int l = dl > 2048 ? 2048 : (int)dl;
+            d.lese( bytes, l );
+            neu.schreibe( bytes, l );
+            dl -= l;
+        }
+    }
+    d.schließen();
+    /*char pAnz = zMdr->polygons->getEintragAnzahl();
+    neu.schreibe( &pAnz, 1 );
+    for( int p = 0; p < pAnz; p++ )
+    {
+        int vAnz = zMdr->polygons->get( p ).vertex->getEintragAnzahl();
+        char textur = 1;
+        for( int i = 0; i < vAnz; i++ )
+            textur &= (char)zMdr->polygons->get( p ).tKordinaten->hat( i );
+        neu.schreibe( &textur, 1 );
+        neu.schreibe( (char*)&vAnz, 4 );
+        for( int i = 0; i < vAnz; i++ )
+        {
+            float v = zMdr->polygons->get( p ).vertex->get( i ).x;
+            neu.schreibe( (char*)&v, 4 );
+            v = zMdr->polygons->get( p ).vertex->get( i ).y;
+            neu.schreibe( (char*)&v, 4 );
+            if( textur )
+            {
+                int t = zMdr->polygons->get( p ).tKordinaten->get( i ).x;
+                neu.schreibe( (char*)&t, 4 );
+                t = zMdr->polygons->get( p ).tKordinaten->get( i ).y;
+                neu.schreibe( (char*)&t, 4 );
+            }
+        }
+    }*/
+    d.löschen();
+    neu.schließen();
+    neu.umbenennen( pfad );
+    leseDaten();
+    return 1;
+}
+
+// Löscht ein 3D Modell aus der Datei
+//  name: Der Name des Modells
+//  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+bool M3Datei::löscheModel( Text *name )
+{
+    return 0;
+}
+
+// Löscht ein 3D Modell aus der Datei
+//  name: Der Name des Modells
+//  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+bool M3Datei::löscheModel( const char *name )
+{
+    return 0;
+}
+
+// Lähd ein 3D Modell aus der Datei
+//  name: Der name des zu ladenden Modells
+//  return: Die geladenen Daten
+Model3DData *M3Datei::ladeModel( Text *name ) const
+{
+    return 0;
+}
+
+// Lähd ein 3D Modell aus der Datei
+//  name: Der name des zu ladenden Modells
+//  return: Die geladenen Daten
+Model3DData *M3Datei::ladeModel( const char *name ) const
+{
+    return 0;
+}
+
+// überprft, ob ein bestimmtes 3D Modell in der Datei existiert
+//  name: Der Name des zu suchenden 3D Modells
+//  return: 1, wenn das Modell gefunden wurde. 0 sonst
+bool M3Datei::hatModel( const char *name ) const
+{
+    return 0;
+}
+
+// ügibt die Anzahl der gespeicherten Modelle zurück
+int M3Datei::getModelAnzahl() const
+{
+    return 0;
+}
+
+// Gibt den Namen eines Bestimmten Modells zurück
+//  i: Der Index des Modells
+//  return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
+Text *M3Datei::zModelName( int i ) const
+{
+    return 0;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+M3Datei *M3Datei::getThis()
+{
+    return 0;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+M3Datei *M3Datei::release()
+{
+    return 0;
+}

+ 77 - 0
M3Datei.h

@@ -0,0 +1,77 @@
+#pragma once
+
+#include "Array.h"
+
+namespace Framework
+{
+    class Text;
+    class Model3DData;
+
+    class M3Datei
+    {
+    private:
+        Text pfad;
+        RCArray< Text > *modelName;
+        Array< __int64 > *modelPos;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) M3Datei();
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+        __declspec( dllexport ) M3Datei( const char *pfad );
+        // Konstruktor
+        //  pfad: Der Pfad zur Datei
+        __declspec( dllexport ) M3Datei( Text *pfad );
+        // Destruktor
+        __declspec( dllexport ) ~M3Datei();
+        // Setzt den Pfad zur Datei
+        //  pfad: Pfad zur Datei
+        __declspec( dllexport ) void setPfad( const char *pfad );
+        // Ließt grundlegende Informationen aus der Datei, die für ihre Verwendung benötigt werden
+        __declspec( dllexport ) void leseDaten();
+        // Speichert 3D Modell Daten in der Datei
+        //  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+        //  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+        //  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+        __declspec( dllexport ) bool saveModel( Model3DData *zMdr, Text *name );
+        // Speichert 3D Modell Daten in der Datei
+        //  zMdr: Ein Zeiger auf die zu speichernden Daten ohne erhöhtem Reference Counter
+        //  name: Der Name, unter dem die Daten in der Datei gespeichert werden sollen
+        //  return: 1, falls das Modell gespeichert wurde. 0, falls ein fehler beim speichern auftrat
+        __declspec( dllexport ) bool saveModel( Model3DData *zMdr, const char *name );
+        // Löscht ein 3D Modell aus der Datei
+        //  name: Der Name des Modells
+        //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+        __declspec( dllexport ) bool löscheModel( Text *name );
+        // Löscht ein 3D Modell aus der Datei
+        //  name: Der Name des Modells
+        //  return: 1, wenn das Modell gelöscht wurde. 0, wenn das Modell nicht gefunden wurde, oder ein fehler beim speichern auftrat
+        __declspec( dllexport ) bool löscheModel( const char *name );
+        // Lähd ein 3D Modell aus der Datei
+        //  name: Der name des zu ladenden Modells
+        //  return: Die geladenen Daten
+        __declspec( dllexport ) Model3DData *ladeModel( Text *name ) const;
+        // Lähd ein 3D Modell aus der Datei
+        //  name: Der name des zu ladenden Modells
+        //  return: Die geladenen Daten
+        __declspec( dllexport ) Model3DData *ladeModel( const char *name ) const;
+        // überprft, ob ein bestimmtes 3D Modell in der Datei existiert
+        //  name: Der Name des zu suchenden 3D Modells
+        //  return: 1, wenn das Modell gefunden wurde. 0 sonst
+        __declspec( dllexport ) bool hatModel( const char *name ) const;
+        // ügibt die Anzahl der gespeicherten Modelle zurück
+        __declspec( dllexport ) int getModelAnzahl() const;
+        // Gibt den Namen eines Bestimmten Modells zurück
+        //  i: Der Index des Modells
+        //  return: Ein Zeiger aud den Namen des Modells ohne erhöhten Reference Counter
+        __declspec( dllexport ) Text *zModelName( int i ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) M3Datei *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) M3Datei *release();
+    };
+}

+ 84 - 0
Mat3.h

@@ -0,0 +1,84 @@
+#ifndef Mat3_H
+#define Mat3_H
+
+#include "Vec2.h"
+
+namespace Framework
+{
+	template< typename T >
+	class Mat3
+	{
+	public:
+		// [ Zeile ][ Spalte ] ( [ y ][ x ] )
+		T elements[ 3 ][ 3 ];
+		// nicht constant
+		Mat3 &operator=( const Mat3 &r )
+		{
+			memcpy( elements, r.elements, sizeof( elements ) );
+			return *this;
+		}
+		Mat3 &operator*=( const T r )
+		{
+			for( T &e : elements )
+				r *= r;
+			return *this;
+		}
+		Mat3 &operator*=( const Mat3 &r )
+		{
+			return *this = *this * r;
+		}
+		// constant
+		Mat3 operator*( const T r ) const
+		{
+			Mat3 result = *this;
+			return result *= r;
+		}
+		Mat3 operator*( const Mat3 &r ) const
+		{
+			Mat3 result;
+			for( int j = 0; j < 3; j++ )
+			{
+				for( int k = 0; k < 3; k++ )
+				{
+					T sum = 0;
+					for( int i = 0; i < 3; i++ )
+						sum += elements[ j ][ i ] * r.elements[ i ][ k ];
+					result.elements[ j ][ k ] = sum;
+				}
+			}
+			return result;
+		}
+		Vec2< T > operator*( const Vec2< T > r ) const
+		{
+			Vec2< T > result;
+			result.x = elements[ 0 ][ 0 ] * r.x + elements[ 0 ][ 1 ] * r.y + elements[ 0 ][ 2 ];
+			result.y = elements[ 1 ][ 0 ] * r.x + elements[ 1 ][ 1 ] * r.y + elements[ 1 ][ 2 ];
+			return  result;
+		}
+		// static
+		static Mat3 rotation( T radian )
+		{
+			const T cosTheta = (T)cos( radian );
+			const T sinTheta = (T)sin( radian );
+			Mat3 r = { cosTheta, -sinTheta, 0, sinTheta, cosTheta, 0, 0, 0, 1 };
+			return r;
+		}
+		static Mat3 scaling( T faktor )
+		{
+			Mat3 s = { faktor, 0, 0, 0, faktor, 0, 0, 0, 1 };
+			return s;
+		}
+		static Mat3 translation( const Vec2< T > offset )
+		{
+			Mat3 t = { 1, 0, offset.x, 0, 1, offset.y, 0, 0, 1 };
+			return t;
+		}
+		static Mat3 identity()
+		{
+			Mat3 i = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
+			return i;
+		}
+	};
+}
+
+#endif

+ 109 - 0
Mat4.h

@@ -0,0 +1,109 @@
+#pragma once
+
+#include "Vec3.h"
+
+namespace Framework
+{
+    template< typename T >
+    class Mat4
+    {
+    public:
+        // [ Zeile ][ Spalte ] ( [ y ][ x ] )
+        T elements[ 4 ][ 4 ];
+        // nicht constant
+        Mat4 &operator=( const Mat4 &r )
+        {
+            memcpy( elements, r.elements, sizeof( elements ) );
+            return *this;
+        }
+        Mat4 &operator*=( const T r )
+        {
+            for( T &e : elements )
+                r *= r;
+            return *this;
+        }
+        Mat4 &operator*=( const Mat4 &r )
+        {
+            return *this = *this * r;
+        }
+        // constant
+        Mat4 operator*( const T r ) const
+        {
+            Mat4 result = *this;
+            return result *= r;
+        }
+        Mat4 operator*( const Mat4 &r ) const
+        {
+            Mat4 result;
+            for( int j = 0; j < 4; j++ )
+            {
+                for( int k = 0; k < 4; k++ )
+                {
+                    T sum = 0;
+                    for( int i = 0; i < 4; i++ )
+                        sum += elements[ j ][ i ] * r.elements[ i ][ k ];
+                    result.elements[ j ][ k ] = sum;
+                }
+            }
+            return result;
+        }
+        Vec3< T > operator*( const Vec3< T > &r ) const
+        {
+            Vec3< T > result;
+            result.x = elements[ 0 ][ 0 ] * r.x + elements[ 0 ][ 1 ] * r.y + elements[ 0 ][ 2 ] * r.z + elements[ 0 ][ 3 ];
+            result.y = elements[ 1 ][ 0 ] * r.x + elements[ 1 ][ 1 ] * r.y + elements[ 1 ][ 2 ] * r.z + elements[ 1 ][ 3 ];
+            result.z = elements[ 2 ][ 0 ] * r.x + elements[ 2 ][ 1 ] * r.y + elements[ 2 ][ 2 ] * r.z + elements[ 2 ][ 3 ];
+            return  result;
+        }
+        // static
+        static Mat4 rotationZ( T radian )
+        {
+            const T cosTheta = (T)cos( radian );
+            const T sinTheta = (T)sin( radian );
+            Mat4 r = { cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
+            return r;
+        }
+        static Mat4 rotationX( T radian )
+        {
+            const T cosTheta = (T)cos( radian );
+            const T sinTheta = (T)sin( radian );
+            Mat4 r = { 1, 0, 0, 0, 0, cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1 };
+            return r;
+        }
+        static Mat4 rotationY( T radian )
+        {
+            const T cosTheta = (T)cos( radian );
+            const T sinTheta = (T)sin( radian );
+            Mat4 r = { cosTheta, 0, sinTheta, 0, 0, 1, 0, 0, -sinTheta, 0, cosTheta, 0, 0, 0, 0, 1 };
+            return r;
+        }
+        static Mat4 scaling( T faktor )
+        {
+            Mat4 s = { faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 1 };
+            return s;
+        }
+        static Mat4 scaling( T faktorX, T faktorY, T faktorZ )
+        {
+            Mat4 s = { faktorX, 0, 0, 0, 0, faktorY, 0, 0, 0, 0, faktorZ, 0, 0, 0, 1 };
+            return s;
+        }
+        static Mat4 translation( const Vec3< T > offset )
+        {
+            Mat4 t = { 1, 0, 0, offset.x, 0, 1, 0, offset.y, 0, 0, 1, offset.z, 0, 0, 0, 1 };
+            return t;
+        }
+        static Mat4 projektion( float öffnungswinkel, float bildschirmXY, float minZ, float maxZ )
+        {
+            Mat4 p = { (float)( 1 / tan( öffnungswinkel / 2 ) ) / bildschirmXY, 0, 0, 0,
+                0, (float)( 1 / tan( öffnungswinkel / 2 ) ), 0, 0, 
+                0, 0, maxZ / ( maxZ - minZ ), -( minZ * maxZ ) / ( maxZ - minZ ),
+                0, 0, 1, 0 };
+            return p;
+        }
+        static Mat4 identity()
+        {
+            Mat4 i = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
+            return i;
+        }
+    };
+}

+ 119 - 0
Maus.cpp

@@ -0,0 +1,119 @@
+#include "Maus.h"
+#include "Bild.h"
+#include "Punkt.h"
+
+using namespace Framework;
+
+// Inhalt der Maus Klasse aus Maus.h
+// Konstruktor 
+Maus::Maus()
+	: hMaus( LoadCursor( 0, IDC_ARROW ) ),
+	  ref( 1 )
+{
+}
+
+// nicht constant
+void Maus::ladeMaus( int mausId )
+{
+	if( mausId == MausId::nichts )
+		hMaus = 0;
+	if( mausId == MausId::normal )
+		hMaus = LoadCursor( 0, IDC_ARROW );
+	if( mausId == MausId::hand )
+		hMaus = LoadCursor( 0, IDC_HAND );
+	if( mausId == MausId::warten )
+		hMaus = LoadCursor( 0, IDC_APPSTARTING );
+	if( mausId == MausId::verschieben )
+		hMaus = LoadCursor( 0, IDC_SIZEALL );
+	if( mausId == MausId::text )
+		hMaus = LoadCursor( 0, IDC_IBEAM );
+	if( mausId == MausId::wahgerecht )
+		hMaus = LoadCursor( 0, IDC_SIZEWE );
+	if( mausId == MausId::senkrecht )
+		hMaus = LoadCursor( 0, IDC_SIZENS );
+	if( mausId == MausId::diagonal1 )
+		hMaus = LoadCursor( 0, IDC_SIZENWSE );
+	if( mausId == MausId::diagonal2 )
+		hMaus = LoadCursor( 0, IDC_SIZENESW );
+	if( mausId == MausId::verboten )
+		hMaus = LoadCursor( 0, IDC_NO );
+	SetCursor( hMaus );
+}
+
+void Maus::ladeMaus( Bild *maus )
+{
+	HBITMAP hAndMaskBitmap;
+	HBITMAP hXorMaskBitmap;
+	HDC hDC = GetDC( 0 );
+	HDC hAndMaskDC = CreateCompatibleDC( hDC );
+	HDC hXorMaskDC = CreateCompatibleDC( hDC );
+
+	hAndMaskBitmap = CreateCompatibleBitmap( hDC, maus->getBreite(), maus->getHöhe() );
+	hXorMaskBitmap = CreateCompatibleBitmap( hDC, maus->getBreite(), maus->getHöhe() );
+
+	//Select the bitmaps to DC
+	HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject( hAndMaskDC, hAndMaskBitmap );
+	HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject( hXorMaskDC, hXorMaskBitmap );
+
+	//Scan each pixel of the souce bitmap and create the masks
+	int y;
+	for( int x = 0; x < maus->getBreite(); ++x )
+	{
+		for( y = 0; y < maus->getHöhe(); ++y )
+		{
+			int pixel = maus->getPixel( x, y );
+			if( ( ( pixel >> 24 ) & 0xFF ) == 0 )
+			{
+				SetPixel( hAndMaskDC, x, y, RGB( 255, 255, 255 ) );
+				SetPixel( hXorMaskDC, x, y, RGB( 0, 0, 0 ) );
+			}
+			else
+			{
+				SetPixel( hAndMaskDC, x, y, RGB( 0, 0, 0 ) );
+				SetPixel( hXorMaskDC, x, y, RGB( ( pixel >> 16 ) & 0xFF, ( pixel >> 8 ) & 0xFF, pixel & 0xFF ) );
+			}
+		}
+	}
+	SelectObject( hAndMaskDC, hOldAndMaskBitmap );
+	SelectObject( hXorMaskDC, hOldXorMaskBitmap );
+
+	DeleteDC( hXorMaskDC );
+	DeleteDC( hAndMaskDC );
+	ReleaseDC( 0, hDC );
+
+	ICONINFO iconinfo = { 0 };
+	iconinfo.fIcon = 0;
+	iconinfo.xHotspot = 0;
+	iconinfo.yHotspot = 0;
+	iconinfo.hbmMask = hAndMaskBitmap;
+	iconinfo.hbmColor = hXorMaskBitmap;
+	hMaus = CreateIconIndirect( &iconinfo );
+
+	SetCursor( hMaus );
+}
+
+void Maus::update()
+{
+	SetCursor( hMaus );
+}
+
+// constant
+HCURSOR Maus::getMausHandle()
+{
+	return hMaus;
+}
+
+// Reference Counting
+Maus *Maus::getThis()
+{
+	++ref;
+	return this;
+}
+
+Maus *Maus::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 58 - 0
Maus.h

@@ -0,0 +1,58 @@
+#ifndef Maus_H
+#define Maus_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+	class Bild; // aus Bild.h
+	class Maus; // aus dieser Datei
+
+	namespace MausId
+	{
+		const int nichts = 0;
+		const int normal = 1;
+		const int hand = 2;
+		const int warten = 3;
+		const int verschieben = 4;
+		const int text = 5;
+		const int wahgerecht = 6;
+		const int senkrecht = 7;
+		const int diagonal1 = 8;
+		const int diagonal2 = 9;
+		const int verboten = 10;
+	}
+
+    // Diese Klasse verwaltet das Bild des Mauszeigers
+    // Sie wird vom Framework intern verwendet
+    // Siehe Globals.h MausZeiger
+	class Maus
+	{
+	private:
+		HCURSOR hMaus;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Maus();
+        // läd eine maus von Windows
+        //  mausId: Werte aus dem Namespace MausId
+        // beispiel: ladeMaus( MausId::hand );
+		__declspec( dllexport ) void ladeMaus( int mausId );
+        // Kopiert ein Bild und verwendet es als Mauszeiger.
+        //  maus: Das Bild, was als Mauszeiger verwendet werden soll
+		__declspec( dllexport ) void ladeMaus( Bild *maus );
+        // Akzualisiert die Maus. Wird vom Framework selbst aufgerufen
+		__declspec( dllexport ) void update();
+        // gibt ein Händle zur maus zurück
+		__declspec( dllexport ) HCURSOR getMausHandle();
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) Maus *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) Maus *release();
+	};
+}
+
+#endif

+ 8 - 0
MausEreignis.cpp

@@ -0,0 +1,8 @@
+#include "MausEreignis.h"
+
+using namespace Framework;
+
+bool Framework::_ret1ME( void *param, void *obj, MausEreignis me )
+{
+	return 1;
+}

+ 54 - 0
MausEreignis.h

@@ -0,0 +1,54 @@
+#ifndef MausEreignis_H
+#define MausEreignis_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+	const int M_Links = 0;
+	const int M_Mitte = 1;
+	const int M_Rechts = 2;
+	const int ME_PLinks = 0;
+	const int ME_PRechts = 1;
+	const int ME_PMitte = 2;
+	const int ME_RLinks = 3;
+	const int ME_RRechts = 4;
+	const int ME_RMitte = 5;
+	const int ME_DKLinks = 6;
+	const int ME_DKRechts = 7;
+	const int ME_DKMitte = 8;
+	const int ME_Betritt = 9;
+	const int ME_Verlässt = 10;
+	const int ME_Bewegung = 11;
+	const int ME_UScroll = 12;
+	const int ME_DScroll = 13;
+	const int ME_RScroll = 14;
+	const int ME_LScroll = 15;
+
+    // Speichert eine bestimmte Mauseingabe des Nutzers
+	struct MausEreignis
+	{
+        // Art der Eingabe
+		int id;
+        // X koordinate auf dem Bildschirm relativ zur Zeichnungposition
+		int mx;
+        // Y Koordinate auf dem Bildschirm relativ zur Zeichnungposition
+		int my;
+        // X Koordinate auf dem Bildschirm zur linken oberen Ecke
+		int rmx;
+        // Y Koordinate auf dem Bildschirm zur linken oberen Ecke
+		int rmy;
+        // Speichert, ob die Eingabe bereits verarbeitet wurde
+		bool verarbeitet;
+	};
+
+    // Standart Maus Ereinis Rückruffunktion
+    //  param: Ein beliebiger Parameter
+    //  obj: Das Zeichnung, welches diese Funktion aufruft
+    //  te: Das Mausereignis, welches verarbeitet werden soll
+    //  return: (true), wenn aufrufende Zeichnung das Ereignis weiterverarbeiten soll. (false) sonnst.
+    // Gibt immer (true) zurück
+	__declspec( dllexport ) bool _ret1ME( void *param, void *obj, MausEreignis me );
+}
+
+#endif

+ 754 - 0
Model2D.cpp

@@ -0,0 +1,754 @@
+#include "Model2D.h"
+#include "Bild.h"
+#include "FrameworkMath.h"
+#include "Mat3.h"
+#ifdef WIN32
+#include "MausEreignis.h"
+#endif
+
+using namespace Framework;
+
+// Inhalt der Model2DData Klasse aus Model2D.h
+// Konstruktor
+Model2DData::Model2DData()
+	: polygons( 0 ),
+	  vListen( 0 ),
+	  minP( 0, 0 ),
+	  maxP( 0, 0 )
+{
+	ref = 1;
+}
+
+// Destruktor
+Model2DData::~Model2DData()
+{
+	if( polygons )
+	{
+		int anz = polygons->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+#ifdef WIN32
+			if( polygons->get( i ).tKordinaten )
+				polygons->get( i ).tKordinaten->release();
+#endif
+			if( polygons->get( i ).vertex )
+				polygons->get( i ).vertex->release();
+		}
+		polygons = polygons->release();
+	}
+	if( vListen )
+		vListen->release();
+}
+
+// privat
+bool Model2DData::istPunktInnen( Vertex p, int polygonId ) const
+{
+	if( p < minP || p > maxP || !polygons )
+		return 0;
+	int num = 0;
+	for( auto *polygon = &polygons->getArray(); polygon && polygon->set; polygon = polygon->next, num++ )
+	{
+		if( polygonId >= 0 && num != polygonId )
+			continue;
+		int anz = polygon->var.vertex->getEintragAnzahl();
+		int ola = outList.z( num )->getEintragAnzahl();
+		bool c = 0;
+		int j = anz - 1;
+		for( int k = 0; k < ola; k++ )
+		{
+			Punkt out = outList.z( num )->get( k );
+			if( out.x < out.y && j > out.x && j < out.y )
+				j = out.x;
+			if( out.x > out.y && ( j > out.x || j < out.y ) )
+				j = out.x;
+		}
+		for( int i = 0; i < anz; i++ )
+		{
+			bool cont = 0;
+			for( int k = 0; k < ola; k++ )
+			{
+				Punkt out = outList.z( num )->get( k );
+				if( out.x < out.y && i > out.x && i < out.y )
+					cont = 1;
+				if( out.x > out.y && ( i > out.x || i < out.y ) )
+					cont = 1;
+			}
+			if( cont )
+				continue;
+			Vertex a = polygon->var.vertex->get( i );
+			Vertex b = polygon->var.vertex->get( j );
+			if( ( ( a.y >= p.y ) != ( b.y >= p.y ) ) && ( p.x <= ( b.x - a.x ) * ( p.y - a.y ) / (float)( b.y - a.y ) + a.x ) )
+				c = !c;
+			j = i;
+		}
+		if( c )
+			return 1;
+	}
+	return 0;
+}
+
+bool Model2DData::istLinieInnen( Vertex a, Vertex b, int polygonId ) const
+{
+	if( !polygons )
+		return 0;
+	int pAnz = polygons->getEintragAnzahl();
+	for( int p = 0; p < pAnz; p++ )
+	{
+		if( polygonId >= 0 && p != polygonId )
+			continue;
+		int ola = outList.z( p )->getEintragAnzahl();
+		int anz = polygons->get( p ).vertex->getEintragAnzahl();
+		int j = anz - 1;
+		for( int k = 0; k < ola; k++ )
+		{
+			Punkt out = outList.z( p )->get( k );
+			if( out.x < out.y && j > out.x && j < out.y )
+				j = out.x;
+			if( out.x > out.y && ( j > out.x || j < out.y ) )
+				j = out.x;
+		}
+		for( int i = 0; i < anz; i++ )
+		{
+			bool cont = 0;
+			for( int k = 0; k < ola; k++ )
+			{
+				Punkt out = outList.z( p )->get( k );
+				if( out.x < out.y && i > out.x && i < out.y )
+					cont = 1;
+				if( out.x > out.y && ( i > out.x || i < out.y ) )
+					cont = 1;
+			}
+			if( cont )
+				continue;
+			Punkt va = polygons->get( p ).vertex->get( i );
+			Punkt vb = polygons->get( p ).vertex->get( j );
+			if( (Punkt)a == va && (Punkt)b == vb )
+				return 1;
+			if( (Punkt)a == vb && (Punkt)b == va )
+				return 1;
+			j = i;
+		}
+		Vertex län = b - a;
+		Vertex speed( län.x > 0 ? 1 : -1.f, län.y > 0 ? 1 : -1.f );
+		int mLän = 0;
+		if( fabs( län.x ) > fabs( län.y ) )
+		{
+			mLän = (int)fabs( län.x );
+			speed.y = län.y / (float)fabs( län.x );
+		}
+		else
+		{
+			mLän = (int)fabs( län.y );
+			speed.x = län.x / (float)fabs( län.y );
+		}
+		int i = 1;
+		bool inside = 1;
+		for( Vertex vp = speed + a; (Punkt)vp != (Punkt)( b - speed ) && inside && i < mLän - 1; vp += speed, i++ )
+			inside &= istPunktInnen( vp, p );
+		if( inside )
+			return 1;
+	}
+	return 0;
+}
+
+// nicht constant
+bool Model2DData::erstelleModell( Array< Polygon2D > *polygons )
+{
+	löscheModell();
+    if( !polygons || !polygons->getEintragAnzahl() )
+    {
+        this->polygons = polygons;
+        vListen = new RCArray< RCArray< DreieckListe< Vertex > > >();
+        return 1;
+    }
+	this->polygons = polygons;
+	int pAnz = polygons->getEintragAnzahl();
+	vListen = new RCArray< RCArray< DreieckListe< Vertex > > >();
+	for( int p = 0; p < pAnz; p++ )
+	{
+		Polygon2D pg = polygons->get( p );
+		if( !pg.vertex || pg.vertex->getEintragAnzahl() < 3 )
+			continue;
+		vListen->add( new RCArray< DreieckListe< Vertex > >() );
+		outList.set( new Array< Punkt >, p );
+		int vAnz = pg.vertex->getEintragAnzahl();
+		bool textur = pg.tKordinaten != 0;
+		for( int i = 0; i < vAnz && textur; i++ )
+			textur &= pg.tKordinaten->hat( i );
+		for( int i = 0; i < vAnz; i++ )
+		{
+			if( maxP.x < fabs( pg.vertex->get( i ).x ) )
+				maxP.x = abs( (int)pg.vertex->get( i ).x ) + 1;
+			if( maxP.y < fabs( pg.vertex->get( i ).y ) )
+				maxP.y = abs( (int)pg.vertex->get( i ).y ) + 1;
+		}
+		minP = -maxP;
+		if( !textur )
+		{
+			if( pg.tKordinaten )
+				pg.tKordinaten->leeren();
+		}
+		RCArray< RCArray< DreieckListe< Vertex > > > lists;
+		int lauf = 0;
+		while( 1 )
+		{
+			lists.set( new RCArray< DreieckListe< Vertex > >(), lauf );
+			outList.z( p )->set( Punkt( 0, 0 ), lauf );
+			bool fertig = 0;
+			Vertex a;
+			Vertex b;
+			Array< Punkt > tmpOutList;
+			for( int i = 0; i < vAnz; i++ )
+			{
+				bool cont = 0;
+				int vorher = i - 1;
+				int nachher = i + 1;
+				if( nachher >= vAnz )
+					nachher = 0;
+				if( vorher < 0 )
+					vorher = vAnz - 1;
+				int ola = outList.z( p )->getEintragAnzahl();
+				for( int j = 0; j < ola; j++ )
+				{
+					Punkt out = outList.z( p )->get( j );
+					if( out.x < out.y )
+					{
+						if( nachher > out.x && nachher < out.y )
+							nachher = out.y;
+						if( vorher > out.x && vorher < out.y )
+							vorher = out.x;
+					}
+					if( out.x > out.y )
+					{
+						if( nachher > out.x || nachher < out.y )
+							nachher = out.y;
+						if( vorher > out.x || vorher < out.y )
+							vorher = out.x;
+					}
+					if( out.x < out.y && i > out.x && i < out.y )
+						cont = 1;
+					if( out.x > out.y && ( i > out.x || i < out.y ) )
+						cont = 1;
+				}
+				if( cont )
+					continue;
+				if( vorher < 0 )
+					a = pg.vertex->get( vAnz + vorher );
+				else
+					a = pg.vertex->get( vorher );
+				if( nachher > vAnz - 1 )
+					b = pg.vertex->get( nachher - vAnz + 1 );
+				else
+					b = pg.vertex->get( nachher );
+				if( istLinieInnen( a, b, p ) )
+				{
+					DreieckListe< Vertex > *lowL = new DreieckListe< Vertex >();
+					DreieckListe< Vertex > *hightL = new DreieckListe< Vertex >();
+					lowL->addPunkt( new Vertex( pg.vertex->get( i ) ), textur ? new Punkt( pg.tKordinaten->get( i ) ) : 0 );
+					hightL->addPunkt( new Vertex( pg.vertex->get( i ) ), textur ? new Punkt( pg.tKordinaten->get( i ) ) : 0 );
+					int hight = i + 1;
+					int low = i - 1;
+					Punkt outL( 0, 0 );
+					Punkt outH( 0, 0 );
+					for( int k = 0; k < 2; k++ )
+					{
+						bool lowp = !k;
+						while( 1 )
+						{
+							if( hight >= vAnz )
+								hight = 0;
+							if( low < 0 )
+								low = vAnz - 1;
+							for( int j = 0; j <= lauf; j++ )
+							{
+								Punkt out = outList.z( p )->get( j );
+								if( out.x < out.y )
+								{
+									if( hight > out.x && hight < out.y )
+										hight = out.y;
+									if( low > out.x && low < out.y )
+										low = out.x;
+								}
+								if( out.x > out.y )
+								{
+									if( hight > out.x || hight < out.y )
+										hight = out.y;
+									if( low > out.x || low < out.y )
+										low = out.x;
+								}
+							}
+							Vertex a = pg.vertex->get( hight );
+							Vertex b = pg.vertex->get( low );
+							if( low == hight )
+							{
+								fertig = 1;
+								outList.z( p )->set( Punkt( 0, 0 ), lauf );
+								if( !k )
+									lowL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
+								else
+									hightL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
+								break;
+							}
+							bool inside = istLinieInnen( a, b, p );
+							if( inside )
+							{
+								if( !k )
+									outL = Punkt( low, hight );
+								else
+									outH = Punkt( low, hight );
+								outList.z( p )->set( Punkt( low, hight ), lauf );
+							}
+							if( lowp )
+							{
+								if( !k )
+									lowL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
+								else
+									hightL->addPunkt( new Vertex( b ), textur ? new Punkt( pg.tKordinaten->get( low ) ) : 0 );
+								low--;
+							}
+							else
+							{
+								if( !k )
+									lowL->addPunkt( new Vertex( a ), textur ? new Punkt( pg.tKordinaten->get( hight ) ) : 0 );
+								else
+									hightL->addPunkt( new Vertex( a ), textur ? new Punkt( pg.tKordinaten->get( hight ) ) : 0 );
+								hight++;
+							}
+							lowp = !lowp;
+							if( !inside )
+							{
+								hight = i + 1;
+								low = i - 1;
+								outList.z( p )->set( Punkt( 0, 0 ), lauf );
+								break;
+							}
+						}
+						if( fertig )
+							break;
+					}
+					if( lowL->getDreieckAnzahl() > hightL->getDreieckAnzahl() )
+					{
+						lists.z( lauf )->set( lowL, i );
+						tmpOutList.set( outL, i );
+						hightL->release();
+					}
+					else
+					{
+						lists.z( lauf )->set( hightL, i );
+						tmpOutList.set( outH, i );
+						lowL->release();
+					}
+				}
+				else
+					lists.z( lauf )->set( new DreieckListe< Vertex >(), i );
+				if( fertig )
+					break;
+			}
+			int maxP = -1;
+			int max = 0;
+			for( int i = 0; i < vAnz; i++ )
+			{
+				if( lists.z( lauf )->z( i ) && lists.z( lauf )->z( i )->getDreieckAnzahl() > max )
+				{
+					max = lists.z( lauf )->z( i )->getDreieckAnzahl();
+					maxP = i;
+				}
+			}
+			if( !max || maxP < 0 )
+				break;
+			vListen->z( p )->add( lists.z( lauf )->get( maxP ) );
+			outList.z( p )->set( tmpOutList.get( maxP ), lauf );
+			if( fertig )
+				break;
+			lauf++;
+		}
+		outList.z( p )->leeren();
+	}
+	return 1;
+}
+
+void Model2DData::löscheModell() // setzt die Vertex daten zurück
+{
+	if( polygons )
+	{
+		int anz = polygons->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			if( polygons->get( i ).tKordinaten )
+				polygons->get( i ).tKordinaten->release();
+			if( polygons->get( i ).vertex )
+				polygons->get( i ).vertex->release();
+		}
+		polygons = polygons->release();
+	}
+	if( vListen )
+		vListen = vListen->release();
+	outList.leeren();
+	minP = Punkt( 0, 0 );
+	maxP = Punkt( 0, 0 );
+}
+
+// Reference Counting
+Model2DData *Model2DData::getThis()
+{
+	ref++;
+	return this;
+}
+
+Model2DData *Model2DData::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der Model2D Klasse aus Model2D.h
+// Konstruktor
+Model2D::Model2D()
+#ifdef WIN32
+	: Zeichnung(),
+	  textur( 0 )
+#endif
+{
+#ifdef WIN32
+	farbe = 0;
+	style = 0;
+#else
+	pos = Punkt( 0, 0 );
+#endif
+	rData = 0;
+	drehung = 0;
+	größe = 1;
+	ref = 1;
+}
+
+// Destruktor
+Model2D::~Model2D()
+{
+	if( rData )
+		rData->release();
+#ifdef WIN32
+	if( textur )
+		textur->release();
+#endif
+}
+
+// nicht constant
+void Model2D::setModel( Model2DData *mdl )
+{
+	if( rData )
+		rData->release();
+	rData = mdl;
+}
+
+void Model2D::setDrehung( float drehung )
+{
+	this->drehung = drehung;
+	while( this->drehung > PI * 2 )
+		this->drehung -= (float)PI * 2;
+	while( this->drehung < 0 )
+		this->drehung += (float)PI * 2;
+#ifdef WIN32
+	rend = 1;
+#endif
+}
+
+void Model2D::addDrehung( float drehung )
+{
+	this->drehung += drehung;
+	while( this->drehung > PI * 2 )
+		this->drehung -= (float)PI * 2;
+	while( this->drehung < 0 )
+		this->drehung += (float)PI * 2;
+#ifdef WIN32
+	rend = 1;
+#endif
+}
+
+void Model2D::setGröße( float größe )
+{
+	this->größe = größe;
+#ifdef WIN32
+	rend = 1;
+#endif
+}
+
+void Model2D::addGröße( float größe )
+{
+	this->größe += größe;
+#ifdef WIN32
+	rend = 1;
+#endif
+}
+#ifdef WIN32
+void Model2D::setTextur( Bild *t )
+{
+	if( textur )
+		textur->release();
+	textur = t;
+}
+
+void Model2D::setFarbe( int f )
+{
+	farbe = f;
+	rend = 1;
+}
+
+void Model2D::doMausEreignis( MausEreignis &me )
+{
+	if( !Mak || me.verarbeitet || !istPunktInnen( Punkt( me.mx, me.my ) )  )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	Mak( makParam, this, me );
+	me.mx += pos.x;
+	me.my += pos.y;
+    me.verarbeitet = 1;
+}
+
+bool Model2D::tick( double tickVal )
+{
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Model2D::render( Bild &zRObj )
+{
+	if( !rData || hatStyleNicht( Model2D::Style::Sichtbar ) || !rData->polygons )
+		return;
+    __super::render( zRObj );
+	int num = 0;
+	for( auto *p = &rData->vListen->getArray(); p && p->set; p = p->next, num++ )
+	{
+		Mat3< float > mat = Mat3< float >::translation( pos ) * Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
+		if( hatStyle( Model2D::Style::Textur ) )
+		{
+			if( !textur || !rData->polygons->get( num ).tKordinaten )
+			{
+				for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
+				{
+					for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
+					{
+						Vertex a = mat * *j->var->punkt;
+						Vertex b = mat * *j->next->var->punkt;
+						Vertex c = mat * *j->next->next->var->punkt;
+						if( hatStyle( Model2D::Style::Alpha ) )
+							zRObj.drawDreieckAlpha( a, b, c, farbe );
+						else
+							zRObj.drawDreieck( a, b, c, farbe );
+					}
+				}
+			}
+			else
+			{
+				for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
+				{
+					for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
+					{
+						Vertex a = mat * *j->var->punkt;
+						Vertex b = mat * *j->next->var->punkt;
+						Vertex c = mat * *j->next->next->var->punkt;
+						if( hatStyle( Model2D::Style::Alpha ) )
+							zRObj.drawDreieckTexturAlpha( a, b, c, *j->var->textur, *j->next->var->textur, *j->next->next->var->textur, *textur );
+						else
+							zRObj.drawDreieckTextur( a, b, c, *j->var->textur, *j->next->var->textur, *j->next->next->var->textur, *textur );
+					}
+				}
+			}
+		}
+		if( hatStyle( Model2D::Style::Mesh ) )
+		{
+			for( auto *i = &p->var->getArray(); i && i->set; i = i->next )
+			{
+				for( auto *j = &i->var->zListe()->getArray(); j->next->next && j->next->next->set; j = j->next )
+				{
+					Vertex a = mat * *j->var->punkt;
+					Vertex b = mat * *j->next->var->punkt;
+					Vertex c = mat * *j->next->next->var->punkt;
+					if( hatStyle( Model2D::Style::Alpha ) )
+					{
+						zRObj.drawLinieAlpha( a, b, farbe );
+						zRObj.drawLinieAlpha( b, c, farbe );
+						zRObj.drawLinieAlpha( c, a, farbe );
+					}
+					else
+					{
+						zRObj.drawLinie( a, b, farbe );
+						zRObj.drawLinie( b, c, farbe );
+						zRObj.drawLinie( c, a, farbe );
+					}
+				}
+			}
+		}
+		if( hatStyle( Model2D::Style::Rahmen ) )
+		{
+			ArrayEintrag< Vertex > &beg = rData->polygons->get( num ).vertex->getArray();
+			if( beg.set )
+			{
+				ArrayEintrag< Vertex > *letzter = 0;
+				for( ArrayEintrag< Vertex > *e = &beg; e && e->next && e->set && e->next->set; e = e->next )
+				{
+					if( hatStyle( Model2D::Style::Alpha ) )
+						zRObj.drawLinieAlpha( mat * e->var, mat * e->next->var, farbe );
+					else
+						zRObj.drawLinie( mat * e->var, mat * e->next->var, farbe );
+					letzter = e->next;
+				}
+				if( letzter && letzter->set )
+				{
+					if( hatStyle( Model2D::Style::Alpha ) )
+						zRObj.drawLinieAlpha( mat * letzter->var, mat * beg.var, farbe );
+					else
+						zRObj.drawLinie( mat * letzter->var, mat * beg.var, farbe );
+				}
+			}
+		}
+	}
+}
+#else
+void Model2D::setPosition( Punkt p )
+{
+	pos = p;
+}
+#endif
+// constant
+float Model2D::getDrehung() const
+{
+	return drehung;
+}
+
+float Model2D::getGröße() const
+{
+	return größe;
+}
+
+bool Model2D::istPunktInnen( Vertex p ) const
+{
+	if( !rData )
+		return 0;
+	p -= pos;
+	if( p < Mat3< float >::scaling( größe ) * rData->minP || p > Mat3< float >::scaling( größe ) * rData->maxP || !rData->polygons )
+		return 0;
+	int num = 0;
+	for( auto *polygon = &rData->polygons->getArray(); polygon && polygon->set; polygon = polygon->next, num++ )
+	{
+		Mat3< float > mat = Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
+		int anz = polygon->var.vertex->getEintragAnzahl();
+		bool c = 0;
+		int j = anz - 1;
+		for( int i = 0; i < anz; i++ )
+		{
+			Vertex a = mat * polygon->var.vertex->get( i );
+			Vertex b = mat * polygon->var.vertex->get( j );
+			if( ( ( a.y >= p.y ) != ( b.y >= p.y ) ) && ( p.x <= ( b.x - a.x ) * ( p.y - a.y ) / (float)( b.y - a.y ) + a.x ) )
+				c = !c;
+			j = i;
+		}
+		if( c )
+			return 1;
+	}
+	return 0;
+}
+
+bool Model2D::istLinieInnen( Vertex a, Vertex b ) const
+{
+	if( !rData || !rData->polygons )
+		return 0;
+	int pAnz = rData->polygons->getEintragAnzahl();
+	for( int p = 0; p < pAnz; p++ )
+	{
+		Mat3< float > mat = Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
+		int anz = rData->polygons->get( p ).vertex->getEintragAnzahl();
+		int j = anz - 1;
+		for( int i = 0; i < anz; i++ )
+		{
+			Punkt va = mat * rData->polygons->get( p ).vertex->get( i );
+			Punkt vb = mat * rData->polygons->get( p ).vertex->get( j );
+			if( (Punkt)a == pos + va && (Punkt)b == pos + vb )
+				return 1;
+			if( (Punkt)a == pos + vb && (Punkt)b == pos + va )
+				return 1;
+			j = i;
+		}
+		Vertex län = b - a;
+		Vertex speed( län.x > 0 ? 1 : -1.f, län.y > 0 ? 1 : -1.f );
+		int mLän = 0;
+		if( fabs( län.x ) > fabs( län.y ) )
+		{
+			mLän = (int)fabs( län.x );
+			speed.y = län.y / (float)fabs( län.x );
+		}
+		else
+		{
+			mLän = (int)fabs( län.y );
+			speed.x = län.x / (float)fabs( län.y );
+		}
+		int i = 1;
+		bool inside = 1;
+		for( Vertex vp = speed + a; (Punkt)vp != (Punkt)( b - speed ) && inside && i < mLän - 1; vp += speed, i++ )
+			inside &= istPunktInnen( vp );
+		if( inside )
+			return 1;
+	}
+	return 0;
+}
+
+bool Model2D::istModelInnen( const Model2D *zMdl, bool end ) const
+{
+	if( !end )
+	{
+		Vertex min = (Vertex)rData->minP * größe + pos;
+		Vertex max = (Vertex)rData->maxP * größe + pos;
+		Vertex min2 = (Vertex)zMdl->zModel()->minP * zMdl->getGröße() + zMdl->getPosition();
+		Vertex max2 = (Vertex)zMdl->zModel()->maxP * zMdl->getGröße() + zMdl->getPosition();
+		if( max.x < min2.x || min.x > max2.x || max.y < min2.y || min.y > max2.y )
+			return 0;
+	}
+	Mat3< float > mat = Mat3< float >::translation( pos ) * Mat3< float >::rotation( drehung ) * Mat3< float >::scaling( größe );
+	for( auto *polygon = &rData->polygons->getArray(); polygon && polygon->set; polygon = polygon->next )
+	{
+		int anz = polygon->var.vertex->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			if( zMdl->istPunktInnen( mat * polygon->var.vertex->get( i ) ) )
+				return 1;
+		}
+	}
+	if( end )
+		return 0;
+	return zMdl->istModelInnen( this, 1 );
+}
+
+Model2DData *Model2D::getModel() const
+{
+	return rData ? rData->getThis() : 0;
+}
+
+Model2DData *Model2D::zModel() const
+{
+	return rData;
+}
+#ifndef WIN32
+Punkt Model2D::getPosition() const
+{
+	return pos;
+}
+#endif
+
+// Reference Counting
+Model2D *Model2D::getThis()
+{
+	++ref;
+	return this;
+}
+
+Model2D *Model2D::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 117 - 0
Model2D.h

@@ -0,0 +1,117 @@
+#ifndef Model2D_H
+#define Model2D_H
+
+#ifdef WIN32
+#include "Zeichnung.h"
+#endif
+#include "Punkt.h"
+#include "Array.h"
+#include "DreieckListe.h"
+#include "Vec3.h"
+
+namespace Framework
+{
+	typedef Vec2< float > Vertex;
+	class Bild;
+
+	// Model2D Klasse löscht die Zeiger
+	struct Polygon2D
+	{
+		Array< Vertex > *vertex;
+		Array< Punkt > *tKordinaten;
+	};
+
+	class Model2DData
+	{
+	private:
+		RCArray< Array< Punkt > > outList;
+		int ref;
+
+		// privat
+		bool istPunktInnen( Vertex p, int polygonId = -1 ) const;
+		bool istLinieInnen( Vertex a, Vertex b, int polygonId = -1 ) const;
+
+	public:
+		Array< Polygon2D > *polygons;
+		RCArray< RCArray< DreieckListe< Vertex > > > *vListen;
+		Punkt minP, maxP;
+
+		// Konstruktor
+		__declspec( dllexport ) Model2DData();
+		// Destruktor
+		__declspec( dllexport ) ~Model2DData();
+		// nicht constant
+		__declspec( dllexport ) bool erstelleModell( Array< Polygon2D > *polygons );
+		__declspec( dllexport ) void löscheModell(); // setzt die Vertex daten zurück
+		// Reference Counting
+		__declspec( dllexport ) Model2DData *getThis();
+		__declspec( dllexport ) Model2DData *release();
+	};
+
+#ifdef WIN32
+	class Model2D : public Zeichnung
+#else
+	class Model2D
+#endif
+	{
+    public:
+#ifdef WIN32
+        class Style : public Zeichnung::Style
+        {
+        public:
+            const static __int64 Textur = 0x8;
+            const static __int64 Rahmen = 0x10;
+            const static __int64 Alpha = 0x40;
+            const static __int64 Mesh = 0x20;
+        };
+#endif
+	private:
+		Model2DData *rData;
+		float drehung;
+		float größe;
+		int ref;
+#ifdef WIN32
+		int farbe;
+		Bild *textur;
+#else
+		Punkt pos;
+#endif
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) Model2D();
+		// Destruktor
+		__declspec( dllexport ) ~Model2D();
+		// nicht constant
+		__declspec( dllexport ) void setModel( Model2DData *mdl );
+		__declspec( dllexport ) void setDrehung( float drehung );
+		__declspec( dllexport ) void addDrehung( float drehung );
+		__declspec( dllexport ) void setGröße( float größe );
+		__declspec( dllexport ) void addGröße( float größe );
+#ifdef WIN32
+		__declspec( dllexport ) void setTextur( Bild *t );
+		__declspec( dllexport ) void setFarbe( int f );
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+		__declspec( dllexport ) bool tick( double tickVal ) override;
+		__declspec( dllexport ) void render( Bild &zRObj ) override;
+#else
+		__declspec( dllexport ) void setPosition( Punkt p );
+#endif
+		// constant
+		__declspec( dllexport ) float getDrehung() const;
+		__declspec( dllexport ) float getGröße() const;
+		__declspec( dllexport ) bool istPunktInnen( Vertex p ) const;
+		__declspec( dllexport ) bool istLinieInnen( Vertex a, Vertex b ) const;
+		__declspec( dllexport ) bool istModelInnen( const Model2D *zMdl, bool end = 0 ) const;
+		__declspec( dllexport ) Model2DData *getModel() const;
+		__declspec( dllexport ) Model2DData *zModel() const;
+#ifndef WIN32
+		Punkt getPosition() const;
+#endif
+		// Reference Counting
+		__declspec( dllexport ) Model2D *getThis();
+		__declspec( dllexport ) Model2D *release();
+	};
+}
+
+#endif

+ 324 - 0
Model3D.cpp

@@ -0,0 +1,324 @@
+#include "Model3D.h"
+#include "Render3D.h"
+#include "Model2D.h"
+#include "DXBuffer.h"
+#include "Textur.h"
+#include <d3d11.h>
+
+using namespace Framework;
+
+// Inhalt des Polygon3D Struct
+
+// Konstruktor
+Polygon3D::Polygon3D()
+{
+    indexAnz = 0;
+    indexList = 0;
+    indexBuffer = new DXIndexBuffer( sizeof( int ) );
+}
+
+// Destruktor
+Polygon3D::~Polygon3D()
+{
+    indexBuffer->release();
+    delete[] indexList;
+}
+
+// Inhalt der Model3DData Klasse
+
+// Konstruktor
+Model3DData::Model3DData()
+{
+    id = -1;
+    vertexList = 0;
+    polygons = new Array< Polygon3D* >();
+    vertexBuffer = new DXVertexBuffer( sizeof( Vertex3D ) );
+    radius = 0;
+    ref = 1;
+}
+
+// Destruktor
+Model3DData::~Model3DData()
+{
+    clearModel();
+    vertexBuffer->release();
+    polygons->release();
+}
+
+// Löscht alle Model daten
+void Model3DData::clearModel()
+{
+    delete[] vertexList;
+    vertexList = 0;
+    for( auto i = polygons->getArray(); i.set; i++ )
+        delete i.var;
+    polygons->leeren();
+}
+
+// Setzt einen Zeiger auf eine Liste mit allen Vertecies des Models
+//  vertexList: Ein Array mit Vertecies
+        //  anz: Die Anzahl der Vertecies im Array
+void Model3DData::setVertecies( Vertex3D *vertexList, int anz )
+{
+    clearModel();
+    this->vertexList = vertexList;
+    vertexBuffer->setData( vertexList );
+    vertexBuffer->setLänge( sizeof( Vertex3D ) * anz );
+    radius = 0;
+    for( int i = 0; i < anz; i++ )
+    {
+        float r = vertexList[ i ].pos.län();
+        if( r > radius )
+            radius = r;
+    }
+}
+
+// Fügt ein Polygon zum Model hinzu
+//  polygon: Das Polygon, das hinzugefügt erden soll
+void Model3DData::addPolygon( Polygon3D *polygon )
+{
+    polygons->add( polygon );
+}
+
+// Konvertiert ein 2d Model zu 3D
+//  model: Das 2d Model, das zu 3d konvertiert werden soll
+//  z: Die z koordinate aller punkte des Models
+void Model3DData::copyModel2D( Model2DData *model, float z )
+{
+    if( model && model->vListen && model->polygons )
+    {
+        clearModel();
+        int vAnz = 0;
+        for( auto i = model->polygons->getArray(); i.set; i++ )
+            vAnz += i.var.vertex->getEintragAnzahl();
+        vertexList = new Vertex3D[ vAnz ];
+        vertexBuffer->setData( vertexList );
+        vertexBuffer->setLänge( sizeof( Vertex3D ) * vAnz );
+        int index = 0;
+        for( auto i = model->vListen->getArray(); i.set; i++ )
+        {
+            Polygon3D *p = new Polygon3D();
+            p->indexAnz = 0;
+            for( auto j = i.var->getArray(); j.set; j++ )
+            {
+                for( auto *k = &j.var->zListe()->getArray(); k->next->next && k->next->next->set; k = k->next )
+                    p->indexAnz += 3;
+            }
+            p->indexList = new int[ p->indexAnz ];
+            p->indexBuffer->setData( p->indexList );
+            p->indexBuffer->setLänge( sizeof( int ) * p->indexAnz );
+            p->indexAnz = 0;
+            for( auto j = i.var->getArray(); j.set; j++ )
+            {
+                for( auto *k = &j.var->zListe()->getArray(); k && k->set; k = k->next )
+                {
+                    vertexList[ index ].pos = Vec3< float >( k->var->punkt->x, k->var->punkt->y, z );
+                    vertexList[ index ].tPos = (Vec2< float >)*k->var->textur;
+                    if( k->next && k->next->set && k->next->next && k->next->next->set )
+                    {
+                        p->indexList[ p->indexAnz ] = index;
+                        p->indexAnz++;
+                        p->indexList[ p->indexAnz ] = index + 1;
+                        p->indexAnz++;
+                        p->indexList[ p->indexAnz ] = index + 2;
+                        p->indexAnz++;
+                    }
+                    index++;
+                }
+            }
+            addPolygon( p );
+        }
+    }
+}
+
+// Entfernt ein Polygon
+//  index: Der Index des Polygons
+void Model3DData::removePolygon( int index )
+{
+    if( !polygons->hat( index ) )
+        return;
+    delete polygons->get( index );
+    polygons->lösche( index );
+}
+
+// Zeichnet alle Polygons
+//  world: Die Welt Matrix, die das Model in die Welt transformiert
+//  zTxt: Eine Liste mit Texturen der einzelnen Polygone
+//  zRObj: Das Objekt, mit dem gezeichnet werden soll
+void Model3DData::render( Mat4< float > &welt, const Model3DTextur *zTxt, Render3D *zRObj )
+{
+    vertexBuffer->copieren( zRObj );
+    zRObj->beginnModel( welt, vertexBuffer, id );
+    int ind = 0;
+    for( auto *i = &polygons->getArray(); i && i->set; i = i->next )
+    {
+        i->var->indexBuffer->copieren( zRObj );
+        Textur *t = zTxt->zPolygonTextur( ind );
+        if( t && t->brauchtUpdate() )
+            t->updateTextur( zRObj );
+        zRObj->draw( i->var->indexBuffer, t );
+        ind++;
+    }
+}
+
+// Gibt die Anzahl an Polygonen zurück
+int Model3DData::getPolygonAnzahl()
+{
+    return polygons->getEintragAnzahl();
+}
+
+// Gibt ein bestimmtes Polygon zurück
+//  index: Der Index des Polygons
+Polygon3D *Model3DData::getPolygon( int index )
+{
+    if( !polygons->hat( index ) )
+        return 0;
+    return polygons->get( index );
+}
+
+// Gibt den radius einer Kugel zurück, die das gesammte Model umschließt
+float Model3DData::getRadius() const
+{
+    return radius;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Model3DData *Model3DData::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Model3DData *Model3DData::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der Model3DTextur
+
+// Konstruktor
+Model3DTextur::Model3DTextur()
+{
+    textures = new RCArray< Textur >();
+    ref = 1;
+}
+
+// Destruktor
+Model3DTextur::~Model3DTextur()
+{
+    textures->release();
+}
+
+// Legt fest, welche Textur für welches Polygon ist
+//  pI: Der Index des Polygons
+//  txt: Die Textur des Polygons
+void Model3DTextur::setPolygonTextur( int pI, Textur *txt )
+{
+    textures->set( txt, pI );
+}
+
+// Gibt einen Zeiger auf die Textur eines Polygons zurück ohne erhöhten Reference Counter
+//  i: Der Index des Polygons
+Textur *Model3DTextur::zPolygonTextur( int i ) const
+{
+    return textures->z( i );
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Model3DTextur *Model3DTextur::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Model3DTextur *Model3DTextur::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der Model3D Klasse
+// Konstruktor
+Model3D::Model3D()
+    : Zeichnung3D()
+{
+    model = 0;
+    textur = 0;
+    ref = 1;
+}
+
+// Destruktor
+Model3D::~Model3D()
+{
+    if( model )
+        model->release();
+    if( textur )
+        textur->release();
+}
+
+// Setzt die Daten des Models
+//  data: Die Daten
+void Model3D::setModelDaten( Model3DData *data )
+{
+    if( model )
+        model->release();
+    model = data;
+}
+
+// Setzt die zum Zeichnen zu benutzenden Texturen
+//  txt: Ein Liste mit Texturen zu den verschiedenen Polygonen zugeordnet
+void Model3D::setModelTextur( Model3DTextur *txt )
+{
+    if( textur )
+        textur->release();
+    textur = txt;
+}
+
+// Verarbeitet die vergangene Zeit
+//  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+//  return: true, wenn sich das Objekt verändert hat, false sonnst.
+bool Model3D::tick( double tickval )
+{
+    radius = model ? model->getRadius() : 0;
+    return __super::tick( tickval );
+}
+
+// Zeichnet das Model
+//  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+void Model3D::render( Render3D *zRObj )
+{
+    if( !model )
+        return;
+    model->render( welt, textur, zRObj );
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Model3D *Model3D::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Model3D *Model3D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 192 - 0
Model3D.h

@@ -0,0 +1,192 @@
+#pragma once
+
+#include "vec2.h"
+#include "Array.h"
+#include "Mat4.h"
+#include "Zeichnung3D.h"
+
+struct ID3D11Buffer;
+
+namespace Framework
+{
+    struct Polygon2D; // Model2D.h
+    class Textur; // Textur.h
+    class Model2DData; // Model2D.h
+    class DXIndexBuffer; // DXBuffer.h
+    class DXVertexBuffer; // DXBuffer.h
+    class Render3D; // Render3D.h
+    class Model3DTextur; // Model3D.h
+    class Model3DList; // Model3DList.h
+
+    struct Vertex3D
+    {
+        Vec3< float > pos;
+        Vec2< float > tPos;
+    };
+
+    class Knochen
+    {
+    private:
+        Vec3< float > pos;
+        Vec3< float > winkel;
+        int *indexList;
+        int indexAnz;
+        DXIndexBuffer *indexBuffer;
+
+    public:
+        // Konstruktor
+        Knochen();
+        // Destruktor
+        ~Knochen();
+        // Setzt die Anzahl der mit dem Knochen verbundenen Vertecies
+        //  anz: Die Anzahl der Vertecies
+        void setVertexAnzahl( int anz );
+        // Setzt deinen bestimmten Vertex des Knochens
+        //  i: Der Index des Vertex im Knochen
+        //  vId: Der Index des Vertex im Model
+        inline void setVertex( int i, int vId );
+        // Setzt die Position des Knochens relativ zum Model Ursprung
+        //  pos: Die Position
+        void setPosition( Vec3< float > &pos );
+        // Setzt die Drehung des Knochens relativ zum Model Ursprung
+        //  winkel: Ein Vektor der die Drehung um die verschiedenen Achsen als Komponenten hat
+        void setDrehung( Vec3< float > &winkel );
+        //
+        void render( Render3D *zRObj, Mat4< float > &mat, )
+    };
+
+    class Skelett
+    {
+    private:
+
+    public:
+
+    };
+
+    struct Polygon3D
+    {
+        int *indexList;
+        int indexAnz;
+        DXIndexBuffer *indexBuffer;
+
+        // Konstruktor
+        __declspec( dllexport ) Polygon3D();
+        // Destruktor
+        __declspec( dllexport ) ~Polygon3D();
+    };
+
+    // Speichert alle Geometrischen Daten eines Modells, also
+    // Raum - und Textur Koordinaten aller Eckpunkte
+    class Model3DData
+    {
+    private:
+        Vertex3D *vertexList;
+        DXVertexBuffer *vertexBuffer;
+        Array< Polygon3D* > *polygons;
+        float radius;
+        int id;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Model3DData();
+        // Destruktor
+        __declspec( dllexport ) ~Model3DData();
+        // Löscht alle Model daten
+        __declspec( dllexport ) void clearModel();
+        // Setzt einen Zeiger auf eine Liste mit allen Vertecies des Models
+        //  vertexList: Ein Array mit Vertecies
+        //  anz: Die Anzahl der Vertecies im Array
+        __declspec( dllexport ) void setVertecies( Vertex3D *vertexList, int anz );
+        // Fügt ein Polygon zum Model hinzu
+        //  polygon: Das Polygon, das hinzugefügt erden soll
+        __declspec( dllexport ) void addPolygon( Polygon3D *polygon );
+        // Konvertiert ein 2d Model zu 3D
+        //  model: Das 2d Model, das zu 3d konvertiert werden soll
+        //  z: Die z koordinate aller punkte des Models
+        __declspec( dllexport ) void copyModel2D( Model2DData *model, float z );
+        // Entfernt ein Polygon
+        //  index: Der Index des Polygons
+        __declspec( dllexport ) void removePolygon( int index );
+        // Zeichnet alle Polygons
+        //  world: Die Welt Matrix, die das Model in die Welt transformiert
+        //  zTxt: Eine Liste mit Texturen der einzelnen Polygone
+        //  zRObj: Das Objekt, mit dem gezeichnet werden soll
+        __declspec( dllexport ) void render( Mat4< float > &welt, const Model3DTextur *zTxt, Render3D *zRObj );
+        // Gibt die Anzahl an Polygonen zurück
+        __declspec( dllexport ) int getPolygonAnzahl();
+        // Gibt ein bestimmtes Polygon zurück
+        //  index: Der Index des Polygons
+        __declspec( dllexport ) Polygon3D *getPolygon( int index );
+        // Gibt den radius einer Kugel zurück, die das gesammte Model umschließt
+        __declspec( dllexport ) float getRadius() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Model3DData *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Model3DData *release();
+
+        friend Model3DList;
+    };
+
+    // Speichert eine Liste mit Texturen und für welche Polygone welche Textur benutzt werden soll
+    class Model3DTextur
+    {
+    private:
+        RCArray< Textur > *textures;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Model3DTextur();
+        // Destruktor
+        __declspec( dllexport ) ~Model3DTextur();
+        // Legt fest, welche Textur für welches Polygon ist
+        //  pI: Der Index des Polygons
+        //  txt: Die Textur des Polygons
+        __declspec( dllexport ) void setPolygonTextur( int pI, Textur *txt );
+        // Gibt einen Zeiger auf die Textur eines Polygons zurück ohne erhöhten Reference Counter
+        //  i: Der Index des Polygons
+        __declspec( dllexport ) Textur *zPolygonTextur( int i ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Model3DTextur *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Model3DTextur *release();
+    };
+
+    class Model3D : public Zeichnung3D
+    {
+    protected:
+        Model3DData *model;
+        Model3DTextur *textur;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Model3D();
+        // Destruktor
+        __declspec( dllexport ) ~Model3D();
+        // Setzt die Daten des Models
+        //  data: Die Daten
+        __declspec( dllexport ) void setModelDaten( Model3DData *data );
+        // Setzt die zum Zeichnen zu benutzenden Texturen
+        //  txt: Ein Liste mit Texturen zu den verschiedenen Polygonen zugeordnet
+        __declspec( dllexport ) void setModelTextur( Model3DTextur *txt );
+        // Verarbeitet die vergangene Zeit
+        //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+        //  return: true, wenn sich das Objekt verändert hat, false sonnst.
+        __declspec( dllexport ) virtual bool tick( double tickval );
+        // Zeichnet das Model
+        //  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+        __declspec( dllexport ) void render( Render3D *zRObj ) override;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Model3D *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) virtual Model3D *release();
+    };
+}

+ 155 - 0
Model3DList.cpp

@@ -0,0 +1,155 @@
+#include "Model3DList.h"
+#include "Model3D.h"
+#include "Text.h"
+
+using namespace Framework;
+
+int Model3DList::id = 0;
+CRITICAL_SECTION Model3DList::cs;
+
+// Inhalt der Model3DList Klasse
+// Konstruktor
+Model3DList::Model3DList()
+{
+    models = new RCArray< Model3DData >();
+    names = new RCArray< Text >();
+    ref = 1;
+}
+
+// Destruktor
+Model3DList::~Model3DList()
+{
+    models->release();
+    names->release();
+}
+
+// Fügt der Liste ein Model Hinzu
+//  mdl: Das Model
+//  name: Der name, unter dem das Model in der Liste gespeichert wird
+bool Model3DList::addModel( Model3DData *mdl, const char *name )
+{
+    EnterCriticalSection( &cs );
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            mdl->release();
+            LeaveCriticalSection( &cs );
+            return 0;
+        }
+    }
+    mdl->id = id++;
+    models->add( mdl );
+    names->add( new Text( name ) );
+    LeaveCriticalSection( &cs );
+    return 1;
+}
+
+// Entfernt ein Model aus der Liste
+//  name: Der Name des Models
+void Model3DList::löscheModel( const char *name )
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            names->lösche( index );
+            models->lösche( index );
+            LeaveCriticalSection( &cs );
+            return;
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+}
+
+// Überprüft, ob unter einem bestimmten Namen ein Model abgespeichert wurde
+//  name: Der Name
+//  return: true, wenn ein Model mit dem Namen existiert
+bool Model3DList::hatModel( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return 1;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt ein bestimmtes Model zurück
+//  name: Der Name des Models
+Model3DData *Model3DList::getModel( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return models->get( index );
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt ein bestimmtes Model ohne erhöhten Reference Counter zurück
+//  name: Der Name des Models
+Model3DData *Model3DList::zModel( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return models->z( index );
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Model3DList *Model3DList::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Model3DList *Model3DList::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// statische Funktionen
+
+// Initialisiert statische private member. Wird vom Framework automatisch aufgerufen.
+void Model3DList::init()
+{
+    id = 0;
+    InitializeCriticalSection( &cs );
+}
+
+// Löscht statische private member. Wird vom Framework automatisch aufgerufen.
+void Model3DList::destroy()
+{
+    DeleteCriticalSection( &cs );
+}

+ 59 - 0
Model3DList.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#include "Array.h"
+
+namespace Framework
+{
+    class Model3DData; // Model3D.h
+    class Text; // Text.h
+    class Model3D; // Model3D.h
+
+    namespace Standart3DTypes
+    {
+        const static char *würfel = "f_würfel";
+    };
+
+    // Verwaltet alle geladenen Modeldaten, so dass mehrere Zeichnungen die selben Daten benutzen können
+    class Model3DList
+    {
+    private:
+        static int id;
+        static CRITICAL_SECTION cs;
+        RCArray< Model3DData > *models;
+        RCArray< Text > *names;
+        int ref;
+
+    public:
+        // Konstruktor
+        Model3DList();
+        // Destruktor
+        ~Model3DList();
+        // Fügt der Liste ein Model Hinzu
+        //  mdl: Das Model
+        //  name: Der name, unter dem das Model in der Liste gespeichert wird
+        bool addModel( Model3DData *mdl, const char *name );
+        // Entfernt ein Model aus der Liste
+        //  name: Der Name des Models
+        void löscheModel( const char *name );
+        // Überprüft, ob unter einem bestimmten Namen ein Model abgespeichert wurde
+        //  name: Der Name
+        //  return: true, wenn ein Model mit dem Namen existiert
+        bool hatModel( const char *name ) const;
+        // Gibt ein bestimmtes Model zurück
+        //  name: Der Name des Models
+        Model3DData *getModel( const char *name ) const;
+        // Gibt ein bestimmtes Model ohne erhöhten Reference Counter zurück
+        //  name: Der Name des Models
+        Model3DData *zModel( const char *name ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        Model3DList *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        Model3DList *release();
+        // Initialisiert statische private member. Wird vom Framework automatisch aufgerufen.
+        static void init();
+        // Löscht statische private member. Wird vom Framework automatisch aufgerufen.
+        static void destroy();
+    };
+}

+ 15 - 0
ObjectRegister.h

@@ -0,0 +1,15 @@
+#pragma once
+
+namespace Framework
+{
+    struct ObjectPointer
+    {
+        void *obj;
+        ObjectPointer *next;
+    };
+
+    class ObjectRegister
+    {
+        
+    };
+}

+ 184 - 0
Prozess.cpp

@@ -0,0 +1,184 @@
+#include "Prozess.h"
+#ifdef WIN32
+#include <Psapi.h>
+#include <tlHelp32.h>
+#else
+#include <sys/time.h>
+#include <fstream>
+#include <string>
+#endif
+
+using namespace Framework;
+
+// Inhalt der Prozess Klasse aus Prozess.h
+// Konstruktor 
+Prozess::Prozess()
+{
+#ifdef WIN32
+	pHandle = GetCurrentProcess();
+	SYSTEM_INFO sysInfo;
+	FILETIME ftime, fsys, fuser;
+
+	GetSystemInfo( &sysInfo );
+	numProcessors = sysInfo.dwNumberOfProcessors;
+
+	GetSystemTimeAsFileTime( &ftime );
+	memcpy( &lastCPU, &ftime, sizeof( FILETIME ) );
+
+	GetProcessTimes( pHandle, &ftime, &ftime, &fsys, &fuser );
+	memcpy( &lastSysCPU, &fsys, sizeof( FILETIME ) );
+	memcpy( &lastUserCPU, &fuser, sizeof( FILETIME ) );
+#endif
+	ref = 1;
+}
+
+// nicht constant 
+#ifdef WIN32
+void Prozess::setProcess( void *pHandle )
+{
+	this->pHandle = pHandle;
+	SYSTEM_INFO sysInfo;
+	FILETIME ftime, fsys, fuser;
+
+	GetSystemInfo( &sysInfo );
+	numProcessors = sysInfo.dwNumberOfProcessors;
+
+	GetSystemTimeAsFileTime( &ftime );
+	memcpy( &lastCPU, &ftime, sizeof( FILETIME ) );
+
+	GetProcessTimes( pHandle, &ftime, &ftime, &fsys, &fuser );
+	memcpy( &lastSysCPU, &fsys, sizeof( FILETIME ) );
+	memcpy( &lastUserCPU, &fuser, sizeof( FILETIME ) );
+}
+#endif
+// constant
+double Prozess::getCPU() const
+{
+#ifdef WIN32
+	FILETIME ftime, fsys, fuser;
+	ULARGE_INTEGER now, sys, user;
+	double percent;
+
+	GetSystemTimeAsFileTime( &ftime );
+	memcpy( &now, &ftime, sizeof( FILETIME ) );
+
+	GetProcessTimes( pHandle, &ftime, &ftime, &fsys, &fuser );
+	memcpy( &sys, &fsys, sizeof( FILETIME ) );
+	memcpy( &user, &fuser, sizeof( FILETIME ) );
+	percent = (double)( ( sys.QuadPart - lastSysCPU.QuadPart ) +
+						( user.QuadPart - lastUserCPU.QuadPart ) );
+	percent /= ( now.QuadPart - lastCPU.QuadPart );
+	percent /= numProcessors;
+	memcpy( (void*)&lastCPU, (void*)&now, sizeof( now ) );
+	memcpy( (void*)&lastUserCPU, (void*)&user, sizeof( now ) );
+	memcpy( (void*)&lastSysCPU, (void*)&sys, sizeof( now ) );
+
+	return percent * 100;
+#else
+	return 0; //usage.ru_stime usage.ru_utime;
+#endif
+}
+
+__int64 Prozess::getMem() const
+{
+#ifdef WIN32
+	PROCESS_MEMORY_COUNTERS pMemCountr;
+	pMemCountr = PROCESS_MEMORY_COUNTERS();
+	if( GetProcessMemoryInfo( pHandle, &pMemCountr, sizeof( pMemCountr ) ) )
+		return pMemCountr.WorkingSetSize;
+	return 0;
+#else
+   using std::ios_base;
+   using std::ifstream;
+   using std::string;
+
+   // 'file' stat seems to give the most reliable results
+   //
+   ifstream stat_stream("/proc/self/stat",ios_base::in);
+
+   // dummy vars for leading entries in stat that we don't care about
+   //
+   string pid, comm, state, ppid, pgrp, session, tty_nr;
+   string tpgid, flags, minflt, cminflt, majflt, cmajflt;
+   string utime, stime, cutime, cstime, priority, nice;
+   string O, itrealvalue, starttime;
+
+   // the two fields we want
+   //
+   unsigned long vsize;
+   long rss;
+
+   stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
+               >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
+               >> utime >> stime >> cutime >> cstime >> priority >> nice
+               >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
+
+   stat_stream.close();
+
+   long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
+   return rss * page_size_kb;
+#endif
+}
+#ifdef WIN32
+MemoryInfo Prozess::getMemInfo() const
+{
+	PROCESS_MEMORY_COUNTERS pMemCountr;
+	pMemCountr = PROCESS_MEMORY_COUNTERS();
+	int result = GetProcessMemoryInfo( pHandle, &pMemCountr, sizeof( pMemCountr ) );
+	MemoryInfo ret;
+	ZeroMemory( &ret, sizeof( ret ) );
+	if( result )
+	{
+		ret.ausgelagerteFehler = pMemCountr.PageFaultCount;
+		ret.ausgelagerterPool = pMemCountr.QuotaPagedPoolUsage;
+		ret.ausgelagerterSpeicher = pMemCountr.WorkingSetSize;
+		ret.höchsteAusgelagerterSpeicher = pMemCountr.PeakWorkingSetSize;
+		ret.höchsterAusgelagerterPool = pMemCountr.QuotaPeakPagedPoolUsage;
+		ret.höchsterNichtAusgelagerterPool = pMemCountr.QuotaPeakNonPagedPoolUsage;
+		ret.höchsterVorreservierterSpeicher = pMemCountr.PeakPagefileUsage;
+		ret.nichtAusgelagerterPool = pMemCountr.QuotaNonPagedPoolUsage;
+		ret.vorreservierterSpeicher = pMemCountr.PagefileUsage;
+		return ret;
+	}
+	return ret;
+}
+
+int Prozess::getThreadAnzahl() const
+{
+	int ret = 0;
+	DWORD processID = GetCurrentProcessId();
+	HANDLE snap = CreateToolhelp32Snapshot( TH32CS_SNAPALL, processID );
+	if( snap != INVALID_HANDLE_VALUE )
+	{
+		PROCESSENTRY32 entry = { 0 };
+		entry.dwSize = sizeof( PROCESSENTRY32 );
+		if( Process32First( snap, &entry ) )
+		{
+			do
+			{
+				if( entry.th32ProcessID == processID )
+				{
+					ret = entry.cntThreads;
+					break;
+				}
+			}
+			while( Process32Next( snap, &entry ) );
+		}
+		CloseHandle( snap );
+	}
+	return ret;
+}
+#endif
+Prozess *Prozess::getThis()
+{
+	++ref;
+	return this;
+}
+
+Prozess *Prozess::release( )
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 70 - 0
Prozess.h

@@ -0,0 +1,70 @@
+#ifndef Prozess_H
+#define Prozess_H
+
+#include "Betriebssystem.h"
+
+#ifdef WIN32
+#pragma comment( lib, "Psapi.lib" )
+#endif
+
+namespace Framework
+{
+#ifdef WIN32
+	struct MemoryInfo; // aus dieser Datei
+#endif
+	class Prozess; // aus dieser Datei
+
+#ifdef WIN32
+	struct MemoryInfo
+	{
+		unsigned long ausgelagerteFehler;
+		__int64 höchsteAusgelagerterSpeicher;
+		__int64 ausgelagerterSpeicher;
+		__int64 höchsterAusgelagerterPool;
+		__int64 ausgelagerterPool;
+		__int64 höchsterNichtAusgelagerterPool;
+		__int64 nichtAusgelagerterPool;
+		__int64 vorreservierterSpeicher;
+		__int64 höchsterVorreservierterSpeicher;
+	};
+#endif
+    // Diese Klasse findet informationen über einen laufenden Prozess heraus (CPU, MEM)
+    // Bei Ubuntu immer der eigene Prozess
+	class Prozess
+	{
+	private:
+#ifdef WIN32
+		int numProcessors;
+		ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
+		void *pHandle;
+#endif
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Prozess();
+		// nicht constant 
+#ifdef WIN32
+        // Setzt den Prozess, der überwacht werden soll (Nur für Windows)
+		__declspec( dllexport ) void setProcess( void *pHandle );
+#endif
+		// Gibt den CPU verbrauch des Prozesses zurück
+		__declspec( dllexport ) double getCPU() const;
+        // Gibt den Speicherverbrauch des Prozesses zurück
+		__declspec( dllexport ) __int64 getMem() const;
+#ifdef WIN32
+        // Gibt detailierte Informationen über den Speicherverbrauch des Prozesses zurück (Nur für Windows)
+		__declspec( dllexport ) MemoryInfo getMemInfo() const;
+        // Gibt die Anzahl der Threads zurück (Nur für Windows)
+		__declspec( dllexport ) int getThreadAnzahl() const;
+#endif
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) Prozess *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) Prozess *release();
+	};
+}
+
+#endif

+ 50 - 0
Punkt.cpp

@@ -0,0 +1,50 @@
+#include "Punkt.h"
+#ifdef WIN32
+#include "Fenster.h"
+#endif
+
+using namespace Framework;
+
+// andere Funktionen 
+#ifdef WIN32
+inline Punkt Framework::BildschirmGröße() // Gibt die Größe des Bildschirms zurück
+{
+	RECT r;
+	GetWindowRect( GetDesktopWindow(), &r );
+	return Punkt( r.right, r.bottom );
+}
+
+inline Punkt Framework::Bildschirmmitte() // Giebt die Mitte des Bildschirms zurück
+{
+	RECT r;
+	GetWindowRect( GetDesktopWindow(), &r ); // Bildschirmgröße herausfinden
+	return Punkt( r.right / 2, r.bottom / 2 );
+}
+
+inline Punkt Framework::Bildschirmmitte( WFenster *f ) // Giebt die Mitte des Bildschirms zurück
+{
+	Punkt p = Bildschirmmitte();
+	Punkt p2 = f->getGröße();
+	f->release();
+	return { p.x - p2.x / 2, p.y - p2.y / 2 };
+}
+#endif
+bool Framework::operator >( const Punkt &a, const Punkt &b ) // Gibt an, ob a > als b ist
+{
+	return a.x > b.x && a.y > b.y;
+}
+
+bool Framework::operator <( const Punkt &a, const Punkt &b ) // Gibt an, ob a < als b ist
+{
+	return a.x < b.x && a.y < b.y;
+}
+
+bool Framework::operator <=( const Punkt &a, const Punkt &b ) // Gibt an, ob a <= als b ist
+{
+	return a.x <= b.x && a.y <= b.y;
+}
+
+bool Framework::operator >=( const Punkt &a, const Punkt &b ) // Gibt an, ob a >= als b ist
+{
+	return a.x >= b.x && a.y >= b.y;
+}

+ 37 - 0
Punkt.h

@@ -0,0 +1,37 @@
+#ifndef Punkt_H
+#define Punkt_H
+//---Include---
+
+#include "Vec2.h"
+
+namespace Framework
+{
+	// benötigte includes
+	class WFenster; // aus Fenster.h
+	
+	typedef Vec2< int > Punkt; // Speichert die ganzzahligen Koordinaten eines Punktes
+
+	
+#ifdef WIN32
+    // Gibt die Größe des Bildschirms zurück
+	__declspec( dllexport ) Punkt BildschirmGröße();
+    // Giebt die Mitte des Bildschirms zurück
+	__declspec( dllexport ) Punkt Bildschirmmitte();
+    // Giebt einen Punkt zurück, der als Fensterposition verwendet werden kann um das Fenster zu zentrieren
+    //  f: Das Fenster, welches Zentriert werden soll
+	__declspec( dllexport ) Punkt Bildschirmmitte( WFenster *f );
+#endif
+    // Prüft, ob ein Punkt weiter rechts unten ist als ein anderer
+    //  return: (true), wenn der linke Punkt weiter rechts und weiter unten ist. (false) sonnst
+	__declspec( dllexport ) bool operator >( const Punkt &a, const Punkt &b );
+    // Prüft, ob ein Punkt weiter links obem ist als ein anderer
+    //  return: (true), wenn der linke Punkt weiter links und weiter oben ist. (false) sonnst
+	__declspec( dllexport ) bool operator <( const Punkt &a, const Punkt &b );
+    // Prüft, ob ein Punkt weiter links obem ist als ein anderer
+    //  return: (true), wenn der linke Punkt weiter links und weiter oben oder gleich ist. (false) sonnst
+	__declspec( dllexport ) inline bool operator <=( const Punkt &a, const Punkt &b );
+    // Prüft, ob ein Punkt weiter rechts unten ist als ein anderer
+    //  return: (true), wenn der linke Punkt weiter rechts und weiter unten oder gleich ist. (false) sonnst
+	__declspec( dllexport ) inline bool operator >=( const Punkt &a, const Punkt &b );
+}
+#endif

+ 115 - 0
Rahmen.cpp

@@ -0,0 +1,115 @@
+#include "Rahmen.h"
+#include "Punkt.h"
+#include "Bild.h"
+#include "Scroll.h"
+#include "ToolTip.h"
+#include "Text.h"
+
+using namespace Framework;
+
+// Inhalt der LRahmen Klasse aus Rahmen.h
+// Konstruktor 
+LRahmen::LRahmen()
+	: Zeichnung(),
+	  br( 1 ),
+	  farbe( 0xFF000000 ),
+	  alpha( 0 ),
+	  ref( 1 )
+{
+}
+
+// nicht constant 
+void LRahmen::setRamenBreite( int br ) // setzt die Breite des Rahmens
+{
+	this->br = br;
+	rend = 1;
+}
+
+void LRahmen::setAlpha( bool a ) // Legt fest, ob der Alphawert der Farbe berücksichtigt werden soll
+{
+	alpha = a;
+	rend = 1;
+}
+
+void LRahmen::setFarbe( int f ) // Legt die Farbe des Rahmens fest
+{
+	farbe = f;
+	rend = 1;
+}
+
+void LRahmen::render( Bild &Obj ) // Zeichnet den Rahmen in das RenderZeichnung
+{
+    __super::render( Obj );
+	int x = pos.x;
+	int y = pos.y;
+	int b = x + gr.x - 1;
+	int h = y + gr.y - 1;
+	if( alpha )
+	{
+		for( int i = 0; i < br; ++i )
+		{
+			Obj.drawLinieHAlpha( x + i + 1, y + i, gr.x - i * 2 - 1, farbe );
+			Obj.drawLinieVAlpha( b - i, y + i + 1, gr.y - i * 2 - 2, farbe );
+			Obj.drawLinieHAlpha( x + i + 1, h - i, gr.x - i * 2 - 1, farbe );
+			Obj.drawLinieVAlpha( x + i, y + i, gr.y - i * 2, farbe );
+		}
+	}
+	else
+	{
+		for( int i = 0; i < br; ++i )
+		{
+			Obj.drawLinieH( x + i + 1, y + i, gr.x - i * 2 - 1, farbe );
+			Obj.drawLinieV( b - i, y + i + 1, gr.y - i * 2 - 2, farbe );
+			Obj.drawLinieH( x + i + 1, h - i, gr.x - i * 2 - 1, farbe );
+			Obj.drawLinieV( x + i, y + i, gr.y - i * 2, farbe );
+		}
+	}
+}
+
+// constant 
+int LRahmen::getRBreite() const // Gibt die Breite des Rahmens zurück
+{
+	return br;
+}
+
+int LRahmen::getFarbe() const // Gibt die Farbe des Ramens zurück
+{
+	return farbe;
+}
+
+bool LRahmen::hatAlpha() const // Gibt zurück, ob der Alphawert der Farbe beachtet wird
+{
+	return alpha;
+}
+
+Zeichnung *LRahmen::dublizieren() const // Kopiert das Zeichnung
+{
+	LRahmen *obj = new LRahmen();
+	obj->setPosition( pos );
+	obj->setGröße( gr );
+	obj->setMausEreignisParameter( makParam );
+	obj->setTastaturEreignisParameter( takParam );
+	obj->setMausEreignis( Mak );
+	obj->setTastaturEreignis( Tak );
+	if( toolTip )
+		obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	obj->setAlpha( alpha );
+	obj->setFarbe( farbe );
+	obj->setRamenBreite( br );
+	return obj;
+}
+
+// Reference Counting 
+LRahmen *LRahmen::getThis()
+{
+	++ref;
+	return this;
+}
+
+LRahmen *LRahmen::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}

+ 40 - 0
Rahmen.h

@@ -0,0 +1,40 @@
+#ifndef Rahmen_H
+#define Rahmen_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class Bild; // aus Bild.h
+	struct VScrollData; // Scroll.h
+	struct HScrollData; // Scroll.h
+	class LRahmen; // aus dieser Datei
+
+	class LRahmen : public Zeichnung // Ramen aus Linien
+	{
+	private:
+		int br;
+		int farbe;
+		bool alpha;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) LRahmen();
+		// nicht constant 
+		__declspec( dllexport ) void setRamenBreite( int br ); // setzt die Breite des Rahmens
+		__declspec( dllexport ) void setAlpha( bool a ); // Legt fest, ob der Alphawert der Farbe berücksichtigt werden soll
+		__declspec( dllexport ) void setFarbe( int f ); // Legt die Farbe des Rahmens fest
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // Zeichnet den Rahmen in das RenderZeichnung
+		// constant 
+		__declspec( dllexport ) int getRBreite() const; // Gibt die Breite des Rahmens zurück
+		__declspec( dllexport ) int getFarbe() const; // Gibt die Farbe des Ramens zurück
+		__declspec( dllexport ) bool hatAlpha() const; // Gibt zurück, ob der Alphawert der Farbe beachtet wird
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Kopiert das Zeichnung
+		// Reference Counting 
+		__declspec( dllexport ) LRahmen *getThis();
+		__declspec( dllexport ) LRahmen *release();
+	};
+}
+
+#endif

+ 301 - 0
Render3D.cpp

@@ -0,0 +1,301 @@
+#include "Render3D.h"
+#include "Shader.h"
+#include "Model3D.h"
+#include "DXBuffer.h"
+#include "Textur.h"
+#include "Bild.h"
+#include <d3d11.h>
+
+using namespace Framework;
+
+// Inhalt der Render3D Klasse
+// Konstruktor
+Render3D::Render3D()
+{
+    device = 0;
+    context = 0;
+    texturRS = 0;
+    meshRS = 0;
+    defaultTextur = new Textur();
+    Bild *b = new Bild();
+    b->neuBild( 10, 10, 0xFFFFFFFF );
+    defaultTextur->setBildZ( b );
+    shader = new RCArray< RCArray< Shader > >();
+    shaderId = new Array< int >();
+    lastObjektId = -1;
+    lastTexturId = -1;
+    ref = 1;
+}
+
+// Destruktor
+Render3D::~Render3D()
+{
+    if( device )
+        device->Release();
+    if( context )
+        context->Release();
+    if( texturRS )
+        texturRS->Release();
+    if( meshRS )
+        meshRS->Release();
+    defaultTextur->release();
+    shader->release();
+    shaderId->release();
+}
+
+// Setzt das Device, was zum zeichnen verwendet werden soll
+//  device: Das neue Device
+void Render3D::setDevice( ID3D11Device *device )
+{
+    if( this->device )
+        this->device->Release();
+    this->device = device;
+    if( device )
+    {
+        if( !texturRS )
+        {
+            D3D11_RASTERIZER_DESC rasterDesc;
+            ZeroMemory( &rasterDesc, sizeof( rasterDesc ) );
+            rasterDesc.AntialiasedLineEnable = false;
+            rasterDesc.CullMode = D3D11_CULL_BACK;
+            rasterDesc.DepthBiasClamp = 0.0f;
+            rasterDesc.DepthClipEnable = true;
+            rasterDesc.FillMode = D3D11_FILL_SOLID;
+            rasterDesc.FrontCounterClockwise = false;
+            rasterDesc.MultisampleEnable = false;
+            rasterDesc.ScissorEnable = false;
+            rasterDesc.SlopeScaledDepthBias = 0.0f;
+            device->CreateRasterizerState( &rasterDesc, &texturRS );
+        }
+        if( !meshRS )
+        {
+            D3D11_RASTERIZER_DESC rasterDesc;
+            ZeroMemory( &rasterDesc, sizeof( rasterDesc ) );
+            rasterDesc.AntialiasedLineEnable = false;
+            rasterDesc.CullMode = D3D11_CULL_BACK;
+            rasterDesc.DepthBiasClamp = 0.0f;
+            rasterDesc.DepthClipEnable = true;
+            rasterDesc.FillMode = D3D11_FILL_WIREFRAME;
+            rasterDesc.FrontCounterClockwise = false;
+            rasterDesc.MultisampleEnable = false;
+            rasterDesc.ScissorEnable = false;
+            rasterDesc.SlopeScaledDepthBias = 0.0f;
+            device->CreateRasterizerState( &rasterDesc, &meshRS );
+        }
+        if( context )
+        {
+            context->RSSetState( texturRS );
+            defaultTextur->updateTextur( this );
+        }
+    }
+}
+
+// Setzt das Context Objekt, das zum Zeichnen verwendet werden soll
+//  context: das neue Conext Objekt
+void Render3D::setContext( ID3D11DeviceContext *context )
+{
+    if( this->context )
+        this->context->Release();
+    this->context = context;
+    if( context )
+    {
+        if( texturRS )
+            context->RSSetState( texturRS );
+        if( device )
+            defaultTextur->updateTextur( this );
+    }
+}
+
+// Setzt den aktuellen Shader. Er wird hinten an die Liste mit zuletzt verwendeten Shadern angefügt
+//  listIndex: Der Index der Liste mit zuletzt verwendeten Shadern
+//  sh: Der Shader, der verwendet werden soll
+void Render3D::benutzeShader( int listIndex, Shader *sh )
+{
+    if( listIndex < 0 )
+        return;
+    if( !shader->z( listIndex ) || !shaderId->hat( listIndex ) )
+    {
+        shader->set( new RCArray< Shader >(), listIndex );
+        shaderId->set( -1, listIndex );
+    }
+    int id = shaderId->get( listIndex ) + 1;
+    shader->z( listIndex )->set( sh, id );
+    shaderId->set( id, listIndex );
+    sh->benutzeShader( context );
+}
+
+// Sprinkt in der Liste mit zuletzt benutzten Shadern zurück und benutzt wieder den dortiegen Shader
+//  listIndex: Der Index der Liste mit zuletzt verwe deten Shadern
+//  anz: Die Anzahl der Shader, die zurückgesprungen werden soll. Bei 0 passiert nichts
+void Render3D::releaseShader( int listIndex, int anz )
+{
+    if( !shader->z( listIndex ) || !shaderId->hat( listIndex ) || anz < 0 )
+        return;
+    int id = shaderId->get( listIndex ) - anz;
+    if( id < 0 )
+        id = 0;
+    if( shader->z( listIndex )->z( id ) )
+        shader->z( listIndex )->z( id )->benutzeShader( context );
+    shaderId->set( id, listIndex );
+}
+
+// Setzt die View und Projektion Matrizen, die zum zeichnen verwendet werden sollen
+//  view: Die View Matrix der Kamera
+//  proj: Die Projektion Matrix der Kamera
+//  kamPos: Die Position der Kamera in der Welt
+void Render3D::setKameraMatrix( Mat4< float > &view, Mat4< float > &proj, Vec3< float > &kamPos )
+{
+    matrixBuffer[ 1 ] = view;
+    matrixBuffer[ 2 ] = proj;
+    this->kamPos = kamPos;
+
+    Mat4< float > tmp = proj * view;
+
+    frustrum[ 0 ].x = tmp.elements[ 3 ][ 0 ] + tmp.elements[ 0 ][ 0 ];
+    frustrum[ 0 ].y = tmp.elements[ 3 ][ 1 ] + tmp.elements[ 0 ][ 1 ];
+    frustrum[ 0 ].z = tmp.elements[ 3 ][ 2 ] + tmp.elements[ 0 ][ 2 ];
+    frustrum[ 0 ].w = tmp.elements[ 3 ][ 3 ] + tmp.elements[ 0 ][ 3 ];
+
+    frustrum[ 1 ].x = tmp.elements[ 3 ][ 0 ] - tmp.elements[ 0 ][ 0 ];
+    frustrum[ 1 ].y = tmp.elements[ 3 ][ 1 ] - tmp.elements[ 0 ][ 1 ];
+    frustrum[ 1 ].z = tmp.elements[ 3 ][ 2 ] - tmp.elements[ 0 ][ 2 ];
+    frustrum[ 1 ].w = tmp.elements[ 3 ][ 3 ] - tmp.elements[ 0 ][ 3 ];
+
+    frustrum[ 2 ].x = tmp.elements[ 3 ][ 0 ] - tmp.elements[ 1 ][ 0 ];
+    frustrum[ 2 ].y = tmp.elements[ 3 ][ 1 ] - tmp.elements[ 1 ][ 1 ];
+    frustrum[ 2 ].z = tmp.elements[ 3 ][ 2 ] - tmp.elements[ 1 ][ 2 ];
+    frustrum[ 2 ].w = tmp.elements[ 3 ][ 3 ] - tmp.elements[ 1 ][ 3 ];
+
+    frustrum[ 3 ].x = tmp.elements[ 3 ][ 0 ] + tmp.elements[ 1 ][ 0 ];
+    frustrum[ 3 ].y = tmp.elements[ 3 ][ 1 ] + tmp.elements[ 1 ][ 1 ];
+    frustrum[ 3 ].z = tmp.elements[ 3 ][ 2 ] + tmp.elements[ 1 ][ 2 ];
+    frustrum[ 3 ].w = tmp.elements[ 3 ][ 3 ] + tmp.elements[ 1 ][ 3 ];
+
+    frustrum[ 4 ].x = tmp.elements[ 2 ][ 0 ];
+    frustrum[ 4 ].y = tmp.elements[ 2 ][ 1 ];
+    frustrum[ 4 ].z = tmp.elements[ 2 ][ 2 ];
+    frustrum[ 4 ].w = tmp.elements[ 2 ][ 3 ];
+
+    frustrum[ 5 ].x = tmp.elements[ 3 ][ 0 ] - tmp.elements[ 2 ][ 0 ];
+    frustrum[ 5 ].y = tmp.elements[ 3 ][ 1 ] - tmp.elements[ 2 ][ 1 ];
+    frustrum[ 5 ].z = tmp.elements[ 3 ][ 2 ] - tmp.elements[ 2 ][ 2 ];
+    frustrum[ 5 ].w = tmp.elements[ 3 ][ 3 ] - tmp.elements[ 2 ][ 3 ];
+
+    for( int i = 0; i < 6; i++ )
+        frustrum[ i ].normalize();
+}
+
+// Beginnt das Zeichnen eines bestimmten objektes
+//  world: Die Matrix, die das Model aus dem Model space in den world space übersetzt
+//  zVertexBuffer: Ein VertexBuffer mit allen Punkten des Models ohne erhöhten Reference Counter
+void Render3D::beginnModel( Mat4< float > &world, DXVertexBuffer *zVertexBuffer, int modelId )
+{
+    matrixBuffer[ 0 ] = world;
+    if( shader->z( VERTEX ) && shaderId->hat( VERTEX ) )
+        shader->z( VERTEX )->z( shaderId->get( VERTEX ) )->füllConstBuffer( context, (char*)matrixBuffer, 0 );
+    if( lastObjektId == -1 || lastObjektId != modelId )
+    {
+        lastObjektId = modelId;
+        unsigned int offset = 0;
+        ID3D11Buffer *b = zVertexBuffer->zBuffer();
+        unsigned int es = (unsigned)zVertexBuffer->getElementLänge();
+        context->IASetVertexBuffers( 0, 1, &b, &es, &offset );
+    }
+}
+
+// Zeichnet eine bestimmte struktur
+//  zIndexBuffer: Ein IndexBuffer, der auf verschiedene Vertices aus dem Vertex Buffer des Models zeigt. Ohne erhöhten Reference Counter
+//  textur: Ein Zeiger auf die Textur, die verwendet werden soll ohne erhöhten Reference Counter
+//  struktur: Die Struktur der angegebenen Indices, Beispiel: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST oder D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ...
+void Render3D::draw( DXIndexBuffer *zIndexBuffer, Textur *textur, D3D_PRIMITIVE_TOPOLOGY struktur )
+{
+    DXGI_FORMAT f = DXGI_FORMAT_R32_UINT;
+    if( zIndexBuffer->getElementLänge() == 2 )
+        f = DXGI_FORMAT_R16_UINT;
+    if( zIndexBuffer->getElementLänge() == 1 )
+        f = DXGI_FORMAT_R8_UINT;
+    context->IASetIndexBuffer( zIndexBuffer->zBuffer(), f, 0 );
+    context->IASetPrimitiveTopology( struktur );
+    if( textur )
+    {
+        if( lastTexturId == -1 || lastTexturId != textur->getId() )
+        {
+            lastTexturId = textur->getId();
+            ID3D11ShaderResourceView *v = *textur;
+            context->PSSetShaderResources( 0, 1, &v );
+        }
+        context->DrawIndexed( zIndexBuffer->getElementAnzahl(), 0, 0 );
+    }
+    else
+    {
+        context->RSSetState( meshRS );
+        ID3D11ShaderResourceView *v = *defaultTextur;
+        context->PSSetShaderResources( 0, 1, &v );
+        context->DrawIndexed( zIndexBuffer->getElementAnzahl(), 0, 0 );
+        context->RSSetState( texturRS );
+    }
+}
+
+// Gibt einen der aktuell verwendeten Shader zurück
+//  listIndex: Der Index der Lise mit Shadern, von denen der aktuell benutzte zurückgegeben werden soll
+Shader *Render3D::getShader( int listIndex ) const
+{
+    if( !shader->z( listIndex ) || !shaderId->hat( listIndex ) )
+        return 0;
+    return shader->z( listIndex )->get( shaderId->get( listIndex ) );
+}
+
+// Gibt einen der aktuell verwendeten Shader ohne erhöhten Reference Counter zurück
+//  listIndex: Der Index der Lise mit Shadern, von denen der aktuell benutzte zurückgegeben werden soll
+Shader *Render3D::zShader( int listIndex ) const
+{
+    if( !shader->z( listIndex ) || !shaderId->hat( listIndex ) )
+        return 0;
+    return shader->z( listIndex )->z( shaderId->get( listIndex ) );
+}
+
+// Gibt das momentan verwendete Device Objekt ohne erhöhten Reference Counter zurück
+ID3D11Device *Render3D::zDevice() const
+{
+    return device;
+}
+
+// Gibt das momentan verwendete Context Objekt ohne erhöhten Reference Counter zurück
+ID3D11DeviceContext *Render3D::zContext() const
+{
+    return context;
+}
+
+// Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und gezeichnet werden muss
+//  pos: Der Mittelpunkt der Kugel
+//  radius: Der Radius der Kugel
+//  dist: Einen Zeiger auf einen float, in dem das quadrat des Abstands zur Kammeraposition gespeichert wird, falls diese Funktion true zurückgiebt und der Zeiger nicht 0 ist
+bool Render3D::isInFrustrum( const Vec3< float > &pos, float radius, float *dist ) const
+{
+    for( int i = 0; i < 6; i++ )
+    {
+        if( frustrum[ i ] * pos + radius < 0 )
+            return 0;
+    }
+    if( dist )
+        *dist = kamPos.abstandSq( pos );
+    return 1;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Render3D *Render3D::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Render3D *Render3D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 92 - 0
Render3D.h

@@ -0,0 +1,92 @@
+#pragma once
+
+#include "Array.h"
+#include "Mat4.h"
+#include "Vec4.h"
+
+struct ID3D11Device;
+struct ID3D11DeviceContext;
+enum D3D_PRIMITIVE_TOPOLOGY;
+struct ID3D11ShaderResourceView;
+struct ID3D11RasterizerState;
+
+namespace Framework
+{
+    class Shader; // Shader.h
+    class DXVertexBuffer; // DXBuffer.h
+    class DXIndexBuffer; // DXBuffer.h
+    class Textur; // Textur.h
+
+    class Render3D
+    {
+    private:
+        Mat4< float > matrixBuffer[ 3 ];
+        Vec4< float > frustrum[ 6 ];
+        Vec3< float > kamPos;
+        ID3D11Device *device;
+        ID3D11DeviceContext *context;
+        ID3D11RasterizerState *texturRS;
+        ID3D11RasterizerState *meshRS;
+        Textur *defaultTextur;
+        RCArray< RCArray< Shader > > *shader;
+        Array< int > *shaderId;
+        int lastObjektId;
+        int lastTexturId;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Render3D();
+        // Destruktor
+        __declspec( dllexport ) ~Render3D();
+        // Setzt das Device, was zum zeichnen verwendet werden soll
+        //  device: Das neue Device
+        __declspec( dllexport ) void setDevice( ID3D11Device *device );
+        // Setzt das Context Objekt, das zum Zeichnen verwendet werden soll
+        //  context: das neue Conext Objekt
+        __declspec( dllexport ) void setContext( ID3D11DeviceContext *context );
+        // Setzt den aktuellen Shader. Er wird hinten an die Liste mit zuletzt verwendeten Shadern angefügt
+        //  listIndex: Der Index der Liste mit zuletzt verwendeten Shadern
+        //  sh: Der Shader, der verwendet werden soll
+        __declspec( dllexport ) void benutzeShader( int listIndex, Shader *sh );
+        // Sprinkt in der Liste mit zuletzt benutzten Shadern zurück und benutzt wieder den dortiegen Shader
+        //  listIndex: Der Index der Liste mit zuletzt verwe deten Shadern
+        //  anz: Die Anzahl der Shader, die zurückgesprungen werden soll. Bei 0 passiert nichts
+        __declspec( dllexport ) void releaseShader( int listIndex, int anz = 1 );
+        // Setzt die View und Projektion Matrizen, die zum zeichnen verwendet werden sollen
+        //  view: Die View Matrix der Kamera
+        //  proj: Die Projektion Matrix der Kamera
+        //  kamPos: Die Position der Kamera in der Welt
+        __declspec( dllexport ) void setKameraMatrix( Mat4< float > &view, Mat4< float > &proj, Vec3< float > &kamPos );
+        // Beginnt das Zeichnen eines bestimmten objektes
+        //  world: Die Matrix, die das Model aus dem Model space in den world space übersetzt
+        //  zVertexBuffer: Ein VertexBuffer mit allen Punkten des Models ohne erhöhten Reference Counter
+        __declspec( dllexport ) void beginnModel( Mat4< float > &world, DXVertexBuffer *zVertexBuffer, int modelId );
+        // Zeichnet eine bestimmte struktur
+        //  zIndexBuffer: Ein IndexBuffer, der auf verschiedene Vertices aus dem Vertex Buffer des Models zeigt. Ohne erhöhten Reference Counter
+        //  textur: Ein Zeiger auf die Textur, die verwendet werden soll ohne erhöhten Reference Counter
+        //  struktur: Die Struktur der angegebenen Indices, Beispiel: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST oder D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ...
+        __declspec( dllexport ) void draw( DXIndexBuffer *zIndexBuffer, Textur *zTextur, D3D_PRIMITIVE_TOPOLOGY struktur = (D3D_PRIMITIVE_TOPOLOGY)4 );
+        // Gibt einen der aktuell verwendeten Shader zurück
+        //  listIndex: Der Index der Lise mit Shadern, von denen der aktuell benutzte zurückgegeben werden soll
+        __declspec( dllexport ) Shader *getShader( int listIndex ) const;
+        // Gibt einen der aktuell verwendeten Shader ohne erhöhten Reference Counter zurück
+        //  listIndex: Der Index der Lise mit Shadern, von denen der aktuell benutzte zurückgegeben werden soll
+        __declspec( dllexport ) Shader *zShader( int listIndex ) const;
+        // Gibt das momentan verwendete Device Objekt ohne erhöhten Reference Counter zurück
+        __declspec( dllexport ) ID3D11Device *zDevice() const;
+        // Gibt das momentan verwendete Context Objekt ohne erhöhten Reference Counter zurück
+        __declspec( dllexport ) ID3D11DeviceContext *zContext() const;
+        // Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und gezeichnet werden muss
+        //  pos: Der Mittelpunkt der Kugel
+        //  radius: Der Radius der Kugel
+        //  dist: Einen Zeiger auf einen float, in dem das quadrat des Abstands zur Kammeraposition gespeichert wird, falls diese Funktion true zurückgiebt und der Zeiger nicht 0 ist
+        __declspec( dllexport ) bool isInFrustrum( const Vec3< float > &pos, float radius, float *dist = 0 ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Render3D *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Render3D *release();
+    };
+}

+ 161 - 0
RenderThread.cpp

@@ -0,0 +1,161 @@
+#include "RenderThread.h"
+#include "Bildschirm.h"
+#include "Zeit.h"
+
+using namespace Framework;
+
+// Inhalt der RenderTh Klasse aus RenderThread.h
+// Konstruktor 
+RenderTh::RenderTh()
+	: stoppen( 0 ),
+	  bildschirm( 0 ),
+	  zeit( new ZeitMesser() ),
+	  renderTickZeit( 1 / 60 ),
+	  renderParameter( 0 ),
+	  tickParameter( 0 ),
+	  renderFunktion( 0 ),
+	  tickFunktion( 0 ),
+	  pause( 0 ),
+	  maxFps( 30 ),
+	  ref( 1 )
+{
+	InitializeCriticalSection( &cs );
+}
+
+// Destruktor 
+RenderTh::~RenderTh()
+{
+	if( run )
+		beenden();
+	if( bildschirm )
+		bildschirm->release();
+	zeit->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void RenderTh::lock()
+{
+	EnterCriticalSection( &cs );
+}
+
+void RenderTh::unlock()
+{
+	LeaveCriticalSection( &cs );
+}
+
+void RenderTh::setBildschirm( Bildschirm *bildschirm ) // setzt den Bildschirm
+{
+	lock();
+	if( this->bildschirm )
+		this->bildschirm->release();
+	this->bildschirm = bildschirm;
+	unlock();
+}
+
+void RenderTh::thread() // Render Schleife
+{
+	zeit->messungStart();
+	double ausgleich = 0;
+	while( !stoppen )
+	{
+		lock();
+		if( bildschirm && !pause )
+		{
+			if( renderFunktion )
+				renderFunktion( renderParameter, this, bildschirm->zRenderBild() );
+			bildschirm->render();
+			if( tickFunktion )
+				tickFunktion( tickParameter, this, renderTickZeit );
+			bildschirm->tick( renderTickZeit );
+			unlock();
+		}
+		else
+		{
+			unlock();
+			Sleep( 100 );
+		}
+		ausgleich += 1.0 / maxFps - renderTickZeit;
+		if( ausgleich > 0 )
+			Sleep( (int)( ausgleich * 1000 ) );
+		zeit->messungEnde();
+		zeit->messungStart();
+		renderTickZeit = zeit->getSekunden();
+	}
+	zeit->messungEnde();
+}
+
+void RenderTh::beginn() // beginnt rendering
+{
+	stoppen = 0;
+	start();
+}
+
+void RenderTh::beenden() // beendet den Thread
+{
+	stoppen = 1;
+	warteAufThread( 2000 );
+	if( run )
+		ende();
+}
+
+void RenderTh::setMaxFps( int fps ) // setzt die Anzahl der Bilder pro Sekunde
+{
+	maxFps = fps;
+}
+
+void RenderTh::setPause( bool p ) // Renderpause
+{
+	pause = p;
+}
+
+void RenderTh::setRenderFunktion( void( *rF )( void *, void *, Bild * ) ) // setzt die Rückruf Funktion beim Rendern
+{
+	renderFunktion = rF;
+}
+
+void RenderTh::setTickFunktion( void( *tF )( void *, void *, double ) ) // setzt die Rückruf Funktion beim Tick
+{
+	tickFunktion = tF;
+}
+
+void RenderTh::setRenderFunktionParameter( void *p ) // setzt den Parameter der Rückruf Funktion beim Rendern
+{
+	renderParameter = p;
+}
+
+void RenderTh::setTickFunktionParameter( void *p ) // setzt den Parameter der Rückruf Funktion beim Tick
+{
+	tickParameter = p;
+}
+
+// constant
+Bildschirm *RenderTh::getBildschirm() const // gibt den Bildschirm zurück
+{
+	return bildschirm ? bildschirm->getThis() : 0;
+}
+
+Bildschirm *RenderTh::zBildschirm() const
+{
+	return bildschirm;
+}
+
+double RenderTh::getRenderTickZeit() const // gibt die Zeit zurück, die zum Rendern und zum Tick benötigt wird
+{
+	return renderTickZeit;
+}
+
+// Reference Counting
+RenderTh *RenderTh::getThis()
+{
+	++ref;
+	return this;
+}
+
+RenderTh *RenderTh::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 56 - 0
RenderThread.h

@@ -0,0 +1,56 @@
+#ifndef RenderThread_H
+#define RenderThread_H
+
+#include "Thread.h"
+
+namespace Framework
+{
+	class Bildschirm; // Bildschirm.h
+	class ZeitMesser; // ZeitMesser.h
+	class Bild; // Bild.h
+
+	class RenderTh : private Thread
+	{
+	private:
+		bool stoppen;
+		Bildschirm *bildschirm;
+		ZeitMesser *zeit;
+		double renderTickZeit;
+		void *renderParameter;
+		void *tickParameter;
+		void ( *renderFunktion )( void *, void *, Bild * );
+		void ( *tickFunktion )( void *, void *, double );
+		bool pause;
+		CRITICAL_SECTION cs;
+		int maxFps;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) RenderTh();
+		// Destruktor 
+		__declspec( dllexport ) ~RenderTh();
+		// nicht constant 
+		__declspec( dllexport ) void lock();
+		__declspec( dllexport ) void unlock();
+		__declspec( dllexport ) void setBildschirm( Bildschirm *bildschirm ); // setzt den Bildschirm
+		__declspec( dllexport ) void thread() override; // Render Schleife
+		__declspec( dllexport ) void beginn(); // beginnt rendering
+		__declspec( dllexport ) void beenden(); // beendet den Thread
+		__declspec( dllexport ) void setMaxFps( int fps ); // setzt die Anzahl der Bilder pro Sekunde
+		__declspec( dllexport ) void setPause( bool p ); // Renderpause
+		__declspec( dllexport ) void setRenderFunktion( void ( *rF )( void *, void *, Bild * ) ); // setzt die Rückruf Funktion beim Rendern
+		__declspec( dllexport ) void setTickFunktion( void ( *tF )( void *, void *, double ) ); // setzt die Rückruf Funktion beim Tick
+		__declspec( dllexport ) void setRenderFunktionParameter( void *p ); // setzt den Parameter der Rückruf Funktion beim Rendern
+		__declspec( dllexport ) void setTickFunktionParameter( void *p ); // setzt den Parameter der Rückruf Funktion beim Tick
+		// constant
+		__declspec( dllexport ) Bildschirm *getBildschirm() const; // gibt den Bildschirm zurück
+		__declspec( dllexport ) Bildschirm *zBildschirm() const;
+		__declspec( dllexport ) double getRenderTickZeit() const; // gibt die Zeit zurück, die zum Rendern und zum Tick benötigt wird
+		// Reference Counting
+		__declspec( dllexport ) RenderTh *getThis();
+		__declspec( dllexport ) RenderTh *release();
+	};
+}
+
+#endif

+ 243 - 0
Schluessel.cpp

@@ -0,0 +1,243 @@
+#include "Schluessel.h"
+
+using namespace Framework::Verschlüsselung;
+
+// Inhalt der Bytes Klasse aus Schlüssel.h
+// Konstruktor
+Bytes::Bytes()
+	: bytes( 0 ),
+	  del( 1 ),
+	  län( 0 ),
+	  ref( 1 )
+{
+}
+
+Bytes::Bytes( int län )
+	: bytes( new char[ län ] ),
+	  del( 1 ),
+	  län( län ),
+	  ref( 1 )
+{
+}
+
+Bytes::Bytes( const char *daten, int län )
+	: bytes( new char[ län ] ),
+	  del( 1 ),
+	  län( län ),
+	  ref( 1 )
+{
+	setBytes( daten );
+}
+
+// Destruktor
+Bytes::~Bytes()
+{
+	if( del )
+	    delete[] bytes;
+}
+
+// nicht constant
+void Bytes::setBytes( const char *daten )
+{
+	if( !bytes || !daten )
+		return;
+	char *end = bytes + län;
+	for( char *c = bytes; c < end; c++, ++daten )
+		*c = *daten;
+}
+
+void Bytes::setBytes( const char *daten, int län )
+{
+	if( !daten || !län )
+		return;
+	if( del )
+	    delete[] bytes;
+	del = 1;
+	bytes = new char[ län ];
+	this->län = län;
+	setBytes( daten );
+}
+
+void Bytes::setBytesZ( char *daten, int län )
+{
+	if( del )
+	    delete[] bytes;
+	del = 0;
+	bytes = daten;
+	this->län = län;
+}
+
+void Bytes::füll( const char c )
+{
+	if( !bytes )
+		return;
+	char *end = bytes + län;
+	for( char *b = bytes; b < end; ++b )
+		*b = c;
+}
+
+void Bytes::füll( const char c, int län )
+{
+	if( !bytes )
+		bytes = new char[ län ];
+	län = län > this->län ? this->län : län;
+	char *end = bytes + län;
+	for( char *b = bytes; b < end; ++b )
+		*b = c;
+}
+
+void Bytes::füll( const char c, int beg, int end )
+{
+	if( beg >= län )
+		return;
+	if( !bytes )
+		bytes = new char[ end - beg ];
+	end = end > this->län ? this->län : end;
+	char *endB = bytes + end;
+	for( char *b = bytes + beg; b < endB; ++b )
+		*b = c;
+}
+
+void Bytes::füll( const char *c, int cLän )
+{
+	if( !c || !cLän || !bytes )
+		return;
+	char *endB = bytes + län;
+	const char *endC = c + cLän;
+	const char *d = c;
+	for( char *b = bytes; b < endB; b++, d = d < endC - 1 ? d + 1 : c )
+		*b = *d;
+}
+
+void Bytes::set( const char c, int pos )
+{
+	if( !bytes || pos >= län )
+		return;
+	bytes[ pos ] = c;
+}
+
+// constant
+int Bytes::getLänge() const
+{
+	return län;
+}
+
+char *Bytes::getBytes() const
+{
+	return bytes;
+}
+
+// Reference Counting
+Bytes *Bytes::getThis()
+{
+	++ref;
+	return this;
+}
+
+Bytes *Bytes::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der Schlüssel Klasse aus Schlüssel.h
+// Konstruktor
+Schlüssel::Schlüssel()
+	: schlüssel( 0 ),
+	  län( 0 ),
+	  pos( 0 ),
+	  ref( 1 )
+{
+}
+
+Schlüssel::Schlüssel( const char *s, int län )
+	: schlüssel( new unsigned char[ län ] ),
+	  län( län ),
+	  pos( 0 ),
+	  ref( 1 )
+{
+	for( int i = 0; i < län; ++i )
+		schlüssel[ i ] = s[ i ];
+}
+
+// Destruktor
+Schlüssel::~Schlüssel()
+{
+	delete[] schlüssel;
+}
+
+// nicht constant
+void Schlüssel::setPos( int p )
+{
+	if( p < 0 )
+		p = 0;
+	pos = p > län ? 0 : p;
+}
+
+void Schlüssel::setSchlüssel( const char *s, int län )
+{
+	delete[] schlüssel;
+	schlüssel = new unsigned char[ län ];
+	for( int i = 0; i < län; ++i )
+		schlüssel[ i ] = s[ i ];
+	pos = 0;
+	this->län = län;
+}
+
+void Schlüssel::codieren( Bytes *daten )
+{
+	if( !schlüssel || !län )
+	{
+		daten->release();
+		return;
+	}
+	int dLän = daten->getLänge();
+	char *bytes = daten->getBytes();
+	char *bEnd = bytes + dLän;
+	for( char *c = bytes; c < bEnd; ++c )
+	{
+		*c = *c + schlüssel[ pos ];
+		++pos;
+		if( pos >= län )
+			pos = 0;
+	}
+	daten->release();
+}
+
+void Schlüssel::decodieren( Bytes *daten )
+{
+	if( !schlüssel || !län )
+	{
+		daten->release();
+		return;
+	}
+	int dLän = daten->getLänge();
+	char *bytes = daten->getBytes();
+	char *bEnd = bytes + dLän;
+	for( char *c = bytes; c < bEnd; ++c )
+	{
+		*c = *c - schlüssel[ pos ];
+		++pos;
+		if( pos >= län )
+			pos = 0;
+	}
+	daten->release();
+}
+
+// Reference Counting
+Schlüssel *Schlüssel::getThis()
+{
+	++ref;
+	return this;
+}
+
+Schlüssel *Schlüssel::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 120 - 0
Schluessel.h

@@ -0,0 +1,120 @@
+#ifndef Schluessel_H
+#define Schluessel_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+	namespace Verschlüsselung
+	{
+        // Speichert einen Array von bytes
+		class Bytes
+		{
+		private:
+			char *bytes;
+			bool del;
+			int län;
+			int ref;
+
+		public:
+			// Erzeugt einen lehren Byte Array
+			__declspec( dllexport ) Bytes();
+            // Erzeugt einen neuen Byte Array mit bestimmter Länge
+            //  län: Die Länge des Arrays
+			__declspec( dllexport ) Bytes( int län );
+            // Erzeugt ein neuen Byte Array durch kopieren der bytes
+            //  daten: Die Bytes, die kopiert werden sollen
+            //  län: Die Anzahl der Bytes die kopiert werden sollen
+			__declspec( dllexport ) Bytes( const char *daten, int län );
+			// Löscht den Array
+			__declspec( dllexport ) ~Bytes();
+			
+            // Befüllt den Bytearray durch kopieren der Bytes
+            //  daten: Die Bytes, die kopiert werden sollen
+			__declspec( dllexport ) void setBytes( const char *daten );
+            // Löscht den Array und erzeugt einen neuen
+            //  daten: Die Bytes, die kopiert werden sollen
+            //  län: Die nänge des Arrays
+			__declspec( dllexport ) void setBytes( const char *daten, int län );
+            // Löscht den Array und übernimmt den übergebenen ohne zu kopieren
+            //  daten: Der neue Byte Array
+            //  län: Die nänge des Arrays
+			__declspec( dllexport ) void setBytesZ( char *daten, int län );
+            // Setzt alle Bytes des Arrays auf einen bestimmten Wert
+            //  c: Der Wert, auf den die Bytes gesetzt werden sollen
+			__declspec( dllexport ) void füll( const char c );
+            // Setzt eine bestimmte Anzahl von Bytes des Arrays auf einen bestimmten Wert
+            //  c: Der Wert, auf den die Bytes gesetzt werden sollen
+            //  län: Die Anzahl der Bytes die gesetzt werden sollen
+			__declspec( dllexport ) void füll( const char c, int län );
+            // Setzt einen bestimmte Abschnitt von Bytes des Arrays auf einen bestimmten Wert
+            //  c: Der Wert, auf den die Bytes gesetzt werden sollen
+            //  beg: Die Startposition des zu setzenden Abschnittes
+            //  end: Die Endposition des zu setzenden Abschnittes (nicht enthalten)
+			__declspec( dllexport ) void füll( const char c, int beg, int end );
+            // Kopiert bestimmte bytes in den Array
+            //  c: Die Bytes, die kopiert werden sollen
+            //  cLän: Die Anzahl an Bytes, die gesetzt werden sollen
+			__declspec( dllexport ) void füll( const char *c, int cLän );
+            // Setzt ein bestimmtes Byte auf einen Wert
+            //  c: Der Wert, auf den das Byte gesetzt werden soll
+            //  pos: Die Position des Bytes im Array
+			__declspec( dllexport ) void set( const char c, int pos );
+			
+            // Gibt die Länge des Arrays zurück
+			__declspec( dllexport ) int getLänge() const;
+            // Gibt den Array von Bytes zurück
+			__declspec( dllexport ) char *getBytes() const;
+
+            // Erhöht den Reference Counting Zähler.
+            //  return: this.
+			__declspec( dllexport ) Bytes *getThis();
+            // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+            //  return: 0.
+			__declspec( dllexport ) Bytes *release();
+		};
+
+        // Kann Bytesequenzen mit bestimmten Schlüsseln verschlüsseln und entschlüsseln
+		class Schlüssel
+		{
+		private:
+			unsigned char *schlüssel;
+			int län;
+			int pos;
+			int ref;
+
+		public:
+			// Erzeugt ein leeres Zeichnung
+			__declspec( dllexport ) Schlüssel();
+            // Erzeugt ein neues Zeichnung mi einem Schlüssel
+            //  s: Der Schlüssel, der zum verschlüsseln und entchlüsseln verwendet werden soll
+            //  län: Die Länge des Schlüssels
+			__declspec( dllexport ) Schlüssel( const char *s, int län );
+			// Löscht das Zeichnung
+			__declspec( dllexport ) ~Schlüssel();
+			
+            // Setzt die Position im Schlüssel, wo mit dem verschlüsseln und entschlüsseln begonnen werden soll
+			//  p: Die Position im Schlüssel
+            __declspec( dllexport ) void setPos( int p );
+            // Setzt den Schlüssel, der zum ver- und entschlüsseln verwendet werden soll
+            //  s: Der Schlüssel
+            //  län: Die Länge des Schlüssels
+			__declspec( dllexport ) void setSchlüssel( const char *s, int län );
+            // Verschlüsselt einen Byte Array mit dem gesetzten Schlüssel
+            //  daten: Der Byte Array, der verschlüsselt werden soll. Wird von der Funktion verändert
+			__declspec( dllexport ) void codieren( Bytes *daten );
+            // Entschlüsselt einen Byte Array mit dem gesetzten Schlüssel
+            //  daten: Der Byte Array, der entschlüsselt werden soll. Wird von der Funktion verändert
+			__declspec( dllexport ) void decodieren( Bytes *daten );
+			
+            // Erhöht den Reference Counting Zähler.
+            //  return: this.
+			__declspec( dllexport ) Schlüssel *getThis();
+            // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+            //  return: 0.
+			__declspec( dllexport ) Schlüssel *release();
+		};
+	}
+}
+
+#endif

+ 1013 - 0
Schrift.cpp

@@ -0,0 +1,1013 @@
+#include "Schrift.h"
+#include "Bild.h"
+#include "Text.h"
+#include "Scroll.h"
+#include "Globals.h"
+#include <Windows.h>
+#include "FrameworkMath.h"
+
+using namespace Framework;
+
+// Inhalt der Buchstabe Klasse aus Schrift.h
+// Konstruktor 
+Buchstabe::Buchstabe()
+	: größe( 0, 0 ),
+	  pos( 0, 0 ),
+	  alpha( 0 ),
+	  schriftGröße( 0 ),
+	  drawSg( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+Buchstabe::~Buchstabe()
+{
+	if( alpha )
+		delete[]alpha;
+}
+
+// nicht constant 
+void Buchstabe::NeuBuchstabe( Punkt &größe ) // Initialisierung
+{
+	this->größe = größe;
+	if( alpha )
+		delete[]alpha;
+	alpha = new unsigned char[ größe.x * größe.y ];
+	ZeroMemory( alpha, größe.x * größe.y );
+}
+
+void Buchstabe::setPixel( Punkt &pos, unsigned char alpha ) // setzt den alphawert des Pixels
+{
+	this->alpha[ pos.x + pos.y * größe.x ] = alpha;
+}
+
+void Buchstabe::setPixel( int x, int y, unsigned char alpha )
+{
+	this->alpha[ x + y * größe.x ] = alpha;
+}
+
+void Buchstabe::setPixel( int i, unsigned char alpha )
+{
+	this->alpha[ i ] = alpha;
+}
+
+void Buchstabe::setPosition( Punkt &pos ) // setzt die Buchstabenposition
+{
+	this->pos = pos;
+}
+
+void Buchstabe::setPosition( int x, int y )
+{
+	pos.x = x;
+	pos.y = y;
+}
+
+void Buchstabe::setSchriftGröße( int sg ) // setzt die Schriftgröße des Buchstaben
+{
+	schriftGröße = sg;
+}
+
+void Buchstabe::setDrawSchriftGröße( int dsg ) // setzt die Zeichengröße des Buchstaben
+{
+	drawSg = dsg;
+}
+
+// constant
+const Punkt &Buchstabe::getGröße() const // gibt die Buchstabenbildgröße zurück
+{
+	return größe;
+}
+
+int Buchstabe::getBreite() const // Buchstabenbreite
+{
+	return (int)( ( (double)größe.x / (double)schriftGröße ) * (double)drawSg + 0.5 );
+}
+
+int Buchstabe::getHöhe() const // Buchstabenhöhe
+{
+	return (int)( ( (double)größe.y / (double)schriftGröße ) *(double)drawSg + 0.5 );
+}
+
+int Buchstabe::getNormHöhe() const // Buchstabenhöhe
+{
+	return größe.y;
+}
+
+unsigned char *Buchstabe::getBuff() const // gibt den Alphabuffer zurück
+{
+	return alpha;
+}
+
+void Buchstabe::render( Bild &zRObj, int f ) const // Zeichnet nach zRObj
+{
+	if( alpha )
+	{
+		const Punkt &zRObjGr = zRObj.getDrawGr();
+		const Punkt &zRObjPos = zRObj.getDrawPos();
+		const Punkt &zRObjOff = zRObj.getDrawOff();
+		int xp = pos.x + zRObjOff.x, yp = pos.y + zRObjOff.y;
+		int xs = xp < zRObjPos.x ? ( zRObjPos.x - xp ) : 0, ys = yp < zRObjPos.y ? ( zRObjPos.y - yp ) : 0;
+		int b = größe.x, h = größe.y;
+		unsigned char a2 = ( 255 - ( f >> 24 ) );
+		f &= 0x00FFFFFF;
+		if( schriftGröße == drawSg )
+		{
+			if( xp >= zRObjGr.x || yp >= zRObjGr.y || xp + b < zRObjPos.x || yp + h < zRObjPos.y )
+				return;
+			b = ( xp + b ) > zRObjGr.x ? ( zRObjGr.x - xp ) : b;
+			h = ( yp + h ) > zRObjGr.y ? ( zRObjGr.y - yp ) : h;
+			if( !a2 )
+			{
+				int xx, ygr = ( ys - 1 ) * größe.x, ygr2 = ( yp + ys - 1 ) * zRObj.getBreite();
+				for( int yy = ys; yy < h; ++yy )
+				{
+					ygr += größe.x;
+					ygr2 += zRObj.getBreite();
+					for( xx = xs; xx < b; ++xx )
+						zRObj.alphaPixel( xp + xx + ygr2, f | ( alpha[ xx + ygr ] << 24 ) );
+				}
+			}
+			else
+			{
+				int a;
+				int xx, ygr = ( ys - 1 ) * größe.x, ygr2 = ( yp + ys - 1 ) * zRObj.getBreite();
+				for( int yy = ys; yy < h; ++yy )
+				{
+					ygr += größe.x;
+					ygr2 += zRObj.getBreite();
+					for( xx = xs; xx < b; ++xx )
+					{
+						a = alpha[ xx + ygr ] - a2;
+						if( a > 0 )
+							zRObj.alphaPixel( xp + xx + ygr2, f | ( a << 24 ) );
+					}
+				}
+			}
+		}
+		else
+		{
+			double xoff = (double)schriftGröße / (double)drawSg,
+				yoff = (double)schriftGröße / (double)drawSg;
+			double x = xs * xoff, y = ys * yoff;
+			int maxX = getBreite(), maxY = getHöhe();
+			maxX = ( xp + maxX ) >= zRObjGr.x ? ( zRObjGr.x - xp ) : maxX;
+			maxY = ( yp + maxY ) >= zRObjGr.y ? ( zRObjGr.y - yp ) : maxY;
+			if( !a2 )
+			{
+				int dx, ygr, ygr2;
+				for( int dy = ys; dy < maxY; ++dy )
+				{
+					ygr2 = ( yp + dy ) * zRObj.getBreite();
+					ygr = (int)y * b;
+					for( dx = xs; dx < maxX; ++dx )
+					{
+						zRObj.alphaPixel( xp + dx + ygr2, f | ( alpha[ (int)x + ygr ] << 24 ) );
+						x += xoff;
+					}
+					x = xs;
+					y += yoff;
+				}
+			}
+			else
+			{
+				int a, dx, ygr, ygr2;
+				for( int dy = ys; dy < maxY; ++dy )
+				{
+					ygr2 = ( yp + dy ) * zRObj.getBreite();
+					ygr = (int)y * b;
+					for( dx = xs; dx < maxX; ++dx )
+					{
+						a = alpha[ (int)x + ygr ] - a2;
+						zRObj.alphaPixel( xp + dx + ygr2, f | ( a << 24 ) );
+						x += xoff;
+					}
+					x = xs;
+					y += yoff;
+				}
+			}
+		}
+	}
+}
+
+// Reference Counting 
+Buchstabe *Buchstabe::getThis()
+{
+	++ref;
+	return this;
+}
+
+Buchstabe *Buchstabe::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der Alphabet Klasse aus Schrift.h
+// Konstruktor 
+Alphabet::Alphabet()
+	: zeichen( new Buchstabe*[ 256 ] ),
+	  schriftGröße( 12 ),
+	  drawSchriftGröße( 12 ),
+	  pos( 0, 0 ),
+	  zeilenHöhe( 0 ),
+	  zeilenAbstand( 5 ),
+	  ref( 1 )
+{
+	for( int i = 0; i < 256; ++i )
+		zeichen[ i ] = 0;
+}
+
+// Destruktor 
+Alphabet::~Alphabet()
+{
+	for( int i = 0; i < 256; ++i )
+	{
+		if( zeichen[ i ] )
+			zeichen[ i ]->release();
+	}
+	delete[]zeichen;
+}
+
+// nicht constant 
+void Alphabet::NeuAlphabet() // Initialisierung 
+{
+	for( int i = 0; i < 256; ++i )
+	{
+		if( zeichen[ i ] )
+			zeichen[ i ]->release();
+	}
+	for( int i = 0; i < 256; ++i )
+		zeichen[ i ] = 0;
+	zeilenHöhe = 0;
+}
+
+void Alphabet::setBuchstabe( unsigned char i, Buchstabe *buchstabe ) // setzt einen Buchstaben
+{
+	if( zeichen[ i ] )
+		zeichen[ i ]->release();
+	zeichen[ i ] = buchstabe;
+	if( zeichen[ i ] )
+	{
+		zeichen[ i ]->setSchriftGröße( schriftGröße );
+		zeichen[ i ]->setDrawSchriftGröße( drawSchriftGröße );
+	}
+	zeilenHöhe = 0;
+	for( int i = 0; i < 256; ++i )
+	{
+		if( zeichen[ i ] != 0 )
+			zeilenHöhe = maxInt( zeichen[ i ]->getHöhe(), zeilenHöhe );
+	}
+}
+
+void Alphabet::setSchriftgröße( int gr ) // setzt die Schriftgröße
+{
+	schriftGröße = gr;
+	for( int i = 0; i < 256; ++i )
+	{
+		if( zeichen[ i ] )
+			zeichen[ i ]->setSchriftGröße( gr );
+	}
+}
+
+void Alphabet::setDrawSchriftgröße( int gr ) // setzt die Zeichengröße
+{
+	drawSchriftGröße = gr;
+	for( int i = 0; i < 256; ++i )
+	{
+		if( zeichen[ i ] )
+			zeichen[ i ]->setDrawSchriftGröße( gr );
+	}
+}
+
+void Alphabet::setZeilenAbstand( int za ) // setzt die Zeilenhöhe( Zeilenabstand )
+{
+	zeilenAbstand = za;
+}
+
+void Alphabet::setDrawPosition( Punkt &pos ) // setzt die Draw Position
+{
+	this->pos = pos;
+}
+
+void Alphabet::setDrawPosition( int x, int y )
+{
+	pos.x = x;
+	pos.y = y;
+}
+
+// constant 
+Buchstabe *Alphabet::getBuchstabe( unsigned char i ) const // gibt einen Buchstaben zurück
+{
+	if( zeichen[ i ] )
+		return zeichen[ i ]->getThis();
+	return 0;
+}
+
+Buchstabe *Alphabet::zBuchstabe( unsigned char i ) const
+{
+	return zeichen[ i ];
+}
+
+bool Alphabet::hatBuchstabe( unsigned char b ) const
+{
+	return zeichen[ b ] != 0;
+}
+
+int Alphabet::getSchriftgröße() const // gibt die Schriftgröße zurück
+{
+	return schriftGröße;
+}
+
+int Alphabet::getDrawSchriftGröße() const // gibt die Zeichengröße zurück
+{
+	return drawSchriftGröße;
+}
+
+int Alphabet::getZeilenAbstand() const // gibt den Zeilenabstand zurück
+{
+	return zeilenAbstand;
+}
+
+int Alphabet::getZeilenHöhe() const // gibt die Höhe des höchsten Zeichens zurück
+{
+	return (int)( (double)zeilenHöhe / schriftGröße * drawSchriftGröße + 0.5 );
+}
+
+const Punkt &Alphabet::getPosition() const // gibt die DrawPosition zurück
+{
+	return pos;
+}
+
+int Alphabet::getTextBreite( Text *zTxt ) const // gibt die Breite des Textes zurück
+{
+	int ret = 0;
+	int län = zTxt->getLänge();
+	char *buff = zTxt->getText();
+	unsigned char c = 0;
+	int tmp = 0;
+	for( int i = 0; i < län; ++i )
+	{
+		c = (unsigned char)buff[ i ];
+		if( buff[ i ] == '\n' )
+		{
+			if( tmp > ret )
+				ret = tmp;
+			tmp = 0;
+		}
+		else if( buff[ i ] == '\r' )
+		{
+			i += 10;
+			continue;
+		}
+        else if( buff[ i ] == '\t' )
+            tmp += drawSchriftGröße;
+		else if( buff[ i ] == ' ' )
+			tmp += drawSchriftGröße / 2;
+		else if( zeichen[ c ] )
+			tmp += zeichen[ c ]->getBreite();
+	}
+	if( tmp > ret )
+		ret = tmp;
+	return ret;
+}
+
+int Alphabet::getTextHöhe( Text *zTxt ) const // gibt die Höhe des Textes zurück
+{
+	int hö = getZeilenHöhe();
+	return hö + ( ( hö + zeilenAbstand ) * zTxt->anzahlVon( '\n' ) );
+}
+
+int Alphabet::textPos( Text *zText, int mausX, int mausY ) const // gibt den Buchstaben zurück, auf den die Maus zeigt
+{
+	char *buffer = zText->getText();
+	int län = zText->getLänge();
+	int tx = 0;
+	int ty = 0;
+	int sh = getZeilenHöhe();
+	if( mausX < 0 || mausY < 0 )
+		return -1;
+	for( int i = 0; i < län; ++i )
+	{
+		if( buffer[ i ] == '\n' )
+		{
+			ty += sh + zeilenAbstand;
+			tx = 0;
+			if( mausY < ty )
+				return i;
+		}
+        if( buffer[ i ] == '\t' )
+            tx += drawSchriftGröße;
+		if( buffer[ i ] == ' ' )
+			tx += drawSchriftGröße / 2;
+		if( zeichen[ (unsigned char)buffer[ i ] ] )
+			tx += zeichen[ (unsigned char)buffer[ i ] ]->getBreite();
+		int txpl = 0;
+		if( zeichen[ (unsigned char)buffer[ i + 1 ] ] )
+			txpl = zeichen[ (unsigned char)buffer[ i + 1 ] ]->getBreite() / 2;
+		if( mausX < tx - txpl && mausY < ty + sh + zeilenAbstand )
+			return i;
+	}
+	if( mausY < ty + sh + zeilenAbstand )
+		return län;
+	return -1;
+}
+
+void Alphabet::textFormatieren( Text *zText, int maxBreite, int schriftGröße ) // fügt zeilenumbrüche ein 
+{
+	int sg = drawSchriftGröße;
+	setDrawSchriftgröße( schriftGröße );
+	int zeilenHöhe = getZeilenHöhe() + getZeilenAbstand();
+	int lastPos = -1;
+	int län = zText->getLänge();
+	char *txt = zText->getText();
+	int x = 0;
+	Text result = zText->getText();
+	for( int i = 0; i < län; ++i )
+	{
+		char c = txt[ i ];
+		if( c == ' ' )
+		{
+			lastPos = i;
+			x += schriftGröße / 2;
+			continue;
+		}
+        if( c == '\t' )
+        {
+            lastPos = i;
+            x += schriftGröße;
+            continue;
+        }
+		if( c == '\n' )
+		{
+			x = 0;
+			lastPos = -1;
+			continue;
+		}
+		if( c == '\r' && län - i >= 11 )
+		{
+			i += 10;
+			continue;
+		}
+		Buchstabe *b = getBuchstabe( (unsigned)c );
+		if( b )
+		{
+			x += b->getBreite();
+			if( x > maxBreite && lastPos > -1 )
+			{
+				result.ersetzen( lastPos, lastPos + 1, "\n" );
+				x = 0;
+				i = lastPos;
+				lastPos = -1;
+			}
+			b = b->release();
+		}
+	}
+	zText->setText( result );
+	setDrawSchriftgröße( sg );
+}
+
+void Alphabet::render( Text *zTxt, Bild &rendezRObj, int f ) const // Zeichnet txt nach rendezRObj
+{
+	int zRObjBr = rendezRObj.getBreite();
+	int zRObjHö = rendezRObj.getHöhe();
+	int xp = pos.x;
+	int yp = pos.y;
+	int zh = getZeilenHöhe();
+	if( yp + ( zh + zeilenAbstand ) * zTxt->anzahlVon( '\n' ) + zh < 0 || xp >= zRObjBr || yp >= zRObjHö )
+		return;
+	char *text = zTxt->getText();
+	int län = zTxt->getLänge();
+	for( int i = 0; i < län; ++i )
+	{
+		unsigned char c = text[ i ];
+		if( c == ' ' )
+		{
+			xp += drawSchriftGröße / 2;
+			continue;
+		}
+        if( c == '\t' )
+        {
+            xp += drawSchriftGröße;
+            continue;
+        }
+		if( c == '\n' )
+		{
+			yp += zh + zeilenAbstand;
+			xp = pos.x;
+			continue;
+		}
+		if( c == '\r' && län - i >= 11 )
+		{
+			i += 3;
+			Text *hex1 = zTxt->getTeilText( i, i + 6 );
+			Text *hex2 = zTxt->getTeilText( i + 6, i + 8 );
+			f = ( TextZuInt( hex1->getText(), 16 ) << 8 ) |
+				( TextZuInt( hex2->getText(), 16 ) );
+			hex1->release();
+			hex2->release();
+			i += 7;
+			continue;
+		}
+		if( zeichen[ c ] )
+		{
+			if( xp >= zRObjBr )
+				continue;
+			zeichen[ c ]->setPosition( xp, yp );
+			zeichen[ c ]->render( rendezRObj, f );
+			xp += zeichen[ c ]->getBreite();
+		}
+	}
+}
+
+void Alphabet::render( Text *zTxt, Bild &rendezRObj, int cpos, int cf, int fbeg, int ff, int f ) const
+{
+	int zRObjBr = rendezRObj.getBreite();
+	int zRObjHö = rendezRObj.getHöhe();
+	int xp = pos.x;
+	int yp = pos.y;
+	int zh = getZeilenHöhe();
+	if( yp + ( zh + zeilenAbstand ) * zTxt->anzahlVon( '\n' ) + zh < 0 || xp >= zRObjBr || yp >= zRObjHö )
+		return;
+	char *text = zTxt->getText();
+	int län = zTxt->getLänge();
+	bool färb = 0;
+	for( int i = 0; i < län; ++i )
+	{
+		unsigned char c = text[ i ];
+		if( i == fbeg )
+			färb = !färb;
+		if( i == cpos )
+		{
+			rendezRObj.drawLinieVAlpha( xp, yp, zh, cf );
+			färb = !färb;
+		}
+		if( c == ' ' )
+		{
+			if( färb )
+				rendezRObj.alphaRegion( xp, yp, drawSchriftGröße / 2, zh, ff );
+			xp += drawSchriftGröße / 2;
+			continue;
+		}
+        if( c == '\t' )
+        {
+            if( färb )
+                rendezRObj.alphaRegion( xp, yp, drawSchriftGröße, zh, ff );
+            xp += drawSchriftGröße;
+            continue;
+        }
+		if( c == '\n' )
+		{
+			yp += zh + zeilenAbstand;
+			xp = pos.x;
+			continue;
+		}
+		if( c == '\r' && län - i >= 11 )
+		{
+			i += 3;
+			Text *hex1 = zTxt->getTeilText( i, i + 6 );
+			Text *hex2 = zTxt->getTeilText( i + 6, i + 8 );
+			f = ( TextZuInt( hex1->getText(), 16 ) << 8 ) |
+				( TextZuInt( hex2->getText(), 16 ) );
+			hex1->release();
+			hex2->release();
+			i += 7;
+			continue;
+		}
+		if( zeichen[ c ] )
+		{
+			if( xp >= zRObjBr )
+				continue;
+			if( färb )
+			{
+				int br = zeichen[ c ]->getBreite();
+				rendezRObj.alphaRegion( xp, yp, br, zh, ff );
+			}
+			zeichen[ c ]->setPosition( xp, yp );
+			zeichen[ c ]->render( rendezRObj, f );
+			xp += zeichen[ c ]->getBreite();
+		}
+	}
+	if( län == cpos )
+		rendezRObj.drawLinieVAlpha( xp, yp, zh, cf );
+}
+
+// Reference Counting 
+Alphabet *Alphabet::getThis()
+{
+	++ref;
+	return this;
+}
+
+Alphabet *Alphabet::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der AlphabetArray Klasse aus Schrift.h
+// Konstruktor 
+AlphabetArray::AlphabetArray()
+	: next( 0 ),
+	  This( 0 )
+{
+}
+
+// Destruktor 
+AlphabetArray::~AlphabetArray()
+{
+	if( This )
+		This->release();
+	delete next;
+}
+
+// nicht constant 
+bool AlphabetArray::addAlphabet( Alphabet *alphabet ) // Fügt ein Alphabet hinzu
+{
+	if( This )
+	{
+		if( This->getSchriftgröße() == alphabet->getSchriftgröße() )
+		{
+			alphabet->release();
+			return false;
+		}
+	}
+	else
+	{
+		This = alphabet;
+		return true;
+	}
+	if( !next )
+		next = new AlphabetArray();
+	return next->addAlphabet( alphabet );
+}
+
+bool AlphabetArray::removeAlphabet( int sg ) // entfernt ein Alphabet
+{
+	if( This )
+	{
+		if( This->getSchriftgröße() == sg )
+			This = This->release();
+		return 1;
+	}
+	if( !next )
+		return 0;
+	if( next->removeAlphabet( sg ) )
+	{
+		AlphabetArray *tmp = next->getNext();
+		next->setNext0();
+		delete next;
+		next = tmp;
+	}
+	return 0;
+}
+
+void AlphabetArray::setDrawSchriftGröße( int sg ) // Setzt die Draw Schriftgröße aller Alphabete
+{
+	if( This )
+		This->setDrawSchriftgröße( sg );
+	if( next )
+		next->setDrawSchriftGröße( sg );
+}
+
+void AlphabetArray::setZeilenAbstand( int za ) // setzt den Zeilenabstant aller Alphabete
+{
+	if( This )
+		This->setZeilenAbstand( za );
+	if( next )
+		next->setZeilenAbstand( za );
+}
+
+void AlphabetArray::setNext0() // setzt den next Zeiger zu 0
+{
+	next = 0;
+}
+
+// constant 
+Alphabet *AlphabetArray::getAlphabet( unsigned char sg ) const // gibt getThis von einem Alphabet zurück
+{
+	if( !This )
+		return 0;
+	if( This->getSchriftgröße() == sg )
+		return This->getThis();
+	if( next )
+		return next->getAlphabet( sg );
+	return 0;
+}
+
+Alphabet *AlphabetArray::zAlphabet( unsigned char sg ) const // gibt ein Alphabet zurück
+{
+	if( !This )
+		return 0;
+	if( This->getSchriftgröße() == sg )
+		return This;
+	if( next )
+		return next->zAlphabet( sg );
+	return 0;
+}
+
+Alphabet *AlphabetArray::getAlphabetI( int index, int count ) const
+{
+	if( count == index )
+		return This->getThis();
+	if( next )
+		return next->getAlphabetI( index, count + 1 );
+	return 0;
+}
+
+Alphabet *AlphabetArray::zAlphabetI( int index, int count ) const
+{
+	if( count == index )
+		return This;
+	if( next )
+		return next->zAlphabetI( index, count + 1 );
+	return 0;
+}
+
+AlphabetArray *AlphabetArray::getNext() const // gibt das nächste Alphabet zurück
+{
+	return next;
+}
+
+// Inhalt der Schrift Klasse aus Schrift.h
+// Konstruktor 
+Schrift::Schrift()
+	: alphabetAnzahl( 0 ),
+	  alphabet( new AlphabetArray() ),
+	  schriftGröße( 12 ),
+	  zeilenAbstand( 5 ),
+	  drawPos( 0, 0 ),
+	  ref( 1 )
+{
+	InitializeCriticalSection( &cs );
+}
+
+// Destruktor 
+Schrift::~Schrift()
+{
+	delete alphabet;
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void Schrift::lock() // lockt die Schrift
+{
+	EnterCriticalSection( &cs );
+}
+
+void Schrift::unlock() // unlockt die Schrift
+{
+	LeaveCriticalSection( &cs );
+}
+
+bool Schrift::addAlphabet( Alphabet *alphabet ) // Fügt der Schrift ein Alphabet hinzu
+{
+	lock();
+    if( this->alphabet->addAlphabet( alphabet ) )
+    {
+        ++alphabetAnzahl;
+        alphabet->setDrawSchriftgröße( schriftGröße );
+        unlock();
+        return true;
+    }
+	unlock();
+    return false;
+}
+
+void Schrift::removeAlphabet( int sg ) // Entfernt ein Alphabet
+{
+	lock();
+    if( alphabet->removeAlphabet( sg ) )
+        --alphabetAnzahl;
+	unlock();
+}
+
+void Schrift::setDrawPosition( int x, int y ) // setzt die Zeichenposition
+{
+	lock();
+	drawPos.x = x;
+	drawPos.y = y;
+	unlock();
+}
+
+void Schrift::setDrawPosition( Punkt &pos )
+{
+	lock();
+	drawPos = pos;
+	unlock();
+}
+
+void Schrift::setSchriftGröße( int sg ) // setzt die Schriftgröße
+{
+	lock();
+	schriftGröße = sg;
+	alphabet->setDrawSchriftGröße( sg );
+	unlock();
+}
+
+void Schrift::setZeilenAbstand( int za ) // setzt den Zeilenabstand
+{
+	lock();
+	zeilenAbstand = za;
+	alphabet->setZeilenAbstand( za );
+	unlock();
+}
+
+void Schrift::textFormatieren( Text *zText, int maxBreite, int schriftGröße ) // fügt zeilenumbrüche ein
+{
+	lock();
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( drawAlphabet )
+		drawAlphabet->textFormatieren( zText, maxBreite, schriftGröße );
+	unlock();
+}
+
+void Schrift::renderText( Text *zTxt, Bild &zRObj, int f ) // zeichnet txt nach zRObj
+{
+	lock();
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( drawAlphabet )
+	{
+		drawAlphabet->setDrawPosition( drawPos.x, drawPos.y );
+		drawAlphabet->render( zTxt, zRObj, f );
+	}
+	unlock();
+}
+
+void Schrift::renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f )
+{
+	lock();
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( drawAlphabet )
+	{
+		drawAlphabet->setDrawPosition( drawPos.x, drawPos.y );
+		drawAlphabet->render( zTxt, zRObj, cpos, cf, fbeg, ff, f );
+	}
+	unlock();
+}
+
+// constant 
+Alphabet *Schrift::getAlphabet( int sg ) const // gibt einen Alphaberarray zurück
+{
+	return alphabet->getAlphabet( sg );
+}
+
+Alphabet *Schrift::zAlphabet( int sg ) const
+{
+	return alphabet->zAlphabet( sg );
+}
+
+Alphabet *Schrift::getAlphabetI( int index ) const
+{
+	return alphabet->getAlphabetI( index, 0 );
+}
+
+Alphabet *Schrift::zAlphabetI( int index ) const
+{
+	return alphabet->zAlphabetI( index, 0 );
+}
+
+unsigned char Schrift::getAlphabetAnzahl() const // gibt die anzahl von in der Schrift enthaltenen Alphabeten zurück
+{
+	return alphabetAnzahl;
+}
+
+int Schrift::getSchriftGröße() const // gibt die Schriftgröße zurück
+{
+	return schriftGröße;
+}
+
+int Schrift::getZeilenabstand() const // gibt den Zeilenabstand zurück
+{
+	return zeilenAbstand;
+}
+
+int Schrift::getDrawX() const // gibt die Zeichenposition zurück
+{
+	return drawPos.x;
+}
+
+int Schrift::getDrawY() const
+{
+	return drawPos.y;
+}
+
+const Punkt &Schrift::getDrawPosition() const
+{
+	return drawPos;
+}
+
+int Schrift::getTextBreite( Text *zTxt ) const // gibt die Breite des Textes zurück
+{
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( !drawAlphabet )
+		return 0;
+	return drawAlphabet->getTextBreite( zTxt );
+}
+
+int Schrift::getTextHöhe( Text *zTxt ) const // gibt die Höhe des Textes zurück
+{
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( !drawAlphabet )
+		return 0;
+	return drawAlphabet->getTextHöhe( zTxt );
+}
+
+int Schrift::textPos( Text *zTxt, int mausX, int mausY ) const // gibt den Buchstaben zurück, auf den die Maus zeigt
+{
+	Alphabet *drawAlphabet = alphabet->zAlphabet( schriftGröße );
+	if( !drawAlphabet )
+	{
+		for( int i = 0; i < 256; ++i )
+		{
+			drawAlphabet = alphabet->zAlphabet( schriftGröße - i );
+			if( drawAlphabet )
+				break;
+			drawAlphabet = alphabet->zAlphabet( schriftGröße + i );
+			if( drawAlphabet )
+				break;
+		}
+	}
+	if( !drawAlphabet )
+		return 0;
+	return drawAlphabet->textPos( zTxt, mausX, mausY );
+}
+
+// Reference Counting 
+Schrift *Schrift::getThis()
+{
+	++ref;
+	return this;
+}
+
+Schrift *Schrift::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}

+ 364 - 0
Schrift.h

@@ -0,0 +1,364 @@
+#ifndef Schrift_H
+#define Schrift_H
+
+#include "Betriebssystem.h"
+#include "Punkt.h"
+
+namespace Framework
+{
+    class Bild; // Bild.h
+    class Text; // Text.h
+    struct VScrollData; // Scroll.h
+    struct HScrollData; // Scroll.h
+    class Buchstabe; // aus dieser Datei
+    class Alphabet; // aus dieser Datei
+    class Schrift; // aus dieser Datei
+
+    // Speichert die Alphawerte eines Zeichens einer bestimmten Schrift
+    // Die anderen Farbwerte werden durch die Schriftfarbe bestimmt. Daher nur die Alpha werte.
+    class Buchstabe
+    {
+    private:
+        Punkt größe;
+        Punkt pos;
+        unsigned char *alpha;
+        int schriftGröße;
+        int drawSg;
+        int ref;
+
+    public:
+        // Erstellt ein neues leeres Zeichnung
+        __declspec( dllexport ) Buchstabe();
+        // Löscht das Zeichnung
+        __declspec( dllexport ) ~Buchstabe();
+
+        // Erstellt einen neuen Buchstaben mit bestimmter Größe
+        //  größe: Die Größe des Buchstabens in Pixel
+        __declspec( dllexport ) void NeuBuchstabe( Punkt &größe );
+        // Setzt den Alphawert eines bestimmten Pixels
+        //  pos: Die position des Pixels
+        //  alpha: Der Wert des Pixels
+        __declspec( dllexport ) void setPixel( Punkt &pos, unsigned char alpha );
+        // Setzt den Alphawert eines bestimmten Pixels
+        //  x: die x Position des Pixels
+        //  y: die y Position des Pixels
+        //  alpha: Der Wert des Pixels
+        __declspec( dllexport ) void setPixel( int x, int y, unsigned char alpha );
+        // Setzt den Alphawert eines bestimmten Pixels
+        //  i: der Index des Pixels. Er berechnet sich durch x + y * breite und geht von 0 bis breite * höhe - 1
+        //  alpha: Der Wert des Pixels
+        __declspec( dllexport ) void setPixel( int i, unsigned char alpha );
+        // Setzt die Position, an die der Buchstabe gezeichnet werden soll
+        //  pos: Die position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setPosition( Punkt &pos );
+        // Setzt die Position, an die der Buchstabe gezeichnet werden soll
+        //  x: Die x position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        //  y: Die y position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setPosition( int x, int y );
+        // Setzt die Schriftgröße, zu der der Buchstabe gehört
+        //  sg: Die Schriftgröße des Buchstabens. Wenn der Buchstabe in einer anderen größe gezeichnet werden soll, wird automatisch skalliert
+        __declspec( dllexport ) void setSchriftGröße( int sg );
+        // Setzt die Schriftgröße, in der der Buchstabe gezeichnet werden soll
+        //  dsg: Die Schriftgröße, in der der Buchstabe gezeichnet werden soll. Ist die ungleich der Schriftgröße, zu der der Buchstabe gehört, so wird automatisch skalliert.
+        __declspec( dllexport ) void setDrawSchriftGröße( int dsg );
+
+        // Gibt die alpha Werte des Buchstabens als array zurück wobei die werte Zeilenweise hintereinander stehen
+        __declspec( dllexport ) unsigned char *getBuff() const;
+        // Gibt die Größe des Buchstabens in Pixeln nicht skalliert zurück.
+        __declspec( dllexport ) const Punkt &getGröße() const;
+        // Gibt die Breite des Buchstabens in Pixeln zurück (Der Wert wurde bereits mit der Draw Schriftgröße skalliert)
+        __declspec( dllexport ) int getBreite() const;
+        // Gibt die Höhe des Buchstabens in Pixeln zurück (Der Wert wurde bereits mit der Draw Schriftgröße skalliert)
+        __declspec( dllexport ) int getHöhe() const;
+        // Gibt die nicht skallierte Höhe des Buchstabens in Pixeln zurück
+        __declspec( dllexport ) int getNormHöhe() const;
+        // Zeichnet den Buchstaben in ein bestimmtes Bild
+        // Nutze (setPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zRObj: Das Bild, in den der Buchstabe gezeichnet werden soll
+        //  f: Die Farbe, in der der Buchstabe gezeichnet werden soll
+        __declspec( dllexport ) void render( Bild &zRObj, int f ) const;
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Buchstabe *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Buchstabe *release();
+    };
+
+    // Speichert alle Buchstaben der selben Schriftgröße.
+    // Wird von der Schrift klasse verwendet
+    class Alphabet
+    {
+    private:
+        Buchstabe **zeichen;
+        int schriftGröße;
+        int drawSchriftGröße;
+        Punkt pos;
+        int zeilenHöhe;
+        int zeilenAbstand;
+        int ref;
+
+    public:
+        // Erzeugt ein leeres Zeichnung
+        __declspec( dllexport ) Alphabet();
+        // Löscht ein Zeichnung
+        __declspec( dllexport ) ~Alphabet();
+
+        // Löscht alle gespeicherten Zeichen
+        __declspec( dllexport ) void NeuAlphabet();
+        // Fügt dem Alphabet einen Buchstaben hinzu
+        // Wenn der hinzugefügte Buchstabe bereits existiert wird er überschrieben
+        //  i: Der ASCII code des Buchstaben, der hinzugefügt werden soll
+        //  buchstabe: Der Buchstabe, der hinzugefügt wird
+        __declspec( dllexport ) void setBuchstabe( unsigned char i, Buchstabe *buchstabe );
+        // Setzt die Schriftgröße des Alphabets und die der gespeicherten buchstaben
+        //  gr: Die Schriftgröße des Alphabets
+        __declspec( dllexport ) void setSchriftgröße( int gr );
+        // Setzt die Schriftgröße, in der die gespeicherten Buchstaben gezeichnet werden sollen.
+        //  gr: Die Zeichen Schriftgröße. Wenn sie ungleich der Schriftgröße des Alphabets ist, wird automatisch skalliert
+        __declspec( dllexport ) void setDrawSchriftgröße( int gr );
+        // Setzt den Zeilenabstand beim Zeichnen eines Textes
+        //  za: Der Abschtand zum unteren Ende der Zeile darüber in Pixeln
+        __declspec( dllexport ) void setZeilenAbstand( int za );
+        // Setzt die Position, an die der Erste buchstabe gezeichnet werden soll
+        //  pos: Die position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setDrawPosition( Punkt &pos );
+        // Setzt die Position, an die der Erste buchstabe gezeichnet werden soll
+        //  x: Die x Position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        //  y: Die y Position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setDrawPosition( int x, int y );
+
+        // Gibt den gespeicherten Buchstaben zu einem bestimmten ASCII Zeichen zurück
+        //  i: Der ASCII code des Zeichens
+        //  return: Ein Zeiger zu dem Buchstaben mit erhöhtem Reference Counter
+        __declspec( dllexport ) Buchstabe *getBuchstabe( unsigned char i ) const;
+        // Gibt den gespeicherten Buchstaben zu einem bestimmten ASCII Zeichen zurück
+        //  i: Der ASCII code des Zeichens
+        //  return: Ein Zeiger zu dem Buchstaben ohne erhöhtem Reference Counter
+        __declspec( dllexport ) Buchstabe *zBuchstabe( unsigned char i ) const;
+        // Prüft, ob zu einem bestimmten ASCII code ein Zeichen vorhanden ist
+        //  b: Der zu prüfende ASCII code
+        //  return: (true), wenn ein Zeichen zu dem Code gefunden wurde. (false) sonnst
+        __declspec( dllexport ) bool hatBuchstabe( unsigned char b ) const;
+        // Gibt die Schriftgröße zurück, deren Zeichen in diesem Alphabet gespeichert werden
+        __declspec( dllexport ) int getSchriftgröße() const;
+        // Gibt die Schriftgröße zurück, in der die gespeicherten Zeichen gezeichnet werden
+        __declspec( dllexport ) int getDrawSchriftGröße() const;
+        // Gibt den Abstand in Pixeln zum unteren Ende der darüber ligenden Zeile zurück
+        __declspec( dllexport ) int getZeilenAbstand() const;
+        // Gibt die skallierte Höhe zurück, die eine gezeichnete Zeile in Pixeln benötigt
+        __declspec( dllexport ) int getZeilenHöhe() const;
+        // gibt die Position zurück, an der der erste Buchstabe gezeichnet wird
+        __declspec( dllexport ) const Punkt &getPosition() const;
+        // Ermittelt, wie viele Pixel benötigt werden, um einen Bestimmten Text vollständig darzustellen
+        //  zTxt: Der Text, von dem die Breite in Pixeln ermitelt werden soll
+        __declspec( dllexport ) int getTextBreite( Text *zTxt ) const;
+        // Ermittelt, wie viele Pixel benötigt werden, um einen Bestimmten Text vollständig darzustellen
+        //  zTxt: Der Text, von dem die Höhe in Pixeln ermitelt werden soll
+        __declspec( dllexport ) int getTextHöhe( Text *zTxt ) const;
+        // Ermittelt das Zeichen im Text, auf das die Maus zeigt
+        //  zTxt: Der Text, auf den die Maus Zeigt
+        //  mausX: Die X Position der Maus in Pixeln Relativ zur Position des ersten Zeichens
+        //  mausY: Die Y Position der Maus in Pixeln Relativ zur Position des ersten Zeichens
+        __declspec( dllexport ) int textPos( Text *zTxt, int mausX, int mausY ) const;
+        // Fügt Zeilenumbrüche in den Text ein, so dass er bei einer vorgegebenen Breite follständig angezeigt wird
+        //  zText: Der text, in den die Zeilenumbrüche eingefügt werden sollen
+        //  maxBreite: Die Breite in Pixeln auf der der Text follständig angezeigt werden soll
+        __declspec( dllexport ) void textFormatieren( Text *zText, int maxBreite, int schriftGröße );
+        // Zeichnet einen Bestimmten Text auf ein Bild
+        // Nutze (setDrawPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  f: Die Farbe, in der der Text gezeichnet werden soll
+        __declspec( dllexport ) void render( Text *zTxt, Bild &zRObj, int f ) const;
+        // Zeichnet einen Bestimmten Text mit Cursor und einfärbung auf ein Bild
+        // Nutze (setPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  cpos: Die position des Cursors im Text
+        //  cf: Die Farbe des Cursors
+        //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
+        //  ff: Die Hintergrund Farbe des eingefärbten Textes
+        //  f: Die Farbe, in der der Text gezeichnet werden soll
+        __declspec( dllexport ) void render( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f ) const;
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Alphabet *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Alphabet *release();
+    };
+
+    // Specihert eine Liste von Alphabeten mit verschiedener Schriftgröße.
+    // Wird von der Schrift Klasse verwendet, um alle Zeichen der Schriftgröße nach sortiert zu speichern.
+    class AlphabetArray
+    {
+    private:
+        AlphabetArray *next;
+        Alphabet *This;
+
+    public:
+        // Erzeugt eine neue Liste
+        __declspec( dllexport ) AlphabetArray();
+        // Löscht eine Liste
+        __declspec( dllexport ) ~AlphabetArray();
+
+        // Fügt der Liste ein Alphabet hinzu
+        // Wenn bereits ein Alphabet mit der selben Schriftgröße existiert, wird das Alphabet nicht hinzugefügt
+        //  alphabet: Das Alphabet, welches hinzugefügt werden soll
+        //  return: (true), wenn das Alphabet hinzugefügt wurde. (false) sonnst.
+        __declspec( dllexport ) bool addAlphabet( Alphabet *alphabet );
+        // Löscht ein Alphabet bestimmter Schriftgröße aus der Liste
+        //  sg: Die Schriftgröße des Alphabets, welches entfernt werden soll
+        //  return: (true), wenn ein Alphabet entfernt wurde. (false) sonnst
+        __declspec( dllexport ) bool removeAlphabet( int sg );
+        // Setzt die Schriftgröße, in der gezeichnet werden soll
+        //  sg: Die Schriftgröße
+        __declspec( dllexport ) void setDrawSchriftGröße( int sg );
+        // Setzt den Zeilenabstand, der zum zeichnen verwendet werden soll
+        //  za: Der Zeilenabstand zum unteren Ende der darüber liegenden zeile in Pixeln
+        __declspec( dllexport ) void setZeilenAbstand( int za );
+        // Setzt den Zeiger auf das nächste Element der Liste auf 0
+        __declspec( dllexport ) void setNext0();
+
+        // Gibt ein bestimmtes Alphabet mit erhöhtem Reference Counter zurück
+        //  sg: Die Schriftgröße, dessen Alphabet gesucht werden soll
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *getAlphabet( unsigned char sg ) const;
+        // Gibt ein bestimmtes Alphabet ohne erhöhtem Reference Counter zurück
+        //  sg: Die Schriftgröße, dessen Alphabet gesucht werden soll
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *zAlphabet( unsigned char sg ) const;
+        // Gibt ein bestimmtes Alphabet mit erhöhtem Reference Counter zurück
+        //  index: Der Index des gesuchten Alphabets in der Reihenfolge wie sie der Liste hinzugefügt wurden
+        //  count: Hier sollte 0 übergeben werden. Gibt an auf dem wievielten Element der Liste die Funktion aufgerufen wird.
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *getAlphabetI( int index, int count ) const;
+        // Gibt ein bestimmtes Alphabet ohne erhöhtem Reference Counter zurück
+        //  index: Der Index des gesuchten Alphabets in der Reihenfolge wie sie der Liste hinzugefügt wurden
+        //  count: Hier sollte 0 übergeben werden. Gibt an auf dem wievielten Element der Liste die Funktion aufgerufen wird.
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *zAlphabetI( int index, int count ) const;
+        // Gibt einen Zeiger auf das nächste Element der Liste zurück
+        __declspec( dllexport ) AlphabetArray *getNext() const;
+    };
+
+    // Speichert alle Buchstaben einer Schrift in verschiedenen Schriftgrößen
+    class Schrift
+    {
+    private:
+        unsigned char alphabetAnzahl;
+        AlphabetArray *alphabet;
+        int schriftGröße;
+        int zeilenAbstand;
+        Punkt drawPos;
+        CRITICAL_SECTION cs;
+        int ref;
+
+    public:
+        // Erzeugt eine leere Schrift
+        __declspec( dllexport ) Schrift();
+        // Löscht ein Zeichnung
+        __declspec( dllexport ) ~Schrift();
+
+        // Bereitet die Schrift auf das zeichnen eines Textes vor.
+        // Dies ist notwendig, falls mehrere Threads gleichzeitig die Schrift benutzen
+        __declspec( dllexport ) void lock();
+        // Beendet den Zeichenforgang der Schrift
+        // Muss für jeden aufruf von (lock();) einmal vom selben Thread aufgerufen werden,
+        // damit die Schrift wieder von anderen Threads verwendet werden kann
+        __declspec( dllexport ) void unlock();
+        // Fügt der Schrift ein Alphabet hinzu. Sollte bereits ein Alphabet der selben Schriftgröße existieren, wird das Alphabet nicht hinzugefügt
+        //  alphabet: Das Alphabet, welches hinzugefügt werden soll
+        //  return: (true), wenn das Alphabet hinzugefügt wurde. (false) sonnst
+        __declspec( dllexport ) bool addAlphabet( Alphabet *alphabet );
+        // Löscht ein bestimmtes Alphabet aus der Schrift
+        //  sg: Die Schriftgröße, deren Alphabet entfernt werden soll
+        __declspec( dllexport ) void removeAlphabet( int sg );
+        // Setzt die Position, an die der Erste buchstabe gezeichnet werden soll
+        //  x: Die x Position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        //  y: Die y Position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setDrawPosition( int x, int y );
+        // Setzt die Position, an die der Erste buchstabe gezeichnet werden soll
+        //  pos: Die Position relativ zu der Draw Position im zeichen Bild (siehe Bild::setDrawOptions)
+        __declspec( dllexport ) void setDrawPosition( Punkt &pos );
+        // Setzt die Schriftgröße, in der gezeichnet werden soll. Die Schrift wählt automatisch das passende Alphabet zum Zeichnen
+        //  sg: Die Schriftgröße
+        __declspec( dllexport ) void setSchriftGröße( int sg );
+        // Setzt den Zeilenabstand, der zum zeichnen verwendet werden soll
+        //  za: Der Zeilenabstand zum unteren Ende der darüber liegenden zeile in Pixeln
+        __declspec( dllexport ) void setZeilenAbstand( int za );
+        // Fügt Zeilenumbrüche in den Text ein, so dass er bei einer vorgegebenen Breite follständig angezeigt wird
+        //  zText: Der text, in den die Zeilenumbrüche eingefügt werden sollen
+        //  maxBreite: Die Breite in Pixeln auf der der Text follständig angezeigt werden soll
+        //  schriftGröße: Die Schriftgröße, die verwendet werden soll
+        __declspec( dllexport ) void textFormatieren( Text *zText, int maxBreite, int schriftGröße );
+        // Zeichnet einen Bestimmten Text auf ein Bild
+        // Nutze (setDrawPosition) und (setSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  f: Die Farbe, in der der Text gezeichnet werden soll
+        __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, int f );
+        // Zeichnet einen Bestimmten Text mit Cursor und einfärbung auf ein Bild
+        // Nutze (setPosition) und (setDrawSchriftGröße) um die Position und die Größe zu verändern
+        //  zText: Der Text, der gezeichnet werden soll
+        //  zRObj: Das Bild, auf das gezeichnet werden soll
+        //  cpos: Die position des Cursors im Text
+        //  cf: Die Farbe des Cursors
+        //  fbeg: Die Position des Zeichens im Text, wo die Einfärbung beginnen soll. Der Text wird von dort bis zur Cursorposition eingefärbt
+        //  ff: Die Hintergrund Farbe des eingefärbten Textes
+        //  f: Die Farbe, in der der Text gezeichnet werden soll
+        __declspec( dllexport ) void renderText( Text *zTxt, Bild &zRObj, int cpos, int cf, int fbeg, int ff, int f );
+        
+        // Gibt ein bestimmtes Alphabet mit erhöhtem Reference Counter zurück
+        //  sg: Die Schriftgröße, dessen Alphabet gesucht werden soll
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *getAlphabet( int sg ) const;
+        // Gibt ein bestimmtes Alphabet ohne erhöhtem Reference Counter zurück
+        //  sg: Die Schriftgröße, dessen Alphabet gesucht werden soll
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *zAlphabet( int sg ) const;
+        // Gibt ein bestimmtes Alphabet mit erhöhtem Reference Counter zurück
+        //  index: Der Index des gesuchten Alphabets in der Reihenfolge wie sie der Liste hinzugefügt wurden
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *getAlphabetI( int index ) const;
+        // Gibt ein bestimmtes Alphabet ohne erhöhtem Reference Counter zurück
+        //  index: Der Index des gesuchten Alphabets in der Reihenfolge wie sie der Liste hinzugefügt wurden
+        //  return: (0), fals kein passendes Alphabet gefunden wurde
+        __declspec( dllexport ) Alphabet *zAlphabetI( int index ) const;
+        // Gibt zurück, wie viele Alphabete (und damit Schriftgrößen) in der Schrift enthalten sind
+        __declspec( dllexport ) unsigned char getAlphabetAnzahl() const;
+        // Gibt die Schriftgröße zurück, die zum Zeichnen verwendet wird
+        __declspec( dllexport ) int getSchriftGröße() const;
+        // Gibt den Abstand in Pixeln zum unteren Ende der darüber ligenden Zeile zurück
+        __declspec( dllexport ) int getZeilenabstand() const;
+        // Gibt die x Koordinate des ersten Zeichens, dass gezeichnet wird, in Pixeln zurück
+        __declspec( dllexport ) int getDrawX() const;
+        // Gibt die y Koordinate des ersten Zeichens, dass gezeichnet wird, in Pixeln zurück
+        __declspec( dllexport ) int getDrawY() const;
+        // Gibt die Position des ersten Zeichens, dass gezeichnet wird, in Pixeln zurück
+        __declspec( dllexport ) const Punkt &getDrawPosition() const;
+        // Ermittelt, wie viele Pixel benötigt werden, um einen Bestimmten Text vollständig darzustellen
+        //  zTxt: Der Text, von dem die Breite in Pixeln ermitelt werden soll
+        __declspec( dllexport ) int getTextBreite( Text *zTxt ) const;
+        // Ermittelt, wie viele Pixel benötigt werden, um einen Bestimmten Text vollständig darzustellen
+        //  zTxt: Der Text, von dem die Höhe in Pixeln ermitelt werden soll
+        __declspec( dllexport ) int getTextHöhe( Text *zTxt ) const;
+        // Ermittelt das Zeichen im Text, auf das die Maus zeigt
+        //  zTxt: Der Text, auf den die Maus Zeigt
+        //  mausX: Die X Position der Maus in Pixeln Relativ zur Position des ersten Zeichens
+        //  mausY: Die Y Position der Maus in Pixeln Relativ zur Position des ersten Zeichens
+        __declspec( dllexport ) int textPos( Text *zTxt, int mausX, int mausY ) const;
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Schrift *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Schrift *release();
+    };
+}
+
+#endif

+ 465 - 0
Scroll.cpp

@@ -0,0 +1,465 @@
+#include "Scroll.h"
+#include "Bild.h"
+#include "MausEreignis.h"
+
+using namespace Framework;
+
+// Inhalt der VScrollBar Klasse aus Scroll.h
+// Konstruktor 
+VScrollBar::VScrollBar()
+	: data(new VScrollData()),
+	  knopfdruck( 0 ),
+	  farbe( 0xFF808080),
+	  bgFarbe( 0xFF000000 ),
+	  bg( 0 ),
+	  klickScroll( 10 ),
+	  mx( -1 ),
+	  my( -1 ),
+	  mp( 0 ),
+	  rend( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+VScrollBar::~VScrollBar()
+{
+	delete data;
+}
+
+// nicht constant
+void VScrollBar::setFarbe( int fc )
+{
+	farbe = fc;
+	rend = 1;
+}
+
+void VScrollBar::setBgFarbe( int fc, bool bgF )
+{
+	bgFarbe = fc;
+	bg = bgF;
+	rend = 1;
+}
+
+void VScrollBar::update( int maxHöhe, int anzeigeHöhe )
+{
+	if( data->maxHöhe != maxHöhe || data->anzeigeHöhe != anzeigeHöhe )
+	{
+		data->maxHöhe = maxHöhe, data->anzeigeHöhe = anzeigeHöhe;
+		rend = 1;
+	}
+	if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe && data->maxHöhe - data->anzeigeHöhe >= 0 )
+	{
+		data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+		rend = 1;
+	}
+	if( data->anzeigeBeginn < 0 )
+	{
+		data->anzeigeBeginn = 0;
+		rend = 1;
+	}
+}
+
+void VScrollBar::setKlickScroll( int ks )
+{
+	klickScroll = ks;
+	rend = 1;
+}
+
+void VScrollBar::scroll( int höhe )
+{
+	data->anzeigeBeginn = höhe;
+	if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+		data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+	if( data->anzeigeBeginn < 0 )
+		data->anzeigeBeginn = 0;
+	rend = 1;
+}
+
+bool VScrollBar::doMausMessage( int x, int y, int br, int hö, MausEreignis &me )
+{
+    bool ret = me.mx >= x && me.mx <= x + br && me.my >= y && me.my <= y + hö;
+	knopfdruck = 0;
+	if( me.verarbeitet )
+	{
+		mx = -1, my = -1;
+		mp = 0;
+		return ret;
+	}
+	if( me.id == ME_UScroll )
+	{
+		data->anzeigeBeginn -= klickScroll;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		rend = 1;
+		return ret;
+	}
+	if( me.id == ME_DScroll )
+	{
+		data->anzeigeBeginn += klickScroll;
+		if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+			data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		rend = 1;
+		return ret;
+	}
+	if( ret )
+		mx = me.mx - x, my = me.my - y;
+	else
+		mx = -1, my = -1;
+	if( me.id == ME_PLinks )
+		mp = 1;
+	if( me.id == ME_RLinks )
+		mp = 0;
+	if( mp )
+	{
+		if( mx >= 0 && my >= 0 )
+		{
+			if( my < br )
+			{
+				knopfdruck = 1;
+				data->anzeigeBeginn -= klickScroll;
+			}
+			else if( my > hö - br )
+			{
+				knopfdruck = 2;
+				data->anzeigeBeginn += klickScroll;
+			}
+			else
+				data->anzeigeBeginn = (int)( ( data->maxHöhe / ( hö - 2.0 * br ) ) * ( my - br ) ) - data->anzeigeHöhe / 2;
+			if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+				data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+			if( data->anzeigeBeginn < 0 )
+				data->anzeigeBeginn = 0;
+			rend = 1;
+		}
+	}
+    return ret;
+}
+
+bool VScrollBar::getRend()
+{
+	if( knopfdruck == 1 )
+	{
+		int tmp = data->anzeigeBeginn;
+		data->anzeigeBeginn -= klickScroll;
+		if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+			data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		if( tmp != data->anzeigeBeginn )
+			rend = 1;
+	}
+	if( knopfdruck == 2 )
+	{
+		int tmp = data->anzeigeBeginn;
+		data->anzeigeBeginn += klickScroll;
+		if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+			data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		if( tmp != data->anzeigeBeginn )
+			rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+// const 
+void VScrollBar::render( int x, int y, int br, int hö, Bild &zRObj ) const
+{
+	if( bg )
+		zRObj.alphaRegion( x, y, br, hö, bgFarbe );
+	--br;
+	--hö;
+	zRObj.drawLinieH( x, y, br + 1, farbe );
+	zRObj.drawLinieH( x, y + hö, br + 1, farbe );
+	zRObj.drawLinieV( x, y + 1, hö - 1, farbe );
+	zRObj.drawLinieV( x + br, y + 1, hö - 1, farbe );
+	zRObj.drawLinieH( x + 1, y + br, br - 1, farbe );
+	zRObj.drawLinieH( x + 1, y + hö - br, br - 1, farbe );
+	++br;
+	++hö;
+	int st = (int)( data->anzeigeBeginn / ( data->maxHöhe / ( hö - br * 2.0 ) ) );
+	int end = (int)( ( hö - 2.0 * br ) / ( (double)data->maxHöhe / data->anzeigeHöhe ) );
+	if( data->anzeigeBeginn > data->maxHöhe - data->anzeigeHöhe )
+		data->anzeigeBeginn = data->maxHöhe - data->anzeigeHöhe;
+	if( data->anzeigeBeginn < 0 )
+	{
+		data->anzeigeBeginn = 0;
+		end = hö - br * 2;
+	}
+	zRObj.füllRegion( x + 1, y + br + st, br - 1, end, farbe );
+}
+
+VScrollData *VScrollBar::getScrollData() const
+{
+	return data;
+}
+
+int VScrollBar::getKlickScroll() const
+{
+	return klickScroll;
+}
+
+int VScrollBar::getFarbe() const
+{
+	return farbe;
+}
+
+int VScrollBar::getBgFarbe() const
+{
+	return bg ? bgFarbe : 0;
+}
+
+int VScrollBar::getScroll() const
+{
+    return data->anzeigeBeginn;
+}
+
+// Reference Counting
+VScrollBar *VScrollBar::getThis()
+{
+	++ref;
+	return this;
+}
+
+VScrollBar *VScrollBar::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}
+
+// Inhalt der HScrollBar Klasse aus Scroll.h
+// Konstruktor 
+HScrollBar::HScrollBar()
+	: data( new HScrollData() ),
+	  knopfdruck( 0 ),
+	  farbe( 0xFF808080),
+	  bgFarbe( 0 ),
+	  bg( 0 ),
+	  klickScroll( 10 ),
+	  mx( -1 ),
+	  my( -1 ),
+	  mp( 0 ),
+	  rend( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+HScrollBar::~HScrollBar()
+{
+	delete data;
+}
+
+// nicht constant
+void HScrollBar::setFarbe( int fc )
+{
+	farbe = fc;
+	rend = 1;
+}
+
+void HScrollBar::setBgFarbe( int fc, bool bgF )
+{
+	bgFarbe = fc;
+	bg = bgF;
+	rend = 1;
+}
+
+void HScrollBar::update( int maxBreite, int anzeigeBreite )
+{
+	if( data->maxBreite != maxBreite || data->anzeigeBreite != anzeigeBreite )
+	{
+		data->maxBreite = maxBreite, data->anzeigeBreite = anzeigeBreite;
+		rend = 1;
+	}
+	if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite && data->maxBreite - data->anzeigeBreite >= 0 )
+	{
+		data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+		rend = 1;
+	}
+	if( data->anzeigeBeginn < 0 )
+	{
+		data->anzeigeBeginn = 0;
+		rend = 1;
+	}
+}
+
+void HScrollBar::setKlickScroll( int ks )
+{
+	klickScroll = ks;
+	rend = 1;
+}
+
+void HScrollBar::scroll( int breite )
+{
+	data->anzeigeBeginn = breite;
+	if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+		data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+	if( data->anzeigeBeginn < 0 )
+		data->anzeigeBeginn = 0;
+	rend = 1;
+}
+
+bool HScrollBar::doMausMessage( int x, int y, int br, int hö, MausEreignis &me )
+{
+    bool ret = me.mx >= x && me.mx <= x + br && me.my >= y && me.my <= y + hö;
+	knopfdruck = 0;
+	if( me.verarbeitet )
+	{
+		mx = -1, my = -1;
+		mp = 0;
+		return ret;
+	}
+	if( me.id == ME_LScroll )
+	{
+		data->anzeigeBeginn -= klickScroll;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		rend = 1;
+		return ret;
+	}
+	if( me.id == ME_RScroll )
+	{
+		data->anzeigeBeginn += klickScroll;
+		if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+			data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		rend = 1;
+		return ret;
+	}
+	if( ret )
+		mx = me.mx - x, my = me.my - y;
+	else
+		mx = -1, my = -1;
+	if( me.id == ME_PLinks )
+		mp = 1;
+	if( me.id == ME_RLinks )
+		mp = 0;
+	if( mp )
+	{
+		if( mx >= 0 && my >= 0 )
+		{
+			if( mx < hö )
+			{
+				knopfdruck = 1;
+				data->anzeigeBeginn -= klickScroll;
+			}
+			else if( mx > br - hö )
+			{
+				knopfdruck = 2;
+				data->anzeigeBeginn += klickScroll;
+			}
+			else
+				data->anzeigeBeginn = (int)( ( data->maxBreite / ( br - 2.0 * hö ) ) * ( mx - hö ) ) - data->anzeigeBreite / 2;
+			if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+				data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+			if( data->anzeigeBeginn < 0 )
+				data->anzeigeBeginn = 0;
+			rend = 1;
+		}
+	}
+    return ret;
+}
+
+bool HScrollBar::getRend()
+{
+	if( knopfdruck == 1 )
+	{
+		int tmp = data->anzeigeBeginn;
+		data->anzeigeBeginn -= klickScroll;
+		if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+			data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		if( tmp != data->anzeigeBeginn )
+			rend = 1;
+	}
+	if( knopfdruck == 2 )
+	{
+		int tmp = data->anzeigeBeginn;
+		data->anzeigeBeginn += klickScroll;
+		if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+			data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+		if( data->anzeigeBeginn < 0 )
+			data->anzeigeBeginn = 0;
+		if( tmp != data->anzeigeBeginn )
+			rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+// const 
+void HScrollBar::render( int x, int y, int br, int hö, Bild &zRObj ) const
+{
+	if( bg )
+		zRObj.alphaRegion( x, y, br, hö, bgFarbe );
+	--br;
+	--hö;
+	zRObj.drawLinieV( x, y, hö + 1, farbe );
+	zRObj.drawLinieV( x + br, y, hö + 1, farbe );
+	zRObj.drawLinieH( x + 1, y, br - 1, farbe );
+	zRObj.drawLinieH( x + 1, y + hö, br - 1, farbe );
+	zRObj.drawLinieV( x + hö, y + 1, hö - 1, farbe );
+	zRObj.drawLinieV( x + br - hö, y + 1, hö - 1, farbe );
+	++br;
+	++hö;
+	int st = (int)( data->anzeigeBeginn / ( data->maxBreite / ( br - hö * 2.0 ) ) );
+	int end = (int)( ( br - 2.0 * hö ) / ( (double)data->maxBreite / data->anzeigeBreite ) );
+	if( data->anzeigeBeginn > data->maxBreite - data->anzeigeBreite )
+		data->anzeigeBeginn = data->maxBreite - data->anzeigeBreite;
+	if( data->anzeigeBeginn < 0 )
+	{
+		data->anzeigeBeginn = 0;
+		end = br - hö * 2;
+	}
+	zRObj.füllRegion( x + hö + st, y + 1, end, hö - 1, farbe );
+}
+
+HScrollData *HScrollBar::getScrollData() const
+{
+	return data;
+}
+
+int HScrollBar::getKlickScroll() const
+{
+	return klickScroll;
+}
+
+int HScrollBar::getFarbe() const
+{
+	return farbe;
+}
+
+int HScrollBar::getBgFarbe() const
+{
+	return bg ? bgFarbe : 0;
+}
+
+int HScrollBar::getScroll() const
+{
+    return data->anzeigeBeginn;
+}
+
+// Reference Counting
+HScrollBar *HScrollBar::getThis()
+{
+	++ref;
+	return this;
+}
+
+HScrollBar *HScrollBar::release()
+{
+	--ref;
+	if( ref == 0 )
+		delete this;
+	return 0;
+}

+ 108 - 0
Scroll.h

@@ -0,0 +1,108 @@
+#ifndef Scroll_H
+#define Scroll_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+	class Bild; // Bild.h
+	struct MausEreignis; // MausEreignis.h
+	struct VScrollData; // aus dieser Datei
+	struct HScrollData; // aus dieser Datei
+	class VScrollBar; // aus dieser Datei
+	class HScrollBar; // aus dieser Datei
+
+	struct VScrollData
+	{
+		int anzeigeHöhe;
+		int maxHöhe;
+		int anzeigeBeginn;
+	};
+
+	struct HScrollData
+	{
+		int anzeigeBreite;
+		int maxBreite;
+		int anzeigeBeginn;
+	};
+
+	class VScrollBar
+	{
+	private:
+		VScrollData *data;
+		int knopfdruck;
+		int farbe;
+		int bgFarbe;
+		bool bg;
+		int klickScroll;
+		int mx, my;
+		bool mp;
+		bool rend;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) VScrollBar();
+		// Destruktor 
+		__declspec( dllexport ) ~VScrollBar();
+		// nicht constant
+		__declspec( dllexport ) void setFarbe( int fc );
+		__declspec( dllexport ) void setBgFarbe( int fc, bool bgF );
+		__declspec( dllexport ) void update( int maxHöhe, int anzeigeHöhe );
+		__declspec( dllexport ) void setKlickScroll( int klickScroll );
+		__declspec( dllexport ) void scroll( int höhe );
+		__declspec( dllexport ) bool doMausMessage( int x, int y, int br, int hö, MausEreignis &me );
+		__declspec( dllexport ) bool getRend();
+		// constant 
+		__declspec( dllexport ) void render( int x, int y, int br, int hö, Bild &zRObj ) const;
+		__declspec( dllexport ) VScrollData *getScrollData() const;
+		__declspec( dllexport ) int getKlickScroll() const;
+		__declspec( dllexport ) int getFarbe() const;
+		__declspec( dllexport ) int getBgFarbe() const;
+        __declspec( dllexport ) int getScroll() const;
+		// Reference Counting
+		__declspec( dllexport ) VScrollBar *getThis();
+		__declspec( dllexport ) VScrollBar *release();
+	};
+
+	class HScrollBar
+	{
+	private:
+		HScrollData *data;
+		int knopfdruck;
+		int farbe;
+		int bgFarbe;
+		bool bg;
+		int klickScroll;
+		int mx, my;
+		bool mp;
+		bool rend;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) HScrollBar();
+		// Destruktor 
+		__declspec( dllexport ) ~HScrollBar();
+		// nicht constant
+		__declspec( dllexport ) void setFarbe( int fc );
+		__declspec( dllexport ) void setBgFarbe( int fc, bool bgF );
+		__declspec( dllexport ) void update( int maxBreite, int anzeigeBreite );
+		__declspec( dllexport ) void setKlickScroll( int klickScroll );
+		__declspec( dllexport ) void scroll( int breite );
+		__declspec( dllexport ) bool doMausMessage( int x, int y, int br, int hö, MausEreignis &me );
+		__declspec( dllexport ) bool getRend();
+		// constant 
+		__declspec( dllexport ) void render( int x, int y, int br, int hö, Bild &zRObj ) const;
+		__declspec( dllexport ) HScrollData *getScrollData() const;
+		__declspec( dllexport ) int getKlickScroll() const;
+		__declspec( dllexport ) int getFarbe() const;
+		__declspec( dllexport ) int getBgFarbe() const;
+        __declspec( dllexport ) int getScroll() const;
+		// Reference Counting
+		__declspec( dllexport ) HScrollBar *getThis();
+		__declspec( dllexport ) HScrollBar *release();
+	};
+}
+
+#endif

+ 336 - 0
Shader.cpp

@@ -0,0 +1,336 @@
+#include "Shader.h"
+#include "Text.h"
+#include "Datei.h"
+#include <d3d11.h>
+#include <D3Dcompiler.h>
+#include <iostream>
+
+using namespace Framework;
+
+// Inhalt der Shader Klasse
+
+// Konstruktor
+Shader::Shader()
+{
+    shader = new Text();
+    shaderBuffer = 0;
+    type = UNBEKANNT;
+    for( int i = 0; i < 14; i++ )
+    {
+        constBuffers[ i ] = 0;
+        buffLän[ i ] = 0;
+    }
+    buffAnz = 0;
+    ref = 1;
+}
+
+// Destruktor
+Shader::~Shader()
+{
+    shader->release();
+    if( shaderBuffer )
+        shaderBuffer->Release();
+    for( int i = 0; i < 14; i++ )
+    {
+        if( constBuffers[ i ] )
+            constBuffers[ i ]->Release();
+    }
+}
+
+// Lähdt den Shader Quellcode aus einer Textdatei
+//  pfad: Der Pfad zur Datei
+//  return: true, wenn der Shader erfolgreich geladen wurde
+bool Shader::ladeAusDatei( const char *pfad )
+{
+    Datei d;
+    d.setDatei( pfad );
+    __int64 gr = d.getGröße();
+    if( gr > 10 * 1024 )
+        return 0; // Datei zu groß für Shader Quellcode
+    shader->füllText( ' ', (int)gr );
+    if( !d.öffnen( Datei::Style::lesen ) )
+        return 0;
+    d.lese( shader->getText(), (int)gr );
+    d.schließen();
+    return 1;
+}
+
+// Setzt den Shader Quellcode
+//  zCode: Der Quellcode des Shaders
+void Shader::setShaderCode( Text *zCode )
+{
+    shader->setText( zCode->getText() );
+}
+
+// Compiliert den Shader Quellcode
+//  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+//  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+//  type: Der Typ und die Version des Shaders. Beispiel: 'vs_5_0' für Vertexshader, 'ps_5_0' für Pixelshader.
+//  return: true, wenn der Quellcode keine Fehler enthällt
+bool Shader::compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *type )
+{
+    ID3D10Blob* errorMessage = 0;
+    unsigned int flag = D3D10_SHADER_ENABLE_STRICTNESS;
+#ifdef _DEBUG
+    flag |= D3D10_SHADER_DEBUG;
+#endif
+    if( shaderBuffer )
+        shaderBuffer->Release();
+    HRESULT result = D3DCompile( shader->getText(), shader->getLänge(), 0, 0, 0, einstiegsFunktion, type, flag, 0, &shaderBuffer, &errorMessage );
+    if( errorMessage )
+    {
+        char *err = (char*)errorMessage->GetBufferPointer();
+        std::cout << err;
+        errorMessage->Release();
+    }
+    return result == S_OK;
+}
+
+// Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
+//  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+void Shader::benutzeShader( ID3D11DeviceContext *zD3d11Context )
+{
+}
+
+// erstellt ein constanten Buffer, der constante daten an den Shader übergibt
+// es können maximal 14 Buffer erstellt werden
+//  zD3d11Device: Das Device, mit dem der Buffer erstellt werden soll
+//  größe: Die größe des buffers in byte
+//  index: Die position des Buffers im Buffer Array. Bereits vorhanderner Buffer wird ersetzt. Buffer 1 kann nicht erstellt werden, wenn Buffer 0 noch nicht erstellt wurde usw.
+bool Shader::erstelleConstBuffer( ID3D11Device *zD3d11Device, int größe, int index )
+{
+    if( index < 0 || index >= 14 )
+        return 0;
+    bool ok = 1;
+    for( int i = 0; i < index; i++ )
+        ok &= constBuffers[ index ] != 0;
+    if( !ok )
+        return 0;
+    D3D11_BUFFER_DESC bufferDesc;
+    bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+    bufferDesc.ByteWidth = größe;
+    bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+    bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    bufferDesc.MiscFlags = 0;
+    bufferDesc.StructureByteStride = 0;
+    if( constBuffers[ index ] )
+    {
+        constBuffers[ index ]->Release();
+        constBuffers[ index ] = 0;
+        buffLän[ index ] = 0;
+    }
+    HRESULT res = zD3d11Device->CreateBuffer( &bufferDesc, 0, &constBuffers[ index ] );
+    if( res == S_OK )
+        buffLän[ index ] = größe;
+    for( buffAnz = 0; buffAnz < 14 && constBuffers[ buffAnz ]; buffAnz++ );
+    return res == S_OK;
+}
+
+// Löscht einen constanten Buffer
+//  index: der Index des Buffers, der gelöscht werden soll. Buffer 0 kann nicht gelöscht werden, solange Buffer 1 noch existiert usw.
+bool Shader::löscheConstBuffer( int index )
+{
+    if( index < 0 || index >= 14 )
+        return 0;
+    bool ok = 1;
+    for( int i = 13; i > index; i-- )
+        ok &= constBuffers[ i ] == 0;
+    if( !ok )
+        return 0;
+    if( constBuffers[ index ] )
+    {
+        constBuffers[ index ]->Release();
+        constBuffers[ index ] = 0;
+        buffLän[ index ] = 0;
+    }
+    for( buffAnz = 0; buffAnz < 14 && constBuffers[ buffAnz ]; buffAnz++ );
+    return 1;
+}
+
+// Kopiert daten in einen constanten buffer
+//  zD3d11Context: Das Context Objekt, das zum kopieren verwendt werden soll
+//  data: Einen zeiger auf en byte Array der größe des Buffers
+//  index: Der Index des Buffers
+bool Shader::füllConstBuffer( ID3D11DeviceContext *zD3d11Context, char *data, int index )
+{
+    if( index < 0 || index >= 14 )
+        return 0;
+    if( !constBuffers[ index ] )
+        return 0;
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT res = zD3d11Context->Map( constBuffers[ index ], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource );
+    if( res != S_OK )
+        return 0;
+    memcpy( mappedResource.pData, data, buffLän[ index ] );
+    zD3d11Context->Unmap( constBuffers[ index ], 0 );
+    return 1;
+}
+
+// Gibt die Länge eines constanten Buffers zurück
+//  index: Der Index des Buffers
+int Shader::getConstBufferLänge( int index ) const
+{
+    if( index < 0 || index >= 14 )
+        return 0;
+    return buffLän[ index ];
+}
+
+// Gibt den Shadertyp zurück
+ShaderType Shader::getType() const
+{
+    return type;
+}
+
+// Erhöht den Reference Counter um 1
+//  Return: Ein zeiger auf diesen Shader
+Shader *Shader::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+//  Return: 0
+Shader *Shader::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Inhalt der PixelShader Klasse
+
+// Konstruktor
+PixelShader::PixelShader()
+    : Shader()
+{
+    pixelShader = 0;
+}
+
+// Destruktor
+PixelShader::~PixelShader()
+{
+    if( pixelShader )
+        pixelShader->Release();
+}
+
+// Compiliert den Shader Quellcode
+//  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+//  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+//  type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
+//  return: true, wenn kein Fehler aufgetreten ist
+bool PixelShader::compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *version )
+{
+    Text v = "ps_";
+    v += version;
+    if( !__super::compile( zD3d11Device, einstiegsFunktion, v ) )
+        return 0;
+    if( pixelShader )
+        pixelShader->Release();
+    pixelShader = 0;
+    HRESULT result = zD3d11Device->CreatePixelShader( shaderBuffer->GetBufferPointer(), shaderBuffer->GetBufferSize(), 0, &pixelShader );
+    shaderBuffer->Release();
+    shaderBuffer = 0;
+    return result == S_OK;
+}
+
+// Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
+//  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+void PixelShader::benutzeShader( ID3D11DeviceContext *zD3d11Context )
+{
+    if( buffAnz )
+        zD3d11Context->PSSetConstantBuffers( 0, buffAnz, constBuffers );
+    if( pixelShader )
+        zD3d11Context->PSSetShader( pixelShader, 0, 0 );
+}
+
+// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+//  Return: 0
+Shader *PixelShader::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Inhalt der VertexShader Klasse
+
+// Konstruktor
+VertexShader::VertexShader()
+    : Shader()
+{
+    vertexShader = 0;
+    inputLayout = 0;
+}
+
+// Destruktor
+VertexShader::~VertexShader()
+{
+    if( vertexShader )
+        vertexShader->Release();
+    if( inputLayout )
+        inputLayout->Release();
+}
+
+// Compiliert den Shader Quellcode
+//  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+//  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+//  type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
+//  return: true, wenn kein Fehler aufgetreten ist
+bool VertexShader::compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *version )
+{
+    Text v = "vs_";
+    v += version;
+    if( !__super::compile( zD3d11Device, einstiegsFunktion, v ) )
+        return 0;
+    if( vertexShader )
+        vertexShader->Release();
+    vertexShader = 0;
+    HRESULT result = zD3d11Device->CreateVertexShader( shaderBuffer->GetBufferPointer(), shaderBuffer->GetBufferSize(), 0, &vertexShader );
+    return result == S_OK;
+}
+
+// erstellt ein InputLayout für den Shader
+// Darf erst nach compile aufgerufen werden
+//  zD3d11Device: Das Device, mit dem das Layout erstellt werden soll
+//  descArray: Ein Array mit initialisierungsdaten
+//  anz: Die Anzahl der Elemente im Array
+bool VertexShader::erstelleInputLayout( ID3D11Device *zD3d11Device, D3D11_INPUT_ELEMENT_DESC *descArray, int anz )
+{
+    if( !shaderBuffer )
+        return 0;
+    if( inputLayout )
+        inputLayout->Release();
+    inputLayout = 0;
+    HRESULT res = zD3d11Device->CreateInputLayout( descArray, anz, shaderBuffer->GetBufferPointer(), shaderBuffer->GetBufferSize(), &inputLayout );
+    if( res == S_OK )
+    {
+        shaderBuffer->Release();
+        shaderBuffer = 0;
+    }
+    return res == S_OK;
+}
+
+// Nach dem Aufruf dieser Funktion wird dieser Shader als Vertex Shader benutzt
+//  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+void VertexShader::benutzeShader( ID3D11DeviceContext *zD3d11Context )
+{
+    if( buffAnz )
+        zD3d11Context->VSSetConstantBuffers( 0, buffAnz, constBuffers );
+    if( inputLayout )
+        zD3d11Context->IASetInputLayout( inputLayout );
+    if( vertexShader )
+        zD3d11Context->VSSetShader( vertexShader, 0, 0 );
+}
+
+// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+//  Return: 0
+Shader *VertexShader::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 136 - 0
Shader.h

@@ -0,0 +1,136 @@
+#pragma once
+
+struct ID3D10Blob;
+struct ID3D11PixelShader;
+struct ID3D11VertexShader;
+struct ID3D11Device;
+struct ID3D11DeviceContext;
+struct D3D11_INPUT_ELEMENT_DESC;
+struct ID3D11Buffer;
+struct ID3D11InputLayout;
+
+namespace Framework
+{
+    class Text;
+
+    enum ShaderType
+    {
+        UNBEKANNT,
+        VERTEX,
+        PIXEL
+    };
+
+    class Shader
+    {
+    protected:
+        Text *shader;
+        ID3D10Blob *shaderBuffer;
+        ShaderType type;
+        ID3D11Buffer *constBuffers[ 14 ];
+        int buffLän[ 14 ];
+        int buffAnz;
+        int ref;
+
+    public:
+        // Konstruktor
+        Shader();
+        // Destruktor
+        ~Shader();
+        // Lähdt den Shader Quellcode aus einer Textdatei
+        //  pfad: Der Pfad zur Datei
+        //  return: true, wenn der Shader erfolgreich geladen wurde
+        bool ladeAusDatei( const char *pfad );
+        // Setzt den Shader Quellcode
+        //  zCode: Der Quellcode des Shaders
+        void setShaderCode( Text *zCode );
+        // Compiliert den Shader Quellcode
+        //  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+        //  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+        //  type: Der Typ und die Version des Shaders. Beispiel: 'vs_5_0' für Vertexshader, 'ps_5_0' für Pixelshader.
+        //  return: true, wenn der Quellcode keine Fehler enthällt
+        virtual bool compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *type );
+        // Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
+        //  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+        virtual void benutzeShader( ID3D11DeviceContext *zD3d11Context );
+        // erstellt ein constanten Buffer, der constante daten an den Shader übergibt
+        // es können maximal 14 Buffer erstellt werden
+        //  zD3d11Device: Das Device, mit dem der Buffer erstellt werden soll
+        //  größe: Die größe des buffers in byte
+        //  index: Die position des Buffers im Buffer Array. Bereits vorhanderner Buffer wird ersetzt. Buffer 1 kann nicht erstellt werden, wenn Buffer 0 noch nicht erstellt wurde usw.
+        bool erstelleConstBuffer( ID3D11Device *zD3d11Device, int größe, int index );
+        // Löscht einen constanten Buffer
+        //  index: der Index des Buffers, der gelöscht werden soll. Buffer 0 kann nicht gelöscht werden, solange Buffer 1 noch existiert usw.
+        bool löscheConstBuffer( int index );
+        // Kopiert daten in einen constanten buffer
+        //  zD3d11Context: Das Context Objekt, das zum kopieren verwendt werden soll
+        //  data: Einen zeiger auf en byte Array der größe des Buffers
+        //  index: Der Index des Buffers
+        bool füllConstBuffer( ID3D11DeviceContext *zD3d11Context, char *data, int index );
+        // Gibt die Länge eines constanten Buffers zurück
+        //  index: Der Index des Buffers
+        int getConstBufferLänge( int index ) const;
+        // Gibt den Shadertyp zurück
+        ShaderType getType() const;
+        // Erhöht den Reference Counter um 1
+        //  Return: Ein zeiger auf diesen Shader
+        Shader *getThis();
+        // Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+        //  Return: 0
+        virtual Shader *release();
+    };
+
+    class PixelShader : public Shader
+    {
+    private:
+        ID3D11PixelShader *pixelShader;
+
+    public:
+        // Konstruktor
+        PixelShader();
+        // Destruktor
+        ~PixelShader();
+        // Compiliert den Shader Quellcode
+        //  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+        //  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+        //  type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
+        //  return: true, wenn kein Fehler aufgetreten ist
+        bool compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *version ) override;
+        // Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
+        //  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+        void benutzeShader( ID3D11DeviceContext *zD3d11Context );
+        // Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+        //  Return: 0
+        Shader *release();
+    };
+
+    class VertexShader : public Shader
+    {
+    private:
+        ID3D11VertexShader *vertexShader;
+        ID3D11InputLayout *inputLayout;
+
+    public:
+        // Konstruktor
+        VertexShader();
+        // Destruktor
+        ~VertexShader();
+        // Compiliert den Shader Quellcode
+        //  zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
+        //  einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
+        //  type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
+        //  return: true, wenn kein Fehler aufgetreten ist
+        bool compile( ID3D11Device *zD3d11Device, const char *einstiegsFunktion, const char *version ) override;
+        // erstellt ein InputLayout für den Shader
+        // Darf erst nach compile aufgerufen werden
+        //  zD3d11Device: Das Device, mit dem das Layout erstellt werden soll
+        //  descArray: Ein Array mit initialisierungsdaten
+        //  anz: Die Anzahl der Elemente im Array
+        bool erstelleInputLayout( ID3D11Device *zD3d11Device, D3D11_INPUT_ELEMENT_DESC *descArray, int anz );
+        // Nach dem Aufruf dieser Funktion wird dieser Shader als Vertex Shader benutzt
+        //  zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
+        void benutzeShader( ID3D11DeviceContext *zD3d11Context );
+        // Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
+        //  Return: 0
+        Shader *release();
+    };
+}

+ 1592 - 0
Tabelle.cpp

@@ -0,0 +1,1592 @@
+#include "Tabelle.h"
+#include "Scroll.h"
+#include "AlphaFeld.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Bild.h"
+#include "Rahmen.h"
+#include "Text.h"
+#include "ToolTip.h"
+
+using namespace Framework;
+
+// Inhalt der ObjTabelle Klasse aus Tabelle.h
+// Konstruktor 
+ObjTabelle::ObjTabelle()
+	: ZeichnungHintergrund(),
+	  zZeichnungs( new RCArray< Array< Zeichnung* > >() ),
+	  spaltenNamen( new RCArray< Text >() ),
+	  zeilenNamen( new RCArray< Text >() ),
+	  spaltenBreite( new Array< int >() ),
+	  zeilenHöhe( new Array< int >() ),
+	  minSpaltenBreite( new Array< int >() ),
+	  maxSpaltenBreite( new Array< int >() ),
+	  minZeilenHöhe( new Array< int >() ),
+	  maxZeilenHöhe( new Array< int >() ),
+	  spaltenAnzahl( 0 ),
+	  zeilenAnzahl( 0 ),
+	  klickSpalte( -1 ),
+	  mSpalte( -1 ),
+	  mZeile( -1 ),
+	  mx( 0 ),
+	  my( 0 ),
+	  selected( -1, -1 ),
+	  rasterFarbe( 0xFF000000 ),
+	  rasterBreite( 1 ),
+	  aRam( 0 ),
+	  aAf( 0 ),
+	  msaRam( new RCArray< RCArray< LRahmen > >() ),
+	  msaAf( new RCArray< RCArray< AlphaFeld > >() ),
+	  styles( new RCArray< Array< __int64 > >() ),
+	  ref( 1 )
+{
+    style = 0;
+}
+
+// Destruktor 
+ObjTabelle::~ObjTabelle()
+{
+	if( zZeichnungs )
+		zZeichnungs->release();
+	if( spaltenNamen )
+		spaltenNamen->release();
+	if( zeilenNamen )
+		zeilenNamen->release();
+	if( spaltenBreite )
+		spaltenBreite->release();
+	if( zeilenHöhe )
+		zeilenHöhe->release();
+	if( minSpaltenBreite )
+		minSpaltenBreite->release();
+	if( maxSpaltenBreite )
+		maxSpaltenBreite->release();
+	if( minZeilenHöhe )
+		minZeilenHöhe->release();
+	if( maxZeilenHöhe )
+		maxZeilenHöhe->release();
+	if( aRam )
+		aRam->release();
+	if( aAf )
+		aAf->release();
+	if( msaRam )
+		msaRam->release();
+	if( msaAf )
+		msaAf->release();
+	if( styles )
+		styles->release();
+}
+
+// nicht constant 
+void ObjTabelle::addSpalte( const char *name ) // Spalte hinzufügen
+{
+	lockZeichnung();
+	zZeichnungs->add( new Array< Zeichnung* >(), spaltenAnzahl );
+	spaltenNamen->add( new Text( name ), spaltenAnzahl );
+	spaltenBreite->add( 100 );
+	msaRam->add( new RCArray< LRahmen >(), spaltenAnzahl );
+	msaAf->add( new RCArray< AlphaFeld >(), spaltenAnzahl );
+	++spaltenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addSpalte( Text *name )
+{
+	lockZeichnung();
+	zZeichnungs->add( new Array< Zeichnung* >(), spaltenAnzahl );
+	spaltenNamen->add( name, spaltenAnzahl );
+	spaltenBreite->add( 100 );
+	msaRam->add( new RCArray< LRahmen >(), spaltenAnzahl );
+	msaAf->add( new RCArray< AlphaFeld >(), spaltenAnzahl );
+	++spaltenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addSpalte( int sNum, const char *name ) // Spalte bei sNum einfügen
+{
+	if( sNum > spaltenAnzahl )
+		return;
+	lockZeichnung();
+	zZeichnungs->add( new Array< Zeichnung* >(), sNum );
+	spaltenNamen->add( new Text( name ), sNum );
+	spaltenBreite->add( 100, sNum );
+	minSpaltenBreite->add( 0, sNum );
+	maxSpaltenBreite->add( 300, sNum );
+	msaRam->add( new RCArray< LRahmen >(), sNum );
+	msaAf->add( new RCArray< AlphaFeld >(), sNum );
+	styles->add( new Array< __int64 >(), sNum );
+	++spaltenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addSpalte( int sNum, Text *name )
+{
+	if( sNum > spaltenAnzahl )
+		return;
+	lockZeichnung();
+	zZeichnungs->add( new Array< Zeichnung* >(), sNum );
+	spaltenNamen->add( name, sNum );
+	spaltenBreite->add( 100, sNum );
+	minSpaltenBreite->add( 0, sNum );
+	maxSpaltenBreite->add( 300, sNum );
+	msaRam->add( new RCArray< LRahmen >(), sNum );
+	msaAf->add( new RCArray< AlphaFeld >(), sNum );
+	styles->add( new Array< __int64 >(), sNum );
+	++spaltenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addZeile( const char *name ) // Zeile Hinzufügen
+{
+	lockZeichnung();
+	zeilenNamen->add( new Text( name ), zeilenAnzahl );
+	zeilenHöhe->add( 20 );
+	++zeilenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addZeile( Text *name )
+{
+	lockZeichnung();
+	zeilenNamen->add( name, zeilenAnzahl );
+	zeilenHöhe->add( 20 );
+	++zeilenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addZeile( int zNum, const char *name ) // Zeile bei zNum einfügen
+{
+	if( zNum > zeilenAnzahl )
+		return;
+	lockZeichnung();
+	zeilenNamen->add( new Text( name ), zNum );
+	zeilenHöhe->add( 20, zNum );
+	minZeilenHöhe->add( 0, zNum );
+	maxZeilenHöhe->add( 100, zNum );
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		if( zZeichnungs->z( i ) )
+			zZeichnungs->z( i )->add( 0, zNum );
+		if( msaRam->z( i ) )
+			msaRam->z( i )->add( 0, zNum );
+		if( msaAf->z( i ) )
+			msaAf->z( i )->add( 0, zNum );
+		if( styles->z( i ) )
+			styles->z( i )->add( 0, zNum );
+	}
+	++zeilenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::addZeile( int zNum, Text *name )
+{
+	if( zNum > zeilenAnzahl )
+		return;
+	lockZeichnung();
+	zeilenNamen->add( name, zNum );
+	zeilenHöhe->add( 20, zNum );
+	minZeilenHöhe->add( 0, zNum );
+	maxZeilenHöhe->add( 100, zNum );
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		if( zZeichnungs->z( i ) )
+			zZeichnungs->z( i )->add( 0, zNum );
+		if( msaRam->z( i ) )
+			msaRam->z( i )->add( 0, zNum );
+		if( msaAf->z( i ) )
+			msaAf->z( i )->add( 0, zNum );
+		if( styles->z( i ) )
+			styles->z( i )->add( 0, zNum );
+	}
+	++zeilenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::removeSpalte( int sNum ) // Spalte löschen
+{
+	if( sNum >= spaltenAnzahl )
+		return;
+	lockZeichnung();
+	zZeichnungs->lösche( sNum );
+	spaltenNamen->lösche( sNum );
+	spaltenBreite->lösche( sNum );
+	minSpaltenBreite->lösche( sNum );
+	maxSpaltenBreite->lösche( sNum );
+	if( msaRam->z( sNum ) )
+		msaRam->z( sNum )->release();
+	msaRam->lösche( sNum );
+	if( msaAf->z( sNum ) )
+		msaAf->z( sNum )->release();
+	msaAf->lösche( sNum );
+	styles->lösche( sNum );
+	--spaltenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::removeSpalte( const char *name )
+{
+	removeSpalte( getSpaltenNummer( name ) );
+}
+
+void ObjTabelle::removeSpalte( Text *name )
+{
+	removeSpalte( getSpaltenNummer( name ) );
+}
+
+void ObjTabelle::removeZeile( int zNum ) // Zeile löschen
+{
+	if( zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	zeilenNamen->lösche( zNum );
+	zeilenHöhe->lösche( zNum );
+	minZeilenHöhe->lösche( zNum );
+	maxZeilenHöhe->lösche( zNum );
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		if( zZeichnungs->z( i ) )
+			zZeichnungs->z( i )->lösche( zNum );
+		if( msaRam->z( i ) )
+			msaRam->z( i )->lösche( zNum );
+		if( msaAf->z( i ) )
+			msaAf->z( i )->lösche( zNum );
+		if( styles->z( i ) )
+			styles->z( i )->lösche( zNum );
+	}
+	--zeilenAnzahl;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::removeZeile( const char *name )
+{
+	removeZeile( getZeilenNummer( name ) );
+}
+
+void ObjTabelle::removeZeile( Text *name )
+{
+	removeZeile( getZeilenNummer( name ) );
+}
+
+void ObjTabelle::setSpaltePosition( const char *name, int pos ) // setzt die Position einer Spalte
+{
+	setSpaltePosition( getSpaltenNummer( name ), pos );
+}
+
+void ObjTabelle::setSpaltePosition( Text *name, int pos )
+{
+	setSpaltePosition( getSpaltenNummer( name ), pos );
+}
+
+void ObjTabelle::setSpaltePosition( int sNum, int pos )
+{
+	if( sNum >= spaltenAnzahl || pos >= spaltenAnzahl || sNum == pos )
+		return;
+	int löschPos = sNum;
+	int insertPos = pos;
+	if( pos < sNum )
+		++löschPos;
+	else
+		++insertPos;
+	lockZeichnung();
+	zZeichnungs->add( zZeichnungs->get( sNum ), insertPos );
+	zZeichnungs->lösche( löschPos );
+	spaltenNamen->add( spaltenNamen->get( sNum ), insertPos );
+	spaltenNamen->lösche( löschPos );
+	spaltenBreite->add( spaltenBreite->hat( sNum ) ? spaltenBreite->get( sNum ) : 0, insertPos );
+	spaltenBreite->lösche( löschPos );
+	minSpaltenBreite->add( minSpaltenBreite->hat( sNum ) ? minSpaltenBreite->get( sNum ) : 0, insertPos );
+	minSpaltenBreite->lösche( löschPos );
+	msaRam->add( msaRam->z( sNum ), insertPos );
+	msaRam->lösche( löschPos );
+	msaAf->add( msaAf->z( sNum ), insertPos );
+	msaAf->lösche( löschPos );
+	styles->add( styles->get( sNum ), insertPos );
+	styles->lösche( löschPos );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setZeilePosition( const char *name, int pos ) // setzt die Zeilen Position
+{
+	setZeilePosition( getZeilenNummer( name ), pos );
+}
+
+void ObjTabelle::setZeilePosition( Text *name, int pos )
+{
+	setZeilePosition( getZeilenNummer( name ), pos );
+}
+
+void ObjTabelle::setZeilePosition( int zNum, int pos )
+{
+	if( zNum >= zeilenAnzahl || pos >= zeilenAnzahl || pos == zNum )
+		return;
+	int löschPos = zNum;
+	int insertPos = pos;
+	if( pos < zNum )
+		++löschPos;
+	else
+		++insertPos;
+	lockZeichnung();
+	zeilenNamen->add( zeilenNamen->get( zNum ), insertPos );
+	zeilenNamen->lösche( löschPos );
+	zeilenHöhe->add( zeilenHöhe->hat( zNum ) ? zeilenHöhe->get( zNum ) : 0, insertPos );
+	zeilenHöhe->lösche( löschPos );
+	minZeilenHöhe->add( minZeilenHöhe->hat( zNum ) ? minZeilenHöhe->get( zNum ) : 0, insertPos );
+	minZeilenHöhe->lösche( löschPos );
+	maxZeilenHöhe->add( maxZeilenHöhe->hat( zNum ) ? maxZeilenHöhe->get( zNum ) : 0, insertPos );
+	maxZeilenHöhe->lösche( löschPos );
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		if( zZeichnungs->z( i ) )
+		{
+			zZeichnungs->z( i )->add( zZeichnungs->z( i )->hat( zNum ) ? zZeichnungs->z( i )->get( zNum ) : 0, insertPos );
+			zZeichnungs->z( i )->lösche( löschPos );
+		}
+		if( msaRam->z( i ) )
+		{
+			msaRam->z( i )->add( msaRam->z( i )->z( zNum ) ? msaRam->z( i )->get( zNum ) : 0, insertPos );
+			msaRam->z( i )->lösche( löschPos );
+		}
+		if( msaAf->z( i ) )
+		{
+			msaAf->z( i )->add( msaAf->z( i )->z( zNum ) ? msaAf->z( i )->get( zNum ) : 0, insertPos );
+			msaAf->z( i )->lösche( löschPos );
+		}
+		if( styles->z( i ) )
+		{
+			styles->z( i )->add( styles->z( i )->hat( zNum ) ? styles->z( i )->get( zNum ) : 0, insertPos );
+			styles->z( i )->lösche( löschPos );
+		}
+	}
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setZeichnungZ( int sNum, int zNum, Zeichnung *zObj ) // setzt ein Zeichnung
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	if( !zZeichnungs->z( sNum ) )
+		zZeichnungs->set( new Array< Zeichnung* >(), sNum );
+	zZeichnungs->z( sNum )->set( zObj, zNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setZeichnungZ( const char *spaltenName, const char *zeilenName, Zeichnung *zZeichnung )
+{
+	setZeichnungZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), zZeichnung );
+}
+
+void ObjTabelle::setZeichnungZ( Text *spaltenName, Text *zeilenName, Zeichnung *zZeichnung )
+{
+	setZeichnungZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), zZeichnung );
+}
+
+void ObjTabelle::setSpaltenBreite( int sNum, int br ) // setzt die Spaltenbreite
+{
+	if( sNum >= spaltenAnzahl )
+		return;
+	lockZeichnung();
+	spaltenBreite->set( br, sNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setSpaltenBreite( const char *name, int br )
+{
+	setSpaltenBreite( getSpaltenNummer( name ), br );
+}
+
+void ObjTabelle::setSpaltenBreite( Text *name, int br )
+{
+	setSpaltenBreite( getSpaltenNummer( name ), br );
+}
+
+void ObjTabelle::setZeilenHöhe( int zNum, int hö ) // setzt die Zeilenhöhe
+{
+	if( zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	zeilenHöhe->set( hö, zNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setZeilenHöhe( const char *name, int hö )
+{
+	setZeilenHöhe( getZeilenNummer( name ), hö );
+}
+
+void ObjTabelle::setZeilenHöhe( Text *name, int hö )
+{
+	setZeilenHöhe( getZeilenNummer( name ), hö );
+}
+
+void ObjTabelle::setMinSpaltenBreite( int sNum, int minBr ) // setzt die mindest Spaltenbreite
+{
+	if( sNum >= spaltenAnzahl )
+		return;
+	lockZeichnung();
+	minSpaltenBreite->set( minBr, sNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setMinSpaltenBreite( const char *name, int minBr )
+{
+	setMinSpaltenBreite( getSpaltenNummer( name ), minBr );
+}
+
+void ObjTabelle::setMinSpaltenBreite( Text *name, int minBr )
+{
+	setMinSpaltenBreite( getSpaltenNummer( name ), minBr );
+}
+
+void ObjTabelle::setMaxSpaltenBreite( int sNum, int maxBr ) // setzt die maximale Spaltenbreite
+{
+	if( sNum >= spaltenAnzahl )
+		return;
+	lockZeichnung();
+	maxSpaltenBreite->set( maxBr, sNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setMaxSpaltenBreite( const char *name, int maxBr )
+{
+	setMaxSpaltenBreite( getSpaltenNummer( name ), maxBr );
+}
+
+void ObjTabelle::setMaxSpaltenBreite( Text *name, int maxBr )
+{
+	setMaxSpaltenBreite( getSpaltenNummer( name ), maxBr );
+}
+
+void ObjTabelle::setMinZeilenHöhe( int zNum, int minHö ) // setzt die mindest Zeilenhöhe
+{
+	if( zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	minZeilenHöhe->set( minHö, zNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setMinZeilenHöhe( const char *name, int minHö )
+{
+	setMinZeilenHöhe( getZeilenNummer( name ), minHö );
+}
+
+void ObjTabelle::setMinZeilenHöhe( Text *name, int minHö )
+{
+	setMinZeilenHöhe( getZeilenNummer( name ), minHö );
+}
+
+void ObjTabelle::setMaxZeilenHöhe( int zNum, int maxHö ) // setzt die maximale Zeilenhöhe
+{
+	if( zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	maxZeilenHöhe->set( maxHö, zNum );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setMaxZeilenHöhe( const char *name, int maxHö )
+{
+	setMaxZeilenHöhe( getZeilenHöhe( name ), maxHö );
+}
+
+void ObjTabelle::setMaxZeilenHöhe( Text *name, int maxHö )
+{
+	setMaxZeilenHöhe( getZeilenHöhe( name ), maxHö );
+}
+
+void ObjTabelle::setAuswahl( int sNum, int zNum ) // wählt das entsprechnde Feld aus
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	lockZeichnung();
+	selected.x = sNum;
+	selected.y = zNum;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ObjTabelle::setAuswahl( const char *spaltenName, const char *zeilenName )
+{
+	setAuswahl( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+void ObjTabelle::setAuswahl( Text *spaltenName, Text *zeilenName )
+{
+	setAuswahl( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+void ObjTabelle::setRasterFarbe( int f ) // settzt die Farbe des Rasters
+{
+	rasterFarbe = f;
+	rend = 1;
+}
+
+void ObjTabelle::setRasterBreite( int br ) // setzt die Breite des Rasters
+{
+	rasterBreite = br;
+	rend = 1;
+}
+
+void ObjTabelle::setARahmenZ( LRahmen *ram ) // setzt den auswahl Rahmen
+{
+	if( aRam )
+		aRam->release();
+	aRam = ram;
+	rend = 1;
+}
+
+void ObjTabelle::setARFarbe( int f ) // setzt die auswahl Rahmen Farbe
+{
+	if( !aRam )
+		aRam = new LRahmen();
+	aRam->setFarbe( f );
+	rend = 1;
+}
+
+void ObjTabelle::setARBreite( int br ) // setzt die auswahl Rahmen Breite
+{
+	if( !aRam )
+		aRam = new LRahmen();
+	aRam->setRamenBreite( br );
+	rend = 1;
+}
+
+void ObjTabelle::setAAlphaFeldZ( AlphaFeld *af ) // setzt das auswahl AlphaFeld
+{
+	if( aAf )
+		aAf->release();
+	aAf = af;
+	rend = 1;
+}
+
+void ObjTabelle::setAAfFarbe( int f ) // setzt die Farbe des auswahl AlphaFeldes
+{
+	if( !aAf )
+		aAf = new AlphaFeld();
+	aAf->setFarbe( f );
+	rend = 1;
+}
+
+void ObjTabelle::setAAfStärke( int st ) // setzt die Stärke des auswahl AlphaFeldes
+{
+	if( !aAf )
+		aAf = new AlphaFeld();
+	aAf->setStärke( st );
+	rend = 1;
+}
+
+void ObjTabelle::setARahmenZ( int sNum, int zNum, LRahmen *ram ) // setzt den auswahl Rahmen
+{
+	if( msaRam->z( sNum ) )
+		msaRam->z( sNum )->set( ram, zNum );
+	rend = 1;
+}
+
+void ObjTabelle::setARahmenZ( const char *spaltenName, const char *zeilenName, LRahmen *ram )
+{
+	setARahmenZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), ram );
+}
+
+void ObjTabelle::setARahmenZ( Text *spaltenName, Text *zeilenName, LRahmen *ram )
+{
+	setARahmenZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), ram );
+}
+
+void ObjTabelle::setARFarbe( int sNum, int zNum, int f ) // setzt die auswahl Rahmen Farbe
+{
+	if( msaRam->z( sNum ) )
+	{
+		LRahmen *tmp = msaRam->z( sNum )->z( zNum );
+		if( !tmp )
+		{
+			tmp = new LRahmen();
+			msaRam->z( sNum )->set( tmp, zNum );
+		}
+		tmp->setFarbe( f );
+		rend = 1;
+	}
+}
+
+void ObjTabelle::setARFarbe( const char *spaltenName, const char *zeilenName, int f )
+{
+	setARFarbe( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), f );
+}
+
+void ObjTabelle::setARFarbe( Text *spaltenName, Text *zeilenName, int f )
+{
+	setARFarbe( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), f );
+}
+
+void ObjTabelle::setARBreite( int sNum, int zNum, int br ) // setzt die auswahl Rahmen Breite
+{
+	if( msaRam->z( sNum ) )
+	{
+		LRahmen *tmp = msaRam->z( sNum )->z( zNum );
+		if( !tmp )
+		{
+			tmp = new LRahmen();
+			msaRam->z( sNum )->set( tmp, zNum );
+		}
+		tmp->setRamenBreite( br );
+		rend = 1;
+	}
+}
+
+void ObjTabelle::setARBreite( const char *spaltenName, const char *zeilenName, int br )
+{
+	setARBreite( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), br );
+}
+
+void ObjTabelle::setARBreite( Text *spaltenName, Text *zeilenName, int br )
+{
+	setARBreite( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), br );
+}
+
+void ObjTabelle::setAAlphaFeldZ( int sNum, int zNum, AlphaFeld *af ) // setzt das auswahl AlphaFeld
+{
+	if( msaAf->z( sNum ) )
+		msaAf->z( sNum )->set( af, zNum );
+	rend = 1;
+}
+
+void ObjTabelle::setAAlphaFeldZ( const char *spaltenName, const char *zeilenName, AlphaFeld *af )
+{
+	setAAlphaFeldZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), af );
+}
+
+void ObjTabelle::setAAlphaFeldZ( Text *spaltenName, Text *zeilenName, AlphaFeld *af )
+{
+	setAAlphaFeldZ( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), af );
+}
+
+void ObjTabelle::setAAfFarbe( int sNum, int zNum, int f ) // setzt die Farbe des auswahl AlphaFeldes
+{
+	if( msaAf->z( sNum ) )
+	{
+		AlphaFeld *tmp = msaAf->z( sNum )->z( zNum );
+		if( !tmp )
+		{
+			tmp = new AlphaFeld();
+			msaAf->z( sNum )->set( tmp, zNum );
+		}
+		tmp->setFarbe( f );
+		rend = 1;
+	}
+}
+
+void ObjTabelle::setAAfFarbe( const char *spaltenName, const char *zeilenName, int f )
+{
+	setAAfFarbe( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), f );
+}
+
+void ObjTabelle::setAAfFarbe( Text *spaltenName, Text *zeilenName, int f )
+{
+	setAAfFarbe( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), f );
+}
+
+void ObjTabelle::setAAfStärke( int sNum, int zNum, int st ) // setzt die Stärke des auswahl AlphaFeldes
+{
+	if( msaAf->z( sNum ) )
+	{
+		AlphaFeld *tmp = msaAf->z( sNum )->z( zNum );
+		if( !tmp )
+		{
+			tmp = new AlphaFeld();
+			msaAf->z( sNum )->set( tmp, zNum );
+		}
+		tmp->setStärke( st );
+		rend = 1;
+	}
+}
+
+void ObjTabelle::setAAfStärke( const char *spaltenName, const char *zeilenName, int st )
+{
+	setAAfStärke( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), st );
+}
+
+void ObjTabelle::setAAfStärke( Text *spaltenName, Text *zeilenName, int st )
+{
+	setAAfStärke( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), st );
+}
+
+void ObjTabelle::addMsStyle( int sNum, int zNum, __int64 style ) // setzt den Style wenn Multistyled
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	if( styles->z( sNum ) )
+		styles->z( sNum )->set( ( styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0 ) | style, zNum );
+	rend = 1;
+}
+
+void ObjTabelle::addMsStyle( const char *spaltenName, const char *zeilenName, __int64 style )
+{
+	addMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+void ObjTabelle::addMsStyle( Text *spaltenName, Text *zeilenName, __int64 style )
+{
+	addMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+void ObjTabelle::setMsStyle( int sNum, int zNum, __int64 style )
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	if( styles->z( sNum ) )
+		styles->z( sNum )->set( style, zNum );
+	rend = 1;
+}
+
+void ObjTabelle::setMsStyle( const char *spaltenName, const char *zeilenName, __int64 style )
+{
+	setMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+void ObjTabelle::setMsStyle( Text *spaltenName, Text *zeilenName, __int64 style )
+{
+	setMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+void ObjTabelle::setMsStyle( int sNum, int zNum, __int64 style, bool add_remove )
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	if( styles->z( sNum ) )
+	{
+		if( add_remove )
+			styles->z( sNum )->set( ( styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0 ) | style, zNum );
+		else
+			styles->z( sNum )->set( ( styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0 ) & ( ~style ), zNum );
+		rend = 1;
+	}
+}
+
+void ObjTabelle::setMsStyle( const char *spaltenName, const char *zeilenName, __int64 style, bool add_remove )
+{
+	setMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style, add_remove );
+}
+
+void ObjTabelle::setMsStyle( Text *spaltenName, Text *zeilenName, __int64 style, bool add_remove )
+{
+	setMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style, add_remove );
+}
+
+void ObjTabelle::löscheMsStyle( int sNum, int zNum, __int64 style )
+{
+	if( sNum >= spaltenAnzahl || zNum >= zeilenAnzahl )
+		return;
+	if( styles->z( sNum ) )
+		styles->z( sNum )->set( ( styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0 ) & ( ~style ), zNum );
+	rend = 1;
+}
+
+void ObjTabelle::löscheMsStyle( const char *spaltenName, const char *zeilenName, __int64 style )
+{
+	löscheMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+void ObjTabelle::löscheMsStyle( Text *spaltenName, Text *zeilenName, __int64 style )
+{
+	löscheMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+bool ObjTabelle::tick( double tickVal ) // tick Message
+{
+	lockZeichnung();
+	for( int i = 0; i < zeilenAnzahl; ++i )
+	{
+		for( int j = 0; j < spaltenAnzahl; ++j )
+		{
+			Zeichnung *obj = zZeichnung( j, i );
+			if( obj )
+				rend |= obj->tick( tickVal );
+		}
+	}
+    unlockZeichnung();
+	return __super::tick( tickVal );
+}
+
+void ObjTabelle::doMausEreignis( MausEreignis &me ) // verarbeitet Nachrichten
+{
+    bool nmakc = !me.verarbeitet;
+	if( hatStyleNicht( Style::Sichtbar ) || hatStyleNicht( Style::Erlaubt ) )
+		return;
+	bool removeFokus = 0;
+	if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+	{
+		if( mausIn )
+		{
+			mausIn = 0;
+			MausEreignis me2;
+			me2.id = ME_Verlässt;
+			me2.mx = me.mx;
+			me2.my = me.my;
+			me2.verarbeitet = 0;
+			doMausEreignis( me2 );
+			return;
+		}
+		removeFokus = 1;
+	}
+	bool außerhalb = !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt;
+	bool MakB = Mak && ( me.verarbeitet || außerhalb || Mak( makParam, this, me ) );
+	if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+	{
+		if( removeFokus && me.id == ME_RLinks )
+		{
+			if( MakB )
+				löscheStyle( Style::Fokus );
+		}
+	}
+	else if( !mausIn && me.id != ME_Verlässt )
+	{
+		mausIn = 1;
+		MausEreignis me2;
+		me2.id = ME_Betritt;
+		me2.mx = me.mx;
+		me2.my = me.my;
+		me2.verarbeitet = 0;
+		doMausEreignis( me2 );
+	}
+	int tmx = me.mx;
+	int tmy = me.my;
+	bool aufScroll = 0;
+	if( !außerhalb && vertikalScrollBar && hatStyle( Style::VScroll ) && me.mx > pos.x + gr.x - 15 )
+		aufScroll = 1;
+	if( !außerhalb && horizontalScrollBar && hatStyle( Style::HScroll ) && me.my > pos.y + gr.y - 15 )
+		aufScroll = 1;
+	me.mx -= pos.x + ( ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScrollData()->anzeigeBeginn : 0 );
+	me.my -= pos.y + ( ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScrollData()->anzeigeBeginn : 0 );
+	if( MakB )
+	{
+		lockZeichnung();
+		if( removeFokus && me.id == ME_RLinks )
+		{
+			löscheStyle( Style::Fokus );
+			klickSpalte = -1;
+		}
+		if( !me.verarbeitet && !außerhalb && !aufScroll )
+		{
+			double ox = getMausSpalte( me.mx + ( ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0 ) );
+			double oy = getMausZeile( me.my + ( ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScroll() : 0 ) );
+			if( me.id == ME_RLinks )
+			{
+				addStyle( Style::Fokus );
+				klickSpalte = -1;
+				mSpalte = -1, mZeile = -1;
+			}
+			if( ( hatStyle( Style::SpaltenBreiteÄnderbar ) || hatStyle( Style::ZeilenHöheÄnderbar ) ) && klickSpalte < 0 )
+			{
+				if( hatStyle( Style::SpaltenBreiteÄnderbar ) )
+				{
+					if( me.id == ME_PLinks && ox != (int)ox )
+					{
+						mSpalte = ox;
+						mx = me.mx;
+						rend = 1;
+					}
+					if( mSpalte > -1 )
+					{
+						int br = getSpaltenBreite( (int)mSpalte ) + ( me.mx - mx );
+						if( hatStyle( Style::SpaltenBreiteMax ) && br > getMaxSpaltenBreite( (int)mSpalte ) )
+							br = getMaxSpaltenBreite( (int)mSpalte );
+						if( hatStyle( Style::SpaltenBreiteMin ) && br < getMinSpaltenBreite( (int)mSpalte ) )
+							br = getMinSpaltenBreite( (int)mSpalte );
+						setSpaltenBreite( (int)mSpalte, br );
+						mx = me.mx;
+						rend = 1;
+					}
+				}
+				if( hatStyle( Style::ZeilenHöheÄnderbar ) )
+				{
+					if( me.id == ME_PLinks && oy != (int)oy )
+					{
+						mZeile = oy;
+						my = me.my;
+						rend = 1;
+					}
+					if( mZeile > -1 )
+					{
+						int hö = getZeilenHöhe( (int)mZeile ) + ( me.my - my );
+						if( hatStyle( Style::ZeilenHöheMax ) && hö > getMaxZeilenHöhe( (int)mZeile ) )
+							hö = getMaxZeilenHöhe( (int)mZeile );
+						if( hatStyle( Style::ZeilenHöheMin ) && hö < getMinZeilenHöhe( (int)mZeile ) )
+							hö = getMinZeilenHöhe( (int)mZeile );
+						setZeilenHöhe( (int)mZeile, hö );
+						my = me.my;
+						rend = 1;
+					}
+				}
+			}
+			if( hatStyle( Style::SpaltenBeweglich ) && ox == (int)ox && mSpalte == -1 && mZeile == -1 )
+			{
+				if( klickSpalte >= 0 && klickSpalte < spaltenAnzahl && klickSpalte != ox && !oy && ox >= 0 )
+				{
+					setSpaltePosition( klickSpalte, (int)ox );
+					klickSpalte = (int)ox;
+					rend = 1;
+				}
+				if( me.id == ME_PLinks )
+				{
+					if( !oy && klickSpalte < 0 )
+					{
+						klickSpalte = (int)ox;
+						rend = 1;
+					}
+				}
+			}
+		}
+        me.mx += ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0;
+        me.my += ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScroll() : 0;
+		if( me.id != ME_Betritt && me.id != ME_Verlässt )
+		{
+			if( !außerhalb )
+			{
+				bool vs = hatStyle( Style::VScroll ) && vertikalScrollBar;
+				bool hs = hatStyle( Style::HScroll ) && horizontalScrollBar;
+				int rbr = rahmen ? rahmen->getRBreite() : 0;
+				if( vs )
+				{
+					if( hs )
+						horizontalScrollBar->doMausMessage( rbr, gr.y - 15 - rbr, gr.x - 15 - rbr * 2, 15, me );
+					vertikalScrollBar->doMausMessage( gr.x - 15 - rbr, rbr, 15, gr.y - rbr * 2, me );
+				}
+				else if( hs )
+					horizontalScrollBar->doMausMessage( rbr, gr.y - 15 - rbr, gr.x - rbr * 2, 15, me );
+			}
+			unlockZeichnung();
+			if( aufScroll )
+				me.verarbeitet = 1;
+			for( int i = 0; i < zeilenAnzahl; ++i )
+			{
+				for( int j = 0; j < spaltenAnzahl; ++j )
+				{
+					bool b = me.verarbeitet;
+					Zeichnung *obj = zZeichnung( j, i );
+					if( obj )
+						obj->doMausEreignis( me );
+					if( !b && me.verarbeitet && me.id == ME_PLinks )
+						selected = Punkt( j, i );
+				}
+			}
+		}
+		else
+			unlockZeichnung();
+		if( me.mx >= 0 && me.mx <= gr.x && me.my >= 0 && me.my <= gr.y )
+			me.verarbeitet = 1;
+	}
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+	me.mx = tmx;
+	me.my = tmy;
+}
+
+void ObjTabelle::doTastaturEreignis( TastaturEreignis &te )
+{
+    bool ntakc = !te.verarbeitet;
+	if( hatStyleNicht( Style::Fokus ) || hatStyleNicht( Style::Erlaubt ) || hatStyleNicht( Style::Sichtbar ) )
+		return;
+	if( Tak && ( te.verarbeitet || Tak( takParam, this, te ) ) )
+	{
+		lockZeichnung();
+		if( zZeichnung( selected.x, selected.y ) )
+		{
+			zZeichnung( selected.x, selected.y )->doTastaturEreignis( te );
+			if( !te.verarbeitet && te.id == TE_Press )
+			{
+				if( te.taste == T_Oben )
+				{
+					--( selected.y );
+					rend = 1;
+				}
+				if( te.taste == T_Unten )
+				{
+					++( selected.y );
+					rend = 1;
+				}
+				if( te.taste == T_Links )
+				{
+					--( selected.x );
+					rend = 1;
+				}
+				if( te.taste == T_Rechts )
+				{
+					++( selected.x );
+					rend = 1;
+				}
+			}
+		}
+		unlockZeichnung();
+	}
+	te.verarbeitet = 1;
+    if( ntakc && te.verarbeitet && nTak )
+        te.verarbeitet = nTak( ntakParam, this, te );
+}
+
+void ObjTabelle::render( Bild &zRObj ) // zeichnet nach zRObj
+{
+	if( hatStyleNicht( Style::Sichtbar ) )
+		return;
+    __super::render( zRObj );
+    lockZeichnung();
+	if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+	{
+		unlockZeichnung();
+		return;
+	}
+	int xPos = 0;
+	if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+		xPos -= horizontalScrollBar->getScrollData()->anzeigeBeginn;
+	for( int s = 0; s < spaltenAnzahl; ++s )
+	{
+		int sBr = spaltenBreite->hat( s ) ? spaltenBreite->get( s ) : 0;
+		int yPos = 0;
+		if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+			yPos -= vertikalScrollBar->getScrollData()->anzeigeBeginn;
+		Array< Zeichnung* > *tmp_zZeichnungs = zZeichnungs->z( s );
+		if( !tmp_zZeichnungs )
+			continue;
+		for( int z = 0; z < zeilenAnzahl && tmp_zZeichnungs; ++z )
+		{
+			int zHö = zeilenHöhe->hat( z ) ? zeilenHöhe->get( z ) : 0;
+			Zeichnung *obj = tmp_zZeichnungs->hat( z ) ? tmp_zZeichnungs->get( z ) : 0;
+			if( obj )
+			{
+				obj->setPosition( xPos, yPos );
+				obj->setGröße( sBr, zHö );
+				obj->render( zRObj );
+				if( selected.x == s && selected.y == z )
+				{
+					LRahmen *tmp_aRam = aRam;
+					AlphaFeld *tmp_aAf = aAf;
+					bool aRamB = hatStyle( Style::AuswahlRahmen ) && tmp_aRam;
+					bool aAfB = hatStyle( Style::AuswahlBuffer ) && tmp_aAf;
+					if( hatStyle( Style::AuswahlMultistyled ) )
+					{
+						tmp_aRam = getARahmen( s, z );
+						tmp_aAf = getAAlphaFeld( s, z );
+						aRamB = hatMsStyle( s, z, Style::AuswahlRahmen ) && tmp_aRam;
+						aAfB = hatMsStyle( s, z, Style::AuswahlBuffer ) && tmp_aAf;
+					}
+					int aRbr = 0;
+					if( aRamB )
+					{
+						tmp_aRam->setPosition( xPos, yPos );
+						tmp_aRam->setGröße( sBr, zHö );
+						tmp_aRam->render( zRObj );
+						aRbr = tmp_aRam->getRBreite();
+					}
+					if( aAfB )
+					{
+						tmp_aAf->setPosition( aRbr + xPos, aRbr + yPos );
+						tmp_aAf->setGröße( sBr - aRbr * 2, zHö - aRbr * 2 );
+						tmp_aAf->render( zRObj );
+					}
+				}
+			}
+			if( hatStyle( Style::Raster ) )
+			{
+				zRObj.drawLinieH( xPos, yPos + zHö, sBr, rasterFarbe );
+				yPos += rasterBreite;
+			}
+			yPos += zHö;
+			if( z == zeilenAnzahl - 1 && vertikalScrollBar && hatStyle( Style::VScroll ) )
+				vertikalScrollBar->getScrollData()->maxHöhe = yPos + vertikalScrollBar->getScrollData()->anzeigeBeginn;
+		}
+		if( hatStyle( Style::Raster ) )
+		{
+			zRObj.drawLinieV( xPos + sBr, 0, innenGröße.y, rasterFarbe );
+			xPos += rasterBreite;
+		}
+		xPos += sBr;
+	}
+	if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+        horizontalScrollBar->getScrollData()->maxBreite = xPos + horizontalScrollBar->getScrollData()->anzeigeBeginn;
+	zRObj.releaseDrawOptions();
+	unlockZeichnung();
+}
+
+// constant 
+int ObjTabelle::getSpaltenAnzahl() const // gibt die Anzahl der Spalten zurück
+{
+	return spaltenAnzahl;
+}
+
+int ObjTabelle::getZeilenAnzahl() const // gibt die Anzahl der Zeilen zurück
+{
+	return zeilenAnzahl;
+}
+
+int ObjTabelle::getSpaltenNummer( const char *name ) const // gibt die Nummer der Spalte mit dem Namen name zurück
+{
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		if( spaltenNamen->z( i )->istGleich( name ) )
+			return i;
+	}
+	return -1;
+}
+
+int ObjTabelle::getSpaltenNummer( Text *name ) const
+{
+	int ret = getSpaltenNummer( name->getText() );
+	name->release();
+	return ret;
+}
+
+Text *ObjTabelle::getSpaltenName( int num ) const // gibt den Namen der Spalte mit Nummer num zurück
+{
+	return spaltenNamen->get( num );
+}
+
+Text *ObjTabelle::zSpaltenName( int num ) const
+{
+	return spaltenNamen->z( num );
+}
+
+int ObjTabelle::getZeilenNummer( const char *name ) const // gibt die Nummer der Zeile mit dem Namen name zurück
+{
+	for( int i = 0; i < zeilenAnzahl; ++i )
+	{
+		if( zeilenNamen->z( i )->istGleich( name ) )
+			return i;
+	}
+	return -1;
+}
+
+int ObjTabelle::getZeilenNummer( Text *name ) const
+{
+	int ret = getZeilenNummer( name->getText() );
+	name->release();
+	return ret;
+}
+
+Text *ObjTabelle::getZeilenName( int num ) const // gibt den Namen der Zeile mit Nummer num zurück
+{
+	return zeilenNamen->get( num );
+}
+
+Text *ObjTabelle::zZeilenName( int num ) const
+{
+	return zeilenNamen->z( num );
+}
+
+Punkt ObjTabelle::getZeichnungPosition( Zeichnung *zObj ) const // gibt die Position eines Zeichnungs zurück
+{
+	for( int x = 0; x < spaltenAnzahl; ++x )
+	{
+		for( int y = 0; y < zeilenAnzahl; ++y )
+		{
+			if( zZeichnung( x, y ) == zObj )
+				return Punkt( x, y  );
+		}
+	}
+	return Punkt( -1, -1 );
+}
+
+Zeichnung *ObjTabelle::zZeichnung( int sNum, int zNum ) const // gibt das Zeichnung auf der Position zurück
+{
+	if( !zZeichnungs->z( sNum ) )
+		return 0;
+	Array< Zeichnung* > *tmp = zZeichnungs->z( sNum );
+	if( !tmp->hat( zNum ) )
+		return 0;
+	return tmp ? tmp->get( zNum ) : 0;
+}
+
+Zeichnung *ObjTabelle::zZeichnung( const char *spaltenName, const char *zeilenName ) const
+{
+	return zZeichnung( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+Zeichnung *ObjTabelle::zZeichnung( Text *spaltenName, Text *zeilenName ) const
+{
+	return zZeichnung( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+int ObjTabelle::getSpaltenBreite( int num ) const // gibt die Breite der Spalte zurück
+{
+	return spaltenBreite->get( num );
+}
+
+int ObjTabelle::getSpaltenBreite( const char *name ) const
+{
+	return getSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getSpaltenBreite( Text *name ) const
+{
+	return getSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getZeilenHöhe( int num ) const // gibt die Höhe der Zeile zurück
+{
+	return zeilenHöhe->get( num );
+}
+
+int ObjTabelle::getZeilenHöhe( const char *name ) const
+{
+	return getZeilenHöhe( getZeilenNummer( name ) );
+}
+
+int ObjTabelle::getZeilenHöhe( Text *name ) const
+{
+	return getZeilenHöhe( getZeilenNummer( name ) );
+}
+
+int ObjTabelle::getMinSpaltenBreite( int num ) const // gibt die minimale Spaltengröße zurück
+{
+	return minSpaltenBreite->get( num );
+}
+
+int ObjTabelle::getMinSpaltenBreite( const char *name ) const
+{
+	return getMinSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getMinSpaltenBreite( Text *name ) const
+{
+	return getMinSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getMaxSpaltenBreite( int num ) const // gibt die maximale Spaltengröße zurück
+{
+	return maxSpaltenBreite->get( num );
+}
+
+int ObjTabelle::getMaxSpaltenBreite( const char *name ) const
+{
+	return getMaxSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getMaxSpaltenBreite( Text *name ) const
+{
+	return getMaxSpaltenBreite( getSpaltenNummer( name ) );
+}
+
+int ObjTabelle::getMinZeilenHöhe( int num ) const // gibt die minimale Zeilenhöhe zurück
+{
+	return minZeilenHöhe->get( num );
+}
+
+int ObjTabelle::getMinZeilenHöhe( const char *name ) const
+{
+	return getMinZeilenHöhe( getZeilenNummer( name ) );
+}
+
+int ObjTabelle::getMinZeilenHöhe( Text *name ) const
+{
+	return getMinZeilenHöhe( getZeilenNummer( name ) );
+}
+
+int ObjTabelle::getMaxZeilenHöhe( int num ) const // gibt die maximale Zeilenhöhe zurück
+{
+	return maxZeilenHöhe->get( num );
+}
+
+int ObjTabelle::getMaxZeilenHöhe( const char *name ) const
+{
+	return getMaxZeilenHöhe( getZeilenNummer( name ) );
+}
+
+int ObjTabelle::getMaxZeilenHöhe( Text *name ) const
+{
+	return getMaxZeilenHöhe( getZeilenNummer( name ) );
+}
+
+double ObjTabelle::getMausSpalte( int mx ) const // ermittelt die Spalte unter der Maus
+{
+	if( mx >= gr.x )
+		return -1;
+	int hsBeg = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0;
+	mx += hsBeg;
+	if( mx < 0 )
+		return -1;
+	int xx = rahmen ? rahmen->getRBreite() : 0;
+	for( int i = 0; i < spaltenAnzahl; ++i )
+	{
+		xx += spaltenBreite->get( i );
+		if( mx < xx - 5 )
+			return i;
+		if( mx < xx + 5 )
+			return i + 0.5;
+		xx += rasterBreite;
+	}
+	return -1;
+}
+
+Text *ObjTabelle::getMausSpaltenName( int mx ) const
+{
+	double tmp = getMausSpalte( mx );
+	if( tmp != (int)tmp )
+		return 0;
+	return getSpaltenName( (int)tmp );
+}
+
+Text *ObjTabelle::zMausSpaltenName( int mx ) const
+{
+	double tmp = getMausSpalte( mx );
+	if( tmp != (int)tmp )
+		return 0;
+	return zSpaltenName( (int)tmp );
+}
+
+double ObjTabelle::getMausZeile( int my ) const // ermittelt die Zeile unter der Maus
+{
+	if( my >= gr.y )
+		return -1;
+	if( my < 0 )
+		return -1;
+    int vsBeg = vertikalScrollBar && hatStyle( Style::VScroll ) ? vertikalScrollBar->getScroll() : 0;
+    my += vsBeg;
+	int yy = rahmen ? rahmen->getRBreite() : 0;
+	for( int i = 0; i < zeilenAnzahl; ++i )
+	{
+		yy += zeilenHöhe->get( i );
+		if( my < yy - 5 )
+			return i;
+		if( my < yy + 5 )
+			return i + 0.5;
+		yy += rasterBreite;
+	}
+	return -1;
+}
+
+Text *ObjTabelle::getMausZeilenName( int my ) const
+{
+	double tmp = getMausZeile( my );
+	if( tmp != (int)tmp )
+		return 0;
+	return getZeilenName( (int)tmp );
+}
+
+Text *ObjTabelle::zMausZeilenName( int my ) const
+{
+	double tmp = getMausZeile( my );
+	if( tmp != (int)tmp )
+		return 0;
+	return zZeilenName( (int)tmp );
+}
+
+const Punkt &ObjTabelle::getAuswahlPosition() const // gibt die Auswahl Position zurück
+{
+	return selected;
+}
+
+int ObjTabelle::getRasterFarbe() const // gibt die Farbe des Rasters zurück
+{
+	return rasterFarbe;
+}
+
+int ObjTabelle::getRasterBreite() const // gibt die Breite des Rasters zurück
+{
+	return rasterBreite;
+}
+
+LRahmen *ObjTabelle::getARahmen() const // gibt den auswahl Rahmen zurück
+{
+	return aRam ? aRam->getThis() : 0;
+}
+
+LRahmen *ObjTabelle::zARahmen() const
+{
+	return aRam;
+}
+
+AlphaFeld *ObjTabelle::getAAlphaFeld() const // gibt das auswahl AlphaFeld zurück
+{
+	return aAf ? aAf->getThis() : 0;
+}
+
+AlphaFeld *ObjTabelle::zAAlphaFeld() const
+{
+	return aAf;
+}
+
+LRahmen *ObjTabelle::getARahmen( int sNum, int zNum ) const // gibt den auswahl Rahmen zurück
+{
+	RCArray< LRahmen > *tmp = msaRam->z( sNum );
+	return tmp ? tmp->get( zNum ) : 0;
+}
+
+LRahmen *ObjTabelle::zARahmen( int sNum, int zNum ) const
+{
+	RCArray< LRahmen > *tmp = msaRam->z( sNum );
+	return tmp ? tmp->z( zNum ) : 0;
+}
+
+AlphaFeld *ObjTabelle::getAAlphaFeld( int sNum, int zNum ) const // gibt das auswahl AlphaFeld zurück
+{
+	RCArray< AlphaFeld > *tmp = msaAf->z( sNum );
+	return tmp ? tmp->get( zNum ) : 0;
+}
+
+AlphaFeld *ObjTabelle::zAAlphaFeld( int sNum, int zNum ) const
+{
+	return msaAf->z( sNum ) ? msaAf->z( sNum )->z( zNum ) : 0;
+}
+
+LRahmen *ObjTabelle::getARahmen( const char *spaltenName, const char *zeilenName ) const // gibt den auswahl Rahmen zurück
+{
+	return getARahmen( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+LRahmen *ObjTabelle::zARahmen( const char *spaltenName, const char *zeilenName ) const
+{
+	return zARahmen( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+AlphaFeld *ObjTabelle::getAAlphaFeld( const char *spaltenName, const char *zeilenName ) const // gibt das auswahl AlphaFeld zurück
+{
+	return getAAlphaFeld( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+AlphaFeld *ObjTabelle::zAAlphaFeld( const char *spaltenName, const char *zeilenName ) const
+{
+	return zAAlphaFeld( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+LRahmen *ObjTabelle::getARahmen( Text *spaltenName, Text *zeilenName ) const // gibt den auswahl Rahmen zurück
+{
+	return getARahmen( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+LRahmen *ObjTabelle::zARahmen( Text *spaltenName, Text *zeilenName ) const
+{
+	return zARahmen( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+AlphaFeld *ObjTabelle::getAAlphaFeld( Text *spaltenName, Text *zeilenName ) const // gibt das auswahl AlphaFeld zurück
+{
+	return getAAlphaFeld( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+AlphaFeld *ObjTabelle::zAAlphaFeld( Text *spaltenName, Text *zeilenName ) const
+{
+	return zAAlphaFeld( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ) );
+}
+
+bool ObjTabelle::hatMsStyle( int sNum, int zNum, __int64 style ) const // prüft, ob style vorhanden ist
+{
+	__int64 s = styles->z( sNum ) && styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0;
+	return ( s | style ) == s;
+}
+
+bool ObjTabelle::hatMsStyleNicht( int sNum, int zNum, __int64 style ) const // prüft, ob style nicht vorhanden ist
+{
+    __int64 s = styles->z( sNum ) && styles->z( sNum )->hat( zNum ) ? styles->z( sNum )->get( zNum ) : 0;
+	return ( s | style ) != s;
+}
+
+bool ObjTabelle::hatMsStyle( const char *spaltenName, const char *zeilenName, __int64 style ) const // prüft, ob style vorhanden ist
+{
+	return hatMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+bool ObjTabelle::hatMsStyleNicht( const char *spaltenName, const char *zeilenName, __int64 style ) const // prüft, ob style nicht vorhanden ist
+{
+	return hatMsStyleNicht( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+bool ObjTabelle::hatMsStyle( Text *spaltenName, Text *zeilenName, __int64 style ) const // prüft, ob style vorhanden ist
+{
+	return hatMsStyle( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+bool ObjTabelle::hatMsStyleNicht( Text *spaltenName, Text *zeilenName, __int64 style ) const // prüft, ob style nicht vorhanden ist
+{
+	return hatMsStyleNicht( getSpaltenNummer( spaltenName ), getZeilenNummer( zeilenName ), style );
+}
+
+Zeichnung *ObjTabelle::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+	ObjTabelle *obj = new ObjTabelle();
+	obj->setPosition( pos );
+	obj->setGröße( gr );
+	obj->setMausEreignisParameter( makParam );
+	obj->setTastaturEreignisParameter( takParam );
+	obj->setMausEreignis( Mak );
+	obj->setTastaturEreignis( Tak );
+	if( toolTip )
+		obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+	obj->setStyle( style );
+	if( rahmen )
+		obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+	obj->setHintergrundFarbe( hintergrundFarbe );
+	if( hintergrundBild )
+		obj->setHintergrundBild( hintergrundBild->getThis() );
+	if( hintergrundFeld )
+		obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+	obj->setRasterFarbe( rasterFarbe );
+	obj->setRasterBreite( rasterBreite );
+	if( aRam )
+		obj->setARahmenZ( (LRahmen*)aRam->dublizieren() );
+	if( aAf )
+		obj->setAAlphaFeldZ( (AlphaFeld*)aAf->dublizieren() );
+	for( int s = 0; s < spaltenAnzahl; ++s )
+	{
+		obj->addSpalte( spaltenNamen->get( s ) );
+		if( spaltenBreite->hat( s ) )
+			obj->setSpaltenBreite( s, spaltenBreite->get( s ) );
+		if( minSpaltenBreite->hat( s ) )
+			obj->setMinSpaltenBreite( s, minSpaltenBreite->get( s ) );
+		if( maxSpaltenBreite->hat( s ) )
+			obj->setMaxSpaltenBreite( s, maxSpaltenBreite->get( s ) );
+		for( int z = 0; z < zeilenAnzahl; ++z )
+		{
+			if( !s )
+			{
+				obj->addZeile( zeilenNamen->get( z ) );
+				if( zeilenHöhe->hat( z ) )
+					obj->setZeilenHöhe( z, zeilenHöhe->get( z ) );
+				if( minZeilenHöhe->hat( z ) )
+					obj->setMinZeilenHöhe( z, minZeilenHöhe->get( z ) );
+				if( maxZeilenHöhe->hat( z ) )
+					obj->setMaxZeilenHöhe( z, maxZeilenHöhe->get( z ) );
+			}
+			if( zZeichnungs->z( s ) && zZeichnungs->z( s )->hat( z ) )
+				obj->setZeichnungZ( s, z, zZeichnungs->z( s )->get( z ) );
+			if( styles->z( s ) && styles->z( s )->hat( z ) )
+				obj->setMsStyle( s, z, styles->z( s )->get( z ) );
+			if( msaRam->z( s ) && msaRam->z( s )->z( z ) )
+				obj->setARahmenZ( s, z, (LRahmen*)msaRam->z( s )->z( z )->dublizieren() );
+			if( msaAf->z( s ) && msaAf->z( s )->z( z ) )
+				obj->setAAlphaFeldZ( s, z, (AlphaFeld*)msaAf->z( s )->z( z )->dublizieren() );
+		}
+	}
+	obj->setAuswahl( selected.x, selected.y );
+	return obj;
+}
+
+// Reference Counting
+ObjTabelle *ObjTabelle::getThis()
+{
+	++ref;
+	return this;
+}
+
+ObjTabelle *ObjTabelle::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 353 - 0
Tabelle.h

@@ -0,0 +1,353 @@
+#ifndef Tabelle_H
+#define Tabelle_H
+
+#include "Zeichnung.h"
+#include "Array.h"
+
+namespace Framework
+{
+	class LRahmen; // Rahmen.h
+	class AlphaFeld; // AlphaFeld.h
+	class VScrollBar; // Scroll.h
+	class HScrollBar; // Scroll.h
+	class Text; // Text.h
+	class ObjTabelle; // aus dieser Datei
+
+    // Verwaltet eine Tabelle aus Zeichnungen
+	class ObjTabelle : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 SpaltenBreiteÄnderbar = 0x00001000; // Wenn dieser Flag gesetzt wird, so kann der Benutzer die Spalten mit der Maus vergrößern und verkleinern
+            const static __int64 ZeilenHöheÄnderbar = 0x00002000; // Wenn dieser Flag gesetzt wird, so kann der Benutzer die Spalten mit der Maus vergrößern und verkleinern
+            const static __int64 SpaltenBreiteMin = 0x00004000; // Wenn dieser Flag gesetzt wird, so kann der Nutzer trotz des Flags SpaltenBreiteÄnderbar die Spaltenbreite nicht kleiner machen als eine bestimmte Grenze
+            const static __int64 SpaltenBreiteMax = 0x00008000; // Wenn dieser Flag gesetzt wird, so kann der Nutzer trotz des Flags SpaltenBreiteÄnderbar die Spaltenbreite nicht größer machen als eine bestimmte Grenze
+            const static __int64 ZeilenHöheMin = 0x00010000; // Wenn dieser Flag gesetzt wird, so kann der Nutzer trotz des Flags ZeilenHöheÄnderbar die Zeilenhöhe nicht kleiner machen als eine bestimmte Grenze
+            const static __int64 ZeilenHöheMax = 0x00020000; // Wenn dieser Flag gesetzt wird, so kann der Nutzer trotz des Flags ZeilenHöheÄnderbar die Zeilenhöhe nicht größer machen als eine bestimmte Grenze
+            const static __int64 SpaltenBeweglich = 0x00040000; // Wenn dieser Flag gesetzt wird, so kann der Nutzer die Reihenfolge der Spalten bestimmen, in dem er sie per Drag and Drop verschiebt
+            const static __int64 AuswahlRahmen = 0x0080000; // Wenn dieser Flag gesetzt ist, so bekommt das Feld, dass der Benutzer durch den Flag Erlaubt auswählen kann einen anderen Rahmen
+            const static __int64 AuswahlBuffer = 0x00100000; // Wenn dieser Flag gesetzt ist, so bekommt das Feld, dass der Benutzer durch den Flag Erlaubt auswählen kann ein anderes AlphaFeld
+            const static __int64 AuswahlMultistyled = 0x00200000; // Wenn dieser Flag gesetzt ist, so kann jedes Feld andere Rahmen und AlphaFelder beim Auswählen haben.
+            const static __int64 Raster = 0x00400000; // Wenn dieser Flag gesetzt ist, so werden zwischen den Feldern Linien gezeichnet
+
+            const static __int64 beweglich = SpaltenBreiteÄnderbar | ZeilenHöheÄnderbar | SpaltenBeweglich; // Vereint die Flags: SpaltenBreiteÄnderbar, ZeilenHöheÄnderbar, SpaltenBeweglich
+            const static __int64 min_max = SpaltenBreiteMax | SpaltenBreiteMin | ZeilenHöheMax | ZeilenHöheMax; // Vereint die Flags: SpaltenBreiteMax, SpaltenBreiteMin, ZeilenHöheMax, ZeilenHöheMax
+            const static __int64 scroll = VScroll | HScroll; // Vereint die Flags: VScroll, HScroll
+            const static __int64 normal = Rahmen | Erlaubt | Sichtbar | AuswahlBuffer | AuswahlRahmen | Raster; // Vereint die Flags: Rahmen, Erlaubt, Sichtbar, SpaltenBeweglich, AuswahlBuffer, AuswahlRahmen, Raster
+        };
+	private:
+		RCArray< Array< Zeichnung* > > *zZeichnungs;
+		RCArray< Text > *spaltenNamen;
+		RCArray< Text > *zeilenNamen;
+		Array< int > *spaltenBreite;
+		Array< int > *zeilenHöhe;
+		Array< int > *minSpaltenBreite;
+		Array< int > *maxSpaltenBreite;
+		Array< int > *minZeilenHöhe;
+		Array< int > *maxZeilenHöhe;
+		int spaltenAnzahl, zeilenAnzahl;
+		int klickSpalte;
+		double mSpalte, mZeile;
+		int mx, my;
+		Punkt selected;
+		int rasterFarbe;
+		int rasterBreite;
+		LRahmen *aRam;
+		AlphaFeld *aAf;
+		RCArray< RCArray< LRahmen > > *msaRam;
+		RCArray< RCArray< AlphaFeld > > *msaAf;
+		RCArray< Array< __int64 > > *styles;
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) ObjTabelle();
+		// Destruktor 
+		__declspec( dllexport ) ~ObjTabelle();
+		// Fügt der Tabelle eine Spalte hinzu
+        //  name: Der Name der Spalte
+		__declspec( dllexport ) void addSpalte( const char *name );
+        // Fügt der Tabelle eine Spalte hinzu
+        //  name: Der Name der Spalte
+		__declspec( dllexport ) void addSpalte( Text *name );
+        // Fügt der Tabelle an einer bestimmten Position eine Spalte hinzu
+        //  sNum: Der Index der neuen Spalte
+        //  name: Der Name der neuen Spalte
+		__declspec( dllexport ) void addSpalte( int sNum, const char *name );
+        // Fügt der Tabelle an einer bestimmten Position eine Spalte hinzu
+        //  sNum: Der Index der neuen Spalte
+        //  name: Der Name der neuen Spalte
+		__declspec( dllexport ) void addSpalte( int sNum, Text *name );
+        // Fügt der Tabelle eine Zeile hinzu
+        //  name: Der Name der Zeile
+		__declspec( dllexport ) void addZeile( const char *name );
+        // Fügt der Tabelle eine Zeile hinzu
+        //  name: Der Name der Zeile
+		__declspec( dllexport ) void addZeile( Text *name );
+        // Fügt der Tabelle an einer bestimmten Position eine Zeile hinzu
+        //  zNum: Der Index der neuen Zeile
+        //  name: Der Name der neuen Zeile
+		__declspec( dllexport ) void addZeile( int zNum, const char *name );
+        // Fügt der Tabelle an einer bestimmten Position eine Zeile hinzu
+        //  sNum: Der Index der neuen Zeile
+        //  name: Der Name der neuen Zeile
+		__declspec( dllexport ) void addZeile( int zNum, Text *name );
+        // Entfernt eine Spalte
+        //  sNum: Der Index der Spalte
+		__declspec( dllexport ) void removeSpalte( int sNum );
+        // Entfernt eine Spalte
+        //  name: Der Name der Spalte
+		__declspec( dllexport ) void removeSpalte( const char *name );
+        // Entfernt eine Spalte
+        //  name: Der Name der Spalte
+		__declspec( dllexport ) void removeSpalte( Text *name );
+        // Entfernt eine Zeile
+        //  zNum: Der Index der Zeile
+		__declspec( dllexport ) void removeZeile( int zNum );
+        // Entfernt eine Zeile
+        //  name: Der Name der Zeile
+		__declspec( dllexport ) void removeZeile( const char *name );
+        // Entfernt eine Zeile
+        //  name: Der Name der Zeile
+		__declspec( dllexport ) void removeZeile( Text *name );
+        // Setzt den Index einer Spalte
+        //  name: Der Name der Spalte
+        //  pos: Der neue Index der Spalte
+		__declspec( dllexport ) void setSpaltePosition( const char *name, int pos );
+        // Setzt den Index einer Spalte
+        //  name: Der Name der Spalte
+        //  pos: Der neue Index der Spalte
+		__declspec( dllexport ) void setSpaltePosition( Text *name, int pos );
+        // Setzt den Index einer Spalte
+        //  sNum: Der alte Index der Spalte
+        //  pos: Der neue Index der Spalte
+		__declspec( dllexport ) void setSpaltePosition( int sNum, int pos );
+        // Setzt den Index einer Zeile
+        //  name: Der Name der Zeile
+        //  pos: Der neue Index der Zeile
+		__declspec( dllexport ) void setZeilePosition( const char *name, int pos );
+        // Setzt den Index einer Zeile
+        //  name: Der Name der Zeile
+        //  pos: Der neue Index der Zeile
+		__declspec( dllexport ) void setZeilePosition( Text *name, int pos );
+        // Setzt den Index einer Zeile
+        //  zNum: Der alte Index der Zeile
+        //  pos: Der neue Index der Zeile
+		__declspec( dllexport ) void setZeilePosition( int zNum, int pos );
+        // Setzt ein Zeichnung, welches in einem Bestimmten Feld sein soll
+        // Wenn bereits ein Zeichnung in dem Feld ist, wird es überschrieben.
+        //  sNum: Der Index der Spalte, in der das Zeichnung stehen soll
+        //  zNum: Der Index der Zeile, in der das Zeichnung stehen soll
+        //  zObj: Das Zeichnung welches in dem Feld sein soll
+		__declspec( dllexport ) void setZeichnungZ( int sNum, int zNum, Zeichnung *zObj );
+        // Setzt ein Zeichnung, welches in einem Bestimmten Feld sein soll
+        // Wenn bereits ein Zeichnung in dem Feld ist, wird es überschrieben.
+        //  spaltenName: Der Name der Spalte, in der das Zeichnung stehen soll
+        //  zeilenName: Der Name der Zeile, in der das Zeichnung stehen soll
+        //  zZeichnung: Das Zeichnung welches in dem Feld sein soll
+		__declspec( dllexport ) void setZeichnungZ( const char *spaltenName, const char *zeilenName, Zeichnung *zZeichnung );
+        // Setzt ein Zeichnung, welches in einem Bestimmten Feld sein soll
+        // Wenn bereits ein Zeichnung in dem Feld ist, wird es überschrieben.
+        //  spaltenName: Der Name der Spalte, in der das Zeichnung stehen soll
+        //  zeilenName: Der Name der Zeile, in der das Zeichnung stehen soll
+        //  zZeichnung: Das Zeichnung welches in dem Feld sein soll
+		__declspec( dllexport ) void setZeichnungZ( Text *spaltenName, Text *zeilenName, Zeichnung *zZeichnung );
+        // Setzt die Spalten Breite
+        //  sNum: Der Index der Spalte
+        //  br: Die Breite in Pixeln
+        __declspec( dllexport ) void setSpaltenBreite( int sNum, int br );
+        // Setzt die Spalten Breite
+        //  name: Der Name der Spalte
+        //  br: Die Breite in Pixeln
+		__declspec( dllexport ) void setSpaltenBreite( const char *name, int br );
+        // Setzt die Spalten Breite
+        //  name: Der Name der Spalte
+        //  br: Die Breite in Pixeln
+		__declspec( dllexport ) void setSpaltenBreite( Text *name, int br );
+        // Setzt die Zeilen Höhe
+        //  zNum: Der Index der Zeile
+        //  hö: Die Höhe in Pixeln
+		__declspec( dllexport ) void setZeilenHöhe( int zNum, int hö );
+        // Setzt die Zeilen Höhe
+        //  name: Der Index der Zeile
+        //  hö: Die Höhe in Pixeln
+		__declspec( dllexport ) void setZeilenHöhe( const char *name, int hö );
+        // Setzt die Zeilen Höhe
+        //  name: Der Index der Zeile
+        //  hö: Die Höhe in Pixeln
+		__declspec( dllexport ) void setZeilenHöhe( Text *name, int hö );
+        // Setzt die minimale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMin)
+        //  sNum: Der Index der Spalte
+        //  minBr: Die minimale Breite in Pixeln
+		__declspec( dllexport ) void setMinSpaltenBreite( int sNum, int minBr );
+        // Setzt die minimale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMin)
+        //  name: Der Name der Spalte
+        //  minBr: Die minimale Breite in Pixeln
+		__declspec( dllexport ) void setMinSpaltenBreite( const char *name, int minBr );
+        // Setzt die minimale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMin)
+        //  name: Der Name der Spalte
+        //  minBr: Die minimale Breite in Pixeln
+		__declspec( dllexport ) void setMinSpaltenBreite( Text *name, int minBr );
+        // Setzt die maximale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMax)
+        //  sNum: Der Index der Spalte
+        //  maxBr: Die maximale Breite in Pixeln
+		__declspec( dllexport ) void setMaxSpaltenBreite( int sNum, int maxBr );
+        // Setzt die maximale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMax)
+        //  name: Der Name der Spalte
+        //  maxBr: Die maximale Breite in Pixeln
+		__declspec( dllexport ) void setMaxSpaltenBreite( const char *name, int maxBr );
+        // Setzt die maximale Spalten Breite (benötigt Flag: SpaltenBreiteÄnderbar, SpaltenBreiteMax)
+        //  name: Der Name der Spalte
+        //  maxBr: Die maximale Breite in Pixeln
+		__declspec( dllexport ) void setMaxSpaltenBreite( Text *name, int maxBr );
+        // Setzt die minimale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMin)
+        //  zNum: Der Index der Zeile
+        //  minHö: Die minimale Höhe in Pixeln
+		__declspec( dllexport ) void setMinZeilenHöhe( int zNum, int minHö );
+        // Setzt die minimale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMin)
+        //  name: Der Name der Zeile
+        //  minHö: Die minimale Höhe in Pixeln
+		__declspec( dllexport ) void setMinZeilenHöhe( const char *name, int minHö );
+        // Setzt die minimale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMin)
+        //  name: Der Name der Zeile
+        //  minHö: Die minimale Höhe in Pixeln
+		__declspec( dllexport ) void setMinZeilenHöhe( Text *name, int minHö );
+        // Setzt die maximale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMax)
+        //  zNum: Der Index der Zeile
+        //  maxHö: Die maximale Höhe in Pixeln
+		__declspec( dllexport ) void setMaxZeilenHöhe( int zNum, int maxHö );
+        // Setzt die maximale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMax)
+        //  name: Der Name der Zeile
+        //  maxHö: Die maximale Höhe in Pixeln
+		__declspec( dllexport ) void setMaxZeilenHöhe( const char *name, int maxHö );
+        // Setzt die maximale Zeilen Höhe (benötigt Flag: ZeilenHöheÄnderbar, ZeienHöheMax)
+        //  name: Der Name der Zeile
+        //  maxHö: Die maximale Höhe in Pixeln
+		__declspec( dllexport ) void setMaxZeilenHöhe( Text *name, int maxHö );
+        // Legt fest, welches Feld ausgewählt ist (benötigt Flag: Erlaubt)
+        //  sNum: Der Index der Spalte des Feldes
+        //  zNum: Der Index der Zeile des Feldes
+		__declspec( dllexport ) void setAuswahl( int sNum, int zNum );
+        // Legt fest, welches Feld ausgewählt ist (benötigt Flag: Erlaubt)
+        //  spaltenName: Der Name der Spalte des Feldes
+        //  zeilenName: Der Name der Zeile des Feldes
+		__declspec( dllexport ) void setAuswahl( const char *spaltenName, const char *zeilenName );
+        // Legt fest, welches Feld ausgewählt ist (benötigt Flag: Erlaubt)
+        //  spaltenName: Der Name der Spalte des Feldes
+        //  zeilenName: Der Name der Zeile des Feldes
+		__declspec( dllexport ) void setAuswahl( Text *spaltenName, Text *zeilenName );
+		__declspec( dllexport ) void setRasterFarbe( int f ); // settzt die Farbe des Rasters
+		__declspec( dllexport ) void setRasterBreite( int br ); // setzt die Breite des Rasters
+		__declspec( dllexport ) void setARahmenZ( LRahmen *ram ); // setzt den auswahl Rahmen
+		__declspec( dllexport ) void setARFarbe( int f ); // setzt die auswahl Rahmen Farbe
+		__declspec( dllexport ) void setARBreite( int br ); // setzt die auswahl Rahmen Breite
+		__declspec( dllexport ) void setAAlphaFeldZ( AlphaFeld *af ); // setzt das auswahl AlphaFeld
+		__declspec( dllexport ) void setAAfFarbe( int f ); // setzt die Farbe des auswahl AlphaFeldes
+		__declspec( dllexport ) void setAAfStärke( int st ); // setzt die Stärke des auswahl AlphaFeldes
+		__declspec( dllexport ) void setARahmenZ( int sNum, int zNum, LRahmen *ram ); // setzt den auswahl Rahmen
+		__declspec( dllexport ) void setARahmenZ( const char *spaltenName, const char *zeilenName, LRahmen *ram );
+		__declspec( dllexport ) void setARahmenZ( Text *spaltenName, Text *zeilenName, LRahmen *ram );
+		__declspec( dllexport ) void setARFarbe( int sNum, int zNum, int f ); // setzt die auswahl Rahmen Farbe
+		__declspec( dllexport ) void setARFarbe( const char *spaltenName, const char *zeilenName, int f );
+		__declspec( dllexport ) void setARFarbe( Text *spaltenName, Text *zeilenName, int f );
+		__declspec( dllexport ) void setARBreite( int sNum, int zNum, int br ); // setzt die auswahl Rahmen Breite
+		__declspec( dllexport ) void setARBreite( const char *spaltenName, const char *zeilenName, int br );
+		__declspec( dllexport ) void setARBreite( Text *spaltenName, Text *zeilenName, int br );
+		__declspec( dllexport ) void setAAlphaFeldZ( int sNum, int zNum, AlphaFeld *af ); // setzt das auswahl AlphaFeld
+		__declspec( dllexport ) void setAAlphaFeldZ( const char *spaltenName, const char *zeilenName, AlphaFeld *af );
+		__declspec( dllexport ) void setAAlphaFeldZ( Text *spaltenName, Text *zeilenName, AlphaFeld *af );
+		__declspec( dllexport ) void setAAfFarbe( int sNum, int zNum, int f ); // setzt die Farbe des auswahl AlphaFeldes
+		__declspec( dllexport ) void setAAfFarbe( const char *spaltenName, const char *zeilenName, int f );
+		__declspec( dllexport ) void setAAfFarbe( Text *spaltenName, Text *zeilenName, int f );
+		__declspec( dllexport ) void setAAfStärke( int sNum, int zNum, int st ); // setzt die Stärke des auswahl AlphaFeldes
+		__declspec( dllexport ) void setAAfStärke( const char *spaltenName, const char *zeilenName, int st );
+		__declspec( dllexport ) void setAAfStärke( Text *spaltenName, Text *zeilenName, int st );
+		__declspec( dllexport ) void addMsStyle( int sNum, int zNum, __int64 style ); // setzt den Style wenn Multistyled
+		__declspec( dllexport ) void addMsStyle( const char *spaltenName, const char *zeilenName, __int64 style );
+		__declspec( dllexport ) void addMsStyle( Text *spaltenName, Text *zeilenName, __int64 style );
+		__declspec( dllexport ) void setMsStyle( int sNum, int zNum, __int64 style );
+		__declspec( dllexport ) void setMsStyle( const char *spaltenName, const char *zeilenName, __int64 style );
+		__declspec( dllexport ) void setMsStyle( Text *spaltenName, Text *zeilenName, __int64 style );
+		__declspec( dllexport ) void setMsStyle( int sNum, int zNum, __int64 style, bool add_remove );
+		__declspec( dllexport ) void setMsStyle( const char *spaltenName, const char *zeilenName, __int64 style, bool add_remove );
+		__declspec( dllexport ) void setMsStyle( Text *spaltenName, Text *zeilenName, __int64 style, bool add_remove );
+		__declspec( dllexport ) void löscheMsStyle( int sNum, int zNum, __int64 style );
+		__declspec( dllexport ) void löscheMsStyle( const char *spaltenName, const char *zeilenName, __int64 style );
+		__declspec( dllexport ) void löscheMsStyle( Text *spaltenName, Text *zeilenName, __int64 style );
+		__declspec( dllexport ) bool tick( double tickVal ) override; // tick Message
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override; // verarbeitet Nachrichten
+		__declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ) override;
+		__declspec( dllexport ) void render( Bild &zRObj ) override; // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) int getSpaltenAnzahl() const; // gibt die Anzahl der Spalten zurück
+		__declspec( dllexport ) int getZeilenAnzahl() const; // gibt die Anzahl der Zeilen zurück
+		__declspec( dllexport ) int getSpaltenNummer( const char *name ) const; // gibt die Nummer der Spalte mit dem Namen name zurück
+		__declspec( dllexport ) int getSpaltenNummer( Text *name ) const;
+		__declspec( dllexport ) Text *getSpaltenName( int num ) const; // gibt den Namen der Spalte mit Nummer num zurück
+		__declspec( dllexport ) Text *zSpaltenName( int num ) const;
+		__declspec( dllexport ) int getZeilenNummer( const char *name ) const; // gibt die Nummer der Zeile mit dem Namen name zurück
+		__declspec( dllexport ) int getZeilenNummer( Text *name ) const;
+		__declspec( dllexport ) Text *getZeilenName( int num ) const; // gibt den Namen der Zeile mit Nummer num zurück
+		__declspec( dllexport ) Text *zZeilenName( int num ) const;
+		__declspec( dllexport ) Punkt getZeichnungPosition( Zeichnung *zObj ) const; // gibt die Position eines Zeichnungs zurück
+		__declspec( dllexport ) Zeichnung *zZeichnung( int sNum, int zNum ) const; // gibt das Zeichnung auf der Position zurück
+		__declspec( dllexport ) Zeichnung *zZeichnung( const char *spaltenName, const char *zeilenName ) const;
+		__declspec( dllexport ) Zeichnung *zZeichnung( Text *spaltenName, Text *zeilenName ) const;
+		__declspec( dllexport ) int getSpaltenBreite( int num ) const; // gibt die Breite der Spalte zurück
+		__declspec( dllexport ) int getSpaltenBreite( const char *name ) const;
+		__declspec( dllexport ) int getSpaltenBreite( Text *name ) const;
+		__declspec( dllexport ) int getZeilenHöhe( int num ) const; // gibt die Höhe der Zeile zurück
+		__declspec( dllexport ) int getZeilenHöhe( const char *name ) const;
+		__declspec( dllexport ) int getZeilenHöhe( Text *name ) const;
+		__declspec( dllexport ) int getMinSpaltenBreite( int num ) const; // gibt die minimale Spaltengröße zurück
+		__declspec( dllexport ) int getMinSpaltenBreite( const char *name ) const;
+		__declspec( dllexport ) int getMinSpaltenBreite( Text *name ) const;
+		__declspec( dllexport ) int getMaxSpaltenBreite( int num ) const; // gibt die maximale Spaltengröße zurück
+		__declspec( dllexport ) int getMaxSpaltenBreite( const char *name ) const;
+		__declspec( dllexport ) int getMaxSpaltenBreite( Text *name ) const;
+		__declspec( dllexport ) int getMinZeilenHöhe( int num ) const; // gibt die minimale Zeilenhöhe zurück
+		__declspec( dllexport ) int getMinZeilenHöhe( const char *name ) const;
+		__declspec( dllexport ) int getMinZeilenHöhe( Text *name ) const;
+		__declspec( dllexport ) int getMaxZeilenHöhe( int num ) const; // gibt die maximale Zeilenhöhe zurück
+		__declspec( dllexport ) int getMaxZeilenHöhe( const char *name ) const;
+		__declspec( dllexport ) int getMaxZeilenHöhe( Text *name ) const;
+		__declspec( dllexport ) double getMausSpalte( int mx ) const; // ermittelt die Spalte unter der Maus
+		__declspec( dllexport ) Text *getMausSpaltenName( int mx ) const;
+		__declspec( dllexport ) Text *zMausSpaltenName( int mx ) const;
+		__declspec( dllexport ) double getMausZeile( int my ) const; // ermittelt die Zeile unter der Maus
+		__declspec( dllexport ) Text *getMausZeilenName( int my ) const;
+		__declspec( dllexport ) Text *zMausZeilenName( int my ) const;
+		__declspec( dllexport ) const Punkt &getAuswahlPosition() const; // gibt die Auswahl Position zurück
+		__declspec( dllexport ) int getRasterFarbe() const; // gibt die Farbe des Rasters zurück
+		__declspec( dllexport ) int getRasterBreite() const; // gibt die Breite des Rasters zurück
+		__declspec( dllexport ) LRahmen *getARahmen() const; // gibt den auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zARahmen() const;
+		__declspec( dllexport ) AlphaFeld *getAAlphaFeld() const; // gibt das auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zAAlphaFeld() const;
+		__declspec( dllexport ) LRahmen *getARahmen( int sNum, int zNum ) const; // gibt den auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zARahmen( int sNum, int zNum ) const;
+		__declspec( dllexport ) AlphaFeld *getAAlphaFeld( int sNum, int zNum ) const; // gibt das auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zAAlphaFeld( int sNum, int zNum ) const;
+		__declspec( dllexport ) LRahmen *getARahmen( const char *spaltenName, const char *zeilenName ) const; // gibt den auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zARahmen( const char *spaltenName, const char *zeilenName ) const;
+		__declspec( dllexport ) AlphaFeld *getAAlphaFeld( const char *spaltenName, const char *zeilenName ) const; // gibt das auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zAAlphaFeld( const char *spaltenName, const char *zeilenName ) const;
+		__declspec( dllexport ) LRahmen *getARahmen( Text *spaltenName, Text *zeilenName ) const; // gibt den auswahl Rahmen zurück
+		__declspec( dllexport ) LRahmen *zARahmen( Text *spaltenName, Text *zeilenName ) const;
+		__declspec( dllexport ) AlphaFeld *getAAlphaFeld( Text *spaltenName, Text *zeilenName ) const; // gibt das auswahl AlphaFeld zurück
+		__declspec( dllexport ) AlphaFeld *zAAlphaFeld( Text *spaltenName, Text *zeilenName ) const;
+		__declspec( dllexport ) inline bool hatMsStyle( int sNum, int zNum, __int64 style ) const; // prüft, ob style vorhanden ist
+		__declspec( dllexport ) inline bool hatMsStyleNicht( int sNum, int zNum, __int64 style ) const; // prüft, ob style nicht vorhanden ist
+		__declspec( dllexport ) inline bool hatMsStyle( const char *spaltenName, const char *zeilenName, __int64 style ) const; // prüft, ob style vorhanden ist
+		__declspec( dllexport ) inline bool hatMsStyleNicht( const char *spaltenName, const char *zeilenName, __int64 style ) const; // prüft, ob style nicht vorhanden ist
+		__declspec( dllexport ) inline bool hatMsStyle( Text *spaltenName, Text *zeilenName, __int64 style ) const; // prüft, ob style vorhanden ist
+		__declspec( dllexport ) inline bool hatMsStyleNicht( Text *spaltenName, Text *zeilenName, __int64 style ) const; // prüft, ob style nicht vorhanden ist
+		__declspec( dllexport ) Zeichnung *dublizieren() const override; // Erzeugt eine Kopie des Zeichnungs
+		// Reference Counting
+		__declspec( dllexport ) ObjTabelle *getThis();
+		__declspec( dllexport ) ObjTabelle *release();
+	};
+}
+#endif

+ 34 - 0
TastaturEreignis.cpp

@@ -0,0 +1,34 @@
+#include "TastaturEreignis.h"
+
+using namespace Framework;
+
+bool Framework::_ret1TE( void *param, void *obj, TastaturEreignis te )
+{
+	return 1;
+}
+
+bool Framework::_nurNummernTE( void *param, void *obj, TastaturEreignis te )
+{
+	if( te.taste >= '0' && te.taste <= '9' )
+		return 1;
+	if( te.taste == T_Entf || te.taste == T_BackSpace )
+		return 1;
+	if( te.taste == T_Links || te.taste == T_Rechts || te.taste == T_Unten || te.taste == T_Oben )
+		return 1;
+	return 0;
+}
+
+bool Framework::_nurHexTE( void *param, void *obj, TastaturEreignis te )
+{
+	if( te.taste >= '0' && te.taste <= '9' )
+		return 1;
+	if( te.taste >= 'A' && te.taste <= 'F' )
+		return 1;
+	if( te.taste >= 'a' && te.taste <= 'f' )
+		return 1;
+	if( te.taste == T_Entf || te.taste == T_BackSpace )
+		return 1;
+	if( te.taste == T_Links || te.taste == T_Rechts || te.taste == T_Unten || te.taste == T_Oben )
+		return 1;
+	return 0;
+}

+ 81 - 0
TastaturEreignis.h

@@ -0,0 +1,81 @@
+#ifndef TastaturEreignis_H
+#define TastaturEreignis_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+    // Es wurde eine Taste runtergedrückt
+	const int TE_Press = 0;
+    // Es wurde eine Taste losgelassen
+	const int TE_Release = 1;
+	const unsigned char T_Esc = 27;
+	const unsigned char T_Tab = 0;
+	const unsigned char T_Enter = 13;
+	const unsigned char T_BackSpace = 8;
+	const unsigned char T_Space = 32;
+	const unsigned char T_Caps_Lock = 129;
+	const unsigned char T_Shift = 130;
+	const unsigned char T_Strg = 141;
+	const unsigned char T_F1 = 143;
+	const unsigned char T_F2 = 144;
+	const unsigned char T_F3 = 157;
+	const unsigned char T_F4 = 160;
+	const unsigned char T_F5 = 130;
+	const unsigned char T_F6 = 132;
+	const unsigned char T_F7 = 133;
+	const unsigned char T_F8 = 134;
+	const unsigned char T_F9 = 135;
+	const unsigned char T_F10 = 136;
+	const unsigned char T_F11 = 137;
+	const unsigned char T_F12 = 138;
+	const unsigned char T_Pause = 139;
+	const unsigned char T_Druck = 140;
+	const unsigned char T_Einfg = 142;
+	const unsigned char T_Entf = 145;
+	const unsigned char T_Links = 146;
+	const unsigned char T_Oben = 147;
+	const unsigned char T_Rechts = 148;
+	const unsigned char T_Unten = 149;
+	const unsigned char T_Alt_Gr = 150;
+	const unsigned char T_Num = 151;
+	const unsigned char T_Pos1 = 152;
+	const unsigned char T_BildO = 153;
+	const unsigned char T_BildU = 154;
+	const unsigned char T_Ende = 155;
+
+    // Speichert den Input eines Nutzers auf der Tastatur
+	struct TastaturEreignis
+	{
+        // Art der Eingabe
+		int id;
+        // Betroffene Taste
+		unsigned char taste;
+        // (true), wenn die Eingabe bereits verarbeitet wurde. (false) sonnst
+		bool verarbeitet;
+	};
+
+    // Standart Tastatur Ereinis Rückruffunktion
+    //  param: Ein beliebiger Parameter
+    //  obj: Das Zeichnung, welches diese Funktion aufruft
+    //  te: Das Tastaturereignis, welches verarbeitet werden soll
+    //  return: (true), wenn aufrufende Zeichnung das Ereignis weiterverarbeiten soll. (false) sonnst.
+    // Gibt immer (true) zurück
+	__declspec( dllexport ) bool _ret1TE( void *param, void *obj, TastaturEreignis te );
+    // Standart Tastatur Ereinis Rückruffunktion
+    //  param: Ein beliebiger Parameter
+    //  obj: Das Zeichnung, welches diese Funktion aufruft
+    //  te: Das Tastaturereignis, welches verarbeitet werden soll
+    //  return: (true), wenn aufrufende Zeichnung das Ereignis weiterverarbeiten soll. (false) sonnst.
+    // Gibt nur (true) zurück, wenn die Taste zwischen '0' und '9' ist, oder zum Löschen oder Cursorbewegen dient
+	__declspec( dllexport ) bool _nurNummernTE( void *param, void *obj, TastaturEreignis te );
+    // Standart Tastatur Ereinis Rückruffunktion
+    //  param: Ein beliebiger Parameter
+    //  obj: Das Zeichnung, welches diese Funktion aufruft
+    //  te: Das Tastaturereignis, welches verarbeitet werden soll
+    //  return: (true), wenn aufrufende Zeichnung das Ereignis weiterverarbeiten soll. (false) sonnst.
+    // Gibt nur (true) zurück, wenn die Taste zwischen '0' und '9' oder 'A' und 'F' ist, oder zum Löschen oder Cursorbewegen dient
+	__declspec( dllexport ) bool _nurHexTE( void *param, void *obj, TastaturEreignis te );
+}
+
+#endif

+ 43 - 0
TestShader.hlsl

@@ -0,0 +1,43 @@
+/////////////                                                                                  
+// GLOBALS //                                                                                  
+/////////////                                                                                  
+cbuffer MatrixBuffer : register( b0 )
+{
+    matrix knochenMatrix[ 128 ];
+};
+
+//////////////                                                                                 
+// TYPEDEFS //                                                                                 
+//////////////                                                                                 
+struct VertexInputType
+{
+    float4 position : POSITION;
+    float2 tex : TEXCOORD0;
+    int knochen : KNOCHEN_ID;
+};
+
+struct PixelInputType
+{
+    float4 position : SV_POSITION;
+    float2 tex : TEXCOORD0;
+};
+
+////////////////////////////////////////////////////////////////////////////////               
+// Vertex Shader                                                                               
+////////////////////////////////////////////////////////////////////////////////               
+PixelInputType TextureVertexShader( VertexInputType input )
+{
+    //return input;                                                                            
+    PixelInputType output;
+
+    // Change the position vector to be 4 units for proper matrix calculations.                
+    input.position.w = 1.0f;
+
+    // Store the texture coordinates for the pixel shader.                                     
+    output.tex = input.tex;
+
+    // Calculate the position of the vertex against the world, view, and projection matrices.  
+    output.position = mul( input.position, knochenMatrix[ input.knochen ] );
+
+    return output;
+}

+ 1346 - 0
Text.cpp

@@ -0,0 +1,1346 @@
+//---Include---
+#include "Text.h"
+#include <sstream>
+#include <string>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iomanip>
+#ifndef WIN32
+#include <string.h>
+#endif
+
+using namespace Framework;
+
+// inhalt der Text Klasse aus Text.h
+// Konstruktor 
+Text::Text()
+	: txt( 0 ),
+	  suchGBeg( 0 ),
+	  suchGEnd( 0 ),
+	  präzision( 0 ),
+	  ref( 1 )
+{
+	setText( "" );
+}
+
+Text::Text( const Text &txt )
+	: txt( 0 ),
+	suchGBeg( 0 ),
+	suchGEnd( 0 ),
+	präzision( 0 ),
+	ref( 1 )
+{
+	setText( txt );
+}
+
+Text::Text( const char *t )
+	: txt( 0 ),
+	  suchGBeg( 0 ),
+	  suchGEnd( 0 ),
+	  präzision( 0 ),
+	  ref( 1 )
+{
+	setText( t ); // Text setzen
+}
+
+Text::Text( int zahl )
+    : txt( 0 ),
+    suchGBeg( 0 ),
+    suchGEnd( 0 ),
+    präzision( 0 ),
+    ref( 1 )
+{
+    *this = zahl;
+}
+
+// Destruktor 
+Text::~Text()
+{
+	delete[]txt;
+}
+
+// nicht constant
+void Text::setSuchGrenzen( char gBeg, char gEnd ) // sucht bei jeder suchfunktion nicht zwischen den Zeichen gBeg und gEnd
+{
+	suchGBeg = gBeg;
+	suchGEnd = gEnd;
+}
+
+void Text::setText( const char *t ) // ersetzt den Text
+{
+	delete[]txt; // alter Text löschen
+	int l = (int)strlen( t ); // Länge des neuen Textes ermitteln
+	txt = new char[ l + 1 ]; // neuen Text erstellen
+	for( int i = 0; i < l; ++i ) // Text befüllen
+		txt[ i ] = t[ i ];
+	txt[ l ] = '\0'; // Textende Festlegen
+}
+
+// unconstant 
+void Text::setText( const char *t, int l ) // ersetzt den Text
+{
+	delete[]txt; // alter Text löschen
+	txt = new char[ l + 1 ]; // neuen Text erstellen
+	for( int i = 0; i < l; ++i ) // Text befüllen
+		txt[ i ] = t[ i ];
+	txt[ l ] = '\0'; // Textende Festlegen
+}
+
+void Text::setText( Text *t )
+{
+	setText( t->getText() ); // Text setzen
+	t = t->release(); // übergabe loslassen
+}
+
+void Text::anhängen( char c ) // hängt an den Text an
+{
+	anhängen( &c, 1 );
+}
+
+void Text::anhängen( const char *t ) // hängt an den Text an
+{
+	int tl = (int)strlen( t ); // länge der übergabe
+	int txl = getLänge(); // länge des Textes
+	char *res = new char[ tl + txl + 1 ]; // neuen Text erstellen
+	for( int i = 0; i < txl; ++i ) // mit jetzigem Text füllen
+		res[ i ] = txt[ i ];
+	for( int i = 0; i < tl; ++i ) // Übergabe anhängen
+		res[ txl + i ] = t[ i ];
+	res[ txl + tl ] = '\0'; // Textende festlegen
+	setText( res ); // Test setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::hexAnhängen( int num ) // hängt die zahl in hex anden Text an
+{
+    int l = getLänge();
+    char *res = new char[ l + 9 ];
+    for( int i = 0; i < l; ++i )
+        res[ i ] = txt[ i ];
+    std::stringstream stream;
+    stream << std::setfill( '0' ) << std::setw( sizeof( int ) * 2 ) << std::hex << num;
+    std::string str = stream.str();
+    for( int i = l; i < l + 8; ++i )
+        res[ i ] = str.c_str()[ i - l ];
+    res[ l + 8 ] = 0;
+    setText( res );
+    delete[] res;
+}
+
+void Text::farbeAnhängen( int fc ) // setzt die Farbe des folgenden Textes
+{
+    int l = getLänge();
+	char *res = new char[ l + 12 ];
+	for( int i = 0; i < l; ++i )
+		res[ i ] = txt[ i ];
+	res[ l ] = '\r';
+	res[ l + 1 ] = '0';
+	res[ l + 2 ] = 'x';
+	std::stringstream stream;
+	stream << std::setfill( '0' ) << std::setw( sizeof( int ) * 2 ) << std::hex << fc;
+	std::string str = stream.str();
+	for( int i = l + 3; i < l + 11; ++i )
+		res[ i ] = str.c_str()[ i - ( l + 3 ) ];
+	res[ l + 11 ] = 0;
+	setText( res );
+	delete[] res;
+}
+
+void Text::anhängen( const char *t, int l ) // hängt an den Text an
+{
+	int txl = getLänge(); // länge des Textes
+	char *res = new char[ l + txl + 1 ]; // neuen Text erstellen
+	for( int i = 0; i < txl; ++i ) // mit jetzigem Text füllen
+		res[ i ] = txt[ i ];
+	for( int i = 0; i < l; ++i ) // Übergabe anhängen
+		res[ txl + i ] = t[ i ];
+	res[ txl + l ] = '\0'; // Textende festlegen
+	setText( res, txl + l ); // Test setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::anhängen( Text *t )
+{
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		anhängen( t->getText() ); // Text anhängen
+	t = t->release(); // Übergabe loslassen
+}
+
+void Text::anhängen( int num )
+{
+	std::stringstream ss;
+	ss << num;
+	anhängen( ss.str().c_str() );
+}
+
+void Text::anhängen( unsigned int num )
+{
+	std::stringstream ss;
+	ss << num;
+	anhängen( ss.str().c_str() );
+}
+
+void Text::anhängen( double num )
+{
+	std::stringstream ss;
+	ss.precision( präzision );
+	ss << num;
+	anhängen( ss.str().c_str() );
+}
+
+void Text::einfügen( int p, char c ) // Fügt an stelle p ein
+{
+	if( p > getLänge() || p < 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	int txl = getLänge(); // Länge des Textes
+	char *res = new char[ txl + 2 ]; // neuer Text erstellen
+	for( int i = 0; i < p; ++i ) // Text füllen
+		res[ i ] = txt[ i ];
+	res[ p ] = c;
+	for( int i = p; i < txl; ++i ) // Text füllen
+		res[ i + 1 ] = txt[ i ];
+	res[ txl + 1 ] = '\0'; // Text ende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::einfügen( int p, const char *t ) // Fügt an stelle p ein
+{
+	if( p > getLänge() || p < 0 || strlen( t ) <= 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	int tl = (int)strlen( t ); // Länge der übergabe
+	int txl = getLänge(); // Länge des Textes
+	char *res = new char[ tl + txl + 1 ]; // neuer Text erstellen
+	for( int i = 0; i < p; ++i ) // Text füllen
+		res[ i ] = txt[ i ];
+	for( int i = 0; i < tl; ++i ) // Text einfügen
+		res[ i + p ] = t[ i ];
+	for( int i = p; i < txl; ++i ) // Text füllen
+		res[ i + tl ] = txt[ i ];
+	res[ tl + txl ] = '\0'; // Text ende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::einfügen( int p, Text *t )
+{
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		einfügen( p, t->getText() ); // Text einfügen
+	t = t->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( int p1, int p2, const char *t ) // Ersetzt den Text von p1 bis p2
+{
+	if( p1 > p2 )
+	{
+		int x = p1; // p1 und p2 tauschen
+		p1 = p2;
+		p2 = x;
+	}
+	löschen( p1, p2 ); // Textabschnitt von p1 zu p2 löschen
+	einfügen( p1, t ); // Übergabe bei p1 einfügen
+}
+
+void Text::ersetzen( int p1, int p2, Text *t )
+{
+	if( t->getLänge() >= 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( p1, p2, t->getText() ); // Text ersetzen
+	t = t->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( char c1, char c2 ) // ersetzt jedes c1 durch c2
+{
+	if( c1 == '\0' || c2 == '\0' ) // Auf unsinnige übergabe prüfen
+		return;
+	if( !hat( c1 ) ) // prüfen ob c1 vorhanden
+		return;
+	int l = getLänge(); // Text Länge
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // Text durchsuchen
+	{
+		bool b = suchGCount != 0;
+		if( txt[ i ] == c1 && !suchGCount )
+			txt[ i ] = c2; // Text ersetzen
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( txt[ i ] == c1 && !suchGCount && b )
+			txt[ i ] = c2; // Text ersetzen
+	}
+}
+
+void Text::ersetzen( const char *t1, const char *t2 ) // ersetzt jedes t1 durch t2
+{
+	int txl = getLänge(); // Text Länge
+	int t1l = (int)strlen( t1 ); // Länge der Übergaben
+	int t2l = (int)strlen( t2 );
+	if( t1l > txl || t1l <= 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	if( !hat( t1 ) ) // prüfen ob t1 vorhanden
+		return;
+	int anz = anzahlVon( t1 ); // Anzahl von t1 im Text
+	int *begin = new int[ anz ];
+	int *end = new int[ anz ];
+	for( int i = 0; i < anz; ++i ) // Positionen von t1 speichern
+	{
+		begin[ i ] = positionVon( t1, i );
+		end[ i ] = begin[ i ] + t1l;
+	}
+	int resl = ( txl - ( anz * t1l ) ) + ( anz * t2l ) + 1; // Länge des Ergebneses
+	char *res = new char[ resl ]; // neuer Text erstellen
+	int rep = 0; // Speichert bei welchen t1 man sich befindet
+	int last = 0; // Füllposition von txt
+	int neu = 0; // Füllporition von res
+	for( ; neu < resl; ++neu ) // Text befüllen
+	{
+		if( rep < anz && last == begin[ rep ] ) // Text ersetzen
+		{
+			last = end[ rep ];
+			++rep;
+			for( int ii = 0; ii < t2l; ++ii )
+			{
+				if( neu >= resl )
+					break;
+				res[ neu ] = t2[ ii ];
+				++neu;
+			}
+			if( neu >= resl )
+				break;
+			--neu;
+		}
+		else // Text Kopieren
+		{
+			res[ neu ] = txt[ last ];
+			++last;
+		}
+	}
+	res[ resl - 1 ] = '\0'; // Textende festlegen
+	setText( res ); // Text setzen
+	delete[]begin; // Speicher freigeben
+	delete[]end;
+	delete[] res;
+}
+
+void Text::ersetzen( Text *t1, const char *t2 )
+{
+	if( t1->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( t1->getText(), t2 ); // ersetzen
+	t1 = t1->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( const char *t1, Text *t2 )
+{
+	if( t2->getLänge() >= 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( t1, t2->getText() ); // ersetzen
+	t2 = t2->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( Text *t1, Text *t2 )
+{
+	if( t1->getLänge() > 0 && t2->getLänge() >= 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( t1->getText(), t2->getText() ); // ersetzen
+	t1 = t1->release(); // Übergaben loslassen
+	t2 = t2->release();
+}
+
+void Text::ersetzen( int index, char c1, char c2 ) // ersetzt das i-te c1 durch c2
+{
+	if( c1 == '\0' || c2 == '\0' || index < 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	if( !hat( c1 ) ) // prüfen ob c1 vorhanden
+		return;
+	int anz = anzahlVon( c1 );
+	if( index >= anz ) // prüfen ob es ein i-tes c1 gibt
+		return;
+	txt[ positionVon( c1, index ) ] = c2;
+}
+
+void Text::ersetzen( int index, const char *t1, const char *t2 ) // ersetzt das i-te t1 durch t2
+{
+	int txl = getLänge(); // Text Länge
+	int t1l = (int)strlen( t1 ); // Länge der Übergaben
+	if( t1l >= txl || t1l <= 0 || index < 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	if( !hat( t1 ) ) // prüfen ob t1 vorhanden
+		return;
+	int anz = anzahlVon( t1 ); // Anzahl von t1 im Text
+	if( index >= anz ) // prüfen ob es ein i-tes t1 gibt
+		return;
+	int begin = positionVon( t1, index );
+	int end = begin + t1l;
+	ersetzen( begin, end, t2 ); // ersetzen
+}
+
+void Text::ersetzen( int i, Text *t1, const char *t2 )
+{
+	if( t1->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( i, t1->getText(), t2 ); // ersetzen
+	t1 = t1->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( int i, const char *t1, Text *t2 )
+{
+	if( t2->getLänge() >= 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( i, t1, t2->getText() ); // ersetzen
+	t2 = t2->release(); // Übergabe loslassen
+}
+
+void Text::ersetzen( int i, Text *t1, Text *t2 )
+{
+	if( t1->getLänge() > 0 || t2->getLänge() >= 0 ) // Auf unsinnige übergabe prüfen
+		ersetzen( i, t1->getText(), t2->getText() ); // ersetzen
+	t1 = t1->release(); // Übergaben loslassen
+	t2 = t2->release();
+}
+
+void Text::füllText( char c, int län ) // setzt den Text zu so vielen c wie län groß ist
+{
+	char *res = new char[ län + 1 ];
+	for( int i = 0; i < län; ++i )
+		res[ i ] = c;
+	res[ län ] = '\0';
+	setText( res );
+	delete[] res;
+}
+
+void Text::löschen( int p ) // löscht p
+{
+	int l = getLänge(); // Text Länge
+	if( p < 0 || p >= l ) // Auf unsinnige übergabe prüfen
+		return;
+	char *res = new char[ l ]; // neuen Text anlegen
+	for( int i = 0; i < p && i < l; ++i ) // Text befüllen
+		res[ i ] = txt[ i ];
+	for( int i = p + 1; i < l; ++i )
+		res[ i - 1 ] = txt[ i ];
+	res[ l - 1 ] = 0;
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( int p1, int p2 ) // löscht von p1 zu p2 ( p2 bleibt )
+{
+	if( p1 > p2 ) // p1 und p2 tauschen
+	{
+		int x = p1;
+		p1 = p2;
+		p2 = x;
+	}
+	int l = getLänge(); // Länge des Testes
+	if( p1 < 0 || p2 > l ) // Auf unsinnige übergabe prüfen
+		return;
+	int resl = l - ( p2 - p1 ); // Länge vom Ergebnis
+	char *res = new char[ resl + 1 ]; // Neuen Text erstellen
+	for( int i = 0; i < p1; ++i ) // Text füllen
+		res[ i ] = txt[ i ];
+	for( int i = p2; i < l; ++i )
+		res[ i - ( p2 - p1 ) ] = txt[ i ];
+	res[ resl ] = '\0'; // Testende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( char c ) // löscht jetes c
+{
+	if( !hat( c ) ) // prüfen ob c vorhanden
+		return;
+	int l = getLänge(); // Länge des Textes
+	int anz = anzahlVon( c ); // Anzahl von c
+	char *res = new char[ l - anz + 1 ]; // neuen Text erstellen
+	int anz2 = 0;
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // Text befüllen
+	{
+		bool b = suchGCount != 0;
+		if( txt[ i ] == c && !suchGCount )
+			++anz2;
+		else
+			res[ i - anz2 ] = txt[ i ];
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( b )
+		{
+			if( txt[ i ] == c && !suchGCount )
+				++anz2;
+			else
+				res[ i - anz2 ] = txt[ i ];
+		}
+	}
+	res[ l - anz ] = '\0'; // Textende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( const char *t ) // löscht jetes t
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	int txl = getLänge(); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return;
+	if( !hat( t ) ) // prüfen ob Text ein t enthält
+		return;
+	int anz = anzahlVon( t ); // anzahl von t
+	int *begin = new int[ anz ];
+	for( int i = 0; i < anz; ++i ) // begin aller t-s finden
+		begin[ i ] = positionVon( t, i );
+	int resl = txl - ( anz * tl ); // Länge vom Ergebnes
+	char *res = new char[ resl + 1 ]; // neuen Text erzeugen
+	int del = 0;
+	for( int i = 0; i < txl; ++i ) // Text befüllen
+	{
+		if( del < anz && i == begin[ del ] ) // Text auslassen
+		{
+			i += tl - 1;
+			++del;
+		}
+		else
+			res[ i - ( del * tl ) ] = txt[ i ]; // Text befüllen
+	}
+	res[ resl ] = '\0'; // Text ende festlegen
+	setText( res ); // Text setzen
+	delete[]begin;
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( Text *t )
+{
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		löschen( t->getText() ); // löschen
+	t = t->release(); // Übergabe loslassen
+}
+
+void Text::löschen( int index, char c )
+{
+	if( index < 0 || !hat( c ) ) // Auf unsinnige übergabe prüfen
+		return;
+	int anz = anzahlVon( c ); // anzahl der i-s
+	if( index >= anz ) // prüfen ob ein i-tes c vorhanden ist
+		return;
+	int pos = positionVon( c, index ); // Position vom i-ten c
+	if( pos < 0 )
+		return;
+	int l = getLänge(); // Länge des Textes
+	if( !l )
+		return;
+	char *res = new char[ l ]; // neuen Text erzeugen
+	for( int i = 0; i < pos && i < l; ++i ) // Text befüllen
+		res[ i ] = txt[ i ];
+	for( int i = pos + 1; i < l; ++i )
+		res[ i - 1 ] = txt[ i ];
+	res[ l - 1 ] = '\0'; // Text ende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( int index, const char *t ) // löscht das i-te t
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	if( index < 0 || !hat( t ) || tl <= 0 ) // Auf unsinnige übergabe prüfen
+		return;
+	int anz = anzahlVon( t ); // anzahl der i-s
+	if( index >= anz ) // prüfen ob ein i-tes c vorhanden ist
+		return;
+	int pos = positionVon( t, index ); // Position vom i-ten c
+	if( pos < 0 )
+		return;
+	int l = getLänge(); // Länge des Textes
+	if( !l )
+		return;
+	char *res = new char[ l - tl + 1 ]; // neuen Text erzeugen
+	for( int i = 0; i < pos && i < l - tl + 1; ++i ) // Text befüllen
+		res[ i ] = txt[ i ];
+	for( int i = pos + tl; i < l; ++i )
+		res[ i - tl ] = txt[ i ];
+	res[ l - tl ] = '\0'; // Text ende festlegen
+	setText( res ); // Text setzen
+	delete[] res; // Speicher freigeben
+}
+
+void Text::löschen( int i, Text *t )
+{
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		löschen( i, t->getText() ); // löschen
+	t = t->release(); // Übergabe loslassen
+}
+
+void Text::setPräzision( int p ) // setzt die Anzahl der Nachkommastellen bei doubles
+{
+	präzision = p;
+}
+
+// constant 
+int Text::getLänge() const // gibt die Text länge zurück
+{
+	if( !txt )
+		return -1;
+	int ret = 0;
+	for( ; txt[ ret ] != '\0'; ++ret ); // zählen
+	return ret;
+}
+
+int Text::getLKick( int pos ) const
+{
+	if( txt[ pos - 1 ] == ' ' )
+	{
+		int ret = 1;
+		for( ; ret < pos && txt[ pos - ret - 1 ] == ' ' && txt[ pos - ret - 1 ] != '\n'; ++ret );
+		return pos - ret;
+	}
+	else
+	{
+		int ret = 1;
+		for( ; ret < pos && txt[ pos - ret - 1 ] != ' ' && txt[ pos - ret - 1 ] != '\n'; ++ret );
+		return pos - ret;
+	}
+}
+
+int Text::getOKick( int pos ) const
+{
+	if( !hat( '\n' ) )
+		return 0;
+	int lpos = 0;
+	while( pos - lpos - 1 > 0 && txt[ pos - lpos - 1 ] != '\n' )
+		++lpos;
+	int vllän = 1;
+	while( pos - lpos - vllän - 1 >= 0 && txt[ pos - lpos - vllän - 1 ] != '\n' )
+		++vllän;
+	if( vllän > lpos )
+		return pos - vllän;
+	else
+		return pos - lpos - 1;
+}
+
+int Text::getRKick( int pos ) const
+{
+	int tl = getLänge();
+	if( txt[ pos ] == ' ' )
+	{
+		int ret = 1;
+		for( ; ret + pos < tl && txt[ pos + ret ] == ' ' && txt[ pos + ret ] != '\n'; ++ret );
+		return pos + ret;
+	}
+	else
+	{
+		int ret = 1;
+		for( ; ret + pos < tl && txt[ pos + ret ] != ' '&& txt[ pos + ret ] != '\n'; ++ret );
+		return pos + ret;
+	}
+}
+
+int Text::getUKick( int pos ) const
+{
+	if( !hat( '\n' ) )
+		return getLänge();
+	int lpos = 0;
+	while( pos - lpos > 0 && txt[ pos - lpos - 1 ] != '\n' )
+		++lpos;
+	int llän = 1;
+	while( pos + llän - 1 < getLänge() && txt[ pos + llän - 1 ] != '\n' )
+		++llän;
+	int vllän = 1;
+	while( pos + llän + vllän - 1 < getLänge() && txt[ pos + llän + vllän - 1 ] != '\n' )
+		++vllän;
+	if( vllän == 1 )
+		return pos + llän < getLänge() ? pos + llän : getLänge();
+	if( vllän < lpos )
+		return pos + llän + vllän - 1;
+	return pos + llän + lpos;
+}
+
+bool Text::hat( Text *t ) const // enthält der Text t
+{
+	bool ret = 0;
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		ret = hat( t->getText() ); // prüfen
+	t = t->release(); // Übergabe loslassen
+	return ret;
+}
+
+bool Text::hat( const char *t ) const
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	int txl = getLänge(); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return 0;
+	int suchGCount = 0;
+	for( int i = 0; i + tl <= txl; ++i ) // Text durchsuchen
+	{
+		if( !suchGCount )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // Text überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				return 1;
+		}
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( !suchGCount )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // Text überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				return 1;
+		}
+	}
+	return 0;
+}
+
+bool Text::hat( char c ) const // enthält c
+{
+	int l = getLänge(); // Text Länge
+	bool ret = 0;
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( !suchGCount ) // überprüfen
+			ret |= txt[ i ] == c;
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( !suchGCount && b ) // überprüfen
+			ret |= txt[ i ] == c;
+	}
+	return ret;
+}
+
+bool Text::istGleich( const char *t ) const // prüft ob det Text gleich t ist
+{
+	int txl = getLänge(); // Text Länge
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	if( txl != tl ) // Auf unsinniege Übergabe prüfen
+		return 0;
+	if( txl == -1 )
+		return 1;
+	bool ret = true;
+	for( int i = 0; i < tl; ++i ) // prüfen
+		ret &= txt[ i ] == t[ i ];
+	return ret;
+}
+
+bool Text::istGleich( Text *t ) const
+{
+	bool ret = istGleich( t->getText() ); // prüfen
+	t->release(); // Übergabe loslassen
+	return ret;
+}
+
+char *Text::getText() const // gibt Text zurück
+{
+	return txt;
+}
+
+int Text::anzahlVon( char c ) const // gibt die Anzahl von c im Text zurück
+{
+	int ret = 0;
+	int l = getLänge(); // Text Länge
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		ret += txt[ i ] == c && !suchGCount; // zählen
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		ret += txt[ i ] == c && !suchGCount && b; // zählen
+	}
+	return ret;
+}
+
+int Text::anzahlVon( const char *t ) const // gibt die Anzahl von t im Text zurück
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	int txl = getLänge(); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return 0;
+	int ret = 0;
+	int suchGCount = 0;
+	for( int i = 0; i + tl <= txl; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( !suchGCount )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				++ret; // zählen
+		}
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( !suchGCount && b )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				++ret; // zählen
+		}
+	}
+	return ret;
+}
+
+int Text::anzahlVon( Text *t ) const
+{
+	int ret = 0;
+	if( t->getLänge() > 0 )  // Auf unsinnige übergabe prüfen
+		ret = anzahlVon( t->getText() ); // zählen
+	t = t->release(); // Übergabe loslassen
+	return ret;
+}
+
+int Text::positionVon( char c ) const // gibt die Position des ersten c zurück
+{
+	int l = getLänge(); // Text Länge
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( txt[ i ] == c && !suchGCount ) // überprüfen
+			return i;
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( txt[ i ] == c && !suchGCount && b ) // überprüfen
+			return i;
+	}
+	return -1;
+}
+
+int Text::positionVon( const char *t ) const // gibt die Position des ersten t zurück
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	int txl = getLänge(); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return -1;
+	int suchGCount = 0;
+	for( int i = 0; i + tl <= txl; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( !suchGCount )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				return i;
+		}
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( !suchGCount && b )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+				return i;
+		}
+	}
+	return -1;
+}
+
+int Text::positionVon( Text *t ) const
+{
+	int ret = 0;
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		ret = positionVon( t->getText() ); // position ermitteln
+	t = t->release(); // Übergabe loslassen
+	return ret;
+}
+
+int Text::positionVon( char c, int index ) const // gibt die Position des i-ten c zurück
+{
+	int l = getLänge(); // Text Länge
+	int ii = 0;
+	int suchGCount = 0;
+	for( int i = 0; i < l; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( txt[ i ] == c && !suchGCount ) // überprüfen
+		{
+			if( ii == index )
+				return i;
+			else
+				++ii;
+		}
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( txt[ i ] == c && !suchGCount && b ) // überprüfen
+		{
+			if( ii == index )
+				return i;
+			else
+				++ii;
+		}
+	}
+	return -1;
+}
+
+int Text::positionVon( const char *t, int index ) const // gibt die Position des i-ten t zurück
+{
+	int tl = (int)strlen( t ); // Länge der Übergabe
+	int txl = getLänge(); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return 0;
+	int i2 = 0;
+	int suchGCount = 0;
+	for( int i = 0; i + tl <= txl; ++i ) // suchen
+	{
+		bool b = suchGCount != 0;
+		if( !suchGCount )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+			{
+				if( i2 == index )
+					return i;
+				else
+					++i2;
+			}
+		}
+		if( txt[ i ] == suchGBeg )
+			++suchGCount;
+		if( txt[ i ] == suchGEnd )
+			--suchGCount;
+		if( !suchGCount && b )
+		{
+			bool b = 1;
+			for( int ii = 0; ii < tl; ++ii ) // überprüfen
+				b &= txt[ i + ii ] == t[ ii ];
+			if( b )
+			{
+				if( i2 == index )
+					return i;
+				else
+					++i2;
+			}
+		}
+	}
+	return -1;
+}
+
+int Text::positionVon( Text *t, int i ) const
+{
+	int ret = 0;
+	if( t->getLänge() > 0 ) // Auf unsinnige übergabe prüfen
+		ret = positionVon( t->getText(), i ); // position ermitteln
+	t = t->release(); // Übergabe loslassen
+	return ret;
+}
+
+Text *Text::getTeilText( int p1, int p2 ) const // gibt den Text von p1 bis p2 zurück
+{
+	if( p1 > p2 ) // p1 und p2 tauschen
+	{
+		int x = p1;
+		p1 = p2;
+		p2 = x;
+	}
+	int l = getLänge(); // Text Länge
+	if( p1 < 0 || p2 > l ) // Auf unsinnige übergabe prüfen
+		return new Text( "" );
+	char *cp = new char[ p2 - p1 + 1 ]; // neuen Text erstellen
+	for( int i = p1; i < p2; ++i ) // Text befüllen
+	{
+		cp[ i - p1 ] = txt[ i ];
+	}
+	cp[ p2 - p1 ] = '\0';
+	Text *t = new Text( cp ); // Text zurückgeben
+	delete[]cp;
+	return t;
+}
+
+Text *Text::getTeilText( int p ) const // gibt den Text von p bis zum Ende zurück
+{
+	return getTeilText( p, getLänge() ); // Text zurückgeben
+}
+
+// Reference Counting
+Text *Text::getThis()
+{
+	++ref;
+	return this;
+}
+
+Text *Text::release()
+{
+	--ref;
+	if( ref < 1 )
+		delete this;
+	return 0;
+}
+
+// Operatoren
+Text &Text::operator+=( const int num )
+{
+	anhängen( num );
+	return *this;
+}
+
+Text &Text::operator+=( const double num )
+{
+	anhängen( num );
+	return *this;
+}
+
+Text &Text::operator+=( const char *txt )
+{
+	anhängen( txt );
+	return *this;
+}
+
+Text &Text::operator+=( const Text &txt )
+{
+	anhängen( txt.getText() );
+	return *this;
+}
+
+Text &Text::operator=( const int num )
+{
+	setText( "" );
+	anhängen( num );
+	return *this;
+}
+
+Text &Text::operator=( const double num )
+{
+	setText( "" );
+	anhängen( num );
+	return *this;
+}
+
+Text &Text::operator=( const char *txt )
+{
+	setText( txt );
+	return *this;
+}
+
+Text &Text::operator=( const Text &txt )
+{
+	setText( txt.getText() );
+	return *this;
+}
+
+Text::operator char*( ) const
+{
+	return txt;
+}
+
+Text::operator int() const
+{
+	if( txt[ 0 ] == '0' && txt[ 1 ] == 'x' )
+		return TextZuInt( ( txt + 2 ), 16 );
+	return TextZuInt( txt, 10 );
+}
+
+Text::operator double() const
+{
+	if( txt[ 0 ] == '0' && txt[ 1 ] == 'x' )
+		return TextZuInt( ( txt + 2 ), 16 );
+	return TextZuDouble( txt );
+}
+
+bool Text::operator>( Text &t ) const
+{
+	int län1 = getLänge();
+	int län2 = t.getLänge();
+	char *txt2 = t;
+	for( int i = 0; i < län1 && i < län2; ++i )
+	{
+		if( txt[ i ] > txt2[ i ] )
+			return 1;
+		if( txt[ i ] < txt2[ i ] )
+			return 0;
+	}
+	if( län1 > län2 )
+		return 1;
+	return 0;
+}
+
+bool Text::operator<( Text &t ) const
+{
+	int län1 = getLänge();
+	int län2 = t.getLänge();
+	char *txt2 = t;
+	for( int i = 0; i < län1 && i < län2; ++i )
+	{
+		if( txt[ i ] < txt2[ i ] )
+			return 1;
+		if( txt[ i ] > txt2[ i ] )
+			return 0;
+	}
+	if( län1 < län2 )
+		return 1;
+	return 0;
+}
+
+// char* operationen
+int Framework::stringPositionVonChar( char *string, char c, int num ) // sucht die position des num-ten c-s in string, -1 bei nicht gefunden
+{
+	int gef = 0;
+	int p = 0;
+	for( char cc = *string; *string; ++string )
+	{
+		if( cc == c )
+		{
+			if( gef == num )
+				return p;
+			else
+				++gef;
+		}
+		++p;
+	}
+	return -1;
+}
+
+int Framework::stringPositionVonString( char *string, char *suche, int sBegPos ) // sucht die position von 'suche' in 'string' ab der Position 'sBegPos', -1 bei nicht gefunden
+{
+	for( int i = 0; i < sBegPos; ++i )
+	{
+		if( !*string )
+			return -1;
+		++string;
+	}
+	int tl = textLänge( suche ); // Länge der Übergabe
+	int txl = textLänge( string ); // Länge des Textes
+	if( tl <= 0 || tl > txl ) // Auf unsinnige übergabe prüfen
+		return -1;
+	for( int i = 0; i + tl <= txl; ++i ) // suchen
+	{
+		bool b = 1;
+		for( int ii = 0; ii < tl; ++ii ) // überprüfen
+			if( b )
+				b = string[ i + ii ] == suche[ ii ];
+		if( b )
+			return i + sBegPos;
+	}
+	return -1;
+}
+
+//---Andere Funktionen---
+void Framework::TextKopieren( const char *txt ) // kopiert den Text in den Zwischenspeicher
+{
+#ifdef WIN32
+	int län = textLänge( txt ) + 1;
+	if( län == 1 )
+		return;
+	HGLOBAL hMem = GlobalAlloc( GMEM_MOVEABLE, län );
+	if( !hMem )
+		return;
+	memcpy( GlobalLock( hMem ), txt, län );
+	GlobalUnlock( hMem );
+	OpenClipboard( 0 );
+	EmptyClipboard();
+	SetClipboardData( CF_TEXT, hMem );
+	CloseClipboard();
+#endif
+}
+
+char *Framework::TextEinfügen() // gibt den Text aus der Zwischenablage zurück
+{
+#ifdef WIN32
+	if( !OpenClipboard( 0 ) )
+		return "";
+	HANDLE hClipData = GetClipboardData( CF_TEXT );
+	char *cBuffer = (char*)GlobalLock( hClipData );
+	GlobalUnlock( hClipData );
+	CloseClipboard();
+	return cBuffer;
+#else
+	return 0;
+#endif
+}
+
+char Framework::KleinOrGroß( char c, bool gr )
+{
+	int ret = c;
+	if( gr )
+	{
+		if( c >= 'a' && c <= 'z' )
+			ret -= 32;
+		else
+		{
+			switch( c )
+			{
+			case '^':
+				return '°';
+			case '1':
+				return '!';
+			case '<':
+				return '>';
+			case '2':
+				return '\"';
+			case '3':
+				return '§';
+			case '4':
+				return '$';
+			case '5':
+				return '%';
+			case '6':
+				return '&';
+			case '7':
+				return '/';
+			case '8':
+				return '(';
+			case '9':
+				return ')';
+			case '0':
+				return '=';
+			case ',':
+				return ';';
+			case '.':
+				return ':';
+			case 'ß':
+				return '?';
+			case '-':
+				return '_';
+			case '´':
+				return '`';
+			case '+':
+				return '*';
+			case '#':
+				return '\'';
+			case 'ü':
+				return 'Ü';
+			case 'ö':
+				return 'Ö';
+			case 'ä':
+				return 'Ä';
+			}
+		}
+	}
+	else
+	{
+		if( c >= 'A' && c <= 'Z' )
+			ret += 32;
+		else
+		{
+			switch( c )
+			{
+			case '°':
+				return '^';
+			case '!':
+				return '1';
+			case '>':
+				return '<';
+			case '\"':
+				return '2';
+			case '§':
+				return '3';
+			case '$':
+				return '4';
+			case '%':
+				return '5';
+			case '&':
+				return '6';
+			case '/':
+				return '7';
+			case '(':
+				return '8';
+			case ')':
+				return '9';
+			case '=':
+				return '0';
+			case ';':
+				return ',';
+			case ':':
+				return '.';
+			case '?':
+				return 'ß';
+			case '_':
+				return '-';
+			case '`':
+				return '´';
+			case '*':
+				return '+';
+			case '\'':
+				return '#';
+			case 'Ü':
+				return 'ü';
+			case 'Ö':
+				return 'ö';
+			case 'Ä':
+				return 'ä';
+			}
+		}
+	}
+	return ret;
+}
+
+bool Framework::istSchreibbar( unsigned char zeichen ) // prüft, ob zeichen ein Schreibbarer Buchstabe ist
+{
+	if( zeichen > 32 && zeichen < 127 )
+		return 1;
+	if( zeichen == 128 || zeichen == 181 || zeichen == 178 || zeichen == 179 )
+		return 1;
+	if( zeichen > 191 && zeichen < 198 )
+		return 1;
+	if( zeichen > 199 && zeichen < 208 )
+		return 1;
+	if( zeichen > 209 && zeichen < 215 )
+		return 1;
+	if( zeichen > 216 && zeichen < 221 )
+		return 1;
+	if( zeichen > 222 && zeichen < 230 )
+		return 1;
+	if( zeichen > 231 && zeichen < 240 )
+		return 1;
+	if( zeichen > 241 && zeichen < 247 )
+		return 1;
+	if( zeichen > 248 && zeichen < 253 )
+		return 1;
+	if( zeichen == ' ' || zeichen == '\t' )
+		return 1;
+	return 0;
+}
+
+unsigned int Framework::TextZuInt( char *c, int system ) // Konvertiert c zu int
+{
+	if( system == 16 )
+		return strtoul( c, 0, system );
+	return strtol( c, 0, system );
+}
+
+unsigned int Framework::TextZuInt( char *c, char **c_ende, int system )
+{
+	if( system == 16 )
+		return strtoul( c, c_ende, system );
+	return strtol( c, c_ende, system );
+}
+
+double Framework::TextZuDouble( char *c ) // Konvertiert c zu double
+{
+	return strtod( c, 0 );
+}
+
+double Framework::TextZuDouble( char *c, char **c_ende )
+{
+	return strtod( c, c_ende );
+}
+
+int Framework::textLänge( const char *txt ) // gibt die Länge von txt zurück
+{
+	if( !txt )
+		return 0;
+	int ret = 0;
+	for( ; txt[ ret ] != 0; ++ret );
+	return ret;
+}

+ 353 - 0
Text.h

@@ -0,0 +1,353 @@
+#ifndef Text_H
+#define Text_H
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+    class Text; // aus dieser Datei
+
+    // Ein ersatz für String
+    class Text
+    {
+    private:
+        char *txt;
+        char suchGBeg;
+        char suchGEnd;
+        int präzision;
+        int ref;
+
+    public:
+        // Erstellt ein neues Text Objekt mit dem Wert ""
+        __declspec( dllexport ) Text();
+        // Erstellt ein neues Text Objekt indem der Wert aus (txt) kopiert wird
+        //  txt: Der Text, der kopiert werden soll
+        __declspec( dllexport ) Text( const Text &txt );
+        // Erstellt ein neues Text Objekt indem der Wert aus (txt) kopiert wird
+        //  txt: Die Zeichenkette, die kopiert werden soll
+        __declspec( dllexport ) Text( const char *txt );
+        // Erstellt ein neues Text Objekt mit einer zahl als text
+        //  zahl: Die Zahl, die im Text sein soll
+        __declspec( dllexport ) Text( int zahl );
+        // Löscht den Text
+        __declspec( dllexport ) ~Text();
+
+        // Legt die Suchgrenzen fest, die von den Suchfunktionen verwendet werden.
+        //  gBeg: Das Zeichen, bei dem die Suche beginnen soll
+        //  gEnd: Das Zeichen, bei dem die Suche enden soll
+        __declspec( dllexport ) void setSuchGrenzen( char gBeg, char gEnd );
+        // Setzt den Text, den das Zeichnung speichert
+        //  t: Eine Zeichenkette, deren Inhalt kopiert wird
+        __declspec( dllexport ) void setText( const char *t );
+        // Setzt den Text, den das Zeichnung speichert
+        //  t: Eine Zeichenkette, deren Inhalt kopiert wird
+        //  l: Die Länge des Textes, der aus (t) kopiert werden soll
+        __declspec( dllexport ) void setText( const char *t, int l );
+        // Setzt den Text, den das Zeichnung speichert
+        //  t: Das TextZeichnung, dessen Inahlt kopiert werden soll
+        __declspec( dllexport ) void setText( Text *t );
+        // Hängt eine Zeichenfolge ans Ende des Textes an, die von der Schrift Klasse beim zeichnen interpretiert wird, so dass der nachfolgende Text in einer anderen Farbe gezeichnet wird.
+        //  fc: Der Farbcode im A8R8G8B8 Format
+        __declspec( dllexport ) void farbeAnhängen( int fc );
+        // Hängt die übergebene Zahl als Hex Text (0-F) ans Ende des Textes an.
+        //  num: Die Zahl, die ins Hex System umgewandelt und angehängt werden soll
+        __declspec( dllexport ) void hexAnhängen( int num );
+        // Fügt den übergebenen Buchtaben der Zeichenkette hinzu
+        //  c: Der Buchstabe, der angehängt werden soll
+        __declspec( dllexport ) void anhängen( char c );
+        // Hängt die übergebene Zeichenkette ans Ende des Textes an
+        //  t: Die Zeichenkette, deren Kopie ans Ende des Textes angehängt werden soll
+        __declspec( dllexport ) void anhängen( const char *t );
+        // Hängt einen Teil der übergebenen Zeichenkette ans Ende des Textes an
+        //  t: Die Zeichenkette, deren Kopie angehängt werden soll
+        //  l: Die Länge des Textabschnittes der angehängt werden soll
+        __declspec( dllexport ) void anhängen( const char *t, int l );
+        // Hängt den Inhalt des eines Textes ans Ende des Textes an
+        //  t: Der Text, dessen Kopie ans Ende des Textes angehängt werden soll
+        __declspec( dllexport ) void anhängen( Text *t );
+        // Hängt eine Zahl ans Ende Des Textes an
+        //  num: Die Zahl, die in einen Text umgewandelt und am Ende angehängt werden soll
+        __declspec( dllexport ) void anhängen( int num );
+        // Hängt eine Zahl ohne Vorzeichenbit am Ende des Textes an
+        //  num: Die Zahl, die in einen Text umgewandelt und am Ende angehängt werden soll
+        __declspec( dllexport ) void anhängen( unsigned int num );
+        // Hängt eine Kommazahl am Ende des Textes an
+        //  num: Die Kommazahl, die am Ende des Textes angehängt werden soll
+        __declspec( dllexport ) void anhängen( double num );
+        // Fügt an einer Bestimmten Stelle ein Zeichen in den Text ein
+        //  p: Die position im Text bei der das Zeichen eingefügt werden soll
+        //  c: Das Zeichen, das eingefügt werden soll
+        __declspec( dllexport ) void einfügen( int p, char c );
+        // Fügt an einer Bestimmten Stelle im Text eine Zeichenkette ein
+        //  p: Die position im Text bei der die Zeichenkette eingefügt werden soll
+        //  t: Die Zeichenkette, deren Kopie an eingefügt werden soll
+        __declspec( dllexport ) void einfügen( int p, const char *t );
+        // Fügt den Inhalt eines Textes an einer Bestimmten Stelle im Text ein
+        //  p: Die Position im Text, bei der der inhalt des Textest eingefügt werden soll
+        //  t: Der Text, dessen Kopie an der Stelle eingefügt werden soll
+        __declspec( dllexport ) void einfügen( int p, Text *t );
+        // Ersetzt einen bestimmten Textabschnitt mit einer anderen Zeichenkette
+        //  p1: Die Startposition des zu ersetzenden Textabschnittes
+        //  p2: Die Endposition des zu ersetzenden Textabschnittes
+        //  t: Die Zeichenkette, die an die entsprechende Stelle kopiert werden soll
+        // Beispiel: ( "Hallo Welt" ).ersetzen( 2, 5, "lt" ); ergibt: "Halt Welt"
+        __declspec( dllexport ) void ersetzen( int p1, int p2, const char *t );
+        // Ersetzt einen bestimmten Textabschnitt mit dem Inhalt eines anderen Textes
+        //  p1: Die Startposition des zu ersetzenden Textabschnittes
+        //  p2: Die Endposition des zu ersetzenden Textabschnittes
+        //  t: Der Text, dessen Inhalt an die entsprechende Stelle kopiert werden soll
+        // Beispiel: ( "Hallo Welt" ).ersetzen( 2, 5, new Text( "lt" ) ); ergibt: "Halt Welt"
+        __declspec( dllexport ) void ersetzen( int p1, int p2, Text *t );
+        // Sucht und erstetzt jedes Vorkommen eines bestimmten Buchstaben durch einen anderen
+        //  c1: Der Buchstabe der ersetzt werden soll
+        //  c2: Der Buchstabe, durch den der Andere ersetzt werden soll
+        __declspec( dllexport ) void ersetzen( char c1, char c2 );
+        // Sucht und erstetzt jedes Vorkommen einer bestimmten Zeichenkette durch eine andere
+        //  t1: Die Zeichenkette, die ersetzt werden soll
+        //  t2: Die Zeichenkette, durch welche die Andere ersetzt werden soll
+        __declspec( dllexport ) void ersetzen( const char *t1, const char *t2 );
+        // Sucht und erstetzt jedes Vorkommen des Inhalts eines Textes durch eine andere Zeichenkette
+        //  t1: Der Text, dessen Inhalt gesucht und ersetzt wird
+        //  t2: Die Zeichenkette, durch welche das Vorkommen des Textes ersetzt werden soll
+        __declspec( dllexport ) void ersetzen( Text *t1, const char *t2 );
+        // Sucht und erstetzt jedes Vorkommen einer Zeichenkette durch den Inhalt eines Textes
+        //  t1: Die Zeichenkette, die ersetzt werden soll
+        //  t2: Der Text, dessen Inhalt das Vorkommen der Zeichenkette ersetzten soll
+        __declspec( dllexport ) void ersetzen( const char *t1, Text *t2 );
+        // Sucht und erstetzt jedes Vorkommen des Inhalts eines Textes durch den Inhalt eines anderen Textes
+        //  t1: Der Text, dessen Vorkommen ersetzt werden sollen
+        //  t2: Der Text, dessen Inhalt das Vorkommen der Zeichenkette ersetzten soll
+        __declspec( dllexport ) void ersetzen( Text *t1, Text *t2 );
+        // Ersetzt das i-te auftreten eines bestimmten Buchstaben mit einem anderen Buchstaben
+        //  i: Das wie vielte Auftreten des Buchstabens ersetzt werden soll
+        //  c1: Der Buchstabe, dessen i-tes Auftreten erstetzt werden soll
+        //  c2: Der Buchstabe, der das i-te Auftreten des anderen Buchstabens ersetzen soll
+        __declspec( dllexport ) void ersetzen( int i, char c1, char c2 );
+        // Ersetzt das i-te auftreten einer bestimmten Zeichenkette mit einer anderen Zeichenkette
+        //  i: Das wie vielte Auftreten der Zeichenkette ersetzt werden soll
+        //  c1: Die Zeichenkette, dessen i-tes Auftreten erstetzt werden soll
+        //  c2: Die Zeichenkette, die das i-te Auftreten der anderen Zeichenkette ersetzen soll
+        __declspec( dllexport ) void ersetzen( int i, const char *t1, const char *t2 );
+        // Ersetzt das i-te auftreten des Inhalts eines Textes mit einer Zeichenkette
+        //  i: Das wie vielte Auftreten des Textes ersetzt werden soll
+        //  c1: Der Text, dessen i-tes Auftreten erstetzt werden soll
+        //  c2: Die Zeichenkette, die das i-te Auftreten des Textes ersetzen soll
+        __declspec( dllexport ) void ersetzen( int i, Text *t1, const char *t2 );
+        // Ersetzt das i-te auftreten einer bestimmten Zeichenkette mit dem Inhalt eines Textes
+        //  i: Das wie vielte Auftreten der Zeichenkette ersetzt werden soll
+        //  c1: Die Zeichenkette, dessen i-tes Auftreten erstetzt werden soll
+        //  c2: Der Text, dessen Inhalt das i-te Auftreten der Zeichenkette ersetzen soll
+        __declspec( dllexport ) void ersetzen( int i, const char *t1, Text *t2 );
+        // Ersetzt das i-te auftreten eines bestimmten Textes mit dem Inhalt eines anderen Textes
+        //  i: Das wie vielte Auftreten des Textes ersetzt werden soll
+        //  c1: Der Text, dessen i-tes Auftreten erstetzt werden soll
+        //  c2: Der Text, dessen Inhalt das i-te Auftreten des anderen Textes ersetzen soll
+        __declspec( dllexport ) void ersetzen( int i, Text *t1, Text *t2 );
+        // Löscht den bisherigen Text und erzeugt einen Text, der aus einem Bestimten Buchstaben besteht, mit einer bestimmten Länge
+        //  c: Der Buchstabe, aus dem der Text bestehen soll
+        //  län: Die Länge des Textes
+        __declspec( dllexport ) void füllText( char c, int län );
+        // Löscht ein Bestimmtes Zeichen aus dem Text
+        //  p: Die Position des zu löschenden Zeichens
+        __declspec( dllexport ) void löschen( int p );
+        // Löscht einen Bestimmten Textabschnitt
+        //  p1: Die Startposition des zu löschenden Abschnittes
+        //  p2: Die Endposition des zu löschenden Abschnittes (Das Zeichen bei p2 bleibt erhalten)
+        __declspec( dllexport ) void löschen( int p1, int p2 );
+        // Löscht jedes Vorkommen eines bestimmten Buchsaben
+        //  c: Der Buchstabe, dessen Vorkommen gelöscht werden soll
+        __declspec( dllexport ) void löschen( char c );
+        // Löscht jedes Vorkommen einer bestimmten Zeichenkette
+        //  t: Die Zeichenkette, deren Vorkommen entfernt werden sollen
+        __declspec( dllexport ) void löschen( const char *t );
+        // Löscht jedes Vorkommen des Inhalts eines Textes
+        //  t: Der text, dessen Inhalt gelöscht werden soll
+        __declspec( dllexport ) void löschen( Text *t );
+        // Löscht das i-te Vorkommen eines bestimmten Buchstaben
+        //  i: Das wie vielte Vorkommen des Buchstabens gelöscht werden soll
+        //  c: Der Buchstabe, dessen i-tes Vorkommen gelöscht werden soll
+        __declspec( dllexport ) void löschen( int i, char c );
+        // Löscht das i-te Vorkommen einer bestimmten Zechenkette
+        //  i: Das wie vielte Vorkommen der Zeichenkette gelöscht werden soll
+        //  t: Die Zeichenkette, dessen i-tes Vorkommen gelöscht werden soll
+        __declspec( dllexport ) void löschen( int i, const char *t );
+        // Löscht das i-te Vorkommen eines bestimmten Textinhaltes
+        //  i: Das wie vielte Vorkommen des Textinhaltes gelöscht werden soll
+        //  t: Der Text, dessen i-tes Vorkommen gelöscht werden soll
+        __declspec( dllexport ) void löschen( int i, Text *t );
+        // Setzt die Anzahl der Nachkommastellen beim Anhängen von Kommazahlen
+        //  p: Die Anzahl der Stellen nach dem Komma
+        __declspec( dllexport ) void setPräzision( int p );
+
+        // Gibt die Länge des Textes zurück
+        __declspec( dllexport ) int getLänge() const;
+        // Ermittelt die neue Curserposition nachdem Drücken der 'Links' Pfeiltaste
+        //  pos: Die alte Curserposition
+        __declspec( dllexport ) int getLKick( int pos ) const;
+        // Ermittelt die neue Curserposition nachdem Drücken der 'Oben' Pfeiltaste
+        //  pos: Die alte Curserposition
+        __declspec( dllexport ) int getOKick( int pos ) const;
+        // Ermittelt die neue Curserposition nachdem Drücken der 'Rechts' Pfeiltaste
+        //  pos: Die alte Curserposition
+        __declspec( dllexport ) int getRKick( int pos ) const;
+        // Ermittelt die neue Curserposition nachdem Drücken der 'Unten' Pfeiltaste
+        //  pos: Die alte Curserposition
+        __declspec( dllexport ) int getUKick( int pos ) const;
+        // Überprüft, ob im Text der Inhalt eines anderen Textes vorkommt
+        //  t: Der Text, nach dessen Inhalt gesucht werden soll
+        //  return: (true), wenn der Inhalt des Textes vorkommt. (false) sonnst
+        __declspec( dllexport ) bool hat( Text *t ) const;
+        // Überprüft, ob im Text eine bestimmte Zeichenkette vorkommt
+        //  t: Die Zeichenkette, nach der gesucht werden soll
+        //  return: (true), wenn die Zeichenkette vorkommt. (false) sonnst
+        __declspec( dllexport ) bool hat( const char *t ) const;
+        // Überprüft, ob im Text ein bestimmtes Zeichen vorkommt
+        //  c: Das Zeichen, nach dem gesucht werden soll
+        //  return: (true), wenn das Zeichen vorkommt. (false) sonnst
+        __declspec( dllexport ) bool hat( char c ) const;
+        // Überprft, ob der Text den selben Inhalt wie eine Zeichenkette hat
+        //  t: Die Zeichenkette, die verglichen werden soll
+        //  return: (true), wenn der Inhalt des Textes gleich der Zeichenkette ist. (false) sonst
+        __declspec( dllexport ) bool istGleich( const char *t ) const;
+        // Überprft, ob der Text den selben Inhalt wie ein anderer Text hat
+        //  t: Der Text, dessen Inhalt verglichen werden soll
+        //  return: (true), wenn die Inhalte der Texte übereinstimmen. (false) sonst
+        __declspec( dllexport ) bool istGleich( Text *t ) const;
+        // Gibt den Inhalt des Textes als Zeichenkette zurück
+        __declspec( dllexport ) char *getText() const;
+        // Zählt, wie oft ein bestimmter Buchstabe im Text vorkomt
+        //  c: Der Buchstabe, der gezählt werden soll
+        //  return: Die Anzahl des Buchstabens im Text
+        __declspec( dllexport ) int anzahlVon( char c ) const;
+        // Zählt, wie oft eine bestimmte Zeichenkette im Text vorkommt
+        //  t: Die Zeichenkette, die gezählt werden soll
+        //  return: Die Anzahl der Zeichenkette im Text
+        __declspec( dllexport ) int anzahlVon( const char *t ) const;
+        // Zählt, wie oft der Inhalt eines Textest im Text vorkommt
+        //  t: Der Text, dessen Inhalt gezählt werden soll
+        //  return: Die Anzahl des Textinhaltes im Text
+        __declspec( dllexport ) int anzahlVon( Text *t ) const;
+        // Gibt die erste Position eines bestimmten Buchstabens im Text zurück
+        //  c: Der Buchstabe, der gefunden werden soll
+        //  return: Die Position des ersten Vorkommens des Buchstabens
+        __declspec( dllexport ) int positionVon( char c ) const;
+        // Gibt die erste Position einer bestimmten Zeichenkette im Text zurück
+        //  t: Die Zeichenkette, die gefunden werden soll
+        //  return: Die Position des ersten Vorkommens der Zeichenkette
+        __declspec( dllexport ) int positionVon( const char *t ) const;
+        // Gibt die erste Position eines Textinhaltes im Text zurück
+        //  t: Der Text, dessen Inhalt gefunden werden soll
+        //  return: Die Position des ersten Vorkommens des Textinhaltes
+        __declspec( dllexport ) int positionVon( Text *t ) const;
+        // Gibt die i-te Position eines bestimmten Buchstabens im Text zurück
+        //  c: Der Buchstabe, der gefunden werden soll
+        //  i: Das wievielte Vorkommen gefunden werden soll
+        //  return: Die Position des i-ten Vorkommens des Buchstabens
+        __declspec( dllexport ) int positionVon( char c, int i ) const;
+        // Gibt die i-te Position einer bestimmten Zeichenkette im Text zurück
+        //  t: Die Zeichenkette, die gefunden werden soll
+        //  i: Das wievielte Vorkommen gefunden werden soll
+        //  return: Die Position des i-ten Vorkommens der Zeichenkette
+        __declspec( dllexport ) int positionVon( const char *t, int i ) const;
+        // Gibt die i-te Position eines Textinhaltes im Text zurück
+        //  t: Der Text, dessen Inhalt gefunden werden soll
+        //  i: Das wievielte Vorkommen gefunden werden soll
+        //  return: Die Position des i-ten Vorkommens des Textinhaltes
+        __declspec( dllexport ) int positionVon( Text *t, int i ) const;
+        // Gibt einen Text zurück, der eine Kopie eines bestimmten Textabschnittes enthält
+        //  p1: Die Startposition des Textabschnittes
+        //  p2: Die Endposition des Textabschnittes (nicht enthalten)
+        __declspec( dllexport ) Text *getTeilText( int p1, int p2 ) const;
+        // Gibt einen Text zurück, der eine Kopie eines bestimmten Textabschnittes enthält
+        //  p1: Die Startposition des Textabschnittes (Der Textabschnitt geht bis ans Ende des Textes)
+        __declspec( dllexport ) Text *getTeilText( int p ) const;
+
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Text *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Text *release();
+
+        // Hängt eine Zahl ans Ende des Textes an
+        __declspec( dllexport ) Text &operator+=( const int num );
+        // Hängt eine Kommazahl ans Ende des Textes an
+        __declspec( dllexport ) Text &operator+=( const double num );
+        // Hängt eine Zeichenkette ans Ende des Textes an
+        __declspec( dllexport ) Text &operator+=( const char *txt );
+        // Hängt eine Kopie des Inhalts eines Textes ans Ende des Textes an
+        __declspec( dllexport ) Text &operator+=( const Text &txt );
+        // Setzt den Inhalt des Textes gleich einer Zahl
+        __declspec( dllexport ) Text &operator=( const int num );
+        // Setzt den Inhalt des Textes gleich einer Kommazahl
+        __declspec( dllexport ) Text &operator=( const double num );
+        // Setzt den Inahlt des Textes gleich einer Zeichenkette
+        __declspec( dllexport ) Text &operator=( const char *txt );
+        // Setzt den Inhalt des Textes gleich einer Kopie des Inhalts eines anderen Textes
+        __declspec( dllexport ) Text &operator=( const Text &txt );
+        // Gibt den Inhalt des Textes als Zeichenkette zurück
+        __declspec( dllexport ) operator char*( ) const;
+        // Konviertiert den Inhalt des Textes zu einer Zahl
+        __declspec( dllexport ) operator int() const;
+        // Konviertiert den Inhalt des Textes zu einer Kommazahl
+        __declspec( dllexport ) operator double() const;
+        // Prüft, ob der Inhalt des Textes nach alphabetischer Ordnung später kommt als der Inhalt eines anderen Textes
+        __declspec( dllexport ) bool operator>( Text &t ) const;
+        // Prüft, ob der Inhalt des Textes nach alphabetischer Ordnung früher kommt als der Inhalt eines anderen Textes
+        __declspec( dllexport ) bool operator<( Text &t ) const;
+    };
+
+    // Durchsucht eine Zeichenkette nach dem num-ten Vorkommen eines bestimmten Buchstabens
+    //  string: Die zu durchsuchende Zeichenkette
+    //  c: Der zu suchende Buchstabe
+    //  num: Das wievielte Vorkommen des Buchtaben gefunden werden soll
+    //  return: (-1), wenn es kein num-tes Vorkommen des Buchstaben gibt. Sonst die Position des num-ten Vorkommens in der Zeichenkette
+    __declspec( dllexport ) int stringPositionVonChar( char *string, char c, int num ); // sucht die position des num-ten c-s in string, -1 bei nicht gefunden
+    // Durchsucht eine Zeichenkette nach einer Anderen Zeichenkette
+    //  string: Die zu durchsuchende Zeichenkette
+    //  suche: Die Zeichenkette, nach der gesucht werden soll
+    //  sBegPos: Die Position, ab der die Suche begonnen werden soll
+    //  return: Die Position, an der die zu suchende Zeichenkette erstmals gefunden wurde. (-1) Wenn nichts gefunden wurde.
+    __declspec( dllexport ) int stringPositionVonString( char *string, char *suche, int sBegPos );
+
+    // Kopiert eine bestimmte Zeichenkette in die Zwischenablage des Betriebssystems
+    //  txt: Die Zeichenkette, die kopiert werden soll
+    __declspec( dllexport ) void TextKopieren( const char *txt );
+    // Ermittelt, ob in der Zwischenablage des Betriebssystems eine Zeichenkette steht.
+    //  return: Die Zeichenkette aus der Zwischenablage. Wenn keine Zeichenkette kopiert wurde, wird eine lehre Zeichenkette zurückgegeben.
+    __declspec( dllexport ) char *TextEinfügen();
+    // Wandelt einen bestimmten schreibbaren Buchstaben in einen Groß- oder Kleinbuchstaben um
+    //  c: Der Buchstabe, der umgewandelt werden soll
+    //  groß: Wenn (true), so wird der Buchstabe in einen Großbuchstaben umgewandelt. Wenn (false), wird er in einen Kleinbuchstaben umgewandelt.
+    //  return: Den umgewandelten Buchstaben
+    __declspec( dllexport ) char KleinOrGroß( char c, bool groß );
+    // Ermittelt, ob ein Buchstabe ein schreibbares Zeichen ist
+    //  zeichen: Der Buchstabe, der geprüft werden soll
+    //  return: (true), wenn der Buchstabe gezeichnet werden kann. (false) sonnst
+    __declspec( dllexport ) bool istSchreibbar( unsigned char zeichen );
+    // Konvertiert eine Zahl aus einer Zeichenkette in belibiger Basis zu einer Zahl
+    //  c: Die Zeichenkette, in der Die Zahl steht
+    //  system: Die Basis der Zahl
+    //  return: Die Zahl, die im Text stand
+    __declspec( dllexport ) unsigned int TextZuInt( char *c, int system );
+    // Konvertiert eine Zahl aus einer Zeichenkette in belibiger Basis zu einer Zahl
+    //  c: Die Zeichenkette, in der Die Zahl steht
+    //  c_ende: Wird duch die Funktion gesetzt und darf 0 sein. Zeigt auf das nächste Zeichen in der Zeichenkette, das nach der Zah steht
+    //  system: Die Basis der Zahl
+    //  return: Die Zahl, die im Text stand
+    __declspec( dllexport ) unsigned int TextZuInt( char *c, char **c_ende, int system );
+    // Konvertiert eine Zeichenkette zu einem Double
+    //  c: Die Zeichenkette, die konvertiert werden soll
+    //  return: Das double, was in der Zeichenkette stand
+    __declspec( dllexport ) double TextZuDouble( char *c );
+    // Konvertiert eine Zeichenkette zu einem Double
+    //  c: Die Zeichenkette, die konvertiert werden soll
+    //  c_ende: Wird duch die Funktion gesetzt und darf 0 sein. Ein Zeiger auf das nächste Zeichen nach dem Double in der Zeichenkette
+    //  return: Das double, was in der Zeichenkette stand
+    __declspec( dllexport ) double TextZuDouble( char *c, char **c_ende );
+    // Ermittelt die Länge einer bestimmten Zeichenkette
+    //  txt: Die Zeichenkette, deren Länge ermittelt werden soll
+    //  return: Die Länge der Zeichenkette
+    __declspec( dllexport ) int textLänge( const char *txt );
+}
+#endif

+ 842 - 0
TextFeld.cpp

@@ -0,0 +1,842 @@
+#include "TextFeld.h"
+#include "Schrift.h"
+#include "Text.h"
+#include "AlphaFeld.h"
+#include "Rahmen.h"
+#include "Bild.h"
+#include "TastaturEreignis.h"
+#include "MausEreignis.h"
+#include "Fenster.h"
+#include "Scroll.h"
+#include <math.h>
+#include "Globals.h"
+#include "ToolTip.h"
+#include "Scroll.h"
+
+using namespace Framework;
+
+// Inhalt der TextFeld Klasse aus TextFeld.h 
+// Konstruktor 
+TextFeld::TextFeld()
+    : ZeichnungHintergrund(),
+    schriftGröße( 12 ),
+    schrift( 0 ),
+    text( 0 ),
+    sF( 0xFF000000 ),
+    showChar( 0 ),
+    begf( 0 ),
+    cpos( 0 ),
+    tickVal( 0 ),
+    mausKlick( 0 ),
+    ref( 1 )
+{
+    horizontalScrollBar = new HScrollBar();
+    vertikalScrollBar = new VScrollBar();
+    style = 0;
+    this->setMausEreignis( _ret1ME );
+    this->setTastaturEreignis( _ret1TE );
+}
+
+// Destruktor 
+TextFeld::~TextFeld()
+{
+    if( schrift )
+        schrift->release();
+    if( text )
+        text->release();
+}
+
+// nicht constant 
+void TextFeld::setText( Text *txt ) // setzt den angezeigten Text
+{
+    lockZeichnung();
+    if( !text )
+        text = new Text();
+    text->setText( txt );
+    if( hatStyle( Style::VScroll ) )
+        updateVScroll();
+    if( hatStyle( Style::HScroll ) )
+        updateHScroll();
+    unlockZeichnung();
+    rend = 1;
+}
+
+void TextFeld::setTextZ( Text *txt ) // setzt einen Zeiger zum angezeigten Text
+{
+    lockZeichnung();
+    if( text )
+        text->release();
+    text = txt;
+    if( hatStyle( Style::VScroll ) )
+        updateVScroll();
+    if( hatStyle( Style::HScroll ) )
+        updateHScroll();
+    rend = 1;
+    unlockZeichnung();
+}
+
+void TextFeld::setText( const char *txt ) // setzt den angezeigten Text
+{
+    lockZeichnung();
+    if( !text )
+        text = new Text();
+    text->setText( txt );
+    if( hatStyle( Style::VScroll ) )
+        updateVScroll();
+    if( hatStyle( Style::HScroll ) )
+        updateHScroll();
+    rend = 1;
+    unlockZeichnung();
+}
+
+void TextFeld::addZeile( const char *zeile ) // fügt Zeile An
+{
+    if( text )
+    {
+        Text *txt = new Text( zeile );
+        txt->anhängen( "\n" );
+        if( schrift )
+        {
+            bool vs = vertikalScrollBar && hatStyle( Style::VScroll );
+            int rbr = ( rahmen && hatStyle( Style::Rahmen ) ) ? rahmen->getRBreite() : 0;
+            schrift->lock();
+            schrift->setSchriftGröße( schriftGröße );
+            schrift->textFormatieren( txt, gr.x - ( (int)vs * 15 ) - rbr * 2, schriftGröße );
+            schrift->unlock();
+        }
+        lockZeichnung();
+        text->anhängen( txt->getText() );
+        unlockZeichnung();
+        txt->release();
+        if( hatStyle( Style::VScroll ) )
+            updateVScroll();
+        if( hatStyle( Style::HScroll ) )
+            updateHScroll();
+        rend = 1;
+    }
+}
+
+void TextFeld::setAuswahl( int pos1, int pos2 ) // setzt den Ausgewählten Text
+{
+    cpos = pos1;
+    begf = pos2;
+    rend = 1;
+}
+
+void TextFeld::setAuswahl( Punkt &auswahl )
+{
+    cpos = auswahl.x;
+    begf = auswahl.y;
+    rend = 1;
+}
+
+void TextFeld::setSchriftZ( Schrift *schrift ) // setzt einen Zeiger zur Schrift
+{
+    if( this->schrift )
+        this->schrift->release();
+    this->schrift = schrift;
+    rend = 1;
+}
+
+void TextFeld::setSchriftGröße( unsigned char gr ) // setzt die Schriftgröße
+{
+    schriftGröße = gr;
+    rend = 1;
+}
+
+void TextFeld::setSchriftFarbe( int fc ) // setzt die Schrift Farbe
+{
+    sF = fc;
+    rend = 1;
+}
+
+void TextFeld::setSchowChar( unsigned char c ) // bei Passwortfeld *
+{
+    showChar = c;
+    rend = 1;
+}
+
+void TextFeld::setVScrollZuZeile( int zeile ) // scrollt zur Zeile
+{
+    if( vertikalScrollBar && schrift && text && hatStyle( Style::Mehrzeilig ) )
+    {
+        schrift->lock();
+        schrift->setSchriftGröße( schriftGröße );
+        Text t = "a";
+        vertikalScrollBar->scroll( zeile * ( schrift->getZeilenabstand() + schrift->getTextHöhe( &t ) ) );
+        schrift->unlock();
+        rend = 1;
+    }
+}
+
+void TextFeld::updateVScroll( int pos ) // scrollt nach unten
+{
+    if( pos == -1 )
+        pos = cpos;
+    if( vertikalScrollBar )
+    {
+        int sPos = 0;
+        int hö = 0;
+        if( text && schrift )
+        {
+            if( hatStyleNicht( Style::Mehrzeilig ) )
+                text->löschen( '\n' );
+            schrift->setSchriftGröße( schriftGröße );
+            hö = gr.y;
+            if( hatStyle( Style::Rahmen ) && rahmen )
+                hö -= rahmen->getRBreite() * 2;
+            if( hatStyle( Style::HScroll ) && horizontalScrollBar )
+                hö -= 15;
+            vertikalScrollBar->update( schrift->getTextHöhe( text ) + schriftGröße + schrift->getTextHöhe( &Text( "a" ) ), hö );
+            Text t;
+            int zh = schrift->getTextHöhe( &t ) + schrift->getZeilenabstand();
+            int l = text->getLänge();
+            for( int i = 0; i < l && ( i < pos || hatStyleNicht( Style::Erlaubt ) ); ++i )
+            {
+                if( text->getText()[ i ] == '\n' )
+                    sPos += zh;
+            }
+        }
+        if( schrift )
+        {
+            if( sPos - schrift->getZeilenabstand() - schrift->getTextHöhe( &Text( "a" ) ) < vertikalScrollBar->getScroll() )
+                vertikalScrollBar->scroll( sPos - schrift->getZeilenabstand() - schrift->getTextHöhe( &Text( "a" ) ) );
+            if( sPos + schrift->getZeilenabstand() + schrift->getTextHöhe( &Text( "a" ) ) > vertikalScrollBar->getScroll() + vertikalScrollBar->getScrollData()->anzeigeHöhe )
+                vertikalScrollBar->scroll( sPos + ( schrift->getZeilenabstand() + schrift->getTextHöhe( &Text( "a" ) ) ) * 2 - hö );
+        }
+        rend = 1;
+    }
+}
+
+void TextFeld::updateHScroll( int pos ) // scrollt zur Curser Position
+{
+    if( pos == -1 )
+        pos = cpos;
+    if( horizontalScrollBar && text && schrift )
+    {
+        schrift->lock();
+        schrift->setSchriftGröße( schriftGröße );
+        int br = gr.x;
+        if( hatStyle( Style::Rahmen ) && rahmen )
+            br -= rahmen->getRBreite() * 2;
+        if( hatStyle( Style::VScroll ) && vertikalScrollBar )
+            br -= 15;
+        int maxBr = schrift->getTextBreite( text ) + schriftGröße;
+        horizontalScrollBar->update( maxBr, br );
+        if( hatStyle( Style::Erlaubt ) && maxBr > br && pos > 0 && pos < text->getLänge() )
+        {
+            int l = text->getLänge();
+            int p1 = 0;
+            char *tmp = text->getText();
+            for( int i = 0; i < pos; i++, tmp++ )
+            {
+                if( *tmp == '\n' )
+                    p1 = i + 1;
+            }
+            Text *t = text->getTeilText( p1, pos );
+            int cbr = schrift->getTextBreite( t );
+            t->release();
+            if( cbr + schriftGröße > horizontalScrollBar->getScroll() + horizontalScrollBar->getScrollData()->anzeigeBreite )
+                horizontalScrollBar->scroll( cbr + schriftGröße - br );
+            if( cbr - schriftGröße < horizontalScrollBar->getScroll() )
+                horizontalScrollBar->scroll( cbr - schriftGröße );
+        }
+        schrift->unlock();
+    }
+}
+
+bool TextFeld::tick( double tickval ) // tick
+{
+    if( hatStyle( Style::Fokus ) )
+    {
+        if( tickVal < 0.5 && tickVal + tickval >= 0.5 )
+            rend = 1;
+        if( tickVal >= 0.5 && tickVal + tickval >= 1 )
+            rend = 1;
+        tickVal += tickval;
+        if( tickVal >= 1 )
+            tickVal -= 1;
+    }
+    return __super::tick( tickval );
+}
+
+void TextFeld::doMausEreignis( MausEreignis &me ) // Maus Ereignis
+{
+    bool nmakc = !me.verarbeitet;
+    if( hatStyleNicht( Style::Erlaubt ) || hatStyleNicht( Style::Sichtbar ) )
+    {
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        me.mx -= pos.x, me.my -= pos.y;
+        int rbr = 0;
+        if( rahmen )
+            rbr = rahmen->getRBreite();
+        if( ( vertikalScrollBar && hatStyle( Style::VScroll ) ||
+              horizontalScrollBar && hatStyle( Style::HScroll ) ) &&
+            me.mx > rbr && me.mx < gr.x - rbr &&
+            me.my > rbr && me.my < gr.y - rbr )
+        {
+            vertikalScrollBar->doMausMessage( gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me );
+            horizontalScrollBar->doMausMessage( rbr, gr.y - rbr * 2 - 15, gr.x - rbr * 2 - ( ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? 15 : 0 ), 15, me );
+            me.verarbeitet = 1;
+        }
+        me.mx += pos.x, me.my += pos.y;
+        mausKlick = 0;
+        return;
+    }
+    bool removeFokus = 0;
+    if( me.verarbeitet || !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+            return;
+        }
+        removeFokus = 1;
+    }
+    if( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt )
+    {
+        if( removeFokus && me.id == ME_RLinks )
+        {
+            me.mx -= pos.x, me.my -= pos.y;
+            if( hatStyle( Style::Fokus ) && Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+                löscheStyle( Style::Fokus );
+            if( nmakc && me.verarbeitet && nMak )
+                me.verarbeitet = nMak( nmakParam, this, me );
+            me.mx += pos.x, me.my += pos.y;
+        }
+        if( toolTip )
+            toolTip->setMausIn( 0 );
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak && ( me.verarbeitet || Mak( makParam, this, me ) ) )
+    {
+        if( removeFokus && me.id == ME_RLinks )
+            löscheStyle( Style::Fokus );
+        if( !me.verarbeitet )
+        {
+            if( hatStyleNicht( Style::Fokus ) )
+            {
+                mausKlick = 0;
+                if( me.id == Framework::ME_PLinks )
+                    addStyle( Style::Fokus );
+            }
+            int rbr = 0;
+            if( rahmen )
+                rbr = rahmen->getRBreite();
+            if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+            {
+                if( vertikalScrollBar->doMausMessage( gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me ) )
+                {
+                    if( nmakc && me.verarbeitet && nMak )
+                        me.verarbeitet = nMak( nmakParam, this, me );
+                    me.mx += pos.x, me.my += pos.y;
+                    return;
+                }
+            }
+            if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+            {
+                if( horizontalScrollBar->doMausMessage( rbr, gr.y - rbr - 15, gr.x - rbr * 2 - ( ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? 15 : 0 ), 15, me ) )
+                {
+                    if( nmakc && me.verarbeitet && nMak )
+                        me.verarbeitet = nMak( nmakParam, this, me );
+                    me.mx += pos.x, me.my += pos.y;
+                    return;
+                }
+            }
+            if( me.mx < gr.x - rbr - 15 )
+            {
+                if( schrift )
+                {
+                    schrift->setSchriftGröße( schriftGröße );
+                    bool shift = TastenStand[ T_Shift ];
+                    if( me.id == Framework::ME_PLinks )
+                    {
+                        int tbr = schrift->getTextBreite( text );
+                        int thö = schrift->getTextHöhe( text );
+                        int scrollHö = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScroll() : 0;
+                        int scrollBr = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0;
+                        int xxx = me.mx - rbr + scrollBr;
+                        int yyy = me.my - rbr + scrollHö;
+                        int scrollBreite = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) * 15;
+                        int scrollHöhe = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) * 15;
+                        if( hatStyle( Style::HCenter ) )
+                            xxx -= ( ( ( gr.x - scrollBreite ) / 2 ) - tbr / 2 ) - rbr;
+                        if( hatStyle( Style::VCenter ) && hatStyleNicht( Style::VScroll ) )
+                            yyy -= ( ( ( gr.y - scrollHö ) / 2 ) - thö / 2 ) - rbr;
+                        int pos = schrift->textPos( text, xxx, yyy );
+                        if( pos != -1 )
+                        {
+                            if( shift )
+                                begf = pos;
+                            else
+                            {
+                                cpos = pos;
+                                begf = pos;
+                            }
+                            rend = 1;
+                            if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                                updateVScroll( begf );
+                            if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                                updateHScroll( begf );
+                        }
+                        mausKlick = 1;
+                    }
+                    if( me.id == ME_Bewegung && mausKlick )
+                    {
+                        int tbr = schrift->getTextBreite( text );
+                        int thö = schrift->getTextHöhe( text );
+                        int scrollHö = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScroll() : 0;
+                        int scrollBr = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0;
+                        int xxx = me.mx - rbr + scrollBr;
+                        int yyy = me.my - rbr + scrollHö;
+                        int scrollBreite = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) * 15;
+                        int scrollHöhe = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) * 15;
+                        if( hatStyle( Style::HCenter ) )
+                            xxx -= ( ( ( gr.x - scrollBreite ) / 2 ) - tbr / 2 ) - rbr;
+                        if( hatStyle( Style::VCenter ) && hatStyleNicht( Style::VScroll ) )
+                            yyy -= ( ( ( gr.y - scrollHöhe ) / 2 ) - thö / 2 ) - rbr;
+                        int pos = schrift->textPos( text, xxx, yyy );
+                        if( pos != -1 )
+                        {
+                            if( begf != pos )
+                                rend = 1;
+                            begf = pos;
+                            if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                                updateVScroll( begf );
+                            if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                                updateHScroll( begf );
+                        }
+                    }
+                    if( me.id == ME_RLinks )
+                    {
+                        if( !shift )
+                        {
+                            int tbr = schrift->getTextBreite( text );
+                            int thö = schrift->getTextHöhe( text );
+                            int scrollHö = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) ? vertikalScrollBar->getScroll() : 0;
+                            int scrollBr = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) ? horizontalScrollBar->getScroll() : 0;
+                            int xxx = me.mx - rbr + scrollBr;
+                            int yyy = me.my - rbr + scrollHö;
+                            int scrollBreite = ( vertikalScrollBar && hatStyle( Style::VScroll ) ) * 15;
+                            int scrollHöhe = ( horizontalScrollBar && hatStyle( Style::HScroll ) ) * 15;
+                            if( hatStyle( Style::HCenter ) )
+                                xxx -= ( ( ( gr.x - scrollBreite ) / 2 ) - tbr / 2 ) - rbr;
+                            if( hatStyle( Style::VCenter ) && hatStyleNicht( Style::VScroll ) )
+                                yyy -= ( ( ( gr.y - scrollHöhe ) / 2 ) - thö / 2 ) - rbr;
+                            int pos = schrift->textPos( text, xxx, yyy );
+                            if( pos != -1 )
+                            {
+                                begf = pos;
+                                if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+                                    updateVScroll( begf );
+                                if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+                                    updateHScroll( begf );
+                            }
+                            rend = 1;
+                        }
+                        mausKlick = 0;
+                    }
+                }
+            }
+        }
+        me.verarbeitet = 1;
+    }
+    if( nmakc && me.verarbeitet && nMak )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x, me.my += pos.y;
+}
+
+void TextFeld::doTastaturEreignis( TastaturEreignis &te )
+{
+    bool ntakc = !te.verarbeitet;
+    if( te.verarbeitet || hatStyleNicht( Style::Fokus ) )
+        return;
+    if( !Tak )
+        return;
+    ++ref;
+    if( Tak( takParam, this, te ) )
+    {
+        if( hatStyleNicht( Style::Erlaubt ) )
+        {
+            --ref;
+            if( !ref )
+                delete this;
+            return;
+        }
+        if( te.id == TE_Press )
+        {
+            bool shift = TastenStand[ T_Shift ];
+            bool strg = TastenStand[ T_Strg ];
+            switch( te.taste )
+            {
+            case T_Entf:
+                if( cpos != begf )
+                    text->löschen( cpos, begf );
+                else
+                    text->löschen( cpos, cpos + 1 );
+                begf = cpos;
+                rend = 1;
+                break;
+            case T_BackSpace:
+                if( cpos != begf )
+                {
+                    text->löschen( cpos, begf );
+                    if( cpos > begf )
+                        cpos -= cpos - begf;
+                }
+                else
+                {
+                    text->löschen( cpos - 1, cpos );
+                    --cpos;
+                }
+                begf = cpos;
+                rend = 1;
+                break;
+            case T_Enter:
+                if( cpos != begf )
+                {
+                    text->löschen( begf, cpos );
+                    if( cpos > begf )
+                        cpos -= cpos - begf;
+                }
+                text->einfügen( cpos, '\n' );
+                ++cpos;
+                begf = cpos;
+                rend = 1;
+                break;
+            case T_Links:
+                if( shift )
+                {
+                    if( strg )
+                        begf = text->getLKick( begf );
+                    else
+                        --begf;
+                }
+                else
+                {
+                    if( strg )
+                        cpos = text->getLKick( cpos );
+                    else
+                        --cpos;
+                    begf = cpos;
+                }
+                rend = 1;
+                break;
+            case T_Oben:
+                if( shift )
+                {
+                    begf = text->getOKick( begf );
+                }
+                else
+                {
+                    cpos = text->getOKick( cpos );
+                    begf = cpos;
+                }
+                rend = 1;
+                break;
+            case T_Rechts:
+                if( shift )
+                {
+                    if( strg )
+                        begf = text->getRKick( begf );
+                    else
+                        ++begf;
+                }
+                else
+                {
+                    if( strg )
+                        cpos = text->getRKick( cpos );
+                    else
+                        ++cpos;
+                    begf = cpos;
+                }
+                rend = 1;
+                break;
+            case T_Unten:
+                if( shift )
+                {
+                    begf = text->getUKick( begf );
+                }
+                else
+                {
+                    cpos = text->getUKick( cpos );
+                    begf = cpos;
+                }
+                rend = 1;
+                break;
+            default:
+                if( strg && te.id == TE_Press )
+                {
+                    if( te.taste == 'c' || te.taste == 'C' )
+                    {
+                        if( begf != cpos )
+                        {
+                            int län = begf - cpos;
+                            if( län < 0 )
+                                län = -län;
+                            char *txt = new char[ län + 1 ];
+                            txt[ län ] = 0;
+                            int beg = begf < cpos ? begf : cpos;
+                            for( int i = beg; i < beg + län; ++i )
+                                txt[ i - beg ] = text->getText()[ i ];
+                            TextKopieren( txt );
+                            delete[] txt;
+                        }
+                        else
+                            TextKopieren( text->getText() );
+                    }
+                    if( te.taste == 'v' || te.taste == 'V' )
+                    {
+                        if( begf != cpos )
+                        {
+                            text->löschen( begf, cpos );
+                            if( cpos > begf )
+                                cpos = begf;
+                        }
+                        char *txt = TextEinfügen();
+                        text->einfügen( cpos, txt );
+                        cpos += textLänge( txt );
+                        begf = cpos;
+                        rend = 1;
+                    }
+                    break;
+                }
+                if( istSchreibbar( te.taste ) )
+                {
+                    if( begf != cpos )
+                    {
+                        text->löschen( begf, cpos );
+                        if( cpos > begf )
+                            cpos = begf;
+                    }
+                    text->einfügen( cpos, (char)te.taste );
+                    ++cpos;
+                    begf = cpos;
+                    rend = 1;
+                }
+                break;
+            }
+        }
+        if( cpos < 0 )
+            cpos = 0;
+        if( cpos > text->getLänge() )
+            cpos = text->getLänge();
+        if( begf < 0 )
+            begf = 0;
+        if( begf > text->getLänge() )
+            begf = text->getLänge();
+        if( hatStyle( Style::VScroll ) )
+            updateVScroll( begf );
+        if( hatStyle( Style::HScroll ) )
+            updateHScroll( begf );
+        te.verarbeitet = 1;
+    }
+    --ref;
+    if( ntakc && te.verarbeitet && nTak )
+        te.verarbeitet = nTak( ntakParam, this, te );
+    if( !ref )
+        delete this;
+}
+
+void TextFeld::render( Bild &zRObj ) // zeichenet nach zRObj
+{
+    if( hatStyleNicht( Style::Sichtbar ) )
+        return;
+    __super::render( zRObj );
+    if( !text || !schrift )
+        return;
+    lockZeichnung();
+    if( !zRObj.setDrawOptions( innenPosition, innenGröße ) )
+    {
+        unlockZeichnung();
+        return;
+    }
+    if( hatStyleNicht( Style::Mehrzeilig ) )
+        text->löschen( '\n' );
+    if( hatStyleNicht( Style::Mehrfarbig ) )
+    {
+        while( text->hat( '\r' ) )
+            text->löschen( text->positionVon( '\r' ), text->positionVon( '\r' ) + 11 );
+    }
+    schrift->setSchriftGröße( schriftGröße );
+    int tbr = schrift->getTextBreite( text );
+    int thö = schrift->getTextHöhe( text );
+    int xxx = 0;
+    int yyy = 0;
+    int breite = innenGröße.x;
+    int höhe = innenGröße.y;
+    bool hs = horizontalScrollBar && hatStyle( Style::HScroll );
+    bool vs = vertikalScrollBar && hatStyle( Style::VScroll );
+    if( vs )
+        yyy -= vertikalScrollBar->getScroll();
+    if( hs )
+        xxx -= horizontalScrollBar->getScroll();
+    if( hatStyle( Style::HCenter ) && !hs )
+        xxx = ( breite / 2 ) - tbr / 2;
+    if( hatStyle( Style::VCenter ) && !vs )
+        yyy = ( höhe / 2 ) - thö / 2;
+    schrift->setDrawPosition( xxx, yyy );
+    if( hatStyle( Style::Fokus ) && hatStyle( Style::Erlaubt ) )
+    {
+        if( istSchreibbar( showChar ) )
+        {
+            Text rt;
+            int län = text->getLänge() - text->anzahlVon( '\n' ) - text->anzahlVon( '\r' ) * 11;
+            rt.füllText( showChar, län );
+            if( tickVal <= 0.5 )
+                schrift->renderText( &rt, zRObj, cpos, 0xFFFF5555, begf, 0xFF0000FF, sF );
+            else
+                schrift->renderText( &rt, zRObj, cpos, 0x00000000, begf, 0xFF0000FF, sF );
+        }
+        else
+        {
+            if( tickVal <= 0.5 )
+                schrift->renderText( text, zRObj, cpos, 0xFFFF5555, begf, 0xFF0000FF, sF );
+            else
+                schrift->renderText( text, zRObj, cpos, 0x00000000, begf, 0xFF0000FF, sF );
+        }
+    }
+    else
+    {
+        if( istSchreibbar( showChar ) )
+        {
+            Text rt;
+            int län = text->getLänge() - text->anzahlVon( '\n' ) - text->anzahlVon( '\r' ) * 11;
+            rt.füllText( showChar, län );
+            schrift->renderText( &rt, zRObj, sF );
+        }
+        else
+            schrift->renderText( text, zRObj, sF );
+    }
+    zRObj.releaseDrawOptions();
+    unlockZeichnung();
+}
+
+// Konstant 
+Text *TextFeld::getText() const // gibt vom Text zurück
+{
+    if( !text )
+        return 0;
+    return text->getThis();
+}
+
+Text *TextFeld::zText() const // gibt den Text zurück
+{
+    return text;
+}
+
+Schrift *TextFeld::getSchrift() const// gint getThis der Schrift Zurück
+{
+    if( !schrift )
+        return 0;
+    return schrift->getThis();
+}
+
+Schrift *TextFeld::zSchrift() const// gibt die Schrift zurück
+{
+    return schrift;
+}
+
+unsigned char TextFeld::getSchriftGröße() const // gibt die Schriftgröße zurück
+{
+    return schriftGröße;
+}
+
+int TextFeld::getSchriftFarbe() const// gibt getThis der Schriftfarbe zurück
+{
+    return sF;
+}
+
+unsigned char TextFeld::getShowChar() const // gibt den Anzeige Char zurück
+{
+    return showChar;
+}
+
+int TextFeld::getCursorPos() const
+{
+    return cpos;
+}
+
+int TextFeld::getFärbungPos() const
+{
+    return begf;
+}
+
+Zeichnung *TextFeld::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+    TextFeld *obj = new TextFeld();
+    obj->setPosition( pos );
+    obj->setGröße( gr );
+    obj->setMausEreignisParameter( makParam );
+    obj->setTastaturEreignisParameter( takParam );
+    obj->setMausEreignis( Mak );
+    obj->setTastaturEreignis( Tak );
+    if( toolTip )
+        obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+    obj->setStyle( style );
+    obj->setSchriftGröße( schriftGröße );
+    if( schrift )
+        obj->setSchriftZ( schrift->getThis() );
+    if( text )
+        obj->setText( text->getText() );
+    obj->setHintergrundFarbe( hintergrundFarbe );
+    obj->setSchriftFarbe( sF );
+    if( hintergrundFeld )
+        obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+    if( rahmen )
+        obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+    if( hintergrundBild )
+        obj->setHintergrundBild( hintergrundBild->getThis() );
+    if( vertikalScrollBar )
+    {
+        obj->setVertikalKlickScroll( vertikalScrollBar->getKlickScroll() );
+        obj->setVertikalScrollPos( vertikalScrollBar->getScroll() );
+        obj->setVertikalScrollFarbe( vertikalScrollBar->getFarbe(), vertikalScrollBar->getBgFarbe() );
+    }
+    if( horizontalScrollBar )
+    {
+        obj->setHorizontalKlickScroll( horizontalScrollBar->getKlickScroll() );
+        obj->setHorizontalScrollPos( horizontalScrollBar->getScroll() );
+        obj->setHorizontalScrollFarbe( horizontalScrollBar->getFarbe(), horizontalScrollBar->getBgFarbe() );
+    }
+    obj->setSchowChar( showChar );
+    obj->setAuswahl( begf, cpos );
+    return obj;
+}
+
+// Reference Counting 
+TextFeld *TextFeld::getThis()
+{
+    ++ref;
+    return this;
+}
+
+TextFeld *TextFeld::release()
+{
+    --ref;
+    if( ref == 0 )
+        delete this;
+    return 0;
+}

+ 135 - 0
TextFeld.h

@@ -0,0 +1,135 @@
+#ifndef TextFeld_H
+#define TextFeld_H
+
+#include "Zeichnung.h"
+
+namespace Framework
+{
+	class Schrift; // Schrift.h
+	class Text; // Text.h
+	class AlphaFeld; // AlphaFeld.h
+	class LRahmen; // Rahmen.h
+	class TextFeld; // aus dieser Datei
+	class VScrollBar; // Scroll.h
+    class HScrollBar; // Scroll.h
+
+    // Verwaltet ein Textfeld
+	class TextFeld : public ZeichnungHintergrund
+	{
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            const static __int64 Mehrzeilig = 0x001000; // Wenn dieser Flag nicht gesetzt wird, werden alle Zeilenumbrüche automatisch aus dem Text entfernt
+            const static __int64 HCenter = 0x002000; // Wenn dieser Flag gesetzt wird, wird der Text genau in der horizontaen Mitte des Feldes plaziert
+            const static __int64 VCenter = 0x004000; // Wenn dieser Flag gesetzt wird, wird der Text genau in der vertikalen Mitte des Feldes plaziert
+            const static __int64 Mehrfarbig = 0x008000; // Wenn dieser Flag gesetzt wird, kann der Text mehrfarbig sein. Die Textfarbe wird im Text selbst gesetzt mit "\r0xAARRGGBB"
+
+            const static __int64 Center = HCenter | VCenter; // Vereint die Flags HCenter und VCenter
+            const static __int64 TextFeld = Sichtbar | Erlaubt | Rahmen | Buffered | VCenter; // Vereint die Flags Sichtbar, Erlaubt, Rahmen, Buffered, VCenter
+            const static __int64 Text = Sichtbar | Mehrfarbig | Mehrzeilig; // Vereint die Flags Sichtbar, Mehrfarbig, Mehrzeilig
+            const static __int64 TextGebiet = Sichtbar | Erlaubt | Rahmen | Hintergrund | Mehrfarbig | Mehrzeilig | VScroll; // Vereint die Flags Sichtbar, Erlaubt, Rahmen, Hintergrund, Mehrzeilig, Mehrfarbig, VScroll
+            const static __int64 Scroll = VScroll | HScroll; // Vereint die Flags VScroll und HScroll
+        };
+	private:
+		unsigned char schriftGröße;
+		Schrift *schrift;
+		Text *text;
+		int sF;
+		unsigned char showChar;
+		int begf, cpos;
+		double tickVal;
+		bool mausKlick;
+    protected:
+		int ref;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) TextFeld();
+		// Destruktor 
+		__declspec( dllexport ) ~TextFeld();
+		// setzt einen Zeiger auf den Text im Textfeld
+        //  txt: Der Zeiger auf den Text
+		__declspec( dllexport ) void setTextZ( Text *txt );
+        // setzt den Text des Textfeldes
+        //  txt: der Text
+        __declspec( dllexport ) void setText( Text *txt );
+        // setzt den Text des Textfeldes
+        //  txt: der Text
+        __declspec( dllexport ) void setText( const char *txt );
+        // Fügt eine Zeile an den Text an
+        //  zeile: Die neue Zeile
+		__declspec( dllexport ) void addZeile( const char *zeile );
+        // Setzt den ausgewählten textabschnitt fest (benötigt Flag zum Zeichnen: Erlaubt, Fokus)
+        //  pos1: Die Cursorposition im Text
+        //  pos2: Die Position im Text, bis zu der der Text eingefärbt werden soll
+		__declspec( dllexport ) void setAuswahl( int pos1, int pos2 );
+        // Setzt den ausgewählten textabschnitt fest (benötigt Flag zum Zeichnen: Erlaubt, Fokus)
+        //  auswahl: Ein punkt mit x als Cursorposition und y als der Position, bis zu der der Text eingefärbt werden soll
+        __declspec( dllexport ) void setAuswahl( Punkt &auswahl );
+        // Setzt einen Zeiger zur Schrift
+        //  schrift: Die Schrift, die zum Textzeichnen verwendet werden soll.
+		__declspec( dllexport ) void setSchriftZ( Schrift *schrift );
+        // Setzt die Schriftgröße (Standart: 12)
+        //  gr: Die Schriftgröße, die zum Textzeichnen verwendet werden soll
+		__declspec( dllexport ) void setSchriftGröße( unsigned char gr );
+        // Setzt die Schrift Farbe
+        //  fc: Die Farbe, die zum Textzeichnen verwendet werden soll
+		__declspec( dllexport ) void setSchriftFarbe( int fc );
+        // Legt einen Buchstaben fest, der zum zeichnen verwendet werden soll, unabhängig vom Text des Textfeldes (benötigt Flag zum Zeichnen: Rahmen)
+        //  c: Der Buchstabe, der gezeichnet werden soll
+        // Beispiel: setShowChar( '*' ); Bei Passwort Textfeldern
+		__declspec( dllexport ) void setSchowChar( unsigned char c );
+        // Scrollt zu einer bestimmten Zeile (benötigt Flag zum Zeichnen: VScroll)
+        //  zeile: Der Index der Zeile, die als oberste Zeile zu sehen sein soll
+		__declspec( dllexport ) void setVScrollZuZeile( int zeile );
+        // Scrollt zu einer bestimmten Position im Text. Ohne den Flag Erlaubt wrd immer ganz nach unten gescrollt. (benötigt Flag zum Zeichnen: VScroll)
+        //  pos: Der Index des Zeichens, zu dem gescrollt werden soll. Standartmäßig wird zur Cursorposition gescrollt
+		__declspec( dllexport ) void updateVScroll( int pos = -1 );
+        // Scrollt zu einer bestimmten Position im Text. Benötigt den Flag Erlaubt. (benötigt Flag zum Zeichnen: HScroll)
+        //  pos: Der Index des Zeichens, zu dem gescrollt werden soll. Standartmäßig wird zur Cursorposition gescrollt
+		__declspec( dllexport ) void updateHScroll( int pos = -1 );
+        // Aktualisiert das Objekt. Wird vom Framework aufgerufen
+        //  tickVal: Die Zeit in sekunden, die seit dem lezten Aufruf dieser Funktion vergangen ist
+        //  return: 1, wenn sich etwas verändert hat und das Bild neu gezeichnet werden muss. 0 sonst
+		__declspec( dllexport ) virtual bool tick( double tickval ) override;
+        // Verarbeitet Maus Nachrichten
+        //  me: Das Ereignis, was durch die Mauseingabe ausgelößt wurde
+		__declspec( dllexport ) virtual void doMausEreignis( MausEreignis &me ) override;
+        // Verarbeitet Tastatur Nachrichten
+        //  me: Das Ereignis, was durch die Tastatureingabe ausgelößt wurde
+		__declspec( dllexport ) void doTastaturEreignis( TastaturEreignis &te ) override;
+        // Zeichnet das Objekt nach zRObj, falls er sichtbar ist
+        //  zRObj: Das Bild, in welches gezeichnet werden soll
+		__declspec( dllexport ) virtual void render( Bild &zRObj ) override;
+		// Gibt den Text aus dem Textfeld zurück
+		__declspec( dllexport ) Text *getText() const;
+        // Gibt den Text aus dem Textfeld ohne erhöhten Reference Counter zurück
+		__declspec( dllexport ) Text *zText() const;
+        // Gibt die Schrift zurück.
+        //  return: 0, falls die Schrift nicht gesetzt wurde
+		__declspec( dllexport ) Schrift *getSchrift() const;
+        // Gibt die Schrift ohne erhöhten Reference Counter zurük
+        //  return: 0, falls die Schrift nicht gesetzt wurde
+		__declspec( dllexport ) Schrift *zSchrift() const;
+        // Gibt die Schriftgröße zurück
+		__declspec( dllexport ) unsigned char getSchriftGröße() const;
+        // Gibt die Schriftfarbe im A8R8G8B8 Format zurück
+		__declspec( dllexport ) int getSchriftFarbe() const;
+        // Gibt den Anzeigebuchstabe zurück
+        __declspec( dllexport ) unsigned char getShowChar() const;
+        // Gibt die Cursorposition zurück
+        __declspec( dllexport ) int getCursorPos() const;
+        // Gibt den Index des Buchstaben zurück, con dem an der Text bis zur Cursorposition eingefärbt ist
+        __declspec( dllexport ) int getFärbungPos() const;
+        // Erzeugt eine Komplette Kopie des Textfeldes, welches ohne auswirkungen verändert werden kann
+		__declspec( dllexport ) Zeichnung *dublizieren() const override;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) virtual TextFeld *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Objekt automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) virtual TextFeld *release();
+	};
+}
+#endif

+ 154 - 0
Textur.cpp

@@ -0,0 +1,154 @@
+#include "Textur.h"
+#include "Bild.h"
+#include "Render3D.h"
+#include <d3d11.h>
+
+using namespace Framework;
+
+
+// Inhalt der Textur Klasse
+// Konstruktor
+Textur::Textur()
+{
+    bild = 0;
+    txt = 0;
+    view = 0;
+    lastGr = Punkt( 0, 0 );
+    id = -1;
+    ref = 1;
+}
+
+// Destruktor
+Textur::~Textur()
+{
+    if( bild )
+        bild->release();
+    if( txt )
+        txt->Release();
+    if( view )
+        view->Release();
+}
+
+// Setzt einen Zeiger auf das Bild, welches die Textur enthält
+//  b: Der Zeiger auf das Bild
+void Textur::setBildZ( Bild *b )
+{
+    if( bild )
+        bild->release();
+    bild = b;
+}
+
+// Setzt das Bild welches die Textur enthält, indem es kopiert wird
+//  b: Das Bild, was kopiert werden soll
+void Textur::setBild( Bild *b )
+{
+    if( !b )
+        return;
+    if( !bild || bild->getBreite() != b->getBreite() || bild->getHöhe() != b->getHöhe() )
+    {
+        if( !bild )
+            bild = new Bild();
+        bild->neuBild( b->getBreite(), b->getHöhe(), 0 );
+    }
+    bild->drawBild( 0, 0, bild->getBreite(), bild->getHöhe(), *b );
+    b->release();
+}
+
+// Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
+//  zRObj: Das Objekt, mit dem die Graphikkarte angesprochen wird
+bool Textur::updateTextur( Render3D *zRObj )
+{
+    if( !bild )
+        return 0;
+    if( !txt || lastGr != bild->getGröße() )
+    {
+        if( txt )
+            txt->Release();
+        txt = 0;
+        D3D11_TEXTURE2D_DESC bufferDesc;
+        memset( &bufferDesc, 0, sizeof( D3D11_TEXTURE2D_DESC ) );
+        bufferDesc.ArraySize = 1;
+        bufferDesc.Width = bild->getBreite();
+        bufferDesc.Height = bild->getHöhe();
+        bufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+        bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.SampleDesc.Count = 1;
+        bufferDesc.MipLevels = 1;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        HRESULT r = zRObj->zDevice()->CreateTexture2D( &bufferDesc, 0, &txt );
+        if( r != S_OK  )
+            return 0;
+    }
+    D3D11_MAPPED_SUBRESOURCE buffer;
+    zRObj->zContext()->Map( txt, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &buffer );
+    int *bgBuff = bild->getBuffer();
+    int tmpBr = 4 * bild->getBreite();
+    for( int y = 0, pitch = 0, bry = 0; y < bild->getHöhe(); ++y, pitch += buffer.RowPitch, bry += bild->getBreite() )
+        memcpy( &( (BYTE *)buffer.pData )[ pitch ], (void*)&( bgBuff[ bry ] ), tmpBr );
+    zRObj->zContext()->Unmap( txt, 0 );
+    if( !view || lastGr != bild->getGröße() )
+    {
+        if( view )
+            view->Release();
+        view = 0;
+        D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesk;
+        memset( &resourceDesk, 0, sizeof( D3D11_SHADER_RESOURCE_VIEW_DESC ) );
+        resourceDesk.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+        resourceDesk.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+        resourceDesk.Texture2D.MipLevels = 1;
+        HRESULT r = zRObj->zDevice()->CreateShaderResourceView( txt, &resourceDesk, &view );
+        if( r != S_OK )
+            return 0;
+    }
+    lastGr = bild->getGröße();
+    return 1;
+}
+
+// Gibt true zurük, wenn updateTextur aufgerufen werden muss
+bool Textur::brauchtUpdate() const
+{
+    return !view;
+}
+
+// Gibt einen Zeiger auf das Bild zurück
+Bild *Textur::getBild() const
+{
+    return bild ? bild->getThis() : 0;
+}
+
+// Gibt einen Zeiger auf das Bild ohne erhöhten Reference Counter zurück
+Bild *Textur::zBild() const
+{
+    return bild;
+}
+
+// Gibt die Id der Textur zurück, wenn sie in einer TexturList registriert wurde. (siehe Framework::zTexturRegister())
+int Textur::getId() const
+{
+    return id;
+}
+
+// Gibt die verwendtete Shader Resource View zurück
+Textur::operator ID3D11ShaderResourceView*( ) const
+{
+    return view;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Textur *Textur::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Textur *Textur::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 58 - 0
Textur.h

@@ -0,0 +1,58 @@
+#pragma once
+
+#include "Punkt.h"
+
+struct ID3D11Texture2D;
+struct ID3D11ShaderResourceView;
+
+namespace Framework
+{
+    class Bild; // Bild.h
+    class Render3D; // Render3D.h
+    class TexturList; // TexturList.h
+
+    // Wandelt ein Bild in eine Textur um, die an die Grafikkarte zum rendern übergeben werden kann
+    class Textur
+    {
+    private:
+        Bild *bild;
+        ID3D11Texture2D *txt;
+        ID3D11ShaderResourceView *view;
+        Punkt lastGr;
+        int id;
+        int ref;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Textur();
+        // Destruktor
+        __declspec( dllexport ) ~Textur();
+        // Setzt einen Zeiger auf das Bild, welches die Textur enthält
+        //  b: Der Zeiger auf das Bild
+        __declspec( dllexport ) void setBildZ( Bild *b );
+        // Setzt das Bild welches die Textur enthält, indem es kopiert wird
+        //  b: Das Bild, was kopiert werden soll
+        __declspec( dllexport ) void setBild( Bild *b );
+        // Aktualisiert die Textur. Die Pixel des aktuellen Bildes werden in den Graphikspeicher kopiert
+        //  zRObj: Das Objekt, mit dem die Graphikkarte angesprochen wird
+        __declspec( dllexport ) bool updateTextur( Render3D *zRObj );
+        // Gibt true zurük, wenn updateTextur aufgerufen werden muss
+        __declspec( dllexport ) bool brauchtUpdate() const;
+        // Gibt einen Zeiger auf das Bild zurück
+        __declspec( dllexport ) Bild *getBild() const;
+        // Gibt einen Zeiger auf das Bild ohne erhöhten Reference Counter zurück
+        __declspec( dllexport ) Bild *zBild() const;
+        // Gibt die Id der Textur zurück, wenn sie in einer TexturList registriert wurde. (siehe Framework::zTexturRegister())
+        __declspec( dllexport ) int getId() const;
+        // Gibt die verwendtete Shader Resource View zurück
+        __declspec( dllexport ) operator ID3D11ShaderResourceView*() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Textur *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Textur *release();
+
+        friend TexturList;
+    };
+}

+ 189 - 0
TexturList.cpp

@@ -0,0 +1,189 @@
+#include "TexturList.h"
+#include "Textur.h"
+#include "Text.h"
+
+using namespace Framework;
+
+int TexturList::id = 0;
+CRITICAL_SECTION TexturList::cs;
+
+// Inhalt der TexturList Klasse
+// Konstruktor
+TexturList::TexturList()
+{
+    textures = new RCArray< Textur >();
+    names = new RCArray< Text >();
+    ref = 1;
+}
+
+// Destruktor
+TexturList::~TexturList()
+{
+    textures->release();
+    names->release();
+}
+
+// Fügt der Liste eine Textur hinzu
+//  t: Die Textur
+//  name: Der name, unter dem die Textur in der Liste gespeichert wird
+bool TexturList::addTextur( Textur *t, const char *name )
+{
+    EnterCriticalSection( &cs );
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            t->release();
+            LeaveCriticalSection( &cs );
+            return 0;
+        }
+    }
+    t->id = id++;
+    textures->add( t );
+    names->add( new Text( name ) );
+    LeaveCriticalSection( &cs );
+    return 1;
+}
+
+// Entfernt eine Textur aus der Liste
+//  name: Der Name der Textur
+void TexturList::löscheTextur( const char *name )
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            names->lösche( index );
+            textures->lösche( index );
+            LeaveCriticalSection( &cs );
+            return;
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+}
+
+// Überprüft, ob unter einem bestimmten Namen eine Textur abgespeichert wurde
+//  name: Der Name
+//  return: true, wenn eine Textur mit dem Namen existiert
+bool TexturList::hatTextur( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return 1;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt eine bestimmte Textur zurück
+//  name: Der Name der Textur
+Textur *TexturList::getTextur( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return textures->get( index );
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt eine bestimmte Textur zurück
+//  id: Die Id der Textur
+Textur *TexturList::getTextur( int id ) const
+{
+    EnterCriticalSection( &cs );
+    for( auto i = textures->getArray(); i.set; i++ )
+    {
+        if( i.var->getId() == id )
+        {
+            LeaveCriticalSection( &cs );
+            return i.var->getThis();
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt eine bestimmte Textur ohne erhöhten Reference Counter zurück
+//  name: Der Name der Textur
+Textur *TexturList::zTextur( const char *name ) const
+{
+    EnterCriticalSection( &cs );
+    int index = 0;
+    for( auto i = names->getArray(); i.set; i++ )
+    {
+        if( i.var->istGleich( name ) )
+        {
+            LeaveCriticalSection( &cs );
+            return textures->z( index );
+        }
+        index++;
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Gibt eine bestimmte Textur ohne erhöhten Reference Counter zurück
+//  id: Die Id der Textur
+Textur *TexturList::zTextur( int id ) const
+{
+    EnterCriticalSection( &cs );
+    for( auto i = textures->getArray(); i.set; i++ )
+    {
+        if( i.var->getId() == id )
+        {
+            LeaveCriticalSection( &cs );
+            return i.var;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return 0;
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+TexturList *TexturList::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+TexturList *TexturList::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// statische Funktionen
+
+// Initialisiert statische private member. Wird vom Framework automatisch aufgerufen.
+void TexturList::init()
+{
+    id = 0;
+    InitializeCriticalSection( &cs );
+}
+
+// Löscht statische private member. Wird vom Framework automatisch aufgerufen.
+void TexturList::destroy()
+{
+    DeleteCriticalSection( &cs );
+}

+ 58 - 0
TexturList.h

@@ -0,0 +1,58 @@
+#pragma once
+
+#include "Array.h"
+
+namespace Framework
+{
+    class Textur; // Textur.h
+
+    // Verwaltet alle geladenen Texturdaten, so dass mehrere Zeichnungen die selben Daten benutzen können
+    class TexturList
+    {
+    private:
+        static int id;
+        static CRITICAL_SECTION cs;
+        RCArray< Textur > *textures;
+        RCArray< Text > *names;
+        int ref;
+
+    public:
+        // Konstruktor
+        TexturList();
+        // Destruktor
+        ~TexturList();
+        // Fügt der Liste eine Textur hinzu
+        //  t: Die Textur
+        //  name: Der name, unter dem die Textur in der Liste gespeichert wird
+        __declspec( dllexport ) bool addTextur( Textur *t, const char *name );
+        // Entfernt eine Textur aus der Liste
+        //  name: Der Name der Textur
+        __declspec( dllexport ) void löscheTextur( const char *name );
+        // Überprüft, ob unter einem bestimmten Namen eine Textur abgespeichert wurde
+        //  name: Der Name
+        //  return: true, wenn eine Textur mit dem Namen existiert
+        __declspec( dllexport ) bool hatTextur( const char *name ) const;
+        // Gibt eine bestimmte Textur zurück
+        //  name: Der Name der Textur
+        __declspec( dllexport ) Textur *getTextur( const char *name ) const;
+        // Gibt eine bestimmte Textur zurück
+        //  id: Die Id der Textur
+        __declspec( dllexport ) Textur *getTextur( int id ) const;
+        // Gibt eine bestimmte Textur ohne erhöhten Reference Counter zurück
+        //  name: Der Name der Textur
+        __declspec( dllexport ) Textur *zTextur( const char *name ) const;
+        // Gibt eine bestimmte Textur ohne erhöhten Reference Counter zurück
+        //  id: Die Id der Textur
+        __declspec( dllexport ) Textur *zTextur( int id ) const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) TexturList *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) TexturList *release();
+        // Initialisiert statische private member. Wird vom Framework automatisch aufgerufen.
+        static void init();
+        // Löscht statische private member. Wird vom Framework automatisch aufgerufen.
+        static void destroy();
+    };
+}

+ 149 - 0
Thread.cpp

@@ -0,0 +1,149 @@
+#include "Thread.h"
+#include "Globals.h"
+
+using namespace Framework;
+
+// inhalt der Thread Klasse aus Thread.h
+// Konstruktor 
+Thread::Thread()
+{
+    thRegister->add( this );
+#ifdef WIN32
+	threadHandle = 0;
+	threadId = 0;
+#endif
+	run = 0;
+}
+
+// Destruktor 
+Thread::~Thread()
+{
+    thRegister->remove( this );
+#ifdef WIN32
+    if( GetCurrentThreadId() == GetThreadId( threadHandle ) )
+        return;
+#else
+    if( pthread_self() == threadHandle )
+        return;
+#endif
+    if( run )
+        warteAufThread( 100000 );
+    if( run )
+        ende();
+}
+
+// nicht constant 
+void Thread::start() // startet den Thread
+{
+	if( !run )
+	{
+#ifdef WIN32
+		threadHandle = CreateThread( 0, 0, threadStart, this, 0, &threadId );
+#else
+		pthread_create( &threadHandle, NULL, threadStart, this );
+#endif
+	}
+	run = 1;
+}
+#ifdef WIN32
+void Thread::pause() // pausiert den Thread
+{
+	if( run )
+		SuspendThread( threadHandle );
+	run = 0;
+}
+
+void Thread::fortsetzen() // pausiert den Thread
+{
+	if( !run )
+		ResumeThread( threadHandle );
+	run = 1;
+}
+#endif
+void Thread::ende() // beendet den Thread
+{
+	if( run )
+	{
+#ifdef WIN32
+#pragma warning(suppress: 6258)
+		TerminateThread( threadHandle, 0 );
+#else
+		pthread_cancel( threadHandle );
+#endif
+	}
+	run = 0;
+}
+
+void Thread::thread() // Thread
+{
+}
+
+void Thread::threadEnd()
+{
+    run = 0;
+}
+
+// constant 
+bool Thread::läuft() const // prüft, ob der Thrad aktiv ist
+{
+	return run;
+}
+
+int Thread::warteAufThread( int zeit ) const // wartet zeit lang auf den Thread
+{
+#ifdef WIN32
+	if( !run )
+		return WAIT_OBJECT_0;
+	if( GetCurrentThreadId() == GetThreadId( threadHandle ) )
+		return WAIT_OBJECT_0;
+	return WaitForSingleObject( threadHandle, zeit );
+#else
+	if( !run )
+		return 0;
+	return pthread_join( threadHandle, 0 );
+#endif
+}
+
+#ifdef WIN32
+void *Thread::getThreadHandle() const
+{
+	return threadHandle;
+}
+#endif
+
+// funktionen 
+#ifdef WIN32
+unsigned long __stdcall Framework::threadStart( void *param )
+{
+    if( istThreadOk( (Thread *)param ) )
+        ( (Thread *)param )->thread();
+    if( istThreadOk( ( Thread *)param ) )
+        ( (Thread *)param )->threadEnd();
+	return 0;
+}
+#else
+void *Framework::threadStart( void *param )
+{
+	pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, 0 );
+	( (Thread *)param )->thread();
+    ( (Thread *)param )->threadEnd();
+	pthread_exit( 0 );
+	return 0;
+}
+#endif
+
+// Inhalt der ThreadRegister Klasse aus Thread.h
+void ThreadRegister::add( Thread *t )
+{
+    threads.add( t );
+}
+
+void ThreadRegister::remove( Thread *t )
+{
+    threads.lösche( threads.getWertIndex( t ) );
+}
+
+bool ThreadRegister::isThread( Thread *t ) const
+{
+    return threads.hat( threads.getWertIndex( t ) );
+}

+ 74 - 0
Thread.h

@@ -0,0 +1,74 @@
+#ifndef Thread_H
+#define Thread_H
+
+#include "Array.h"
+
+namespace Framework
+{
+	class Thread;
+
+    // Ein neuer Thread wie die Thread Klasse aus Java
+	class Thread
+	{
+	protected:
+#ifdef WIN32
+		void *threadHandle;
+		unsigned long threadId;
+#else
+		pthread_t threadHandle;
+#endif
+		bool run;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Thread();
+		// Destruktor 
+		__declspec( dllexport ) ~Thread();
+		// Startet den neuen Thread 
+		__declspec( dllexport ) void start();
+#ifdef WIN32
+        // Pausiert den Thread (Nur für Windows)
+		__declspec( dllexport ) void pause();
+        // Setzt den Thread Fort (Nur für Windows)
+		__declspec( dllexport ) void fortsetzen();
+#endif
+        // Beendet den Thread
+		__declspec( dllexport ) void ende();
+        // Diese Funktion wird von dem neuen Thread ausgeführt.
+		__declspec( dllexport ) virtual void thread();
+        // Diese Funktion wird eufgerufen, nachdem die thread Funktion zuende ist
+        __declspec( dllexport ) virtual void threadEnd();
+        // prüft, ob der Thrad aktiv ist
+        // return: true, falls der Thread läuft. 
+        //         false, wenn der Thread beendet, pausiert oder noch nicht gestartet wurde.
+		__declspec( dllexport ) bool läuft() const;
+        // wartet zeit lang auf den Thread
+        // zeit: Die Zeit, die auf den Thread gewartet werden soll. 1000 = 1 Sekunde
+		__declspec( dllexport ) int warteAufThread( int zeit ) const;
+#ifdef WIN32
+        // Gibt ein Handle auf den Thread zurück (Nur für Windows)
+		__declspec( dllexport ) void *getThreadHandle() const;
+#endif
+	};
+
+#ifdef WIN32
+    // Diese Funktion wird fon der Thread Klasse benutzt um einen thread zu starten
+	__declspec( dllexport ) unsigned long __stdcall threadStart( void *param ); 
+#else
+    // Diese Funktion wird fon der Thread Klasse benutzt um einen thread zu starten
+	void *threadStart( void *param ); // startet thread
+#endif
+
+    class ThreadRegister
+    {
+    private:
+        Array< Thread* > threads;
+
+    public:
+        void add( Thread *t );
+        void remove( Thread *t );
+        bool isThread( Thread *t ) const;
+    };
+}
+
+#endif

+ 190 - 0
ToolTip.cpp

@@ -0,0 +1,190 @@
+#include "ToolTip.h"
+#include "TextFeld.h"
+#include "Text.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include "MausEreignis.h"
+#include "Schrift.h"
+#include "Bildschirm.h"
+
+using namespace Framework;
+
+// Inhalt der ToolTip Klasse aus ToolTip.h
+// Konstruktor
+ToolTip::ToolTip( Bildschirm *zScreen )
+    : TextFeld(),
+    größe( 0, 0 ),
+    animationSpeed( 250 ),
+    warten( 1 ),
+    wartenCount( 0 ),
+    tval( 0 ),
+    mausIn( 0 ),
+    alpha( 0 ),
+    sichtbar( 0 ),
+    bildschirm( zScreen ),
+    zeichnen( 0 )
+{
+    bildschirm->addToolTip( ( ToolTip* )this->getThis() );
+}
+
+// Destruktor
+ToolTip::~ToolTip()
+{}
+
+// nicht constant
+void ToolTip::setGröße( int breite, int höhe )
+{
+    größe.x = breite;
+    größe.y = höhe;
+    rend = 1;
+}
+
+void ToolTip::setGröße( Punkt &gr )
+{
+    größe = gr;
+    rend = 1;
+}
+
+void ToolTip::setWarten( double warten )
+{
+    this->warten = warten;
+}
+
+void ToolTip::setAnimationSpeed( double speed )
+{
+    animationSpeed = speed;
+}
+
+void ToolTip::setMausIn( bool mausIn )
+{
+    if( this->mausIn != mausIn )
+        rend = 1;
+    this->mausIn = mausIn;
+    if( !mausIn )
+        sichtbar = 0;
+}
+
+void ToolTip::wartenReset()
+{
+    wartenCount = 0;
+}
+
+void ToolTip::setZeichnen()
+{
+    zeichnen = 1;
+}
+
+bool ToolTip::tick( double tickVal )
+{
+    this->tval += tickVal * animationSpeed;
+    int val = ( int )this->tval;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    this->tval -= val;
+    if( !sichtbar )
+    {
+        if( alpha )
+        {
+            if( alpha - val < 0 )
+                alpha = 0;
+            else
+                alpha -= val;
+            rend = 1;
+        }
+        if( mausIn )
+        {
+            wartenCount += tickVal;
+            if( wartenCount >= warten )
+            {
+                sichtbar = 1;
+                wartenCount = 0;
+                alpha = 0xFF;
+                __super::setGröße( 0, 0 );
+            }
+        }
+        else
+            wartenCount = 0;
+    }
+    else
+    {
+        if( getBreite() != größe.x )
+        {
+            __super::setGröße( getBreite() + val, getSchriftGröße() + getLinienRahmenBreite() * 2 );
+            if( getBreite() > größe.x )
+                __super::setGröße( größe.x, getHöhe() );
+            rend = 1;
+        }
+        else if( getHöhe() != größe.y )
+        {
+            __super::setGröße( getBreite(), getHöhe() + val );
+            if( getHöhe() > größe.y )
+                __super::setGröße( getBreite(), größe.y );
+            rend = 1;
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void ToolTip::doMausEreignis( MausEreignis &me )
+{
+    if( mausIn )
+        pos.x = me.mx, pos.y = me.my + 15;
+    sichtbar = 0;
+    if( alpha )
+        rend = 1;
+}
+
+void ToolTip::render( Bild &zRObj )
+{
+    if( alpha && zeichnen )
+    {
+        zSchrift()->lock();
+        zSchrift()->setSchriftGröße( getSchriftGröße() );
+        größe = Punkt( zSchrift()->getTextBreite( zText() ) + getLinienRahmenBreite() * 2, zSchrift()->getTextHöhe( zText() ) + getLinienRahmenBreite() * 2 );
+        zSchrift()->unlock();
+        zRObj.setAlpha( alpha );
+        setPosition( pos );
+        if( getX() + getBreite() > zRObj.getBreite() )
+            setPosition( getX() - ( getX() + getBreite() - zRObj.getBreite() ), getY() );
+        if( getY() + getHöhe() > zRObj.getHöhe() )
+            setPosition( getX(), getY() - ( getY() + getHöhe() - zRObj.getHöhe() ) );
+        __super::render( zRObj );
+        zRObj.releaseAlpha();
+        zeichnen = 0;
+    }
+}
+
+// constant
+Bildschirm *ToolTip::zBildschirm() const
+{
+    return bildschirm;
+}
+
+// Reference Counting
+TextFeld *ToolTip::getThis()
+{
+    ++ref;
+    return this;
+}
+
+TextFeld *ToolTip::release()
+{
+    --ref;
+    if( !ref )
+    {
+        delete this;
+        return 0;
+    }
+    if( ref == 1 )
+    {
+        if( !bildschirm->removeToolTip( this ) )
+            delete this;
+    }
+    return 0;
+}

+ 81 - 0
ToolTip.h

@@ -0,0 +1,81 @@
+#ifndef ToolTip_H
+#define ToolTip_H
+
+#include "TextFeld.h"
+
+namespace Framework
+{
+	class Schrift; // Schrift.h
+	class Bild; // Bild.h
+	class AlphaFeld; // AlphaFeld.h
+	class Text; // Text.h
+	class LRahmen; // Rahmen.h
+	struct MausEreignis; // MausEreignis.h
+	class Bildschirm; // Bildschirm.h
+
+    // Verwaltet ein automatisch ausfahrendes Fenster an der Mausposition, wo hilfe Texte eingeblendet werden
+	class ToolTip : public TextFeld
+	{
+    public:
+        class Style : public TextFeld::Style{};
+	private:
+        Punkt größe;
+		double animationSpeed;
+		double warten;
+		double wartenCount;
+        double tval;
+		bool mausIn;
+		unsigned char alpha;
+		bool sichtbar;
+        bool zeichnen;
+		Bildschirm *bildschirm;
+
+	public:
+		// Konstruktor
+		__declspec( dllexport ) ToolTip( Bildschirm *zSceen );
+		// Destruktor
+		__declspec( dllexport ) ~ToolTip();
+		// Setzt die ausgeklappte Größe.
+        //  breite: Die Breite in Pixeln
+        //  höhe: Die Höhe in Pixeln
+        // Die Größe wird beim rendern überschrieben
+		__declspec( dllexport ) void setGröße( int breite, int höhe );
+        // Setzt die ausgeklappte Größe.
+        //  gr: Die Größe in Pixeln
+        // Die Größe wird beim rendern überschrieben
+		__declspec( dllexport ) void setGröße( Punkt &gr );
+        // Setzt die anzahl an Seunden, de gewartet wird bis der Tipp erscheint
+        //  warten: Die Anzahl an Sekunden
+		__declspec( dllexport ) void setWarten( double warten );
+        // Legt fest, wie schnell der Tipp erscheint
+        //  speed: Anzahl der Pixel, die pro Sekunde eingeblendet werden. (Standart: 250)
+		__declspec( dllexport ) void setAnimationSpeed( double speed );
+        // Legt Fest, ob die Maus in dem Zeichnung ist, zu dem der Tip gehört
+        //  mausIn: 1, wenn die Maus in dem Zeichnung ist. 0 sonst
+		__declspec( dllexport ) void setMausIn( bool mausIn );
+        // Setzt den Counter zurück, der zählt, wann der Tipp eingeblendet wird.
+		__declspec( dllexport ) void wartenReset();
+        // Legt fest, das das Zeichnung, zu dem der Tip gehört gezeichnet wurde, so dass der Tip auch gezeichnet werden könnte
+        __declspec( dllexport ) void setZeichnen();
+        // Aktualisiert den Tip. Wird vom Framework aufgerufen
+        //  tickVal: Die Zeit in sekunden, die seit dem lezten Aufruf dieser Funktion vergangen ist
+		//  return: 1, wenn sich etwas verändert hat und das Bild neu gezeichnet werden muss. 0 sonst
+        __declspec( dllexport ) bool tick( double tickVal ) override;
+        // Verarbeitet Maus Nachrichten
+        //  me: Das Ereignis, was durch die Mauseingabe ausgelößt wurde
+		__declspec( dllexport ) void doMausEreignis( MausEreignis &me ) override;
+        // Zeichnet den Tip nach zRObj, falls er sichtbar ist und das zugehörige Zeichnung ebenfalls gezeichnet wurde
+        //  zRObj: Das Bild, in welches gezeichnet werden soll
+		__declspec( dllexport ) void render( Bild &zRObj ) override;
+		// Gibt einen Zeiger auf den Bildschirm ohne erhöhten Reference Counter zurück, so dem der Tooltip gehört.
+		__declspec( dllexport ) Bildschirm *zBildschirm() const;
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+		__declspec( dllexport ) TextFeld *getThis() override;
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+		__declspec( dllexport ) TextFeld *release() override;
+	};
+}
+
+#endif

+ 156 - 0
Vec2.h

@@ -0,0 +1,156 @@
+#ifndef Vec2_H
+#define Vec2_H
+
+#include "FrameworkMath.h"
+
+namespace Framework
+{
+	template< typename T >
+	class Vec2
+	{
+	public:
+		T x;
+		T y;
+		// Konstruktor
+		inline Vec2()
+		{
+		}
+		inline Vec2( T x, T y )
+			: x( x ),
+			  y( y )
+		{
+		}
+		inline Vec2( const Vec2 &vect )
+			: x( (T)vect.x ),
+			  y( (T)vect.y )
+		{
+		}
+		// nicht constant
+		inline Vec2 &normalize()
+		{
+			const T länge = län();
+			x /= länge;
+			y /= länge;
+			return *this;
+		}
+		inline Vec2 &CCW90()
+		{
+			T temp = y;
+			y = -x;
+			x = temp;
+			return *this;
+		}
+		inline Vec2 &CW90()
+		{
+			T temp = y;
+			y = x;
+			x = -temp;
+			return *this;
+		}
+		inline Vec2 &Swap( Vec2 &vect )
+		{
+			const Vec2 tmp = vect;
+			vect = *this;
+			*this = tmp;
+			return *this;
+		}
+		inline Vec2 operator=( const Vec2 &r )
+		{
+			x = r.x;
+			y = r.y;
+			return *this;
+		}
+		inline Vec2 operator+=( const Vec2 &r )
+		{
+			x += r.x;
+			y += r.y;
+			return *this;
+		}
+		inline Vec2 operator-=( const Vec2 &r )
+		{
+			x -= r.x;
+			y -= r.y;
+			return *this;
+		}
+		inline Vec2 operator*=( const T &r )
+		{
+			x *= r;
+			y *= r;
+			return *this;
+		}
+		inline Vec2 operator/=( const T &r )
+		{
+			x /= r;
+			y /= r;
+			return *this;
+		}
+		// constant
+		inline Vec2 operator-( ) const
+		{
+			return Vec2< T >( -x, -y );
+		}
+		template< typename T2 >
+		inline operator Vec2< T2 >() const
+		{
+			return Vec2< T2 >( (T2)x, (T2)y );
+		}
+		inline T länSq() const
+		{
+			return *this * *this;
+		}
+		inline T län() const
+		{
+			return sqrt( länSq() );
+		}
+		inline T operator*( const Vec2 &r ) const
+		{
+			return x * r.x + y * r.y;
+		}
+		inline Vec2 operator+( const Vec2 &r ) const
+		{
+			return Vec2( *this ) += r;
+		}
+		inline Vec2 operator-( const Vec2 &r ) const
+		{
+			return Vec2( *this ) -= r;
+		}
+		inline Vec2 operator*( const T &r ) const
+		{
+			return Vec2( *this ) *= r;
+		}
+		inline Vec2 operator/( const T &r ) const
+		{
+			return Vec2( *this ) /= r;
+		}
+		inline bool istInRegion( const Vec2 &p1, const Vec2 &p2 ) const
+		{
+			const T medianX = (T)( ( p1.x + p2.x ) / 2.0 );
+			const T medianY = (T)( ( p1.y + p2.y ) / 2.0 );
+			return abs< T >( medianX - x ) <= abs< T >( medianX - p1.x ) &&
+				   abs< T >( medianY - y ) <= abs< T >( medianY - p1.y );
+		}
+		inline bool operator==( const Vec2 &r ) const
+		{
+			return x == r.x && y == r.y;
+		}
+		inline bool operator!=( const Vec2 &r ) const
+		{
+			return !( *this == r );
+		}
+		inline Vec2 mittelpunktMit( const Vec2 &p2 ) const
+		{
+			return Vec2( (T)( ( x + p2.x ) / 2.0 ), (T)( ( y + p2.y ) / 2.0 ) );
+		}
+		inline Vec2 rotation( const float angle ) const
+		{
+			Vec2 result;
+			float cosine = cosf( angle );
+			float sine = sinf( angle );
+			result.x = (T)( x * cosine - y * sine );
+			result.y = (T)( x * sine + y * cosine );
+			return result;
+		}
+	};
+}
+
+#endif

+ 137 - 0
Vec3.h

@@ -0,0 +1,137 @@
+#ifndef Vec3_H
+#define Vec3_H
+
+#include "FrameworkMath.h"
+
+namespace Framework
+{
+	template< typename T >
+	class Vec3
+	{
+	public:
+		T x;
+		T y;
+		T z;
+		// Konstruktor
+		inline Vec3()
+		{
+		}
+		inline Vec3( T x, T y, T z )
+			: x( x ),
+			  y( y ),
+			  z( z )
+		{
+		}
+		inline Vec3( const Vec3 &vect )
+			: Vec3( vect.x, vect.y, vect.z )
+		{
+		}
+		// nicht constant
+		inline Vec3 &normalize()
+		{
+			const T länge = län();
+			x /= länge;
+			y /= länge;
+			z /= länge;
+			return *this;
+		}
+		inline Vec3 &Swap( Vec3 &vect )
+		{
+			const Vec3 tmp = vect;
+			vect = *this;
+			*this = tmp;
+			return *this;
+		}
+		inline Vec3 operator=( const Vec3 &r )
+		{
+			x = r.x;
+			y = r.y;
+			z = r.z;
+			return *this;
+		}
+		inline Vec3 operator+=( const Vec3 &r )
+		{
+			x += r.x;
+			y += r.y;
+			z += r.z;
+			return *this;
+		}
+		inline Vec3 operator-=( const Vec3 &r )
+		{
+			x -= r.x;
+			y -= r.y;
+			z -= r.z;
+			return *this;
+		}
+		inline Vec3 operator*=( const T &r )
+		{
+			x *= r;
+			y *= r;
+			z *= r;
+			return *this;
+		}
+		inline Vec3 operator/=( const T &r )
+		{
+			x /= r;
+			y /= r;
+			z /= r;
+			return *this;
+		}
+		// constant
+        inline T abstandSq( const Vec3 &p ) const
+        {
+            return ( x - p.x ) * ( x - p.x ) + ( y - p.y ) * ( y - p.y ) + ( z - p.z ) * ( z - p.z );
+        }
+        inline T abstand( const Vec3 &p ) const
+        {
+            return sqrt( abstandSq( p ) );
+        }
+		inline Vec3 operator-( ) const
+		{
+			return{ -x, -y, -z };
+		}
+		template< typename T2 >
+		inline operator Vec3< T2 >() const
+		{
+			return{ (T2)x, (T2)y, (T2)z };
+		}
+		inline T länSq() const
+		{
+			return *this * *this;
+		}
+		inline T län() const
+		{
+			return sqrt( länSq() );
+		}
+		inline T operator*( const Vec3 &r ) const
+		{
+			return x * r.x + y * r.y + z * r.z;
+		}
+		inline Vec3 operator+( const Vec3 &r ) const
+		{
+			return Vec3( *this ) += r;
+		}
+		inline Vec3 operator-( const Vec3 &r ) const
+		{
+			return Vec3( *this ) -= r;
+		}
+		inline Vec3 operator*( const T &r ) const
+		{
+			return Vec3( *this ) *= r;
+		}
+		inline Vec3 operator/( const T &r ) const
+		{
+			return Vec3( *this ) /= r;
+		}
+		inline bool operator==( const Vec3 &r ) const
+		{
+			return x == r.x && y == r.y && z == r.z;
+		}
+		inline bool operator!=( const Vec3 &r ) const
+		{
+			return !( *this == r );
+		}
+	};
+}
+
+#endif

+ 135 - 0
Vec4.h

@@ -0,0 +1,135 @@
+#pragma once
+
+#include "Vec3.h"
+
+namespace Framework
+{
+    template< typename T >
+    class Vec4
+    {
+    public:
+        T x;
+        T y;
+        T z;
+        T w;
+        // Konstruktor
+        inline Vec4()
+        {}
+        inline Vec4( T x, T y, T z, T w )
+            : x( x ),
+            y( y ),
+            z( z ),
+            w( w )
+        {}
+        inline Vec4( const Vec4 &vect )
+            : Vec4( vect.x, vect.y, vect.z, vect.w )
+        {}
+        // nicht constant
+        inline Vec4 &normalize()
+        {
+            const T länge = län();
+            x /= länge;
+            y /= länge;
+            z /= länge;
+            w /= länge;
+            return *this;
+        }
+        inline Vec4 &Swap( Vec4 &vect )
+        {
+            const Vec4 tmp = vect;
+            vect = *this;
+            *this = tmp;
+            return *this;
+        }
+        inline Vec4 operator=( const Vec4 &r )
+        {
+            x = r.x;
+            y = r.y;
+            z = r.z;
+            w = r.w;
+            return *this;
+        }
+        inline Vec4 operator+=( const Vec4 &r )
+        {
+            x += r.x;
+            y += r.y;
+            z += r.z;
+            w += r.w;
+            return *this;
+        }
+        inline Vec4 operator-=( const Vec4 &r )
+        {
+            x -= r.x;
+            y -= r.y;
+            z -= r.z;
+            w -= r.w;
+            return *this;
+        }
+        inline Vec4 operator*=( const T &r )
+        {
+            x *= r;
+            y *= r;
+            z *= r;
+            w *= r;
+            return *this;
+        }
+        inline Vec4 operator/=( const T &r )
+        {
+            x /= r;
+            y /= r;
+            z /= r;
+            w /= r;
+            return *this;
+        }
+        // constant
+        inline Vec4 operator-() const
+        {
+            return{ -x, -y, -z, -w };
+        }
+        template< typename T2 >
+        inline operator Vec4< T2 >() const
+        {
+            return{ (T2)x, (T2)y, (T2)z, (T2)w };
+        }
+        inline T länSq() const
+        {
+            return *this * *this;
+        }
+        inline T län() const
+        {
+            return sqrt( länSq() );
+        }
+        inline T operator*( const Vec4 &r ) const
+        {
+            return x * r.x + y * r.y + z * r.z;// +w * r.w;
+        }
+        inline T operator*( const Vec3< T > &r ) const
+        {
+            return x * r.x + y * r.y + z * r.z + w;
+        }
+        inline Vec4 operator+( const Vec4 &r ) const
+        {
+            return Vec4( *this ) += r;
+        }
+        inline Vec4 operator-( const Vec4 &r ) const
+        {
+            return Vec4( *this ) -= r;
+        }
+        inline Vec4 operator*( const T &r ) const
+        {
+            return Vec4( *this ) *= r;
+        }
+        inline Vec4 operator/( const T &r ) const
+        {
+            return Vec4( *this ) /= r;
+        }
+        inline bool operator==( const Vec4 &r ) const
+        {
+            return x == r.x && y == r.y && z == r.z && w == r.w;
+        }
+        inline bool operator!=( const Vec4 &r ) const
+        {
+            return !( *this == r );
+        }
+    };
+}

+ 120 - 0
Welt2D.cpp

@@ -0,0 +1,120 @@
+#include "Welt2D.h"
+#include "Model2D.h"
+
+using namespace Framework;
+
+// Inhalt der Welt2D Klasse aus Welt3D.h
+// Konstruktor
+Welt2D::Welt2D()
+{
+    obj = new RCArray< Model2D >();
+    ref = 1;
+}
+
+// Destruktor
+Welt2D::~Welt2D()
+{
+    obj->release();
+}
+
+// nicht constant
+void Welt2D::addModel( Model2D *obj )
+{
+    this->obj->add( obj, 0 );
+}
+
+void Welt2D::removeModel( Model2D *zObj )
+{
+    auto *e = &obj->getArray();
+    for( int z = 0; e && e->set; z++, e = e->next )
+    {
+        if( e->var == zObj )
+        {
+            obj->lösche( z );
+            return;
+        }
+    }
+}
+
+void Welt2D::setModelInVordergrund( Model2D *zObj )
+{
+    auto *e = &obj->getArray();
+    for( int z = 0; e && e->set; z++, e = e->next )
+    {
+        if( e->var == zObj )
+        {
+            obj->setPosition( z, 0 );
+            return;
+        }
+    }
+}
+
+void Welt2D::setModelInHintergrund( Model2D *zObj )
+{
+    int anz = obj->getEintragAnzahl();
+    auto *e = &obj->getArray();
+    for( int z = 0; e && e->set; z++, e = e->next )
+    {
+        if( e->var == zObj && z != anz - 1 )
+        {
+            obj->setPosition( z, anz - 1 );
+            return;
+        }
+    }
+}
+
+void Welt2D::removeAll()
+{
+    obj->leeren();
+}
+
+void Welt2D::doMausEreignis( MausEreignis &me )
+{
+
+}
+
+void Welt2D::doTastaturEreignis( TastaturEreignis &me )
+{
+
+}
+
+bool Welt2D::tick( double t )
+{
+    return 0;
+}
+
+void Welt2D::render( Bild &zRObj, Punkt &wPos, Punkt &wGr, Punkt &kamGr )
+{
+
+}
+
+// constant
+int Welt2D::getModelAnzahl() const
+{
+    return obj->getEintragAnzahl();
+}
+
+Model2D *Welt2D::getModel( int z ) const
+{
+    return obj->get( z );
+}
+
+Model2D *Welt2D::zModel( int z ) const
+{
+    return obj->z( z );
+}
+
+// Reference Counting
+Welt2D *Welt2D::getThis()
+{
+    ref++;
+    return this;
+}
+
+Welt2D *Welt2D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 54 - 0
Welt2D.h

@@ -0,0 +1,54 @@
+#pragma once
+
+#include "Array.h"
+#include "Punkt.h"
+
+namespace Framework
+{
+    class Model2D; // Model2D.h
+    struct MausEreignis;
+    struct TastaturEreignis;
+    class Bild;
+
+    class Welt2D
+    {
+    public:
+        class Style
+        {
+        public:
+            const static __int64 HORIZONTAL_UNENDLICH = 0x0001; // Zeichnunge die rechts austreten erscheinen links wieder und umgekehrt
+            const static __int64 VERTIKAL_UNENDLICH = 0x0002; // Zeichnunge die unten austreten erscheinen oben wieder und umgekehrt
+            const static __int64 BEI_VERLASSEN_LÖSCHEN = 0x0004; // Entfernt Zeichnunge, die die Welt an den Rändern verlassen
+            const static __int64 HINTERGRUND_BENUTZEN = 0x0008; // Legt fest ob es eine seperate Liste mit HintergrundZeichnungen gibt
+            const static __int64 HINTERGRUND_EREIGNISSE = 0x0010; // Legt festm ob die HintergrundZeichnunge Benutzereingaben empfangen
+            const static __int64 HINTERGRUND_TICK = 0x0020; // Legt fest, ob der Hintergrund annimerbar ist
+        };
+    private:
+        RCArray< Model2D > *obj;
+        int style;
+        int ref;
+
+    public:
+        // Konstruktor
+        Welt2D();
+        // Destruktor
+        ~Welt2D();
+        // nicht constant
+        void addModel( Model2D *obj );
+        void removeModel( Model2D *zObj );
+        void setModelInVordergrund( Model2D *zObj );
+        void setModelInHintergrund( Model2D *zObj );
+        void removeAll();
+        void doMausEreignis( MausEreignis &me );
+        void doTastaturEreignis( TastaturEreignis &me );
+        bool tick( double t );
+        void render( Bild &zRObj, Punkt &wPos, Punkt &wGr, Punkt &kamGr );
+        // constant
+        int getModelAnzahl() const;
+        Model2D *getModel( int z ) const;
+        Model2D *zModel( int z ) const;
+        // Reference Counting
+        Welt2D *getThis();
+        Welt2D *release();
+    };
+}

+ 199 - 0
Welt3D.cpp

@@ -0,0 +1,199 @@
+#include "Welt3D.h"
+#include "Zeichnung3D.h"
+#include "Render3D.h"
+
+using namespace Framework;
+
+// Inhalt der Welt3D Klasse aus Welt3D.h
+// Konstructor
+Welt3D::Welt3D()
+{
+    arraySize = 100;
+    arraySizeAlpha = 100;
+    members = new Zeichnung3D*[ arraySize ];
+    membersAlpha = new Zeichnung3D*[ arraySizeAlpha ];
+    used = new bool[ arraySizeAlpha ];
+    distSq = new float[ arraySizeAlpha ];
+    alphaVS = new Zeichnung3D*[ arraySizeAlpha ];
+    for( int i = 0; i < arraySize; i++ )
+        members[ i ] = 0;
+    for( int i = 0; i < arraySizeAlpha; i++ )
+        membersAlpha[ i ] = 0;
+    ref = 1;
+}
+
+// Destruktor
+Welt3D::~Welt3D()
+{
+    delete[] members;
+    delete[] membersAlpha;
+    delete[] used;
+    delete[] distSq;
+    delete[] alphaVS;
+}
+
+// Fügt der Welt ein Objekt hinzu
+//  obj: Das Objekt, was hinzugefügt werden soll
+void Welt3D::addZeichnung( Zeichnung3D *obj )
+{
+    Zeichnung3D **tmp = members;
+    int max = arraySize;
+    if( obj->hatAlpha() )
+    {
+        tmp = membersAlpha;
+        max = arraySizeAlpha;
+    }
+    for( int i = 0; i < max; i++ )
+    {
+        if( !*tmp )
+        {
+            *tmp = obj;
+            return;
+        }
+        tmp++;
+    }
+    if( obj->hatAlpha() )
+    {
+        arraySizeAlpha += 100;
+        Zeichnung3D **nm = new Zeichnung3D*[ arraySizeAlpha ];
+        memcpy( nm, membersAlpha, sizeof( Zeichnung3D * ) * ( arraySizeAlpha - 100 ) );
+        memset( &nm[ arraySizeAlpha - 100 ], 0, sizeof( Zeichnung3D * ) * 100 );
+        delete[] membersAlpha;
+        membersAlpha = nm;
+        membersAlpha[ arraySizeAlpha - 100 ] = obj;
+        delete[] used;
+        delete[] distSq;
+        delete[] alphaVS;
+        used = new bool[ arraySizeAlpha ];
+        distSq = new float[ arraySizeAlpha ];
+        alphaVS = new Zeichnung3D*[ arraySizeAlpha ];
+        return;
+    }
+    arraySize += 100;
+    Zeichnung3D **nm = new Zeichnung3D*[ arraySize ];
+    memcpy( nm, members, sizeof( Zeichnung3D * ) * ( arraySize - 100 ) );
+    memset( &nm[ arraySize - 100 ], 0, sizeof( Zeichnung3D * ) * 100 );
+    delete[] members;
+    members = nm;
+    members[ arraySize - 100 ] = obj;
+}
+
+// Entfernt ein Objekt aus der Welt
+//  obj: Das Objekt, das entwernt werden soll
+void Welt3D::removeZeichnung( Zeichnung3D *obj )
+{
+    int index = 0;
+    if( !obj->hatAlpha() )
+    {
+        for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
+        {
+            if( *i == obj )
+            {
+                *i = 0;
+                return;
+            }
+        }
+        return;
+    }
+    for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
+    {
+        if( *i == obj )
+        {
+            *i = 0;
+            return;
+        }
+    }
+}
+// Verarbeitet die vergangene Zeit
+//  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+//  return: true, wenn sich das Objekt verändert hat, false sonnst.
+bool Welt3D::tick( double tickval )
+{
+    int index = 0;
+    bool ret = 0;
+    for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
+    {
+        if( *i && ( *i )->hatAlpha() )
+        {
+            addZeichnung( *i );
+            *i = 0;
+            continue;
+        }
+        ret |= *i ? ( *i )->tick( tickval ) : 0;
+    }
+    index = 0;
+    for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
+    {
+        ret |= *i ? ( *i )->tick( tickval ) : 0;
+        if( *i && !( *i )->hatAlpha() )
+        {
+            addZeichnung( *i );
+            *i = 0;
+            continue;
+        }
+    }
+    return ret;
+}
+
+// Zeichnet einen ausschnitt der Welt
+//  zRObj: Enthällt alle Werkzeuge, die zum Zeichnen verwendet werden
+void Welt3D::render( Render3D *zRObj )
+{
+    int index = 0;
+    for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
+    {
+        if( *i && zRObj->isInFrustrum( (*i)->getPos(), (*i)->getRadius() ) )
+            ( *i )->render( zRObj );
+    }
+    memset( used, 0, arraySizeAlpha * sizeof( bool ) );
+    memset( alphaVS, 0, arraySizeAlpha * sizeof( Zeichnung3D * ) );
+    index = 0;
+    int index2 = 0;
+    for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
+    {
+        if( *i && zRObj->isInFrustrum( ( *i )->getPos(), ( *i )->getRadius(), &distSq[ index2 ] ) )
+        {
+            alphaVS[ index2 ] = *i;
+            index2++;
+        }
+    }
+    float maxEntf;
+    int ind;
+    do
+    {
+        maxEntf = -1;
+        ind = -1;
+        for( int i = 0; i < index2; i++ )
+        {
+            if( !used[ i ] && distSq[ i ] > maxEntf )
+            {
+                maxEntf = distSq[ i ];
+                ind = i;
+            }
+        }
+        if( ind >= 0 )
+        {
+            alphaVS[ ind ]->render( zRObj );
+            used[ ind ] = 1;
+        }
+    }
+    while( ind >= 0 );
+}
+
+// Erhöht den Reference Counting Zähler.
+//  return: this.
+Welt3D *Welt3D::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+//  return: 0.
+Welt3D *Welt3D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 48 - 0
Welt3D.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include "Betriebssystem.h"
+
+namespace Framework
+{
+    class Zeichnung3DArray; // Zeichnung3D.h
+    class Zeichnung3D; // Zeichnung.h
+    class Render3D; // Render3D.h
+
+    class Welt3D
+    {
+    private:
+        Zeichnung3D **members;
+        Zeichnung3D **membersAlpha;
+        bool *used;
+        float *distSq;
+        Zeichnung3D **alphaVS;
+        int arraySize;
+        int arraySizeAlpha;
+        int ref;
+
+    public:
+        // Konstructor
+        __declspec( dllexport ) Welt3D();
+        // Destruktor
+        __declspec( dllexport ) ~Welt3D();
+        // Fügt der Welt ein Objekt hinzu
+        //  obj: Das Objekt, was hinzugefügt werden soll
+        __declspec( dllexport ) void addZeichnung( Zeichnung3D *obj );
+        // Entfernt ein Objekt aus der Welt
+        //  obj: Das Objekt, das entwernt werden soll
+        __declspec( dllexport ) void removeZeichnung( Zeichnung3D *obj );
+        // Verarbeitet die vergangene Zeit
+        //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+        //  return: true, wenn sich das Objekt verändert hat, false sonnst.
+        __declspec( dllexport ) virtual bool tick( double tickval );
+        // Zeichnet einen ausschnitt der Welt
+        //  zRObj: Enthällt alle Werkzeuge, die zum Zeichnen verwendet werden
+        __declspec( dllexport ) void render( Render3D *zRObj );
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) Welt3D *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) Welt3D *release();
+    };
+}

+ 972 - 0
Zeichnung.cpp

@@ -0,0 +1,972 @@
+#include "Zeichnung.h"
+#include "MausEreignis.h"
+#include "TastaturEreignis.h"
+#include "Globals.h"
+#include "ToolTip.h"
+#include "Scroll.h"
+#include "Text.h"
+#include "Rahmen.h"
+#include "AlphaFeld.h"
+#include "Bild.h"
+#include <Windows.h>
+
+using namespace Framework;
+
+// Inhalt der Zeichnung Klasse aus Zeichnung.h
+// Konstruktor 
+Zeichnung::Zeichnung()
+    : pos( 0, 0 ),
+    gr( 0, 0 ),
+    makParam( 0 ),
+    takParam( 0 ),
+    Mak( 0 ),
+    Tak( 0 ),
+    nmakParam( 0 ),
+    ntakParam( 0 ),
+    nMak( 0 ),
+    nTak( 0 ),
+    mausIn( 0 ),
+    toolTip( 0 ),
+    rend( 0 )
+{
+    InitializeCriticalSection( &cs );
+}
+
+// Destruktor 
+Zeichnung::~Zeichnung()
+{
+    DeleteCriticalSection( &cs );
+    if( toolTip )
+        toolTip->release();
+}
+
+// nicht constant 
+void Zeichnung::setRender()
+{
+    rend = 1;
+}
+
+void Zeichnung::setToolTipText( const char *txt, Bildschirm *zScreen )
+{
+    if( !txt )
+        toolTip = (ToolTip*)toolTip->release();
+    else
+    {
+        if( !toolTip )
+            toolTip = new ToolTip( zScreen );
+        toolTip->setText( txt );
+    }
+}
+
+void Zeichnung::lockZeichnung()
+{
+    EnterCriticalSection( &cs );
+}
+
+void Zeichnung::unlockZeichnung()
+{
+    LeaveCriticalSection( &cs );
+}
+
+void Zeichnung::setMausEreignisParameter( void *p ) // setzt den Parameter vom Maus Ereignis
+{
+    makParam = p;
+}
+
+void Zeichnung::setTastaturEreignisParameter( void *p ) // setzt den Parameter vom Tastatur Ereignis
+{
+    takParam = p;
+}
+
+void Zeichnung::setMausEreignis( bool( *ak )( void *, void *, MausEreignis ) ) // setzt das Maus Ereignis
+{
+    Mak = ak;
+}
+
+void Zeichnung::setTastaturEreignis( bool( *ak )( void *, void *, TastaturEreignis ) ) // setzt das TastaturEreignis
+{
+    Tak = ak;
+}
+
+void Zeichnung::setNMausEreignisParameter( void *p ) // setzt den Parameter vom Maus Ereignis
+{
+    nmakParam = p;
+}
+
+void Zeichnung::setNTastaturEreignisParameter( void *p ) // setzt den Parameter vom Tastatur Ereignis
+{
+    ntakParam = p;
+}
+
+void Zeichnung::setNMausEreignis( bool( *ak )( void *, void *, MausEreignis ) ) // setzt das Maus Ereignis
+{
+    nMak = ak;
+}
+
+void Zeichnung::setNTastaturEreignis( bool( *ak )( void *, void *, TastaturEreignis ) ) // setzt das TastaturEreignis
+{
+    nTak = ak;
+}
+
+void Zeichnung::doMausEreignis( MausEreignis &me ) // ruft Mak auf
+{
+    if( me.verarbeitet || ( !( me.mx >= pos.x && me.mx <= pos.x + gr.x && me.my >= pos.y && me.my <= pos.y + gr.y ) && me.id != ME_Verlässt ) )
+    {
+        if( mausIn )
+        {
+            mausIn = 0;
+            if( toolTip )
+                toolTip->setMausIn( 0 );
+            MausEreignis me2;
+            me2.id = ME_Verlässt;
+            me2.mx = me.mx;
+            me2.my = me.my;
+            me2.verarbeitet = 0;
+            doMausEreignis( me2 );
+        }
+        return;
+    }
+    if( !mausIn && me.id != ME_Verlässt )
+    {
+        mausIn = 1;
+        if( toolTip )
+            toolTip->setMausIn( 1 );
+        MausEreignis me2;
+        me2.id = ME_Betritt;
+        me2.mx = me.mx;
+        me2.my = me.my;
+        me2.verarbeitet = 0;
+        doMausEreignis( me2 );
+    }
+    me.mx -= pos.x, me.my -= pos.y;
+    if( Mak )
+        me.verarbeitet |= Mak( makParam, this, me );
+    if( nMak && me.verarbeitet )
+        me.verarbeitet = nMak( nmakParam, this, me );
+    me.mx += pos.x, me.my += pos.y;
+}
+
+void Zeichnung::doTastaturEreignis( TastaturEreignis &te ) // ruft Tak auf
+{
+    if( te.verarbeitet )
+        return;
+    if( Tak )
+        te.verarbeitet |= Tak( takParam, this, te );
+    if( nTak && te.verarbeitet )
+        te.verarbeitet = nTak( ntakParam, this, te );
+}
+
+void Zeichnung::setPosition( const Punkt &pos ) // setzt die position
+{
+    lockZeichnung();
+    if( this->pos != pos )
+        rend = 1;
+    this->pos = pos;
+    unlockZeichnung();
+}
+
+void Zeichnung::setX( int xPos )
+{
+    lockZeichnung();
+    if( pos.x != xPos )
+    {
+        rend = 1;
+        pos.x = xPos;
+    }
+    unlockZeichnung();
+}
+
+void Zeichnung::setY( int yPos )
+{
+    lockZeichnung();
+    if( pos.y != yPos )
+    {
+        rend = 1;
+        pos.y = yPos;
+    }
+    unlockZeichnung();
+}
+
+void Zeichnung::setGröße( const Punkt &gr ) // setzt die Größe
+{
+    lockZeichnung();
+    if( this->gr != gr )
+        rend = 1;
+    this->gr = gr;
+    unlockZeichnung();
+}
+
+void Zeichnung::setPosition( int x, int y ) // setzt die position
+{
+    setPosition( Punkt( x, y ) );
+}
+
+void Zeichnung::setGröße( int x, int y ) // setzt die Größe
+{
+    setGröße( Punkt( x, y ) );
+}
+
+bool Zeichnung::tick( double tickval )
+{
+    bool r = rend;
+    rend = 0;
+    return r;
+}
+
+void Zeichnung::setStyle( __int64 style ) // setzt den Style des Text Feldes
+{
+    if( this->style != style )
+    {
+        this->style = style;
+        rend = 1;
+    }
+}
+
+void Zeichnung::setStyle( __int64 style, bool add_löschen )
+{
+    if( add_löschen && ( this->style | style ) != this->style )
+    {
+        this->style |= style;
+        rend = 1;
+    }
+    else if( !add_löschen && ( this->style & ~style ) != this->style )
+    {
+        if( toolTip && ( style | Style::Sichtbar ) == style )
+            toolTip->setMausIn( 0 );
+        this->style &= ~style;
+        rend = 1;
+    }
+}
+
+void Zeichnung::addStyle( __int64 style )
+{
+    if( ( this->style | style ) != this->style )
+    {
+        this->style |= style;
+        rend = 1;
+    }
+}
+
+void Zeichnung::löscheStyle( __int64 style )
+{
+    if( ( this->style & ~style ) != this->style )
+    {
+        if( toolTip && ( style | Style::Sichtbar ) == style )
+            toolTip->setMausIn( 0 );
+        this->style &= ~style;
+        rend = 1;
+    }
+}
+
+void Zeichnung::render( Bild &zRObj )
+{
+    if( toolTip && ( style | Style::Sichtbar ) == style )
+        toolTip->setZeichnen();
+}
+
+// constant 
+bool Zeichnung::hatMausEreignis() const // prüft, ob Mak gesetzt ist
+{
+    return Mak != 0;
+}
+
+bool Zeichnung::hatTastaturEreignis() const // prüft, ob Tak gesetzt ist
+{
+    return Tak != 0;
+}
+
+const Punkt &Zeichnung::getPosition() const // gibt die Position zurück
+{
+    return pos;
+}
+
+const Punkt &Zeichnung::getGröße() const // gibt die Größe zurück
+{
+    return gr;
+}
+
+int Zeichnung::getBreite() const // gibt die Breite zurück
+{
+    return gr.x;
+}
+
+int Zeichnung::getHöhe() const // gibt die Höhe zurück
+{
+    return gr.y;
+}
+
+int Zeichnung::getX() const // gibt X zurück
+{
+    return pos.x;
+}
+
+int Zeichnung::getY() const // gibt Y zurück
+{
+    return pos.y;
+}
+
+ToolTip *Zeichnung::getToolTip() const // gibt den ToolTip Text
+{
+    return (ToolTip*)toolTip->getThis();
+}
+
+ToolTip *Zeichnung::zToolTip() const
+{
+    return toolTip;
+}
+
+bool Zeichnung::hatStyle( __int64 style ) const // prüft, ob style vorhanden
+{
+    return ( this->style | style ) == this->style;
+}
+
+bool Zeichnung::hatStyleNicht( __int64 style ) const // prüft, ob style nicht vorhanden
+{
+    return ( this->style | style ) != this->style;
+}
+
+Zeichnung *Zeichnung::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+    Zeichnung *obj = new Zeichnung();
+    obj->setPosition( pos );
+    obj->setGröße( gr );
+    obj->setMausEreignisParameter( makParam );
+    obj->setTastaturEreignisParameter( takParam );
+    obj->setMausEreignis( Mak );
+    obj->setTastaturEreignis( Tak );
+    if( toolTip )
+        obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+    return obj;
+}
+
+// Inhalt der ZeichnungArray Klasse aus Zeichnung.h
+// Konstruktor 
+ZeichnungArray::ZeichnungArray()
+    : This( 0 ),
+    next( 0 )
+{}
+
+// Destruktor 
+ZeichnungArray::~ZeichnungArray()
+{
+    delete next;
+}
+
+// nicht const 
+bool ZeichnungArray::addZeichnung( Zeichnung *obj ) // Fügt ein Zeichnung hinzu
+{
+    if( obj == This )
+        return 0;
+    if( !This )
+    {
+        This = obj;
+        return 1;
+    }
+    if( !next )
+        next = new ZeichnungArray();
+    return next->addZeichnung( obj );
+}
+
+bool ZeichnungArray::removeZeichnung( Zeichnung *obj ) // Entfernt ein Zeichnung
+{
+    if( obj == This )
+    {
+        if( index == 0 )
+        {
+            if( next )
+            {
+                This = next->getZeichnung();
+                ZeichnungArray *tmp = next->getNext();
+                next->setNext0();
+                delete next;
+                next = tmp;
+            }
+            else
+                This = 0;
+            return 0;
+        }
+        return 1;
+    }
+    if( !next )
+        return 0;
+    if( next->removeZeichnung( obj ) )
+    {
+        ZeichnungArray *tmp = next->getNext();
+        next->setNext0();
+        delete next;
+        next = tmp;
+    }
+    return 0;
+}
+
+bool ZeichnungArray::removeZeichnung( int i ) // Entfernt das von diesem aus i-te Zeichnung
+{
+    if( i == index )
+    {
+        if( index == 0 )
+        {
+            This = next->getZeichnung();
+            ZeichnungArray *tmp = next->getNext();
+            next->setNext0();
+            delete next;
+            next = tmp;
+            return 0;
+        }
+        return 1;
+    }
+    if( !next )
+        return 0;
+    if( next->removeZeichnung( i ) )
+    {
+        ZeichnungArray *tmp = next->getNext();
+        next->setNext0();
+        delete next;
+        next = tmp;
+    }
+    return 0;
+}
+
+void ZeichnungArray::setNext0() // Setzt das nächste Zeichnung zu 0
+{
+    next = 0;
+}
+
+void ZeichnungArray::updateIndex( int i ) // aktualisiert die Index variable
+{
+    index = i;
+    if( next )
+        next->updateIndex( i + 1 );
+}
+
+// constant 
+ZeichnungArray *ZeichnungArray::getNext() const // gibt das nächste Zeichnung zurück
+{
+    return next;
+}
+
+Zeichnung *ZeichnungArray::getZeichnung( int i ) const // gibt das von diesem aus i-te Zeichnung zurück
+{
+    if( i == index )
+        return This;
+    if( !next )
+        return 0;
+    return next->getZeichnung( i );
+}
+
+Zeichnung *ZeichnungArray::getZeichnung() const // gibt das von diesem aus i-te Zeichnung zurück
+{
+    return This;
+}
+
+int ZeichnungArray::getIndex() const // Gibt den Index zurück
+{
+    return index;
+}
+
+void ZeichnungArray::sendMausAll( MausEreignis &me ) const // sendet me an alle volgenden Zeichnunge
+{
+    if( next )
+        next->sendMausAll( me );
+    if( This )
+        This->doMausEreignis( me );
+}
+
+void ZeichnungArray::sendTastaturAll( TastaturEreignis &te ) const // sendet te an alle volgenden Zeichnunge
+{
+    if( next )
+        next->sendTastaturAll( te );
+    if( This )
+        This->doTastaturEreignis( te );
+}
+
+void ZeichnungArray::render( Bild &zRObj )
+{
+    if( This )
+        This->render( zRObj );
+    if( next )
+        next->render( zRObj );
+}
+
+bool ZeichnungArray::tick( double tickval )
+{
+    return ( This && This->tick( tickval ) ) | ( next && next->tick( tickval ) );
+}
+
+
+// Inhalt der ZeichnungHintergrund Klasse aus Zeichnung.h
+// Konstruktor 
+ZeichnungHintergrund::ZeichnungHintergrund()
+    : Zeichnung()
+{
+    hintergrundFarbe = 0xFF000000;
+    rahmen = 0;
+    hintergrundBild = 0;
+    hintergrundFeld = 0;
+    horizontalScrollBar = 0;
+    vertikalScrollBar = 0;
+    innenPosition.x = 0;
+    innenPosition.y = 0;
+    innenGröße.x = 0;
+    innenGröße.y = 0;
+}
+
+// Destruktor 
+ZeichnungHintergrund::~ZeichnungHintergrund()
+{
+    if( rahmen )
+        rahmen->release();
+    if( hintergrundBild )
+        hintergrundBild->release();
+    if( hintergrundFeld )
+        hintergrundFeld->release();
+    if( horizontalScrollBar )
+        horizontalScrollBar->release();
+    if( vertikalScrollBar )
+        vertikalScrollBar->release();
+}
+
+void ZeichnungHintergrund::setHintergrundBild( Bild *bild ) // setzt das Hintergrund Bild
+{
+    if( !hintergrundBild )
+        hintergrundBild = new Bild();
+    hintergrundBild->neuBild( bild->getBreite(), bild->getHöhe(), 0 );
+    int *buff1 = hintergrundBild->getBuffer();
+    int *buff2 = bild->getBuffer();
+    for( int i = 0; i < bild->getBreite() * bild->getHöhe(); ++i )
+        buff1[ i ] = buff2[ i ];
+    bild->release();
+    rend = 1;
+}
+
+void ZeichnungHintergrund::setHintergrundBildZ( Bild *bild ) // setzt einen Zeiger zum Hintergrund Bild
+{
+    if( hintergrundBild != bild )
+    {
+        if( hintergrundBild )
+            hintergrundBild->release();
+        hintergrundBild = bild;
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setHintergrundFarbe( int fc ) // setzt die Hintergrundfarbe
+{
+    if( hintergrundFarbe != fc )
+    {
+        hintergrundFarbe = fc;
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setAlphaFeldZ( AlphaFeld *buff ) // setzt einen Zeiger zum Hintergrund Buffer
+{
+    if( hintergrundFeld != buff )
+    {
+        if( hintergrundFeld )
+            hintergrundFeld->release();
+        hintergrundFeld = buff;
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setAlphaFeldStärke( int st ) // setzt die Stärke des Hintergrund Buffers
+{
+    if( !hintergrundFeld )
+    {
+        hintergrundFeld = new AlphaFeld();
+        rend = 1;
+    }
+    if( hintergrundFeld->getStärke() != st )
+    {
+        hintergrundFeld->setStärke( st );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setAlphaFeldFarbe( int fc ) // setzt die Farbe des Hintergrund Buffers
+{
+    if( !hintergrundFeld )
+    {
+        hintergrundFeld = new AlphaFeld();
+        rend = 1;
+    }
+    if( hintergrundFeld->getFarbe() != fc )
+    {
+        hintergrundFeld->setFarbe( fc );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setLinienRahmenZ( LRahmen *ram ) // setzt einen Zeiger zum Rahmen
+{
+    if( rahmen != ram )
+    {
+        if( rahmen )
+            rahmen->release();
+        rahmen = ram;
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setLinienRahmenBreite( int br ) // setzt die Breite des Rahmens
+{
+    if( !rahmen )
+    {
+        rahmen = new LRahmen();
+        rend = 1;
+    }
+    if( rahmen->getRBreite() != br )
+    {
+        rahmen->setRamenBreite( br );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setLinienRahmenFarbe( int fc ) // setzt die Farbe des Rahmens
+{
+    if( !rahmen )
+    {
+        rahmen = new LRahmen();
+        rend = 1;
+    }
+    if( rahmen->getFarbe() != fc )
+    {
+        rahmen->setFarbe( fc );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setVertikalKlickScroll( int ks ) // setzt die vertikale Scroll geschwindigkeit
+{
+    if( !vertikalScrollBar )
+    {
+        vertikalScrollBar = new VScrollBar();
+        rend = 1;
+    }
+    if( vertikalScrollBar->getKlickScroll() != ks )
+    {
+        vertikalScrollBar->setKlickScroll( ks );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setVertikalScrollPos( int pos ) // setzt die vertikale Scroll Position
+{
+    if( !vertikalScrollBar )
+    {
+        vertikalScrollBar = new VScrollBar();
+        rend = 1;
+    }
+    if( vertikalScrollBar && vertikalScrollBar->getScroll() != pos )
+    {
+        vertikalScrollBar->scroll( pos );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setVertikalScrollFarbe( int f, int bgF ) // setzt die scroll Farbe
+{
+    if( !vertikalScrollBar )
+    {
+        vertikalScrollBar = new VScrollBar();
+        rend = 1;
+    }
+    if( vertikalScrollBar && ( vertikalScrollBar->getFarbe() != f || vertikalScrollBar->getBgFarbe() != bgF ) )
+    {
+        vertikalScrollBar->setFarbe( f );
+        vertikalScrollBar->setBgFarbe( bgF, bgF != 0 );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setHorizontalKlickScroll( int ks ) // setzt die horizontale Scroll geschwindigkeit
+{
+    if( !horizontalScrollBar )
+    {
+        horizontalScrollBar = new HScrollBar();
+        rend = 1;
+    }
+    if( horizontalScrollBar && horizontalScrollBar->getKlickScroll() != ks )
+    {
+        horizontalScrollBar->setKlickScroll( ks );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setHorizontalScrollPos( int pos ) // setzt die horizontale Scroll Position
+{
+    if( !horizontalScrollBar )
+    {
+        horizontalScrollBar = new HScrollBar();
+        rend = 1;
+    }
+    if( horizontalScrollBar && horizontalScrollBar->getScroll() != pos )
+    {
+        horizontalScrollBar->scroll( pos );
+        rend = 1;
+    }
+}
+
+void ZeichnungHintergrund::setHorizontalScrollFarbe( int f, int bgF ) // setzt die scroll Farbe
+{
+    if( !horizontalScrollBar )
+    {
+        horizontalScrollBar = new HScrollBar();
+        rend = 1;
+    }
+    if( horizontalScrollBar && ( horizontalScrollBar->getFarbe() != f || horizontalScrollBar->getBgFarbe() != bgF ) )
+    {
+        horizontalScrollBar->setFarbe( f );
+        horizontalScrollBar->setBgFarbe( bgF, bgF != 0 );
+        rend = 1;
+    }
+}
+
+bool ZeichnungHintergrund::tick( double tickVal )
+{
+    if( vertikalScrollBar && hatStyle( Style::VScroll ) )
+        rend |= vertikalScrollBar->getRend();
+    if( horizontalScrollBar && hatStyle( Style::HScroll ) )
+        rend |= horizontalScrollBar->getRend();
+    return __super::tick( tickVal );
+}
+
+void ZeichnungHintergrund::render( Bild &rObj )
+{
+    innenPosition.x = pos.x;
+    innenPosition.y = pos.y;
+    innenGröße.x = gr.x;
+    innenGröße.y = gr.y;
+    if( hatStyleNicht( Style::Sichtbar ) )
+        return;
+    lockZeichnung();
+    if( !rObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+    {
+        unlockZeichnung();
+        return;
+    }
+    __super::render( rObj );
+    int rbr = 0;
+    if( hatStyle( Style::Rahmen ) && rahmen )
+    {
+        rahmen->setGröße( gr );
+        rahmen->render( rObj );
+        rbr = rahmen->getRBreite();
+    }
+    innenPosition.x += rbr;
+    innenPosition.y += rbr;
+    innenGröße.x -= rbr * 2;
+    innenGröße.y -= rbr * 2;
+    if( !rObj.setDrawOptions( rbr, rbr, gr.x - rbr * 2, gr.y - rbr * 2 ) )
+    {
+        rObj.releaseDrawOptions();
+        unlockZeichnung();
+        return;
+    }
+    bool vs = vertikalScrollBar && hatStyle( Style::VScroll );
+    bool hs = horizontalScrollBar && hatStyle( Style::HScroll );
+    if( vs )
+    {
+        vertikalScrollBar->render( gr.x - rbr * 2 - 15, 0, 15, gr.y - rbr * 2, rObj );
+        innenGröße.x -= 15;
+        if( hs )
+        {
+            horizontalScrollBar->render( 0, gr.y - rbr * 2 - 15, gr.x - rbr * 2 - 15, 15, rObj );
+            innenGröße.y -= 15;
+            if( !rObj.setDrawOptions( 0, 0, gr.x - rbr * 2 - 15, gr.y - rbr * 2 - 15 ) )
+            {
+                rObj.releaseDrawOptions();
+                rObj.releaseDrawOptions();
+                unlockZeichnung();
+                return;
+            }
+            horizontalScrollBar->update( horizontalScrollBar->getScrollData()->maxBreite, innenGröße.x );
+        }
+        else
+        {
+            if( !rObj.setDrawOptions( 0, 0, gr.x - rbr * 2 - 15, gr.y - rbr * 2 ) )
+            {
+                rObj.releaseDrawOptions();
+                rObj.releaseDrawOptions();
+                unlockZeichnung();
+                return;
+            }
+        }
+        vertikalScrollBar->update( vertikalScrollBar->getScrollData()->maxHöhe, innenGröße.y );
+    }
+    else if( hs )
+    {
+        horizontalScrollBar->render( rbr, gr.y - rbr * 2 - 15, gr.x - rbr * 2, 15, rObj );
+        innenGröße.y -= 15;
+        if( !rObj.setDrawOptions( 0, 0, gr.x - rbr * 2, gr.y - rbr * 2 - 15 ) )
+        {
+            rObj.releaseDrawOptions();
+            rObj.releaseDrawOptions();
+            unlockZeichnung();
+            return;
+        }
+    }
+    if( hatStyle( Style::Hintergrund ) )
+    {
+        if( hatStyle( Style::HAlpha ) )
+            rObj.alphaRegion( 0, 0, gr.x - rbr * 2, gr.y - rbr * 2, hintergrundFarbe );
+        else
+            rObj.füllRegion( 0, 0, gr.x - rbr * 2, gr.y - rbr * 2, hintergrundFarbe );
+        if( hatStyle( Style::HBild ) && hintergrundBild )
+        {
+            if( hatStyle( Style::HAlpha ) )
+                rObj.alphaBildSkall( 0, 0, gr.x - rbr * 2, gr.y - rbr * 2, *hintergrundBild );
+            else
+                rObj.drawBildSkall( 0, 0, gr.x - rbr * 2, gr.y - rbr * 2, *hintergrundBild );
+        }
+    }
+    if( hatStyle( Style::Buffered ) && hintergrundFeld )
+    {
+        hintergrundFeld->setGröße( gr.x - rbr * 2, gr.y - rbr * 2 );
+        hintergrundFeld->render( rObj );
+    }
+    if( vs || hs )
+        rObj.releaseDrawOptions();
+    rObj.releaseDrawOptions();
+    rObj.releaseDrawOptions();
+    unlockZeichnung();
+}
+
+Bild *ZeichnungHintergrund::getHintergrundBild() const // gibt getThis vom Hintergrund Bild zurück
+{
+    if( !hintergrundBild )
+        return 0;
+    return hintergrundBild->getThis();
+}
+
+Bild *ZeichnungHintergrund::zHintergrundBild() const // gibt das Hintergrund Bild zurück
+{
+    return hintergrundBild;
+}
+
+int ZeichnungHintergrund::getHintergrundFarbe() const // giebt getThis der Hintergrundfarbe zurück
+{
+    return hintergrundFarbe;
+}
+
+AlphaFeld *ZeichnungHintergrund::getAlphaFeld() const // gibt getThir vom Hintergrund Buffer zurück
+{
+    if( !hintergrundFeld )
+        return 0;
+    return hintergrundFeld->getThis();
+}
+
+AlphaFeld *ZeichnungHintergrund::zAlphaFeld() const // gibt den Hintergrund Buffer zurück
+{
+    return hintergrundFeld;
+}
+
+int ZeichnungHintergrund::getAlphaFeldStärke() const // gibt die Stärke des Hintergrund Buffers zurück
+{
+    if( !hintergrundFeld )
+        return 0;
+    return hintergrundFeld->getStärke();
+}
+
+int ZeichnungHintergrund::getAlphaFeldFarbe() const // gibt getThis von der Farbe des Hintergrund Buffers zurück
+{
+    return hintergrundFeld->getFarbe();
+}
+
+LRahmen *ZeichnungHintergrund::getLinienRahmen() const // gibt getThis des Rahmens zurück
+{
+    if( !rahmen )
+        return 0;
+    return rahmen->getThis();
+}
+
+LRahmen *ZeichnungHintergrund::zLinienRahmen() const // gibt den Rahmen zurück
+{
+    return rahmen;
+}
+
+int ZeichnungHintergrund::getLinienRahmenBreite() const // gibt die Breite des Rahmens zurück
+{
+    if( !rahmen || hatStyleNicht( Style::Rahmen ) )
+        return 0;
+    return rahmen->getRBreite();
+}
+
+int ZeichnungHintergrund::getLinienRahmenFarbe() const // gibt getThis der Farbe des Rahmens zurück
+{
+    return rahmen->getFarbe();
+}
+
+int ZeichnungHintergrund::getVertikalKlickScroll() const
+{
+    return vertikalScrollBar ? vertikalScrollBar->getKlickScroll() : 0;
+}
+
+int ZeichnungHintergrund::getVertikalScrollPos() const
+{
+    return vertikalScrollBar ? vertikalScrollBar->getScroll() : 0;
+}
+
+int ZeichnungHintergrund::getVertikalScrollFarbe() const
+{
+    return vertikalScrollBar ? vertikalScrollBar->getFarbe() : 0;
+}
+
+int ZeichnungHintergrund::getVertikalScrollHintergrund() const
+{
+    return vertikalScrollBar ? vertikalScrollBar->getBgFarbe() : 0;
+}
+
+int ZeichnungHintergrund::getHorizontalKlickScroll() const
+{
+    return horizontalScrollBar ? horizontalScrollBar->getKlickScroll() : 0;
+}
+
+int ZeichnungHintergrund::getHorizontalScrollPos() const
+{
+    return horizontalScrollBar ? horizontalScrollBar->getScroll() : 0;
+}
+
+int ZeichnungHintergrund::getHorizontalScrollFarbe() const
+{
+    return horizontalScrollBar ? horizontalScrollBar->getFarbe() : 0;
+}
+
+int ZeichnungHintergrund::getHorizontalScrollHintergrund() const
+{
+    return horizontalScrollBar ? horizontalScrollBar->getBgFarbe() : 0;
+}
+
+Zeichnung *ZeichnungHintergrund::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
+{
+    ZeichnungHintergrund *obj = new ZeichnungHintergrund();
+    obj->setPosition( pos );
+    obj->setGröße( gr );
+    obj->setMausEreignisParameter( makParam );
+    obj->setTastaturEreignisParameter( takParam );
+    obj->setMausEreignis( Mak );
+    obj->setTastaturEreignis( Tak );
+    if( toolTip )
+        obj->setToolTipText( toolTip->zText()->getText(), toolTip->zBildschirm() );
+    obj->setStyle( style );
+    obj->setHintergrundFarbe( hintergrundFarbe );
+    if( hintergrundFeld )
+        obj->setAlphaFeldZ( (AlphaFeld*)hintergrundFeld->dublizieren() );
+    if( rahmen )
+        obj->setLinienRahmenZ( (LRahmen*)rahmen->dublizieren() );
+    if( hintergrundBild )
+        obj->setHintergrundBild( hintergrundBild->getThis() );
+    if( vertikalScrollBar )
+    {
+        obj->setVertikalKlickScroll( vertikalScrollBar->getKlickScroll() );
+        obj->setVertikalScrollPos( vertikalScrollBar->getScrollData()->anzeigeBeginn );
+        obj->setVertikalScrollFarbe( vertikalScrollBar->getFarbe(), vertikalScrollBar->getBgFarbe() );
+    }
+    if( horizontalScrollBar )
+    {
+        obj->setHorizontalKlickScroll( horizontalScrollBar->getKlickScroll() );
+        obj->setHorizontalScrollPos( horizontalScrollBar->getScrollData()->anzeigeBeginn );
+        obj->setHorizontalScrollFarbe( horizontalScrollBar->getFarbe(), horizontalScrollBar->getBgFarbe() );
+    }
+    return obj;
+}

+ 260 - 0
Zeichnung.h

@@ -0,0 +1,260 @@
+#ifndef Zeichnung_H
+#define Zeichnung_H
+
+#include "Punkt.h"
+
+namespace Framework
+{
+	struct VScrollData; // Scroll.h
+	struct HScrollData; // Scroll.h
+	struct MausEreignis; // MausEreignis.h
+	struct TastaturEreignis; // TastaturEreignis.h
+	class Bild; // Bild.h
+	class Zeichnung; // Aus dieser Datei
+	class ZeichnungArray; // Aus dieser Datei
+	class ToolTip; // ToopTip.h
+	class Bildschirm; // Bildschirm.h
+    class LRahmen; // Rahmen.h
+    class AlphaFeld; // AlphaFeld.h
+    class VScrollBar; // Scroll.h
+    class HScrollBar; // Scroll.h
+
+	class Zeichnung
+	{
+    public:
+        class Style
+        {
+        public:
+            const static __int64 Sichtbar = 0x00001;
+            const static __int64 Erlaubt = 0x00002;
+            const static __int64 Fokus = 0x00040;// 0x80
+        };
+	protected:
+		Punkt pos;
+		Punkt gr;
+		void *makParam;
+		void *takParam;
+		bool( *Mak )( void *, void *, MausEreignis );
+		bool( *Tak )( void *, void *, TastaturEreignis );
+        void *nmakParam;
+        void *ntakParam;
+        bool( *nMak )( void *, void *, MausEreignis );
+        bool( *nTak )( void *, void *, TastaturEreignis );
+		bool mausIn;
+		CRITICAL_SECTION cs;
+		ToolTip *toolTip;
+        __int64 style;
+		bool rend;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) Zeichnung();
+		// Destruktor 
+		__declspec( dllexport ) ~Zeichnung();
+		// nicht constant 
+		__declspec( dllexport ) void setRender();
+		__declspec( dllexport ) void setToolTipText( const char *txt, Bildschirm *zScreen );
+		__declspec( dllexport ) void lockZeichnung();
+		__declspec( dllexport ) void unlockZeichnung();
+		__declspec( dllexport ) void setMausEreignisParameter( void *p ); // setzt den Parameter vom Maus Ereignis
+		__declspec( dllexport ) void setTastaturEreignisParameter( void *p ); // setzt den Parameter vom Tastatur Ereignis
+		__declspec( dllexport ) void setMausEreignis( bool( *ak )( void *, void *, MausEreignis ) ); // setzt das Maus Ereignis
+		__declspec( dllexport ) void setTastaturEreignis( bool( *ak )( void *, void *, TastaturEreignis ) ); // setzt das TastaturEreignis
+		__declspec( dllexport ) void setNMausEreignisParameter( void *p ); // setzt den Parameter vom Maus Ereignis
+		__declspec( dllexport ) void setNTastaturEreignisParameter( void *p ); // setzt den Parameter vom Tastatur Ereignis
+		__declspec( dllexport ) void setNMausEreignis( bool( *ak )( void *, void *, MausEreignis ) ); // setzt das Maus Ereignis
+		__declspec( dllexport ) void setNTastaturEreignis( bool( *ak )( void *, void *, TastaturEreignis ) ); // setzt das TastaturEreignis
+		__declspec( dllexport ) virtual void doMausEreignis( MausEreignis &me ); // ruft Mak auf
+		__declspec( dllexport ) virtual void doTastaturEreignis( TastaturEreignis &te ); // ruft Tak auf
+		__declspec( dllexport ) virtual bool tick( double tickval ); // tick
+		__declspec( dllexport ) void setPosition( const Punkt &pos ); // setzt die position
+		__declspec( dllexport ) void setX( int xPos ); // setzt die x position
+		__declspec( dllexport ) void setY( int yPos ); // setzt die y position
+		__declspec( dllexport ) void setGröße( const Punkt &gr ); // setzt die Größe
+		__declspec( dllexport ) void setPosition( int x, int y ); // setzt die position
+		__declspec( dllexport ) void setGröße( int x, int y ); // setzt die Größe
+		__declspec( dllexport ) void setStyle( __int64 style ); // setzt den Style des Zeichnunges
+		__declspec( dllexport ) void setStyle( __int64 style, bool add_löschen );
+		__declspec( dllexport ) void addStyle( __int64 style );
+		__declspec( dllexport ) void löscheStyle( __int64 style );
+		__declspec( dllexport ) virtual void render( Bild &zRObj ); // zeichnet nach zRObj
+		// constant 
+		__declspec( dllexport ) bool hatMausEreignis() const; // prüft, ob Mak gesetzt ist
+		__declspec( dllexport ) bool hatTastaturEreignis() const; // prüft, ob Tak gesetzt ist
+		__declspec( dllexport ) const Punkt &getPosition() const; // gibt die Position zurück
+		__declspec( dllexport ) const Punkt &getGröße() const; // gibt die Größe zurück
+		__declspec( dllexport ) int getBreite() const; // gibt die Breite zurück
+		__declspec( dllexport ) int getHöhe() const; // gibt die Höhe zurück
+		__declspec( dllexport ) int getX() const; // gibt X zurück
+		__declspec( dllexport ) int getY() const; // gibt Y zurück
+		__declspec( dllexport ) ToolTip *getToolTip() const; // gibt den ToolTip Text
+		__declspec( dllexport ) ToolTip *zToolTip() const;
+        __declspec( dllexport ) inline bool hatStyle( __int64 style ) const; // prüft, ob style vorhanden
+        __declspec( dllexport ) inline bool hatStyleNicht( __int64 style ) const; // prüft, ob style nicht vorhanden
+		__declspec( dllexport ) virtual Zeichnung *dublizieren() const; // Erzeugt eine Kopie des Zeichnungs
+		// reference Counting 
+	};
+
+	class ZeichnungArray// Array von Zeichnungen
+	{
+	private:
+        Zeichnung *This;
+        ZeichnungArray *next;
+		int index;
+
+	public:
+		// Konstruktor 
+		__declspec( dllexport ) ZeichnungArray();
+		// Destruktor 
+		__declspec( dllexport ) ~ZeichnungArray();
+		// nicht const 
+		__declspec( dllexport ) bool addZeichnung( Zeichnung *obj ); // Fügt ein Zeichnung hinzu
+		__declspec( dllexport ) bool removeZeichnung( Zeichnung *obj ); // Entfernt ein Zeichnung
+		__declspec( dllexport ) bool removeZeichnung( int i ); // Entfernt das i-te Zeichnung
+		__declspec( dllexport ) void setNext0(); // Setzt das nächste Zeichnung zu 0
+		__declspec( dllexport ) void updateIndex( int i ); // aktualisiert die Index variable
+		// constant 
+		__declspec( dllexport ) ZeichnungArray *getNext() const; // gibt das nächste Zeichnung zurück
+		__declspec( dllexport ) Zeichnung *getZeichnung( int i ) const; // gibt das i-te Zeichnung zurück
+		__declspec( dllexport ) Zeichnung *getZeichnung() const; // gibt das Zeichnung zurück
+		__declspec( dllexport ) int getIndex() const; // Gibt den Index zurück
+		__declspec( dllexport ) void sendMausAll( MausEreignis &me ) const; // sendet me an alle volgenden Zeichnunge
+		__declspec( dllexport ) void sendTastaturAll( TastaturEreignis &te ) const; // sendet te an alle volgenden Zeichnunge
+		__declspec( dllexport ) void render( Bild &zRObj ); // Zeichnet alle nach zRObj
+		__declspec( dllexport ) bool tick( double tickval ); // tick
+	};
+
+    class ZeichnungHintergrund : public Zeichnung
+    {
+    public:
+        class Style : public Zeichnung::Style
+        {
+        public:
+            const static __int64 Rahmen = 0x00010; // 0x4
+            const static __int64 Hintergrund = 0x00020; // 0x8
+            const static __int64 HAlpha = 0x00040; // 0x10
+            const static __int64 HBild = 0x00080; // 0x20
+            const static __int64 Buffered = 0x00100; // 0x40
+            const static __int64 VScroll = 0x00200; // Wenn dieser Flag gesetzt wird, erscheint eine Scrollbar am rechten Rand
+            const static __int64 HScroll = 0x00400; // Wenn dieser Flag gesetzt wird, erscheint eine Scrollbar am unteren Rand
+        };
+
+    protected:
+        int hintergrundFarbe;
+        LRahmen *rahmen;
+        Bild *hintergrundBild;
+        AlphaFeld *hintergrundFeld;
+        VScrollBar *vertikalScrollBar;
+        HScrollBar *horizontalScrollBar;
+        Punkt innenPosition;
+        Punkt innenGröße;
+
+    public:
+        // Konstruktor 
+        __declspec( dllexport ) ZeichnungHintergrund();
+        // Destruktor 
+        __declspec( dllexport ) ~ZeichnungHintergrund();
+        // Setzt das Hintergrund Bild (benötigt Flag zum Zeichnen: Hintergrund, HBild)
+        //  bild: Das Bild wird kopiert und als Hintergrundbild verwendet
+        __declspec( dllexport ) void setHintergrundBild( Bild *bild );
+        // Setzt einen Zeiger auf das Hintergrund Bild (benötigt Flag zum Zeichnen: Hintergrund)
+        //  bild: Das Bild wid ohne es zu kopieren verwendet
+        __declspec( dllexport ) void setHintergrundBildZ( Bild *bild );
+        // Setzt die Hintergrund Farbe (benötigt Flag zum Zeichnen: Hintergrund)
+        //  fc: Die Hintergrundfarbe im A8R8G8B8 Format
+        __declspec( dllexport ) void setHintergrundFarbe( int fc );
+        // Setzt einen Zeiger auf das AlphaFeld (benötigt Flag zum Zeichnen: Buffered)
+        //  buff: Das AlphaFeld, das über den Hintergrund gezeichnet werden soll
+        __declspec( dllexport ) void setAlphaFeldZ( AlphaFeld *buff );
+        // Setzt die Stärke des AlphaFeldes (benötigt Flag zum Zeichnen: Buffered)
+        //  st: Die Stärke des AlphaFeldes, welches über dem Hintergrund gezeichnet werden soll
+        __declspec( dllexport ) void setAlphaFeldStärke( int st );
+        // Setzt die Farbe des AlphaFeldes (benötigt Flag zum Zeichnen: Buffered)
+        //  fc: Die Farbe des AlphaFeldes, welches über dem Hintergrund gezeichnet werden soll
+        __declspec( dllexport ) void setAlphaFeldFarbe( int fc );
+        // Setzt einen Zeiger zu dem Linien Rahmen, der um das TextFeld gezeichnet werden soll (benötigt Flag zum Zeichnen: Rahmen)
+        //  ram: Der Rahmen
+        __declspec( dllexport ) void setLinienRahmenZ( LRahmen *ram );
+        // Setzt die Breite des Linien Rahmens (benötigt Flag zum Zeichnen: Rahmen)
+        //  br: Die Breite in Pixeln
+        __declspec( dllexport ) void setLinienRahmenBreite( int br );
+        // Setzt die Farbe des Linien Rahmens (benötigt Flag zum Zeichnen: Rahmen)
+        //  fc: Die Farbe im A8R8G8B8 Format
+        __declspec( dllexport ) void setLinienRahmenFarbe( int fc );
+        // Setzt die Scrollgeschwindigkeit der vertikalen ScrollBar (benötigt Flag zum Zeichnen: VScroll)
+        //  ks: Die Scrollgeschwindigkeit in Pixeln für jeden Maus Klick
+        __declspec( dllexport ) void setVertikalKlickScroll( int ks );
+        // Scrollt an eine Bestimmte Stelle bei der vertikalen ScrollBar (benötigt Flag zum Zeichnen: VScroll)
+        //  pos: Das Scroll Offset in Pixeln.
+        __declspec( dllexport ) void setVertikalScrollPos( int pos );
+        // Setzt die Farbe der vertikalen ScrollBar (benötigt Flag zum Zeichnen: VScroll)
+        //  f: Die Fordergrundfarbe der ScrollBar im A8R8G8B8 Format
+        //  bgF: Die Hintergrundfarbe der ScrollBar im A8R8G8B8 Format
+        __declspec( dllexport ) void setVertikalScrollFarbe( int f, int bgF );
+        // Setzt die Scrollgeschwindigkeit der horizontalen ScrollBar (benötigt Flag zum Zeichnen: HScroll)
+        //  ks: Die Scrollgeschwindigkeit in Pixeln für jeden Maus Klick
+        __declspec( dllexport ) void setHorizontalKlickScroll( int ks );
+        // Scrollt an eine Bestimmte Stelle bei der horizontalen ScrollBar (benötigt Flag zum Zeichnen: HScroll)
+        //  pos: Das Scroll Offset in Pixeln.
+        __declspec( dllexport ) void setHorizontalScrollPos( int pos );
+        // Setzt die Farbe der horizontalen ScrollBar (benötigt Flag zum Zeichnen: HScroll)
+        //  f: Die Fordergrundfarbe der ScrollBar im A8R8G8B8 Format
+        //  bgF: Die Hintergrundfarbe der ScrollBar im A8R8G8B8 Format
+        __declspec( dllexport ) void setHorizontalScrollFarbe( int f, int bgF );
+        // Updated den Zeichenhintergrund
+        //  tickVal: Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf dieser Funktion verstrichen ist
+        //  return: 1, wenn das Bild neu gezeichnet werden muss. 0 sonnst
+        __declspec( dllexport ) bool tick( double tickVal ) override;
+        // Zeichnet den Hintergrund eines Zeichnunges nach rObj
+        __declspec( dllexport ) void render( Bild &rObj ) override;
+
+        // Gibt das Hintergrundbild zurück.
+        //  return: 0, falls kein Hintergrundbild verwendet wird
+        __declspec( dllexport ) Bild *getHintergrundBild() const;
+        // Gibt das Hintergrundbild ohne erhöhten reference Counter zurück.
+        //  return: 0, falls kein Hintergrundbild verwendet wird
+        __declspec( dllexport ) Bild *zHintergrundBild() const;
+        // Gibt die Hintergrundfarbe im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getHintergrundFarbe() const;
+        // Gibt das AlphaFeld zurück, das über den Hintergrund gezeichnet wird.
+        //  return: 0, falls das AlphaFeld nicht definiert wurde
+        __declspec( dllexport ) AlphaFeld *getAlphaFeld() const;
+        // Gibt das AlphaFeld ohne erhöhten Reference Counter zurück, das über den Hintergrund gezeichnet wird.
+        //  return: 0, falls das AlphaFeld nicht definiert wurde
+        __declspec( dllexport ) AlphaFeld *zAlphaFeld() const;
+        // Git die Stärke des Alphafeldes zurück
+        __declspec( dllexport ) int getAlphaFeldStärke() const;
+        // Gibt die Farbe des Alphafedes im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getAlphaFeldFarbe() const;
+        // Gibt den Rahmen zurück
+        //  return: 0, falls kein Rahmen definiert wurde
+        __declspec( dllexport ) LRahmen *getLinienRahmen() const;
+        // Gibt den Rahmen ohne erhöhten Reference Counter zurück
+        //  return: 0, falls kein Rahmen definiert wurde
+        __declspec( dllexport ) LRahmen *zLinienRahmen() const;
+        // Gibt die Breite des Rahmens in Pixeln zurück
+        __declspec( dllexport ) int getLinienRahmenBreite() const;
+        // Gibt die Farbe des Rahmens im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getLinienRahmenFarbe() const;
+        // Gibt die Scroll geschwindigkeit der vertikalen Scroll Bar zurück
+        __declspec( dllexport ) int getVertikalKlickScroll() const;
+        // Gibt die Scroll Position der vertikalen Scroll Bar zurück
+        __declspec( dllexport ) int getVertikalScrollPos() const;
+        // Gibt die Farbe der vertikalen Scroll Bar im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getVertikalScrollFarbe() const;
+        // Gibt die Hintergrundfarbe der vertikalen Scroll Bar im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getVertikalScrollHintergrund() const;
+        // Gibt die Scroll geschwindigkeit der horizontalen Scroll Bar zurück
+        __declspec( dllexport ) int getHorizontalKlickScroll() const;
+        // Gibt die Scroll Position der horizontalen Scroll Bar zurück
+        __declspec( dllexport ) int getHorizontalScrollPos() const;
+        // Gibt die Farbe der horizontalen Scroll Bar im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getHorizontalScrollFarbe() const;
+        // Gibt die Hintergrundfarbe der horizontalen Scroll Bar im A8R8G8B8 Format zurück
+        __declspec( dllexport ) int getHorizontalScrollHintergrund() const;
+        // Erzeugt eine Kopie der Zeichnung, die ohne Auswirkungen auf das Original verändert werden kann
+        __declspec( dllexport ) virtual Zeichnung *dublizieren() const;
+    };
+}
+
+#endif

+ 200 - 0
Zeichnung3D.cpp

@@ -0,0 +1,200 @@
+#include "Zeichnung3D.h"
+
+using namespace Framework;
+// Inhalt der Zeichnung3D Klasse
+
+// Konstruktor
+Zeichnung3D::Zeichnung3D()
+{
+    welt = welt.identity();
+    pos = Vec3< float >( 0, 0, 0 );
+    angle = Vec3< float >( 0, 0, 0 );
+    rend = 0;
+    alpha = 0;
+    radius = 0;
+}
+
+// Setzt die Position der Zeichnung in der Welt
+//  p: Die Position
+void Zeichnung3D::setPosition( Vec3< float > &p )
+{
+    pos = p;
+    rend = 1;
+}
+
+// Setzt die Position der Zeichnung in der Welt
+//  x: Die x Position
+//  y: Die y Position
+//  z: Die z Position
+void Zeichnung3D::setPosition( float x, float y, float z )
+{
+    pos.x = x;
+    pos.y = y;
+    pos.z = z;
+    rend = 1;
+}
+
+// Setzt die Position der Zeichnung in der Welt
+//  x: Die x Position
+void Zeichnung3D::setX( float x )
+{
+    pos.x = x;
+    rend = 1;
+}
+
+// Setzt die Position der Zeichnung in der Welt
+//  y: Die y Position
+void Zeichnung3D::setY( float y )
+{
+    pos.y = y;
+    rend = 1;
+}
+
+// Setzt die Position der Zeichnung in der Welt
+//  z: Die z Position
+void Zeichnung3D::setZ( float z )
+{
+    pos.z = z;
+    rend = 1;
+}
+
+// Setzt die Drehung der Zeichnung in der Welt
+//  d: Die drehung um die x, y und z achse
+void Zeichnung3D::setDrehung( Vec3< float > &d )
+{
+    angle = d;
+    rend = 1;
+}
+
+// Setzt die Drehung der Zeichnung in der Welt
+//  xWinkel: Die drehung um die x achse
+//  yWinkel: Die drehung um die y achse
+//  zWinkel: Die drehung um die z achse
+void Zeichnung3D::setDrehung( float xWinkel, float yWinkel, float zWinkel )
+{
+    angle.x = xWinkel;
+    angle.y = yWinkel;
+    angle.z = zWinkel;
+    rend = 1;
+}
+
+// Setzt die Drehung der Zeichnung in der Welt
+//  winkel: Die drehung um die x achse
+void Zeichnung3D::setDrehungX( float winkel )
+{
+    angle.x = winkel;
+    rend = 1;
+}
+
+// Setzt die Drehung der Zeichnung in der Welt
+//  winkel: Die drehung um die y achse
+void Zeichnung3D::setDrehungY( float winkel )
+{
+    angle.y = winkel;
+    rend = 1;
+}
+
+// Setzt die Drehung der Zeichnung in der Welt
+//  winkel: Die drehung um die z achse
+void Zeichnung3D::setDrehungZ( float winkel )
+{
+    angle.z = winkel;
+    rend = 1;
+}
+
+// Legt fest, ob das Objekt teilweise oder ganz transparente stellen enthält
+//  a: true, wenn teilweise oder ganz transparente stellen vorhanden sind
+void Zeichnung3D::setAlpha( bool a )
+{
+    alpha = a;
+    rend = 1;
+}
+
+// Verarbeitet ein Mausereignis
+//  me: Das Mausereignis, das verarbeitet werden soll
+void Zeichnung3D::doMausEreignis( MausEreignis &me )
+{}
+
+// Verarbeitet ein Tastaturereignis
+//  te: das Tastaturereignis, das verarbeitet werden soll
+void Zeichnung3D::doTastaturEreignis( TastaturEreignis &te )
+{}
+
+// Verarbeitet die vergangene Zeit
+//  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+//  return: true, wenn sich das Objekt verändert hat, false sonnst.
+bool Zeichnung3D::tick( double tickval )
+{
+    if( rend )
+    {
+        welt = welt.translation( pos ) * welt.rotationZ( angle.z ) * welt.rotationX( angle.x ) * welt.rotationY( angle.y );
+        rend = 0;
+        return 1;
+    }
+    return 0;
+}
+
+// Zeichnet das Objekt
+//  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+void Zeichnung3D::render( Render3D *zRObj )
+{}
+
+// Gibt zurück, ob das Objekt teilweise oder ganz transparente stellen enthält
+bool Zeichnung3D::hatAlpha() const
+{
+    return alpha;
+}
+
+// Gibt den radius einer Kugel zurück, die das gesammte Model umschließt
+float Zeichnung3D::getRadius() const
+{
+    return radius;
+}
+
+// Gibt einen Punkt zurück, der die Position der Zeichnung in der Welt darstellt
+const Vec3< float > &Zeichnung3D::getPos() const
+{
+    return pos;
+}
+
+// Gibt die X Position der Zeichnung in der Welt zurück
+float Zeichnung3D::getX() const
+{
+    return pos.x;
+}
+
+// Gibt die Y Position der Zeichnung in der Welt zurück
+float Zeichnung3D::getY() const
+{
+    return pos.y;
+}
+
+// Gibt die Z Position der Zeichnung in der Welt zurück
+float Zeichnung3D::getZ() const
+{
+    return pos.z;
+}
+
+// Gibt einen Vektor zurück, der die drehung der Zeichnung in der Welt darstellt. x ist die Drehung um die X Achse im Bogenmaß usw
+const Vec3< float > &Zeichnung3D::getDrehung() const
+{
+    return angle;
+}
+
+// Gibt die Drehung um die X Achse im Bogenmaß zurück
+float Zeichnung3D::getXDrehung() const
+{
+    return angle.x;
+}
+
+// Gibt die Drehung um die Y Achse im Bogenmaß zurück
+float Zeichnung3D::getYDrehung() const
+{
+    return angle.y;
+}
+
+// Gibt die Drehung um die Z Achse im Bogenmaß zurück
+float Zeichnung3D::getZDrehung() const
+{
+    return angle.z;
+}

+ 96 - 0
Zeichnung3D.h

@@ -0,0 +1,96 @@
+#pragma once
+
+#include "Mat4.h"
+
+namespace Framework
+{
+    struct MausEreignis;
+    struct TastaturEreignis;
+    class Render3D; // Render3D.h
+
+    // Ein Objekt, das von der Bildschirm3D Klasse gezeichnet werden kann.
+    class Zeichnung3D
+    {
+    protected:
+        Vec3< float > pos; // Position des Objekts
+        Vec3< float > angle; // Drehungswinkel für x, y und z
+        Mat4< float > welt; // Wlet translation matrix
+        float radius; // Der radius einer Kugel, der das gesamte Objekt umschließt
+        bool alpha; // Speichert ob das Objekt teilweise oder ganz transparente stellen enthält
+        bool rend;
+
+    public:
+        // Konstruktor
+        __declspec( dllexport ) Zeichnung3D();
+        // Setzt die Position der Zeichnung in der Welt
+        //  p: Die Position
+        __declspec( dllexport ) void setPosition( Vec3< float > &p );
+        // Setzt die Position der Zeichnung in der Welt
+        //  x: Die x Position
+        //  y: Die y Position
+        //  z: Die z Position
+        __declspec( dllexport ) void setPosition( float x, float y, float z );
+        // Setzt die Position der Zeichnung in der Welt
+        //  x: Die x Position
+        __declspec( dllexport ) void setX( float x );
+        // Setzt die Position der Zeichnung in der Welt
+        //  y: Die y Position
+        __declspec( dllexport ) void setY( float y );
+        // Setzt die Position der Zeichnung in der Welt
+        //  z: Die z Position
+        __declspec( dllexport ) void setZ( float z );
+        // Setzt die Drehung der Zeichnung in der Welt
+        //  d: Die drehung um die x, y und z achse
+        __declspec( dllexport ) void setDrehung( Vec3< float > &d );
+        // Setzt die Drehung der Zeichnung in der Welt
+        //  xWinkel: Die drehung um die x achse
+        //  yWinkel: Die drehung um die y achse
+        //  zWinkel: Die drehung um die z achse
+        __declspec( dllexport ) void setDrehung( float xWinkel, float yWinkel, float zWinkel );
+        // Setzt die Drehung der Zeichnung in der Welt
+        //  winkel: Die drehung um die x achse
+        __declspec( dllexport ) void setDrehungX( float winkel );
+        // Setzt die Drehung der Zeichnung in der Welt
+        //  winkel: Die drehung um die y achse
+        __declspec( dllexport ) void setDrehungY( float winkel );
+        // Setzt die Drehung der Zeichnung in der Welt
+        //  winkel: Die drehung um die z achse
+        __declspec( dllexport ) void setDrehungZ( float winkel );
+        // Legt fest, ob das Objekt teilweise oder ganz transparente stellen enthält
+        //  a: true, wenn teilweise oder ganz transparente stellen vorhanden sind
+        __declspec( dllexport ) void setAlpha( bool a );
+        // Verarbeitet ein Mausereignis
+        //  me: Das Mausereignis, das verarbeitet werden soll
+        __declspec( dllexport ) virtual void doMausEreignis( MausEreignis &me );
+        // Verarbeitet ein Tastaturereignis
+        //  te: das Tastaturereignis, das verarbeitet werden soll
+        __declspec( dllexport ) virtual void doTastaturEreignis( TastaturEreignis &te );
+        // Verarbeitet die vergangene Zeit
+        //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
+        //  return: true, wenn sich das Objekt verändert hat, false sonnst.
+        __declspec( dllexport ) virtual bool tick( double tickval );
+        // Zeichnet das Objekt
+        //  zRObj: Ein Zeiger auf das Objekt, das zum Zeichnen verwendet werden soll (ohne erhöhten Reference Counter)
+		__declspec( dllexport ) virtual void render( Render3D *zRObj );
+        // Gibt zurück, ob das Objekt teilweise oder ganz transparente stellen enthält
+        __declspec( dllexport ) bool hatAlpha() const;
+        // Gibt den radius einer Kugel zurück, die das gesammte Model umschließt
+        __declspec( dllexport ) float getRadius() const;
+        // Gibt einen Punkt zurück, der die Position der Zeichnung in der Welt darstellt
+        const Vec3< float > &getPos() const;
+        // Gibt die X Position der Zeichnung in der Welt zurück
+        float getX() const;
+        // Gibt die Y Position der Zeichnung in der Welt zurück
+        float getY() const;
+        // Gibt die Z Position der Zeichnung in der Welt zurück
+        float getZ() const;
+        // Gibt einen Vektor zurück, der die drehung der Zeichnung in der Welt darstellt. x ist die Drehung um die X Achse im Bogenmaß usw
+        const Vec3< float > &getDrehung() const;
+        // Gibt die Drehung um die X Achse im Bogenmaß zurück
+        float getXDrehung() const;
+        // Gibt die Drehung um die Y Achse im Bogenmaß zurück
+        float getYDrehung() const;
+        // Gibt die Drehung um die Z Achse im Bogenmaß zurück
+        float getZDrehung() const;
+    };
+}

+ 1983 - 0
Zeit.cpp

@@ -0,0 +1,1983 @@
+#include "Zeit.h"
+#include "Text.h"
+#include <time.h>
+#include <ctime>
+#ifdef WIN32
+#include "Fenster.h"
+#else
+#include <string.h>
+#include <sys/time.h>
+#endif
+
+#ifdef WIN32
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+#else
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+#endif
+
+struct timeval
+{
+	long tv_sec;        // Sekunden seit dem 1.1.1970
+	long tv_usec;       // und Mikrosekunden
+};
+
+struct timezone
+{
+	int tz_minuteswest; // minutes W of Greenwich
+	int tz_dsttime;     // type of dst correction
+};
+
+int gettimeofday( struct timeval *tv, struct timezone *tz )
+{
+	FILETIME ft;
+	unsigned __int64 tmpres = 0;
+	static int tzflag;
+
+	if( NULL != tv )
+	{
+		GetSystemTimeAsFileTime( &ft );
+
+		tmpres |= ft.dwHighDateTime;
+		tmpres <<= 32;
+		tmpres |= ft.dwLowDateTime;
+
+		//converting file time to unix epoch
+		tmpres -= DELTA_EPOCH_IN_MICROSECS;
+		tmpres /= 10;  //convert into microseconds
+		tv->tv_sec = (long)( tmpres / 1000000UL );
+		tv->tv_usec = (long)( tmpres % 1000000UL );
+	}
+
+	if( NULL != tz )
+	{
+		if( !tzflag )
+		{
+			_tzset();
+			++tzflag;
+		}
+		_get_timezone( (long*)&( tz->tz_minuteswest ) );
+		tz->tz_minuteswest /= 60;
+		_get_daylight( &( tz->tz_dsttime ) );
+	}
+
+	return 0;
+}
+
+#endif
+
+
+using namespace Framework;
+
+// Inhalt der Uhrzeit Klasse aus Zeit.h
+// Privat 
+int Uhrzeit::update() // berechnet die neue Zeit
+{
+	int ret = 0;
+	while( sekunde >= 60 )
+	{
+		sekunde -= 60;
+		++minute;
+	}
+	while( minute >= 60 )
+	{
+		minute -= 60;
+		++stunde;
+	}
+	while( stunde >= 24 )
+	{
+		stunde -= 24;
+		++ret;
+	}
+	while( sekunde < 0 )
+	{
+		sekunde += 60;
+		--minute;
+	}
+	while( minute < 0 )
+	{
+		minute += 60;
+		--stunde;
+	}
+	while( stunde < 0 )
+	{
+		stunde += 24;
+		--ret;
+	}
+	return ret;
+}
+
+Uhrzeit::Uhrzeit()
+	: stunde( 0 ),
+	  minute( 0 ),
+	  sekunde( 0 ),
+	  ref( 1 )
+{
+}
+
+int Uhrzeit::setUhrzeit( Uhrzeit *zeit ) // setzt die Uhrzeit
+{
+	stunde = zeit->getStunde();
+	minute = zeit->getMinute();
+	sekunde = zeit->getSekunde();
+	zeit->release();
+	return update();
+}
+
+int Uhrzeit::setUhrzeit( int stunde, int minute, int sekunde )
+{
+	this->stunde = stunde;
+	this->minute = minute;
+	this->sekunde = sekunde;
+	return update();
+}
+
+int Uhrzeit::setUhrzeit( const char *format, const char *zeit ) // format Beispiele: "H:i:s", "H-i-s" (H=stunde,i=minute,s=sekunde)
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			stunde = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			minute = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sekunde = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return update();
+}
+
+int Uhrzeit::setUhrzeit( const char *format, Text *zeit )
+{
+	int ret = setUhrzeit( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+int Uhrzeit::setStunde( int stunde ) // setzt die Stunde
+{
+	this->stunde = stunde;
+	return update();
+}
+
+int Uhrzeit::setMinute( int minute ) // setzt die Minute
+{
+	this->minute = minute;
+	return update();
+}
+
+int Uhrzeit::setSekunde( int sekunde ) // setzt die Sekunde
+{
+	this->sekunde = sekunde;
+	return update();
+}
+
+int Uhrzeit::plusUhrzeit( Uhrzeit *zeit ) // addiert die zeiten
+{
+	stunde += zeit->getStunde();
+	minute += zeit->getMinute();
+	sekunde += zeit->getSekunde();
+	return update();
+}
+
+int Uhrzeit::plusUhrzeit( int stunde, int minute, int sekunde )
+{
+	this->stunde += stunde;
+	this->minute += minute;
+	this->sekunde += sekunde;
+	return update();
+}
+
+int Uhrzeit::plusUhrzeit( const char *format, const char *zeit )
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			stunde += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			minute += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sekunde += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return update();
+}
+
+int Uhrzeit::plusUhrzeit( const char *format, Text *zeit )
+{
+	int ret = plusUhrzeit( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+int Uhrzeit::plusStunde( int stunde ) // addiert stunde Stunden
+{
+	this->stunde += stunde;
+	return update();
+}
+
+int Uhrzeit::plusMinute( int minute ) // addiert minute Minuten
+{
+	this->minute += minute;
+	return update();
+}
+
+int Uhrzeit::plusSekunde( int sekunde ) // addiert sekunde Sekunden
+{
+	this->sekunde += sekunde;
+	return update();
+}
+
+int Uhrzeit::minusUhrzeit( Uhrzeit *zeit ) // subtrahiert die zeiten
+{
+	stunde -= zeit->getStunde();
+	minute -= zeit->getMinute();
+	sekunde -= zeit->getSekunde();
+	zeit->release();
+	return update();
+}
+
+int Uhrzeit::minusUhrzeit( int stunde, int minute, int sekunde )
+{
+	this->stunde -= stunde;
+	this->minute -= minute;
+	this->sekunde -= sekunde;
+	return update();
+}
+
+int Uhrzeit::minusUhrzeit( const char *format, const char *zeit )
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			stunde -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			minute -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sekunde -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return update();
+}
+
+int Uhrzeit::minusUhrzeit( const char *format, Text *zeit )
+{
+	int ret = plusUhrzeit( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+int Uhrzeit::minusStunde( int stunde ) // subtrahiert stunde Stunden
+{
+	this->stunde -= stunde;
+	return update();
+}
+
+int Uhrzeit::minusMinute( int minute ) // subtrahiert minute Minuten
+{
+	this->minute -= minute;
+	return update();
+}
+
+int Uhrzeit::minusSekunde( int sekunde ) // subtrahiert sekunde Sekunden
+{
+	this->sekunde -= sekunde;
+	return update();
+}
+
+// constant 
+int Uhrzeit::getStunde() const // gibt die Stunde zurück
+{
+	return stunde;
+}
+
+int Uhrzeit::getMinute() const // gibt die Minute zurück
+{
+	return minute;
+}
+
+int Uhrzeit::getSekunde() const // gibt die Sekunde zurück
+{
+	return sekunde;
+}
+
+Text *Uhrzeit::getUhrzeit( const char *format ) const // gibt die Uhrzeit als Text formatiert zurück
+{
+	Text *ret = new Text( "" );
+	int flän = textLänge( format );
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			ret->anhängen( stunde );
+			break;
+		case 'i':
+			ret->anhängen( minute );
+			break;
+		case 's':
+			ret->anhängen( sekunde );
+			break;
+		default:
+			ret->anhängen( f, 1 );
+			break;
+		}
+	}
+	return ret;
+}
+
+bool Uhrzeit::istGleich( Uhrzeit *zeit ) const // prüft, ob die Uhrzeit gleich zeit ist
+{
+	bool ret = stunde == zeit->getStunde() &&
+		minute == zeit->getMinute() &&
+		sekunde == zeit->getSekunde();
+	zeit->release();
+	return ret;
+}
+
+bool Uhrzeit::istGleich( const char *format, const char *zeit ) const
+{
+	int st = stunde, min = minute, sek = sekunde;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			st = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			min = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sek = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	bool ret = stunde == st &&
+		minute == min &&
+		sekunde == sek;
+	return ret;
+}
+
+bool Uhrzeit::istGleich( const char *format, Text *zeit ) const
+{
+	bool ret = istGleich( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+bool Uhrzeit::istGleich( int stunde, int minute, int sekunde ) const
+{
+	return this->stunde == stunde &&
+		this->minute == minute &&
+		this->sekunde == sekunde;
+}
+
+bool Uhrzeit::stundeGleich( int stunde ) const // prüft, ob die Stunde gleich stunde ist
+{
+	return this->stunde == stunde;
+}
+
+bool Uhrzeit::minuteGleich( int minute ) const // prüft, ob die Minute gleich minute ist
+{
+	return this->minute == minute;
+}
+
+bool Uhrzeit::sekundeGleich( int sekunde ) const // prüft, ob die Sekunde gleich sekunde ist
+{
+	return this->sekunde == sekunde;
+}
+
+bool Uhrzeit::istKleiner( Uhrzeit *zeit ) const // prüft, ob die Zeit kleiner als zeit ist
+{
+	bool ret = istKleiner( zeit->getStunde(), zeit->getMinute(), zeit->getSekunde() );
+	zeit->release();
+	return ret;
+}
+
+bool Uhrzeit::istKleiner( int stunde, int minute, int sekunde ) const
+{
+	if( this->stunde < stunde )
+		return 1;
+	else if( this->stunde == stunde )
+	{
+		if( this->minute < minute )
+			return 1;
+		else if( this->minute == minute )
+		{
+			if( this->sekunde < sekunde )
+				return 1;
+			else if( this->sekunde == sekunde )
+				return 0;
+			else
+				return 0;
+		}
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Uhrzeit::istKleiner( const char *format, const char *zeit ) const
+{
+	int st = stunde, min = minute, sek = sekunde;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			st = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			min = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sek = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return istKleiner( st, min, sek );
+}
+
+bool Uhrzeit::istKleiner( const char *format, Text *zeit ) const
+{
+	bool ret = istKleiner( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+bool Uhrzeit::istGrößer( Uhrzeit *zeit ) const // prüft, ob die Zeit größer als zeit ist
+{
+	bool ret = istGrößer( zeit->getStunde(), zeit->getMinute(), zeit->getSekunde() );
+	zeit->release();
+	return ret;
+}
+
+bool Uhrzeit::istGrößer( int stunde, int minute, int sekunde ) const
+{
+	if( this->stunde > stunde )
+		return 1;
+	else if( this->stunde == stunde )
+	{
+		if( this->minute > minute )
+			return 1;
+		else if( this->minute == minute )
+		{
+			if( this->sekunde > sekunde )
+				return 1;
+			else if( this->sekunde == sekunde )
+				return 0;
+			else
+				return 0;
+		}
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Uhrzeit::istGrößer( const char *format, const char *zeit ) const
+{
+	int st = stunde, min = minute, sek = sekunde;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'h':
+			st = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			min = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			sek = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return istGrößer( st, min, sek );
+}
+
+bool Uhrzeit::istGrößer( const char *format, Text *zeit ) const
+{
+	bool ret = istGrößer( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+// Reference Counting 
+Uhrzeit *Uhrzeit::getThis()
+{
+	++ref;
+	return this;
+}
+
+Uhrzeit *Uhrzeit::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der Datum Klasse aus Zeit.h
+// Privat 
+void Datum::update() // berechnet die neue Zeit
+{
+	while( monat > 12 )
+	{
+		monat -= 12;
+		++jahr;
+	}
+	while( monat <= 0 )
+	{
+		monat += 12;
+		--jahr;
+	}
+	if( istSchaltjahr( jahr ) )
+		maxTage[ 1 ] = 29;
+	else
+		maxTage[ 1 ] = 28;
+	while( tag > maxTage[ monat - 1 ] )
+	{
+		tag -= maxTage[ monat - 1 ];
+		++monat;
+		if( monat > 12 )
+		{
+			monat -= 12;
+			++jahr;
+			if( istSchaltjahr( jahr ) )
+				maxTage[ 1 ] = 29;
+			else
+				maxTage[ 1 ] = 28;
+		}
+	}
+	while( tag <= 0 )
+	{
+		tag += maxTage[ ( monat - 2 > 0 ? monat - 2 : 11 ) ];
+		--monat;
+		if( monat <= 0 )
+		{
+			monat += 12;
+			--jahr;
+			if( istSchaltjahr( jahr ) )
+				maxTage[ 1 ] = 29;
+			else
+				maxTage[ 1 ] = 28;
+		}
+	}
+}
+
+// Konstruktor 
+Datum::Datum()
+	: jahr( 0 ),
+	  monat( 0 ),
+	  tag( 0 ),
+	  ref( 1 )
+{
+	int maxT[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+    maxTage = new int[ 12 ];
+	memcpy( maxTage, maxT, 12 * sizeof( int ) );
+}
+
+// Destruktor 
+Datum::~Datum()
+{
+    delete[] maxTage;
+}
+
+// nicht constant 
+void Datum::setDatum( Datum *datum ) // setzt das Datum
+{
+	jahr = datum->getJahr();
+	monat = datum->getMonat();
+	tag = datum->getTag();
+	datum->release();
+	update();
+}
+
+void Datum::setDatum( int jahr, int monat, int tag )
+{
+	this->jahr = jahr;
+	this->monat = monat;
+	this->tag = tag;
+	update();
+}
+
+void Datum::setDatum( const char *format, const char *datum ) // format Beispiele: "Y:m:d", "Y-m-d" (Y=Jahr,m=Monat,d=tag)
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			jahr = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			monat = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			tag = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	update();
+}
+
+void Datum::setDatum( const char *format, Text *datum )
+{
+	setDatum( format, datum->getText() );
+	datum->release();
+}
+
+void Datum::setJahr( int jahr ) // setzt das Jahr
+{
+	this->jahr = jahr;
+	update();
+}
+
+void Datum::setMonat( int monat ) // setzt den Monat
+{
+	this->monat = monat;
+	update();
+}
+
+void Datum::setTag( int tag ) // setzt den Tag
+{
+	this->tag = tag;
+	update();
+}
+
+void Datum::plusDatum( Datum *datum ) // addiert das datum
+{
+	this->jahr += datum->getJahr();
+	this->monat += datum->getMonat();
+	this->tag += datum->getTag();
+	datum->release();
+	update();
+}
+
+void Datum::plusDatum( int jahr, int monat, int tag )
+{
+	this->jahr += jahr;
+	this->monat += monat;
+	this->tag += tag;
+	update();
+}
+
+void Datum::plusDatum( const char *format, const char *datum )
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			jahr += TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			monat += TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			tag += TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	update();
+}
+
+void Datum::plusDatum( const char *format, Text *datum )
+{
+	plusDatum( format, datum->getText() );
+	datum->release();
+}
+
+void Datum::plusJahr( int jahr ) // addiert jahr Jahre
+{
+	this->jahr += jahr;
+	update();
+}
+
+void Datum::plusMonat( int monat ) // addiert monat Monate
+{
+	this->monat = monat;
+	update();
+}
+
+void Datum::plusTag( int tag ) // addiert tag Tage
+{
+	this->tag += tag;
+	update();
+}
+
+void Datum::minusDatum( Datum *datum ) // subtrahiert das datum
+{
+	jahr -= datum->getJahr();
+	monat -= datum->getMonat();
+	tag -= datum->getTag();
+	datum->release();
+	update();
+}
+
+void Datum::minusDatum( int jahr, int monat, int tag )
+{
+	this->jahr -= jahr;
+	this->monat -= monat;
+	this->tag -= tag;
+	update();
+}
+
+void Datum::minusDatum( const char *format, const char *datum )
+{
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			jahr -= TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			monat -= TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			tag -= TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	update();
+}
+
+void Datum::minusDatum( const char *format, Text *datum )
+{
+	minusDatum( format, datum->getText() );
+	datum->release();
+}
+
+void Datum::minusJahr( int jahr ) // subtrahiert jahr Jahre
+{
+	this->jahr -= jahr;
+	update();
+}
+
+void Datum::minusMonat( int monat ) // subtrahiert monat Monate
+{
+	this->monat -= monat;
+	update();
+}
+
+void Datum::minusTag( int tag ) // subtrahiert tag Tage
+{
+	this->tag -= tag;
+	update();
+}
+
+// constant 
+int Datum::getJahr() const // gibt das Jahr zurück
+{
+	return jahr;
+}
+
+int Datum::getMonat() const // gibt der Monat zurück
+{
+	return monat;
+}
+
+int Datum::getTag() const // gibt der Tag zurück
+{
+	return tag;
+}
+
+Text *Datum::getDatum( const char *format ) const // gibt das Datum als Text formatiert zurück
+{
+	Text *ret = new Text( "" );
+	int flän = textLänge( format );
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			ret->anhängen( jahr );
+			break;
+		case 'm':
+			ret->anhängen( monat );
+			break;
+		case 'd':
+			ret->anhängen( tag );
+			break;
+		default:
+			ret->anhängen( f, 1 );
+			break;
+		}
+	}
+	return ret;
+}
+
+bool Datum::istGleich( Datum *datum ) const // prüft, ob das Datum gleich datum ist
+{
+	bool ret = jahr == datum->getJahr() &&
+		monat == datum->getMonat() &&
+		tag == datum->getTag();
+	datum->release();
+	return ret;
+}
+
+bool Datum::istGleich( const char *format, const char *datum ) const
+{
+	int j = jahr, m = monat, t = tag;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			j = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			t = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	bool ret = jahr == j &&
+		monat == m &&
+		tag == t;
+	return ret;
+}
+
+bool Datum::istGleich( const char *format, Text *datum ) const
+{
+	bool ret = istGleich( format, datum->getText() );
+	datum->release();
+	return ret;
+}
+
+bool Datum::istGleich( int jahr, int monat, int tag ) const
+{
+	return this->jahr == jahr &&
+		this->monat == monat &&
+		this->tag == tag;
+}
+
+bool Datum::jahrGleich( int jahr ) const // prüft, ob das Jahr gleich jahr ist
+{
+	return this->jahr == jahr;
+}
+
+bool Datum::monatGleich( int monat ) const // prüft, ob der Monat gleich monat ist
+{
+	return this->monat == monat;
+}
+
+bool Datum::tagGleich( int tag ) const // prüft, ob der Tag gleich tag ist
+{
+	return this->tag == tag;
+}
+
+bool Datum::istKleiner( Datum *datum ) const // prüft, ob die Datum kleiner als datum ist
+{
+	bool ret = istKleiner( datum->getJahr(), datum->getMonat(), datum->getTag() );
+	datum->release();
+	return ret;
+}
+
+bool Datum::istKleiner( int jahr, int monat, int tag ) const
+{
+	if( this->jahr < jahr )
+		return 1;
+	else if( this->jahr == jahr )
+	{
+		if( this->monat < monat )
+			return 1;
+		else if( this->monat == monat )
+		{
+			if( this->tag < tag )
+				return 1;
+			else if( this->tag == tag )
+				return 0;
+			else
+				return 0;
+		}
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Datum::istKleiner( const char *format, const char *datum ) const
+{
+	int j = jahr, m = monat, t = tag;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			j = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			t = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	return istKleiner( j, m, t );
+}
+
+bool Datum::istKleiner( const char *format, Text *datum ) const
+{
+	bool ret = istKleiner( format, datum->getText() );
+	datum->release();
+	return ret;
+}
+
+bool Datum::istGrößer( Datum *datum ) const // prüft, ob die Datum größer als datum ist
+{
+	bool ret = istGrößer( datum->getJahr(), datum->getMonat(), datum->getTag() );
+	datum->release();
+	return ret;
+}
+
+bool Datum::istGrößer( int jahr, int monat, int tag ) const
+{
+	if( this->jahr > jahr )
+		return 1;
+	else if( this->jahr == jahr )
+	{
+		if( this->monat > monat )
+			return 1;
+		else if( this->monat == monat )
+		{
+			if( this->tag > tag )
+				return 1;
+			else if( this->tag == tag )
+				return 0;
+			else
+				return 0;
+		}
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Datum::istGrößer( const char *format, const char *datum ) const
+{
+	int j = jahr, m = monat, t = tag;
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			j = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		case 'd':
+			t = TextZuInt( (char*)datum, &ende, 10 );
+			datum = ende;
+			ende = 0;
+			break;
+		default:
+			++datum;
+			break;
+		}
+	}
+	return istGrößer( j, m, t );
+}
+
+bool Datum::istGrößer( const char *format, Text *datum ) const
+{
+	bool ret = istGrößer( format, datum->getText() );
+	datum->release();
+	return ret;
+}
+
+// Reference Counting 
+Datum *Datum::getThis()
+{
+	++ref;
+	return this;
+}
+
+Datum *Datum::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der Zeit Klasse aus Zeit.h
+// Konstruktor 
+Zeit::Zeit()
+	: datum( new Datum() ),
+	  uhrzeit( new Uhrzeit() ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+Zeit::~Zeit()
+{
+	datum->release();
+	uhrzeit->release();
+}
+
+// nicht constant 
+void Zeit::setZeit( Zeit *zeit ) // setzt die Zeit
+{
+	datum->setDatum( zeit->getDatum() );
+	datum->plusTag( uhrzeit->setUhrzeit( zeit->getUhrzeit() ) );
+	zeit->release();
+}
+
+void Zeit::setZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde )
+{
+	datum->setDatum( jahr, monat, tag );
+	datum->plusTag( uhrzeit->setUhrzeit( stunde, minute, sekunde ) );
+}
+
+void Zeit::setZeit( const char *format, const char *zeit ) // format Beispiele: "Y:m:d H-i-s", "Y-m-d H:i:s" (Y=Jahr,m=Monat,d=tag,H=stunde,i=minute,s=sekunde)
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	datum->setDatum( y, m, d );
+	datum->plusTag( uhrzeit->setUhrzeit( h, i, s ) );
+}
+
+void Zeit::setZeit( const char *format, Text *zeit )
+{
+	setZeit( format, zeit->getText() );
+	zeit->release();
+}
+
+void Zeit::setJahr( int jahr ) // setzt das Jahr
+{
+	datum->setJahr( jahr );
+}
+
+void Zeit::setMonat( int monat ) // setzt den Monat
+{
+	datum->setMonat( monat );
+}
+
+void Zeit::setTag( int tag ) // setzt den Tag
+{
+	datum->setTag( tag );
+}
+
+void Zeit::setStunde( int stunde ) // setzt die Stunde
+{
+	datum->plusTag( uhrzeit->setStunde( stunde ) );
+}
+
+void Zeit::setMinute( int minute ) // setzt die Minute
+{
+	datum->plusTag( uhrzeit->setMinute( minute ) );
+}
+
+void Zeit::setSekunde( int sekunde ) // setzt die Sekunde
+{
+	datum->plusTag( uhrzeit->setSekunde( sekunde ) );
+}
+
+void Zeit::plusZeit( Zeit *zeit ) // addiert die zeit
+{
+	datum->plusDatum( zeit->getDatum() );
+	datum->plusTag( uhrzeit->plusUhrzeit( zeit->getUhrzeit() ) );
+	zeit->release();
+}
+
+void Zeit::plusZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde )
+{
+	datum->plusDatum( jahr, monat, tag );
+	datum->plusTag( uhrzeit->plusUhrzeit( stunde, minute, sekunde ) );
+}
+
+void Zeit::plusZeit( const char *format, const char *zeit )
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	datum->setDatum( y, m, d );
+	datum->plusTag( uhrzeit->setUhrzeit( h, i, s ) );
+}
+
+void Zeit::plusZeit( const char *format, Text *zeit )
+{
+	plusZeit( format, zeit->getText() );
+	zeit->release();
+}
+
+void Zeit::plusJahr( int jahr ) // addiert jahr Jahre
+{
+	datum->plusJahr( jahr );
+}
+
+void Zeit::plusMonat( int monat ) // addiert monat Monate
+{
+	datum->plusMonat( monat );
+}
+
+void Zeit::plusTag( int tag ) // addiert tag Tage
+{
+	datum->plusTag( tag );
+}
+
+void Zeit::plusStunde( int stunde ) // addiert stunde Stunden
+{
+	datum->plusTag( uhrzeit->plusStunde( stunde ) );
+}
+
+void Zeit::plusMinute( int minute ) // addiert minute Minuten
+{
+	datum->plusTag( uhrzeit->plusMinute( minute ) );
+}
+
+void Zeit::plusSekunde( int sekunde ) // addiert sekunde Sekunden
+{
+	datum->plusTag( uhrzeit->plusSekunde( sekunde ) );
+}
+
+void Zeit::minusZeit( Zeit *zeit ) // subtrahiert die zeit
+{
+	datum->minusDatum( zeit->getDatum() );
+	datum->plusTag( uhrzeit->minusUhrzeit( zeit->getUhrzeit() ) );
+	zeit->release();
+}
+
+void Zeit::minusZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde )
+{
+	datum->minusDatum( jahr, monat, tag );
+	datum->plusTag( uhrzeit->plusUhrzeit( stunde, minute, sekunde ) );
+}
+
+void Zeit::minusZeit( const char *format, const char *zeit )
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h += TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s -= TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	datum->setDatum( y, m, d );
+	datum->plusTag( uhrzeit->setUhrzeit( h, i, s ) );
+}
+
+void Zeit::minusZeit( const char *format, Text *zeit )
+{
+	minusZeit( format, zeit->getText() );
+	zeit->release();
+}
+
+void Zeit::minusJahr( int jahr ) // subtrahiert jahr Jahre
+{
+	datum->minusJahr( jahr );
+}
+
+void Zeit::minusMonat( int monat ) // subtrahiert monat Monate
+{
+	datum->minusMonat( monat );
+}
+
+void Zeit::minusTag( int tag ) // subtrahiert tag Tage
+{
+	datum->minusTag( tag );
+}
+
+void Zeit::minusStunde( int stunde ) // subtrahiert stunde Stunden
+{
+	datum->plusTag( uhrzeit->minusStunde( stunde ) );
+}
+
+void Zeit::minusMinute( int minute ) // subtrahiert minute Minuten
+{
+	datum->plusTag( uhrzeit->minusMinute( minute ) );
+}
+
+void Zeit::minusSekunde( int sekunde ) // subtrahiert sekunde Sekunden
+{
+	datum->plusTag( uhrzeit->minusSekunde( sekunde ) );
+}
+
+// constant 
+Text *Zeit::getZeit( const char *format ) const // gibt die Zeit als Text formatiert zurück
+{
+	Text *ret = new Text( "" );
+	int flän = textLänge( format );
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			ret->anhängen( datum->getJahr() );
+			break;
+		case 'm':
+			ret->anhängen( datum->getMonat() );
+			break;
+		case 'd':
+			ret->anhängen( datum->getTag() );
+			break;
+		case 'h':
+			ret->anhängen( uhrzeit->getStunde() );
+			break;
+		case 'i':
+			ret->anhängen( uhrzeit->getMinute() );
+			break;
+		case 's':
+			ret->anhängen( uhrzeit->getSekunde() );
+			break;
+		default:
+			ret->anhängen( f, 1 );
+		}
+	}
+	return ret;
+}
+
+bool Zeit::istGleich( Zeit *zeit ) const // prüft, ob die Uhrzeit gleich zeit ist
+{
+	bool ret = datum->istGleich( zeit->getDatum() ) && uhrzeit->istGleich( zeit->getUhrzeit() );
+	zeit->release();
+	return ret;
+}
+
+bool Zeit::istGleich( const char *format, const char *zeit ) const
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	return datum->istGleich( y, m, d ) && uhrzeit->istGleich( h, i, s );
+}
+
+bool Zeit::istGleich( const char *format, Text *zeit ) const
+{
+	bool ret = istGleich( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+bool Zeit::istGleich( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const
+{
+	return datum->istGleich( jahr, monat, tag ) && uhrzeit->istGleich( stunde, minute, sekunde );
+}
+
+Datum *Zeit::getDatum() const // gibt das Datum zurück
+{
+	return datum->getThis();
+}
+
+Datum *Zeit::zDatum() const
+{
+	return datum;
+}
+
+Uhrzeit *Zeit::getUhrzeit() const // gibt die Uhrzeit zurück
+{
+	return uhrzeit->getThis();
+}
+
+Uhrzeit *Zeit::zUhrzeit() const
+{
+	return uhrzeit;
+}
+
+bool Zeit::istKleiner( Zeit *zeit ) const // prüft, ob die Zeit kleiner als zeit ist
+{
+	if( datum->istKleiner( zeit->getDatum() ) )
+	{
+		zeit->release();
+		return 1;
+	}
+	else if( datum->istGleich( zeit->getDatum() ) )
+	{
+		if( uhrzeit->istKleiner( zeit->getUhrzeit() ) )
+		{
+			zeit->release();
+			return 1;
+		}
+		else
+		{
+			zeit->release();
+			return 0;
+		}
+	}
+	else
+	{
+		zeit->release();
+		return 0;
+	}
+}
+
+bool Zeit::istKleiner( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const
+{
+	if( datum->istKleiner( jahr, monat, tag ) )
+		return 1;
+	else if( datum->istGleich( jahr, monat, tag ) )
+	{
+		if( uhrzeit->istKleiner( stunde, minute, sekunde ) )
+			return 1;
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Zeit::istKleiner( const char *format, const char *zeit ) const
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	if( datum->istKleiner( y, m, d ) )
+		return 1;
+	else if( datum->istGleich( y, m, d ) )
+	{
+		if( uhrzeit->istKleiner( h, i, s ) )
+			return 1;
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Zeit::istKleiner( const char *format, Text *zeit ) const
+{
+	bool ret = istKleiner( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+bool Zeit::istGrößer( Zeit *zeit ) const // prüft, ob die Zeit größer als zeit ist
+{
+	if( datum->istGrößer( zeit->getDatum() ) )
+	{
+		zeit->release();
+		return 1;
+	}
+	else if( datum->istGleich( zeit->getDatum() ) )
+	{
+		if( uhrzeit->istGrößer( zeit->getUhrzeit() ) )
+		{
+			zeit->release();
+			return 1;
+		}
+		else
+		{
+			zeit->release();
+			return 0;
+		}
+	}
+	else
+	{
+		zeit->release();
+		return 0;
+	}
+}
+
+bool Zeit::istGrößer( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const
+{
+	if( datum->istGrößer( jahr, monat, tag ) )
+		return 1;
+	else if( datum->istGleich( jahr, monat, tag ) )
+	{
+		if( uhrzeit->istGrößer( stunde, minute, sekunde ) )
+			return 1;
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Zeit::istGrößer( const char *format, const char *zeit ) const
+{
+	int y = datum->getJahr();
+	int m = datum->getMonat();
+	int d = datum->getTag();
+	int h = uhrzeit->getStunde();
+	int i = uhrzeit->getMinute();
+	int s = uhrzeit->getSekunde();
+
+	int flän = textLänge( format );
+	char *ende = 0;
+	for( const char *f = format; f < format + flän; ++f )
+	{
+		switch( *f )
+		{
+		case 'y':
+			y = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'm':
+			m = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'd':
+			d = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'h':
+			h = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 'i':
+			i = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		case 's':
+			s = TextZuInt( (char*)zeit, &ende, 10 );
+			zeit = ende;
+			ende = 0;
+			break;
+		default:
+			++zeit;
+			break;
+		}
+	}
+	if( datum->istGrößer( y, m, d ) )
+		return 1;
+	else if( datum->istGleich( y, m, d ) )
+	{
+		if( uhrzeit->istGrößer( h, i, s ) )
+			return 1;
+		else
+			return 0;
+	}
+	else
+		return 0;
+}
+
+bool Zeit::istGrößer( const char *format, Text *zeit ) const
+{
+	bool ret = istGrößer( format, zeit->getText() );
+	zeit->release();
+	return ret;
+}
+
+// Reference Counting 
+Zeit *Zeit::getThis()
+{
+	++ref;
+	return this;
+}
+
+Zeit *Zeit::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der ZeitMesser Klasse aus Zeit.h
+// Konstruktor 
+ZeitMesser::ZeitMesser()
+	: start( 0 ),
+	  ende( 0 ),
+	  messung( 0 ),
+	  ref( 1 )
+{
+}
+
+// Destruktor 
+ZeitMesser::~ZeitMesser()
+{
+
+}
+
+// nicht constant 
+void ZeitMesser::messungStart() // legt des Startpunkt der Zeitmessung fest
+{
+	timeval tv;
+	gettimeofday( &tv, 0 );
+	start = tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+void ZeitMesser::messungEnde() // legt des Endpunkt der Zeitmessung fest
+{
+	timeval tv;
+	gettimeofday( &tv, 0 );
+	ende = tv.tv_sec + tv.tv_usec / 1000000.0;
+	messung = ende - start;
+}
+
+// constant 
+double ZeitMesser::getSekunden() const // gibt den sekundenabstand zwischen start und ende der Messung zurück
+{
+	return messung;
+}
+
+double ZeitMesser::getMinuten() const // gibt den minutenabstand zwischen start und ende der Messung zurück
+{
+	return messung / 60;
+}
+
+double ZeitMesser::getStunden() const // gibt den stundenabstand zwischen start und ende der Messung zurück
+{
+	return messung / 3600;
+}
+
+// Reference Counting 
+ZeitMesser *ZeitMesser::getThis()
+{
+	++ref;
+	return this;
+}
+
+ZeitMesser *ZeitMesser::release()
+{
+	--ref;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Globale Funktionen 
+Uhrzeit *Framework::getUhrzeit() // gibt die aktuelle Uhrzeit zurück
+{
+#ifdef WIN32
+	Uhrzeit *ret = new Uhrzeit();
+	time_t Zeitstempel = time( 0 );
+	tm now;
+	localtime_s( &now, &Zeitstempel );
+	ret->setUhrzeit( now.tm_hour, now.tm_min, now.tm_sec );
+	return ret;
+#else
+	Uhrzeit *ret = new Uhrzeit( );
+	time_t Zeitstempel = time( 0 );
+	tm *now = localtime( &Zeitstempel );
+	ret->setUhrzeit( now->tm_hour, now->tm_min, now->tm_sec );
+	return ret;
+#endif
+}
+
+Datum *Framework::getDatum() // gibt das aktuelle Datum zurück
+{
+#ifdef WIN32
+	Datum *ret = new Datum();
+	time_t Zeitstempel = time( 0 );
+	tm now;
+	localtime_s( &now, &Zeitstempel );
+	ret->setDatum( now.tm_year + 1900, now.tm_mon + 1, now.tm_mday );
+	return ret;
+#else
+	Datum *ret = new Datum( );
+	time_t Zeitstempel = time( 0 );
+	tm *now = localtime( &Zeitstempel );
+	ret->setDatum( now->tm_year + 1900, now->tm_mon + 1, now->tm_mday );
+	return ret;
+#endif
+}
+
+Zeit *Framework::getZeit() // gibt die aktuelle Zeit( Datum und Uhrzeit ) zurück
+{
+#ifdef WIN32
+	Zeit *ret = new Zeit();
+	time_t Zeitstempel = time( 0 );
+	tm now;
+	localtime_s( &now, &Zeitstempel );
+	ret->setZeit( now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec );
+	return ret;
+#else
+	Zeit *ret = new Zeit( );
+	time_t Zeitstempel = time( 0 );
+	tm *now = localtime( &Zeitstempel );
+	ret->setZeit( now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec );
+	return ret;
+#endif
+}
+
+bool Framework::istSchaltjahr( int jahr ) // prüft, ob jahr ein Schaltjahr ist
+{
+	if( jahr % 4 == 0 )
+	{
+		if( jahr % 100 == 0 )
+		{
+			if( jahr % 400 == 0 )
+				return true;
+			else
+				return false;
+		}
+		else
+			return true;
+	}
+	else
+		return false;
+}

+ 719 - 0
Zeit.h

@@ -0,0 +1,719 @@
+#ifndef Zeit_H
+#define Zeit_H
+
+#include "Betriebssystem.h"
+#include <time.h>
+
+namespace Framework
+{
+    class Text; // Text.h
+    class Uhrzeit; // Aus dieser Datei
+    class Datum; // Aus dieser Datei
+    class Zeit; // Aus dieser Datei
+    class ZeitMesser; // Aus dieser Datei
+
+    // Diese Klasse speichert eine Uhrzeit in form von Stunden, Minuten und Sekunden
+    class Uhrzeit
+    {
+    private:
+        int stunde, minute, sekunde;
+        int ref;
+        int update();
+
+    public:
+        //Erzeugt ein neues Uhrzeit Zeichnung mit den Standartwerten 00:00:00
+        __declspec( dllexport ) Uhrzeit();
+
+        //Setzt die Uhrzeit durch kopieren.
+        //  zeit: Aus diesem Zeichnung werden die Werte für Stunde, Minute und Sekunde kopiert.
+        __declspec( dllexport ) int setUhrzeit( Uhrzeit *zeit );
+        //Setzt die Uhrzeit.
+        //  stunde: Die Stunde der neuen Uhrzeit.
+        //  minute: Die Minute der neuen Uhrzeit.
+        //  sekunde: Die Sekunde der neuen Uhrzeit.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: setUhrzeit( 30, 30, 30 ); return: 1, gespeichert: 6:30:30
+        __declspec( dllexport ) int setUhrzeit( int stunde, int minute, int sekunde );
+        //Setzt die Uhrzeit.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: setUhrzeit( "h:i:s", "05:30:00" );
+        // Beispiel: setUhrzeit( "h:i:s", "30:30:00" ); return: 1, gespeichert: 6:30:00
+        __declspec( dllexport ) int setUhrzeit( const char *format, const char *zeit );
+        //Setzt die Uhrzeit.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, dass die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: setUhrzeit( "h:i:s", new Text( "05:30:00" ) );
+        // Beispiel: setUhrzeit( "h:i:s", new Text( "30:30:00" ) ); return: 1, gespeichert: 6:30:00
+        __declspec( dllexport ) int setUhrzeit( const char *format, Text *zeit );
+        // setzt die Stunde.
+        //  stunde: Die Stunde, die gespeichert werden soll.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: setStunde( 30 ); return: 1 Tag, gespeicherte Stunden: 6
+        __declspec( dllexport ) int setStunde( int stunde );
+        // setzt die Minute.
+        //  minute: Die Minute, die gespeichert werden soll.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 23:50:10, setMinute( 80 ); return: 1, gespeicherte Zeit: 01:10:10
+        __declspec( dllexport ) int setMinute( int minute );
+        // setzt die Sekunde.
+        //  minute: Die Sekunde, die gespeichert werden soll.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 23:59:10, setSekunde( 80 ); return: 1, gespeicherte Zeit: 00:00:30
+        __declspec( dllexport ) int setSekunde( int sekunde );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  zeit: Die Uhrzeit, deren Werte addiert werden sollen.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 19:40:18, plusZeit( (10:05:30) ); return 1, gespeicherte Zeit: 05:45:48
+        __declspec( dllexport ) int plusUhrzeit( Uhrzeit *zeit );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  stunde: Die Stunden die Werte addiert werden sollen.
+        //  minute: Die Minute die Werte addiert werden sollen.
+        //  sekunde: Die Sekunde die Werte addiert werden sollen.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 19:40:18, plusZeit( 10, 5, 30 ); return 1, gespeicherte Zeit: 05:45:48
+        __declspec( dllexport ) int plusUhrzeit( int stunde, int minute, int sekunde );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: plusUhrzeit( "h:i:s", "05:20:00" );
+        // Beispiel: Alte Zeit: 19:40:18, plusZeit( "h:i:s", "10:05:30" ); return 1, gespeicherte Zeit: 05:45:48
+        __declspec( dllexport ) int plusUhrzeit( const char *format, const char *zeit );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: plusUhrzeit( "h:i:s", new Text( "05:20:00" ) );
+        // Beispiel: Alte Zeit: 19:40:18, plusZeit( "h:i:s", new Text( "10:05:30" ) ); return 1, gespeicherte Zeit: 05:45:48
+        __declspec( dllexport ) int plusUhrzeit( const char *format, Text *zeit );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  stunde: die draufzurechnenden Stunden.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 20:50:30, plusStunde( 10 ); return 1, gespeicherte Zeit: 6:50:30
+        __declspec( dllexport ) int plusStunde( int stunde );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  minute: die draufzurechnenden Minuten.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 23:50:30, plusMinute( 11 ); return 1, gespeicherte Zeit: 00:01:30
+        __declspec( dllexport ) int plusMinute( int minute );
+        // errechnet die Summe von dieser und einer anderen Uhrzeit und speichert diese.
+        //  sekunde: die draufzurechnenden Sekunden.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel: Alte Zeit: 23:59:30, plusSekunde( 40 ); return 1, gespeicherte Zeit: 00:00:10
+        __declspec( dllexport ) int plusSekunde( int sekunde );
+        // zieht eine gegebene Uhrzeit von dieser ab und speichert das Ergebnis.
+        //  zeit: Die Uhrzeit, die von dieser abgezogen werden soll.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 10:40:18, minusUhrzeit( (19:05:30) ); return -1, gespeicherte Zeit: 15:34:48
+        __declspec( dllexport ) int minusUhrzeit( Uhrzeit *zeit );
+        // zieht eine gegebene Uhrzeit von dieser ab und speichert das Ergebnis.
+        //  stunde: Die Stunden, die von dieser Uhrzeit abgezogen werden sollen.
+        //  minute: Die Minuten, die von dieser Uhrzeit abgezogen werden sollen.
+        //  sekunde: Die Sekunden, die von dieser Uhrzeit abgezogen werden sollen.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 10:40:18, minusUhrzeit( 19, 05, 30 ); return -1, gespeicherte Zeit: 15:34:48
+        __declspec( dllexport ) int minusUhrzeit( int stunde, int minute, int sekunde );
+        // zieht eine gegebene Uhrzeit von dieser ab und speichert das Ergebnis.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 10:40:18, minusUhrzeit( "h:i:s", "19:05:30" ); return -1, gespeicherte Zeit: 15:34:48
+        __declspec( dllexport ) int minusUhrzeit( const char *format, const char *zeit );
+        // zieht eine gegebene Uhrzeit von dieser ab und speichert das Ergebnis.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die neue Uhrzeit enthält.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 10:40:18, minusUhrzeit( "h:i:s", new Text( "19:05:30" ) ); return -1, gespeicherte Zeit: 15:34:48
+        __declspec( dllexport ) int minusUhrzeit( const char *format, Text *zeit );
+        // zieht eine gegebene Zeit von dieser ab und speichert das Ergebnis.
+        //  stunde: Die abzuziehenden Stunden.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 10:40:18, minusStunde( 19 ); return -1, gespeicherte Zeit: 15:40:18
+        __declspec( dllexport ) int minusStunde( int stunde );
+        // zieht eine gegebene Zeit von dieser ab und speichert das Ergebnis.
+        //  minute: Die abzuziehenden Minuten.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 00:40:18, minusStunde( 50 ); return -1, gespeicherte Zeit: 23:50:18
+        __declspec( dllexport ) int minusMinute( int minute );
+        // zieht eine gegebene Zeit von dieser ab und speichert das Ergebnis.
+        //  sekunde: Die abzuziehenden Sekunden.
+        //  return: Die Anzahl übriger Tage.
+        // Beispiel Alte Zeit: 00:00:20, minusStunde( 50 ); return -1, gespeicherte Zeit: 23:59:30
+        __declspec( dllexport ) int minusSekunde( int sekunde );
+
+        // gibt die Stunde zurück.
+        __declspec( dllexport ) int getStunde() const;
+        // gibt die Minute zurück.
+        __declspec( dllexport ) int getMinute() const;
+        // gibt die Sekunde zurück.
+        __declspec( dllexport ) int getSekunde() const;
+        // gibt die Uhrzeit als Text formatiert zurück.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit zurückgegeben werden soll. h=Stunde, i=Minute,s=Sekunde.
+        // Beispiel: Zeit: 5:40:39, getUhrzeit( "h:i:s" ); return: "5:40:39"
+        __declspec( dllexport ) Text *getUhrzeit( const char *format ) const;
+        // prüft, ob die Uhrzeit gleich zeit ist.
+        //  zeit: Die Uhrzeit, mit der diese verglichen werden soll.
+        //  return: (true), wenn die beiden Zeiten geich sind. (false), wenn die Zeiten nicht gleich sind.
+        __declspec( dllexport ) bool istGleich( Uhrzeit *zeit ) const;
+        // prüft, ob die Uhrzeit gleich zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die andere Uhrzeit enthält.
+        //  return: (true), wenn die beiden Zeiten geich sind. (false), wenn die Zeiten nicht gleich sind.
+        __declspec( dllexport ) bool istGleich( const char *format, const char *zeit ) const;
+        // prüft, ob die Uhrzeit gleich zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die andere Uhrzeit enthält.
+        //  return: (true), wenn die beiden Zeiten geich sind. (false), wenn die Zeiten nicht gleich sind.
+        __declspec( dllexport ) bool istGleich( const char *format, Text *zeit ) const;
+        // prüft, ob die Uhrzeit gleich der übergebenen Zeit ist. Hier wird nicht beachtet, ob die gegebene Zeit eine gültige Uhrzeit ist.
+        //  stunde: Die Stunden der zu überprüfenden Uhrzeit
+        //  minute: Die Minuten der zu überprüfenden Uhrzeit
+        //  sekunde: Die Sekunden der zu überprüfenden Uhrzeit
+        //  return: (true), wenn die beiden Zeiten geich sind. (false), wenn die Zeiten nicht gleich sind.
+        __declspec( dllexport ) bool istGleich( int stunde, int minute, int sekunde ) const;
+        // prüft, ob die Stunde gleich der gegebenen Stunde ist.
+        //  stunde: die zu prüfende Stunde.
+        //  return: (true), wenn die Stunden gleich sind. (false), wenn sie nicht gleich sind.
+        __declspec( dllexport ) bool stundeGleich( int stunde ) const;
+        // prüft, ob die Minute gleich der gegebenen Minute ist.
+        //  minute: die zu prüfende Minute.
+        //  return: (true), wenn die Minuten gleich sind. (false), wenn sie nicht gleich sind.
+        __declspec( dllexport ) bool minuteGleich( int minute ) const;
+        // prüft, ob die Sekunde gleich der gegebenen Sekunde ist.
+        //  sekunde: die zu prüfende Sekunde.
+        //  return: (true), wenn die Sekunden gleich sind. (false), wenn sie nicht gleich sind.
+        __declspec( dllexport ) bool sekundeGleich( int sekunde ) const;
+        // prüft, ob die Uhrzeit kleiner als zeit ist.
+        //  zeit: Die zu prüfende Uhrzeit.
+        //  return: (true), wenn die gespeicherte Zeit kleiner als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istKleiner( (10:40:29) ); return true
+        __declspec( dllexport ) bool istKleiner( Uhrzeit *zeit ) const;
+        // prüft, ob die Uhrzeit kleiner als die übergebene Zeit ist.
+        //  stunde: Die Stunden der zu prüfenden Zeit.
+        //  minute: Die Minute der zu prüfenden Zeit.
+        //  sekunde: Die Sekunde der zu prüfenden Zeit.
+        //  return: (true), wenn die gespeicherte Zeit kleiner als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istKleiner( 10, 40, 29 ); return true
+        __declspec( dllexport ) bool istKleiner( int stunde, int minute, int sekunde ) const;
+        // prüft, ob die Uhrzeit kleiner als die übergebene Zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die andere Uhrzeit enthält.
+        //  return: (true), wenn die gespeicherte Zeit kleiner als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istKleiner( "h:i:s", "10:40:29" ); return true
+        __declspec( dllexport ) bool istKleiner( const char *format, const char *zeit ) const;
+        // prüft, ob die Uhrzeit kleiner als die übergebene Zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die andere Uhrzeit enthält.
+        //  return: (true), wenn die gespeicherte Zeit kleiner als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istKleiner( "h:i:s", "10:40:29" ); return true
+        __declspec( dllexport ) bool istKleiner( const char *format, Text *zeit ) const;
+        // prüft, ob die Uhrzeit größer als zeit ist.
+        //  zeit: Die zu prüfende Uhrzeit.
+        //  return: (true), wenn die gespeicherte Zeit größer als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istGrößer( (10:40:29) ); return false
+        __declspec( dllexport ) bool istGrößer( Uhrzeit *zeit ) const;
+        // prüft, ob die Uhrzeit größer als die übergebene Zeit ist.
+        //  stunde: Die Stunden der zu prüfenden Zeit.
+        //  minute: Die Minute der zu prüfenden Zeit.
+        //  sekunde: Die Sekunde der zu prüfenden Zeit.
+        //  return: (true), wenn die gespeicherte Zeit größer als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istGrößer( 10, 40, 29 ); return false
+        __declspec( dllexport ) bool istGrößer( int stunde, int minute, int sekunde ) const;
+        // prüft, ob die Uhrzeit größer als die übergebene Zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Eine Zeichenfolge die die andere Uhrzeit enthält.
+        //  return: (true), wenn die gespeicherte Zeit größer als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istGrößer( "h:i:s", "10:40:29" ); return false
+        __declspec( dllexport ) bool istGrößer( const char *format, const char *zeit ) const;
+        // prüft, ob die Uhrzeit größer als die übergebene Zeit ist.
+        //  format: Eine Zeichenfolge, die bestimmt in welcher Form die Uhrzeit in (zeit) vorliegt. h=Stunde, i=Minute,s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die andere Uhrzeit enthält.
+        //  return: (true), wenn die gespeicherte Zeit größer als die übergebene Zeit ist. (false) sonst.
+        // Beispiel: (5:30:00).istGrößer( "h:i:s", "10:40:29" ); return false
+        __declspec( dllexport ) bool istGrößer( const char *format, Text *zeit ) const;
+        
+        // Erhöht den Reference Counting Zähler
+        //  return: this
+        __declspec( dllexport ) Uhrzeit *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht
+        //  return: 0
+        __declspec( dllexport ) Uhrzeit *release();
+    };
+
+    // Diese Klasse speichert ein Datum in Form von Jahr, Monat und Tagen
+    class Datum
+    {
+    private:
+        int jahr, monat, tag;
+        int ref;
+        int *maxTage;
+        void update();
+
+    public:
+        // Erzeugt ein neues Datum Zeichnung mit den Standartwerten 0.0.0.
+        __declspec( dllexport ) Datum();
+        // Löscht das Datum.
+        __declspec( dllexport ) ~Datum();
+
+        // Setzt das Datum durch kopieren.
+        //  datum: Das zu speichernde Datum.
+        __declspec( dllexport ) void setDatum( Datum *datum );
+        // Setzt das Datum zu den übergebenen Werten.
+        //  jahr: Das Jahr des neuen Datums.
+        //  monat: Der Monat des neuen Datums.
+        //  tag: Der Tag des neuen Datums.
+        __declspec( dllexport ) void setDatum( int jahr, int monat, int tag );
+        // Setzt das Datum zu dem übergebenen Wert.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das neue Datum enthält.
+        // Beispiel: setDatum( "y-m-d", "2016-01-25" );
+        __declspec( dllexport ) void setDatum( const char *format, const char *datum );
+        // Setzt das Datum zu dem übergebenen Wert.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das neue Datum enthält.
+        // Beispiel: setDatum( "y-m-d", new Text(  "2016-01-25" ) );
+        __declspec( dllexport ) void setDatum( const char *format, Text *datum );
+        // Ändert das Jahr des Datums.
+        //  jahr: Das neue Jahr.
+        __declspec( dllexport ) void setJahr( int jahr );
+        // Ändert den Monat des Datums.
+        //  monat: Der neue Monat.
+        __declspec( dllexport ) void setMonat( int monat );
+        // Ändert den Tag des Datums.
+        //  tag: Der neue Tag.
+        __declspec( dllexport ) void setTag( int tag );
+        // Addiert zum aktuellen Datum das übergebene Datum dazu und speichert das Ergebnis.
+        //  datum: Das zu addierende Datum.
+        // Beispiel: ( 1.11.1995 ).plusDatum( ( 5.2.7 ) ); neues Datum: 6.1.2003
+        __declspec( dllexport ) void plusDatum( Datum *datum );
+        // Addiert zum aktuellen Datum das übergebene Datum dazu und speichert das Ergebnis.
+        //  jahr: Das zu addierende Jahr.
+        //  monat: Der zu addierende Monat.
+        //  tag: Der zu addierende Tag.
+        // Beispiel: ( 1.11.1995 ).plusDatum( ( 7, 2, 5 ) ); neues Datum: 6.1.2003
+        __declspec( dllexport ) void plusDatum( int jahr, int monat, int tag );
+        // Addiert zum aktuellen Datum das übergebene Datum dazu und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das zu addierende Datum enthält.
+        // Beispiel: ( 1.11.1995 ).plusDatum( "d.m.y", "5.2.7" ); neues Datum: 6.1.2003
+        __declspec( dllexport ) void plusDatum( const char *format, const char *datum );
+        // Addiert zum aktuellen Datum das übergebene Datum dazu und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das zu addierende Datum enthält.
+        // Beispiel: ( 1.11.1995 ).plusDatum( "d.m.y", new Text( "5.2.7" ) ); neues Datum: 6.1.2003
+        __declspec( dllexport ) void plusDatum( const char *format, Text *datum );
+        // Addiert zum aktuellen Datum das übergebene Jahr dazu und speichert das Ergebnis.
+        //  jahr: Das zu addierende Jahr.
+        // Beispiel: ( 1.11.1995 ).plusJahr( 21 ); neues Datum: 1.11.2016
+        __declspec( dllexport ) void plusJahr( int jahr );
+        // Addiert zum aktuellen Datum den übergebenen Monat dazu und speichert das Ergebnis.
+        //  monat: Der zu addierende Monat.
+        // Beispiel: ( 1.11.1995 ).plusMonat( 13 ); neues Datum: 1.12.1996
+        __declspec( dllexport ) void plusMonat( int monat );
+        // Addiert zum aktuellen Datum den übergebenen Tag dazu und speichert das Ergebnis.
+        //  tag: Der zu addierende Tag.
+        // Beispiel: ( 1.1.2000 ).plusTag( 32 ); neues Datum: 2.2.2000
+        __declspec( dllexport ) void plusTag( int tag );
+        // Zieht vom aktuellen Datum das übergebene Datum ab und speichert das Ergebnis.
+        //  datum: Das abzuzuehende Datum.
+        // Beispiel: ( 2.12.1996 ).minusDatum( ( 1.1.1 ) ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusDatum( Datum *datum );
+        // Zieht vom aktuellen Datum das übergebene Datum ab und speichert das Ergebnis.
+        //  jahr: Das abzuzuehende Jahr.
+        //  monat: Der abzuzuehende Monat.
+        //  tag: Der abzuzuehende Tag.
+        // Beispiel: ( 2.12.1996 ).minusDatum( 1, 1, 1 ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusDatum( int jahr, int monat, int tag );
+        // Zieht vom aktuellen Datum das übergebene Datum ab und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das abzuziehende Datum enthält.
+        // Beispiel: ( 2.12.1996 ).minusDatum( "d.m.y", "1.1.1" ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusDatum( const char *format, const char *datum );
+        // Zieht vom aktuellen Datum das übergebene Datum ab und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das abzuziehende Datum enthält.
+        // Beispiel: ( 2.12.1996 ).minusDatum( "d.m.y", new Text( "1.1.1" ) ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusDatum( const char *format, Text *datum );
+        // Zieht vom aktuellen Datum das übergebene Jahr ab und speichert das Ergebnis.
+        //  jahr: Das abzuzuehende Jahr.
+        // Beispiel: ( 1.11.1996 ).minusJahr( 1 ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusJahr( int jahr );
+        // Zieht vom aktuellen Datum den übergebenen Monat ab und speichert das Ergebnis.
+        //  monat: Der abzuzuehende Monat.
+        // Beispiel: ( 1.12.1996 ).minusMonat( 13 ); neues Datum: 1.11.1995
+        __declspec( dllexport ) void minusMonat( int monat );
+        // Zieht vom aktuellen Datum den übergebenen Tag ab und speichert das Ergebnis.
+        //  monat: Der abzuzuehende Tag.
+        // Beispiel: ( 5.2.2016 ).minusMonat( 11 ); neues Datum: 25.1.2016
+        __declspec( dllexport ) void minusTag( int tag );
+
+        // gibt das Jahr zurück.
+        __declspec( dllexport ) int getJahr() const;
+        // gibt der Monat zurück.
+        __declspec( dllexport ) int getMonat() const;
+        // gibt der Tag zurück.
+        __declspec( dllexport ) int getTag() const;
+        // Gibt das Datum als Text Zeichnung zurück.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum zurückgegeben werden soll. y=Jahr, m=Monat, d=Tag.
+        // Beispiel: ( 1.11.1995 ).getDatum( "y-m-d" ); return: "1995-11-1"
+        __declspec( dllexport ) Text *getDatum( const char *format ) const;
+        // Prüft, ob das Datum gleich dem übergebenen Datum ist.
+        //  datum: das zu prüfende Datum.
+        //  return: (true), wenn das übergebene Datum dem gespeicherten entspricht. (false) sonnst.
+        __declspec( dllexport ) bool istGleich( Datum *datum ) const;
+        // Prüft, ob das Datum gleich dem übergebenen Datum ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das zu überprüfende Datum enthält.
+        //  return: (true), wenn das übergebene Datum dem gespeicherten entspricht. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGleich( "y-m-d", "1995-11-1" ); return: true
+        __declspec( dllexport ) bool istGleich( const char *format, const char *datum ) const;
+        // Prüft, ob das Datum gleich dem übergebenen Datum ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das zu überprüfende Datum enthält.
+        //  return: (true), wenn das übergebene Datum dem gespeicherten entspricht. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGleich( "y-m-d", new Text( "1995-11-1" ) ); return: true
+        __declspec( dllexport ) bool istGleich( const char *format, Text *datum ) const;
+        // Prüft, ob das Datum gleich dem übergebenen Datum ist.
+        //  jahr: Das Jahr des zu überprüfenden Datums.
+        //  monat: Der Monat des zu überprüfenden Datums.
+        //  tag: Der Tag des zu überprüfenden Datums.
+        //  return: (true), wenn das übergebene Datum dem gespeicherten entspricht. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGleich( 1995, 11, 1 ); return: true
+        __declspec( dllexport ) bool istGleich( int jahr, int monat, int tag ) const;
+        // Prüft, ob das Jahr gleich dem übergebenen Jahr ist.
+        //  jahr: Das zu prüfende Jahr.
+        //  return: (true), wenn das übergebene Jahr dem gespeicherten entspricht. (false) sonnst.
+        __declspec( dllexport ) bool jahrGleich( int jahr ) const;
+        // Prüft, ob der Monat gleich dem übergebenen Monat ist.
+        //  monat: Der zu prüfende Monat.
+        //  return: (true), wenn der übergebene Monat dem gespeicherten entspricht. (false) sonnst.
+        __declspec( dllexport ) bool monatGleich( int monat ) const;
+        // Prüft, ob der Tag gleich dem übergebenen Tag ist.
+        //  tag: Der zu prüfende Tag.
+        //  return: (true), wenn der übergebene Tag dem gespeicherten entspricht. (false) sonnst.
+        __declspec( dllexport ) bool tagGleich( int tag ) const;
+        // Prüft, ob das gespeicherte Datum kleiner als das übergebene ist.
+        //  datum: Das zu prüfende Datum.
+        //  return: (true), wenn das gespeicherte Datum vor dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istKleiner( ( 23.1.2016 ) ); return true
+        __declspec( dllexport ) bool istKleiner( Datum *datum ) const;
+        // Prüft, ob das gespeicherte Datum kleiner als das übergebene ist.
+        //  jahr: Das Jahr des zu prüfenden Datums.
+        //  monat: Der Monat des zu prüfenden Datums.
+        //  tag: Der Tag des zu prüfenden Datums.
+        //  return: (true), wenn das gespeicherte Datum vor dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istKleiner( 2016, 1, 23 ); return true
+        __declspec( dllexport ) bool istKleiner( int jahr, int monat, int tag ) const;
+        // Prüft, ob das gespeicherte Datum kleiner als das übergebene ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das zu überprüfende Datum enthält.
+        //  return: (true), wenn das gespeicherte Datum vor dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istKleiner( "y, m, d", "2016, 1, 23" ); return true
+        __declspec( dllexport ) bool istKleiner( const char *format, const char *datum ) const;
+        // Prüft, ob das gespeicherte Datum kleiner als das übergebene ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das zu überprüfende Datum enthält.
+        //  return: (true), wenn das gespeicherte Datum vor dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istKleiner( "y, m, d", new Text( "2016, 1, 23" ) ); return true
+        __declspec( dllexport ) bool istKleiner( const char *format, Text *datum ) const;
+        // Prüft, ob das gespeicherte Datum größer als das übergebene ist.
+        //  datum: Das zu prüfende Datum.
+        //  return: (true), wenn das gespeicherte Datum hinter dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGrößer( ( 23.1.2016 ) ); return false
+        __declspec( dllexport ) bool istGrößer( Datum *datum ) const;
+        // Prüft, ob das gespeicherte Datum größer als das übergebene ist.
+        //  jahr: Das Jahr des zu prüfenden Datums.
+        //  monat: Der Monat des zu prüfenden Datums.
+        //  tag: Der Tag des zu prüfenden Datums.
+        //  return: (true), wenn das gespeicherte Datum hinter dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGrößer( 2016, 1, 23 ); return false
+        __declspec( dllexport ) bool istGrößer( int jahr, int monat, int tag ) const;
+        // Prüft, ob das gespeicherte Datum größer als das übergebene ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Eine Zeichenkette, die das zu überprüfende Datum enthält.
+        //  return: (true), wenn das gespeicherte Datum hinter dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGrößer( "y, m, d", "2016, 1, 23" ); return false
+        __declspec( dllexport ) bool istGrößer( const char *format, const char *datum ) const;
+        // Prüft, ob das gespeicherte Datum größer als das übergebene ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form das Datum in (datum) vorhanden ist. y=Jahr, m=Monat, d=Tag.
+        //  datum: Ein Text Zeichnung, welches das zu überprüfende Datum enthält.
+        //  return: (true), wenn das gespeicherte Datum hinter dem übergebenen liegt. (false) sonnst.
+        // Beispiel: ( 1.11.1995 ).istGrößer( "y, m, d", new Text( "2016, 1, 23" ) ) ); return true
+        __declspec( dllexport ) bool istGrößer( const char *format, Text *datum ) const;
+
+        // Erhöht den Reference Counting Zähler
+        //  return: this
+        __declspec( dllexport ) Datum *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht
+        //  return: 0
+        __declspec( dllexport ) Datum *release();
+    };
+
+    // Diese Klasse vereint die beiden Klassen Datum und Uhrzeit und speichert somit einen Zeitstempel mit Jahr, Monat, Tag, Stunde, Minute und Sekunde
+    class Zeit
+    {
+    private:
+        Datum *datum;
+        Uhrzeit *uhrzeit;
+        int ref;
+
+    public:
+        // Erzeugt ein neues Zeichnung mit den Standartwerten 0.0.0 0:0:0.
+        __declspec( dllexport ) Zeit();
+        // Löscht das aktuelle Zeichnung.
+        __declspec( dllexport ) ~Zeit();
+        
+        // Ändert die gespeicherte Zeit durch kopieren der Werte aus (zeit).
+        //  zeit: Die neue Zeit.
+        __declspec( dllexport ) void setZeit( Zeit *zeit );
+        // Ändert die gespeicherte Zeit.
+        //  jahr: Das neue Jahr.
+        //  monat: Der neue Monat.
+        //  tag: Det neue Tag.
+        //  stunde: Die neue Stunde.
+        //  minute: Die neue Minute.
+        //  sekunde: Die neue Sekunde.
+        __declspec( dllexport ) void setZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde );
+        // Ändert die gespeicherte Zeit.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die neue Zeit enthält.
+        // Beispiel: setZeit( "y-m-d h:i:s", "2016-1-25 21:59:30" );
+        __declspec( dllexport ) void setZeit( const char *format, const char *zeit );
+        // Ändert die gespeicherte Zeit.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die neue Zeit enthält.
+        // Beispiel: setZeit( "y-m-d h:i:s", new Text( "2016-1-25 21:59:30" ) );
+        __declspec( dllexport ) void setZeit( const char *format, Text *zeit );
+        // Ändert das gespeicherte Jahr.
+        //  jahr: Das neue Jahr.
+        __declspec( dllexport ) void setJahr( int jahr );
+        // Ändert den gespeicherten Monat.
+        //  monat: Der neue Monat.
+        __declspec( dllexport ) void setMonat( int monat );
+        // Ändert den gespeicherten Tag.
+        //  tag: Der neue Tag.
+        __declspec( dllexport ) void setTag( int tag );
+        // Ändert die gespeicherte Stunde.
+        //  stunde: Die neue Stunde.
+        __declspec( dllexport ) void setStunde( int stunde );
+        // Ändert die gespeicherte Minute.
+        //  minute: Die neue Minute.
+        __declspec( dllexport ) void setMinute( int minute );
+        // Ändert die gespeicherte Sekunde.
+        //  sekunde: Die neue Sekunde.
+        __declspec( dllexport ) void setSekunde( int sekunde );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  zeit: Die zu Addierende Zeit.
+        __declspec( dllexport ) void plusZeit( Zeit *zeit );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  jahr: Das zu addierende Jahr.
+        //  monat: Der zu addierende Monat.
+        //  tag: Der zu addierende Tag.
+        //  stunde: Die zu addierende Stunde.
+        //  minute: Die zu addierende Minute.
+        //  sekunde: Die zu addierende Sekunde.
+        __declspec( dllexport ) void plusZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die zu addierende Zeit enthält.
+        __declspec( dllexport ) void plusZeit( const char *format, const char *zeit );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die zu addierende Zeit enthält.
+        __declspec( dllexport ) void plusZeit( const char *format, Text *zeit );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  jahr: Das zu addierende Jahr.
+        __declspec( dllexport ) void plusJahr( int jahr );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  monat: Der zu addierende Monat.
+        __declspec( dllexport ) void plusMonat( int monat );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  tag: Der zu addierende Tag.
+        __declspec( dllexport ) void plusTag( int tag );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  stunde: Die zu addierende Stunde.
+        __declspec( dllexport ) void plusStunde( int stunde );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  minute: Die zu addierende Minute.
+        __declspec( dllexport ) void plusMinute( int minute );
+        // Addiert die übergebene Zeit und speichert das Ergebnis.
+        //  sekunde: Die zu addierende Sekunde.
+        __declspec( dllexport ) void plusSekunde( int sekunde );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  zeit: Die abzuziehende Zeit.
+        __declspec( dllexport ) void minusZeit( Zeit *zeit );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  jahr: Das abzuziehende Jahr.
+        //  monat: Der abzuziehende Monat.
+        //  tag: Der abzuziehende Tag.
+        //  stunde: Die abzuziehende Stunde.
+        //  minute: Die abzuziehende Minute.
+        //  sekunde: Die abzuziehende Sekunde.
+        __declspec( dllexport ) void minusZeit( int jahr, int monat, int tag, int stunde, int minute, int sekunde );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die abzuziehende Zeit enthält.
+        __declspec( dllexport ) void minusZeit( const char *format, const char *zeit );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Ein Text Zeichnung, welches die abzuziehende Zeit enthält.
+        __declspec( dllexport ) void minusZeit( const char *format, Text *zeit );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  jahr: Das abzuziehende Jahr.
+        __declspec( dllexport ) void minusJahr( int jahr );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  monat: Der abzuziehende Monat.
+        __declspec( dllexport ) void minusMonat( int monat );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  tag: Der abzuziehende Tag.
+        __declspec( dllexport ) void minusTag( int tag );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  stunde: Die abzuziehende Stunde.
+        __declspec( dllexport ) void minusStunde( int stunde );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  minute: Die abzuziehende Minute.
+        __declspec( dllexport ) void minusMinute( int minute );
+        // Zieht die übergebene Zeit ab und speichert das Ergebnis.
+        //  sekunde: Die abzuziehende Sekunde.
+        __declspec( dllexport ) void minusSekunde( int sekunde );
+        
+        // Gibt die gespeicherte Zeit als Text zurück.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit zurückgegeben werden soll. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        __declspec( dllexport ) Text *getZeit( const char *format ) const;
+        // Überprüft, ob die Zeit gleich der übergebenen Zeit ist.
+        //  zeit: die zu überprüfende Zeit.
+        //  return: (true), wenn die Zeiten gleich sind. (false) sonst.
+        __declspec( dllexport ) bool istGleich( Zeit *zeit ) const;
+        // Überprüft, ob die Zeit gleich der übergebenen Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die zu überprüfende Zeit enthält.
+        //  return: (true), wenn die Zeiten gleich sind. (false) sonst.
+        __declspec( dllexport ) bool istGleich( const char *format, const char *zeit ) const;
+        // Überprüft, ob die Zeit gleich der übergebenen Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Text Zeichnung, welches die zu überprüfende Zeit enthält.
+        //  return: (true), wenn die Zeiten gleich sind. (false) sonst.
+        __declspec( dllexport ) bool istGleich( const char *format, Text *zeit ) const;
+        // Überprüft, ob die Zeit gleich der übergebenen Zeit ist.
+        //  jahr: Das zu überprüfende Jahr.
+        //  monat: Der zu überprüfende Monat.
+        //  tag: Der zu überprüfende Tag.
+        //  stunde: Die zu überprüfende Stunde.
+        //  minute: Die zu überprüfende Minute.
+        //  sekunde: Die zu überprüfende Sekunde.
+        //  return: (true), wenn die Zeiten gleich sind. (false) sonst.
+        __declspec( dllexport ) bool istGleich( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const;
+        // Gibt das Zeichnung zurück, in dem das Datum gespeichert wird mit erhöhtem Reference Counter.
+        __declspec( dllexport ) Datum *getDatum() const;
+        // Gibt das Zeichnung zurück, in dem das Datum gespeichert wird ohne erhöhten Reference Counter.
+        __declspec( dllexport ) Datum *zDatum() const;
+        // Gibt das Zeichnung zurück, in dem die Uhrzeit gespeichert wird mit erhöhtem Reference Counter.
+        __declspec( dllexport ) Uhrzeit *getUhrzeit() const;
+        // Gibt das Zeichnung zurück, in dem die uhrzeit gespeichert wird ohne erhöhten Reference Counter.
+        __declspec( dllexport ) Uhrzeit *zUhrzeit() const;
+        // Überprüft, ob die gespeicherte Zeit kleiner als die übergebene Zeit ist.
+        //  zeit: Die zu überprüfende Zeit.
+        //  return: (true) wenn die gespeicherte Zeit vor der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istKleiner( Zeit *zeit ) const;
+        // Überprüft, ob die gespeicherte Zeit kleiner als die übergebene Zeit ist.
+        //  jahr: Das zu überprüfende Jahr.
+        //  monat: Der zu überprüfende Monat.
+        //  tag: Der zu überprüfende Tag.
+        //  stunde: Die zu überprüfende Stunde.
+        //  minute: Die zu überprüfende Minute.
+        //  sekunde: Die zu überprüfende Sekunde.
+        //  return: (true) wenn die gespeicherte Zeit vor der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istKleiner( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const;
+        // Überprüft, ob die gespeicherte Zeit kleiner als die übergebene Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die zu überprüfende Zeit enthält.
+        //  return: (true) wenn die gespeicherte Zeit vor der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istKleiner( const char *format, const char *zeit ) const;
+        // Überprüft, ob die gespeicherte Zeit kleiner als die übergebene Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Text Zeichnung, welches die zu überprüfende Zeit enthält.
+        //  return: (true) wenn die gespeicherte Zeit vor der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istKleiner( const char *format, Text *zeit ) const;
+        // Überprüft, ob die gespeicherte Zeit größer als die übergebene Zeit ist.
+        //  zeit: Die zu überprüfende Zeit.
+        //  return: (true) wenn die gespeicherte Zeit nach der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istGrößer( Zeit *zeit ) const;
+        // Überprüft, ob die gespeicherte Zeit größer als die übergebene Zeit ist.
+        //  jahr: Das zu überprüfende Jahr.
+        //  monat: Der zu überprüfende Monat.
+        //  tag: Der zu überprüfende Tag.
+        //  stunde: Die zu überprüfende Stunde.
+        //  minute: Die zu überprüfende Minute.
+        //  sekunde: Die zu überprüfende Sekunde.
+        //  return: (true) wenn die gespeicherte Zeit nach der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istGrößer( int jahr, int monat, int tag, int stunde, int minute, int sekunde ) const;
+        // Überprüft, ob die gespeicherte Zeit größer als die übergebene Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Zeichenkette, die die zu überprüfende Zeit enthält.
+        //  return: (true) wenn die gespeicherte Zeit nach der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istGrößer( const char *format, const char *zeit ) const;
+        // Überprüft, ob die gespeicherte Zeit größer als die übergebene Zeit ist.
+        //  format: Eine Zeichenkette, die angibt in welcher Form die neue Zeit in (zeit) vorhanden ist. y=Jahr, m=Monat, d=Tag, h=Stunde, i=Minute, s=Sekunde.
+        //  zeit: Eine Text Zeichnung, welches die zu überprüfende Zeit enthält.
+        //  return: (true) wenn die gespeicherte Zeit nach der übergebenen Zeit liegt. (false) sonnst.
+        __declspec( dllexport ) bool istGrößer( const char *format, Text *zeit ) const;
+
+        // Erhöht den Reference Counting Zähler
+        //  return: this
+        __declspec( dllexport ) Zeit *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht
+        //  return: 0
+        __declspec( dllexport ) Zeit *release();
+    };
+
+    // Diese Klasse kann messen, wie viel Zeit zwischen zwei Zeitpunkten verstrichen ist
+    class ZeitMesser
+    {
+    private:
+        double start;
+        double ende;
+        double messung;
+        int ref;
+
+    public:
+        // Erzeugt ein neues ZeitMesser Zeichnung
+        __declspec( dllexport ) ZeitMesser();
+        // Löscht das aktuelle Zeichnung
+        __declspec( dllexport ) ~ZeitMesser();
+
+        // legt den Startpunkt des zeitstoppens fest
+        __declspec( dllexport ) void messungStart();
+        // legt des Endpunkt der Zeitmessung fest
+        __declspec( dllexport ) void messungEnde();
+        
+        // gibt den Abstand zwischen start und ende der Messung in Sekunden zurück
+        __declspec( dllexport ) double getSekunden() const;
+        // gibt den Abstand zwischen start und ende der Messung in Minuten zurück
+        __declspec( dllexport ) double getMinuten() const;
+        // gibt den Abstand zwischen start und ende der Messung in Stunden zurück
+        __declspec( dllexport ) double getStunden() const;
+        
+        // Erhöht den Reference Counting Zähler.
+        //  return: this.
+        __declspec( dllexport ) ZeitMesser *getThis();
+        // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Zeichnung automatisch gelöscht.
+        //  return: 0.
+        __declspec( dllexport ) ZeitMesser *release();
+    };
+
+    // gibt die aktuelle Uhrzeit zurück.
+    __declspec( dllexport ) Uhrzeit *getUhrzeit();
+    // gibt das aktuelle Datum zurück.
+    __declspec( dllexport ) Datum *getDatum();
+    // gibt die aktuelle Zeit( Datum und Uhrzeit ) zurück.
+    __declspec( dllexport ) Zeit *getZeit();
+    // prüft, ob jahr ein Schaltjahr ist.
+    //  jahr: Das zu überprüfende Jahr.
+    //  return: (true), wenn das übergebene jahr ein Schaltjahr ist. (false) sonst.
+    __declspec( dllexport ) bool istSchaltjahr( int jahr );
+}
+
+#endif

+ 56 - 0
main.h

@@ -0,0 +1,56 @@
+#ifndef main_H
+#define main_H
+
+#ifdef _DEBUG
+#ifndef _LTMDB
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
+#define new DEBUG_CLIENTBLOCK
+#define _LTMDB
+#endif
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#define KSGStart __stdcall
+
+namespace Framework
+{
+    // Speichert die dem Programm vom Betriebssystem beim Start übergebenen Parameter
+	struct Startparam
+	{
+		HINSTANCE hinst, hpinst;
+		LPSTR cmd;
+		int show;
+	};
+
+    // Überschreibe diese Funktion. Sie wird vom Framework automatisch beim Start des Programmes aufgerufen
+    //  p: Die Parameter, die dem Programm beim Start vom Betriebssystem übergeben wurden
+	int KSGStart Start( Startparam p );
+    // Initialisiert das Framework
+    // Wird in der (WinMain) des Frameworks automatisch aufgerufen
+	__declspec( dllexport ) void initFramework();
+    // Gibt den duch (initFramework) benutzten Arbeitsspeicher wieder frei
+    // Wird in der (WinMain) des Frameworks automatisch aufgerufen
+	__declspec( dllexport ) void releaseFramework();
+}
+
+int WINAPI WinMain( _In_ HINSTANCE hinst, _In_opt_ HINSTANCE hpinst, _In_ LPSTR cmd, int _In_ show )
+{
+#ifdef _DEBUG
+    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+	Framework::initFramework();
+	Framework::Startparam stp;
+	stp.hinst = hinst;
+	stp.hpinst = hpinst;
+	stp.cmd = cmd;
+	stp.show = show;
+	int ret = Framework::Start( stp );
+	Framework::releaseFramework();
+	return ret;
+}
+
+#endif