Bitmaps, hDC & Co



  • hallo
    kannst du mir bitte den quelltext, der für dein bitmap "verantwortlich" ist, schicken?
    ich schaffe das mit dem BMP nicht 😞
    also wie ladest du es und lässt es dann anzeigen?



  • Moment,
    du machst quasi folgendes:

    1. hdc_premem erzeugen (womit? CreateCompatibleDC() ?)
    2. Bitmap laden
    3. Bitmap in hdc_premem selektieren
    4. hdc_mem erzeugen? (wo? und womit ?)
    5. BitBlt() mit hdc_premem als Quelle und hdc_mem als Ziel ?

    Wenn du Transparenz brauchst, kannst du in deiner Draw()-Methode TransparentBlt() verwenden oder evtl. AlphaBlend(). Bei TransparentBlt() unbedingt in der MSDN unten die Remarks lesen 😉



  • ich erzeuge jedes hDC immer mit CreateCompatibleDC() ....

    das hdc mem is ein attribut der klasse ( um das bild zu speichern)

    hdc_mem=CreateCompatibleDC(hdC);-> steht dann im Konstruktor der Klasse (hab ich vergessen... sorry)

    also:

    1. ja
    2. ja
    3. ja
    4. schon vorher im konstruktor
    5. ja!

    und dann mit draw von hdc_mem auf den bildschirm!

    @Phillip:
    erst heut abend wenn ich mehr zeit hab...
    schick mir einfach eine PN damit ich mich erinner 🙂

    @transparenz:
    danke...werd schaun ob das geht!



  • vielen dank, wegen pn, muss man dazu nicht angemeldet sein?
    ich schreibe dir einfach hier am abend!

    jedenfalls danke dass du mir deine zeit opferst, aber ich hänge im moment echt in der luft!



  • pn gibt es hier nicht. auch wenn man angemeldet ist.



  • kein pn^^

    ja na ich hab ja icq da geht das schon...

    zu den Problems:

    ich werd das mit der transparenz einfahc mal versuchen...
    das mit dem Speichern is mir allerdigns immer noch ein rätsel!



  • Kann ich mir auch nich erklären.
    Hast du mal die Rückgabewerte der einzelnen Funktionen überprüft ?



  • nein eigentlich nichtz aber aufgerufen werden sie das weiß ich...und eigentlich funktioniert auch alles aber das HDC_mem is eifnach leer....
    ->hm?!
    das der da die daten der bitmnap einfach verliert...
    ich könnt höchsten ein große nehmen und in die alles reinspeichern...
    und dann immer wieder hin und her übergeben...so müsst ichs nur einmal laden...

    habs auch schon mit den globalen hDCs probiert aber es funktioniert nicht...

    die hDC daten gehen verloren wenn die Funktion / Methode in der die bitmap gealden wurde verlassen wird!...
    ->was auch logisch wäre...wenn die hDC`s nicht global wären!

    nebenfrage...
    gibts einen Befehl mit dem ich in den vollbildmodus umschalkten kann?
    also ohne titelleiste und ohne taskleiste?

    vlt gleich am anfang wenn ich das fenster aufbaue`?

    sowas wie VISIBLE und co...

    wie macht ihr das wenn ihr ein paar bitmapsdarstellen wollt? (Befehle...Programmreihenfolge und so)

    (wenn man die ned dauernd neu zeichnet, das fenster aber minimiert dann sind die ja weg....auch so ein prob)



  • Vollbildmodus geht mit ChangeDisplaySettings() Fenster am besten nur mit WS_POPUP und WS_VISIBLE erstellen, dann wird keine Titelzeile und Rahmen etc. erzeugt.



  • danke...super!

    das mit dem hDC...mal sehen vlt bekomm ich das ja nochmal hin...hm...

    das mit dem soundabspielen is auch ok...nur dass wenn ich einen zweiten abspieln will der erste abgebrochen wird oder? (konnts noch ned testen)

    muss ich dafür noch irgendwas besonderes runterladen oder ändern (Bibliotheken und so)?

    Mfg Kuldren



  • Ich glaub PlaySound() hatte da nen Flag für - SND_ASYNC oder so.



  • hm..
    ich muss zugeben dass ich damit nix anfangen kann...

    also mit flag und SND_ASYNC

    Aber danke für die vielen Tips! 🙂



  • Du schriebst, du versuchst es so:

    1. hdc_premem erzeugen (womit? CreateCompatibleDC() ?)
    2. Bitmap laden
    3. Bitmap in hdc_premem selektieren
    4. hdc_mem erzeugen? (wo? und womit ?)
    5. BitBlt() mit hdc_premem als Quelle und hdc_mem als Ziel ?

    1. Wieso der Umweg über hdc_premem? (den BitBlt-Aufruf kannst du dir dann sparen)
    2. Ein Gerätekontext muss sich auf irgendetwas beziehen, z.B. Bildschirm, Drucker, Bitmap, etc. Dein hdc_mem bezieht sich auf ein 1x1px großes, monochomes Bitmap (ist standardmäßig in jedem DC), dort muss du vorher, wenn du den unnötigen Umstand bestehen lassen willst, ein, deinem Bitmap entsprechendes (Farbetiefe, Größe (CreateCompatibleBitmap!)), Bitmap hineinselektieren.



  • sorry, habe vergessen dich zu erinnern dass du mir den quellcode schickst, kannst du das bitte nachholen und ihn mir hier reinstellen?
    danke



  • Ich hab den Umweg genommen weil das als zwischenspeicher dient bis ichs dort reinkopier (hDC_mem) wo es bleuben soll, und wo ichs mir auch immer rauskopieren kann( halt von hdc_mem auf hDC)

    das mit dem 1x1Pixel monochromen bitmap hab ich ned gewusst...
    d.h. ich muss das hDC_mem und pre_mem nicht als CreateCompatibledDC()
    sondern als CreateCompatibleBitmap anlegen?
    ->vlt speichert er es deshalb nicht ab!...hm...was meinst ihr?

    @Phillip:
    sorry ich hatte gestern abend so viel zu tun...ich kam ned mal dazu nach meinen mails zu gucken...
    heut abend hab ich zeit...schreib einfach ins forum oder mich im icq an...
    Dann geb ich dir den ganzen quellcode...jetz hab ich ihn leider nicht dabei...



  • Du musst nach CreateCompatibleDC erst noch ein Bitmap der richtigen Größe und des richtigen Formats hineinselektieren - also ertweder direkt dein Bitmap, oder eines, das du über CreateCompatibleBitmap erstellst 😉



  • meinst du "SelectObject(hdc_irgendwas, Bitmap) ?"
    Ich nehm da einfahc immer BITMAP Bitmap...

    Poste mal den Code den du meinst... 🙂



  • Probiers mal so (für n Bitmaps):

    // irgendwo statisch oder global:
    HBITMAP hBitmap[n];
    HDC hdcBitmap[n];
    
    // irgendwo am Anfang des Programms:
    HDC hdc = GetDC(NULL);
    
    hBitmap[0] = LoadImage(...);
    hdcBitmap[0] = CreateCompatibleDC(hdc);
    SelectObject(hdcBitmap[0], hBitmap[0]);
    //...
    hBitmap[n] = LoadImage(...);
    hdcBitmap[n] = CreateCompatibleDC(hdc);
    SelectObject(hdcBitmap[n], hBitmap[n]);
    
    ReleaseDC(NULL, hdc);
    // ab hier kannst du die Bitmaps über hdcBitmap[i] ansprechen
    

    Wichtig die Bitmaps und Gerätekontexte musst du später wieder freigeben, also:

    DeleteDC(hdcBitmap[0]);
    //...
    DeleteDC(hdcBitmap[n]);
    DeleteObject(hBitmap[0]);
    //...
    DeleteObject(hBitmap[n]);
    

    (Normalerweise sollte man einen Gerätekontext zwar so zurückgeben wie man ihn bekommen hat (also die vorigen Gdi-Objekte wieder hineinselektieren), aber so sollte es für den Anfang auch gehen.)

    Wenn du sehr viele Bitmaps hast geht obiger Ansatz mit eigenem DC für jedes Bitmap evtl. nicht (ich weiß nicht wieviele DCs Windows bereitstellt, Windows XP wahrscheinlich aber genug).
    Dann musst du vor jedem zeichnen eines Bitmaps, dieses in einen DC selektieren, zeichnen und dann das nächste selektieren, zeichnen, usw.



  • also nach:

    // irgendwo statisch oder global:
    HBITMAP hBitmap[n];
    HDC hdcBitmap[n];
    
    // irgendwo am Anfang des Programms:
    HDC hdc = GetDC(NULL);
    
    hBitmap[0] = LoadImage(...);
    hdcBitmap[0] = CreateCompatibleDC(hdc);
    SelectObject(hdcBitmap[0], hBitmap[0]);
    //...
    hBitmap[n] = LoadImage(...);
    hdcBitmap[n] = CreateCompatibleDC(hdc);
    SelectObject(hdcBitmap[n], hBitmap[n]);
    
    ReleaseDC(NULL, hdc);
    // ab hier kannst du die Bitmaps über hdcBitmap[i] ansprechen
    

    kann ich die einzelnen Bitmaps mit hdcBitmap[irgendeine] ansprechen...

    muss ich dann SelectObejct(hDC_mem,hdcBitmap[0])
    und danach BitBlt(hDC,,,,,,hDC_mem);

    oder nur BitBlt(hDC,,,,hdcBitmap[0]);

    schreiben...?

    ich hoffe die bleiben dann darin gespeichert und ich kann sie dann mehrere Male verwenden...(das sie ned scho wieder verschwinden *grml*)



  • Kuldren schrieb:

    d.h. ich muss das hDC_mem und pre_mem nicht als CreateCompatibleDC()
    sondern als CreateCompatibleBitmap anlegen?

    Nicht ganz, d.h. du musst hdc_mem und hdc_pre_mem zwar mit CreateCompatibleDC() erzeugen, aber anschließend noch für beide mit CreateCompatibleBitmap() eine Bitmap mit der entsprechenden Größe erzeugen und mit SelectObject() jeweils in die beiden DCs selektieren.

    Mit CreateCompatibleBitmap() noch beim 1. Parameter aufpassen, als 1. Parameter NICHT das gerade mit CreateCompatibleDC() erzeugte HDC verwenden, sonst ist die erzeugte Bitmap nämlich monochrom, da ja in den erzeugten DCs nur eine 1x1 große monochrom-Bitmap sitzt. Stattdessen den Desktop-DC angeben (den man mit GetDC(NULL) bekommt - hinterher ReleaseDC() nicht vergessen...)

    CreateCompatibleDC() erzeugt ein Memory-DC.
    GetDC() holt ein Display-DC.
    Es gibt auch noch Printer-DCs...
    Ein DeviceContext (DC) speichert lediglich Infos zu reinselektierten Objekten (Pen, Brush, Bitmap, etc...) und anderes Zeugs. Ein DC ist allerdings keine Zielfläche für Grafikoptionen, aber mit der Zielfläche verbunden.

    Bei einem Memory-DC ist die Zielfläche quasi die rein-selektierte Bitmap.
    Bei einem Display-DC ist es direkt der Bildschirm oder ein Teil davon.
    Bei einem Printer-DC ist es der Drucker.

    Daher sieht man bei einem frisch mit CreateCompatibleDC() erzeugten Memory-DC nichts (höchstens 1x1 Pixel ;D), sofern man nicht eine Bitmap reinselektiert, die groß genug ist.

    Btw: Wenn das nen Spiel wird, würde ich evtl. über DirectDraw oder neuer nachdenken. DirectDraw ist meistens deutlich schneller als die GDI-Funktionen.
    Du lädst da die Grafiken in Surfaces und hast die Probleme mit den DCs nicht.
    Ich hab selber mal nen bisschen mit dem alten DirectDraw von DirectX7 rumprobiert und das ganze scheint recht unkompliziert zu sein.


Anmelden zum Antworten