How to set Taskbar to Auto Hide programmatically?
- 
				TerryHough
 - Enthusiast

 - Posts: 781
 - Joined: Fri Apr 25, 2003 6:51 pm
 - Location: NC, USA
 - Contact:
 
How to set Taskbar to Auto Hide programmatically?
Is it possible with PB to set the Taskbar to Auto Hide?
I have a program that needs the entire screen. This is fine on systems that have the Taskbar settings set to Auto Hide. However, some users do not have their systems set this way and lose the bottom line to the Taskbar.
How can I temporarily change that setting so that the Taskbar does Auto Hide while my program is running and then reset it to the user's original setting when my program exits?
A search on the forum yields a couple of clues. One allowed me to query the Taskbar settings and display them (fsw), modifying another allowed me to modify the setting to Auto Hide, but then it doesn't actually auto hide the task bar. Another example causes the taskbar to be "hidden" but it doesn't reapper as it does in Auto Hide until the program "unhides" it.
Any suggestions or code examples appreciated.
Terry
			
			
									
									
						I have a program that needs the entire screen. This is fine on systems that have the Taskbar settings set to Auto Hide. However, some users do not have their systems set this way and lose the bottom line to the Taskbar.
How can I temporarily change that setting so that the Taskbar does Auto Hide while my program is running and then reset it to the user's original setting when my program exits?
A search on the forum yields a couple of clues. One allowed me to query the Taskbar settings and display them (fsw), modifying another allowed me to modify the setting to Auto Hide, but then it doesn't actually auto hide the task bar. Another example causes the taskbar to be "hidden" but it doesn't reapper as it does in Auto Hide until the program "unhides" it.
Any suggestions or code examples appreciated.
Terry
- netmaestro
 - PureBasic Bullfrog

 - Posts: 8452
 - Joined: Wed Jul 06, 2005 5:42 am
 - Location: Fort Nelson, BC, Canada
 
Here you go Terry:
			
			
									
									Code: Select all
#ABM_SETSTATE = 10
aBdata.AppBarData
aBdata\cbsize = SizeOf(AppBarData)
aBdata\lparam = #ABS_AUTOHIDE
SHAppBarMessage_(#ABM_SETSTATE, @aBdata)
Delay(5000) ;during this time, hover mouse over taskbar to test
aBdata\lparam = #ABS_ALWAYSONTOP
SHAppBarMessage_(#ABM_SETSTATE, @aBdata)BERESHEIT
						- 
				TerryHough
 - Enthusiast

 - Posts: 781
 - Joined: Fri Apr 25, 2003 6:51 pm
 - Location: NC, USA
 - Contact:
 
Thanks for the reply, netmaestro!
But, it doesn't really seem to do anything here (Win98SE, PB 4.0)
Try my modification of your code:
I don't get any change in the Auto Hide or Always On Top status.
Terry
			
			
									
									
						But, it doesn't really seem to do anything here (Win98SE, PB 4.0)
Try my modification of your code:
Code: Select all
;#ABS_ALWAYSONTOP = 2
;#ABS_AUTOHIDE = 1
#ABM_SETSTATE = 10 
aBdata.AppBarData 
aBdata\cbsize = SizeOf(AppBarData) 
Explanation$ =  #LF$ + #LF$ + "0 = Neither AutoHide or AlwaysOnTop" + #LF$ + "1 = AutoHide" + #LF$ + "2 = AlwaysOnTop" + #LF$ + "3 = AutoHide and AlwaysOnTop"
MessageRequester("Taskbar Starting Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$)
aBdata\lparam = #ABS_AUTOHIDE 
SHAppBarMessage_(#ABM_SETSTATE, @aBdata) 
aBdata\lparam = #ABS_ALWAYSONTOP 
SHAppBarMessage_(#ABM_SETSTATE, @aBdata)
MessageRequester("Taskbar Adjusted Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$)
Terry
- netmaestro
 - PureBasic Bullfrog

 - Posts: 8452
 - Joined: Wed Jul 06, 2005 5:42 am
 - Location: Fort Nelson, BC, Canada
 
Your snippet does:
1. display the status
2. change to autohide
3. change to alwaysontop
4. display the status
With that, I don't see a change. I modified it to:
1. change to autohide
2. display the status
3. change to alwaysontop
4. display the status
Using that order, the mb reports 1=autohide first, and testing it works, then after replying to the mb, it reports 2=alwaysontop. MSDN's doc for this command says it's applicable all the way back to W95, so it really should work in W98SE. If it doesn't, I'm mystified.
			
			
									
									1. display the status
2. change to autohide
3. change to alwaysontop
4. display the status
With that, I don't see a change. I modified it to:
1. change to autohide
2. display the status
3. change to alwaysontop
4. display the status
Using that order, the mb reports 1=autohide first, and testing it works, then after replying to the mb, it reports 2=alwaysontop. MSDN's doc for this command says it's applicable all the way back to W95, so it really should work in W98SE. If it doesn't, I'm mystified.
Code: Select all
;#ABS_ALWAYSONTOP = 2 
;#ABS_AUTOHIDE = 1 
#ABM_SETSTATE = 10 
aBdata.AppBarData 
aBdata\cbsize = SizeOf(AppBarData) 
aBdata\lparam = #ABS_AUTOHIDE 
SHAppBarMessage_(#ABM_SETSTATE, @aBdata) 
Explanation$ =  #LF$ + #LF$ + "0 = Neither AutoHide or AlwaysOnTop" + #LF$ + "1 = AutoHide" + #LF$ + "2 = AlwaysOnTop" + #LF$ + "3 = AutoHide and AlwaysOnTop" 
MessageRequester("Taskbar Starting Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$) 
aBdata\lparam = #ABS_ALWAYSONTOP 
SHAppBarMessage_(#ABM_SETSTATE, @aBdata) 
MessageRequester("Taskbar Adjusted Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$) 
BERESHEIT
						- 
				TerryHough
 - Enthusiast

 - Posts: 781
 - Joined: Fri Apr 25, 2003 6:51 pm
 - Location: NC, USA
 - Contact:
 
@netmaestro
Must be a problem with my Win98SE. I will try another Win98SE box.
Just tried a WinXP box with both options turned off intitially. Both are
turned on by the following code as expected.
Thanks for your help.
Terry
			
			
									
									
						Must be a problem with my Win98SE. I will try another Win98SE box.
Just tried a WinXP box with both options turned off intitially. Both are
turned on by the following code as expected.
Code: Select all
#ABM_SETSTATE = 10 
aBdata.AppBarData 
aBdata\cbsize = SizeOf(AppBarData) 
Explanation$ =  #LF$ + #LF$ + "0 = Neither AutoHide or AlwaysOnTop" + #LF$ + "1 = AutoHide" + #LF$ + "2 = AlwaysOnTop" + #LF$ + "3 = AutoHide and AlwaysOnTop" 
MessageRequester("Taskbar Starting Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$) 
aBdata\lparam = #ABS_ALWAYSONTOP | #ABS_AUTOHIDE 
SHAppBarMessage_(#ABM_SETSTATE, @aBdata) 
MessageRequester("Taskbar Adjusted Status", "Taskbar Status is: " + Str(SHAppBarMessage_(#ABM_GETSTATE, @aBdata)) + Explanation$) 
Terry
I have also tried the different code examples under WinNT 4 SP6 and they also didn't work, but worked fine under WinXP SP2. Further investigation revealed that the constant ABM_SETSTATE is only supported beginning with WinXP:
http://msdn.microsoft.com/library/defau ... tstate.asp
http://support.microsoft.com/kb/143117/en-us
			
			
									
									
						http://msdn.microsoft.com/library/defau ... tstate.asp
Therefore in Win9x/ME/2000 it is only possible to query the taskbar state but not to change it, because the function ABM_SETSTATE is not supported. For those interested in a VisualBASIC 6 example for querying the taskbar state:Minimum operating systems Windows XP
http://support.microsoft.com/kb/143117/en-us
- netmaestro
 - PureBasic Bullfrog

 - Posts: 8452
 - Joined: Wed Jul 06, 2005 5:42 am
 - Location: Fort Nelson, BC, Canada
 
Of course it is possible to hide and show the taskbar also in older Windows versions (but only with a brutal  
 and not very elegant approach):
			
			
									
									
						Code: Select all
TrayHandle = FindWindow_("Shell_TrayWnd", #NULL$)
MessageRequester("Info", "Press OK to hide Taskbar")
If TrayHandle <> 0
  SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_HIDEWINDOW)
EndIf
MessageRequester("Info", "Press OK to show Taskbar")
If TrayHandle <> 0
  SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_SHOWWINDOW)
EndIf
It would be much better to do a fullscreen window!
Here is an example (full screen directx window with)
same method can be used with a normal fullscreen window.
http://www.purebasic.fr/english/viewtopic.php?t=21211
Windows will basicaly turn any window (with no border) that is the size of the full screen into a fullscreen window, covering the taskbar.
That way the user can have their desktop whatever way they want.
This is the prefered way of full screen window applications.
Messing with hiding and showing the taskbar is bad you should always avoid changing the user system settings.
Here is a skeleton example for ya,
I use something very similar in my applications. usually offering a F4 or similar key to toggle fullscreen app and normal (I also keep track of the user maximized state too)
EDIT you said "I have a program that needs the entire screen."
That can be a pain to handle. What if someone only has a 800x600 resolution?
What if they have something other than 1024x768 (even though the majority do these days) there is a lot of odd sizes not all got 4:3 screens.
And what about those with larger resolutions?
If you app really need the whole screen and is resolution locked,
my suggestion would be to either 1. use my example above and make your layout slightly dynamic so that it looks "ok" from 800x600 to 1600x1200 and base it around your 1024x768 sweetspot.
Or 2. put all the stuff inside a container and make sure the user can scroll everything if they do not happen to have the proper resolution.
Or even a mix of these two methods!
			
			
									
									
						Here is an example (full screen directx window with)
same method can be used with a normal fullscreen window.
http://www.purebasic.fr/english/viewtopic.php?t=21211
Windows will basicaly turn any window (with no border) that is the size of the full screen into a fullscreen window, covering the taskbar.
That way the user can have their desktop whatever way they want.
This is the prefered way of full screen window applications.
Messing with hiding and showing the taskbar is bad you should always avoid changing the user system settings.
Here is a skeleton example for ya,
I use something very similar in my applications. usually offering a F4 or similar key to toggle fullscreen app and normal (I also keep track of the user maximized state too)
Code: Select all
Macro MakeWindowTopmost(window)
 SetWindowPos_(WindowID(window),#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_FRAMECHANGED)
EndMacro
#Flags=#PB_Window_Invisible|#PB_Window_Maximize|#PB_Window_BorderLess
OpenWindow(0,0,0,800,600,"our screen",#Flags)
HideWindow(0,#False)
SmartWindowRefresh(0,#True)
#Flags2=#PB_Window_Invisible|#PB_Window_SystemMenu|#PB_Window_WindowCentered|#PB_Window_BorderLess
OpenWindow(1,0,0,200,200,"screen "+Str(WindowWidth(0))+"x"+Str(WindowHeight(0)),#Flags2,WindowID(0))
MakeWindowTopmost(1)
CreateGadgetList(WindowID(1))
WebGadget(1,0,20,WindowWidth(1),WindowHeight(1)-20,"http://www.purebasic.com")
HideWindow(1,#False)
SmartWindowRefresh(1,#True)
Repeat
 Event=WaitWindowEvent(1)
Until Event=#PB_Event_CloseWindowThat can be a pain to handle. What if someone only has a 800x600 resolution?
What if they have something other than 1024x768 (even though the majority do these days) there is a lot of odd sizes not all got 4:3 screens.
And what about those with larger resolutions?
If you app really need the whole screen and is resolution locked,
my suggestion would be to either 1. use my example above and make your layout slightly dynamic so that it looks "ok" from 800x600 to 1600x1200 and base it around your 1024x768 sweetspot.
Or 2. put all the stuff inside a container and make sure the user can scroll everything if they do not happen to have the proper resolution.
Or even a mix of these two methods!
- 
				TerryHough
 - Enthusiast

 - Posts: 781
 - Joined: Fri Apr 25, 2003 6:51 pm
 - Location: NC, USA
 - Contact:
 
@Rescator
Thanks for your reply, comments, and the nifty example code.
Unfortunately, it does not solve my problem. Making the windowprevents the Taskbar (Appbar) from displaying or activating.
I don't want it disabled. I just want it to Auto Hide while my program is active regardless of the user's actual settings for the Taskbar. If the user moves his cursor to the Taskbar's normal position, I want it to unHide and be responsive as normal.
 Yes, I want the user to have their desktop however they want it, just not have the Taskbar overlaying part of my screen unnecessarily.  So, I set it to Auto Hide after capturing their settings and restore those settings upon my programs exit.  A variation of the code offered by netmaestro above works perfectly on WinXP.  Unfortunately, I have been unable to accomplish this on Win98SE as of yet (my users have 100s of Win98SE machines still in use.)
So, I will have to keep searching for a way to set the Auto Hide on Win98SE. Certainly it is possible!
Your comments regarding resolution are well taken. Fortunately, all of my users have 1024 x 768 capabilities so that is not a concern at the moment. Currently, the higher resolutions present no problem as the application is written, although we are not taking advantage of the higher resolution.
Thanks again.
Terry
			
			
									
									
						Thanks for your reply, comments, and the nifty example code.
Unfortunately, it does not solve my problem. Making the window
Code: Select all
SetWindowPos_(WindowID(window),#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_FRAMECHANGED)I don't want it disabled. I just want it to Auto Hide while my program is active regardless of the user's actual settings for the Taskbar. If the user moves his cursor to the Taskbar's normal position, I want it to unHide and be responsive as normal.
... the user can have their desktop whatever way they want. ...
Messing with hiding and showing the taskbar is bad you should always avoid changing the user system settings.
So, I will have to keep searching for a way to set the Auto Hide on Win98SE. Certainly it is possible!
Your comments regarding resolution are well taken. Fortunately, all of my users have 1024 x 768 capabilities so that is not a concern at the moment. Currently, the higher resolutions present no problem as the application is written, although we are not taking advantage of the higher resolution.
Thanks again.
Terry
Terry,
as I tried to explain in my previous post the Win-API function #ABM_SETSTATE is implemented by Microsoft only for operating systems beginning with WinXP. So there exists no "easy" way to implement an autohide function for Win9x/NT/2000 though it might of course be possible. Therefore I have written an "emulation" of the autohide function for non-XP systems in PureBASIC code (tested with WinNT 4 SP6, since I am at work and have no possibility to test it under Win98SE, but in the evening at home I will try it there also):
If the example code detects that taskbar ALWAYSONTOP is activated it hides the taskbar until the end of the program. If the cursor reaches the bottom of the screen the taskbar is shown again. If the cursor leaves the bottom position the taskbar is again hidden.
I hope you can find some use in that code and that it solves your problem.
			
			
									
									
						as I tried to explain in my previous post the Win-API function #ABM_SETSTATE is implemented by Microsoft only for operating systems beginning with WinXP. So there exists no "easy" way to implement an autohide function for Win9x/NT/2000 though it might of course be possible. Therefore I have written an "emulation" of the autohide function for non-XP systems in PureBASIC code (tested with WinNT 4 SP6, since I am at work and have no possibility to test it under Win98SE, but in the evening at home I will try it there also):
Code: Select all
AppBarDataStructure.APPBARDATA
InitialTaskbarState.L
TaskbarIsHidden.L
TrayHandle.L
WindowEventID.L
yPosTaskbarBottom.L
InitialTaskbarState = SHAppBarMessage_(#ABM_GETSTATE, @AppBarDataStructure)
TrayHandle = FindWindow_("Shell_TrayWnd", #NULL$)
SHAppBarMessage_(#ABM_GETTASKBARPOS, @AppBarDataStructure)
yPosTaskbarBottom = AppBarDataStructure\rc\bottom - 3
If InitialTaskbarState = #ABS_ALWAYSONTOP
  SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_HIDEWINDOW)
  TaskbarIsHidden = #True
EndIf
OpenWindow(1, 0, 0, 205, 100, "Non-XP Hide Taskbar Demo", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
Repeat
  WindowEventID = WaitWindowEvent(1)
  If InitialTaskbarState = #ABS_ALWAYSONTOP
    ; ----- Show Taskbar if ALWAYSONTOP and yPos Cursor >= yPosTaskbarBottom and Taskbar is currently hidden
    If DesktopMouseY() >= yPosTaskbarBottom
      If TaskbarIsHidden = #True
        SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_SHOWWINDOW)
        TaskbarIsHidden = #False
      EndIf
    Else
    ; ----- Hide Taskbar if ALWAYSONTOP and yPos Cursor < yPosTaskbarBottom and Taskbar is currently shown
      If TaskbarIsHidden = #False
        SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_HIDEWINDOW)
        TaskbarIsHidden = #True
      EndIf
    EndIf
  EndIf
Until WindowEventID = #PB_Event_CloseWindow
If InitialTaskbarState = #ABS_ALWAYSONTOP
  SetWindowPos_(TrayHandle, 0, 0, 0, 0, 0, #SWP_SHOWWINDOW)
EndIf
I hope you can find some use in that code and that it solves your problem.
