How Create This TabCtrl?

Just starting out? Need help? Post your questions and find answers here.
shu7734
User
User
Posts: 30
Joined: Thu May 15, 2008 5:53 am

How Create This TabCtrl?

Post by shu7734 »

How Create This TabCtrl?

Image

is not

Image

thanks
Win7X64 Purebasic5.22x86DEMO
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How Create This TabCtrl?

Post 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!
BERESHEIT
shu7734
User
User
Posts: 30
Joined: Thu May 15, 2008 5:53 am

Re: How Create This TabCtrl?

Post 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
Win7X64 Purebasic5.22x86DEMO
User avatar
Alireza
Enthusiast
Enthusiast
Posts: 143
Joined: Sat Aug 16, 2008 2:02 pm
Location: Iran

above first pic

Post by Alireza »

any sample for this style (above first pic)? :?:
i need absolutely :|
PB v 5.6 :D
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: above first pic

Post 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. :|
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
User avatar
Alireza
Enthusiast
Enthusiast
Posts: 143
Joined: Sat Aug 16, 2008 2:02 pm
Location: Iran

Re: How Create This TabCtrl?

Post by Alireza »

Thank for reply, i like first pic just. Merci
PB v 5.6 :D
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Re: How Create This TabCtrl?

Post 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
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How Create This TabCtrl?

Post 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).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: How Create This TabCtrl?

Post 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.
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: How Create This TabCtrl?

Post by ts-soft »

@PureLust
The Structure, defined in PB = TC_ITEM works fine :wink:
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: How Create This TabCtrl?

Post 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
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Re: How Create This TabCtrl?

Post 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
Last edited by Justin on Tue Dec 14, 2010 9:58 pm, edited 1 time in total.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: How Create This TabCtrl?

Post by IdeasVacuum »

btw, what happens with the code identation?, it worked before
Only works when within code tags, not within quote tags.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
shu7734
User
User
Posts: 30
Joined: Thu May 15, 2008 5:53 am

Re: How Create This TabCtrl?

Post by shu7734 »

it's so good.
thanks for all.
maybe……can Change title to the right?
Win7X64 Purebasic5.22x86DEMO
User avatar
Shardik
Addict
Addict
Posts: 2060
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: How Create This TabCtrl?

Post 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
Post Reply