Jump to content
Sign in to follow this  
Vadersapien

Tab Control interferes with Aero Glass

Recommended Posts

Vadersapien

Hello all,

If I create a tab control in a GUI which has the DWM window frame extended into it, the glass seems to turn white...any idea?

Full code here:

#Include <GUIConstants.au3>
#Include <WinAPI.au3>

$GUI = GUICreate('GUI Window', 800, 600)
GUISetState()

$DWM_Margins = DllStructCreate('int cxLeftWidth;int cxRightWidth;int cyTopHeight;int cyBottomHeight;')
DllStructSetData($DWM_Margins, 'cyTopHeight', 40)

$tab = GUICtrlCreateTab(0, 20, 200, 100)

$tab0 = GUICtrlCreateTabItem("tab0")

If _WinAPI_DwmIsCompositionEnabled() Then
    GUICtrlCreateLabel('', 0, 0, 800, 40, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetBkColor(-1, 0x000000)
    _WinAPI_DwmExtendFrameIntoClientArea($GUI, $DWM_Margins)
EndIf


While 1
    $GUIMsg = GUIGetMsg()
    Select
        Case $GUIMsg = $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSelect
WEnd

Try Pacfox, my Firefox theme.Try Power Eject, my windows gadget that allows you to eject most drives.Using AutoIt 3.3.4.0, Windows 7 Premium, Intel Core 2 Quad CPU @ 2.66ghz, 4gb RAM, Nvidia GeForce 9500GT Graphics Card & Samsung 22" Monitor.

Share this post


Link to post
Share on other sites
Authenticity

#include <Constants.au3>
#include <Date.au3>
#include <EditConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUITab.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Opt("MustDeclareVars", 1)

If Not IsDeclared("WM_DWMCOMPOSITIonchangeD") Then Global Const $WM_DWMCOMPOSITIonchangeD = 0x031E
If Not IsDeclared("WM_PRINT") Then Global Const $WM_PRINT = 0x0317
If Not IsDeclared("WM_PRINTCLIENT") Then Global Const $WM_PRINTCLIENT = 0x0318
If Not IsDeclared("tagBP_PAINTPARAMS") Then Global Const $tagBP_PAINTPARAMS = "uint Size;uint Flags;" & $tagRECT & ";ptr BlendFunction;"
If Not IsDeclared ("tagDWM_BLURBEHIND") Then Global Const $tagDWM_BLURBEHIND = "uint Flags;int Enable;hwnd RgnBlur;int TransitionOnMaximized;"
If Not IsDeclared("tagPAINTSTRUCT") Then Global Const $tagPAINTSTRUCT = "hwnd hDC;int Erase;" & $tagRECT & ";int Restore;int IncUpdate;ubyte Reserved[32]"
If Not IsDeclared("tagDTTOPTS") Then Global Const $tagDTTOPTS = _
"uint Size;uint Flags;uint clrText;uint clrBorder;uint clrShadow;int TextShadowType;" & $tagPOINT & _
";int BorderSize;int FontPropId;int ColorPropId;int StateId;int ApplyOverlay;int GlowSize;ptr DrawTextCallback;int lParam;"

Global Enum $BPBF_COMPATIBLEBITMAP, $BPBF_DIB, $BPBF_TOPDOWNDIB, $BPBF_TOPDOWNMONODIB
Global Const $PRF_CHECKVISIBLE = 0x00000001
Global Const $PRF_NONCLIENT = 0x00000002
Global Const $PRF_CLIENT = 0x00000004
Global Const $PRF_ERASEBKGND = 0x00000008
Global Const $PRF_CHILDREN = 0x00000010
Global Const $PRF_OWNED = 0x00000020
Global Const $DWM_BB_ENABLE = 0x00000001
Global Const $DWM_BB_BLURREGION = 0x00000002
Global Const $DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
Global Const $DTT_GRAYED = 0x00000001
Global Const $DTT_FLAGS2VALIDBITS = $DTT_GRAYED
Global Const $DTT_TEXTCOLOR = 0x00000001
Global Const $DTT_BORDERCOLOR = 0x00000002
Global Const $DTT_SHADOWCOLOR = 0x00000004
Global Const $DTT_SHADOWTYPE = 0x00000008
Global Const $DTT_SHADOWOFFSET = 0x00000010
Global Const $DTT_BORDERSIZE = 0x00000020
Global Const $DTT_FONTPROP = 0x00000040
Global Const $DTT_COLORPROP = 0x00000080
Global Const $DTT_STATEID = 0x00000100
Global Const $DTT_CALCRECT = 0x00000200
Global Const $DTT_APPLYOVERLAY = 0x00000400
Global Const $DTT_GLOWSIZE = 0x00000800
Global Const $DTT_CALLBACK = 0x00001000
Global Const $DTT_COMPOSITED = 0x00002000
Global Const $DTT_VALIDBITS = BitOR($DTT_TEXTCOLOR, $DTT_BORDERCOLOR, $DTT_SHADOWCOLOR, $DTT_SHADOWTYPE, $DTT_SHADOWOFFSET, $DTT_BORDERSIZE, _
        $DTT_FONTPROP, $DTT_COLORPROP, $DTT_STATEID, $DTT_CALCRECT, $DTT_APPLYOVERLAY, $DTT_GLOWSIZE, $DTT_COMPOSITED)

Global $hUxTheme = DllOpen("uxtheme.dll")

Global $hGUI = GUICreate('GUI Window', 800, 600)
Global $hTheme = _WinAPI_OpenThemeData($hGUI, "globals", $hUxTheme)
; Initialize buffered painting for the current thread.
_WinAPI_BufferedPaintInit($hUxTheme)

Global $tab = GUICtrlCreateTab(0, 20, 200, 100)
Global $tab0 = GUICtrlCreateTabItem("tab0")
Global $tab1 = GUICtrlCreateTabItem("tab1")
Global $htab = GUICtrlGetHandle($tab)

Global $DWM_Margins = DllStructCreate('int cxLeftWidth;int cxRightWidth;int cyTopHeight;int cyBottomHeight;')
DllStructSetData($DWM_Margins, 'cyTopHeight', 40)

If _WinAPI_DwmIsCompositionEnabled() Then
    _WinAPI_DwmExtendFrameIntoClientArea($hGUI, $DWM_Margins)
EndIf


Global $hTabProc = DllCallbackRegister("_TabProc", "int", "hwnd;uint;wparam;lparam")
Global $hWndProc = _WinAPI_SetWindowLong($htab, $GWL_WNDPROC, DllCallbackGetPtr($hTabProc))
GUIRegisterMsg($WM_ERASEBKGND, "_WM_ERASEBKGND")
GUIRegisterMsg($WM_NCHITTEST, "_WM_NCHITTEST")
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_CloseThemeData($hTheme, $hUxTheme)
_WinAPI_SetWindowLong($htab, $GWL_WNDPROC, $hWndProc)
DllCallbackFree($hTabProc)

;Closes down buffered painting for the current thread.
_WinAPI_BufferedPaintUnInit($hUxTheme)
GUIDelete()
Exit


Func _TabProc($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hDC, $hBufferedDC, $hPaintBuffer
    Local $tPS, $pPS
    Local $tRect
    
    Switch $iMsg
        Case $WM_PAINT
            $tPS = DllStructCreate($tagPAINTSTRUCT)
            $pPS = DllStructGetPtr($tPS)
            $hDC = _WinAPI_BeginPaint($hWnd, $pPS)
            $tRect = DllStructCreate($tagRECT)
            
            For $i = 1 To 4
                DllStructSetData($tRect, $i, DllStructGetData($tPS, $i+2))
            Next
            
            $hPaintBuffer = _WinAPI_BeginBufferedPaint($hDC, DllStructGetPtr($tRect), $BPBF_TOPDOWNDIB, 0, $hBufferedDC, $hUxTheme)
            _SendMessage($hWnd, $WM_PRINTCLIENT, $hBufferedDC, $PRF_CLIENT)
            _WinAPI_BufferedPaintSetAlpha($hPaintBuffer, 0, 255, $hUxTheme)
            
            ; Tweak to get the desired region to fill
;~          Local $hRgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
;~          Local $iItems = _GUICtrlTab_GetItemCount($hWnd)
;~          Local $iCurrItem = _GUICtrlTab_GetCurSel($hWnd)
;~          Local $aRect
;~          
;~          For $i = 0 To $iItems-1
;~              $aRect = _GUICtrlTab_GetItemRect($hWnd, $i)
;~              For $i = 0 To UBound($aRect)-1
;~                  ConsoleWrite($aRect[$i] & " ")
;~              Next
;~              ConsoleWrite(@CRLF)
;~              If $i = $iCurrItem Then
;~                  $aRect[0] -= 1
;~                  $aRect[1] -= 2
;~                  $aRect[2] += 1
;~                  If $i = 0 Then
;~                      $aRect[0] -= 1
;~                      $aRect[2] += 1
;~                  EndIf
;~                  If $i = $iItems-1 Then $aRect[2] += 1
;~                  
;~              Else
;~                  $aRect[2] -= 1
;~                  If $i = $iItems-1 Then $aRect[2] -= 1
;~              EndIf
;~              
;~              Local $hTabRgn = _WinAPI_CreateRectRgn($aRect[0], $aRect[1], $aRect[2], $aRect[3])
;~              _WinAPI_CombineRgn($hRgn, $hRgn, $hTabRgn, $RGN_OR)
;~              _WinAPI_DeleteObject($hTabRgn)
;~          Next

;~          $tRect = _WinAPI_GetClientRect($hWnd)
;~          Local $hFillRgn = _WinAPI_CreateRectRgn(DllStructGetData($tRect, "Left"), DllStructGetData($tRect, "Top"), DllStructGetData($tRect, "Right"), DllStructGetData($tRect, "Bottom"))
;~          _WinAPI_CombineRgn($hFillRgn, $hFillRgn, $hRgn, $RGN_DIFF)
;~          _WinAPI_SelectClipRgn($hBufferedDC, $hFillRgn)
;~          Local $hBrush = _WinAPI_CreateSolidBrush(0)
;~          _WinAPI_FillRgn($hBufferedDC, $hFillRgn, $hBrush)
;~          _WinAPI_DeleteObject($hBrush)
;~          _WinAPI_DeleteObject($hFillRgn)
;~          _WinAPI_DeleteObject($hRgn)
            
            If $hPaintBuffer Then _WinAPI_EndBufferedPaint($hPaintBuffer, True, $hUxTheme)
            
            _WinAPI_EndPaint($hWnd, $pPS)
            Return 0
    EndSwitch
    
    Return _WinAPI_CallWindowProc($hWndProc, $hWnd, $iMsg, $iwParam, $ilParam)
EndFunc

Func _WinAPI_SelectClipRgn($hDC, $hRgn)
    Local $aResult = DllCall("gdi32.dll", "int", "SelectClipRgn", "hwnd", $hDC, "hwnd", $hRgn)
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, 0, $aResult[0])
EndFunc

Func _WinAPI_FillRgn($hDC, $hRgn, $hBrush)
    Local $aResult
    
    If IsPtr($hBrush) Then
        $aResult = DllCall("gdi32.dll", "int", "FillRgn", "hwnd", $hDC, "hwnd", $hRgn, "hwnd", $hBrush)
    Else
        $aResult = DllCall("gdi32.dll", "int", "FillRgn", "hwnd", $hDC, "hwnd", $hRgn, "int", $hBrush)
    EndIf
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, 0, $aResult[0] <> 0)
EndFunc

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

    _WinAPI_FillRect($hDC, DllStructGetPtr($tClientRect), $hBrush)
    _WinAPI_DeleteObject($hBrush)
    
    $tClientRect = _WinAPI_GetClientRect($hWnd)
    DllStructSetData($tClientRect, "Top", 40)
    $hBrush = _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_BTNFACE))
    _WinAPI_FillRect($hDC, DllStructGetPtr($tClientRect), $hBrush)
    _WinAPI_DeleteObject($hBrush)
    
    Return 1
EndFunc

Func _WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    Return $HTCAPTION
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

Func _WinAPI_BeginPaint($hWnd, $pPaintStruct)
    Local $aResult = DllCall("user32.dll", "hwnd", "BeginPaint", "hwnd", $hWnd, "ptr", $pPaintStruct)
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, 0, $aResult[0])
EndFunc

Func _WinAPI_EndPaint($hWnd, $pPaintStruct)
    Local $aResult = DllCall("user32.dll", "int", "EndPaint", "hwnd", $hWnd, "ptr", $pPaintStruct)
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, 0, $aResult[0])
EndFunc

Func _WinAPI_OpenThemeData($hWnd, $sClassList, $hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "hwnd", "OpenThemeData", "hwnd", $hWnd, "wstr", $sClassList)

    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, 0, $aResult[0])
EndFunc

Func _WinAPI_CloseThemeData($hTheme, $hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "int", "CloseThemeData", "hwnd", $hTheme)

    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[0], $aResult[0] = 0)
EndFunc
 
Func _WinAPI_BufferedPaintInit($hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "int", "BufferedPaintInit")
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[0], $aResult[0] = 0)
EndFunc

Func _WinAPI_BufferedPaintUnInit($hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "int", "BufferedPaintUnInit")
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[0], $aResult[0] = 0)
EndFunc

Func _WinAPI_BeginBufferedPaint($hDC, $pRc, $iBufferFormat, $pPaintParams ,ByRef $phDC, $hDll = "uxtheme.dll")
    Local $tHDC = DllStructCreate("hwnd")
    Local $aResult = DllCall($hDll, "hwnd", "BeginBufferedPaint", "hwnd", $hDC, "ptr", $pRc, "int", $iBufferFormat, "ptr", $pPaintParams, "ptr", DllStructGetPtr($tHDC))
    
    If @error Then Return SetError(@error, @extended, 0)
    $phDC = DllStructGetData($tHDC, 1)
    Return SetError(0, 0, $aResult[0])
EndFunc

Func _WinAPI_EndBufferedPaint($hPaintBuffer, $fUpdateTarget = True, $hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "int", "EndBufferedPaint", "hwnd", $hPaintBuffer, "int", $fUpdateTarget)
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[0], $aResult[0] = 0)
EndFunc

Func _WinAPI_BufferedPaintSetAlpha($hPaintBuffer, $pRc, $bAlpha = 255, $hDll = "uxtheme.dll")
    Local $aResult = DllCall($hDll, "int", "BufferedPaintSetAlpha", "hwnd", $hPaintBuffer, "ptr", $pRc, "ubyte", $bAlpha)
    
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError(0, $aResult[0], $aResult[0] = 0)
EndFunc

I've commented out a part of the code so you can also makeup the non client area of the tab which right now is gray, taken from here

Share this post


Link to post
Share on other sites
Vadersapien

Hmm...more complex than I thought...is there an easier way?


Try Pacfox, my Firefox theme.Try Power Eject, my windows gadget that allows you to eject most drives.Using AutoIt 3.3.4.0, Windows 7 Premium, Intel Core 2 Quad CPU @ 2.66ghz, 4gb RAM, Nvidia GeForce 9500GT Graphics Card & Samsung 22" Monitor.

Share this post


Link to post
Share on other sites
Authenticity

Yes, moving the tab control to the true client area, not on any of the frame edges. Again, when it comes to the old GDI and the new DWM APIs that work with an alpha channels you need to add a few hacks.

Share this post


Link to post
Share on other sites
Vadersapien

Suppose I'll just have stick with the first method...I really wanted tabs on the glass...

Maybe a 2010 style ribbon interface would work...how hard would that be to implement?

What about custom tabs?

I think Microsoft should have spent more time on thinking about DWM and added a new GDI dll...

EDIT: Your code is really glitchy...

Edited by Vadersapien

Try Pacfox, my Firefox theme.Try Power Eject, my windows gadget that allows you to eject most drives.Using AutoIt 3.3.4.0, Windows 7 Premium, Intel Core 2 Quad CPU @ 2.66ghz, 4gb RAM, Nvidia GeForce 9500GT Graphics Card & Samsung 22" Monitor.

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  

×