Sign in to follow this  
Followers 0
-Ultima-

GUICtrlSetStyle() unhides hidden control...

9 posts in this topic

#1 ·  Posted (edited)

The topic title pretty much sums up the problem I'm having. When I have a hidden control, and I set the style on the control, it magically unhides itself. I'm not sure if that's to be expected, but I guess can see why it would unhide itself when its style gets changed (since a style is a presentation thing). When this is all combined with tab controls, though, the problem jumps to a somewhat higher level of annoyance.

The thing is, in normal situations, if I use GUICtrlSetStyle() and it unhides a control, I can always hide the control again using GUICtrlSetState() with $GUI_HIDE (albeit with a bit of a flicker). With tab controls (which inherently hide controls that aren't in the active page), though, if I set the state on a control in an inactive/hidden tab, that control suddenly pops in front of all of the other controls on the active tab.

I can try hiding the control again, but then that'd (theoretically) cause the control to be hidden when I switch back to its containing tab page. What's odd, though, is how GUICtrlSetState() with $GUI_HIDE doesn't even work properly in this situation either. The control I manually hide isn't actually hidden until I switch back and forth between its container tab and another tab twice. See the following example:

#Include <GUIConstantsEx.au3>
#Include <ListViewConstants.au3>

Global $iWidth = 108, $iHeight = 120

GUICreate("", $iWidth, $iHeight)

GUICtrlCreateTab(5, 5, $iWidth - 10, $iHeight - 35)
    GUICtrlCreateTabItem("Visible")
        Global $ListView = GUICtrlCreateListView("ListView", 10, 30, $iWidth - 20, $iHeight - 65)
    GUICtrlCreateTabItem("Invisible")
        GUICtrlSetState(-1, $GUI_SHOW)
    GUICtrlCreateTabItem("")

Global $Button = GUICtrlCreateButton("Button", 5, $iHeight - 25, $iWidth - 10, 20)

GUISetState()
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            GUICtrlSetStyle($ListView, $LVS_REPORT)
            GUICtrlSetState($ListView, $GUI_HIDE)
    EndSwitch
WEnd

My question here is: how do I get around this problem? I've tried playing around with a ton of things, but to no avail. My first reaction was that it was possibly a problem specific to AutoIt's implementation of GUICtrlSetStyle(), so I took the manual route and used GetWindowLong/SetWindowLong instead, but the problem persisted even using native Win32 APIs.

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I found a messy solution. If the tab that you want is currently open it sets the style just like it's supposed to. If not, it tells the program to do it as soon as you click the one that has the listview.

I added the $NO_HEADERS thingy just so you can actually see when it's changing.

#Include <GUIConstantsEx.au3>
#Include <ListViewConstants.au3>
#include <WindowsConstants.au3>; <--- ADDED
#include <GuiTab.au3>; <--- ADDED

Global $iWidth = 208, $iHeight = 220

Global $pendingSetStyle = False; <--- ADDED

GUICreate("", $iWidth, $iHeight)

$tab = GUICtrlCreateTab(5, 5, $iWidth - 10, $iHeight - 35)
    GUICtrlCreateTabItem("Visible")
        Global $ListView = GUICtrlCreateListView("ListView", 10, 30, $iWidth - 20, $iHeight - 65)
    GUICtrlCreateTabItem("Invisible")
;~       GUICtrlSetState(-1, $GUI_SHOW)
    GUICtrlCreateTabItem("")

Global $Button = GUICtrlCreateButton("Button", 5, $iHeight - 25, $iWidth - 10, 20)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY"); <--- ADDED 

GUISetState()
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            If GUICtrlRead($tab) = 0 then 
                GUICtrlSetStyle($ListView, $LVS_REPORT)
                GUICtrlSetStyle($ListView, $LVS_NOCOLUMNHEADER)
            Else 
                $pendingSetStyle = True 
            EndIf 
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTab
    $hWndTab = $tab
    If Not IsHWnd($tab) Then $hWndTab = GUICtrlGetHandle($tab)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndTab
            Switch GUICtrlRead($tab) 
                Case 0; Visible 
                    If $pendingSetStyle then GUICtrlSetStyle($ListView, $LVS_REPORT) 
                    If $pendingSetStyle then GUICtrlSetStyle($ListView, $LVS_NOCOLUMNHEADER) 
                    $pendingSetStyle = False 
                    
            EndSwitch 
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Edited by Ichigo

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites

-Ultima-

Example:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListViewConstants.au3>

Global $iWidth = 108, $iHeight = 120

$hGUI = GUICreate("", $iWidth + 5, $iHeight)

GUICtrlCreateTab(5, 5, $iWidth - 5, $iHeight - 35)

GUICtrlCreateTabItem("Visible")

$ListView = GUICtrlCreateListView("ListView", 10, 30, $iWidth - 20, $iHeight - 65)
GUICtrlSetState($ListView, $GUI_HIDE)

$hListView = GUICtrlGetHandle($ListView)
ShowWindow($hListView, @SW_HIDE)

GUICtrlCreateTabItem("Invisible")
GUICtrlSetState(-1, $GUI_SHOW)

GUICtrlCreateTabItem("")

$Button = GUICtrlCreateButton("Style", 5, $iHeight - 25, 50, 20)

$Button_Show = GUICtrlCreateButton("Show", 60, $iHeight - 25, 50, 20)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            GUICtrlSetStyle($ListView, $LVS_REPORT)
            GUICtrlSetState($ListView, $GUI_HIDE)
            ShowWindow($hListView, @SW_HIDE)
        Case $Button_Show
            GUICtrlSetState($ListView, $GUI_SHOW)
    EndSwitch
WEnd

Func ShowWindow($hWnd, $nState)
    DllCall("User32.dll", "int", "ShowWindow", _
                                "hwnd", $hWnd, _
                                "int", $nState)
EndFunc

:)

Share this post


Link to post
Share on other sites

@raism: Hah, that's an elegant solution (relative to everything I've tried so far xD). Much thanks to you!

@Ichigo: Thanks for the alternative solution :) It is indeed messier than I would like, but works better than anything I've come up with :o

Thanks again to both of you!


[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites

@raism: Hah, that's an elegant solution (relative to everything I've tried so far xD). Much thanks to you!

@Ichigo: Thanks for the alternative solution :) It is indeed messier than I would like, but works better than anything I've come up with :o

Thanks again to both of you!

I fix for the next beta for now you can also select the visible tabitem and unselect it right away

Case $Button
           GUICtrlSetStyle($ListView, $LVS_REPORT)
           GUICtrlSetState($visible, $GUI_SHOW)
           GUICtrlSetState($invisible, $GUI_SHOW)

Happy new year :D

Share this post


Link to post
Share on other sites

I fix for the next beta for now you can also select the visible tabitem and unselect it right away

Case $Button
           GUICtrlSetStyle($ListView, $LVS_REPORT)
           GUICtrlSetState($visible, $GUI_SHOW)
           GUICtrlSetState($invisible, $GUI_SHOW)

Happy new year :o

Nice solution! :)

Share this post


Link to post
Share on other sites

Nice solution! :)

I would have say go around ...

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I thought of a similar workound while playing with this, but raism's workaround is actually preferrable to me, as it incurs a smaller amount of repainting (I have several controls on each tab). Also, I have more than 2 tabs, and I don't really ever know immediately (without having to test again, or clunkily storing the tab on change) which tab is activated when the user runs the function that calls GUICtrlSetStyle(), so it's slightly annoying to switch tabs and switch back to the current active tab.

Glad to hear it'll be fixed in a future version though! I wasn't too sure whether this would be classified as a valid bug, so I decided to post in this subforum instead. Too bad I probably won't be able to use the next version for this project I'm working on due to dropped support for Windows 9x (I'm even stuck on 3.2.12.1 for the same reason), but good enough :)

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Share this post


Link to post
Share on other sites

I thought of a similar workound while playing with this, but raism's workaround is actually preferrable to me, as it incurs a smaller amount of repainting (I have several controls on each tab). Also, I have more than 2 tabs, and I don't really ever know immediately (without having to test again, or clunkily storing the tab on change) which tab is activated when the user runs the function that calls GUICtrlSetStyle(), so it's slightly annoying to switch tabs and switch back to the current active tab.

Glad to hear it'll be fixed in a future version though! I wasn't too sure whether this would be classified as a valid bug, so I decided to post in this subforum instead. Too bad I probably won't be able to use the next version for this project I'm working on due to dropped support for Windows 9x (I'm even stuck on 3.2.12.1 for the same reason), but good enough :)

I understand I hope my fix will not produce too much flickering if any.

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