Sign in to follow this  
Followers 0
qwert

Problem with using graphic as transparent button

8 posts in this topic

I have a script that uses transparent graphic controls as buttons overlaid on a static background. Apparently it's a commonly used technique, but I've encountered a problem that wasn't mentioned in any of the examples:

The response times on successive clicks of the "graphic buttons" is proving to be unacceptable. A normal button is fast -- click 10 times rapidly on a "input one character" button and you get 10 characters. A graphic button is slow -- trying to click even twice in a row misses the second click. Pausing slightly (1/2 second?) between clicks allows each click to be received.

Is there some default setting that can explain this? Or is this normal behaviour? There just seems to be a pause that occurs between mouse clicks -- yet all of those parameters are set to their defaults (10) and the WinWaitDelay is 10. The button definition is simply:

$button = GUICtrlCreateGraphic( 15, 60, 40, 20)

If there's a way to define a true button that's transparent, I haven't found it -- but that would certainly be the solution.

I will certainly appreciate any help solving this. Thanks in advance.

Share this post


Link to post
Share on other sites



Perhaps it is seeing the rapid clicks as double clicks? So instead of getting *click click click click* it's getting *double click... double click...* This was a problem with the button control once before.

If you get what I'm saying.

Are you drawing on the graphic control at all? Cus I kind of got the idea that you aren't (if I'm wrong, ignore this part), perhaps you could just use a label control instead?

Share this post


Link to post
Share on other sites

Here's an adaptation of a script from a previous topic ("Making a graphic control act like a button") that demonstrates the behavior I've described:

;   A comparison of the response of a "clickable graphic" and a normal button
;
;   The normal button response is immediate; the graphic is slow
;
;   (click each button five times in succession to see the difference)
;
;
#include <GUIConstants.au3>

GUICreate("Graphic Example", 200, 177, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

GUICtrlCreatePic(@Systemdir & "\oobe\images\mslogo.jpg", -1, -1, 200, 50)
GUICtrlSetState(-1, $GUI_DISABLE)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 160, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateGraphic(33, 14, 40, 30, $SS_NOTIFY + $SS_WHITEFRAME)
GUICtrlSetTip(-1, "Grahic Button")

$Graphic2 = GUICtrlCreateButton("", 74, 14, 48, 30, $SS_NOTIFY + $SS_WHITEFRAME)
GUICtrlSetTip(-1, "Normal Button")

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $Graphic1
;           MsgBox(0, "Which was clicked on?", "Graphic around Win")
            GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
        Case $Graphic2
;           MsgBox(0, "Which was clicked on?", "Graphic around dows")
            GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "Y" )
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

And there was another surprise during my testing: Adding GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) causes a normal button to become sluggish!

I would certainly like to understand what's behind this behavior -- and know if there's any way around it.

Thanks for your help.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Yes, it has to do with double click notifications, but the problem is not what you think. Give GUICtrlCreateButton in your example the BS_NOTIFY style and see what happens. The update becomes the same "sluggish" as for static controls, because this enables BN_DBLCLK notification, and the rapid clicks are seen as double clicks. Button without BS_NOTIFY processes all clicks as single clicks, and that's why it's so fast. And AutoIt's control events are triggered by single click.

Here's your example made fast:

#include <GUIConstants.au3>

GUICreate("Graphic Example", 200, 177, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

GUICtrlCreatePic(@Systemdir & "\oobe\images\mslogo.jpg", -1, -1, 200, 50)
GUICtrlSetState(-1, $GUI_DISABLE)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 160, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateGraphic(33, 14, 40, 30, $SS_NOTIFY + $SS_WHITEFRAME)
GUICtrlSetTip(-1, "Grahic Button")

$Graphic2 = GUICtrlCreateButton("", 74, 14, 48, 30, $SS_WHITEFRAME)
GUICtrlSetTip(-1, "Normal Button")

GUIRegisterMsg($WM_COMMAND, "On_WM_COMMAND")
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $Graphic1
;            MsgBox(0, "Which was clicked on?", "Graphic around Win")
;~             GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
        Case $Graphic2
;            MsgBox(0, "Which was clicked on?", "Graphic around dows")
            GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "Y" )
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc
Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thanks very much for your response.

So, does the following summarize the situation correctly?

Buttons are fast because they get $SS_NOTIFY by default

Graphics are slow because they get $BS_NOTIFY by default

Graphics can be made fast by adding $SS_NOTIFY to the create

EDIT: and include the function On_WM_COMMAND

The reason I ask it this way is that I tried just adding $SS_NOTIFY to a graphic on my main script and it didn't help -- although I certainly can see the result in the example you posted. Is there something else I should consider? Or is there a way to force $BS_NOTIFY to "off" in case it is somehow "on"?

EDIT: Sorry, I posted too soon. I just realized the purpose of the additional function, On_WM_COMMAND.

By including it, the responses in my main script are exactly the same as with a normal button. The problem is resolved!

THANKS.

Edited by qwert

Share this post


Link to post
Share on other sites

Post script to the above

For more information about the defined function, refer to the documentation for GUIRegisterMsg

... and also to the excellent discussion on: topic

Share this post


Link to post
Share on other sites

So, does the following summarize the situation correctly?

The reason I ask it this way is that I tried just adding $SS_NOTIFY to a graphic on my main script and it didn't help -- although I certainly can see the result in the example you posted. Is there something else I should consider? Or is there a way to force $BS_NOTIFY to "off" in case it is somehow "on"?

Not quite.

- $SS_NOTIFY is not a valid button style at all, just like $BS_NOTIFY is not a valid style for static controls (AutoIt Pic, Graphic, Label). I think this is self-explanatory. Each common control has its own style constants. SS_ means Static style. BS_ means Button style. SS <> BS. I'm confused why would anyone get confused. Styles shared by all controls start with WS_, which means Window style.

- AutoIt Buttons are "fast" because they don't get $BS_NOTIFY by default (despite what helpfile says). Buttons send single click notifications even without that style, which is their advantage compared to Static controls:

- Static controls must have $SS_NOTIFY style in order to send any kind of click notifications. AutoIt static controls already have $SS_NOTIFY set by default. Which means they send both singleclick and doubleclick notifications to their parent.

- AutoIt GUI control events are triggered only by single clicks. So in order to make static controls "fast", you have to handle doubleclicks somehow too. Which is what is done in the example above, handling WM_COMMAND notifications sent by $Graphic1 (in that example single clicks are handled there too, so $Graphic1 case in GuiGetMsg() loop isn't needed anymore).

Setting BS_USERBUTTON, BS_RADIOBUTTON, and BS_OWNERDRAW styles also make a button send double click notifications. Which is what GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) did for you - AutoIt achieves transparency by owner-drawing the button.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

OK. Wow. Just when I thought I was close to understanding, there's more to consider.

Maybe I'd better restate my objective: to have clickable (with fast response) transparent buttons that are placed on top of a background graphic.

So what's my best bet for achieving that? A transparent label with $SS_NOTIFY, plus the WM_COMMAND function? I thought it was, but now I'm less than certain.

Share this post


Link to post
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
Sign in to follow this  
Followers 0