BITMAP' in 'HGDIOBJ' nicht möglich



  • Nein, ich bekomme das Bitmap so:

    ExtractIconEx((LPCTSTR)"c:\\file.bmp", 0, &hIconLarge, NULL, 1);
    	GetIconInfo(hIconLarge, &IconInfo);  
    	GetObject ( IconInfo.hbmColor, sizeof(BITMAP), &bmp ) ;
    

    Mit der Typumwandlung habe ich es versucht, da kommt der gleiche Fehler...

    Gruß
    Alex



  • BITMAP != HBITMAP

    BITMAP und HGDIOBJ sind nicht kompatibel.
    HBITMAP und HGDIOBJ schon.

    Du willst keine BITMAP sondern ein HBITMAP.

    ExtractIconEx() liefert HICON zurück (welches von GetObject() übrigens gar nicht unterstützt wird)

    Um ein HICON in eine HBITMAP umzuwandeln:
    - Einen MemoryDC erzeugen (CreateCompatibleDC)
    - Eine Bitmap der Größe des Icons erzeugen (CreateCompatibleBitmap)
    - Bitmap in den MemoryDC selektieren (SelectObject, dessen Rückgabewert speichern!)
    - Das Icon auf das MemoryDC und somit in die Bitmap zeichnen (DrawIcon)
    - SelectObject() und den gespeicherten Rückgabewert als HGDIOBJ einsetzen
    - Die HBITMAP von CreateCompatibleBitmap enthält jetzt dein Icon.
    - Sofern das HICON sonst nicht mehr gebraucht wird: DestroyIcon

    Die Größe von Small und Large Icons kannst du über GetSystemMetrics() mit SM_CXSMICON, SM_CYSMICON (für Small-Icons) und SM_CXICON, SM_CYICON für Large Icons bestimmen.



  • Danke,

    ich habe es versucht umzustezen:

    HDC hDC = GetDC( NULL ) ;
    
    //- Einen MemoryDC erzeugen (CreateCompatibleDC)
    HDC bmpDC = CreateCompatibleDC(hDC);
    HDC bmpDC2 = CreateCompatibleDC(hDC);
    //- Eine Bitmap der Größe des Icons erzeugen (CreateCompatibleBitmap)
    HBITMAP memBM = CreateCompatibleBitmap ( hDC, 32, 32 );
    //- Bitmap in den MemoryDC selektieren (SelectObject, dessen Rückgabewert speichern!)
    HGDIOBJ myObct = SelectObject(bmpDC, memBM);
    //- Das Icon auf das MemoryDC und somit in die Bitmap zeichnen (DrawIcon)
    DrawIcon(bmpDC, 0, 0, hIconLarge);
    //- SelectObject() und den gespeicherten Rückgabewert als HGDIOBJ einsetzen
    myObct = SelectObject(bmpDC2, bmpDC);
    //- Die HBITMAP von CreateCompatibleBitmap enthält jetzt dein Icon.
    //- Sofern das HICON sonst nicht mehr gebraucht wird: DestroyIcon 
    
    	cout << "Pixel: " << GetPixel(bmpDC2, 0, 1) << "\n";
    	cout << "Pixel: " << GetPixel(bmpDC2, 1, 2) << "\n";
    

    Allerdings scheint es nicht zu klappen:
    Ausgabe:

    Pixel: 4294967295
    Pixel: 4294967295
    

    Habe ich was falsch gemacht?

    Gruß
    Alex



  • Nein an der stelle im bild sind genau 2 weiße pixel -> 0xffffffff.
    Das problem ist nur die ausgabe über cout. Das bild selber ist aber richtig.



  • Hmm ich bin mir nicht sicher,

    ich habe eine kleine Schleife gebaut:

    for(int i=0; i<32; i++){
    		for(int i2=0; i2<32; i2++)
    			cout << "Pixel NR " << i << "Wert: " << GetPixel(bmpDC2, i2, i) << "\n";
    }
    

    Es kommt immer nur 4294967295 als Wert raus, da stimmt noch nicht alles...

    Gruß
    Alex



  • Ist Dir bewusst, das Dein Code haufenweise GDI-Leaks erzeugt?

    Gib die Farben mal Komponentenweise aus (R,G,B) via GetRColor, GetGColor, ... .



  • CodeFinder schrieb:

    Ist Dir bewusst, das Dein Code haufenweise GDI-Leaks erzeugt?

    Gib die Farben mal Komponentenweise aus (R,G,B) via GetRColor, GetGColor, ... .

    Hm?



  • HDC hDC = GetDC( NULL ) ;
    
    //- Einen MemoryDC erzeugen (CreateCompatibleDC)
    HDC bmpDC = CreateCompatibleDC(hDC);
    
    //- Eine Bitmap der Größe des Icons erzeugen (CreateCompatibleBitmap)
    HBITMAP myBMP = CreateCompatibleBitmap ( bmpDC, 32, 32 );
    
    //- Bitmap in den MemoryDC selektieren (SelectObject, dessen Rückgabewert speichern!)
    HGDIOBJ fallback;
    fallback = SelectObject(bmpDC, myBMP);
    
    //- Das Icon auf das MemoryDC und somit in die Bitmap zeichnen (DrawIcon)
    DrawIcon(bmpDC, 1, 1, hIconLarge);
    
    //- SelectObject() und den gespeicherten Rückgabewert als HGDIOBJ einsetzen
    SelectObject(bmpDC, myBMP);
    
    //- Die HBITMAP von CreateCompatibleBitmap enthält jetzt dein Icon.
    //- Sofern das HICON sonst nicht mehr gebraucht wird: DestroyIcon
    
    	for(int i=0; i<32; i++){
    		for(int i2=0; i2<32; i2++)
    			cout << "Pixel NR " << i << "Wert: " << GetPixel(bmpDC, i2, i) << "\n";
    	}
    
    }
    

    So scheint es zu funktionieren, was mich aber wundert, ist dass immer wieder nur die gleiche Farbe vorzukommen scheint:

    Pixel NR 7Wert: 16777215
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 16777215
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 16777215
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 16777215
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 7Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 16777215
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 0
    Pixel NR 8Wert: 16777215

    ...usw.
    Warum ist es so? Wähle ich ein anderes Icon aus, dann kommt auch jeweils nur dieser Wert oben vor.

    16777215 ist ja der RGB Wert für weiß...

    EDIT:
    Ich habe mal Probehalber folgendes gemacht:

    for(int i=0; i<32; i++){
    		for(int i2=0; i2<=32; i2++)
    		{
    			if(GetPixel(bmpDC, i2, i)==16777215)
    				cout << "X";
    			else
    				cout << ".";
    			if(i2==32)
    				cout << "\n";
    		}
    	}
    

    Es wird dann tatsächlich das Icon gezeichnet. Also es scheint "16777215" an den Stellen zu stehen, wo sich nicht weiße Pixel befinden 😕

    Gruß
    Alex



  • CodeFinder schrieb:

    Ist Dir bewusst, das Dein Code haufenweise GDI-Leaks erzeugt?

    ➡

    [u]Du Verwendet:[/u]            [u]Benötigt allerdings noch...:[/u]
     CreateCompatibleDC       DeleteDC
     CreateCompatibleBitmap   DeleteObject
     SelectObject             SelectObject ('reselect', siehe MSDN)
    

    CodeFinder schrieb:

    Gib die Farben mal Komponentenweise aus (R,G,B) via GetRColor, GetGColor, ... .

    Oh sorry, es war nicht GetRColor, sondern GetRValue etc. ...; also something like this:

    cout << "RGB(" << GetRValue(color) << "," << GetGValue(color) << "," << GetBValue(color) << ")" << endl;
    


  • Oh, Du hast natürlich Recht. Vielen Dank. Habe noch keine Erfahrung.

    Zu meinem letzten Posting:
    Ich glaube ich weiß, wieso das Bitmap monochrom ist:

    Note: When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the hDC that was used to create the memory device context, as shown in the following code:

    HDC memDC = CreateCompatibleDC ( hDC );
    HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
    SelectObject ( memDC, memBM );

    Das Problem ist wahrscheinlich hier:

    HDC hDC = GetDC( NULL ) ;
    //- Einen MemoryDC erzeugen (CreateCompatibleDC)
    HDC bmpDC = CreateCompatibleDC(hDC);
    //- Eine Bitmap der Größe des Icons erzeugen (CreateCompatibleBitmap)
    HBITMAP myBMP = CreateCompatibleBitmap ( bmpDC, 32, 32 );
    

    Aber meine Anwendung hat kein hDC, weil es als Win32 Consolenanwendung erstellt wurde (ich hoffe ich bringe jetzt nicht komplett alles durcheinander...)

    Gruß
    Alex



  • Öhm, ne bringst nix durcheinander (sogar lobenswert, dass hier entlich mal einer in die MSDN guckt 😉 !), aber daran liegts trotzdem nicht, denn:

    MSDN zu GetDC schrieb:

    Handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen.

    (Bezogen auf den Parameter; Quelle: http://msdn.microsoft.com/en-us/library/ms533241.aspx)
    Sie ist also nicht mono.

    Ich schau mir -falls es nicht jemand anderes bis dahin schon getan hat- Deinen Code Morgen Abend mal an.



  • Vielen Dank.

    Hier der ganze Codeabschnitt, damit es einfacher mit dem Angucken ist:

    //ICON auslesen
    	ExtractIconEx((LPCTSTR)"c:\\CtrlSrv.exe", 0, &hIconLarge, NULL, 1);
    	GetIconInfo(hIconLarge, &IconInfo);  
    
    HDC hDC = GetDC( NULL ) ;
    
    //- Einen MemoryDC erzeugen (CreateCompatibleDC)
    HDC bmpDC = CreateCompatibleDC(hDC);
    
    //- Eine Bitmap der Größe des Icons erzeugen (CreateCompatibleBitmap)
    HBITMAP myBMP = CreateCompatibleBitmap ( bmpDC, 32, 32 );
    
    //- Bitmap in den MemoryDC selektieren (SelectObject, dessen Rückgabewert speichern!)
    HGDIOBJ fallback;
    fallback = SelectObject(bmpDC, myBMP);
    
    //- Das Icon auf das MemoryDC und somit in die Bitmap zeichnen (DrawIcon)
    DrawIcon(bmpDC, 0, 0, hIconLarge);
    
    //- SelectObject() und den gespeicherten Rückgabewert als HGDIOBJ einsetzen
    SelectObject(bmpDC, myBMP);
    
    	for(int i=0; i<32; i++){
    		for(int i2=0; i2<=32; i2++)
    		{
    			//cout << "Pixel NR " << i << "Wert: " << GetPixel(bmpDC, i2, i) << "\n";
    			if(GetPixel(bmpDC, i2, i)==16777215)
    				cout << "X";
    			else
    				cout << ".";
    			if(i2==32)
    				cout << "\n";
    		}
    	}
    
    	DeleteDC(hDC);
    	DeleteDC(bmpDC);
    	DeleteObject(myBMP); 
    	DeleteObject(fallback); 
    	DestroyIcon(hIconLarge);
    

    Grüße
    Alex



  • Jo gib bei CreateCompatibleDC() nicht bmpDC (welches monochrom ist anfangs) sondern hDC an.



  • geeky schrieb:

    Jo gib bei CreateCompatibleDC() nicht bmpDC (welches monochrom ist anfangs) sondern hDC an.

    Danke, jetzt klappt es!


Anmelden zum Antworten