Jump to content

Recommended Posts

Posted (edited)

I'm trying to create a GUI from an img, draggable, with some zones in it that hovering them get another GUI and other zones clickable to open another GUI.

I got it in 2 ways:

WinAPI

and

GDIPlus

Which one is the better approach?

 

This is the WinAPI code:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GUIToolTip.au3>
#include <GUIListView.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>


    _GDIPlus_Startup()

    Global Const $SC_DRAGMOVE = 0xF012
    Global $iW, $iH, $hImage, $hBitmap, $hImageL, $hBitmapL
    
    $sMainPic = "Star.png"
    $hImage = _GDIPlus_BitmapCreateFromFile($sMainPic)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $iW = _GDIPlus_ImageGetWidth($hImage)
    $iH = _GDIPlus_ImageGetHeight($hImage)
    ;~ global $hGUImain = GUICreate("", _GDIPlus_ImageGetWidth($hSplashlogo), _GDIPlus_ImageGetHeight($hSplashlogo), $logowidth, $logoheight, $WS_POPUP, BitOR( $WS_EX_TOPMOST,$WS_EX_LAYERED,$WS_EX_TOOLWINDOW))
    global $hGUImain = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP,$WS_EX_LAYERED )
    ;~ global $hGUImain = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOR( $WS_EX_TOPMOST,$WS_EX_LAYERED,$WS_EX_TOOLWINDOW) )
        GUISetState()
        _WinAPI_BitmapDisplayTransparentInGUI($hBitmap, $hGUImain)
        Global $mContext = GUICtrlCreateContextMenu()
        Global $mExit = GUICtrlCreateMenuItem("&Exit", $mContext)
        GUISetState(@SW_SHOW, $hGUImain)


    $sMainPic = "star_LowSPike.png"
    $hImageL = _GDIPlus_BitmapCreateFromFile($sMainPic)
    $hBitmapL = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImageL)
    $iW = _GDIPlus_ImageGetWidth($hImageL)
    $iH = _GDIPlus_ImageGetHeight($hImageL)
    global $hGUImainLowPoint = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP,  BitOR($WS_EX_TOPMOST,$WS_EX_LAYERED))
        GUISetState()
        _WinAPI_BitmapDisplayTransparentInGUI($hBitmapL, $hGUImainLowPoint)
        GUISetState(@SW_SHOW, $hGUImainLowPoint)
    
    ; *************************** GUI_SETTINGS
    global  $hGUIsettings = GUICreate("KWsettings", 950 , 680 ,90,100,  BitOr( $WS_CAPTION , $WS_POPUP ) ) 
    GUISetState(@SW_HIDE, $hGUIsettings)

    ; *************************** GUI_OVER
    global $hGUIbutt1 = GUICreate("Butt1", 800, 300, 50, 100, $WS_POPUP, $WS_EX_LAYERED, $hGUImain)
        GUISetBkColor(0x00F0F0)
        ;~ GUICtrlSetDefColor(0x010101, $hGUIbutt1)
        GUISetCoord(200, 10)
        global $button1        = GUICtrlCreateButton("GUI1" , -1,  -1,  450, 40,-1, $GUI_WS_EX_PARENTDRAG)
        _WinAPI_SetLayeredWindowAttributes($hGUIbutt1, 0x00F0F0, 255)

    global $hGUIbutt2 = GUICreate("Butt2", 800, 300, 50, 100, $WS_POPUP, $WS_EX_LAYERED, $hGUImainLowPoint)
    GUISetBkColor(0x00FF00)
    GUISetCoord(200, 10)
    global $button2        = GUICtrlCreateButton("GUI2" , -1,  -1,  450, 40,-1, $GUI_WS_EX_PARENTDRAG)
    _WinAPI_SetLayeredWindowAttributes($hGUIbutt2, 0x00FF00, 255)


    Global  $aMPos = '',$aMPosUP = ''

    while 1 

        local $hWnd = _getHoveredHwnd()
        ;~ ConsoleWrite($HWnd & "_" & $hGUImainLowPoint & @CRLF)
        if $hWnd = $hGUImain Then
            ConsoleWrite("INmain"  & @CRLF)
            GUISetState(@SW_SHOW,$hGUIbutt1 )
        else
            GUISetState(@SW_HIDE,$hGUIbutt1 )
        EndIf
        if $hWnd = $hGUImainLowPoint Then
            ConsoleWrite("INlow"  & @CRLF)
            GUISetState(@SW_SHOW,$hGUIbutt2 )
        else
            GUISetState(@SW_HIDE,$hGUIbutt2 )   
        endif

        $aMsg = GUIGetMsg(1)
        Switch $aMsg[1]
            Case $hGUImain
                Switch $aMsg[0]
                    Case $mExit
                        _WinAPI_DeleteObject($hBitmap)
                        _GDIPlus_BitmapDispose($hImage)
                        _WinAPI_DeleteObject($hBitmapL)
                        _GDIPlus_BitmapDispose($hImageL)
                        _GDIPlus_Shutdown()
                        GUIDelete()
                        Exit

                    Case $GUI_EVENT_PRIMARYUP
                        $aMPosUP = MouseGetPos()
                        if $hWnd = $hGUImain and IsArray($aMPos) and $aMPos[0] = $aMPosUP[0] and  $aMPos[1] = $aMPosUP[1] Then
                            GUISetState(@SW_SHOW,$hGUIsettings )
                        EndIf

                    Case $GUI_EVENT_PRIMARYDOWN
                        ;~ ConsoleWrite(":")
                        $aMPos = MouseGetPos()
                        _SendMessage($hGUImain, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)  ; DRAG GUI
                        _SendMessage($hGUImainLowPoint, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)  ; DRAG GUI                   
                EndSwitch
        EndSwitch

        Sleep(30)
    wend

Func _getHoveredHwnd()
    local $timer = TimerInit()
    ;controllo mouseOver GUImain e GuiButt
    If @AutoItX64 Then
        Local $tPoint = DllStructCreate("int X;int Y")
        DllStructSetData ( $tPoint, "X", MouseGetPos(0))
        DllStructSetData ( $tPoint, "Y", MouseGetPos(1))
        Local $tPoint64 = DllStructCreate("int64", DllStructGetPtr($tPoint))
        Local $aHwnd = DllCall("user32.dll", "hwnd", "WindowFromPoint", "int64", DllStructGetData($tPoint64, 1))
    Else
        Local $aHwnd = DllCall("user32.dll", "hwnd", "WindowFromPoint", "uint", MouseGetPos(0), "uint", MouseGetPos(1))
    EndIf
    If IsArray($aHwnd) Then
        Return HWnd($aHwnd[0])
    endif
    Return SetError(1, 0, 0)
EndFunc


Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

I made a BG img and another GUI image superimposed over the BG, overlapping its countors to get the different overGUI.

Actual problem is, in dragging the GUI, the 2nd GUI-img does not follow the main one, it remains fixed: I used 2x _SendMessage to the hGUIs.

Is there some overall better approach?

Here basic test Imgs:

Star.png

star_LowSpike.png

Edited by frank10
Posted

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
  • Recently Browsing   0 members

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