Jump to content


Photo

Can't toggle Windows Toolbars with remote or keyboard


  • Please log in to reply
24 replies to this topic

#1 majstang

majstang
  • Members
  • 386 posts

Posted 19 September 2008 - 09:51 PM

Hi Guys!

Maybe some knowledgeable person here could help me to solve the following problem? I have created Toolbars on my Windows Taskbar containing folders I often use. My problem are that I can't navigate to these Toolbars either with keyboard (TAB) or remotecontrol (which I prefer to use) only with mouse. I use the PC as a HTPC and prefer to control everything with ny remotecontrol. I have to say that I'm actually are able to navigate with keyboard to my first toolbar "Inspelat" but only after mouseclicking on START-button and then TAB to "Inspelat". When reaching "Inspelat" I'm stuck. There is no way to get on from there either way. Using left or right arrow doesn't matter...nothing happens. Left and Right arrow is usually the way to toggle between Quick Launch Icons and it should work even for toggle between Toolbarfolders, but no.
My last resort are now some kind of script that makes it possible for me to navigate to Toolbars with one key on keyboard/remotecontrol and toggle between my Toolbarsfolders with directionbuttons left and right. Toggle between files with up and down and activate files using enter works fine with remote and don't need to be incorporated into script. I only need a onebutton way to go to first Toolbar "Inspelat" and toggle between the toolbars.

My Toolbar folders are named:

1. Inspelat
2. Subbad
3. Blu-Ray
4. DVD
5. Musik
6. TV-Serier
7. Timeshift

Hoping for someone to take on this dilemma of mine.
I have much to learn using all these scriptcommands. Don't know where to start. Please Help!
If you haven't used toolbar yourself it's easy to create. Just rightclick on taskbar and choose "Toolbars" and Choose "New Toolbar" and navigate to the folder you want as a Toolbar on your taskbar. This is a real timesaver using this way to activate often used files and folders.
If anything is unclear what I'n aiming for please contact me and I'll try to clarify :)

Best Regards
Majstang

#2 majstang

majstang
  • Members
  • 386 posts

Posted 20 September 2008 - 04:00 PM

I made a very simple solution myself. Discovered that toggle between My Windows Taskbar Toolbars it was required hitting the ESC key before TABbing on to the next Toolbar on the right. Therefor the solution to my Toggle-dilemma was
Send, {ESC}{TAB}

Next solution to highlight/navigate to first Toolbar "Inspelat" was
Send, {LWINDOWN}{LWINUP}
Send, {TAB 3}

This is not dependant on which applications on the Windows Taskbar that is open because I moved my Toolbars to the left of the activated applications field. It would always take 3 TABs to go to first toolbar after hitting the startbutton. Sadly these two solutions takes two scripts and therefor will take two buttons on my remote and with hardly any free buttons that I can configure left, it is not an ideal solution. Would have been great to only have one button on my remote stearing both opening of first toolbar and an another click on same button would toggle to next toolbar on the right ("Timeshift" in my case). Maybe this is not possible?
Anyone have any good ideas?

Regards
Majstang

#3 majstang

majstang
  • Members
  • 386 posts

Posted 20 September 2008 - 11:49 PM

Nah...this was no solution that is reliable. After some testing i did stumbled on some anomalies. The simple code used earlier does only work as intended when I have one or more applications running. Doesn't matter which applications running, it seem only to require some active application on Taskbar application field is opened. When trying to navigate to first Toolbar on windows Taskbar without any other application running I sometimes fail to hit target. It seem to be dependant what on Taskbar is highlighted when executing the code. I need some focusing of some kind. I thought hitting the Startbutton was the focusing but apparently not in every case. When leftclicking on desktop once and then execute the code I always hit target. But when first Toolbar is choosen my togglecode doesn't work. Instead of TABbing forward to next Toolbar it goes back to the first Quick Launch Icon. Instead of sending ESC and TAB it seem to send ESC and SHIFT TAB. Very strange!! I really need some help with getting to first Toolbar without sending keystrokes. Pretty much like a postmessage command does for applications. This must be possible but I don't know how to do it.

Please help!

#4 Serenity

Serenity
  • Members
  • 1271 posts

Posted 21 September 2008 - 11:24 PM

Hi Majstang,

It's possible to use PostMessage. Each toolbar has its own handle (hWnd), wParam is the zero-based index of each button in the toolbar, lParam needs to be the hWnd of the Toolbar control.

; for button 2 in toolbar 1
ControlGet, toolbar1, Hwnd,, ToolbarWindow322, ahk_class Shell_TrayWnd
PostMessage, 0x111, 1, %toolbar1%,, ahk_class Shell_TrayWnd

If I add another toolbar, this becomes ToolbarWindow322, and the first one becomes ToolbarWindow323, so check this with Window Spy. The same will work for QuickLaunch buttons since it is also a toolbar control.

Edited to add:

If you have added a folder and only have the title and chevron showing (>>) and want to click it (to show a popup menu with the folders contents), you need to use RB_SETBANDINFO. This is quite involved as it requires two structures, although it might be possible to skip RB_GETBANDINFO.

These methods don't work, they just cause the chevron to change to a folder and back:

; LButton, Enter, Tab cause the chevron to change to folder and back, but don't show the menu
ControlSend, RebarWindow321, {LButton}, ahk_class Shell_TrayWnd
ControlClick, RebarWindow321, ahk_class Shell_TrayWnd


#5 majstang

majstang
  • Members
  • 386 posts

Posted 22 September 2008 - 06:28 PM

Hello Serenity!

Nice to hera from ya again :D Cool code by the way. You're sharp at this for sure. After some testing I'm beginning to see how the code works together.

; for button 2 in toolbar 1 
ControlGet, toolbar1, Hwnd,, ToolbarWindow322, ahk_class Shell_TrayWnd 
PostMessage, 0x111, 1, %toolbar1%,, ahk_class Shell_TrayWnd 

This code works excellent but it's not quite what I had in mind. This code executes one of the mediafiles/buttons my foldertoolbar contains straight away.

If you have added a folder and only have the title and chevron showing (>>) and want to click it (to show a popup menu with the folders contents)


SPOT ON! This is exactly my layup and the way I wan't the script to do. It's for easy access to my mediafiles using remotecontrol. Navigating these chevrons and popup menues is a dream compared to the explorer way, if it had worked as I wanted to of course.
Nothing happens however when trying out your next code as it is:

; LButton, Enter, Tab cause the chevron to change to folder and back, but don't show the menu 
ControlSend, RebarWindow321, {LButton}, ahk_class Shell_TrayWnd 
ControlClick, RebarWindow321, ahk_class Shell_TrayWnd

Changing ReBarWindow321 to ToolbarWindow327 (My first Toolbarfolder "Inspelat") in the ControlClick line and run it as a single line makes it work like the postmessage code, executing first mediafile in "Inspelat"-toolbarfolder straight away.

Exactly how to use RB_SETBANDINFO as you suggest in some code is a little bit too advanced for me, but I managed to take the messages for RB_SETBANDINFOW according to the Winspector Spy method you taught me earlier when extracting message ID from WM_COMMAND for MPC. These data shows up when filtering RB_SETBANDINFOW and pressing chevron for "Inspelat":

RB_SETBANDINFOW
Band Index: 1
Struct Size: 80
Mask: RBBIM_CHILD|RBBIMCHILDSIZE etc....
hwndChild: 0x000100ac
cxMinChild: 0
cyMinChild: 30
cyChild: 30
cyMaxChild: 32000
cyIntegral: 30
cxIdeal: 960
wID: 2
Text: Inspelat
fStyle: .....etc....

Maybe these data could be helpful?

#6 Serenity

Serenity
  • Members
  • 1271 posts

Posted 25 September 2008 - 05:03 PM

For some reason Explorer crashes with the first SendMessage. I'll try again when I can reboot.

RB_GETBANDINFOA := 0x41D, RB_SETBANDINFOA := 0x406

; first we get REBARBANDINFO
VarSetCapacity( RB_GETBANDINFO, 100, 0 ) ; crashes Explorer, but without it Errorlevel returns 1
SendMessage, %RB_GETBANDINFOA%, 0, &RB_GETBANDINFO, RebarWindow321, ahk_class Shell_TrayWnd
; Msgbox % Errorlevel ; 0

list = cbSize,fMask,fStyle,clrFore,clrBack,lpText,cch,iImage,hwndChild
,cxMinChild,cyMinChild,cx,hbmBack,wID,cyChild,cyMaxChild,cyIntegral,cxIdeal,lParam,cxHeader
,rcChevronLocation_left,rcChevronLocation_top,rcChevronLocation_right,rcChevronLocation_bottom
,uChevronState

Loop, Parse, list, `,
{
	n+=4
	%A_Loopfield% := NumGet(RB_SETBANDINFO, (A_Index = 1 ? 0 : n-4), "UInt")
}

; change our vars here, e.g:
; cbSize = 4

; apply new settings
VarSetCapacity( RB_SETBANDINFO, 100, 0 )
n=0
Loop, Parse, list, `,
{
	n+=4
	NumPut(A_Loopfield, RB_SETBANDINFO, (A_Index = 1 ? 0 : n-4), "UInt")
	Msgbox % A_Loopfield . "|" . (A_Index = 1 ? 0 : n-4)
}	

SendMessage, %RB_SETBANDINFOA%, 0, &RB_SETBANDINFO, RebarWindow321, ahk_class Shell_TrayWnd


#7 majstang

majstang
  • Members
  • 386 posts

Posted 25 September 2008 - 07:22 PM

Man, now we're talking! :D The code is really getting complex now. Yes you're right Explorer crashes for me as well (WinXPPro).

#8 majstang

majstang
  • Members
  • 386 posts

Posted 28 September 2008 - 02:11 PM

Hi Serenity!

I'm such a newbe at this sitting here and changing around different things in the code without knowing basic structures and rules. Your earlier code made explorer crash and I was playing around with that particular code peace and changed all SetbandinfoA's to SetbandinfoW and same for all GetbandinfoA's to W's. And to my surprice the code was steady, not making Explorer crash. Maybe this is complete nonsence and a wild guess, but when playing around with Winspector spy I remember that i didn't get any hits when filtering Setbandinfoa but i did got hits when filtering setbandinfow. Whishing and hoping you could crack this one :)

RB_GETBANDINFOW := 0x41D, RB_SETBANDINFOW := 0x406 

; first we get REBARBANDINFO 
VarSetCapacity( RB_GETBANDINFOW, 100, 0 ) ; crashes Explorer, but without it Errorlevel returns 1 
SendMessage, %RB_GETBANDINFOW%, 0, &RB_GETBANDINFOW, RebarWindow321, ahk_class Shell_TrayWnd 
; Msgbox % Errorlevel ; 0 

When applying your following code:

list = cbSize,fMask,fStyle,clrFore,clrBack,lpText,cch,iImage,hwndChild 
,cxMinChild,cyMinChild,cx,hbmBack,wID,cyChild,cyMaxChild,cyIntegral,cxIdeal,lParam,cxHeader 
,rcChevronLocation_left,rcChevronLocation_top,rcChevronLocation_right,rcChevronLocation_bottom 
,uChevronState 

Loop, Parse, list, `, 
{ 
   n+=4 
   %A_Loopfield% := NumGet(RB_SETBANDINFO, (A_Index = 1 ? 0 : n-4), "UInt") 
} 

; change our vars here, e.g: 
; cbSize = 4 

; apply new settings 
VarSetCapacity( RB_SETBANDINFO, 100, 0 ) 
n=0 
Loop, Parse, list, `, 
{ 
   n+=4 
   NumPut(A_Loopfield, RB_SETBANDINFO, (A_Index = 1 ? 0 : n-4), "UInt") 
   Msgbox % A_Loopfield . "|" . (A_Index = 1 ? 0 : n-4) 
}    

SendMessage, %RB_SETBANDINFOA%, 0, &RB_SETBANDINFO, RebarWindow321, ahk_class Shell_TrayWnd

It starts to pop up several messageboxes telling me what values all your listings have. I'm sure there's a way to hide these messages. Another thought i had...are these listvalues positiondependant?
After i have pressed OK on every listvalue message nothing happens. No popup menu or anything.

#9 Serenity

Serenity
  • Members
  • 1271 posts

Posted 29 September 2008 - 02:34 PM

Your earlier code made explorer crash and I was playing around with that particular code peace and changed all SetbandinfoA's to SetbandinfoW and same for all GetbandinfoA's to W's. And to my surprice the code was steady, not making Explorer crash.


Changing the variable name shouldn't make a difference since the message value being sent is still the same (0x41D).

I forgot to set cbSize and fMask, but it still crashes with these set. It crashes with RB_GETBANDINFOW and RB_GETBANDINFO too.

; constants
RB_GETBANDINFOA := 0x41D, RB_SETBANDINFOA := 0x406
RB_GETBANDINFOW := 0x41C, RB_SETBANDINFOW := 0x40B
RB_GETBANDINFO := 0x405, RB_GETBANDINFO := RB_SETBANDINFOA

; fMask
RBBIM_CHILD := 0x10, RBBIM_CHILDSIZE := 0x20, RBBIM_IDEALSIZE = 0x200, 
RBBIM_ID := 0x100, RBBIM_STYLE := 0x1, RBBIM_TEXT := 0x4, RBBIM_SIZE := 0x40

; fStyle
RBBS_FIXEDBMP := 0x20, RBBS_GRIPPERALWAYS := 0x80, RBBS_USECHEVRON := 0x200
RBBS_VARIABLEHEIGHT := 0x40

; first we get REBARBANDINFO
; http://msdn.microsoft.com/en-us/library/bb774451(VS.85).aspx

VarSetCapacity( RB_GETBANDINFO, 80, 0 ) ; Struct size = 80

; set the cbSize member of this structure to the size of the REBARBANDINFO structure 
Numput( 80, RB_GETBANDINFO, 0, "UInt" ) 

; set the fMask member to the items you want to retrieve
; fMask := RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_STYLE | RBBIM_TEXT

; Additionally, you must set the cch member of the REBARBANDINFO structure 
; to the size of the lpText buffer when RBBIM_TEXT is specified.

; (let's just see if this works for now), crashes with both
; fMask := RBBIM_CHILDSIZE | RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE
fMask := RBBIM_CHILDSIZE + RBBIM_ID + RBBIM_SIZE + RBBIM_STYLE ; 0x161
Numput( %fMask%, RB_GETBANDINFO, 4, "UInt" )

SendMessage, RB_GETBANDINFOW, 0, &RB_GETBANDINFO, RebarWindow321, ahk_class Shell_TrayWnd
Msgbox % Errorlevel ; 0

If you don't move the toolbars or taskbar you could use MouseClick with the coords of the chevrons instead.

#10 majstang

majstang
  • Members
  • 386 posts

Posted 29 September 2008 - 04:35 PM

If you don't move the toolbars or taskbar you could use MouseClick with the coords of the chevrons instead.

I run my HTPC with two different monitors (FullHD Samsung and a HD-ready TV with a resolution of 1376X768) in two different rooms. Because of the different resolutions I want to eliminate every positiondependant scripts cuz it will only work with one of my monitors/TVs. Don't wanna have two scripts for each resolution cuz it would take up buttons on my remote that i don't have (there is no more programmable buttons left as it is). The only way to make this script work on both TVs is either a script sending keystrokes, which I already tried but with strange anomalies as result or this way that you're helping me with. I didn't expect this operation, that appears to be so easy when navigating with mouse, to get this complicated though. Sorry for that! If you make this script work as I want there's a little something for you I'd like to contribute with. This is also for the script you helped me with earlier (with that codestructure i managed to change all my other scripts that are now working exactly as I want which is GREAT. These scripts are worth a lot for me...making my HTPC a really fun experience to navigate/operate with remote control :)

Now to your latest scriptcode.
Trying out the code as it is render two results depending on how I execute the script. A messagebox pops up when running the script from Explorer doubbleclicking the ahk file. The messagebox only says 0 (zero) and the the heading of the messagebox is the name of the scriptfile. Script will not finish and gets stuck on line 034 saying "034: MsgBox,Errorlevel (2566.25)"
Compiling ahk and executing the script with assigned keyboardcommand makes explorer crash however after clicking OK on a messagebox saying "FAIL".
Do I have to make some changes to the script (I mean if some values for some reason are different on my machine from yours)?

#11 Serenity

Serenity
  • Members
  • 1271 posts

Posted 05 October 2008 - 12:07 AM

Finally solved it!

RB_PUSHCHEVRON(1) ; first toolbar
; RB_PUSHCHEVRON(2) ; second toolbar

RB_PUSHCHEVRON( uBand=0 )
{
	WM_USER := 0x400, RB_PUSHCHEVRON := WM_USER + 43
	VarSetCapacity( lAppValue, 80 )
	SendMessage, RB_PUSHCHEVRON, uBand, &lAppValue, ReBarWindow321, ahk_class Shell_TrayWnd
	Return Errorlevel	
}


#12 majstang

majstang
  • Members
  • 386 posts

Posted 05 October 2008 - 08:35 AM

MAN, your the best!!!!!!
Aha, so you found a command especially for chevrons. Really impressing!

The first part of the script now works well, but I did noticed a windows sound when activating the script. Don't know why? It's a windows standardsound according to "properties for sound".

When executing the script and then trying to toggle/Tab/jump to the next toolbarfolder/popupmenu to the right (in my case "Film") with my simple togglescript:
Send {ESC} {TAB}
It doesn't TABbing to the right. Instead it toggles to the left to first Quick Launch Icon. Executing the script for toggle a second time and I'm back at the first chevron/popupmenu. A third time and the togglescript works as it should...TABbimg to the right to my other toolbars.
It's the same result with keyboard as well.

I suspect I need some focusing before sending the togglekeystrokes, but how do I do that?

Is it possible to scrap the togglescript and incorporate the toggleing into the first script, simply executing your script a second time makes it go to the the second chevron/popupmenu directly?
Sound complicated and not viable what so ever...the main thing for me are to make the togglescript to not jump to the left from first popupmenu but to the right immediately. Do you think it's possible?

Best regards
Majstang

#13 Serenity

Serenity
  • Members
  • 1271 posts

Posted 05 October 2008 - 09:27 AM

I suspect I need some focusing before sending the togglekeystrokes, but how do I do that?


You can use ControlFocus:

ControlFocus, ReBarWindow321, ahk_class Shell_TrayWnd

Is it possible to scrap the togglescript and incorporate the toggleing into the first script, simply executing your script a second time makes it go to the the second chevron/popupmenu directly?


I'm not sure which script you are referring to. It is possible to use a counter so each call to the function presses the next chevron. You could use RB_GETBANDCOUNT to get the total number of toolbar controls so it will adapt to however many toolbars are present. For some reason this returns 3 when I have only 2 toolbars. Here's an example:

b::
if ( count = RB_GETBANDCOUNT()-1 ) 
	count = 0 ; reset
count++
RB_PUSHCHEVRON( count )
Return

RB_PUSHCHEVRON( uBand=0 )
{
	WM_USER := 0x400, RB_PUSHCHEVRON := WM_USER + 43
	VarSetCapacity( lAppValue, 80 )
	SendMessage, RB_PUSHCHEVRON, uBand, &lAppValue, ReBarWindow321, ahk_class Shell_TrayWnd
	Return Errorlevel	
}

RB_GETBANDCOUNT() 
{
	WM_USER := 0x400, RB_GETBANDCOUNT := WM_USER + 12
	SendMessage, RB_GETBANDCOUNT,,, RebarWindow321, ahk_class Shell_TrayWnd
	Return Errorlevel
}


#14 majstang

majstang
  • Members
  • 386 posts

Posted 05 October 2008 - 04:39 PM

It is possible to use a counter so each call to the function presses the next chevron. You could use RB_GETBANDCOUNT to get the total number of toolbar controls so it will adapt to however many toolbars are present.


Wow, this is really exciting! Getting this to work means I could navigate to first chevron and toggle to the next with one button on my remote. MAAAN this is a lot better than I thought would be possible :D

Do you think you could give me a few pointers on where to set number of toolbars in your scriptexample? And maybe give me some more info on which code does what? Number of toolbars for me at the moment is 6. Tried to play around with your script as it is but got stuck on first line. Pressing the "b" key on keyboard executes the script and first chevron pops up. In this example is the intension for the "b" key to execue the counter/TABbing to next chevron/toolbar to the right or what? I'm not exactly sure on how this is supposed to work.

#15 Serenity

Serenity
  • Members
  • 1271 posts

Posted 05 October 2008 - 05:07 PM

Each time you press b it should automatically press the next chevron. The script I posted calls RB_GETBANDCOUNT so you shouldn't have to set the number of toolbars in the script. Could you tell me how many toolbars you have, and what this returns?

Msgbox % RB_GETBANDCOUNT()

RB_GETBANDCOUNT()
{
	WM_USER := 0x400, RB_GETBANDCOUNT := WM_USER + 12
	SendMessage, RB_GETBANDCOUNT,,, RebarWindow321, ahk_class Shell_TrayWnd
	Return Errorlevel
}