Jump to content

Recommended Posts

Posted

By popular demand, updated UDF in the first post.

  • Added support for multi-line buttons using the $BS_MULTILINE button style
  • Added ellipses when text is longer than the button
  • Fixed compatibility with Opt("MustDeclareVars", 1)
  • Added an example for the $BS_MULTILINE style
  • 1 month later...
Posted

@kurtykurtyboy Very nice UDF. I want to use it to display some flat buttons that have an icon only, no text. I omitted the $style parameter of the GuiFlatButton_Create function since I want the icon centered on the button.

Global $idBrowse = GuiFlatButton_Create("", 0, 0, 66, 66)
GUICtrlSetImage($idBrowse, "BrowseFolders.ico")

In this case my button is 66 x 66 and my icon is 48 x 48. The icon is correctly centered top to bottom on the button but it's leaving less space at the left than the right.

image.png.e0b7621e8f6b79cb802d8c8d94ea3153.png

I've examined the code for the GuiFlatButton_DrawButton function and am curious about this formula for calculating the $iIconX value:

$iIconX = ($iRight - $iLeft) / 2 - ($iTextWidth + $bmWidth + 2) / 2 - 1

In my case this formula is returning a value of 7, since (66 - 0) / 2 - (0 + 48 + 2) / 2 - 1 = 7

But the correct value in order to center my icon on the button would be 9. So my icon is 2 pixels too far to the left.

Is there some reason you don't just the same formula for $iIconX when no style is specified as you use for the $bToolButton style?

ElseIf $bToolButton Then
    $iIconX = ($iRight - $iLeft) / 2 - $bmWidth / 2
    $iIconY = ($iBottom - $iTop) / 2 - ($iTextHeight + $bmHeight) / 2
Else
    $iIconX = ($iRight - $iLeft) / 2 - ($iTextWidth + $bmWidth + 2) / 2 - 1
    ; Why not this? --> $iIconX = ($iRight - $iLeft) / 2 - $bmWidth / 2
    $iIconY = $iButtonH / 2 - $bmHeight / 2
EndIf

When I make that change to the code, my icon is now centered correctly both ways.

image.png.1254cf3a88b6b13fc82a114983380a30.png

I haven't tried this with an $IMAGE_BITMAP type of image on the button, just an $IMAGE_ICON, but the same odd formula for $iIconX is used in both cases so if that is indeed confirmed to be a bug it needs to be fixed in both places in the GuiFlatButton_DrawButton function code.

Posted

I've run into another little quirk with this handy UDF that, while not a deal-breaker, does need require a little work-around.

I'm using the flat buttons in an app that will have more than one GUI, so I use the advanced form of the GUIGetMsg call to distinguish which GUI I'm receiving messages for.

Assume that in $hGUI_Main I've created 3 controls consisting of 2 of these GuiFlatButton controls, as well as 1 regular button control.

So the bare bones of my GUIGetMsg routine looks something like this:

Do
    Local $Msg = ""
    Local $aMsg = GUIGetMsg(1)
        ; returns an array with extended info
        ; $aMsg[0] = 0 or Event ID or Control ID
        ; $aMsg[1] = The window handle the event is from
        ; $aMsg[2] = The control handle the event is from (if applicable)
        ; $aMsg[3] = The current X position of the mouse cursor (relative to the GUI window)
        ; $aMsg[4] = The current Y position of the mouse cursor (relative to the GUI window)
    Local $MsgNum = $aMsg[0]
    Switch $aMsg[1]
        Case 0
            ; no GUI events
        Case $hGUI_Main ; messages for the primary GUI
            Switch $MsgNum
                Case $idGuiFlatBtn1  ; <-- never gets triggered
                    $Msg = "Clicked GuiFlatBtn1"
                Case $idGuiFlatBtn2  ; <-- never gets triggered
                    $Msg = "Clicked GuiFlatBtn2"
                Case $idNormalBtn  ; <-- gets triggered as expected
                    $Msg = "Clicked NormalBtn"
            EndSwitch
            If $Msg <> "" Then ConsoleWrite($Msg & "  [" & _ArrayToString($aMsg) & "]" & @CRLF)
        Case $hGUI_2 ; messages for the secondary GUI
            ConsoleWrite("Event in secondary GUI  [" & _ArrayToString($aMsg) & "]" & @CRLF)
        Case Else
            ; This is where the click events for the GuiFlatBtn controls fall
            ; since they aren't tagged to one of my known GUI handles.
            ConsoleWrite("-Event in GUI with hWnd: " & $aMsg[1] & "  [" & _ArrayToString($aMsg) & "]" & @CRLF)
    EndSwitch

Until $aMsg[1] = $hGUI And $MsgNum = $GUI_EVENT_CLOSE

GUIDelete()
Exit

The problem is that the GuiFlatButton controls aren't parented to the GUI I created them on. Each is parented on its own child-GUI, which makes getting the events for them a bit messy in a multi-GUI app. Apparently from the UDF source code, this is to facilitate the necessary subclassing of each control.

To work around this issue, I modified my GUIGetMsg routine by changing this line:

Case $hGUI_Main ; messages for the primary GUI

to

Case $hGUI_Main, _WinAPI_GetParent(GUICtrlGetHandle($idGuiFlatBtn1)), _WinAPI_GetParent(GUICtrlGetHandle($idGuiFlatBtn1))

That change makes the events for the GuiFlatButtons get triggered as expected.

Obviously it would be better to save each of those parent hWnds in variables one time when the GuiFlatButtons are created rather calling the _WinAPI_GetParent function a zillion times while the code is running, but you get the idea.

  • 7 months later...
Posted

GUICtrlSetResizing is not working with these buttons. Every other control stays in place, but these buttons stretch and move.

GUICtrlSetResizing(-1, $GUI_DOCKSIZE+$GUI_DOCKBOTTOM+$GUI_DOCKLEFT) has no effect.

Any solution or workaround?

Posted (edited)

@Champak Do you have an example script to show this behavior? If I run the following, none of the buttons move or stretch. Since each button is technically on its own child window, I would expect them to never move with window resizing.

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include "GuiFlatButton.au3"
Opt("GUIResizeMode", 4)
Example()

;GUI with one button
Func Example()

    Local $hGUI, $mybutton1

    $hGUI = GUICreate("GuiFlatButton Ex0", 275, 120, -1, -1, BITOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
    GUISetBkColor(0x333333)


    Local $idLabel = GUICtrlCreateLabel("Click the button", 10, 100, 150, 30)
    GUICtrlSetColor(-1, 0xFFFFFF)

    ;create new button then set the background and foreground colors
    $mybutton1 = GuiFlatButton_Create("Button 1" & @CRLF & "Line 2", 78, 20, 120, 40, $BS_MULTILINE)
    GuiFlatButton_SetBkColor(-1, 0x5555FF)
    GuiFlatButton_SetColor(-1, 0xFFFFFF)

    GUISetState(@SW_SHOW, $hGUI)

    Local $i = 0
    Local $iMsg
    While 1
        $iMsg = GUIGetMsg()

        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $mybutton1
                $i += 1
                GUICtrlSetData($idLabel, $i)
                ConsoleWrite($i & @CRLF)
        EndSwitch

        Sleep(10)
    WEnd

    GUIDelete()
EndFunc   ;==>Example

 

Edited by kurtykurtyboy
Posted

I don't remember what I did to get it to stretch because I was just trying different combos to get it to work...or maybe I was seeing one of the older buttons stretch and didn't realize, but if you look at my adjusted example, it won't dock to the bottom.

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include "GuiFlatButton.au3"
Opt("GUIResizeMode", 4)
Example()

;GUI with one button
Func Example()

    Local $hGUI, $mybutton1

    $hGUI = GUICreate("GuiFlatButton Ex0", 325, 120, -1, -1, BITOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
    GUISetBkColor(0x333333)


    Local $idLabel = GUICtrlCreateLabel("Click the button", 10, 100, 150, 30)
    GUICtrlSetColor(-1, 0xFFFFFF)

    ;create new button then set the background and foreground colors
    $mybutton1 = GuiFlatButton_Create("Button 1" & @CRLF & "Line 2", 180, 20, 120, 40, $BS_MULTILINE)
    ;GUICtrlSetResizing(-1, $GUI_DOCKSIZE+$GUI_DOCKBOTTOM+$GUI_DOCKLEFT)
    GuiFlatButton_SetBkColor(-1, 0x5555FF)
    GuiFlatButton_SetColor(-1, 0xFFFFFF)


    GUICtrlCreateButton("Button 2", 0, 20, 120, 40)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE+$GUI_DOCKBOTTOM+$GUI_DOCKLEFT)

    GUISetState(@SW_SHOW, $hGUI)

    Local $i = 0
    Local $iMsg
    While 1
        $iMsg = GUIGetMsg()

        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $mybutton1
                $i += 1
                GUICtrlSetData($idLabel, $i)
                ConsoleWrite($i & @CRLF)
        EndSwitch

        Sleep(10)
    WEnd

    GUIDelete()
EndFunc   ;==>Example

 

Posted

Since each button lives on its own child window, it isn't going to work with GUICtrlSetResizing. It could be done with some fancy manipulations though...

Might be a fun challenge. I'll get back to you on that.

  • 2 months later...
Posted

Hello!

You can find lots of great things here in the forum. Thanks for this nice code.

I have a little wish:

The first twelve buttons should form their own group. The first button should already be clicked when the GUI loads. Can you also group buttons so that when you click "QR-Code generieren" the first 12 buttons retain their current status? Thanks!

Greetings, René

 

 

qr-menue.png

qrgen_test.zip

Posted

 

 

ControlClick($hWnd, "", $btTab1)

47 minutes ago, mumpel said:

The first button should already be clicked when the GUI loads.

This problem is solved: ControlClick($hWnd, "", $btTab1)

  • 1 month later...
Posted (edited)

GuiFlatButton_SetState(-1, $gui_focus) doesn't seem to work.

Specifically, when I had guictrlsetstate on a regular button and my app started, when I hit the enter button, the button was activated. That is not happening with the buttons from this udf.

Edited by Champak

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
×
×
  • Create New...