AutoHotkey Community

It is currently May 25th, 2012, 8:23 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: March 20th, 2007, 6:54 pm 
Offline

Joined: March 20th, 2007, 5:23 pm
Posts: 6
Hi all,

I'm fairly new to AHK, but I've some Windows Script Host experience. AHK is much superior in terms of memory usage and manageability as compared to WSH in my opinion. In any case, I'm trying to build a comprehensive hotkey script for my Logitech Revolution mouse. Users of this mouse may be familiar with its somewhat bizarre layout, but for the uninitiated--there's a "tilt" feature on the mousewheel, allowing for the index finger to tilt the wheel to the left or the right, sending different commands. (Note that you can still scroll the wheel up and down normally.)

My application here should make users of Firefox drool: you can easily switch between open tabs by just remapping (using the bundled drivers) the tilt. Result: super ez tab browsing by flicking your finger a few millimeters.

I want to extend this functionality more broadly to the OS--but as in so many other things, Windows XP causes problems. I'm trying to do for the taskbar what I did for Firefox tabs--basically make the taskbar into an elaborate "tabbing" system, in which you can cycle focus to the right or left via tilt.

The obvious answer would seem to be to use Windows' built-in taskbar hotkeys Win+Tab & Win+Tab+Shift, and then send an Enter immediately following:
Code:
^9::Send #{tab}{Enter}
^8::Send #{tab}{Shift}{Enter}
...and then simply remap CTRL-8 & CTRL-9 to the mouse tilt.

The problem is that these keys do a piss-poor job of cycling. For instance, hitting Win+Tab will not necessarily cycle to the bar adjacent to the active one; instead, it seems to cycle to the 2nd bar no matter what, and from THERE you can cycle adjacent bars. This is a real problem though (besides being more annoying to script) since in order to create some looping function to correctly enter the right number of Win+Tab's, you would need to have some way of figuring out how many "bars" separate the currently active bar from the 2nd bar, and then incorporating that into a loop.

I don't know how to do that--how do you access the details of Shell_TrayWnd as an object? Is there some way to get an ordered list of the items in the taskbar? (Note that just getting a list of windows from the API will return them in the z-list order, not necessarily the order on the taskbar. This is an easier implementation, but tilting to the right or left wouldn't correspond to the right or left bars on the taskbar.)

WindowSpy gives some hints, but doesn't give much indication of how to manipulate the taskbar (other than messing with ToolbarWindow322).

Anyway, after an unsuccessful search through the forums, I thought I'd defer to collective wisdom. Any takers?

Lac


Last edited by Lacrossa on March 21st, 2007, 4:08 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2007, 8:28 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
Hi Lacrossa,

I have no idea how the thing you described could be done.
But maybe you could use Alt+Tab to flip through the apps.
With the TaskSwitch PowerToy you would have a real nice switcher.

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2007, 8:51 pm 
Offline

Joined: March 20th, 2007, 5:23 pm
Posts: 6
Hey toralf--thanks for the reply. It is indeed a task, and one which seems to be much more complicated than I originally intended. This would be enough to discourage me from continuing on this project, but the promise of super-lazy cycling across all programs in WinXP is just too tantalizing.

I seem to have stumbled on a few clues, maybe, from the forums--

1. http://www.codeproject.com/csharp/taskbarsorter.asp is a program that takes as its input a lot of what I'd need to know. The page is highly annotated so no need to even wade through the source code--he's clearly using User32.dll f(x)'s for taskbar queries.

2. The attempt to hide individual windows from the taskbar (http://www.autohotkey.com/forum/viewtopic.php?t=5411) also seems to touch on some of the same issues.

3. Skan's post in Tips 'n Tricks (http://www.autohotkey.com/forum/viewtopic.php?p=68698#68698) looked like it was really close to a major breakthrough but... anticlimax :)

I think #1 looks the most promising, but I'm at a loss as to how you would achieve those kinds of function calls in AHK.

Lac


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2007, 11:33 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
You may use this script, replacing ToolbarWindow321 with ToolbarWindow322 in your system:
http://www.autohotkey.com/forum/topic17314.html

You can sort the task buttons using MoveTrayIcon() function, and hide/show HideTrayIcon() function.
(:Some infos, like nMsg & uID & hIcon, aren't applicable in this taskbar case)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Solution
PostPosted: March 21st, 2007, 4:17 am 
Offline

Joined: March 20th, 2007, 5:23 pm
Posts: 6
Sean,

I had found your post and was knee-deep through the code at the time of your reply. I'd just like to say that I was pretty doubtful as to how this one would work out this morning, but after wasting plenty of hours at work I've figured out the solution, thanks in no small part to Sean's heavy-lifting. I owe you a big one. I made some modifications, but the credit is all yours--thanks a lot friend!



Script to Scroll Sequentially Across Taskbar

Code:
#Persistent
#NoEnv
#NoTrayIcon
DetectHiddenWindows, On

^9:: ;forward scroll--map to any key/button
{
   i = 0
   WinGet, active_id, ID, A
   WinGet, pid, PID, ahk_class Shell_TrayWnd
   hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pid)
   pRB := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)
   VarSetCapacity(btn, 20)
   VarSetCapacity(nfo, 24)
   SendMessage, 0x418, 0, 0, ToolbarWindow322, ahk_class Shell_TrayWnd
   Loop, %ErrorLevel%
   {
      SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow322, ahk_class Shell_TrayWnd
      DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)
      dwData  := DecodeInteger(&btn +12)
      DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 24, "Uint", 0)
      hWnd  := DecodeInteger(&nfo + 0)
      if hWnd = 0
         Continue
      i++
      active_hWnd%i% := hWnd
      SetFormat, integer, h
      active_hWnd%i% += 0
      test_Handle := active_hWnd%i%
      SetFormat, integer, d
      %i% += 0
      if test_Handle = %active_id%
      {
         currentHandleIndex := i
      }
   }
   DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
   DllCall("CloseHandle", "Uint", hProc)
   desiredHandleIndex := currentHandleIndex + 1
   if desiredHandleIndex > %i%
   {
      desiredHandleIndex := 1
   }
   next_hWnd := active_hWnd%desiredHandleIndex%
   WinActivate ahk_id %next_hWnd%
return
}


^8:: ;backward scroll--map to any key/button
{
   i = 0
   WinGet, active_id, ID, A
   WinGet, pid, PID, ahk_class Shell_TrayWnd
   hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pid)
   pRB := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)
   VarSetCapacity(btn, 20)
   VarSetCapacity(nfo, 24)
   SendMessage, 0x418, 0, 0, ToolbarWindow322, ahk_class Shell_TrayWnd
   Loop, %ErrorLevel%
   {
      SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow322, ahk_class Shell_TrayWnd
      DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)
      dwData  := DecodeInteger(&btn +12)
      DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 24, "Uint", 0)
      hWnd  := DecodeInteger(&nfo + 0)
      if hWnd = 0
         Continue
      i++
      active_hWnd%i% := hWnd
      SetFormat, integer, h
      active_hWnd%i% += 0
      test_Handle := active_hWnd%i%
      SetFormat, integer, d
      %i% += 0
      if test_Handle = %active_id%
      {
         currentHandleIndex := i
      }
   }
   DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
   DllCall("CloseHandle", "Uint", hProc)
   desiredHandleIndex := currentHandleIndex - 1
   if desiredHandleIndex < 1
   {
      desiredHandleIndex = %i%
   }
   next_hWnd := active_hWnd%desiredHandleIndex%
   WinActivate ahk_id %next_hWnd%
return
}

DecodeInteger(ptr)
{
   Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}


Comments are welcome--it could be more elegant, and there might be some extraneous bits still intact from Sean's f(x) calls, but I think it's pretty clean at getting the job done.

Thanks everyone!

Lac


Report this post
Top
 Profile  
Reply with quote  
PostPosted: March 24th, 2007, 11:37 am 
Offline

Joined: March 23rd, 2007, 10:36 pm
Posts: 5
Greetings...brand new to AHK here...i come in looking for something to help me extend/replace the native functionality of the mouse. It's great to see someone has broken as much ice with this model as you have...you'd make short work of some of the initial usage question I'm posing in a new thread. Hope you can stop in and give me a leg up.

BTW, (hey hey - unexpanded abbr...see how new AHK user i am?) am logging in from LaCrosse, WI which has to merit a quick hey given your nic.

By another way...in your quest for the above window cycling script, why aren't you using the thumb wheel...isn't that exactly what it's for?

thx again,
--steve...

_________________
justSteve


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 8th, 2007, 9:22 am 
Offline

Joined: August 8th, 2007, 9:14 am
Posts: 1
justSteve wrote:
By another way...in your quest for the above window cycling script, why aren't you using the thumb wheel...isn't that exactly what it's for?


He exactly want to do this... but the Logitech SW for this thumb wheel is really stupid :roll:

:?: But i have a Problem with the skript:
It works fine, till i switch forward or backward to a office window (word, excel, powerpoint..) . If i try to switch again forward or backward in a office window, the window flashs fast 4 or 5 times, but dont switch. Only if i do the opposite operation it will work....(if i switched in with forward, then i have to use backward. if i switched in with backward, then i have to use forward).... Any idea why ?

Thx Xyen


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2007, 6:18 pm 
Does anyone know how to make this script work for Windows 2000?
It works fantastic in Windows XP but unfortunately I can't make it work for Windows 2000.

I think the problem is that the ToolbarWindow322 class is not available for Windows 2000, any alternatives?

Thanks in advance.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2007, 9:14 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8666
Location: Salem, MA
what is the class in Win2k?

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2007, 11:19 pm 
Offline

Joined: July 15th, 2006, 1:30 am
Posts: 48
engunneer wrote:
what is the class in Win2k?


I am not sure at all, I tried using AU3_Spy to see the class but I couldn't find it. If someone knows something about it please share it.

_________________
One hotkey to rule them all!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 9th, 2007, 7:19 pm 
Offline

Joined: July 15th, 2006, 1:30 am
Posts: 48
I was wrong, there is a class ToolbarWindow322 in Windows 2000.
The problem is that at the loop, hWnd is always the same so I assume that the function cannot find the next or previous window.

Thanks again.

_________________
One hotkey to rule them all!


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Azevedo, JSLover, krajan, rbrtryn, sks, vsub, Yahoo [Bot] and 66 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group