Jump to content

Recommended Posts

Posted (edited)

I simulated a title bar for my zPlayer in order to utilize the empty space in the title bar. That was necessary because I wanted to keep the size of the GUI to the minimum. In the case of zPlayer, the GUI was not resizable, so It did not not need the _UpdateCoverPosition( ) function. I added it as an idea if it is necessary.
 

#include <GUIConstants.au3>
#include <WinAPIGdi.au3>

Global $guiWidth = 320, $guiHeight = 100, $barColor = 0x198CFF
Global $hGUI, $borderWidth, $barHeight, $GUIPos, $ClientPos
Global $hCover, $idMinimize, $ctrlClose, $hRgn, $aMsg, $sMsg

$hGUI = GUICreate("", $guiWidth, $guiHeight, -1, -1, $WS_OVERLAPPEDWINDOW)
$GUIPos = WinGetPos($hGUI)
$ClientPos = WinGetClientSize($hGUI)
$borderWidth = ($GUIPos[2] - $ClientPos[0])/2
$barHeight = $GUIPos[3] - $ClientPos[1] - $borderWidth

$hCover = GUICreate("", $ClientPos[0]+1, $barHeight, $GUIPos[0]+$borderWidth, $GUIPos[1]+1, $WS_POPUP, -1, $hGUI)
GUISetBkColor($barColor, $hCover)
GUISetFont(12, 400, 0, "Arial")
GUICtrlCreateIcon("user32.dll", 101, 5, 5, 20, 20)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKSIZE)
GUICtrlCreateLabel("Colored Bar Example", 30, 7, 160, 20)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKSIZE)
$ctrlClose = GUICtrlCreateLabel("X", $guiWidth-40, 1, 40, $barHeight, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetBkColor(-1, $barColor)
GUICtrlSetColor(-1, 0x404040)
GUICtrlSetResizing(-1, $GUI_DOCKRIGHT+$GUI_DOCKSIZE)

GUISetState(@SW_SHOW, $hCover)
GUISetState(@SW_SHOW, $hGUI)

If @OSVersion = "WIN_11" Then   ; Create round corners for $hCover
    $hRgn = _WinAPI_CreateRoundRectRgn(0, 0, $ClientPos[0]+1, $barHeight+10, 13, 13)
    _WinAPI_SetWindowRgn($hCover, $hRgn)
    _WinAPI_DeleteObject($hRgn)
EndIf

GUIRegisterMsg($WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED")
AdlibRegister("_ColorButton", 100)

While 1
    $aMsg = GUIGetMsg(1)
    $sMsg = $aMsg[0]
    Switch $aMsg[1]
        Case $hCover
            Switch $sMsg
                Case $ctrlClose
                    ExitLoop
                Case $GUI_EVENT_PRIMARYDOWN     ; Click and drag $hCover
                    DllCall("user32.dll", "int", "SendMessageW", "hwnd", $hCover, "uint", $WM_NCLBUTTONDOWN, "wparam", $HTCAPTION, "lparam", 0)
            EndSwitch
    EndSwitch
WEnd

Func WM_WINDOWPOSCHANGED($hWnd, $MsgID, $wParam, $lParam)   ; Sync movement of $hGUI and $hCover
    #forceref $MsgID, $wParam, $lParam
    Switch $hWnd
        Case $hCover
            Local $aPos = WinGetPos($hCover)
            WinMove($hGUI, "", $aPos[0]-$borderWidth, $aPos[1]-1)
        Case $hGUI
            UpdateCoverPosition()
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func _ColorButton() ; Change background color of buttons when the mouse is over them
    Local $aArray = GUIGetCursorInfo($hCover)
    If $aArray[4] = $ctrlClose Then
        GUICtrlSetBkColor($ctrlClose, 0xC42B1C)
        GUICtrlSetColor(-1, 0xFFFFFF)
    Else
        GUICtrlSetBkColor($ctrlClose, $barColor)
        GUICtrlSetColor(-1, 0x404040)
    EndIf
EndFunc

Func UpdateCoverPosition()
    $GUIPos = WinGetPos($hGUI)
    $ClientPos = WinGetClientSize($hGUI)
    WinMove($hCover, "", $GUIPos[0]+$borderWidth, $GUIPos[1]+1, $ClientPos[0]+1, $barHeight)
    If @OSVersion = "WIN_11" Then   ; Update round corners for $hCover
        $hRgn = _WinAPI_CreateRoundRectRgn(0, 0, $ClientPos[0]+1, $barHeight+10, 13, 13)
        _WinAPI_SetWindowRgn($hCover, $hRgn)
        _WinAPI_DeleteObject($hRgn)
    EndIf
EndFunc

 

Edited by CYCho
Posted (edited)

It was pretty much tricky to match the curvature of the child window's corner to that of the parent. I tried in vain to find the Windows default $iWidthEllipse and $iHeightEllipse numbers for _WinAPI_CreateRoundRectRgn() function. According to my visual test with different numbers, 13 was the best matching number for a $WS_OVERLAPPEDWINDOW. For a popup window, it was 12. Does anyone know if Windows has this information somewhere?

Edit: This article says it is 8. But, acording to my test, 12 or 13 looks better.

Edited by CYCho
Posted

@CYCho, testing on Windows 7, the resize does not function correctly - the title bar does not resize while the edge is dragged, only when the drag ends.

Signature - my forum contributions:

Spoiler

UDF:

LFN - support for long file names (over 260 characters)

InputImpose - impose valid characters in an input control

TimeConvert - convert UTC to/from local time and/or reformat the string representation

AMF - accept multiple files from Windows Explorer context menu

DateDuration -  literal description of the difference between given dates

Apps:

Touch - set the "modified" timestamp of a file to current time

Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes

SPDiff - Single-Pane Text Diff

 

Posted (edited)

@orbs good test :)

@CYCho this should fix it, by replacing Func WM_WINDOWPOSCHANGED with this one :

Func WM_WINDOWPOSCHANGED($hWnd, $MsgID, $wParam, $lParam)   ; Sync movement of $hGUI and $hCover
    #forceref $MsgID, $wParam, $lParam
    Switch $hWnd
        Case $hCover
            Local $aPos = WinGetPos($hCover)
            WinMove($hGUI, "", $aPos[0]-$borderWidth, $aPos[1]-1)
        Case $hGUI
            UpdateCoverPosition()
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

After that, you shouldn't need this part in main loop :

;~         Case $hGUI
;~             If $sMsg = $GUI_EVENT_RESIZED Then
;~                 UpdateCoverPosition()
;~             EndIf
Edited by pixelsearch

"I think you are searching a bug where there is no bug..."

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