Jump to content

How to 'clearglass' windows in Win7?


Skrip
 Share

Recommended Posts

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]

Link to comment
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?

Link to comment
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]

Link to comment
Share on other sites

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
Link to comment
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.

Link to comment
Share on other sites

  • 1 month later...

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...