Hallo Leute, mein WinApi Programm zeichnet momentan per "SetPixel" Bilder in das Fenster. Da aber mein Programm durch das ständige neuzeichnen total langsam ist, möchte ich das ganze in DIB machen. Leider bekomme ich es nicht hin, dass mein Byte-Array (mit den Farbinformationen in RGB) in die DIB Section zu zeichnen. hier sind die wesentlichen code-teile: HBITMAP hBitmap, bitmap; BYTE *pBits, testzz[5000]; BITMAPINFOHEADER bmih; BITMAPINFO *pbmi; void init_bmp(void); HDC hdcMem; hBitmap = CreateDIBSection(NULL, (BITMAPINFO *)&bmih, 0, (void**) pBits,NULL,0); pBits = &testzz[0]; //in testzz sind die Farbinformationen hDC = BeginPaint(hwnd, &ps); hdcMem = CreateCompatibleDC(hDC); GetObject(hBitmap, sizeof(HBITMAP), &bitmap); SelectObject (hdcMem, hBitmap); BitBlt(hDC, 10,40, 100, 50, hdcMem, 0, 0, SRCCOPY); EndPaint(hwnd, &ps); Hat jemand eine Ahnung wie ich meine Pixel Informationen (testzz) in die DIB Section zeichnen kann? Danke im Voraus!
Sieh Dir mal die Bedeutung des vierten Parameters von CreateDIBSection genauer an. Das ist ein Pointer auf einen Pointer, der auf den von der DIB genutzten Speicher zeigen wird. Den Speicher stellt die Funktion selbst zur Verfügung (wenn Du nicht ein Filemapping-Objekt benutzt, aber das tust Du nicht). Also musst Du nicht pBits selbst übergeben, sondern dessen Adresse. Und nach dem Aufruf von CreateDIBSection darfst Du pBits nicht verändern (was Du mit Deiner Zuweisung auf testzz tust). Wenn der Inhalt von testzz in der DIB auftauchen soll, musst Du ihn hineinkopieren, und nicht den von der Funktion zurückgegebenen Pointer verändern.
1 | hBitmap = CreateDIBSection(NULL, (BITMAPINFO *) &bmih, 0, &pBits, NULL, 0); |
2 | |
3 | memcpy(pBits, testzz, 5000); |
Der memcpy-Aufruf ist so natürlich mutig, weil nicht überprüft wird, ob a) pBits überhaupt irgendwohin zeigt (hBitmap nach Aufruf von CreateDIBSection überprüfen, pBits vor Aufruf auf NULL setzen, danach überprüfen, ob nicht NULL) und b) ob der Speicher, auf den pBits zeigt, groß genug ist für die hineinkopierten 5000 Bytes.
mammamia schrieb: > YEAAAH funktioniert, vielen Dank!!!!! Und hast du auch mal den Speicherverbrauch des Programms beobachtet, wenn sich das Fenster neuzeichnet? Ich könnte mir vorstellen, dass der langsam anwächst.. :) Fehlt da nicht ein DeleteDC (hdcMem); vor EndPaint? Was meint Rufus?
http://msdn.microsoft.com/en-us/library/dd183494(v=vs.85).aspx As noted above, if hSection is NULL, the system allocates memory for the DIB. The system closes the handle to that memory when you later delete the DIB by calling the DeleteObject function. Ansonsten ist es in der Tat ratsam, jedes Handle, jedes Objekt etc. nach Gebrauch zurückzugeben. Der Resourcenverbrauch eines laufenden Programmes kann z.B. mit dem ProcessExplorer untersucht werden.
Da sich das Fenster immer neuzeichnet brauche ich die DIB Section nur einmal zu erzeugen und erst beim beenden des Pogrammes löschen oder? Oder ist es ratsam bei jedem neuzeichnen die Section neu zu erzeugen?
Da muss ich passen. Vermutlich nicht; aber Du könntest mal das Ressourcenverhalten untersuchen, indem Du Dein Programm längere Zeit laufen und sehr oft das Fenster aktualisieren lässt und derweil mit dem Process Explorer zusiehst.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.