# Bildschirmspeicher



## eviluser (3. November 2003)

Hallo

Ich möchte folgends programm schreiben und scheitere leider an meinen fähigkeiten. 
Das Programm soll den bildschirmspeicher zeile für  zeile auslesen und nach einem bestimmten farbwert suchen. findet es den farbwert bricht er sofort ab und übergibt x und y koordinaten.

ich dachte an c++ mit inline assembler und hab Dev-C++ welches irgend so ein AT&T Assembler verwendet.
Ich will dieses programm in windows XP  zum laufen bringen und probiere schon ziemlich verkrampft rum. ich hab keine ahnung wie ich physischen speicher adressieren soll und zu diesem AT&T zeug finde ich keine dokus (zumindest nix was ich ohne weiteres verstehen kann).

ich wäre für jede hilfe dankbar.
eviluser


----------



## Tobias K. (3. November 2003)

moin


Ich glaube nciht das du noch zugriff auf diesen Speicher bekommst.
Mach doch einen Screenshot und such dadrin nach deinen Farbwert.


mfg
umbrasaxum


----------



## chibisuke (4. November 2003)

Wenn du direkten zugriff auf dem speicher hast:

Nun im realmode ist der graphikspeicher an 0xA000:0000 - 0xA000:FFFF zu finden im VGA modus...
im PMode musste einen eintrag in der GDT machen, der als anfangsaddresse 0xA0000 benutzt, und dann musste einen selektor für den deskriptor erstellen, den musste dann in ein segmentregister laden, pass dabei auf das du auch mit dem CPL höher oder gleich DPL und RPL sein muss... hierfür empfehle ich dir als weiterführende lektüre das "Datenblatt" zur i386 architektor, da ist unter anderem beschrieben wir man die GDT bearbeitet, wie selektoren und desktoptoren aufgebaut werden müssen und wie sich CPL, DPL und RPL verhällt.

Aber da du das ganze ja unter windows machen willst sieht es nunmal so aus:
In windows XP? vergiss es...

Das einzige programm was in windows XP direkt auf den bildschirmspeicher zugreifen darf ist ein GRAPHIKTREIBER

Das heißt direkt auf den bildschirmspeicher schaffste nicht ohne das du dich mit dem DDK auseinander setzt, und das vergisste am besten wieder, weil da is schon das kompilieren ein hammer, das Debuggen von Drivern is der blanke horror, ich sag nur.. einmal und nie wieder , davon abgesehen das du bei sowas auf jedenfall 2 PCs mit netzwerk verbindung, einen Kernel mode debugger der remote debuging unterstützt und extrem gute kenntnisse der internen architektur von windows haben musst. 

Aber es gibt alternativen, und zwar gleich 2 stück...

dafür folgendes.. 
1.) Vergiss Assembler, is viel zu kompliziert das in assembler zu schreiben...

Nun hast du folgende möglichkeiten
a.) GDI
b.) DirectDraw

a.)Wenn du über GDI gehst musst du mit CreateDC() einen gerätekontext für das gerät "DISPLAY" erzeugen.. dadurch verbindest du einen neuen gerätekontext mit dem bildschirmspeicher, nun erstellst du ein bitmap mit der entsprechenden größe CreateBitmap müsste das sein.. erstellst einen kompatiblen Device Context.. CreateCompabibleDC().. dann das bitmap mit dem DC verbinden ... SelectObject() dann von der aktiven bildschirmseite in das bitmap blitten BitBlt() , dann die graphik in einen systemspeicher buffer kopieren... GetDIBits() und dann die daten auswerten. nun DeleteDC(), DeleteDC() also sowohl den DISPLAY als auch den kompatiblen.. nun DeleteObject auf das hBitmap

b.) COM initialisieren CoInitalizeEx(), instanz von IDirectDraw erstellen CoCreateInstance(), DirectDraw initialisieren.. IDirectDraw::init(), dann Coopertative level auf cooperation mit GDI einstellen... IDirectDraw::setCooperativeLevel(), dann primary surface in größe des bildschirms erstellen, dabei auf IDirectDrawClipper verzichten... IDirectDraw::createSurface(), zu beachten ist das es sich dabei um ein primary surface in größe auflösung und farbtife des bildschirms handeln muss... nun ein entsprechends backsuface erzeigen IDirectDraw::createSurface, diesmal als offscreen surface, selbe größe selbe farbtife... nun IDirectDrawSurface::BltFast() von Primary auf Offscreen surface... nun IDirectDrawSurface::lock() (das offscreen surface ist gemeint) nun bekommste n pointer auf die daten... diese mit memcpy raus kopieren ... dannach sofort IDirectDrawSurface::unlock() aufpassen,.. wenn zwischen lock und unlock was schief geht, der rest des systems regiert in dieser fase absolut gar nicht... IDirectDrawSurface::release() IDirectDrawSurface::release() also beide surfaces.. dann IDirectDraw::release() und nun CoUninitialize()

so und nun such dir eine methode aus wie dus machen willst... alle wichtigen schritte sind aufgeführt, die entsprechenden parameter listen zu den funktionen gibts in der MSDN, das DirectX SDK ist auf der M$ website zu bekommen.
Wenn du es doch mit dem DDK versuchen willst,, gibts auch auf der M$ website, aber sag nicht ich hab dich nicht gewarnt..

Viel spaß!


----------



## yaXay (23. November 2003)

Wieso einfach machen, wenn's auch kompliziert geht, wie?
Ich empfehle dir Win32 ASM & Win GDI!
GetDesktopWindow, GetDC, GetDIBits, ReleaseDC.. und der vergleich geht ja mit asm ganz schnell..

MfG,
yaXay


----------

