PrintWindow przy włączonej kompozycji odświeża okienko - Win7

0

Witam.
Mam mały problem z funkcją "PrintWindow".
Chcę napisać funkcję do podwójnego buforowania lecz kiedy wywołuję PrintWindow to okno samo się odświeża co powoduję migotanie (a tego chcę właśnie uniknąć), potem BitBlt co daje w rezultacie jeszcze gorszy efekt niż bez użycia podwójnego buforowania. Przy wyłączonej kompozycji wszystko działa idealnie. Próbowałem także wysyłać WM_PRINT zamiast PrintWindow i tutaj nie występuje ww efekt ale zaś kontrolki są źle rysowane itp.

Jakieś pomysły czemu tak się dzieje??

Zamieszczony kod jest w języku Autohotkey lecz myślę, że jest to w miarę czytelne dla tych co znają inne języki.

GuiSize:
   WM_SETREDRAW(hwnd,0)
   (tutaj trochę kodu po zmianie rozmiaru okna)
   WM_SETREDRAW(hwnd,1)
   RedrawDB(hwnd)
return
RedrawDB(hWnd) {
; Critical
	;==========================================================================
	; Get required coordinates
	;==========================================================================
		Static SizeOfWINDOWINFO := 60
		VarSetCapacity(WINDOWINFO, SizeOfWINDOWINFO, 0)
		NumPut(SizeOfWINDOWINFO, WINDOWINFO, "UInt")
		DllCall("GetWindowInfo", "Ptr",hWnd, "Ptr",&WINDOWINFO)
		WX := NumGet(WINDOWINFO,  4, "Int")       ; X coordinate of the window
		WY := NumGet(WINDOWINFO,  8, "Int")       ; Y coordinate of the window
		WW := NumGet(WINDOWINFO, 12, "Int") - WX  ; Width of the window
		WH := NumGet(WINDOWINFO, 16, "Int") - WY  ; Height of the window
		CX := NumGet(WINDOWINFO, 20, "Int")       ; X coordinate of the client area
		CY := NumGet(WINDOWINFO, 24, "Int")       ; Y coordinate of the client area
		CW := NumGet(WINDOWINFO, 28, "Int") - CX  ; Width of the client area
		CH := NumGet(WINDOWINFO, 32, "Int") - CY  ; Height of the client area
	
	;==========================================================================
	; Create Buffer
	;==========================================================================
		hdcDest := DllCall("GetDC", "Ptr",hWnd)
		hdcBuf  := DllCall("CreateCompatibleDC", "Ptr",hdcDest)  ; buffer
		Static bmw, bmh, hbmBuf
		if (ww > bmw) or (wh > bmh) ; Create new bitmap only while new one is bigger
		{
			DllCall("DeleteObject", "Ptr",hbmBuf)
			hbmBuf := DllCall("CreateCompatibleBitmap", "Ptr",hdcDest, "Int",ww, "Int",wh)
			bmw := ww, bmh := wh
		}
		obmBuf  := DllCall("SelectObject", "Ptr",hdcBuf, "Ptr",hbmBuf)
	
	;==========================================================================
	; Capture - PrintWindow
	;==========================================================================
		DllCall("PrintWindow", "Ptr",hwnd, "Ptr",hdcBuf, "uint",0) ; Przy włączonej kompozycji odświeża się okienko hwnd
		; SM_WM_PRINT(hwnd, hdcBuf)
	;==========================================================================
	; Draw - StretchBlt
	;==========================================================================
	bitblt(hdcDest,0,0,cw,ch,hdcBuf,cx-wx,cy-wy)
		; DllCall("StretchBlt"
		; , "Ptr", hdcDest
		; , "Int", 0
		; , "Int", 0
		; , "Int", cw
		; , "Int", ch
		; , "Ptr", hdcBuf
		; , "Int", cx - wx
		; , "Int", cy - wy
		; , "Int", cw
		; , "Int", ch
		; ,"UInt", 0xCC0020) ; SRCCOPY  
	
	;==========================================================================
	; Clear
	;==========================================================================
		DllCall("ReleaseDC", "uint",hwnd, "uint",hdcDest)
		DllCall("SelectObject", "Ptr",hdcBuf, "Ptr",obmBuf)
		DllCall("DeleteDC", "Ptr",hdcBuf)
		; DllCall("DeleteObject", "Ptr",hbmBuf)
		
}

dodanie znaczników <code class="cpp"> - furious programming

0

a jak robisz zwykly zrzut programu (ALT + PRTSC) to czy okno tez migocze?

0
mca64 napisał(a):

a jak robisz zwykly zrzut programu (ALT + PRTSC) to czy okno tez migocze?

nie

1

pod koniec tego pliku
http://webrtc.googlecode.com/svn/trunk/webrtc/modules/desktop_capture/window_capturer_win.cc
masz komentarz.
wynika z niego, że używają PrintWindow jeśli nie ma kompozycji, a BitBlt jeśli jest.

// If Aero is enabled, we prefer BitBlt() because it's faster and avoids
// window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may
// render occluding windows on top of the desired window.

przestudiuj kod, ja się na GDI za bardzo nie znam.

0

to z tego wynika ze nie mozesz uzywac PrintWindow. Migotnie jest od WM_ERASEBKGND, aplikacja to dostanie i masz taki efekt. Chcyba ze zrobisz hacka i pozbedziesz sie tego :P Zrzut ekranu za pomoca PRTSC to jest BitBlt wiec z tym kombinuj

0
Azarien napisał(a):

pod koniec tego pliku
http://webrtc.googlecode.com/svn/trunk/webrtc/modules/desktop_capture/window_capturer_win.cc
masz komentarz.
wynika z niego, że używają PrintWindow jeśli nie ma kompozycji, a BitBlt jeśli jest.

// If Aero is enabled, we prefer BitBlt() because it's faster and avoids
// window flickering. Otherwise, we prefer PrintWindow() because BitBlt() may
// render occluding windows on top of the desired window.

przestudiuj kod, ja się na GDI za bardzo nie znam.

Z BitBlt jest taki problem, że kopiuje on zawartość okna razem ze wszystkimi śmieciami/artefaktami a moim przypadku zablokowałem "redraw", wykonałem kod zmiany pozycji kontrolek i odblokowałem "redraw", czyli zawartość okna ulegnie zmianie dopiero po wywołaniu RedrawWindow (ona także powoduje migotanie) czyli BitBlt niewiele wniesie.

Podany przez ciebie przykład owszem jest poprawny lecz tam wykonuje się shooty już wyrenderowanych okienek.
PrintWindow zaś, teoretycznie powinien zrobić render do zewnętrznego DC, niestety Aero wnosi tutaj swoje 2 grosze i przy okazji odświeża okno którego właśnie nie chcę odświeżać...

Z tego co widzę to jest to raczej powszechny problem w internecie.
Brawa dla panów z M$ z tak wspaniałe API.

Zrzut ekranu za pomoca PRTSC to jest BitBlt wiec z tym kombinuj

owszem lecz jak już pisałem, BitBlt kopiuje zawartość okna (w zasadzie to DC), a u mnie redraw był zablokowany czyli nic w oknie nie uległo zmianie i muszę to właśnie wyrenderować miedzy innymi za pomocą PrintWindow

0

smarq napisz cos wiecej na temat twojego programu. Jaka funkcje ma dokladnie?

0

Retiming, korekta, posprocessing, ekstracja z mkv, łączenie, comparowanie napisów głównie w formacie *.ass chociaż wątpię aby miało to jakiś wpływ na zagadnienie double bufferingu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1