Что нового

Моргает POPUP окно при изменении размеров

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Сделал я значит POPUP окно, в ручную обрабатываю сообщения чтобы можно было тащить за края окна и тем самым изменять его размеры, подключил в скрипт DSEngine.dll для воспроизведения видео, когда начинаю изменять размеры окна, то оно сильно мигает, если применяю стиль к окну $WS_EX_COMPOSITED, то мигания пропадают и появляются следующие проблемы, видео всегда поверх всех окон, как будто оно не прикреплено к моему, если перетащить окно в самый низ раб. стола, то на панели где кнопка пуск появляется кадр с этого ролика.. уже не знаю что и придумать, все стили перепробовал, пробовал и _WinAPI_RedrawWindow() и _WinAPI_SetWindowPos(), не помогло, посоветуйте как быть?

Код:
Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <Misc.au3>
#Include <DSEngine.au3>

$sFile = FileOpenDialog('Select Video File', @ScriptDir, 'Video Files (*.avi;*.mpg;*.wmv;*.mov;*.3gp;*.asf;*.mp4;*.flv;*.rv)')
If Not $sFile Then
	Exit
EndIf

If @OSArch == 'X86' Then
  Engine_Startup(@ScriptDir & '\DSEngine_UDF.dll')
ElseIf @OSArch == 'X64' Then
  Engine_Startup(@ScriptDir & '\DSEngine_UDF_x64.dll')
Else
  Exit
EndIf

$hForm = GUICreate('', 500, 350, -1, -1, $WS_POPUP, $WS_EX_COMPOSITED)
GUISetBkColor(0x151515)
Engine_LoadFile($sFile, $hForm)
Engine_SetRects(0, 0, 0, 0, 0, 0, 500, 350)
GUIRegisterMsg($WM_MOUSEMOVE, 'WndProc')
GUIRegisterMsg($WM_LBUTTONDBLCLK, 'WndProc')
GUIRegisterMsg($WM_LBUTTONDOWN, 'WndProc')
GUISetState()

Engine_SetWindow($hForm)
Engine_StartPlayback()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
Wend

Func SizeWindow($iLeft, $iTop, $iWidth, $iHeight)
	Engine_SetRects(0, 0, 0, 0, 0, 0, $iWidth, $iHeight)
EndFunc

Func WndProc($hWnd, $iMsg, $wParam, $lParam)
	Local Static $iBorder = 0
	Switch $hWnd
		Case $hForm
			Switch $iMsg
				Case $WM_MOUSEMOVE
					$iBorder = IsOverBorder($hWnd, 5)
                Case $WM_LBUTTONDOWN
					If ($iBorder <> 0) Then
					    ResizeBorder($hWnd, $iBorder, 'SizeWindow')
					Else
						_SendMessage($hWnd, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
                    EndIf
			EndSwitch
	EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func IsOverBorder($hWnd, $iPixel)
    Local $X, $Y, $iPos = WinGetPos($hWnd)
	$X = _WinAPI_GetMousePosX(True, $hWnd)
	$Y = _WinAPI_GetMousePosY(True, $hWnd)
	If (($X >= 0) And ($X <= $iPixel) And ($Y >= $iPixel) And ($Y <= $iPos[3] - ($iPixel * 2))) Then
		ResizeCursor(1)
	    Return 1
	ElseIf (($X >= $iPixel) And ($X <= ($iPos[2] - ($iPixel * 2))) And ($Y >= 0) And ($Y <= $iPixel)) Then
		ResizeCursor(2)
		Return 2
    ElseIf (($X >= ($iPos[2] - $iPixel)) And ($X <= $iPos[2]) And ($Y >= $iPixel) And ($Y <= ($iPos[3] - ($iPixel * 2)))) Then
		ResizeCursor(3)
        Return 3
    ElseIf (($X >= $iPixel) And ($X <= ($iPos[2] - ($iPixel * 2))) And ($Y >= ($iPos[3] - $iPixel)) And ($Y <= $iPos[3])) Then
		ResizeCursor(4)
        Return 4
	ElseIf (($X >= 0) And ($X <= $iPixel) And ($Y >= 0) And ($Y <= $iPixel)) Then
		ResizeCursor(5)
        Return 5
	ElseIf (($X >= ($iPos[2] - $iPixel)) And ($X <= $iPos[2]) And ($Y >= 0) And ($Y <= $iPixel)) Then
		ResizeCursor(6)
		Return 6
	ElseIf (($X >= 0) And ($X <= $iPixel) And ($Y >= $iPos[3] - $iPixel) And ($Y <= $iPos[3])) Then
		ResizeCursor(7)
		Return 7
	ElseIf 	(($X >= ($iPos[2] - $iPixel)) And ($X <= $iPos[2]) And ($Y >= $iPos[3] - $iPixel) And ($Y <= $iPos[3])) Then
		ResizeCursor(8)
		Return 8
	Else
		ResizeCursor(0)
		Return 0
    EndIf
EndFunc

Func ResizeBorder($hWnd, $iType, $sFunc)
	Local $sMouse, $dMouse, $iPos
	$sMouse = MouseGetPos()
	$iPos = WinGetPos($hWnd)
	ResizeCursor($iType)
	While _IsPressed(1)
		$dMouse = MouseGetPos()
		Switch $iType
			Case 1
		        WinMove($hWnd, '', $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1], $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3])
				Call($sFunc, $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1], $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3])
			Case 2
				WinMove($hWnd, '', $iPos[0], $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2], $iPos[3] + ($sMouse[1] - $dMouse[1]))
				Call($sFunc, $iPos[0], $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2], $iPos[3] + ($sMouse[1] - $dMouse[1]))
			Case 3
				WinMove($hWnd, '', $iPos[0], $iPos[1], $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3])
				Call($sFunc, $iPos[0], $iPos[1], $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3])
			Case 4
                WinMove($hWnd, '', $iPos[0], $iPos[1], $iPos[2], $iPos[3] + ($dMouse[1] - $sMouse[1]))
				Call($sFunc, $iPos[0], $iPos[1], $iPos[2], $iPos[3] + ($dMouse[1] - $sMouse[1]))
			Case 5
                WinMove($hWnd, '', $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3] + ($sMouse[1] - $dMouse[1]))
		        Call($sFunc, $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3] + ($sMouse[1] - $dMouse[1]))
			Case 6
				WinMove($hWnd, '', $iPos[0], $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3] + ($sMouse[1] - $dMouse[1]))
			    Call($sFunc, $iPos[0], $iPos[1] + ($dMouse[1] - $sMouse[1]), $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3] + ($sMouse[1] - $dMouse[1]))
			Case 7
                WinMove($hWnd, '', $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1], $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3] + ($dMouse[1] - $sMouse[1]))
			    Call($sFunc, $iPos[0] + ($dMouse[0] - $sMouse[0]), $iPos[1], $iPos[2] + ($sMouse[0] - $dMouse[0]), $iPos[3] + ($dMouse[1] - $sMouse[1]))
			Case 8
                WinMove($hWnd, '', $iPos[0], $iPos[1], $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3] + ($dMouse[1] - $sMouse[1]))
				Call($sFunc, $iPos[0], $iPos[1], $iPos[2] + ($dMouse[0] - $sMouse[0]), $iPos[3] + ($dMouse[1] - $sMouse[1]))
		EndSwitch
	WEnd
EndFunc

Func ResizeCursor($iType)
	Switch $iType
		Case 1, 3
			_WinAPI_SetCursor(_WinAPI_LoadCursor(0, 32644))
		Case 2, 4
			_WinAPI_SetCursor(_WinAPI_LoadCursor(0, 32645))
        Case 5, 8
			_WinAPI_SetCursor(_WinAPI_LoadCursor(0, 32642))
		Case 6, 7
			_WinAPI_SetCursor(_WinAPI_LoadCursor(0, 32643))
        Case Else
            _WinAPI_SetCursor(_WinAPI_LoadCursor(0, 32512))
	EndSwitch
EndFunc

Архив: DSEngine + Source code


Добавлено:
Сообщение автоматически объединено:

Всё, сам додумал :smile: кому интересно...

Код:
...
GUIRegisterMsg($WM_ERASEBKGND, 'WndProc')
...

Func WndProc($hWnd, $iMsg, $wParam, $lParam)
	Local Static $iBorder = 0
	Switch $hWnd
		Case $hForm
			Switch $iMsg
				Case $WM_ERASEBKGND
					Return 0
                EndSwitch
	EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc
...
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Хотя нет, $WM_ERASEBKGND не подходит, как заставить не обновляться окно когда меняешь его размеры?

Код:
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <APIConstants.au3>
#include <WinAPIEx.au3>
#Include <DSEngine.au3>

$sFile = FileOpenDialog('Select Video File', @ScriptDir, 'Video Files (*.avi;*.mpg;*.wmv;*.mov;*.3gp;*.asf;*.mp4;*.flv;*.rv)')
If Not $sFile Then
	Exit
EndIf

If (@OSArch == 'X86') Then
  Engine_Startup(@ScriptDir & '\DSEngine_UDF.dll')
ElseIf (@OSArch == 'X64') Then
  Engine_Startup(@ScriptDir & '\DSEngine_UDF_x64.dll')
Else
  Exit
EndIf

$hForm = GUICreate('', 500, 350, -1, -1, BitOR($WS_POPUP, $WS_CLIPCHILDREN))
GUISetBkColor(0x151515)
$iButton = GUICtrlCreateButton('Exit', 20, 20, 100, 20)
Engine_LoadFile($sFile, $hForm)
Engine_SetRects(0, 0, 0, 0, 0, 0, 500, 350)
Engine_StartPlayback()
GUIRegisterMsg($WM_LBUTTONDBLCLK, 'WndProc')
GUIRegisterMsg($WM_NCHITTEST, 'WndProc')
GUIRegisterMsg($WM_SIZE, 'WndProc')
GUIRegisterMsg($WM_SIZING, 'WndProc')
GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iButton
            Exit
	EndSwitch
Wend

Func WndProc($hWnd, $iMsg, $wParam, $lParam)
	Local Static $iMaximize = 0
	Local $iPos, $iX, $iY
	Switch $hWnd
		Case $hForm
			Switch $iMsg
				Case $WM_LBUTTONDBLCLK
					If (Not $iMaximize) Then
						GUISetState(@SW_MAXIMIZE, $hWnd)
						$iMaximize = 1
					Else
                        GUISetState(@SW_RESTORE, $hWnd)
						$iMaximize = 0
 					EndIf
				Case $WM_SIZE, $WM_SIZING
					$iPos = WinGetPos($hWnd)
					If ((Not @error) And IsArray($iPos)) Then
						If Engine_GetState() Then
					        Engine_SetRects(0, 0, 0, 0, 0, 0, $iPos[2], $iPos[3])
						EndIf
					EndIf
				Case $WM_NCHITTEST
					If (Not $iMaximize) Then
					    $iPos = WinGetPos($hWnd)
					    If ((Not @error) And IsArray($iPos)) Then
					        $iX = (BitAND($lParam, 0xFFFF) - $iPos[0])
					        $iY = (BitAND(BitShift($lParam, 16), 0xFFFF) - $iPos[1])
					        If (($iX <= 4) And ($iY < ($iPos[3] - 4))) Then
                                If ($iY > 4) Then
                                    Return $HTLEFT
                                Else
                                    Return $HTTOPLEFT
                                EndIf
                            ElseIf ($iY <= 4) Then
                                If ($iX < ($iPos[2] - 4)) Then
                                    Return $HTTOP
                                Else
                                    Return $HTTOPRIGHT
                                EndIf
                            ElseIf ($iX >= ($iPos[2] - 4)) Then
						        If ($iY < ($iPos[3] - 4)) Then
                                    Return $HTRIGHT
                                Else
                                    Return $HTBOTTOMRIGHT
                                EndIf
                            ElseIf ($iY >= ($iPos[3] - 4)) Then
                                If ($iX > 4) Then
                                    Return $HTBOTTOM
                                Else
                                    Return $HTBOTTOMLEFT
                                EndIf
                            Else
							    _SendMessage($hWnd, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
                            EndIf
					    EndIf
					EndIf
			EndSwitch
	EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc



Добавлено:
Сообщение автоматически объединено:

Млин, написал тоже самое на PureBasic, там окно не моргает :scratch:
 

Arei

Скриптер
Сообщения
938
Репутация
115
Было бы интересно узнать ответ на данную тему.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Viktor1703 [?]
Сделал я значит POPUP окно, в ручную обрабатываю сообщения чтобы можно было тащить за края окна и тем самым изменять его размеры

Раз уж сообщения обрабатываются в самом скрипте, то имеется смысл в следующем :
при перемещении мыши, показывать только изменение размеров рамки окна, а само окно перемещать только один раз - при отпускании кнопки мыши.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Не много не понял, у меня есть окно, на нём отображается видео во всё POPUP окно, когда перемещаю окно - всё нормально, когда тяну за край окна, то окно меняет свой размер и при этом жутко моргает видео. У меня код поменялся, во втором сообщении уже не используются функции IsOverBorder и ResizeBorder.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Viktor1703 [?]
Не много не понял
Во время нажатия ЛКМ на краю окна создается прозрачное окно с рамкой как у Au3Info, чтобы видеть конечное положение окна. При отпускании ЛКМ дополнительное окно убирается и изменяется размер основного окна, при этом размер основного окна меняется только один раз.

Или, как разновидность - делается снимок окна, и на время ресайза, поверх видео устанавливается картинка.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Хорошо, если ни чего так и не придумаю с плавной прорисовкой, то сделаю как Вы посоветовали, спасибо :smile:
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Viktor1703

Замена
Код:
Engine_LoadFile($sFile, $hForm)

на
Код:
Engine_LoadFile($sFile, 0)

приводит к созданию окна видеоплеера, не связанного с основным окном, и это окно не моргает при изменении размеров.

Думаю, возможно с помощью функций изменения стиля привести это окно к нужному виду, а свое GUI с кнопками рисовать поверх него, перемещать эти окна вместе и т. д.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
перемещать эти окна вместе и т. д.

Нет, видео должно рисоваться прямо на окне, иначе мне придётся обрабатывать сообщения окна самого плеера и моего и по мимо них будет ещё как минимум 2 окна
 
Верх