Jump to content

GuiFlatButton UDF : Change Colors of Regular Buttons


kurtykurtyboy
 Share

Recommended Posts

Thanks for chiming in.

I want to add a couple of things to this puzzle:

First, I've now used the Au3 Inspection Tool to confirm that, indeed, the buttons are completely gone from the GUI. What were (initially ) identified as "Button 1, 2, 3 ... etc., don't show anything at all, once they've disappeared.

Second, I opened the FlatButton UDF, itself, and found this ominous line of code:

OnAutoItExitRegister("GUIFlatButton_Exit")

This button exit function specifically deletes each of a GUIs defined buttons. Given that Au3's function can be triggered by any of 5 different actions, it opens the possibility (to me) of some extraneous operation within the FlatButton UDF.

So I have to ask: Do Flat Buttons require the _Exit? ... or will they be deleted by the normal Au3 GUI close processing?

Link to comment
Share on other sites

After much testing, I can add a couple more findings:

OnAutoItExitRegister("GUIFlatButton_Exit")  does not appear to be a problem. I removed it and added the delete button call to my _Exit() and the buttons still disappear.

But I have now isolated a main suspect. One of the functions of my GUI creates and then deletes a $WS_POPUP overlay window that is defined as an MDI_CHILD window. After that function has been used, the flat buttons always disappear the next time I try to drag the main GUI to a new position on the desktop. Without the drag GUI action, the flat buttons are fine and work properly. But any subsequent drag causes the buttons to immediately disappear.

This is about as strange as anything I've ever encountered with Au3. I'm trying different combinations of CLIP_CHILDREN and CLIPSIBLINGS, but so far, nothing helps.

Link to comment
Share on other sites

With a couple more hours of effort, I now have a workaround.

First, I've concluded that there's some deep-seated problem with the way MDI Child Windows are managed when they're deleted. I was using the MDI child method for a small overlay panel that my GUI uses. It worked well because it would overlay whatever was defined under it on the main GUI (... which happen to be Flat Buttons). As I stated, previously, the problem was that when I was finished with the overlay panel and deleted it, the Flat Buttons were deleted upon the first drag action of the Main GUI.

My workaround is this: before creating my overlay panel, I use GuiFlatButton_SetState to hide the buttons that are under the panel. I then create the panel as a simple Child window (not an MDI Child). I then delete the panel and $GUI_SHOW the hidden buttons. Everything now works fine.

Unless someone poses at clean solution, I'll use this method and consider the problem solved. (And, BTW, searches on this forum revealed there are enough fringe problems with MDI Child Windows to give one doubts about using them in any situation beyond the simplest ones.)

Link to comment
Share on other sites

On 4/26/2021 at 12:57 AM, qwert said:

With a couple more hours of effort, I now have a workaround.

First, I've concluded that there's some deep-seated problem with the way MDI Child Windows are managed when they're deleted. I was using the MDI child method for a small overlay panel that my GUI uses. It worked well because it would overlay whatever was defined under it on the main GUI (... which happen to be Flat Buttons). As I stated, previously, the problem was that when I was finished with the overlay panel and deleted it, the Flat Buttons were deleted upon the first drag action of the Main GUI.

My workaround is this: before creating my overlay panel, I use GuiFlatButton_SetState to hide the buttons that are under the panel. I then create the panel as a simple Child window (not an MDI Child). I then delete the panel and $GUI_SHOW the hidden buttons. Everything now works fine.

Unless someone poses at clean solution, I'll use this method and consider the problem solved. (And, BTW, searches on this forum revealed there are enough fringe problems with MDI Child Windows to give one doubts about using them in any situation beyond the simplest ones.)

please put your sample code

Link to comment
Share on other sites

  • 2 months later...
On 4/25/2021 at 10:35 AM, qwert said:

But I have now isolated a main suspect. One of the functions of my GUI creates and then deletes a $WS_POPUP overlay window that is defined as an MDI_CHILD window. After that function has been used, the flat buttons always disappear the next time I try to drag the main GUI to a new position on the desktop. Without the drag GUI action, the flat buttons are fine and work properly. But any subsequent drag causes the buttons to immediately disappear.

Sorry, just seeing this now. If you don't mind posting some example code showing the issue, I would be happy to take a look at it.

Link to comment
Share on other sites

  • 1 month later...

FYI, I confirmed the issue where the buttons are deleted after a $WS_EX_MDICHILD window is deleted, but I could not figure it out yet.

I was certain I had a reproducer script, but now I can't get it to do it again!

@qwert does this example work for you?

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include "GuiFlatButton.au3"

Example()

Func Example()
    Local $hGUI, $idLabel, $mybutton1

    $hGUI = GUICreate("GuiFlatButton Ex1", 300, 600)
    GUISetBkColor(0x444444)

    ;create new button then set the colors
    $mybutton1 = GuiFlatButton_Create("Button 1", 10, 10, 140, 40)
    GuiFlatButton_SetBkColor(-1, 0x777777)
    GuiFlatButton_SetColor(-1, 0xFFFFFF)

;~     $mybutton2 = GuiFlatButton_Create("Button 1", 10, 100, 140, 40)
;~     GuiFlatButton_SetBkColor(-1, 0x777777)
;~     GuiFlatButton_SetColor(-1, 0xFFFFFF)

    GUISetState(@SW_SHOW, $hGUI)

    $hchild = GUICreate("", 150, 200, 5, 250, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
    GUISetBkColor(0x0000FF)
    GUISetState(@SW_SHOWNOACTIVATE, $hchild)

;~  Sleep(5000)
;~  GUIDelete($hchild)

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

        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $mybutton1
;~                 GUIDelete($hchild)
                ConsoleWrite($i & @CRLF)
                $i += 1

        EndSwitch

        Sleep(10)
    WEnd

    GUIDelete()
EndFunc   ;==>Example

 

Edited by kurtykurtyboy
updated test script
Link to comment
Share on other sites

Interesting... same thing happens to me. I modified the test to increment a counter on button press. Even after the buttons disappear, I can keep hitting spacebar to keep counting. This means the buttons still exist but there must be something funky with my drawitem logic.

Link to comment
Share on other sites

Well I discovered the problem, but not the cause. It appears that moving the window over the tiniest amount causes the buttons to fly way off the screen.

Here are the positions. 0 is before I moved the window. 1 is after I moved the window. Removing the $WS_EX_MDICHILD extended style makes it behave as expected. There must be something strange happening internally. I think I have a workaround but will need to test later.

0:   X:821  Y:248  W:140  H:40
1:   X:5744  Y:1676  W:140  H:40

 

Link to comment
Share on other sites

First post updated with a graceful workaround to the MDI child issue. I am intercepting the $WM_WINDOWPOSCHANGING message to 'block' any position changing unless it is an intentional move by the GuiFlatButton_SetPos function.

 

@qwert It is looking like your initial guess of some deep-rooted internal AutoIt logic may be the cause. If you run this example and drag the window around, you can see the 2nd regular child window immediately disappears and the "MDI" child has a sort of shadow effect while dragging. I know the help docs say this is a simulation of MDI child, so my theory is AutoIt is continuously changing the MDI window position, trying to keep up with the parent window while dragging. Hence the shadow effect. It seems that somewhere in the logic, the other child windows are getting their positions thrown out of whack. However, my flat button does just beautifully now!

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include "GuiFlatButton.au3"

Example()

Func Example()
    Local $hGUI, $idLabel, $mybutton1

    $hGUI = GUICreate("GuiFlatButton MDI Example", 400, 600)
    GUISetBkColor(0x444444)
    ConsoleWrite("GUI Handle: " & $hGUI & @CRLF)

    ;create new button then set the colors
    $mybutton1 = GuiFlatButton_Create("Button 1", 10, 10, 140, 40)
    GuiFlatButton_SetBkColor(-1, 0x777777)
    GuiFlatButton_SetColor(-1, 0xFFFFFF)


    GUISetState(@SW_SHOW, $hGUI)

    ;create an MDI child window
    $hchild = GUICreate("", 150, 200, 5, 250, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
    GUISetBkColor(0x0000FF)
    GUISetState(@SW_SHOWNOACTIVATE, $hchild)

    ;create a 'normal' child window
    Local $childHWND = GUICreate("", 150, 200, 210, 250, BitOR($WS_CHILD, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS), $WS_EX_CONTROLPARENT, $hGUI)
    GUISetState(@SW_SHOWNOACTIVATE, $childHWND)

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

        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $mybutton1
                $aPos = GuiFlatButton_GetPos($mybutton1)
                ConsoleWrite($i & ": " & "  X:" & $aPos[0] & "  Y:" & $aPos[1] & "  W:" & $aPos[2] & "  H:" & $aPos[3] & @CRLF)
                $i += 1

        EndSwitch

        Sleep(10)
    WEnd

    GUIDelete()
EndFunc   ;==>Example

 

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 months later...

First I'd like to thank you for creating this UDF. It's simple to use and provides the perfect alternative to the buttons we have.

However I have an issue where if I use a background image for a GUI the button does not render until I hover over it with a mouse. The button would also disappear until hovered over if I were to update the background picture. This applies to buttons with enabled and disabled state, but disabled ones won't draw at all until enabled first.

Is there a solution to this? I've tried redrawing the window but it doesn't work.

#include <GUIConstantsEx.au3>
#include <GuiFlatButton.au3>

$hGUI = GUICreate('test', 100, 100, -1, -1, $WS_POPUP + $WS_BORDER)
GUICtrlCreatePic('C:\Windows\Web\Wallpaper\Windows\img0.jpg', 0, 0, 80, 100)
GUICtrlSetState(-1, $GUI_DISABLE)

GuiFlatButton_Create('test', 10, 40, 100, 20, $BS_LEFT)

GUISetState(@SW_SHOW, $hGUI)

While 1
    Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI)
                Exit
        EndSwitch
    Sleep(10)
WEnd

 

Link to comment
Share on other sites

@NMS,

I'm not sure exactly what is causing this issue, but here are 2 workarounds. More investigation is required to create a proper fix...


Option 1: create the GUI with the $WS_EX_COMPOSITED extended style

$hGUI = GUICreate('test', 100, 100, -1, -1, BITOR($WS_POPUP, $WS_BORDER), $WS_EX_COMPOSITED)


Option 2: redraw the button AFTER showing the GUI with GUISetState

$buttonID = GuiFlatButton_Create('test', 10, 40, 100, 20, $BS_LEFT)

GUISetState(@SW_SHOW, $hGUI)
_WinAPI_RedrawWindow(GUICtrlGetHandle($buttonID))


Hope this helps.

Link to comment
Share on other sites

Hi @NMS & @kurtykurtyboy
A few months ago, we discussed this overlapping controls issue with @jpm in Trac Ticket #3877

A workable solution is to create the background pic control with a $WS_CLIPSIBLINGS style, changing this line of code in NMS script...

; GUICtrlCreatePic('C:\Windows\Web\Wallpaper\Windows\img0.jpg', 0, 0, 80, 100)

...to this :

#include <StaticConstants.au3>
...
GUICtrlCreatePic('C:\Windows\Web\Wallpaper\Windows\img0.jpg', 0, 0, 80, 100, BitOR($GUI_SS_DEFAULT_PIC, $WS_CLIPSIBLINGS))

Now the button is immediately visible when the GUI is displayed
Hope it helps

Link to comment
Share on other sites

Thank you both for the responses!

In my case the solution with adding $WS_EX_COMPOSITED style to the main GUI works better as I also change that background image further down the code and this doesn't cause the elements to disappear.

Adding BitOR($GUI_SS_DEFAULT_PIC, $WS_CLIPSIBLINGS) to the picture control works but only with the enabled controls. I have some buttons that have $GUI_DISABLE state from the beginning and they don't render.

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

×
×
  • Create New...