Disable PanelGadget tabs?

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Disable PanelGadget tabs?

Post by PB »

Anyone know how to disable a PanelGadget tab? (I did a search here for
"disable tab" and nothing relevant was found).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I wasn't able to find any API to disable a tab, but I did come up with a quick way to prevent a tab from being selected. If you want more control of the appearance, you'll have to ownerdraw your PanelGadget. ;)

Code: Select all

#WinMain = 0
#MyPanel = 0

Global oldCallback

; --> SubClass procedure for PanelGadget
Procedure PanelCallback(hwnd, msg, wparam, lparam)
  Shared previousTab
  result = CallWindowProc_(oldCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY
      *pNMHDR.NMHDR = lparam
      Select *pNMHDR\code
        Case #TCN_SELCHANGING
          ; --> Get the index of the Tab that is about to lose focus
          previousTab = GetGadgetState(#MyPanel)
        Case #TCN_SELCHANGE 
          ; --> Get the index of the selected Tab
          currentTab = GetGadgetState(#MyPanel)
          ; --> If it's Tab index 2, our disabled tab, 
          ; --> SetGadgetState to the previousTab index
          If currentTab = 2
            SetGadgetState(0, previousTab)
          EndIf
      EndSelect
  EndSelect
  ProcedureReturn result
EndProcedure
      
If OpenWindow(#WinMain, 0, 0, 300, 200, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "PanelGadget") And CreateGadgetList(WindowID(#WinMain))
  PanelGadget(#MyPanel, 10, 10, 280, 180)
  AddGadgetItem (#MyPanel, -1, "Panel 1")
  AddGadgetItem (#MyPanel, -1, "Panel 2")
  AddGadgetItem (#MyPanel, -1, "Disabled")
  CloseGadgetList()
  ; --> We need the parent of PanelGadget so we can subclass and recieve messages
  hPanelParent = GetParent_(GadgetID(#MyPanel))
  oldCallback = SetWindowLong_(hPanelParent, #GWL_WNDPROC, @PanelCallback()) 
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Thanks Sparkie, but my app already has a callback and using your code
seems to interfere with it (ie. gadgets are no longer drawn correctly, etc).
Any way to integrate the above into my current callback? I did try but I
could still select other panels... :(

(Basically, I want to just have one panel available until a certain gadget
is checked, so if the user tries to select other panels, nothing happens).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Sorry about that PB. :( I just threw that code together so there wasn't much testing on my part. If you can you post some of your code, maybe I can figure it out. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

No worries Sparkie. :) I'm using a normal Callback as per the docs, and here's
the only part of your code I injected into the routine. This doesn't stop me
selecting another tab. I'll probably work it out, just need to play for a bit.

Update: If I put a Debug command after #WM_NOTIFY, it never gets seen,
so it seems this message isn't received in my callback. Hmm.

Code: Select all

; prevtab is global.
Case #WM_NOTIFY
  *pNMHDR.NMHDR=lParam
  If *pNMHDR\code=#TCN_SELCHANGING
    prevtab=GetGadgetState(#panel)
  ElseIf *pNMHDR\code=#TCN_SELCHANGE
    If GetGadgetState(#panel)<>2 : SetGadgetState(#panel,prevtab) : EndIf
  EndIf
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

The PanelGadet's parent is a static control and not the main window. That's why you're not recieving the #WM_NOTIFY messages when changing tabs. This is why I had to subclass the static control. I'm not sure why that subclass procedure is interfering with your gadget draws though. :?
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

WORKING! :D Here's what I did this time:

Code: Select all

Procedure PanelCallback(hWnd,msg,wparam,lParam)
  Result=CallWindowProc_(MainCallback,hWnd,msg,wparam,lParam)
  If msg=#WM_NOTIFY
    *pNMHDR.NMHDR=lParam
    Select *pNMHDR\code
      Case #TCN_SELCHANGING : prevtab=GetGadgetState(#panel)
      Case #TCN_SELCHANGE : If GetGadgetState(#panel)<>2 : SetGadgetState(#panel,prevtab) : EndIf
    EndSelect
  EndIf
  ProcedureReturn Result
EndProcedure
And in my main code:

Code: Select all

SetWindowCallback(@Callback())
MainCallback=SetWindowLong_(GetParent_(GadgetID(#panel)),#GWL_WNDPROC,@PanelCallback())
Both "MainCallback" and "prevtab" are global variables. Maybe I just had
a typo or missed something before. All works and all gadgets drawn. :)

@Fred: New command request -- DisablePanelGadgetTab(#gadget,index)

;)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Or maybe my explaining the process to you was a little unclear. Glad you worked it out. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

I never really understood subclassing, to be honest. I thought it was the same
thing as a callback -- obviously not. :) I thought I could just take your code and
throw it into my existing callback, but subclassing seems to be something more.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

Post by localmotion34 »

PB wrote: @Fred: New command request -- DisablePanelGadgetTab(#gadget,index)

;)
i dont think that will be an option since there is no associated MESSAGE in win32.hlp about disabling a paneltab.

you can add a tab by sending the #tcm_insertitem message, but there is no associated "#tcm_disableitem" message

what youd have to do to get the greyed "disabled" look for that tab item is to create an ownerdrawn tabcontrol, and each time the tab is drawn, check to see if the item is disabled, and then draw the text in a color that mimicks the "disabled" state

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Manol
User
User
Posts: 11
Joined: Thu May 05, 2005 1:19 pm
Location: Spain

Post by Manol »

Hi PB,
See the next code

Code: Select all

Procedure showPanel()
    AddGadgetItem(1, 2, "New Hidden Panel")
EndProcedure

Procedure hidePanel()
    RemoveGadgetItem(1, 2)
EndProcedure


OpenWindow(1, 0,0,300, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "")

    If CreateMenu(0, WindowID())
        MenuTitle("Panel")
            MenuItem( 1, "Create New Panel")
            MenuItem( 2, "Remove New Panel")
    EndIf

    CreateGadgetList(WindowID())
    
        PanelGadget(1, 10, 10, 250, 250)
             AddGadgetItem(1, 0, "Test Panel 1")
             AddGadgetItem(1, 1, "Test Panel 2")
       ; ClosePanelGadget()

Repeat

        EventID.l = WaitWindowEvent()
        Select EventID

            Case #PB_EventMenu
                Select EventMenuID()
                    Case 1
                        showPanel()
                    Case 2
                        hidePanel()
                EndSelect

            Case #PB_EventGadget
                Select EventGadgetID()

                EndSelect
                
        EndSelect

Until quit
Or this other
OpenWindow( 0,0,0,300,300,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Test" )
CreateGadgetList( WindowID( 0 ) )

OptionGadget ( 0, 10, 10, 150, 20, "Show Secret Gadget" )
OptionGadget ( 1, 10, 30, 150, 20, "Hide Secret Gadget" )
SetGadgetState( 1, 1 )


PanelGadget( 2, 10, 60, 270, 230 )
AddGadgetItem( 2,-1,"Secret" )
StringGadget( 3,10,10,100,20,"" )

;ClosePanelGadget()

HideGadget ( 2,1 )
HideWindow ( 0, 0 )

Repeat
EW = WaitWindowEvent()

If EW = #PB_Event_Gadget
Select EventGadgetID()
Case 0 : HideGadget( 2, 0 )
Case 1 : HideGadget( 2, 1 )
EndSelect
EndIf

Until EW = #PB_EventCloseWindow
End
Manolo
Edwin Knoppert
Addict
Addict
Posts: 1073
Joined: Fri Apr 25, 2003 11:13 pm
Location: Netherlands
Contact:

Post by Edwin Knoppert »

You can determine where mouse is and cancel the hittest or mouseactivate.
Of course the keys is a problem.

The following topic (PowerBASIC) shows how to determine that.

http://www.hellobasic.com/cgi-bin/forum ... 1105091425

However, the latest approach differs completely, due poor results i simply used WM_SETREDRAW and restore to previous tab.

Selchanging:

' Store currently selected tab in a property.
SetProp NMH.hWndFrom, "VD__CURSEL", VD_Tab_GetCursel( NMH.hWndFrom, 0 )

' Freeze this main form, we release it in another event.
SendMessage nCbHndl, %WM_SETREDRAW, 0, 0

Selchange:


Local R As RECT

' Here we decide To Restore To desired form, example uses some dumb timer+Mod, use your own criteria..

VD_Debug_Print Str$( Round( Timer, 0 ) Mod 2 )

If IsFalse( Round( Timer, 0 ) Mod 2 ) Then

' Set To previously selected form.
VD_Tab_ShowForm( NMH.hWndFrom, 0, GetProp( NMH.hWndFrom, "VD__CURSEL" ) )

End If

' It's important we repaint the whole form.

' Release..
SendMessage nCbHndl, %WM_SETREDRAW, 1, 0

' Obtain client area For redraw.
GetClientRect nCbHndl, R

' Redraw all.
RedrawWindow( nCbHndl, R, 0, %RDW_ERASE Or %RDW_INVALIDATE Or %RDW_UPDATENOW Or %RDW_ALLCHILDREN )


The timer is just nonsense code, remove, it's just a flag you should maintain if the restore is required or not.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Thanks Manol and Edwin, but Sparkie's method is what I require in this case.
I don't want to hide/show the panel tab, as it's in the middle and not an end.
And with Sparkie's code, it also works if the keyboard tries to change tabs.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply