Page 1 of 2

How Create This TabCtrl?

Posted: Thu Mar 18, 2010 4:30 am
by shu7734
How Create This TabCtrl?

Image

is not

Image

thanks

Re: How Create This TabCtrl?

Posted: Thu Mar 18, 2010 2:45 pm
by netmaestro
You can accomplish it by applying the following styles to the panelgadget:

#TCS_OWNERDRAWFIXED
#TCS_FIXEDWIDTH
#TCS_MULTILINE
#TCS_VERTICAL

Note that #TCS_VERTICAL is not supported for Commctrl32 v6, so don't use XP styles. Examples of using #TCS_OWNERDRAWFIXED may be found by searching the forums, sorry I haven't time to make a sample. Good luck!

Re: How Create This TabCtrl?

Posted: Wed Mar 31, 2010 4:00 am
by shu7734
I tried Lord Owner draw fixed(VC)

but the Label Width=Caption length

SetItemSize() is not work,

so the shape is abnormal;

my english is pretty bad,thanks

above first pic

Posted: Wed Dec 01, 2010 12:07 pm
by Alireza
any sample for this style (above first pic)? :?:
i need absolutely :|

Re: above first pic

Posted: Sun Dec 12, 2010 8:11 am
by PureLust
Alireza wrote:any sample for this style (above first pic)? :?:
i need absolutely :|
I could give you an example for the vertical Panel-Tabs (2nd pic) if you like, but not for the horizontal Tabs (1st pic) ... sorry. :|

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 1:10 pm
by Alireza
Thank for reply, i like first pic just. Merci

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 5:14 pm
by Justin
If you can work with the winapi this is how it's done
;horizontal tab
;justin 12/10

enableexplicit

Structure TCITEM
mask.l
dwState.l
dwStateMask.l
pszText.i
cchTextMax.i
iImage.i
lParam.i
EndStructure

Macro MAKELONG(a, b)
(a | b<<16)
EndMacro

procedure ondrawitem(hwnd.i, msg.i, wparam.i, *di.DRAWITEMSTRUCT)
define.RECT rcitem
define.s text
define.TCITEM tci
define.w hpad, vpad

if *di\CtlType = #ODT_TAB
;item text
tci\mask = #TCIF_TEXT
tci\pszText = allocatememory(#max_path)
tci\cchTextMax = #max_path
SendMessage_(*di\hwndItem, #TCM_GETITEM, *di\itemID, @tci)

;item rect
SendMessage_(*di\hwndItem, #TCM_GETITEMRECT, *di\itemID, @rcitem)

;draw text
SelectObject_(*di\hdc, GetStockObject_(#DEFAULT_GUI_FONT)) ;removes vertical orientation
hpad = 4
vpad = 4
rcitem\left = rcitem\left + hpad
rcitem\top = rcitem\top + vpad
DrawText_(*di\hDC, tci\pszText, lstrlen_(tci\pszText), @rcitem, #DT_LEFT|#DT_VCENTER)
freememory(tci\pszText)
endif
endprocedure

procedure wndproc(hwnd.i, msg.i, wparam.i, lparam.i)
select msg
case #WM_DRAWITEM : procedurereturn ondrawitem(hwnd, msg, wparam, lparam)

default : procedurereturn #PB_ProcessPureBasicEvents
endselect
endprocedure

define.i hwnd, hwtab
define.TCITEM tci

OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
setwindowcallback(@wndproc())
hwnd = windowid(0)

hwtab = CreateWindowEx_(0, #WC_TABCONTROL, "", #WS_CHILD|#WS_VISIBLE|#TCS_VERTICAL|#TCS_FIXEDWIDTH|#TCS_OWNERDRAWFIXED, 8, 8, 300, 203, hwnd, 0, GetModuleHandle_(0), 0)
SendMessage_(hwtab, #TCM_SETITEMSIZE, 0, MAKELONG(24, 100))

tci\mask = #TCIF_TEXT
tci\pszText = @"item 1"
SendMessage_(hwtab, #TCM_INSERTITEM, 0, @tci)
tci\pszText = @"item 2"
SendMessage_(hwtab, #TCM_INSERTITEM, 0, @tci)


Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 7:44 pm
by IdeasVacuum
If you need to stay cross-platform, you could use buttons as tabs and show-hide containers/widgets.

Edit: Or define in HTML and display in a web gadget. (you will find some mention of this on the forum).

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 8:14 pm
by PureLust
Oh, I see ... I've missed this part in my attempt:
Justin wrote:
SendMessage_(hwtab, #TCM_SETITEMSIZE, 0, MAKELONG(24, 100))
Thanks for the helpful example. Image

Just a cue:
To make your code x64-compatible, you should add the padding to the structure, which is required for x64 (othervise you'll get an IMA with your example at x64):

Code: Select all

Structure TCITEM			; TabControl
	mask.l
	StructureUnion
		dwState.l			; <= #if (_WIN32_IE >= 0x0300)
		lpReserved1.l		; <= used in earlier OS-Versions
	EndStructureUnion
	StructureUnion
		dwStateMask.l		; <= #if (_WIN32_IE >= 0x0300)
		lpReserved2.l		; <= used in earlier OS-Versions
	EndStructureUnion
	CompilerIf #PB_Compiler_Processor = #PB_Processor_x64 : _pad1.l : CompilerEndIf		; <= padding for x64
	pszText.i
	cchTextMax.l
	iImage.l
	lParam.i
EndStructure
Thanks and greets, PL.

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 8:40 pm
by ts-soft
@PureLust
The Structure, defined in PB = TC_ITEM works fine :wink:

Re: How Create This TabCtrl?

Posted: Sun Dec 12, 2010 8:49 pm
by PureLust
ts-soft wrote:@PureLust
The Structure, defined in PB = TC_ITEM works fine :wink:
Oh, I see. I missed this because of the different naming to the original in th API.
Maybe I'll find some other Structures I've missed before as well. :mrgreen:

Thanks a lot Thomas. Image

Re: How Create This TabCtrl?

Posted: Tue Dec 14, 2010 3:42 pm
by Justin
I worked a little on this and did an include, it shows and hides tab items content automatically like the panel gadget using containers. You only have to put the hzTab_OnDrawItem(), hzTab_OnSelChanging(), hzTab_OnSelChange() handlers in the window callback.
include:

Code: Select all

;horizontal tab
;justin 12/10

enableexplicit

Macro MAKELONG(a, b)
(a | b<<16)
EndMacro

structure HZTAB_ITEMEXTRA
	param.i
	container.i
endstructure 

structure HZTAB_TCITEM extends TC_ITEMHEADER
	itEx.hzTab_ITEMEXTRA
endstructure 

procedure.s hzTab_GetItemText(hwtab.i, item.i)
	define.s text
	define.i buf
	define.TC_ITEM tci

	buf = allocatememory(#max_path)
	if buf
		tci\mask = #TCIF_TEXT
		tci\pszText = buf
		tci\cchTextMax = #max_path
		SendMessage_(hwtab, #TCM_GETITEM, item, @tci)

		text = peeks(buf)
		freememory(buf)
		procedurereturn text
	endif 
endprocedure 

procedure hzTab_OnDrawItem(hwnd.i, msg.i, wparam.i, *di.DRAWITEMSTRUCT)
	define.RECT rcitem
	define.w hpad, vpad
	define.i oldobj
	define.s text

	if *di\CtlType = #ODT_TAB
		;item text
		text = hzTab_GetItemText(*di\hwndItem, *di\itemID)

		;item rect
		SendMessage_(*di\hwndItem, #TCM_GETITEMRECT, *di\itemID, @rcitem)

		;draw text
		oldobj = SelectObject_(*di\hdc, GetStockObject_(#DEFAULT_GUI_FONT)) ;removes vertical orientation
		hpad = 4
		vpad = 4

		if SendMessage_(*di\hwndItem, #TCM_GETCURSEL, 0, 0)=*di\itemID
			hpad + 2
			vpad - 2
		endif 
		rcitem\left = rcitem\left + hpad
		rcitem\top = rcitem\top + vpad
		DrawText_(*di\hDC, text, len(text), @rcitem, #DT_LEFT|#DT_VCENTER)
		SelectObject_(*di\hdc, oldobj)
	endif
endprocedure 

procedure hzTab_OnSelChanging(hwnd.i, msg.i, wparam.i, *nmh.NMHDR)
	define.i cursel
	define.hzTab_TCITEM tci

	cursel = SendMessage_(*nmh\hwndFrom, #TCM_GETCURSEL, 0, 0)
	tci\mask = #TCIF_PARAM
	SendMessage_(*nmh\hwndFrom, #TCM_GETITEM, cursel, @tci)
	HideGadget(tci\itEx\container, 1)

	procedurereturn #false
endprocedure 

procedure hzTab_OnSelChange(hwnd.i, msg.i, wparam.i, *nmh.NMHDR)
	define.i cursel
	define.hzTab_TCITEM tci

	cursel = SendMessage_(*nmh\hwndFrom, #TCM_GETCURSEL, 0, 0)
	tci\mask = #TCIF_PARAM
	SendMessage_(*nmh\hwndFrom, #TCM_GETITEM, cursel, @tci)
	HideGadget(tci\itEx\container, 0)
endprocedure 

procedure hzTab_Create(exstyle.l, style.l, x.i, y.i, width.i, height.i, hwParent.i, itemWidth.i)
	define.i hwtab, pad
	define.LOGFONT lf

	hwtab = CreateWindowEx_(exstyle, #WC_TABCONTROL, "", style | #TCS_VERTICAL|#TCS_FIXEDWIDTH|#TCS_OWNERDRAWFIXED, x, y, width, height, hwParent, 0, GetModuleHandle_(0), 0)
	if hwtab
		pad = 5
		GetObject_(GetStockObject_(#DEFAULT_GUI_FONT), sizeof(LOGFONT), @lf)
		if lf\lfHeight < 0 
			lf\lfHeight = lf\lfHeight * -1
		endif 

		SendMessage_(hwtab, #TCM_SETITEMSIZE, 0, MAKELONG(lf\lfHeight + (2*pad), itemWidth))
		SendMessage_(hwtab, #TCM_SETITEMEXTRA, sizeof(hzTab_ITEMEXTRA), 0)
	endif 

	procedurereturn hwtab
endprocedure 

procedure hzTab_InsertItem(hwtab.i, item.i, text.s)
	define.hzTab_TCITEM tci
	define.RECT rcItem, rcdisplay
	define.i container, newItem, hdc

	if item=-1 : item = SendMessage_(hwtab, #TCM_GETITEMCOUNT, 0, 0) : endif

	tci\mask = #TCIF_TEXT
	tci\pszText = @text
	newItem = SendMessage_(hwtab, #TCM_INSERTITEM, item, @tci)
	if newItem<>-1
		UseGadgetList(hwtab)
		;item rect
		SendMessage_(hwtab, #TCM_GETITEMRECT, 0, @rcitem)
		;display rect
		GetClientRect_(hwtab, rcDisplay)
		SendMessage_(hwtab, #TCM_ADJUSTRECT, #false, @rcDisplay)
		tci\itEx\container = ContainerGadget(#pb_any, rcDisplay\left, rcDisplay\top, rcDisplay\right - rcDisplay\left, rcDisplay\bottom - rcDisplay\top)
		if SendMessage_(hwtab, #TCM_GETCURSEL, 0, 0)<>newItem
			HideGadget(tci\itEx\container, 1)
		endif 

		tci\mask = #TCIF_PARAM
		SendMessage_(hwtab, #TCM_SETITEM, item, @tci)
	
		CloseGadgetList()
	endif 

	procedurereturn newItem
endprocedure 

procedure hzTab_GetItemContainer(hwtab.i, item.i)
	define.hzTab_TCITEM tci

	tci\mask = #TCIF_PARAM
	SendMessage_(hwtab, #TCM_GETITEM, item, @tci)

	procedurereturn tci\itEx\container
endprocedure 

procedure hzTab_DeleteItem(hwtab.i, item.i)
	define.i container

	container = hzTab_GetItemContainer(hwtab, item)
	if container
		FreeGadget(container)
	endif 

	procedurereturn SendMessage_(hwtab, #TCM_DELETEITEM, item, 0)
endprocedure 

procedure hzTab_GetItemParam(hwtab.i, item.i)
	define.hzTab_TCITEM tci

	tci\mask = #TCIF_PARAM
	SendMessage_(hwtab, #TCM_GETITEM, item, @tci)

	procedurereturn tci\itEx\param
endprocedure 

procedure hzTab_SetItemParam(hwtab.i, item.i, param.i)
	define.hzTab_TCITEM tci

	tci\mask = #TCIF_PARAM
	tci\itEx\param = param

	procedurereturn SendMessage_(hwtab, #TCM_SETITEM, item, @tci)
endprocedure 

procedure hzTab_SetItemText(hwtab.i, item.i, text.s)
	define.TC_ITEM tci

	tci\mask = #TCIF_TEXT
	tci\pszText = @text

	procedurereturn SendMessage_(hwtab, #TCM_SETITEM, item, @tci)
endprocedure 

procedure hzTab_GetContainerRect(hwtab.i, item.i, *rc.RECT)
	define.i container

	container = hzTab_GetItemContainer(hwtab, item)
	if container
		GetClientRect_(gadgetid(container), *rc)
	endif 
endprocedure 

macro hzTab_OpenItemList(hwtab, item)
	opengadgetlist(hzTab_GetItemContainer(hwtab, item))
endmacro
test using nested tabs

Code: Select all

;- CODE
global.i g_hwtab, g_hwtab2
define.i hwnd, item
define.RECT rc

procedure wndproc(hwnd.i, msg.i, wparam.i, lparam.i)
	define.NMHDR *nmh
	define.DRAWITEMSTRUCT *di

	select msg
		case #WM_DRAWITEM
			*di = lparam
			select *di\hwndItem
				case g_hwtab, g_hwtab2 : procedurereturn hzTab_OnDrawItem(hwnd, msg, wparam, lparam)
			endselect 

		case #WM_NOTIFY
			*nmh = lparam
			select *nmh\hwndFrom
				case g_hwtab, g_hwtab2
					if *nmh\code = #TCN_SELCHANGING : procedurereturn hzTab_OnSelChanging(hwnd, msg, wparam, lparam)
					elseif *nmh\code = #TCN_SELCHANGE : procedurereturn hzTab_OnSelChange(hwnd, msg, wparam, lparam)
					endif 
			endselect 

		default : procedurereturn #PB_ProcessPureBasicEvents
	endselect 
endprocedure

OpenWindow(0, 0, 0, 322, 220, "PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
setwindowcallback(@wndproc())
hwnd = windowid(0)

g_hwtab = hzTab_Create(0, #WS_CHILD|#WS_VISIBLE, 8, 8, 300, 200, hwnd, 100)

item = hzTab_InsertItem(g_hwtab, -1, "item 0")
hzTab_OpenItemList(g_hwtab, item)
	ButtonGadget(#pb_any, 10, 15, 80, 24, "Button 0")
CloseGadgetList()

item = hzTab_InsertItem(g_hwtab, -1, "item 1")
hzTab_OpenItemList(g_hwtab, item)
hzTab_GetContainerRect(g_hwtab, item, @rc)
ButtonGadget(#pb_any, 2, rc\bottom - 50, 80, 24, "Button 2")
g_hwtab2 = hzTab_Create(0, #WS_CHILD|#WS_VISIBLE, 0, 0, rc\right, rc\bottom - 50, gadgetid(hzTab_GetItemContainer(g_hwtab, item)), 50)
CloseGadgetList()

item = hzTab_InsertItem(g_hwtab2, -1, "item 1-1")
hzTab_OpenItemList(g_hwtab2, item)
ButtonGadget(#pb_any, 2, 0, 80, 24, "Button 3")
CloseGadgetList()

item = hzTab_InsertItem(g_hwtab2, -1, "item 1-2")
hzTab_OpenItemList(g_hwtab2, item)
ButtonGadget(#pb_any, 2, 40, 80, 24, "Button 4")
CloseGadgetList()

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
btw, what happens with the code identation?, it worked before

Re: How Create This TabCtrl?

Posted: Tue Dec 14, 2010 3:56 pm
by IdeasVacuum
btw, what happens with the code identation?, it worked before
Only works when within code tags, not within quote tags.

Re: How Create This TabCtrl?

Posted: Wed Dec 15, 2010 9:15 am
by shu7734
it's so good.
thanks for all.
maybe……can Change title to the right?

Re: How Create This TabCtrl?

Posted: Wed Dec 15, 2010 3:06 pm
by Shardik
In Linux it's much easier as in Windows to display the tabs at the left side of a PanelGadget
(as in shu7734's first image of his first posting) because only one additional line is necessary:

Code: Select all

gtk_notebook_set_tab_pos(GadgetID(Gadget#), x)
To position the tabs at the wanted location replace x with one of the following numbers:

0: tabs at the left side
1: tabs at the right side
2: tabs at the top
3: tabs at the bottom

A simple example:

Code: Select all

OpenWindow(0, 0, 0, 322, 220, "PanelGadget")
PanelGadget(0, 8, 8, 306, 203)
AddGadgetItem (0, -1, "Panel 1")
AddGadgetItem (0, -1, "Panel 2")

gtk_notebook_set_tab_pos_(GadgetID(0), 0)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow