nach GetWindowDC() zeichnet sich das fenster manchmal nicht mehr richig neu
-
Hallo,
nach folgender Funktion wird das Fenster, dass ich mit GetWindowDC() auslese, teilweise nicht mehr richtig neugezeichnet. Alte Teile werden nicht richtig gelöscht, sondern einfach nur übermalt und Fenster, die ich darüber ziehe, hinterlassen "Schlieren".
Ich dachte, das Problem gibt es nur, wenn man nicht ReleaseDC aufruft, aber ReleaseDC gibt 1 zurück.HDC hdc = GetWindowDC(hwnd); HDC _2hdc = CreateCompatibleDC(hdc);//HDC to put the hidden window in HBITMAP hbmp = CreateCompatibleBitmap(hdc,winWidth, winHeight); SelectObject(_2hdc,hbmp); PrintWindow(hwnd,_2hdc,0); HDC hdcMem = CreateCompatibleDC(_2hdc);//hdc to copy the needed part of the hidden window in(stored in _2hdc) HBITMAP hbmp2 = CreateCompatibleBitmap(_2hdc,clientWidth,clientHeight);//bmp with hidden window SelectObject(hdcMem, hbmp2); BitBlt(hdcMem, 0,0,clientWidth,clientHeight, _2hdc, xOffset,yOffset, SRCCOPY); BITMAPINFO* bmInfo = new BITMAPINFO(); bmInfo->bmiHeader.biSize = 40; bmInfo->bmiHeader.biWidth = clientWidth; bmInfo->bmiHeader.biHeight = clientHeight; bmInfo->bmiHeader.biPlanes = 1; bmInfo->bmiHeader.biBitCount = BytesPerPixel*8; bmInfo->bmiHeader.biCompression = BI_RGB; bmInfo->bmiHeader.biSizeImage = 0; bmInfo->bmiHeader.biXPelsPerMeter = 0; bmInfo->bmiHeader.biYPelsPerMeter = 0; bmInfo->bmiHeader.biClrUsed = 0; bmInfo->bmiHeader.biClrImportant = 0; GetDIBits(hdcMem, hbmp2, 0,clientHeight, bBytes, bmInfo, DIB_RGB_COLORS); delete bmInfo; DeleteDC(_2hdc); DeleteDC(hdcMem); DeleteObject(hbmp); DeleteObject(hbmp2); if(!ReleaseDC(hwnd, hdc)) cout << "error while releasing dc" << endl;Muss ich noch mehr/anders releasen?
danke im voraus
veio
-
Wenn Du ein Objekt in einen DC selektierst (besonders Bitmaps), dann musst Du das Alte Objekt, dass Du durch SelectObject erhälst, wieder zurückselektieren. Andernfalls kann das Objekt nicht gelöscht werden.
-
Habe es mal analog zu folgendem probiert: http://msdn2.microsoft.com/en-us/library/ms532629(VS.85).aspx
HDC hdc = GetWindowDC(hwnd); HDC _2hdc = CreateCompatibleDC(hdc);//HDC to put the hidden window in HBITMAP hbmpOld, hbmp = CreateCompatibleBitmap(hdc,winWidth, winHeight); hbmpOld = (HBITMAP)SelectObject(_2hdc,hbmp); PrintWindow(hwnd,_2hdc,0); HDC hdcMem = CreateCompatibleDC(_2hdc);//hdc to copy the needed part of the hidden window in(stored in _2hdc) HBITMAP hbmp2Old, hbmp2 = CreateCompatibleBitmap(_2hdc,clientWidth,clientHeight);//bmp with hidden window hbmp2Old = (HBITMAP)SelectObject(hdcMem, hbmp2); BitBlt(hdcMem, 0,0,clientWidth,clientHeight, _2hdc, xOffset,yOffset, SRCCOPY); BITMAPINFO* bmInfo = new BITMAPINFO(); bmInfo->bmiHeader.biSize = 40; bmInfo->bmiHeader.biWidth = clientWidth; bmInfo->bmiHeader.biHeight = clientHeight; bmInfo->bmiHeader.biPlanes = 1; bmInfo->bmiHeader.biBitCount = BytesPerPixel*8; bmInfo->bmiHeader.biCompression = BI_RGB; bmInfo->bmiHeader.biSizeImage = 0; bmInfo->bmiHeader.biXPelsPerMeter = 0; bmInfo->bmiHeader.biYPelsPerMeter = 0; bmInfo->bmiHeader.biClrUsed = 0; bmInfo->bmiHeader.biClrImportant = 0; GetDIBits(hdcMem, hbmp2, 0,clientHeight, bBytes, bmInfo, DIB_RGB_COLORS); //Cleaning up delete bmInfo; SelectObject(_2hdc, hbmpOld); SelectObject(hdcMem,hbmp2Old); if(!DeleteObject(hbmp)) cout << "error while releasing hbmp" << endl; if(!DeleteObject(hbmp2)) cout << "error while releasing hbmp2" << endl; DeleteDC(_2hdc); DeleteDC(hdcMem); if(!ReleaseDC(hwnd, hdc)) cout << "error while releasing dc" << endl;Klappt aber nicht.
Warum muss ich bei SelectObject immer casten? In den beispielen müssen die das nie.
-
suche rat

-
ich glaube, die grafik fehler passieren immer dann, wenn während der ausführung der funktion(dauert so 20-40ms) der inhalt des fensters geändert wird.
edit: nen RedrawWindow() oder UpdateWindow() nach der Funktion aufzurufen hilft auch nicht

-
hab noch mal ein wenig rum probiert und der übeltäter ist die funktion printwindow() - macht auch irgendwie ein wenig sinn, da die funktion ja den fenster inhalt nicht im fenster ausgibt sondern in meine variable und vielleicht somit veränderungen, die in der zeit passieren, schluckt oder so etwas.
Wie sage ich dem Fenster, dass es sich neu zeichnen soll, so wie es sich bei zurückholen aus den minimierten zustand neu zeichnet? UpdateWindow und redrawWindow() haben nicht funktioniert

Müsste
SendMessageA(hwnd, WM_ERASEBKGND, WPARAM(hdc),PRF_ERASEBKGND);
nicht den Hintergrund neumalen? das ist nämlich immer das, was falsch gezeich net wird. Klappt aber auch nicht
Übergebe ich den hdc richtig bzw. den richtigen?
-
InvalidateRect()
-
@veio: Kann es sein, dass dass Du außerhaöb von WM_PAINT zeichnest.
Grundsätzlich sollltest Du nur in Deinem WM_PAINT Handler zeichnen und nur durch InvalidateRect/UpdateWindow/RedrawWindow ein neuzeichnen veranlassen...
-
Martin Richter schrieb:
@veio: Kann es sein, dass dass Du außerhaöb von WM_PAINT zeichnest.
Grundsätzlich sollltest Du nur in Deinem WM_PAINT Handler zeichnen und nur durch InvalidateRect/UpdateWindow/RedrawWindow ein neuzeichnen veranlassen...
Ich selber zeichne gar nicht, ich will nur das Fenster auslesen.
Ich werde das mit invalidateRect() nachher mal probieren, nur im Moment startet mein Notebook nicht mehr °°
-
InvalidateRect() klappt zumindest für die Clientarea.