Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Control, Tab, N


  • Please log in to reply
9 replies to this topic
corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

TabLeft [, Count]: Moves left by one or more tabs in a SysTabControl32. Count is assumed to be 1 if omitted or blank. To instead select a tab directly by number, replace the number 5 below with one less than the tab number you wish to select. In other words, 0 selects the first tab, 1 selects the second, and so on:
SendMessage, 0x130C, 5,, SysTabControl321, WinTitle ; 0x130C is TCM_SETCURSEL.

The method of selecting a specific tab that is mentioned seems to be incomplete unfortunately. On this system (Win XP pro SP2) it seems that a couple calls are necessary to switch to a specific tab. TCM_SETCURSEL will switch to the tab by itself but the contents of the tab won't change. Sending a TCM_SETCURFOCUS message and sleep, 0 first seems to work well in most cases. This method doesn't seem to work when the tab control has TCS_BUTTONS style though so it seems to be necessary to temporarily modify the style.

Here's a function that seems to work ok:
SwitchToTabN(t_TabControl, t_TabNumber, t_Wintitle="")
{
  If t_TabControl is not number
    ControlGet, t_TabControl, Hwnd,, %t_TabControl%, %t_WinTitle%
  WinGet, t_tabStyle, Style, ahk_id %t_TabControl%
  If (t_tabStyle & 0x100) { ; buttons are enabled - remove TCS_BUTTONS style
    WinSet, Style, -0x100, ahk_id %t_TabControl%
    t_tbuttons = 1
  } 
  SendMessage, 0x1330, %t_TabNumber%,,, ahk_id %t_TabControl%  ; 0x1330 is TCM_SETCURFOCUS
  sleep, 0 ; to prevent redraw issues
  SendMessage, 0x130C, %t_TabNumber%,,, ahk_id %t_TabControl%  ; 0x130C is TCM_SETCURSEL
  If (t_tbuttons)
    WinSet, Style, +0x100, ahk_id %t_TabControl%
}

t_TabControl - either the HWND or classNN of the tab control
t_TabNumber - the index of the tab to switch to
t_Wintitle - if a classNN is specified for t_TabControl then a Window title can optionally be specified

Could this function (or similar) be added to the documentation or the functionality be built in? If built in, maybe as a Tab, N option?

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I've used TabLeft and Right with good results, though never on a TCS_BUTTONS control. The code behind it is this:

PostMessage(control_window, WM_KEYDOWN, vk, lparam | 0x00000001);
Sleep(0);
PostMessage(control_window, WM_KEYUP, vk, lparam | 0xC0000001);

... where "vk" is VK_LEFT or VK_RIGHT (i.e. the arrow keys) and lparam is equal to the key's scan code bit shifted left (<<) by 16.

Although it seems best not to change the existing code unless its clearly broken on all systems (for backward compatibility), a new option or command could be added. I'll add it to the to-do list. Thanks.

If anyone else can reproduce these results, please post here. It would also help to have a common/standard app with which to test the various Tab methods.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Thanks for providing the code for the existing functions :) . I did have a look out of curiosity. I was mainly having issues with the code mentioned for selecting a specific tab instead. This part:

To instead select a tab directly by number, replace the number 5 below with one less than the tab number you wish to select. In other words, 0 selects the first tab, 1 selects the second, and so on:
SendMessage, 0x130C, 5,, SysTabControl321, WinTitle ; 0x130C is TCM_SETCURSEL.

was the part I was having difficulty with on my system. A built in option for selecting a specific tab instead of determining the current tab selected then moving left or right would be great. The function I put together seems to work well so far though.

The existing TabLeft and TabRight options seem to work well on my system if focus is set to one of the tabs in a control first. If focus isn't set first then TabLeft and TabRight seem to have no effect unfortunately.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks for these informative details.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Well, I'm a bit confused but pleasantly surprised today after additional testing. I'm not sure why the results seem a bit different today (seems to work in more applications than in previous testing). I tested a few applications with tab style controls and found that TabLeft, TabRight seem to work well (AutoHotkey help file, Jens File Editor, API-Guide, Kerio Personal Firewall, Windows XP Display Properties, Windows XP System Properties, and a few others...). The function I put together seems to also work well in most of them. The exception seems to be API-Guide where the tab changes but the info in the tab wasn't updated. At this point I'm assuming that the XP property windows are good test subjects. Any thoughts on this?

Strangely though, the controls that I seem to have the most difficulty with are Tab controls in an AutoHotkey GUI. This script, for example, doesn't seem to respond as expected when trying to change tabs. Using almost the same function in the GUI script seems to work ok though... These are the results I'm currently getting when testing in Windows XP Pro SP2:

TabLeft and TabRight don't seem to work on the Tab control on the left but the function seems to work ok. TabLeft and TabRight seem to move which tab is highlighted for the control on the right but the same tab stays selected and the content displayed doesn't change. The function seems to change tabs ok but content isn't displayed after the switch (this doesn't seem to be an issue with the code in the GUI itself). When testing TabLeft and TabRight on both controls, if you first click a tab with the mouse a couple times until it gets focus (border around text in tab), then test again, TabLeft and TabRight seem to work ok. If you click a button then try again they'll stop working.

Here's the script I'm currently using for testing:
^+LButton::
MouseGetPos,,,, tabctrl, 1 
MouseGetPos,,,, tabhwnd, 2 
SplashTextOn, 500, 40, Control Selected, %tabctrl% - hwnd: %tabhwnd%
SetTimer, toff, 2000
Return

toff:
SplashTextOff
Return

Numpad0::
; move to first tab
If (tabhwnd) 
  SwitchToTabN(tabhwnd, "0")
Return

Numpad1::
; move left
If (tabhwnd) 
  Control, TabLeft, 1,, ahk_id %tabhwnd%
Return

Numpad3::
; move right
If (tabhwnd) 
  Control, TabRight, 1,, ahk_id %tabhwnd%
Return

SwitchToTabN(t_TabControl, t_TabNumber, t_Wintitle="")
{
  If t_TabControl is not number
    ControlGet, t_TabControl, Hwnd,, %t_TabControl%, %t_WinTitle%
  WinGet, t_tabStyle, Style, ahk_id %t_TabControl%
  If (t_tabStyle & 0x100) { ; buttons are enabled - remove TCS_BUTTONS style
    WinSet, Style, -0x100, ahk_id %t_TabControl%
    t_tbuttons = 1
  } 
  DllCall("SendMessage", "UInt", t_TabControl, "UInt", 0x1330, UInt, "0", UInt, "0")
  sleep, 0 ; to prevent redraw issues
  DllCall("SendMessage", "UInt", t_TabControl, "UInt", 0x130C, UInt, "0", UInt, "0")

  If (t_tbuttons)
    WinSet, Style, +0x100, ahk_id %t_TabControl%
}

Edit: The issue with the controls disappearing after using the function on the Tab control on the right can be replicated by changing the Tab control's style.
^!s::
WinSet, Style, ^0x100, ahk_id %tabhwnd%
Return


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks for the detailed post.

It doesn't surprise me that the tab controls in AHK GUIs -- in contrast to the tab controls of other apps -- don't respond consistently to "GuiControl TabLeft/Right". This is because AHK tab controls were not programmed in a traditional method such as MFC.

There are some planned improvements to tab controls and control automation that may address this.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Thanks. Workarounds for the current behaviour seem possible though and may be a good idea in general for me to add to a generic function. Testing different methods on various controls has been interesting and fun so far :) .

Peter
  • Members
  • 448 posts
  • Last active: Jan 15 2010 05:41 AM
  • Joined: 30 Dec 2005
In the first post:

TabLeft [, Count]: Moves left by one or more tabs in a SysTabControl32. Count is assumed to be 1 if omitted or blank. To instead select a tab directly by number, replace the number 5 below with one less than the tab number you wish to select. In other words, 0 selects the first tab, 1 selects the second, and so on:
SendMessage, 0x130C, 5,, SysTabControl321, WinTitle ; 0x130C is TCM_SETCURSEL.

The method of selecting a specific tab that is mentioned seems to be incomplete unfortunately. On this system (Win XP pro SP2) it seems that a couple calls are necessary to switch to a specific tab. TCM_SETCURSEL will switch to the tab by itself but the contents of the tab won't change. Sending a TCM_SETCURFOCUS message and sleep, 0 first seems to work well in most cases. This method doesn't seem to work when the tab control has TCS_BUTTONS style though so it seems to be necessary to temporarily modify the style.

AHK Help documentation V1.0.47.00 says still the same :? . I didn't work on any SysTabControl32 control I've tried so far (WinXP Pro SP1, WinXP Home SP2). (E.g. taskmanager)
@corrupt: Your solution works fine though :) . (Although, I don't really understand the purpose of "Sleep, 0 ; for redrawn issues".)
@Chris: doesn't need AHK Help to be changed with extra SendMessage, or a link to the solution above,...? Thanks :) .

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I've updated the example to be the following:

To instead select a tab directly by number, replace the number 5 below with one less than the tab number you wish to select. In other words, 0 selects the first tab, 1 selects the second, and so on:
SendMessage, 0x1330, [color=red]5[/color],, SysTabControl321, WinTitle  ; 0x1330 is TCM_SETCURFOCUS.
Sleep 0  ; This line and the next are necessary only for certain tab controls.
SendMessage, 0x130C, [color=red]5[/color],, SysTabControl321, WinTitle  ; 0x130C is TCM_SETCURSEL.
Thanks.

guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011
bumping this suggestion based on support thread here
http://www.autohotke...ow-eg-filemenu/

i'm fine just using the sendmessage example thats listed on the help page but this new person didn't really understand it

if implemented, my suggestion is to NOT use Control, Tab, N but rather keep the syntax consistent with GuiControl and use the Choose subcommand like this:
 
Control, Choose, N, TabControl, WinTitle
but i suppose either is fine