Efecto AERO de win7 en XP

Tus experiencias con la informática, o fuera de la informática
Responder
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Efecto AERO de win7 en XP

Mensaje por ms999 »

Hola foreros! Vengo con una duda acerca de como hace el AERO de windows para lograr el efecto blur sobre el fondo.
El tema es que quiero crear por hobby varianbtes del efecto ese que hace AERO, ya conozco la funciones de AERO para lograr el efecto sobre cualquier ventana, mi problema no es con eso porque quiero hacer algo personalizado, tambien se como crear a travez de GDI+ plantillas semitranparentes con algunos efectos, pero el efecto que quiero lobrar es el blur... no se me ocurre como lo hara windows y si es posible reproducir con AutoIt a travez de APIs.

Les adjunto algunas imagenes.

Esto es la una GUI en la cual estoy trabajando(no es transparente)
Imagen

Esta si es transparente y esta fundida a la GUI
Imagen

Este es el efecto de AERO que quiero reproducir
Imagen

EDIT: yo se que dentro del archivo C:\Windows\Resources\Themes\Aero\aero.msstyles estan los PNGs que usa Aero para las graficas del efecto, pero no creo que con solo una imagen pueda hacer el blur de detras de la ventana.
Última edición por ms999 el 05 Sep 2011, 12:23, editado 1 vez en total.
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Efecto AERO de win7

Mensaje por Chefito »

El que busca encuentra :smt002 :
http://www.autoitscript.com/forum/index ... mMainBar=1

He probado este código en w7 (buscado en google) y va bien: http://www.autoitscript.com/forum/topic ... functions/
Pero mira los demás no sea que sean mejores.
Lo único que he tenido que hacer es quitar la condición del sistema operativo vista.

Según microsoft: http://msdn.microsoft.com/en-us/library ... s.85).aspx
Estudia sus apis y su dll.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7

Mensaje por ms999 »

Gracias chefito por la respuesta, pero esas funciones ya las conozco, lo que quiero lograr yo es el mismo efecto blur pero con mis proppios diseños, como veras en las imagenes que subi he logrado hacer la ventana trannsparente con unos efectos de rayos todo a travez de GDI+, lo que me falta lograr es que lo que se ve a travez de la ventana se vea borroso.

Se que esto no es sencillo porque no uso el AERO de windows sino crear algo personalizado donde pueda elegir el colory controlar la grafica qque se ve en el glass.

Esto lo hago de hobby, :smt024 y creo que es imposible, pero quiza este pasando algo por alto, en un proximo post les subire algunos scripts con mis intentos suerte y saludos foreros
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Efecto AERO de win7

Mensaje por Ximorro »

¿No se podría hacer combinando algunas opciones de _WinAPI_BitBlt()? Quizás mezclando la imagen con una versión de ella misma desplazada...
¿No hay en GDI algo parecido para copiar bitmaps con operadores de copia?

Aquí lo hacen en GDI redimensionando la ventana (en este caso era toda la pantalla pero será cosa de utilizar el bitmap que te interese. El caso es que retoquean de modo exagerado la interpolación y offset y así el resultado queda borroso.
http://www.autoitscript.com/forum/topic ... _p__458911
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7

Mensaje por ms999 »

Ximorro sos un genio!, me estoy acercando al objetivo, todabia me falta encontrarla operación justa de BitBlt para lograr el efecto mas adecuadamente, encontrar la manera de aplicarlo(cada cuanto, cuantas veces) y buscar la manera de aplicarle una imagen semi-transparente al efecto... pero va en buen camino asi que supongo que ya lo ire resolviendo.
Aca te dejo un Snippet con lo que intente hasta ahora y hasta donde funcionó.

Código: Seleccionar todo

#include <WindowsConstants.au3>
#include <WinAPI.au3>

HotKeySet("{ESC}", "_Exit")

Global $WinPos

$hGui = GUICreate("Test Blur", -1, -1, -1, -1, $WS_POPUP)
;~ GUISetBkColor(0x227722)
WinSetTrans($hGui, "", 200)
GUISetState()

GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")

$hDeskDC = _WinAPI_GetDC(0)
$hDC = _WinAPI_GetDC($hGui)

AdlibRegister("AllTimeDrawing", 20)

Do

Until GUIGetMsg() = -3

_Exit()

Func WM_NCHITTEST($hWndGUI, $MsgID, $WParam, $LParam)
	Return $HTCAPTION
EndFunc   ;==>WM_NCHITTEST

Func AllTimeDrawing()
	$WinPos = WinGetPos($hGui)
	_WinAPI_BitBlt($hDC, -1, -1, 402, 402, $hDeskDC, $WinPos[0], $WinPos[1], $SRCCOPY)
EndFunc   ;==>AllTimeDrawing

Func _Exit()
	AdlibUnRegister("AllTimeDrawing")
	_WinAPI_ReleaseDC($hGui, $hDC)
	_WinAPI_ReleaseDC(0, $hDeskDC)
	Exit
EndFunc   ;==>_Exit
Gracias! ahora seguimos con lo que falta!

EDIT: Se me paso por alto eso de buscar si hay una funcion para copiar un bitmap con alguna operacion de por medio, me imagino que el efecto se logra cuando unis una misma imagen una siendo levemente mas grande que la otra... asi que lo voy a ir pensando que quiza no sea taaan dificil como parecía... de a poco se va resolviendo el puzzle.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Efecto AERO de win7

Mensaje por Ximorro »

Tú sí que eres una máquina. Y con qué facilidad lo manejas, para mí GDI+ era una pesadilla (bueno, este último no es de GDI, pero de la familia ;-)

El efecto es muy sutil, yo he tenido que quitarle transparencia para que se ve más, lo he dejado a
WinSetTrans($hGui, "", 100)

¿Has probado el operador $NOTSRCCOPY? No es lo que te interesa, pero deja un efecto interesante de "emboss", quizás puedas poner opciones de diferentes efectos.

Por lo del borroso, igual te toca copiar más en otro desplazamiento, o una idea sacado del enlace que te he puesto es copiar el bitmap a otro más pequeño, escalándolo, por ejemplo con StretchBlt de GDI+ (creo que no está en la UDF), con lo que pierde detalle. Después puedes volver a escalar al tamaño original, como ha perdido detalle se verá borroso ¿no?

Y lo bueno de todo esto es que estará inspirado en el Aero de Vista/Seven, ¡pero va perfectamente en un XP! ;-)

¿Tienes pensado hacer algún tipo de librería para aplicar efectos a ventanas?
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7

Mensaje por ms999 »

Lo del embbros se ve bastante bien, con relieve, me gustaria pero para la propia ventana, algo asi como labels con relieve. La manera que creo que se puede hacer facil esto es con HBITMAPS porque trabajan rapido, y son bastante manipulables. con uno o dos ya bastan para lograr efectos, aunque voy a ver el metodo que me resulte mas sencillo y manipulable. Creo que el desafìo final de este tema sería hacer una libreria sencilla de usar para otros usuarios.

Acerca de lo de GDI+ ultimamente estoy que vuelo con esto, me estoy haciendo un hobbista de GDI+, ya aveces ni le encuentro practicidad a lo que estoy haciendo, solo me gusta lograr efectos y cosas poco comunes.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Efecto AERO de win7

Mensaje por Ximorro »

La librería fácil sería limitarse a programas mono-GUI (o quizás varios GUI con el mismo efcto) y en vez del estándar GUICreate hacer un GUICreateWithFantasticEffects ;-)

Yo estuve haciendo experimentos con GDI, hice algunas animaciones que puedes ver por el foro (si buscas "bolas" saldrán los importantes ;-) ), pero la verdad es que no me gusta nada el modelo de trabajo, con objetos sueltos por todas partes, cuando algunos deberían ser propiedades de otros, y que si bitmaps, grapchis, contextos, todo parecido pero diferente... :smt005

Ya nos enseñarás tus experimentos, parece que te encuentras a gusto con ello. Seguro que podremos aprender mucho. ¡Ya tenemos experto de GDI+ en el foro! :smt032
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7

Mensaje por ms999 »

No he encontrado manera de hacer el bitmap transparente, he ido probando otras soluciones y salieron efectos bastante raros. dejo lo que hay por ahora. Tengan en cuenta que hay cosas comentadas porque es un borrador de prueba, incluso hay algunas cosas por ahi que ni siquera uso... bueno gente hoy me desvele, por alla debe ser casi mediodia y por aca recien salio el sol, me voy a descansar y pensar en otra cosa que ya tube bastante GDI por hoy... saludos

Código: Seleccionar todo

#AutoIt3Wrapper_UseX64=n
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>

HotKeySet("{ESC}", "_Exit")

Global $WinPos
Global $check = True
;~ $hDeskTop = _WinAPI_GetDesktopWindow()

$hGui = GUICreate("Test Blur", -1, -1, -1, -1, $WS_POPUP)

;~ GUISetBkColor(0x227722)
WinSetTrans($hGui, "", 200)
GUISetState()

GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUIRegisterMsg($WM_MOVING, "WM_MOVING")

$hDeskDC = _WinAPI_GetDC(0)
$hDC = _WinAPI_GetDC($hGui)

_GDIPlus_Startup()

$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)

$hBitmapBuffer = _GDIPlus_BitmapCreateFromGraphics(400, 400, $hGraphics)
$hGraphBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmapBuffer)

$hBrush = _GDIPlus_BrushCreateSolid(0x55005555)
;~ $hBrush = _WinAPI_CreateSolidBrush(0x550055)
$tRECT = DllStructCreate($tagRECT)

AdlibRegister("AllTimeDrawing", 50)

Do

Until GUIGetMsg() = -3

_Exit()

Func WM_NCHITTEST($hWndGUI, $MsgID, $WParam, $LParam)
	Return $HTCAPTION
EndFunc   ;==>WM_NCHITTEST

Func WM_MOVING($hWndGUI, $MsgID, $WParam, $LParam)
	$WinPos = WinGetPos($hGui)
;~ 	DllStructSetData($tRECT, 1 , $WinPos[0])
;~ 	DllStructSetData($tRECT, 2 , $WinPos[1])
;~ 	DllStructSetData($tRECT, 3 , $WinPos[0]+$WinPos[2])
;~ 	DllStructSetData($tRECT, 4 , $WinPos[1]+$WinPos[3])
	_GDIPlus_GraphicsFillRect($hGraphics,0,0,400,400,$hBrush)
;~ 	_GDIPlus_GraphicsFillRect($hGraphBuffer,0,0,400,400,$hBrush)
;~ 	_GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmapBuffer,0,0,400,400)
	_WinAPI_StretchBlt($hDC, 0, 0, 400, 400, $hDeskDC, $WinPos[0] + 50, $WinPos[1] + 50, $WinPos[2] - 100, $WinPos[3] - 100, $SRCCOPY)
EndFunc   ;==>WM_MOVING

Func AllTimeDrawing()
	$WinPos = WinGetPos($hGui)
;~ 	DllStructSetData($tRECT, 1 , $WinPos[0])
;~ 	DllStructSetData($tRECT, 2 , $WinPos[1])
;~ 	DllStructSetData($tRECT, 3 , $WinPos[0]+$WinPos[2])
;~ 	DllStructSetData($tRECT, 4 , $WinPos[1]+$WinPos[3])
;~ 	_GDIPlus_GraphicsFillRect($hGraphics,0,0,400,400,$hBrush) ; This;)
;~ 	_GDIPlus_GraphicsFillRect($hGraphBuffer,0,0,400,400,$hBrush)
;~ 	_GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmapBuffer,0,0,400,400)
	_WinAPI_StretchBlt($hDC, 0, 0, 400, 400, $hDeskDC, $WinPos[0] + 50, $WinPos[1] + 50, $WinPos[2] - 100, $WinPos[3] - 100, $SRCCOPY)
EndFunc   ;==>AllTimeDrawing

Func _Exit()
	AdlibUnRegister("AllTimeDrawing")
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_GraphicsDispose($hGraphBuffer)
	_GDIPlus_BitmapDispose($hBitmapBuffer)
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_Shutdown()
	_WinAPI_ReleaseDC($hGui, $hDC)
	_WinAPI_ReleaseDC(0, $hDeskDC)
	Exit
EndFunc   ;==>_Exit
EDIT: Podrian mover esto a alguna sección mas acorde en el foro?
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7 en XP

Mensaje por ms999 »

Va mejorando el tema :smt035

Código: Seleccionar todo

#include <WindowsConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>

HotKeySet("{ESC}", "_Exit")

Global $hDCBuffer, $Timer, $Results

$hGui = GUICreate("Test Blur", -1, -1, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0x227722)
_WinAPI_SetLayeredWindowAttributes($hGui, 0x227722, 220, 0x02)
$iButton = GUICtrlCreateButton("Test", 10, 10, 150, 40)
GUISetState()

GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUIRegisterMsg($WM_MOVING, "WM_MOVING")

$hDeskDC = _WinAPI_GetDC(0)
$hDC = _WinAPI_GetDC($hGui)

_GDIPlus_Startup()

$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)

$hRgn = _WinAPI_CreateRectRgn(10, 10, 160, 50)
_GDIPlus_GraphicsSetClipHrgn($hGraphics, $hRgn, 3)

$hBitmapBuffer = _GDIPlus_BitmapCreateFromGraphics(400, 400, $hGraphics)
$hGraphBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmapBuffer)

$hBrush = _GDIPlus_BrushCreateSolid(0x33550055)

$tRECT = DllStructCreate($tagRECT)

AdlibRegister("AllTimeDrawing", 50)

$WinPos = WinGetPos($hGui) ; Only Once

While True
	$iMsg = GuiGetMsg()
	If $iMsg = -3 then ExitLoop
	If $iMsg = $iButton then consolewrite($Results&@CRLF)
WEnd

_Exit()

Func WM_NCHITTEST($hWndGUI, $MsgID, $WParam, $LParam)
	If ($hWndGUI = $hGui) And ($MsgID = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc   ;==>WM_NCHITTEST

Func WM_MOVING($hWndGUI, $MsgID, $WParam, $LParam)
	$Timer = TimerInit()
	AdlibUnRegister("AllTimeDrawing")
	_GDIPlus_GraphicsReleaseDC($hGraphBuffer, $hDCBuffer)
	$tRECT = DllStructCreate($tagRECT, $LParam)
	$WinPos[0] = DllStructGetData($tRECT, 1)
	$WinPos[1] = DllStructGetData($tRECT, 2)
	$WinPos[2] = DllStructGetData($tRECT, 3) - $WinPos[0]
	$WinPos[3] = DllStructGetData($tRECT, 4) - $WinPos[1]
	$hDCBuffer = _GDIPlus_GraphicsGetDC($hGraphBuffer)
	_WinAPI_BitBlt($hDCBuffer, 0, 0, 400, 400, $hDeskDC, $WinPos[0] - 1, $WinPos[1] - 1, $SRCCOPY)
	_GDIPlus_GraphicsReleaseDC($hGraphBuffer, $hDCBuffer)
	_GDIPlus_GraphicsFillRect($hGraphBuffer, 0, 0, 400, 400, $hBrush)
	_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapBuffer, 0, 0, 400, 400)
	AdlibRegister("AllTimeDrawing", 50)
	$Results = TimerDiff($Timer)
	Return True
EndFunc   ;==>WM_MOVING

Func AllTimeDrawing()
;~ 	$Timer = TimerInit()
	$hDCBuffer = _GDIPlus_GraphicsGetDC($hGraphBuffer)
	_WinAPI_BitBlt($hDCBuffer, 0, 0, 400, 400, $hDeskDC, $WinPos[0] - 1, $WinPos[1] - 1, $SRCCOPY)
;~ 	_WinAPI_StretchBlt($hDCBuffer, 0, 0, 400, 400, $hDeskDC, $WinPos[0]+5, $WinPos[1]+5 , $WinPos[2]-10 , $WinPos[3]-10, $SRCCOPY)
	_GDIPlus_GraphicsReleaseDC($hGraphBuffer, $hDCBuffer)
	_GDIPlus_GraphicsFillRect($hGraphBuffer, 0, 0, 400, 400, $hBrush)
	_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmapBuffer, 0, 0, 400, 400)
;~ 	$Results = TimerDiff($Timer)
EndFunc   ;==>AllTimeDrawing

Func _GDIPlus_GraphicsSetClipHrgn($hGraphics, $hRgn, $iCombineMode = 0)
	Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetClipHrgn", "hwnd", $hGraphics, "hwnd", $hRgn, "int", $iCombineMode)

	If @error Then Return SetError(@error, @extended, False)
	$GDIP_STATUS = $aResult[0]
	Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_GraphicsSetClipHrgn

Func _Exit()
	AdlibUnRegister("AllTimeDrawing")
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_GraphicsDispose($hGraphBuffer)
	_GDIPlus_BitmapDispose($hBitmapBuffer)
	_WinAPI_DeleteObject($hRgn)
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_Shutdown()
	_WinAPI_ReleaseDC($hGui, $hDC)
	_WinAPI_ReleaseDC(0, $hDeskDC)
	Exit
EndFunc   ;==>_Exit
Me parece que lo que le falta a esto es el asunto del movimiento de la ventana, también el asunto de ponerle una imagen semi transparente de algun diseño, ya sea rayos, o cualquier cosa que se nos ocurra, va a parecer un adorno esta GUI :smt003 .
Sobre el asunto del movimiento de la ventana, algo se me debe estar pasando, AERO de windows debe usar algunas rutinas que no podré hacer en AutoIt pero debe haber un modo de simularlas de mejor manera. el asunto principal de esto es que la ventana causa un blur sobre el fondo, el blur debe ser causado porque una imagen de windows, hasta donde tengo entendido no causa efectos sobre otra imagen, osea que el efecto debe ser generado cada vez que windows repinta el escritorio... mmmh :smt017 quiza me equivoque en esto ultimo. Habrá que pensar posibles hipotesis de como lograrlo de manera rapida casi instantanea. igualmente esto tarda 40ms pero se deja ver algunos gliches por ahi.

Saludos Foro!!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Efecto AERO de win7 en XP

Mensaje por Ximorro »

Bueno, yo tengo bastante claro que lo del Aero se hace a base de tarjeta gráfica, no creo que esté hecho a base de CPU con las librerías gráficas como GDI+.
Así que va a ser bastante difícil conseguir el rendimiento de la GPU, pero se puede simular y hacer otros efectos. Mientras mueves yo haría otro efecto que no dependa de lo que hay debajo, o hacerlo bastante rápido, como pintar cuadrados de 20x20 con el color medio de lo que tienen debajo, como un efecto pixelzar, así sí tiene que ver con lo que hay debajo, manteniendo los tonos de lo que hay detrás.
O vaya, pones algo estático que no tengo que ver con lo de abajo, o un simple oscurecimiento de lo que hay detrás...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
ms999
Hacker del Foro
Mensajes: 116
Registrado: 26 Ene 2011, 06:13

Re: Efecto AERO de win7 en XP

Mensaje por ms999 »

Esas ideas Ximorro son bastante buenas, la idea es me parece que cambió de la original, no solo se trata de lograr el blur, sino el hecho de combinar GUIs con aspectos graficos dinamicos(con movimiento o interaccion con el fondo) y los controles estáticos.
Responder