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

PrintWindow przy włączonej kompozycji odświeża okienko - Win7
SM
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:47
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.

Kopiuj
GuiSize:
   WM_SETREDRAW(hwnd,0)
   (tutaj trochę kodu po zmianie rozmiaru okna)
   WM_SETREDRAW(hwnd,1)
   RedrawDB(hwnd)
return
Kopiuj
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

edytowany 3x, ostatnio: flowCRANE
M6
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 6 lat
  • Postów:220
0

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


SM
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:47
0
mca64 napisał(a):

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

nie

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 21 godzin
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.

edytowany 1x, ostatnio: Azarien
M6
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 6 lat
  • Postów:220
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


edytowany 1x, ostatnio: mca64
SM
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:47
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

edytowany 2x, ostatnio: smarq
Azarien
"kopiuje on zawartość okna razem ze wszystkimi śmieciami/artefaktami " — jakimi śmieciami/artefaktami? jeśli jest włączona kompozycja to używasz BitBlt. jeśli nie jest, to PrintWindow. w ten sposób w obu przypadkach masz prawidłowe działanie kodu.
Azarien
PS. robisz jakąś bardzo dziwną rzecz, że chcesz zrzut okna którego nie rysujesz na ekranie. nie dziw się, że API nie współpracuje :-)
SM
śmieci powstają kiedy np bardzo szybo zmienia się rozmiar okna myszką wtedy np kontrolki nachodzą na siebie i potem pozostaje na jednej polowa innej dopóki na nią nie najedziemy i się nie odświeży itp. I nie jest to tak, że robię zrzut okna którego w ogóle nie rysuję. Po prostu tymczasowo wyłączam rysowanie kontrolek kiedy zmieniam ich położenie, kiedy wszystko się poprzestawia to odblokowuję rysowanie i teraz mógłbym odświeżyć okno za pomocą RedrawWindow lecz powoduje to migotanie i dlatego właśnie chcę napisać podwójne buforowanie.
SM
I tak zamiast RedrawWindow chcę użyć PrintWindow aby namalować wszystko w pamięci i potem BitBlt do okienka bez żadnego blinkowania.
M6
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 6 lat
  • Postów:220
0

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


SM
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:47
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.

edytowany 1x, ostatnio: flowCRANE
flowCRANE
Przestań cytować każdy post, do którego szykujesz odpowiedź; Jeśli chcesz skomentować czyjąś odpowiedź to po prostu wstaw jego nick ze znakiem @ i już będzie wiadomo na czyje słowa odpowiadasz; A tak to tylko bałagan się robi;
M6
inaczej. Ten skrin tyczy sie tylko twojej aplikacji czy nie?
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)