Jump to content

Layered Window without Image


ProgAndy
 Share

Recommended Posts

I translated two functions from the WinAPI to AutoIt, so we can create transparent windows without any images.

Therefore, we call _WinAPI_SetLayeredWindowAttributes with $i_transparentcolor set to the bg-color of the GUI and ... the background is gone :)

CODE
#include <GUIConstants.au3>

#include <Constants.au3>

#include <WindowsConstants.au3>

#include <WINAPI.au3>

;############# Constants ##########

Global Const $LWA_ALPHA = 0x2

Global Const $LWA_COLORKEY = 0x1

;############# Example ############

#Region - GUI Create

$gui = GUICreate("trans", 300, 400, -1, -1, -1, $WS_EX_LAYERED)

GUICtrlCreateLabel("This is text on a transparent Layered GUI", 10, 10, 200, 20, -1, $GUI_WS_EX_PARENTDRAG)

GUICtrlSetTip(-1, "Click label to drag layered window")

$layButt = GUICtrlCreateButton("Button", 10, 40, 40)

GUISetBkColor(0xABCDEF)

_WinAPI_SetLayeredWindowAttributes($gui, 0x010101)

GUISetState()

$guicontrol = GUICreate("ControlGUI", 300, 400, 100, 100)

$checkTrans = GUICtrlCreateCheckbox("Transparent color 0xABCDEF (Checked) Or 0x010101", 10, 10)

$checkBorder = GUICtrlCreateCheckbox("POPUP-Style", 10, 30)

GUICtrlCreateLabel("Transparency for Layered GUI", 10, 50)

$slidTrans = GUICtrlCreateSlider(10, 70, 200, 30)

GUICtrlSetLimit($slidTrans, 255, 0)

GUICtrlSetData(-1, 255)

GUISetState()

#EndRegion - GUI Create

#Region - GUI SelectLoop

While 1

$extMsg = GUIGetMsg(1)

$msg = $extMsg[0]

Switch $extMsg[1]

Case $guicontrol

Select

Case $msg = $GUI_EVENT_CLOSE

Exit

Case $msg = $checkTrans Or $msg = $slidTrans

; Change Attributes of Trans-Color and Window Transparency

If BitAND(GUICtrlRead($checkTrans), $GUI_CHECKED) = $GUI_CHECKED Then

_WinAPI_SetLayeredWindowAttributes($gui, 0xABCDEF, GUICtrlRead($slidTrans))

Else

_WinAPI_SetLayeredWindowAttributes($gui, 0x010101, GUICtrlRead($slidTrans))

EndIf

Case $msg = $checkBorder

If BitAND(GUICtrlRead($checkBorder), $GUI_CHECKED) = $GUI_CHECKED Then

GUISetStyle($WS_POPUP, -1, $gui)

Else

GUISetStyle($GUI_SS_DEFAULT_GUI, -1, $gui)

EndIf

EndSelect

Case $gui

Select

Case $msg = $layButt

Dim $transcolor, $alpha

$info = _WinAPI_GetLayeredWindowAttributes($gui,$transcolor, $alpha)

MsgBox(0, 'Layered GUI', "Button on layered Window Clicked" & @CRLF & "Information about this window: " & @CRLF & _

"Transparent Color: " & $transcolor & @CRLF & _

"Alpha Value: " & $alpha & @CRLF & _

"LWA_COLORKEY: " & (BitAND($info,$LWA_COLORKEY)=$LWA_COLORKEY) & @CRLF & _

"LWA_ALPHA: " & (BitAND($info,$LWA_ALPHA)=$LWA_ALPHA) )

Case $msg = $GUI_EVENT_CLOSE

Exit MsgBox(0, '', "Close from Layered GUI")

EndSelect

EndSwitch

WEnd

#EndRegion - GUI SelectLoop

;############# EndExample #########

;===============================================================================

;

; Function Name: _WinAPI_SetLayeredWindowAttributes

; Description:: Sets Layered Window Attributes:) See MSDN for more informaion

; Parameter(s):

; $hwnd - Handle of GUI to work on

; $i_transcolor - Transparent color

; $Transparency - Set Transparancy of GUI

; $isColorRef - If True, $i_transcolor is a COLORREF( 0x00bbggrr ), else an RGB-Color

; Requirement(s): Layered Windows

; Return Value(s): Success: 1

; Error: 0

; @error: 1 to 3 - Error from DllCall

; @error: 4 - Function did not succeed - use

; _WinAPI_GetLastErrorMessage or _WinAPI_GetLastError to get more information

; Author(s): Prog@ndy

;

; Link : @@MsdnLink@@ SetLayeredWindowAttributes

; Example : Yes

;===============================================================================

;

Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)

; #############################################

; You are NOT ALLOWED to remove the following lines

; Function Name: _WinAPI_SetLayeredWindowAttributes

; Author(s): Prog@ndy

; #############################################

If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03

If Not $isColorRef Then

$i_transcolor = Hex(String($i_transcolor), 6)

$i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))

EndIf

Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)

Select

Case @error

Return SetError(@error, 0, 0)

Case $Ret[0] = 0

Return SetError(4, _WinAPI_GetLastError(), 0)

Case Else

Return 1

EndSelect

EndFunc ;==>_WinAPI_SetLayeredWindowAttributes

;===============================================================================

;

; Function Name: _WinAPI_GetLayeredWindowAttributes

; Description:: Gets Layered Window Attributes:) See MSDN for more informaion

; Parameter(s):

; $hwnd - Handle of GUI to work on

; $i_transcolor - Returns Transparent color ( dword as 0x00bbggrr or string "0xRRGGBB")

; $Transparency - Returns Transparancy of GUI

; $isColorRef - If True, $i_transcolor will be a COLORREF( 0x00bbggrr ), else an RGB-Color

; Requirement(s): Layered Windows

; Return Value(s): Success: Usage of LWA_ALPHA and LWA_COLORKEY (use BitAnd)

; Error: 0

; @error: 1 to 3 - Error from DllCall

; @error: 4 - Function did not succeed

; - use _WinAPI_GetLastErrorMessage or _WinAPI_GetLastError to get more information

; - @extended contains _WinAPI_GetLastError

; Author(s): Prog@ndy

;

; Link : @@MsdnLink@@ GetLayeredWindowAttributes

; Example : Yes

;===============================================================================

;

Func _WinAPI_GetLayeredWindowAttributes($hwnd, ByRef $i_transcolor, ByRef $Transparency,$asColorRef = False)

; #############################################

; You are NOT ALLOWED to remove the following lines

; Function Name: _WinAPI_SetLayeredWindowAttributes

; Author(s): Prog@ndy

; #############################################

$i_transcolor = -1

$Transparency = -1

Local $Ret = DllCall("user32.dll", "int", "GetLayeredWindowAttributes", "hwnd", $hwnd, "long*", $i_transcolor, "byte*", $Transparency, "long*", 0)

Select

Case @error

Return SetError(@error, 0, 0)

Case $Ret[0] = 0

Return SetError(4, _WinAPI_GetLastError(), 0)

Case Else

If Not $asColorRef Then

$Ret[2] = Hex(String($Ret[2]), 6)

$Ret[2] = '0x' & StringMid($Ret[2], 5, 2) & StringMid($Ret[2], 3, 2) & StringMid($Ret[2], 1, 2)

EndIf

$i_transcolor = $Ret[2]

$Transparency = $Ret[3]

Return $Ret[4]

EndSelect

EndFunc ;==>_WinAPI_GetLayeredWindowAttributes

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 1 month later...

I think, this should be added to WinAPI.au3, at least _WinAPI_SetLayeredWindowAttributes, because it is needed for correct Handling of layered windows, which become more and more important.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I translated two functions from the WinAPI to AutoIt, so we can create transparent windows without any images.

I've been experimenting with _WinAPI_SetLayeredWindowAttributes.

Here is a non-layered window which has the properties of a layered window with an image.

The transparent color used is the top left pixel of the captured image on the GUI.

#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Global $iTransparentColor ; = 0xFFFFFFFF ; = 0xFF000000 ;  = 0xD4D0C8 ; 
Global $iWidth, $iHeight, $hBitmap, $GuiSizeX = 400, $GuiSizeY = 400
Local $x,$Flag

$hGUI2 = GUICreate("$hGUI2", $GuiSizeX, $GuiSizeY) ;, -1, -1, 0, ($WS_EX_LAYERED))
WinSetTrans($hGUI2, "", 255)
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hBitmap = _ScreenCapture_Capture("", 0, 0, $GuiSizeX, $GuiSizeY, False)
$hImage2 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$iWidth = _GDIPlus_ImageGetWidth($hImage2)
$iHeight = _GDIPlus_ImageGetHeight($hImage2)
_GDIPlus_ImageDispose($hImage2)
$hDDC2 = _WinAPI_GetDC($hGUI2)
$hCDC2 = _WinAPI_CreateCompatibleDC($hDDC2)
_WinAPI_SelectObject($hCDC2, $hBitmap)

_WinAPI_BitBlt($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2, 0, 0, $SRCCOPY)
If Not IsNumber($iTransparentColor) Then $iTransparentColor = "0x" & Hex(PixelGetColor(1, 1, $hGUI2), 6)

$x = 250
do  
    if $x = 0 then $Flag = 0
    if $x = 255 then $Flag = 1
    $x += 5 - ($Flag*10)
    _WinAPI_SetLayeredWindowAttributes($hGUI2, $iTransparentColor,$x)
    sleep(100)
until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_DeleteObject($hBitmap)
_WinAPI_ReleaseDC($hGUI2, $hDDC2)
_WinAPI_DeleteDC($hCDC2)
_GDIPlus_Shutdown()

Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)
    If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03

    If Not $isColorRef Then
        $i_transcolor = Hex(String($i_transcolor), 6)
        $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)
    Select
        Case @error
            Return SetError(@error, 0, 0)
        Case $Ret[0] = 0
            Return SetError(4, _WinAPI_GetLastError(), 0)
        Case Else
            Return 1
    EndSelect
EndFunc   ;==>_WinAPI_SetLayeredWindowAttributes

I thought it was interesting, a curio.

Edit: 2008-08-13 Added auto Fade-in/Fade-out loop.

Edited by Malkey
Link to comment
Share on other sites

  • 7 months later...

How do you create the PNG? GUICtrlCreatePic can't show a PNG-file. Here is an example for PNG: http://www.autoitscript.com/forum/index.ph...7651&hl=png (my UDF can replace the grey.gif for the Control-GUI here)

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

btw was done before :D but GJ

#include <GuiConstants.au3>
#include <windowsconstants.au3>
HotKeySet("{ESC}", "QuitApp")

$main_Gui = GUICreate("",400,400,20,20,$WS_POPUP, $WS_EX_TOOLWINDOW+$WS_EX_TOPMOST)
$but1 = GUICtrlCreateButton(" Exit ", 100, 100,80,21)
$Info_Edit = GUICtrlCreateEdit("A few words to start off with", 80, 150, 300, 220)

$masterMask = CreateMasterMask();
AddToMask($masterMask,$main_Gui,$but1);add button to mask
AddToMask($masterMask,$main_Gui,$Info_Edit);add the edit
FitMask($masterMask,$main_gui);apply the mask to the window

GUISetState()


While 1    
    if GUIGetMsg() = $but1 then exit
WEnd

Func CreateMasterMask()
    return DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
EndFunc

Func FitMask($aMask,$hWnd)
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aMask[0], "int", 1)
endfunc

Func AddToMask(ByRef $MM, $hWnd, $ID)
    $pp = ControlGetPos($hWnd,'',$ID)
    Local $Mask1 = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $pp[0], "long", $pp[1], "long", $pp[0] + $pp[2], "long",$pp[1] + $pp[3])
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $MM[0], "long", $Mask1[0], "long", $MM[0],"int",2)
EndFunc


Func QuitApp()
    Exit
EndFunc
Link to comment
Share on other sites

btw was done before :D but GJ

...

Func CreateMasterMask()
    return DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
EndFunc

Func FitMask($aMask,$hWnd)
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aMask[0], "int", 1)
endfunc

Func AddToMask(ByRef $MM, $hWnd, $ID)
    $pp = ControlGetPos($hWnd,'',$ID)
    Local $Mask1 = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $pp[0], "long", $pp[1], "long", $pp[0] + $pp[2], "long",$pp[1] + $pp[3])
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $MM[0], "long", $Mask1[0], "long", $MM[0],"int",2)
EndFunc
This is not the same :o MSDN says transparent layered windows are faster than regions. Also, you have to add each Control to the region and non-rectangular forms are difficult to create. With layered window transparency you just have to choose a transparent color you won't display in your GUI.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

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...