CreateDIBSection Aufruf in einem Thread schlägt fehl



  • Guten Tag,

    ich habe das Problem das ich ein Bild in den Speicher laden muss um dann daraus eine DIB Section zu erstellen.

    Das funktioniert auch soweit einwandfrei wenn ich die Funktion zur Erzeugung der DIB Section aus dem Main Thread aufrufe...
    wenn ich dies allerdings aus einem neuen Thread heraus mache schlägt die Funktion fehl.

    Die Funktion zur Erzeugung der DIB Section sieht wie folgt aus:

    HDC			lHdcTemp;
    	HBITMAP		lHbmpTemp;
    	IPicture	*lPicture;
    	long		lWidth;
    	long		lHeight;
    	long		lWidthPixels;
    	long		lHeightPixels;
    	GLint		lMaxTexDim;
    
    	HRESULT lHres = OleLoadPicturePath(pPathName, 0, 0, 0, IID_IPicture, (void**)&lPicture);
    
    	if(FAILED(lHres))
    	{
    		return FALSE;
    	}
    
    	lHdcTemp = CreateCompatibleDC(GetDC(NULL));
    	if(!lHdcTemp)
    	{
    		lPicture->Release();
    		return FALSE;
    	}
    
    	lPicture->get_Width(&lWidth);
    	lWidthPixels	= MulDiv(lWidth, GetDeviceCaps(lHdcTemp, LOGPIXELSX), 2540);
    	lPicture->get_Height(&lHeight);
    	lHeightPixels	= MulDiv(lHeight, GetDeviceCaps(lHdcTemp, LOGPIXELSY), 2540);
    
    	BITMAPINFO	lBitmapInfo		= {0};
    	DWORD		*lBitmapBits	= 0;
    
    	lBitmapInfo.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
    	lBitmapInfo.bmiHeader.biBitCount		= 32;
    	lBitmapInfo.bmiHeader.biWidth			= lWidthPixels;
    	lBitmapInfo.bmiHeader.biHeight			= lHeightPixels;
    	lBitmapInfo.bmiHeader.biCompression		= BI_RGB;
    	lBitmapInfo.bmiHeader.biPlanes			= 1;
    	lBitmapInfo.bmiHeader.biClrUsed			= 0;
    	lBitmapInfo.bmiHeader.biClrImportant	= 0;
    
    	lHbmpTemp = CreateDIBSection(lHdcTemp,
    								 &lBitmapInfo,
    								 DIB_RGB_COLORS,
    								 (void**)&lBitmapBits,
    								 NULL,
    								 NULL);
    
    	if(!lHbmpTemp)
    	{
    		DeleteDC(lHdcTemp);
    		lPicture->Release();
    		return FALSE;
    	}
    

    Den Thread starte ich mit:

    gFLHandle = (HANDLE)_beginthreadex(NULL,
    									   0,
    									   FmpFrameLoader,
    									   (void*)gTexHolder,
    									   NULL,
    									   NULL);
    

    Die Frage ist nun, wieso funktioniert alles einwandfrei wenn ich die Funktion so aufrufe
    und wieso geht es nicht wenn die Funktion aus dem Thread heraus aufgerufen wird?

    Hat darauf irgendwer eine Antwort? Das würde mir sehr weiterhelfen...
    Vielen dank schon mal.



  • Vielleicht weil COM nicht initialisiert wurde? (CoInitialize)



  • Daran scheint es nicht zu liegen. Ich habe die COM Initialisierung hinzugefügt,
    dass Problem besteht aber weiterhin.

    Die Funktion CreateDIBSection(...) gibt NULL zurück, allerdings ohne Fehlercode
    (GetLastError() gibt alles ok zurück).



  • Danke für die Hilfe, ich habe das Problem jetzt gelöst.

    Es lag daran das durch einen mir bis jetzt nicht ganz klaren Grund
    wohl die Größenangaben in der BITMAPINFO Struktur auf 0 gesetzt wurden.
    Dadurch wurde natürlich keine DIB Section erstellt und die Funktion ist ohne
    Fehler beendet worden.

    Vielen Dank an alle die sich darüber Gedanken gemacht haben.



  • Du solltest aber noch den via

    GetDC(NULL)
    

    angeforderten Gerätekontext wieder freigeben mit:

    ReleaseDC(NULL, hdcEntireScreen);
    

    wobei 'hdcEntireScreen' natürlich von GetDC initialisiert worden ist 😉 .

    Wobei ich mir da grad mal auch nicht ganz sicher bin:

    MSDN schrieb:

    [...] Class and private DCs do not have to be released. [...]

    Quelle ➡ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_4esj.asp
    Was die hier mit 'Class-DC's' meinen ... 🙄 .


Log in to reply