Sign in to follow this  
Followers 0
Skrip

How to 'clearglass' windows in Win7?

8 posts in this topic

How can you use a script to make a window look like this? Win7 only. It happens when you roll your mouse over a window icon on the taskbar.

Posted Image


[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Share this post


Link to post
Share on other sites



How can you use a script to make a window look like this? Win7 only. It happens when you roll your mouse over a window icon on the taskbar.

Posted Image

http://www.autoitscript.com/forum/index.php?showtopic=75429&hl=aero&st=0

Is that what your looking for?

Share this post


Link to post
Share on other sites

Hmm... I recognized that, but didn't think it was glass, due to it being clear completely without a color hue. Any idea how to recreate that color/trans?


[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Share this post


Link to post
Share on other sites

That feature may not be available to programs. It's potentially an OS internal tool since I don't see any use in making a window look like that.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

It can be DwmExtendFrameIntoClientArea's work. Extending the translucent area into the client area.

Edit: If you manage to dismiss the lower margin black frame you'll get this same effect. By the way it's easier to do so using WPF.

#include <WinAPI.au3>
#include <WindowsConstants.au3>
Opt("MustDeclareVars", 1)

If Not IsDeclared("WM_DWMCOMPOSITIonchangeD") Then Global Const $WM_DWMCOMPOSITIonchangeD = 0x031E

Global $hGUI = GUICreate("Test", 300, 300)
GUICtrlCreateButton("Button", 115, 137, 70, 24)

GUIRegisterMsg($WM_ERASEBKGND, "_WM_ERASEBKGND")
GUIRegisterMsg($WM_DWMCOMPOSITIonchangeD, "_WM_DWMCOMPOSITIonchangeD")
GUISetState()

_SendMessage($hGUI, $WM_DWMCOMPOSITIonchangeD)

Do
Until GUIGetMsg() = -3

GUIDelete()
Exit

Func _WM_ERASEBKGND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hDC = $iwParam
    Local $tClientRect = _WinAPI_GetClientRect($hWnd)
    Local $hBrush = _WinAPI_GetStockObject($BLACK_BRUSH)

    _WinAPI_FillRect($hDC, DllStructGetPtr($tClientRect), $hBrush)
    
    Return 1
EndFunc

Func _WM_DWMCOMPOSITIonchangeD($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tMargs = DllStructCreate($tagMARGINS)

    If _WinAPI_DwmIsCompositionEnabled() Then
        DllStructSetData($tMargs, 3, 300)
        _WinAPI_DwmExtendFrameIntoClientArea($hWnd, $tMargs)
    EndIf
    
    Return 0
EndFunc

Func _WinAPI_DwmExtendFrameIntoClientArea($hWnd, ByRef $tMargins)
    Local $aResult = DllCall("dwmapi.dll", "int", "DwmExtendFrameIntoClientArea", "hwnd", $hWnd, "ptr", DllStructGetPtr($tMargins))
    
    If @error Then Return SetError(@error, @extended, -1)
    Return $aResult[0]
EndFunc

Func _WinAPI_DwmIsCompositionEnabled()
    Local $aResult = DllCall("dwmapi.dll", "int", "DwmIsCompositionEnabled", "int*", 0)
    
    If @error Then Return SetError(@error, @extended, -1)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc
Edited by Authenticity

Share this post


Link to post
Share on other sites

Extending the frame does not make the controls on the window disappear. That just makes the background of the window glass instead of gray (or similar color).

Share this post


Link to post
Share on other sites

Extending the frame just allows you to literally extend the Aero glass theme into the client. What you choose to do with the controls is your decision. For example you can make the control invisible like:

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

Opt("MustDeclareVars", 1)
HotKeySet("#c", "_Test") ; win + c

If Not IsDeclared("WM_DWMCOMPOSITIonchangeD") Then Global Const $WM_DWMCOMPOSITIonchangeD = 0x031E

Global $fTest = False
Global $hGUI = GUICreate("Test", 300, 300)
Global $Button = GUICtrlCreateButton("Button", 115, 137, 70, 24)

GUIRegisterMsg($WM_ERASEBKGND, "_WM_ERASEBKGND")
GUIRegisterMsg($WM_DWMCOMPOSITIonchangeD, "_WM_DWMCOMPOSITIonchangeD")
GUISetState()

_SendMessage($hGUI, $WM_DWMCOMPOSITIonchangeD)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

GUIDelete()
Exit

Func _Test()
    $fTest = Not $fTest
    
    If $fTest Then
        GUICtrlSetState($Button, $GUI_HIDE)
    Else
        GUICtrlSetState($Button, $GUI_SHOW)
    EndIf
EndFunc

Func _WM_ERASEBKGND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hDC = $iwParam
    Local $tClientRect = _WinAPI_GetClientRect($hWnd)
    Local $hBrush = _WinAPI_GetStockObject($BLACK_BRUSH)

    _WinAPI_FillRect($hDC, DllStructGetPtr($tClientRect), $hBrush)
    
    Return 1
EndFunc

Func _WM_DWMCOMPOSITIonchangeD($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tMargs = DllStructCreate($tagMARGINS)

    If _WinAPI_DwmIsCompositionEnabled() Then
        DllStructSetData($tMargs, 3, 300)
        _WinAPI_DwmExtendFrameIntoClientArea($hWnd, $tMargs)
    EndIf
    
    Return 0
EndFunc

Func _WinAPI_DwmExtendFrameIntoClientArea($hWnd, ByRef $tMargins)
    Local $aResult = DllCall("dwmapi.dll", "int", "DwmExtendFrameIntoClientArea", "hwnd", $hWnd, "ptr", DllStructGetPtr($tMargins))
    
    If @error Then Return SetError(@error, @extended, -1)
    Return $aResult[0]
EndFunc

Func _WinAPI_DwmIsCompositionEnabled()
    Local $aResult = DllCall("dwmapi.dll", "int", "DwmIsCompositionEnabled", "int*", 0)
    
    If @error Then Return SetError(@error, @extended, -1)
    Return SetError($aResult[0], 0, $aResult[1])
EndFunc

What I think that makes it less attractive than C# or other object-oriented code language is that you need to set the state of the controls one after another using enumeration or controls collection which in C# for example could be easy using delegates.

PS. The Aero glass is just a dark blur brush on a minimal transparent window. It can be replicated easily and even with greater control over blur distortion and other effects.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Authenticity's example works good. Thanks man! Also, to get sheet of glass properly, behold...

Func _WM_DWMCOMPOSITIonchangeD($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tMargs = DllStructCreate($tagMARGINS)
    If _WinAPI_DwmIsCompositionEnabled() Then
        DllStructSetData($tMargs, $_glassify_xOpt, $_glassify_xVal)
        DllStructSetData($tMargs, $_glassify_yOpt, $_glassify_yVal)
        _WinAPI_DwmExtendFrameIntoClientArea($hWnd, $tMargs)
    EndIf
EndFunc

...where -

$_glassify_xOpt is 1 or 2 for draw-from-left or draw-from-right (respectively)

$_glassify_yOpt is 3 or 4 for draw-from-top or draw-from-bottom (respectively)

$_glassify_xVal and $_glassify_yVal are obviously the pixels, using -1 applies a sheet of glass to the entire window.

I don't know too much about this DLL stuff so sorry if my explanation sucks but oh well hope it helps someone ;) Curious to know if this has any side effects apart from some fiddly code for redrawing *some* controls (Statics seem fine) but if I encounter anything of note I'll reply here...

EDIT: To the original poster, did you not want the Aero effect but rather a 100% transparent window that you can draw your own image on (e.g. a PNG in 24bpp+alpha)? I use a function like this that I don't know who created originally (sorry!):

; #Include <WinAPI.au3>

Func _drawPNG($hImage, $hGUI, $iAlpha=255)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iStep)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($gGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc

If you use Zedna's "Resources in a DLL" UDF, you can have $hImage = _ResourceGetAsImage("MYPIC", $RT_RCDATA, "data.dll") for example and it works well.

$hGUI is the GUI handle to paint the PNG on... the existing GUI must have Extended Style $WS_EX_LAYERED and might need the $WS_DISABLED style too I can't remember if that was my own error or not You only need $WS_DISABLED if you're setting a PNG as a "background" via a Pic control and want to keep it behind all the other controls.... $iAlpha is obviously the transparency with 255 being fully opaque.

Although I use that for a Splash screen, not sure how Controls will look if added... pretty sure it'll work fine though as long as you do _drawpng before adding controls to the GUI, why not?

...yeah all of that has been posted before surely, but I find that function to be fast enough to be called in a step=3 loop for fading in and out a Splash Screen with <1% CPU usage so it's worth a try :evil:

EDIT2: Just saw the image load in the OP *facepalm* go to http://msdn.microsoft.com/en-us/library/aa969527%28VS.85%29.aspx I am sure that one of those many entry points (functions? whatever) for dwmapi.dll can do this.

Edited by DanielC

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0