PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Christian Weilguny on June 27, 2010, 09:03:35 AM

Title: Tab Control on the fly
Post by: Christian Weilguny on June 27, 2010, 09:03:35 AM
Hi,

is there a possibility to assign an existing Dialog to a tabchild at runtime?

It would be easy to set the Parent of the Dialog to the handle of tabchild, but I see no way to get the handle of tabchild. Always I get only the index.

Christian
Title: Re: Tab Control on the fly
Post by: Paul Squires on June 27, 2010, 09:59:31 AM
It can be done however it is not very straight forward. The hWnd of the child tab form needs to be stored in the lParam of the TabControl's tab (via TCITEM). You are also responsible for correctly sizing the child form when it is created to fit into the TabControl's tab space area.

This code shows a new tab being created at runtime and then sized correctly.


'--------------------------------------------------------------------------------
Function FRMMAIN_WM_CREATE ( _
                         hWndForm As Dword, _      ' handle of Form
                         ByVal UserData As Long _  ' optional user defined Long value
                         ) As Long

    Local TCITEM     As TC_ITEM
    Local TabNum     As Long
    Local FLY_Notify As NMHDR   
    Local rc         As Rect
     
    ' Add a new tab to the control
    TabNum = FF_TabControl_GetTabCount (HWND_FRMMAIN_TABCONTROL1)  'this is already one based
    FF_TabControl_AddTab HWND_FRMMAIN_TABCONTROL1, "Tab" & Format$(TabNum+1), TabNum

    ' Add a new child tab form by storing the hwnd of the child form into the
    ' lParam of the tabcontrol.                               
    TCITEM.Mask   = %TCIF_PARAM   
    TCITEM.lParam = Form2_Show( hWndForm, %FALSE)
    TabCtrl_SetItem HWND_FRMMAIN_TABCONTROL1, TabNum, TCITEM
   
    ' Size the child form correctly to fit in the TabControl space
    GetWindowRect HWND_FRMMAIN_TABCONTROL1, rc
    TabCtrl_AdjustRect HWND_FRMMAIN_TABCONTROL1, 0, rc
    MapWindowPoints %HWND_DESKTOP, hWndForm, rc, 2
    SetWindowPos TCITEM.lParam, %HWND_TOP, rc.nLeft, rc.nTop, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, 0

    ' Fire the notifications that cause the correct child tab form to display
    FLY_Notify.hwndFrom = HWND_FRMMAIN_TABCONTROL1
    FLY_Notify.Code     = %TCN_SELCHANGING
    SendMessage hWndForm, %WM_NOTIFY, IDC_FRMMAIN_TABCONTROL1, VarPtr(Fly_Notify)
    FLY_Notify.Code     = %TCN_SELCHANGE
    SendMessage hWndForm, %WM_NOTIFY, IDC_FRMMAIN_TABCONTROL1, VarPtr(Fly_Notify)

End Function

Title: Re: Tab Control on the fly
Post by: Robert Eaton on June 27, 2010, 12:52:32 PM
That was perfect timing for me :D
I was just getting ready to look into how to do that.
I did get a duplicate definition error on the TCITEM variable. After changing that it worked great!
Title: Re: Tab Control on the fly
Post by: José Roca on June 27, 2010, 01:49:52 PM
It's not a good idea to use TCITEM for a variable name, since it is also the name of an structure. The outdated PB headers only use TC_ITEM, but mine also use TCITEM, following the latest C++ headers.
Title: Re: Tab Control on the fly
Post by: Robert Eaton on June 27, 2010, 07:05:14 PM
I'd like to reuse the same child form (including it's controls) for each tab. This appears to work, but I'm not sure how to get handles to the controls on the new child forms so I can interact with them (ex: get text from a text box on a new child form). Can someone point me in the right direction?

Thanks,
Bob
Title: Re: Tab Control on the fly
Post by: Christian Weilguny on June 27, 2010, 07:34:04 PM
Hi Paul,

thanks for the prompt posting.
This works fine as always. In moment I have probs with resizing (the childform is always a little too big, so it covered the Tab-Button) but I think there's anywhere in my code the problem.

Christian
Title: Re: Tab Control on the fly
Post by: Paul Squires on June 27, 2010, 09:24:57 PM
Quote from: Robert Eaton on June 27, 2010, 07:05:14 PM
I'd like to reuse the same child form (including it's controls) for each tab. This appears to work, but I'm not sure how to get handles to the controls on the new child forms so I can interact with them (ex: get text from a text box on a new child form). Can someone point me in the right direction?

Thanks,
Bob

Hi Bob,

Because you are using multiple instances of the same form, you need to get the handles based on the control id's. I believe there is a topic in the Help file that addresses this sort of thing (MDI Forms need to use this type of approach).

You use the GetDlgItem api call to get the control's handle.

hWndControl = GetDlgItem( hWndForm, ControlID )

Title: Re: Tab Control on the fly
Post by: Robert Eaton on June 28, 2010, 03:18:20 PM
Paul,
That only seems to work from within the context of the child form. Looks like I need to know the handle of the child form.

If I know the handle of the child form, then I can gather info from controls on the child form even if it isn't visible.

My big dummy solution was to save the handle for each new child form in a global array when the form is created, and this seems to work :)
Is there more elegant way to find the child form's handle?

Thanks,
Bob