# Screenshot – wieso funktioniert das nicht?



## DelphiDell (29. März 2006)

Hi , hallo miteinander ich habe mier eine Kleine Klasse um einen Screenshot zu machen geschrieben 


```
#include <windows.h>
#include <string>
#include <iostream>

using namespace std;

class CStellwerk
{
private:
	HWND m_hDesktop;
public:

	void MakeScreenshot(char SavePath[]);
	void SaveScreen(HWND pScreen, char Path[]);
};

void CStellwerk::MakeScreenshot(char SavePath[])
{
	 m_hDesktop =  GetDesktopWindow();
	 if(m_hDesktop == NULL)
	 {
		 exit(1);
	 }
	 SaveScreen(m_hDesktop,SavePath);
}
	 

int main()
{
	CStellwerk Stellwerk;
	Stellwerk.MakeScreenshot("C:\\screen.bmp");
	
}


void CStellwerk::SaveScreen(HWND pScreen, char Path[])
{
	HDC hdcScreen;
    HBITMAP hbmScreen;


    //---------------Bitmap Informationen
	BITMAPINFO infobmp;
	infobmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	infobmp.bmiHeader.biWidth = 1024;
	infobmp.bmiHeader.biHeight = 768;
	infobmp.bmiHeader.biPlanes = 1;
	infobmp.bmiHeader.biBitCount = 24;
	infobmp.bmiHeader.biCompression = 0;
    infobmp.bmiHeader.biSizeImage = 0;
    infobmp.bmiHeader.biXPelsPerMeter = 0;
    infobmp.bmiHeader.biYPelsPerMeter = 0;
    infobmp.bmiHeader.biClrUsed = 0;
    infobmp.bmiHeader.biClrImportant = 0;

	int* bitmap = new int[1024*768*16];

	BITMAPFILEHEADER bfheader;
	
	bfheader.bfType = 19778;
	bfheader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(bitmap)+ sizeof(BITMAPINFOHEADER);
	bfheader.bfReserved1 = 0;
    bfheader.bfReserved2 = 0;
	bfheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    //Bitmap -----------------------      Informationen


    hdcScreen = GetDC(pScreen);
	hbmScreen = CreateCompatibleBitmap(hdcScreen,1024,768);

	GetDIBits(hdcScreen,hbmScreen,0,500,bitmap,&infobmp,DIB_RGB_COLORS);

	HANDLE hfile = CreateFile((LPCWSTR) Path,GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0);

	//Datei Schreiben

	DWORD word;
	WriteFile(hfile,&bfheader,14,&word,NULL);
	WriteFile(hfile,&infobmp,40,&word,NULL);
	WriteFile(hfile,bitmap,750000,&word,NULL);

	ReleaseDC(pScreen,hdcScreen);
	CloseHandle(hfile);
	delete[] bitmap;
}
```

Das Programm Srarted ohne Fehler und Beendet wieder ohne Fehler, aber am Schluss ist keine Datei zu finden  

//Edit hab grad gefunden wo die Datein Stecken in meine visual C++ Verzeichniss Wiso denn dass 

Aber die Datein sind irgendwie etwas verkrüppelt :-  

Kann sie nicht oeffnen und der Dateinahme ist dass ??????p  :-

Hoffe Jemand kann mier Helfen


----------



## Endurion (30. März 2006)

A) Du hast einen char-Pointer (Path) auf einen Unicode-String gecastet. Das versaut deinen Dateinamen. Wenn du ein Unicode-Projekt hast, musst du auch einen echten Unicode-Dateinamen angeben.

B) Was soll das * 16 bei dem bitmap-new? * 3 reicht für 24bit aus. Was machst du, wenn jemandes Desktop nicht 1024x768 hat (praktisch 99% aller User)?

C) sizeof(bitmap) gibt dir NICHT die Grösse des alloziierten Speicherbereichs zurück, sondern die Grösse eines Pointers.

D) Wenn du die 750000 beim Schreiben auf die echte Grösse des Buffers anpasst (1024*768*3), dann kann man die BMP schon mal laden. Beim Testen habe ich da aber noch nicht den richtigen Inhalt des Desktops gesehen.


----------



## DelphiDell (30. März 2006)

A) Wie kann ich einen Unicode Dateinahmen angeben


----------



## DelphiDell (30. März 2006)

Hi dass Bild sieht irgendwie besch.... aus 

im oberen Drittel ist es grau im unteren drittel Schwart 


//Edit liefert 

GetDesktopWindow(); ueberhaubt ein Handel auf den Bildschirm zurück oder bloss auf dass fenseter ?


----------



## Endurion (30. März 2006)

So, habe den Rest auch raus: Scheinbar klappt GetDIBits nicht auf dem HDC vom Desktop, dann legt man eben einen Zwischenschritt ein:



```
void SaveScreen(HWND pScreen, char Path[]) 
{ 
    HDC hdcScreen; 
    HBITMAP hbmScreen; 


    //---------------Bitmap Informationen 
    BITMAPINFO infobmp; 
    infobmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    infobmp.bmiHeader.biWidth = 1024; 
    infobmp.bmiHeader.biHeight = 768; 
    infobmp.bmiHeader.biPlanes = 1; 
    infobmp.bmiHeader.biBitCount = 24; 
    infobmp.bmiHeader.biCompression = 0; 
    infobmp.bmiHeader.biSizeImage = 0; 
    infobmp.bmiHeader.biXPelsPerMeter = 0; 
    infobmp.bmiHeader.biYPelsPerMeter = 0; 
    infobmp.bmiHeader.biClrUsed = 0; 
    infobmp.bmiHeader.biClrImportant = 0; 

    int* bitmap = new int[1024*768*3]; 

    BITMAPFILEHEADER bfheader; 
     
    bfheader.bfType = 19778; 
    bfheader.bfSize = sizeof(BITMAPFILEHEADER) + 1024*768*3 + sizeof(BITMAPINFOHEADER); 
    bfheader.bfReserved1 = 0; 
    bfheader.bfReserved2 = 0; 
    bfheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
    //Bitmap -----------------------      Informationen 


    hdcScreen = GetWindowDC(pScreen); 
    hbmScreen = CreateCompatibleBitmap(hdcScreen,1024,768); 

    // temporärer DC
    HDC hdcTemp = CreateCompatibleDC( hdcScreen );

    // Bitmap reinselektieren
    HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen );

    // Inhalt von Desktop übertragen
    BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY );

    int iResult = GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS); 

    // aufräumen
    SelectObject( hdcTemp, hbmOld );
    DeleteObject( hbmScreen );
    DeleteDC( hdcTemp );

    HANDLE hfile = CreateFile( Path,GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0); 

    //Datei Schreiben 

    DWORD word; 
    WriteFile(hfile,&bfheader,14,&word,NULL); 
    WriteFile(hfile,&infobmp,40,&word,NULL); 
    WriteFile(hfile,bitmap,1024*768*3,&word,NULL); 

    ReleaseDC(pScreen,hdcScreen); 
    CloseHandle(hfile); 
    delete[] bitmap; 
}
```


----------



## MCoder (30. März 2006)

Hallo,

dein Code enthält einige Fehler, vergleiche mal mit meiner Variante.

Gruß
MCoder

```
int     nWidth  = GetSystemMetrics(SM_CXSCREEN);
int     nHeight = GetSystemMetrics(SM_CYSCREEN);

HWND    hWnd    = ::GetDesktopWindow();
HDC     hdc     = ::GetDC(hWnd);
HDC     memDC   = ::CreateCompatibleDC(hdc);
HBITMAP hbm     = ::CreateCompatibleBitmap(hdc, nWidth, nHeight);
HBITMAP hbmOld  = (HBITMAP)::SelectObject(memDC, hbm);

::BitBlt(memDC, 0, 0, nWidth, nHeight, hdc, 0, 0, SRCCOPY);
                                 
BITMAPINFO bmi;

ZeroMemory(&bmi, sizeof(bmi));

bmi.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth        = nWidth;
bmi.bmiHeader.biHeight       = nHeight;
bmi.bmiHeader.biBitCount     = 24;
bmi.bmiHeader.biPlanes       = 1;
bmi.bmiHeader.biCompression  = BI_RGB;
bmi.bmiHeader.biSizeImage    = 32 * nWidth * nHeight / 8;

BYTE *pbBits = new BYTE[bmi.bmiHeader.biSizeImage];

::GetDIBits( memDC, 
             hbm,
             0,
             bmi.bmiHeader.biHeight,
             pbBits,
             &bmi,
             DIB_RGB_COLORS );

BITMAPFILEHEADER bfh;

bfh.bfType      = ('M' << 8) + 'B';
bfh.bfSize      = sizeof(BITMAPFILEHEADER)  +
                  bmi.bmiHeader.biSizeImage +
                  sizeof(BITMAPINFOHEADER); 
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

HANDLE hfile = CreateFile( _T("c:\\temp\\screen.bmp"),
                           GENERIC_WRITE,
                           0,
                           0,
                           OPEN_ALWAYS,
                           0,
                           0 ); 

DWORD dwWritten;
 
WriteFile(hfile,&bfh,           sizeof(bfh),               &dwWritten, NULL); 
WriteFile(hfile,&bmi.bmiHeader, sizeof(BITMAPINFOHEADER),  &dwWritten, NULL); 
WriteFile(hfile,pbBits,         bmi.bmiHeader.biSizeImage, &dwWritten, NULL); 

CloseHandle(hfile); 

::SelectObject(memDC, hbmOld);
::DeleteDC(memDC);
::ReleaseDC(hWnd,hdc); 
::DeleteObject(hbm);

delete[] pbBits;
```


----------



## Endurion (30. März 2006)

Der Code von MCoder ist natürlich noch besser, der geht auf die aktuelle Auflösung des Desktops ein. Nur ein kleiner Meckerer: Wieso bei biSIzeImage 32 / 8? Da ist doch ein viertel überflüssig belegt?


----------



## MCoder (30. März 2006)

Endurion hat gesagt.:
			
		

> Nur ein kleiner Meckerer: Wieso bei biSIzeImage 32 / 8? Da ist doch ein viertel überflüssig belegt?


Vollkommen richtig, sollte eigentlich auch so aussehen:

```
bmi.bmiHeader.biSizeImage = bmi.bmiHeader.biBitCount * nWidth * nHeight / 8;
```


----------



## DelphiDell (5. April 2006)

Danke Funktioniert toll kann mier jemand dass noch genau erklären 


```
HDC hdcTemp = CreateCompatibleDC( hdcScreen );   

HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen );   
 
BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY );    

int iResult = GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS);
```


----------



## MCoder (6. April 2006)

*HDC hdcTemp = CreateCompatibleDC( hdcScreen );*
Erstellt einen Speicher-Device-Kontext, der die gleichen Eigenschaften wie der des Desktop-Fensters hat.

*HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen );*
Grafikausgabe bei Windows funktioniert mit sogenannten GDI-Objekten, die vor ihrer Verwendung ausgewählt werden müssen. Dabei muss das vorher (von Windows) verwendete Objekt gespeichert und am Schluss wiederhergestellt werden. Sonst gibt's ein Speicherloch, weil Windows dieses Objekt nicht mehr verwenden und ggf. freigeben kann.
In unserem Fall benötigen wir ein Bitmap als GDI-Objekt, um die entsprechenden Daten daraus zu extrahieren. 
Dieses Bitmap bekommen wir nicht vom Device-Kontext des Desktop-Fensters, sondern müssen es Speicher-Kontext selber erzeugen und dem Speicher-Kontext zuordnen.

*BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY );*
Kopiert das Bild vom Desktop in den Speicher-Kontext.

*int iResult = GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS);*
Kopiert die Bilddaten in einen Buffer. Diese Bildaten werden dann, mit einem entsprechenden Dateikopf versehen, dann als Bitmap-Datei gespeichert.

Gruß
MCoder


----------



## ibot (25. März 2007)

Guten Tag,

ich habe die ganzen Codes mal zusammen gebastelt und wollte das nun compilieren. 

Aber ich bekomme immer folgende fehler meldung zurück:


```
error C2501: 'BitBlt' : Fehlende Speicherklasse oder Typbezeichner
```

Ich hoffe ihr könnt mir helfen was das heißen soll.

Vielleicht bin ich auch zu doof zum zusammen fügen der ganzen Code Teile hier. Ne Komplete version wäre vielleicht was feines.

Danke schon mal MFG iBot


----------



## MCoder (25. März 2007)

Was für ein Projekt: MFC, Win32, Console? Ist  *#include <windows.h>* vorhanden? Zeige doch evt. mal die zusammengebastelten Codes.

Gruß
MCoder


----------



## ibot (25. März 2007)

Also ich habe folgendes geplant:
ein script soll alle 5 sekunden ein screenshot machen und diesen auf einen FTP server hochladen.

Dafür brauch ich ein script/datei/anwedung was beim aufrufen ein screenshot erstellt und diese als Datei speichert.

Also denke ich mal das zählt als Consolen Projekt (soll auf Win XP laufen)

MFG iBot


----------



## Endurion (25. März 2007)

Wie MCoder schon sagt:

Hast du <windows.h> includet? Das sollte Schritt 1 sein, wenn du mit GDI zu arbeiten gedenkst. Alles andere sollte sich dann finden.

Wenn du dein Projekt testweise als ZIP irgendwo hochlädst, können wir das auch einfacher ansehen. Wenn der Code nicht allzulang ist (oder ein simples Beispielprojekt), dann am besten mit [ code ] -Tags posten.


----------



## ibot (25. März 2007)

Endurion hat gesagt.:


> Wie MCoder schon sagt:
> 
> Hast du <windows.h> includet? Das sollte Schritt 1 sein, wenn du mit GDI zu arbeiten gedenkst. Alles andere sollte sich dann finden.
> 
> Wenn du dein Projekt testweise als ZIP irgendwo hochlädst, können wir das auch einfacher ansehen. Wenn der Code nicht allzulang ist (oder ein simples Beispielprojekt), dann am besten mit [ code ] -Tags posten.


Ja ich habe Windows.h includet.
Die fehler meldung ist folgende

```
(62) : fatal error C1004: Unerwartetes Dateiende gefunden
```
Also das ist das was ich mal so aus den codes zusammen gebastelt habe auf dieser seite

```
#include <windows.h> 
#include <string.h> 
#include <iostream> 

using namespace std; 

class CStellwerk 
{ 
private: 
HWND m_hDesktop; 
public: 

void MakeScreenshot(char SavePath[]); 
void SaveScreen(HWND pScreen, char Path[]) 
{ 
HDC hdcScreen; 
HBITMAP hbmScreen; 
//---------------Bitmap Informationen 
BITMAPINFO infobmp; 
infobmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
infobmp.bmiHeader.biWidth = 1024; 
infobmp.bmiHeader.biHeight = 768; 
infobmp.bmiHeader.biPlanes = 1; 
infobmp.bmiHeader.biBitCount = 24; 
infobmp.bmiHeader.biCompression = 0; 
infobmp.bmiHeader.biSizeImage = 0; 
infobmp.bmiHeader.biXPelsPerMeter = 0; 
infobmp.bmiHeader.biYPelsPerMeter = 0; 
infobmp.bmiHeader.biClrUsed = 0; 
infobmp.bmiHeader.biClrImportant = 0; 
int* bitmap = new int[1024*768*3]; 
BITMAPFILEHEADER bfheader; 
bfheader.bfType = 19778; 
bfheader.bfSize = sizeof(BITMAPFILEHEADER) + 1024*768*3 + sizeof(BITMAPINFOHEADER); 
bfheader.bfReserved1 = 0; 
bfheader.bfReserved2 = 0; 
bfheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
//Bitmap ----------------------- Informationen 
hdcScreen = GetWindowDC(pScreen); 
hbmScreen = CreateCompatibleBitmap(hdcScreen,1024,768); 
// temporärer DC
HDC hdcTemp = CreateCompatibleDC( hdcScreen );
// Bitmap reinselektieren
HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen );
// Inhalt von Desktop übertragen
BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY );
int iResult = GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS); 
// aufräumen
SelectObject( hdcTemp, hbmOld );
DeleteObject( hbmScreen );
DeleteDC( hdcTemp );
HANDLE hfile = CreateFile( Path,GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0); 
//Datei Schreiben 
DWORD word; 
WriteFile(hfile,&bfheader,14,&word,NULL); 
WriteFile(hfile,&infobmp,40,&word,NULL); 
WriteFile(hfile,bitmap,1024*768*3,&word,NULL); 
ReleaseDC(pScreen,hdcScreen); 
CloseHandle(hfile); 
delete[] bitmap; 
}
```


----------



## MCoder (25. März 2007)

Am Ende der Klassendeklaration fehlt die schließende Klammer und das Semikolon:

```
class CStellwerk 
{ 

    // ...

}; // fehlt !!
```
Gruß
MCoder


----------



## ibot (25. März 2007)

MCoder hat gesagt.:


> Am Ende der Klassendeklaration fehlt die schließende Klammer und das Semikolon:
> 
> ```
> class CStellwerk
> ...


Ich habe das fehlende ";" am ende des scriptes angehängt, aber der fehler ist immer noch der selbe.


----------



## MCoder (25. März 2007)

Dann liegts wahrscheinlich an den vorkompilierten Headern. Füge mal in der .cpp-Datei ein als allererstes *#include "stdafx.h"* ein.

Gruß
MCoder


----------



## ibot (25. März 2007)

MCoder hat gesagt.:


> Dann liegts wahrscheinlich an den vorkompilierten Headern. Füge mal in der .cpp-Datei ein als allererstes *#include "stdafx.h"* ein.
> 
> Gruß
> MCoder


Jetzt habe ich 5 Fehlermeldungen

```
error C2371: 'INT_PTR' : Neudefinition; unterschiedliche Basistypen
basetsd.h(123) : Siehe Deklaration von 'INT_PTR'

error C2371: 'PINT_PTR' : Neudefinition; unterschiedliche Basistypen
basetsd.h(123) : Siehe Deklaration von 'PINT_PTR'

error C2371: 'UINT_PTR' : Neudefinition; unterschiedliche Basistypen
basetsd.h(124) : Siehe Deklaration von 'UINT_PTR'

error C2371: 'PUINT_PTR' : Neudefinition; unterschiedliche Basistypen
basetsd.h(124) : Siehe Deklaration von 'PUINT_PTR'

fatal error C1083: Include-Datei kann nicht geoeffnet werden: 'HtmlHelp.H': No such file or directory
```


----------



## Endurion (26. März 2007)

Hmm, Alternative zum stdafx.h includen:

Stell mal die Precompiled Headers in den Projekt-Eigenschaften auf "nicht verwenden". Hat man nur Probleme mit.


----------



## MCoder (26. März 2007)

Falls doch precompilierte Header, dann auf jeden Falle wieder das "#include <windows.h>" entfernen. Die "stdafx.h" enthält bereits alle nötigen Includes.


----------



## ibot (26. März 2007)

habe jetzt das windows.h entfernt.
Nun bekomme ich folgende fehler meldung beim Compilieren:

```
HWND does not name a type
```


----------



## MCoder (27. März 2007)

Hallo,
es scheint, dass die ganze Struktur nicht so richtig passt. Versuche doch mal, deine Klasse in eine Form zu bringen, wie ich sie weiter unten skizziert habe, also die Trennung von Deklaration und Implementation in zwei Dateien.
Was steht denn aktuell in deiner Datei "stdafx.h" drinnen?

Gruß
MCoder


```
///////////////
// stellwerk.h
///////////////

#ifndef STELLWERK_H
#define STELLWERK_H

class CStellwerk  
{
public:
	CStellwerk();
	~CStellwerk();

public:
    void MakeScreenshot(char SavePath[]); 
    void SaveScreen(HWND pScreen, char Path[]);

private:
    HWND m_hDesktop;
};

#endif
```


```
/////////////////
// stellwerk.cpp
/////////////////

#include "stdafx.h"
#include "Stellwerk.h"

#include <string.h> 
#include <iostream> 

using namespace std; 

CStellwerk::CStellwerk()  { }
CStellwerk::~CStellwerk() { }

void CStellwerk::MakeScreenshot(char SavePath[])
{
    // ... Inhalt der Methode MakeScreenshot
}

void CStellwerk::SaveScreen(HWND pScreen, char Path[])
{
    // ... Inhalt der Methode SaveScreen
}
```


----------



## ibot (27. März 2007)

Ich bekomme immer mehr fehler meldungen. Ich glaube ich bekomme den Code einfach nicht richtig zusammen aus den ganzen Schnipseln hier.

Könnte mir jemand evtl. mal den Code zusammen stellen und hoch laden bzw. posten.

Danke schon mal

MFG iBot


----------



## MCoder (28. März 2007)

Naja, viel mehr als die Schnipsel ist da auch nicht dran. Laufen den wenigstens die Klassen (erstmal ohne die Funktionalität für den Screenshot) , die ich gepostet hatte?


----------



## ibot (29. März 2007)

Also ich habe probleme mit diesem HWND, das will bei mir nciht so recht. ich weiß nciht wie ich das deklarieren soll. könnt ihr mir helfen? bitte


----------



## MCoder (2. April 2007)

Ich vermute, deine Projekteinstellungen sind irgendwie verkorkst. Lege doch einfach nochmal eine Win32-Anwendung oder Win32-Konsolenanwendung neu an und probiere dann dort die Codeschnipsel aus.

Gruß
MCoder


----------



## No_name (25. Juni 2007)

Wenn der Code dann ohne probleme geht, kann Ihn dann jemand mal uppen? Also als kompletten Sourcecode? 

Kann nämlich gerade nicht mit C++ arbeiten, da ich es nicht installiert habe (auf diesen Pc).

Wäre zumindest geil, weil wenn ich mich dann mal da ransetzt, habe ich nicht gleich wieder tausend Fehler und muss Sie auch nicht alle wieder ausbessern ^^


----------



## No_name (3. Juli 2007)

Und? Hat es nun schon jemand geschafft/gemacht und könnte den Sourcecode uppen? =)


----------



## flo_321 (19. Mai 2008)

hi,

habe grade deinen codeschnipsel ausprobieren wollen, aber ich bekomme einen error in der zeile:


```
HANDLE hfile = CreateFile(_T("c:\\temp\\screen.bmp"),GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0 );
```



> f:\programmieren\screenshot2ftp\screenshot2ftp\screenshot2ftp\sfp_screenshot.h(44) : error C3861: "_T": Bezeichner wurde nicht gefunden.



was ist da falsch?

danke, flo


----------



## Endurion (20. Mai 2008)

Dafür benötigst du 
#include <tchar.h>


----------



## Doccos (12. Mai 2009)

Gibts für dieses Programm nun ein funktionierenden Source Code?

Will nämlich auch sowas ähnliches machen nur in einer Konsole aber irgentwie funktioniert das bei mir nicht


----------

