Entwickler-Ecke

Windows API - GetDC von Bitmaps


HenryHux - Sa 12.03.11 19:20
Titel: GetDC von Bitmaps
Hi, tut mir leid, wenn ich hier schon wieder frage, aber finde nichts im Internet und habe schon viel ausprobiert..

Und zwar habe ich folgende Prozedur, mit der ich wunderbar Screenshots machen kann.
Jetzt will ich mit ihr aber nicht den gescreenshotteten Desktop schneiden, sondern ein HBitmap, welches ich übergebe.
Sieht so aus :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
property Bitmap: HBITMAP read FBitmap;

//...
procedure TScreenshot.CutH(Links, Rechts, Oben, Unten : Integer; SourceBitmap : HBitmap);
const
  CAPTUREBLT = $40000000;
var
  Width, Height: Integer;
  SourceDC, TargetDC, MyHDC: HDC;
  DesktopWindow: HWND;

//...
  Width := Rechts - Links;
  Height := Unten - Oben;
  DesktopWindow := GetDesktopWindow;
  SourceDC := GetDC(DesktopWindow);
  TargetDC := CreateCompatibleDC(SourceDC);
  FBitmap := CreateCompatibleBitmap(SourceDC, Width, Height);
  SelectObject(TargetDC, FBitmap);
  BitBlt(TargetDC, 00, rechts, unten, SourceDC, links, oben, SRCCOPY or CAPTUREBLT);
  ReleaseDC(SourceBitmap, SourceDC);
  DeleteDC(TargetDC);


Also ist mein Problem praktisch das SourceDC, welches hier den Desktop-Screenshot annimmt.
Das müsste ich mit einem HBitmap schaffen, aber kriege ich nicht hin...
Danke,

Lg

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Also vielleicht hab ich das ein bisschen doof beschrieben :D
Bis jetzt hatte ich immer zuerst einen Screenshot vom Bildschirm gemacht, den auf ein Quadrat geschnitten.
Danach habe ich den nochmal geschnitten, so dass ich genau das Bild hatte was ich wollte.
Ich weiß, ich hätte das schlauer machen können, mit zb nur einmal Schneiden :D
Naja, jetzt hab ich halt genau die Zahlen, die das sein müssten...
Also dachte ich mir ich hab 2 Möglichkeiten das jetzt zu realisieren (nur mit Bitmap Handles) :
1. Es gibt irgendwelche mathematischen Formeln um soetwas auszurechnen, das würde mich dann dazu führen, dass ich nur einmal schneiden müsste. Wäre Perfekt. Nur kann ich garkein Mathe :D
2. Ich kriege das so irgendwie hin... In meiner Funktion die ich bis jetzt habe kriege ich den ersten Schritt problemlos hin (der wo zuerst ein Quadrat geschnitten wird). Doch das zweite mal Schneiden geht nicht, oder nicht so wie ich will.
Entweder schneidet er zwar die richtige Größe, aber falsche Stelle. Habe mir schon ein paar Dokumentationen durchgelesen, aber ich verstehe trotzdem nicht was hinter Funktionen wie SelectObject steckt und wie die arbeiten.
Vielleicht kann mir ja jemand auf die Sprünge helfen..
Ich poste mal was ich bis jetzt so probiert habe, vielleicht sieht ja dann jemand wo dras Problem ist :D

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
//Bis hierhin habe ich das Quadrat gespeichert in einem HBitmap genannt ZBitmap..
//Ich will das neue HBitmap auf eine Variable FBitmap kriegen
  FBitmap := SelectObject(TargetDC, ZBitmap); //Das alte Bitmap in das Neue
  FBitmap := CreateCompatibleBitmap(TargetDC, Width2, Height2);  //Größe des Neuen einstellen
  BitBlt(FBitmap, 00, rechts, unten, TargetDC, links, oben, SRCCOPY);  //Und schneiden
  //FBitmap bleibt schwarz...

Lg


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Sa 12.03.2011 um 23:41


jaenicke - Sa 12.03.11 23:15

CreateCompatibleBitmap gibt eine HBitmap zurück, BitBlt erwartet aber einen DC, einen Device Context.


HenryHux - Sa 12.03.11 23:54

Ok, danke, Compiler nimmts ohne Warnung -.-
Also den Device Context brauche ich ja von dem FBitmap.
Also zuerst eine neue HDC anlegen, die für BitBlt benutzen und danach mit SelectObject(FBitmap, NewDC) den DC auf das HBitmap übertragen?

Also

Delphi-Quelltext
1:
2:
3:
1. MyHBitmap := CreateCompatibleBitmap(NewDC, Width, Height) // Ist es hier egal welchen DC ich einsetze?
2. BitBlt(NewDC, 00, rechts, unten, TargetDC, links, oben, SRCCOPY);
3. SelectObject(NewDC, MyHBitmap);

Sry, dass ich mich so blöd anstelle, mich verwirrt der Unterschied zwischen Handles und DCs und zwischen SelectObject und BitBlt :D


HenryHux - So 13.03.11 10:41

So, bei mir geht garnichts mehr, ich blicke kein bisschen mehr durch.
Habe bestimmt schon 20mal das gleiche probiert.
Erstmal habe ich eine Frage zu der mathematischen Lösung in einem Mathe Forum gestellt, ich glaube da passt das ein bisschen besser hin :D
http://www.matheboard.de/thread.php?threadid=449144
So, aber auch wenn das klappt will ich herausbekommen, wie das mit der Informatiker-Lösung klappt, kratzt an meiner Ehre.. :D
Also wenn ich das so ausführe

Delphi-Quelltext
1:
2:
3:
  DesktopWindow := GetDesktopWindow;
  SourceDC := GetDC(DesktopWindow);
  TargetDC := CreateCompatibleDC(SourceDC);
dann klappt es wunderbar, nur dass er direkt den ganzen Bildschirm aufnimmt. Das will ich jetzt als Ausgangssituation nicht mit dem GetDesktopWindow haben, sondern mit einem HBitmap.
Ich frage mich andauernd, wo denn eigentlich das Problem ist, so schwierig dürfte es doch nicht sein :D
So wie ich das verstanden habe nimmt SourceDC hier den Device Context zu dem DesktopWindow auf.
Dass heißt wenn ich jetzt den SourceDC einfach den DC von den HBitmap aufnehmen lassen würde m ü s s t e es ja klappen..
Das geht aber weder mit

Delphi-Quelltext
1:
SourceDC := GetDC(HBitmap);                    

Noch mit

Delphi-Quelltext
1:
SourceDC := HBitmap;                    

Noch mit

Delphi-Quelltext
1:
SourceDC := CreateCompatibleDC(HBitmap);                    


Kennt da jemand das eine Schlüsselwort?

Lg


jaenicke - So 13.03.11 11:13

Zuerst CreateCompatibleDC auf einen bestehenden DC, danach SelectObject um die Bitmap in den DC zu setzen.