1

Тема: AHK: Перемещение ярлыков на панели задач

На панели задач есть открытые вкладки
https://i.imgur.com/gSDokVI.png

Нужна команда для того, чтобы переместить открытую вкладку на левую позицию, чтобы выглядело примерно так:

https://i.imgur.com/YV5UcPA.png

Так же интересует вопрос, какой командой можно удалять закрепленные окна
https://i.imgur.com/ufTEq2e.png

Можете помочь с этим, пожалуйста?

2

Re: AHK: Перемещение ярлыков на панели задач

Простых решений для этих задач нет. Если они существует, то довольно сложные.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: Malcev, 2021-08-05 19:27:42)

Re: AHK: Перемещение ярлыков на панели задач

Можно сначала все удалить:
https://docs.microsoft.com/en-us/window … -deletetab
А потом добавить в нужном порядке:
https://docs.microsoft.com/en-us/window … ist-addtab

Так же интересует вопрос, какой командой можно удалять закрепленные окна

Например так, только надо на ahk v1 перенести:
https://www.autohotkey.com/boards/viewtopic.php?t=72033
Либо пробовать так:
https://www.autohotkey.com/boards/viewtopic.php?t=21637

4

Re: AHK: Перемещение ярлыков на панели задач

Malcev пишет:

А потом добавить в нужном порядке:

А какой hwnd указывать в случае вкладки?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Перемещение ярлыков на панели задач

Хендл окна этой вкладки.

6

Re: AHK: Перемещение ярлыков на панели задач

А как его узнать?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Перемещение ярлыков на панели задач

https://www.codeproject.com/Articles/10 … ur-taskbar

8 (изменено: Clannad5, 2021-08-06 10:15:59)

Re: AHK: Перемещение ярлыков на панели задач

Привожу следующий код:


#SingleInstance force
#Persistent
#If MouseIsOverClass("Shell_TrayWnd")
LButton::
MouseGetPos, OutputVarX, OutputVarY, OutputVarWin, OutputVarControl, 3
Sleep, 100
If OutputVarX between 60 and 100
{
                Send, {Control down}
                Click
                Send, {Control up}
    Msgbox, % OutputVarX " " OutputVarY
}
Msgbox, % OutputVarX " " OutputVarY
MouseIsOverClass(sought){
MouseGetPos,,,WinID
WinGetClass, WinClass, ahk_id %WinID%
return WinClass=sought ; ends up returning true if they are equal, else false if they are not equal
}

По логике, он должен тыкать куда надо и открываться.
Но по какой-то причине его координаты становятся не между 60 и 100, а -500
Я стал выяснять и понял, что сама панель задач иногда сбоит и показывает координаты в минусах.
Как можно решить проблему?
Можно как-нибудь получить название ярлыка, по которому тыкаешь?

9

Re: AHK: Перемещение ярлыков на панели задач

Ссылка, которую я привел, только для WinXP.
В современных виндовсах наверное придется инжектиться в explorer.exe.

Можно как-нибудь получить название ярлыка, по которому тыкаешь?

Читайте про iAccessible.

10

Re: AHK: Перемещение ярлыков на панели задач

Clannad5 пишет:

показывает координаты в минусах.

Читайте про CoordMode.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Перемещение ярлыков на панели задач

Придумал как хендлы узнать можно.
Получаем список окон, активируем вкладки по этому списку:
https://docs.microsoft.com/en-us/window … ctivatetab
После чего через iaccessible смотрим позицию активной вкладки и пихаем в массив.

12

Re: AHK: Перемещение ярлыков на панели задач

Malcev пишет:

активируем вкладки по этому списку

Ну не сказал бы, что хороший вариант.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Перемещение ярлыков на панели задач

Почему?

14

Re: AHK: Перемещение ярлыков на панели задач

teadrinker
Я пробовал через CoordMode, но видимо придётся если только весь экран использовать, а ведь я иногда могу держать хотбар сверху, снизу.

15

Re: AHK: Перемещение ярлыков на панели задач

Malcev пишет:

Почему?

Во-первых как-то некрасиво, во-вторых, мало ли что там во вкладках, может активация на что-то повлияет.

Clannad5 пишет:

ведь я иногда могу держать хотбар сверху, снизу

Это не важно. В момент клика до срабатывания метки LButton панель задач может не успевать активизироваться, и полученные координаты будут неверны.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Перемещение ярлыков на панели задач

teadrinker пишет:

Во-первых как-то некрасиво

Вам шашечки или ехать?

teadrinker пишет:

во-вторых, мало ли что там во вкладках, может активация на что-то повлияет.

А на что может повлиять активация вкладки (не окна)?

17

Re: AHK: Перемещение ярлыков на панели задач

А разве при активации вкладки окно не активируется (не пробовал)? В любом случае повлиять в разных случаях на что-то может. Например, если это «спящая» вкладка, она начнёт загружаться.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18

Re: AHK: Перемещение ярлыков на панели задач

ITaskbarList::ActivateTab method (shobjidl_core.h)
Activates an item on the taskbar. The window is not actually activated; the window's item on the taskbar is merely displayed as active.

teadrinker пишет:

Например, если это «спящая» вкладка, она начнёт загружаться.

Не знаю, что такое спящая вкладка.
Пример привести можешь?

19

Re: AHK: Перемещение ярлыков на панели задач

Malcev

Мне кажется он имел ввиду, что есть вкладки, которые выгружают память и имеют белый фон, до тех пор, пока ты не развернешь её.

20

Re: AHK: Перемещение ярлыков на панели задач

А, если кнопка только отрисовывается, как активная, тогда не должно быть проблем, но надо пробовать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21 (изменено: Malcev, 2021-08-07 03:05:44)

Re: AHK: Перемещение ярлыков на панели задач

Вот например:

setbatchlines -1
tbl := ComObjCreate(CLSID_TaskbarList := "{56FDF344-FD6D-11d0-958A-006097C9A090}", IID_ITaskbarList := "{56FDF342-FD6D-11d0-958A-006097C9A090}")
DllCall(NumGet(NumGet(tbl+0)+3*A_PtrSize), "ptr", tbl)   ; ITaskbarList::HrInit
WinGet, hShell_TrayWnd, id, ahk_class Shell_TrayWnd
ControlGet, hTaskbar, hwnd,, MSTaskListWClass1, ahk_id %hShell_TrayWnd%
oAcc := Acc_Get("Object", 4, 0, "ahk_id" hTaskbar)

f11::
oAccArray := [], oTaskbar := {}
loop % oAcc.accChildCount
{
   if (oAcc.accState(A_Index) != 0) and !(oAcc.accState(A_Index) & 0x00008000)   ; visible
      oAccArray.Push(A_Index)
}
hWindows := GetAltTabWindows()
for k, v in hWindows
{
   DllCall(NumGet(NumGet(tbl+0)+6*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::ActivateTab
   for k1, v1 in oAccArray
   {
      if (oAcc.accState(v1) & 0x00000008)   ; pressed
      {
         oTaskbar[v1] := v
         oAccArray.Delete(k1)
         break
      }
   }
}
if (oAccArray.Count() != 0)
{
   msgbox smth goes wrong
   return
}
for k, v in oTaskbar
{
   DllCall(NumGet(NumGet(tbl+0)+5*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::DeleteTab
   sleep 1000
}
for k, v in oTaskbar
{
   DllCall(NumGet(NumGet(tbl+0)+4*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::AddTab
   sleep 1000
}
return


GetAltTabWindows() {
   AltTabList := []
   WinGet, list, List
   Loop % list
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   Return AltTabList
}

IsAltTabWindow(hWnd) {
   static GA_ROOTOWNER := 3, WS_EX_APPWINDOW := 0x40000, WS_EX_TOOLWINDOW := 0x80, DWMWA_CLOAKED := 14
   if !DllCall("IsWindowVisible", "Ptr", hWnd)
      Return false
   
   hOwner := DllCall("GetAncestor", "Ptr", hWnd, "UInt", GA_ROOTOWNER, "Ptr")
   hPopup := DllCall("GetLastActivePopup", "Ptr", hOwner, "Ptr")
   if (hOwner = hWnd && hPopup != hWnd)
      Return false
   
   WinGet, exStyles, ExStyle, ahk_id %hWnd%
   if (exStyles & WS_EX_TOOLWINDOW) && !(exStyles & WS_EX_APPWINDOW)
      Return false
      
   DllCall("DwmApi\DwmGetWindowAttribute", "Ptr", hWnd, "UInt", DWMWA_CLOAKED, "UIntP", cloaked, "UInt", 4)
   Return !cloaked
}


; http://www.autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/
; https://dl.dropbox.com/u/47573473/Web%20Server/AHK_L/Acc.ahk
;------------------------------------------------------------------------------
; Acc.ahk Standard Library
; by Sean
; Updated by jethrow:
; 	Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1)
; 	Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs)
; 	Added Acc_GetRoleText & Acc_GetStateText
; 	Added additional functions - commented below
; 	Removed original Acc_Children function
; last updated 2/25/2010
;------------------------------------------------------------------------------

Acc_Init()
{
	Static	h
	If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromWindow(hWnd, idObject = -4)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
	Return	ComObjEnwrap(9,pacc,1)
}

Acc_WindowFromObject(pacc)
{
	If	DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
	Return	hWnd
}

Acc_GetRoleText(nRole)
{
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	Return	sRole
}

Acc_GetStateText(nState)
{
	nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
	Return	sState
}

Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
	Return	DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}

Acc_UnhookWinEvent(hHook)
{
	Return	DllCall("UnhookWinEvent", "Ptr", hHook)
}
/*	Win Events:
	pCallback := RegisterCallback("WinEventProc")
	WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
	{
		Critical
		Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
		; Code Here:
	}
*/

; Written by jethrow
Acc_Role(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
	try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
	catch
		return
	Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
	return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
	try child:=Acc.accChild(ChildId)
	return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
	static setting:=0
	return p=""?setting:setting:=p
}
Acc_Children(Acc) {
	if ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren%
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
			return Children.MaxIndex()?Children:
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
	if ComObjType(Acc,"Name")!="IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren% {
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
				if NumGet(varChildren,i-8)=9
					AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
				else
					Acc_Role(Acc, child)=Role?Children.Insert(child):
			}
			return Children.MaxIndex()?Children:, ErrorLevel:=0
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
	static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
	AccObj :=   IsObject(WinTitle)? WinTitle
			:   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
	if ComObjType(AccObj, "Name") != "IAccessible"
		ErrorLevel := "Could not access an IAccessible Object"
	else {
		StringReplace, ChildPath, ChildPath, _, %A_Space%, All
		AccError:=Acc_Error(), Acc_Error(true)
		Loop Parse, ChildPath, ., %A_Space%
			try {
				if A_LoopField is digit
					Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
				else
					RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
				if Not Children.HasKey(m2)
					throw
				AccObj := Children[m2]
			} catch {
				ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
				if Acc_Error()
					throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
				return
			}
		Acc_Error(AccError)
		StringReplace, Cmd, Cmd, %A_Space%, , All
		properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
		try {
			if (Cmd = "Location")
				AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
			  , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
			else if (Cmd = "Object")
				ret_val := AccObj
			else if Cmd in Role,State
				ret_val := Acc_%Cmd%(AccObj, ChildID+0)
			else if Cmd in ChildCount,Selection,Focus
				ret_val := AccObj["acc" Cmd]
			else
				ret_val := AccObj["acc" Cmd](ChildID+0)
		} catch {
			ErrorLevel := """" Cmd """ Cmd Not Implemented"
			if Acc_Error()
				throw Exception("Cmd Not Implemented", -1, Cmd)
			return
		}
		return ret_val, ErrorLevel:=0
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}

22 (изменено: Malcev, 2021-08-07 07:55:38)

Re: AHK: Перемещение ярлыков на панели задач

А вот так должен перемещать вкладку активного окна влево:

setbatchlines -1
tbl := ComObjCreate(CLSID_TaskbarList := "{56FDF344-FD6D-11d0-958A-006097C9A090}", IID_ITaskbarList := "{56FDF342-FD6D-11d0-958A-006097C9A090}")
DllCall(NumGet(NumGet(tbl+0)+3*A_PtrSize), "ptr", tbl)   ; ITaskbarList::HrInit
WinGet, hShell_TrayWnd, id, ahk_class Shell_TrayWnd
ControlGet, hTaskbar, hwnd,, MSTaskListWClass1, ahk_id %hShell_TrayWnd%
oAcc := Acc_Get("Object", 4, 0, "ahk_id" hTaskbar)

f11::
oAccArray := [], oTaskbar := {}, pressedCurrent := ""
loop % oAcc.accChildCount
{
   if (oAcc.accState(A_Index) != 0) and !(oAcc.accState(A_Index) & 0x00008000)   ; visible
   {
      oAccArray.Push(A_Index)
      if (oAcc.accState(A_Index) & 0x00000008)   ; pressed
         pressedCurrent := A_Index
   }
}
hWindows := GetAltTabWindows()
for k, v in hWindows
{
   owner := v
   loop
   {
      owner := DllCall("GetWindow", "ptr", owner, "uint", GW_OWNER := 4)
      if (owner != 0)
      {
         if DllCall("IsWindowVisible", "ptr", owner)
            v := owner
      }
      else
         break
   }
   DllCall(NumGet(NumGet(tbl+0)+6*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::ActivateTab
   for k1, v1 in oAccArray
   {
      if (oAcc.accState(v1) & 0x00000008)   ; pressed
      {
         if (v1 = pressedCurrent)
            oTaskbar[0] := v
         else
            oTaskbar[v1] := v
         oAccArray.Delete(k1)
         break
      }
   }
}
if (oAccArray.Count() != 0)
{
   msgbox smth goes wrong
   return
}
for k, v in oTaskbar
   DllCall(NumGet(NumGet(tbl+0)+5*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::DeleteTab
sleep 10
for k, v in oTaskbar
   DllCall(NumGet(NumGet(tbl+0)+4*A_PtrSize), "ptr", tbl, "ptr", v)   ; ITaskbarList::AddTab
return


GetAltTabWindows() {
   AltTabList := []
   WinGet, list, List
   Loop % list
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   Return AltTabList
}

IsAltTabWindow(hWnd) {
   static GA_ROOTOWNER := 3, WS_EX_APPWINDOW := 0x40000, WS_EX_TOOLWINDOW := 0x80, DWMWA_CLOAKED := 14
   if !DllCall("IsWindowVisible", "Ptr", hWnd)
      Return false
   
   hOwner := DllCall("GetAncestor", "Ptr", hWnd, "UInt", GA_ROOTOWNER, "Ptr")
   hPopup := DllCall("GetLastActivePopup", "Ptr", hOwner, "Ptr")
   if (hOwner = hWnd && hPopup != hWnd)
      Return false
   
   WinGet, exStyles, ExStyle, ahk_id %hWnd%
   if (exStyles & WS_EX_TOOLWINDOW) && !(exStyles & WS_EX_APPWINDOW)
      Return false
      
   DllCall("DwmApi\DwmGetWindowAttribute", "Ptr", hWnd, "UInt", DWMWA_CLOAKED, "UIntP", cloaked, "UInt", 4)
   Return !cloaked
}


; http://www.autohotkey.com/board/topic/77303-acc-library-ahk-l-updated-09272012/
; https://dl.dropbox.com/u/47573473/Web%20Server/AHK_L/Acc.ahk
;------------------------------------------------------------------------------
; Acc.ahk Standard Library
; by Sean
; Updated by jethrow:
; 	Modified ComObjEnwrap params from (9,pacc) --> (9,pacc,1)
; 	Changed ComObjUnwrap to ComObjValue in order to avoid AddRef (thanks fincs)
; 	Added Acc_GetRoleText & Acc_GetStateText
; 	Added additional functions - commented below
; 	Removed original Acc_Children function
; last updated 2/25/2010
;------------------------------------------------------------------------------

Acc_Init()
{
	Static	h
	If Not	h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromEvent(ByRef _idChild_, hWnd, idObject, idChild)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromEvent", "Ptr", hWnd, "UInt", idObject, "UInt", idChild, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "")
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return	ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}

Acc_ObjectFromWindow(hWnd, idObject = -4)
{
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
	Return	ComObjEnwrap(9,pacc,1)
}

Acc_WindowFromObject(pacc)
{
	If	DllCall("oleacc\WindowFromAccessibleObject", "Ptr", IsObject(pacc)?ComObjValue(pacc):pacc, "Ptr*", hWnd)=0
	Return	hWnd
}

Acc_GetRoleText(nRole)
{
	nSize := DllCall("oleacc\GetRoleText", "Uint", nRole, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sRole, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetRoleText", "Uint", nRole, "str", sRole, "Uint", nSize+1)
	Return	sRole
}

Acc_GetStateText(nState)
{
	nSize := DllCall("oleacc\GetStateText", "Uint", nState, "Ptr", 0, "Uint", 0)
	VarSetCapacity(sState, (A_IsUnicode?2:1)*nSize)
	DllCall("oleacc\GetStateText", "Uint", nState, "str", sState, "Uint", nSize+1)
	Return	sState
}

Acc_SetWinEventHook(eventMin, eventMax, pCallback)
{
	Return	DllCall("SetWinEventHook", "Uint", eventMin, "Uint", eventMax, "Uint", 0, "Ptr", pCallback, "Uint", 0, "Uint", 0, "Uint", 0)
}

Acc_UnhookWinEvent(hHook)
{
	Return	DllCall("UnhookWinEvent", "Ptr", hHook)
}
/*	Win Events:
	pCallback := RegisterCallback("WinEventProc")
	WinEventProc(hHook, event, hWnd, idObject, idChild, eventThread, eventTime)
	{
		Critical
		Acc := Acc_ObjectFromEvent(_idChild_, hWnd, idObject, idChild)
		; Code Here:
	}
*/

; Written by jethrow
Acc_Role(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetRoleText(Acc.accRole(ChildId)):"invalid object"
}
Acc_State(Acc, ChildId=0) {
	try return ComObjType(Acc,"Name")="IAccessible"?Acc_GetStateText(Acc.accState(ChildId)):"invalid object"
}
Acc_Location(Acc, ChildId=0, byref Position="") { ; adapted from Sean's code
	try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
	catch
		return
	Position := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
	return	{x:NumGet(x,0,"int"), y:NumGet(y,0,"int"), w:NumGet(w,0,"int"), h:NumGet(h,0,"int")}
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Child(Acc, ChildId=0) {
	try child:=Acc.accChild(ChildId)
	return child?Acc_Query(child):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Error(p="") {
	static setting:=0
	return p=""?setting:setting:=p
}
Acc_Children(Acc) {
	if ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren%
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
			return Children.MaxIndex()?Children:
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_ChildrenByRole(Acc, Role) {
	if ComObjType(Acc,"Name")!="IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		if DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren% {
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i)
				if NumGet(varChildren,i-8)=9
					AccChild:=Acc_Query(child), ObjRelease(child), Acc_Role(AccChild)=Role?Children.Insert(AccChild):
				else
					Acc_Role(Acc, child)=Role?Children.Insert(child):
			}
			return Children.MaxIndex()?Children:, ErrorLevel:=0
		} else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}
Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
	static properties := {Action:"DefaultAction", DoAction:"DoDefaultAction", Keyboard:"KeyboardShortcut"}
	AccObj :=   IsObject(WinTitle)? WinTitle
			:   Acc_ObjectFromWindow( WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText), 0 )
	if ComObjType(AccObj, "Name") != "IAccessible"
		ErrorLevel := "Could not access an IAccessible Object"
	else {
		StringReplace, ChildPath, ChildPath, _, %A_Space%, All
		AccError:=Acc_Error(), Acc_Error(true)
		Loop Parse, ChildPath, ., %A_Space%
			try {
				if A_LoopField is digit
					Children:=Acc_Children(AccObj), m2:=A_LoopField ; mimic "m2" output in else-statement
				else
					RegExMatch(A_LoopField, "(\D*)(\d*)", m), Children:=Acc_ChildrenByRole(AccObj, m1), m2:=(m2?m2:1)
				if Not Children.HasKey(m2)
					throw
				AccObj := Children[m2]
			} catch {
				ErrorLevel:="Cannot access ChildPath Item #" A_Index " -> " A_LoopField, Acc_Error(AccError)
				if Acc_Error()
					throw Exception("Cannot access ChildPath Item", -1, "Item #" A_Index " -> " A_LoopField)
				return
			}
		Acc_Error(AccError)
		StringReplace, Cmd, Cmd, %A_Space%, , All
		properties.HasKey(Cmd)? Cmd:=properties[Cmd]:
		try {
			if (Cmd = "Location")
				AccObj.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId)
			  , ret_val := "x" NumGet(x,0,"int") " y" NumGet(y,0,"int") " w" NumGet(w,0,"int") " h" NumGet(h,0,"int")
			else if (Cmd = "Object")
				ret_val := AccObj
			else if Cmd in Role,State
				ret_val := Acc_%Cmd%(AccObj, ChildID+0)
			else if Cmd in ChildCount,Selection,Focus
				ret_val := AccObj["acc" Cmd]
			else
				ret_val := AccObj["acc" Cmd](ChildID+0)
		} catch {
			ErrorLevel := """" Cmd """ Cmd Not Implemented"
			if Acc_Error()
				throw Exception("Cmd Not Implemented", -1, Cmd)
			return
		}
		return ret_val, ErrorLevel:=0
	}
	if Acc_Error()
		throw Exception(ErrorLevel,-1)
}

23

Re: AHK: Перемещение ярлыков на панели задач

Malcev
Ваш пример неплох, однако он не перемещает в самый левый край. Так и должно быть?

24

Re: AHK: Перемещение ярлыков на панели задач

Он должен переносить.
Но если есть закрепленные окна, то он будет перемещать после них.
Если надо, чтоб перед ними, то можно сделать проще, посмотреть координаты кнопки нажатой вкладки и переместить с помощью MouseClickDrag.
Кстати, мой код не работает с uwp окнами, так как ITaskbarList api они не поддерживают.