Disable the blue highlighting for tabs?

BlitzPlus Forums/BlitzPlus Programming/Disable the blue highlighting for tabs?

sswift(Posted 2005) [#1]
The way tabs highlight in a dark blue color whenever I move over one is really annoying me... I was wondering if anyone knew how to disable this?

Also, I think I saw someone post some kind of code that would send messages to gadgets to make them do certain things that were normally not supported, and there were a bunch of constants with it, and I thought that might contain something to disable this for tabs.


sswift(Posted 2005) [#2]
Ugh... It looks like there is no way to disable that property once it is enabled...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/tab/reflist.asp

Specifically, the property that Mark appears to have enabled for the tabs is "TCS_HOTTRACK", which causes whichever tab the mouse is hovering over to be highlighted blue.

The only way to fix this would be to create a tab control manually. But I'm not sure if that would work with Blitz's event system or not.


skidracer(Posted 2005) [#3]
If you want the XP orange highlight color instead you can place a manifest file in the same dir as your exe.

http://www.blitzbasic.com/Community/posts.php?topic=31503

also you may want to try the GWL_STYLE option of the SetWindowLong command for altering a window's style (tabber uses WS_CHILD|WS_CLIPCHILDREN|TCS_FOCUSNEVER|TCS_HOTTRACK).


sswift(Posted 2005) [#4]
Um... SetWindowLong needs an int as a parameter. If I do this, will Blitz automatically convert the longint to an int, or is it going to cause a memory leak or a crash or something?

SetWindowLong%(hWnd%, nIndex%, dwNewLong%):"SetWindowLong"

And if I can't do that, then how can I access this function? Am I stuck because of limitations of how Blitz allows me to access DLLs?

Also, just where am I supposed to find the values for all these constants? MSDN conveniently leaves the values out, and I keep having to search for them with google.


sswift(Posted 2005) [#5]
I tried to access that functiin, but Blitz tosses up an error when I actually try to call the function in the program saying the user lib function is not found. The compiler is obviously finding the entry, and I've spelled it right, so either the function name is different somehow in the dll itself, or it does not like the longint parameter where there should be an int... Hm...


skidracer(Posted 2005) [#6]
You need access to the windows sdk for the constants, the files winuser.h and commctrl.h in particular.

Longs and ints are both 32 bit values in win32 so you should be fine.

From reading the notes in MSDN you might not see a style changes take effect until you resize the gadget.

/*
* Window Styles
*/
#define WS_OVERLAPPED 0x00000000L
#define WS_POPUP 0x80000000L
#define WS_CHILD 0x40000000L
#define WS_MINIMIZE 0x20000000L
#define WS_VISIBLE 0x10000000L
#define WS_DISABLED 0x08000000L
#define WS_CLIPSIBLINGS 0x04000000L
#define WS_CLIPCHILDREN 0x02000000L
#define WS_MAXIMIZE 0x01000000L
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
#define WS_BORDER 0x00800000L
#define WS_DLGFRAME 0x00400000L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_GROUP 0x00020000L
#define WS_TABSTOP 0x00010000L

#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L


#define WS_TILED WS_OVERLAPPED
#define WS_ICONIC WS_MINIMIZE
#define WS_SIZEBOX WS_THICKFRAME
#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW


#if (_WIN32_IE >= 0x0300)
#define TCS_SCROLLOPPOSITE 0x0001 // assumes multiline tab
#define TCS_BOTTOM 0x0002
#define TCS_RIGHT 0x0002
#define TCS_MULTISELECT 0x0004 // allow multi-select in button mode
#endif
#if (_WIN32_IE >= 0x0400)
#define TCS_FLATBUTTONS 0x0008
#endif
#define TCS_FORCEICONLEFT 0x0010
#define TCS_FORCELABELLEFT 0x0020
#if (_WIN32_IE >= 0x0300)
#define TCS_HOTTRACK 0x0040
#define TCS_VERTICAL 0x0080
#endif
#define TCS_TABS 0x0000
#define TCS_BUTTONS 0x0100
#define TCS_SINGLELINE 0x0000
#define TCS_MULTILINE 0x0200
#define TCS_RIGHTJUSTIFY 0x0000
#define TCS_FIXEDWIDTH 0x0400
#define TCS_RAGGEDRIGHT 0x0800
#define TCS_FOCUSONBUTTONDOWN 0x1000
#define TCS_OWNERDRAWFIXED 0x2000
#define TCS_TOOLTIPS 0x4000
#define TCS_FOCUSNEVER 0x8000


sswift(Posted 2005) [#7]

user32.decls:
.lib "user32.dll"
SetWindowLong%(hWnd%, nIndex%, dwNewLong%):"SetWindowLongA"

Function Test(Gadget)

	Local GWL_STYLE       = -16
	Local WS_CHILD        = $40000000
	Local WS_CLIPCHILDREN = $02000000
	Local TCS_FOCUSNEVER  = $8000
	
	Blah = SetWindowLong(QueryObject(Gadget, 1), GWL_STYLE, WS_CHILD Or WS_CLIPCHILDREN Or TCS_FOCUSNEVER)
	
End Function



I tried this, but it doesn't work. I call it immediately after creating my tabber, and I then insert my tabs, reposition/resize it with setgadgetshape, and then attach a panel with a canvas inside it to the tabber.

This used to work fine, but now the panel with canvas does not show up, and the tabber still highlights the tabs, as if to mock me.


sswift(Posted 2005) [#8]
Aha... You forgot WS_VISIBLE. The tabber needs that property too.

But the tabber continues to mock me. As I feared, the documentation that said you can only remove certain properties, not including the one I want to remove, was probably telling the truth... The highlighted tabs still there. :-(


BlitzSupport(Posted 2005) [#9]
Try reading the window details (GetWindowLong IIRC) and combining the flags you want/don't want with that result.

You might also need to update/refresh the window afterwards (can't remember offhand). The SetWindowLong docs say something along these lines.


sswift(Posted 2005) [#10]
Argh, this is so annoying.

BlitzSupport:
I took your advice and tried calling SetWindowPos to be sure, even though I thought the SetGadgetShape should be enough to trigger the change, but no dice. The appearance of the tabber doesn't change.

Function Test(Gadget)

	Local GWL_STYLE        = -16
	Local WS_CHILD         = $40000000
	Local WS_CLIPCHILDREN  = $02000000
	Local TCS_FOCUSNEVER   = $8000
	Local WS_VISIBLE       = $10000000
	Local HWND_TOP         = 0				; Place window at top of Z order.
	Local SWP_NOSIZE       = 1
	Local SWP_NOMOVE       = 2
	Local SWP_NOZORDER     = 4		
	Local SWP_FRAMECHANGED = 20
	
	Blah = SetWindowLong(QueryObject(Gadget, 1), GWL_STYLE, WS_CHILD Or WS_CLIPCHILDREN Or TCS_FOCUSNEVER Or WS_VISIBLE)
	Blah = SetWindowPos(QueryObject(Gadget, 1), HWND_TOP, GadgetX(Gadget), GadgetY(Gadget), GadgetWidth(Gadget), GadgetHeight(Gadget), SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOZORDER Or SWP_FRAMECHANGED)	
	
End Function



Eikon(Posted 2005) [#11]
This was an aggravating bugger, but I finally figured it out after an hour of messing around. It turns out that calling QueryObject on the tabber only returns the client hwnd (the work area below the tabs), and not the handle to the tabber itself. Calling GetParent on the original hWnd fixes the problem.
;SetWindowLong%(hWnd%,Val%,Long%):"SetWindowLongA"
;GetWindowLong%(hWnd%,Val%):"GetWindowLongA"
;GetParent%(hwnd%)

Function Test(Gadget)

	Local hWnd% = QueryObject(Gadget, 1)
	hWnd = GetParent(hWnd)
	
	Local GWL_STYLE        = -16
	Local TCS_HOTTRACK     = $40

	SetWindowLong hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) - TCS_HOTTRACK

End Function



sswift(Posted 2005) [#12]
I don't think you're supposed to use - when dealing with windows constants like that... I think maybe you want to use AND NOT?

In this case you know the TCS_HOTTACK is on, but if Mark turns it off in a future version of Blitz this code (as is) could screw up all the properties of the tabber, I think.


sswift(Posted 2005) [#13]
Hm, well, AND (NOT TCS_HOTTRACK) just makes the tabber dissapear, and yours works, so I guess I'll use yours.

But I'm not sure why that is. :-)


Eikon(Posted 2005) [#14]
I tryed that but couldn't get it to work. Both of these fail:

GetWindowLong(hWnd, GWL_STYLE) And Not TCS_HOTTRACK
GetWindowLong(hWnd, GWL_STYLE) And (Not TCS_HOTTRACK)

How should I do it?

* Edit * Ok, cool :)


sswift(Posted 2005) [#15]
It appears that NOT in Blitzplus does not do a bitwise not. It does a boolean NOT.

Try this:

TCS_HOTTRACK = $40
Print Not TCS_HOTTRACK
Waitkey()

Your result will be 0, which is clearly wrong for a bitwise NOT, and correct for a boolean NOT. Any value other than 0 in boolean is TRUE, so here the boolean not sees Print NOT TRUE, which is FALSE, which is 0.

Is there any way to do a bitwise NOT in Blitzplus?

If not, then you could just do this:

TCS_HOTTRACK = %00000000000000000000000001000000
NOT_TCS_HOTTRACK = %11111111111111111111111110111111

Which comes out to -65 in decimal, which is $FFFFFFFFFFFFFF6F in hexadecimal.

Gonna test this now....


sswift(Posted 2005) [#16]
Yes that works, and will not break if Mark changes the tabber properties so they no longer include the hot tracking. :-)

; Add to User32.decls:
;
; .lib "user32.dll"
; SetWindowLong%(hWnd%,Val%,Long%):"SetWindowLongA"
; GetWindowLong%(hWnd%,Val%):"GetWindowLongA"
; GetParent%(hwnd%)

Function RemoveTabberHottrack(Gadget)

	Local hWnd% = QueryObject(Gadget, 1)
	hWnd = GetParent(hWnd)
	
	Local GWL_STYLE        = -16
	Local TCS_HOTTRACK     = $40
	Local NOT_TCS_HOTTRACK = -65
	
	SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) And NOT_TCS_HOTTRACK)

End Function



I'll stick this in the code archives now. :-)