Jump to content

Two questions about Layered GUI


qwert
 Share

Recommended Posts

I'm fairly new at working with layered windows ... and this sample scrpt shows my attempt to add a close button to a floating, draggable PNG image. The close button works properly, but it just doesn't show up. I marked my two questions in the script with "????????????"

#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <StaticConstants.au3>
#include <GUIConstants.au3>
;
Global Const $AC_SRC_ALPHA = 1
; Load PNG file as GDI bitmap
_GDIPlus_Startup()
$pngSrc = @scriptdir&"\Torus.png"
$hImage = _GDIPlus_ImageLoadFromFile($pngSrc)
; Extract image width and height from PNG
$width =  _GDIPlus_ImageGetWidth ($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)
; Create layered window
$GUI = GUICreate("test", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
SetBitMap($GUI, $hImage, 0)
; Register notification messages
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()
WinSetOnTop($gui,"",1)
SetBitMap($GUI, $hImage, 255)
AutoItSetOption ( "GUIOnEventMode", 1)
$ExitButton = GUICtrlCreateLabel("x", 80, 10, 30, 30, $SS_NOTIFY + $SS_CENTER)
GUICtrlSetFont(-1, 18, 800)
GUICtrlSetColor(-1, 0x000000)    ; why doesn't X show?                            ?????????????
GUICtrlSetTip(-1, " Close ")
GUICtrlSetOnEvent($ExitButton, "Terminate")
GUISetState(@SW_SHOW)
; And what was the following for? ... since it doesn't appear to be needed.                                           ??????????????
;$controlGui = GUICreate("ControlGUI", $width, $height, 0,0,$WS_POPUP,BitOR($WS_EX_LAYERED,$WS_EX_MDICHILD),$gui)
;GUICtrlCreatePic(-1,0,0,$width,$height)
;GuiCtrlSetState(-1,$GUI_DISABLE)
GUISetState()
While 1
Sleep(500)
WEnd
Func Terminate()
_WinAPI_DeleteObject($hImage)
_GDIPlus_Shutdown()
      Exit
EndFunc
; ===============================================================================================================================
; Handle the WM_NCHITTEST for the layered window so it can be dragged by clicking anywhere on the image.
; ===============================================================================================================================
Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
  if ($hWnd = $GUI) and ($iMsg = $WM_NCHITTEST) then Return $HTCAPTION
EndFunc
; ===============================================================================================================================
; SetBitMap
; ===============================================================================================================================
Func SetBitmap($hGUI, $hImage, $iOpacity)
  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" , $iOpacity )
  DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
  _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
  _WinAPI_ReleaseDC   (0, $hScrDC)
  _WinAPI_SelectObject($hMemDC, $hOld)
  _WinAPI_DeleteObject($hBitmap)
  _WinAPI_DeleteDC  ($hMemDC)
EndFunc

The script is based on segments of the PNG as GUI example posted in 2007 by lod3n

Thanks in advance for any help with this.

Link to comment
Share on other sites

Study lod3n's script. He commented every step and why it is necessary.

; And what was the following for? ... since it doesn't appear to be needed. ??????????????

; create child MDI gui window to hold controls
; this part could use some work - there is some flicker sometimes...
....
; child window transparency is required to accomplish the full effect, so $WS_EX_LAYERED above, and
; I think the way this works is the transparent window color is based on the image you set here:

what you do is create the label in the main $GUI, which appearently is only thought to be used to show the transparent png.

To make controls visible you need to create a child window, place a gif with certain color on it and then you add controls to this child window.

Though i thought i saw a more up to date way to do it.

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite
Link to comment
Share on other sites

Thanks very much for replying to my post.

I think part of my problem/question is that I'm trying to use the other method for transparent PNGs ... the one that doesn't involve setting up a gif with a certain color. It is a more recent method, although I've read they both have their uses.

What I'm lacking is a basic understanding of child windows in the layered method. I've been searching for a higher level explanation ... something along the lines of:

Create the parent GUI ... as a layered window

Create a child window to hold the PNG graphic ... and set it visible.

Create another child window to hold any controls ... and set it visible.

Then set <this> and set <that> .... you can create as many child windows as you want(?)

At this point I'm caught up in trying combination after combination ... but without a road map of the forest I'm in.

Any suggestions or other information will be appreciated. (i.e., beyond lod3n's example)

BTW, here's one that I found, but I wasn't able to make much of it: http://alexkr.com/source-code/50/layered-windows-and-updatelayeredwindow/

Link to comment
Share on other sites

found it, its _WinAPI_SetLayeredWindowAttributes and a _GUICreate_Alpha UDF

This seems to be much more cleaner.

You can comment out the dragable and static child guis

A good example of using that method:

Edited by qsek
Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite
Link to comment
Share on other sites

qsek, thanks for locating those examples. The first is a little off the mark, mainly because it doesn't do exactly what its comments say (like the second image moving with the first). But the second example (which downloads its own image files ... a bonus feature demonstration) is excellent. The buttons on the draggable image explain everything. My compliments to goldenix for such a concise example.
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...