“浏览文件夹”中的定位,AHKL版

#SingleInstance force
#NoEnv
#include RemoteBuf.ahk
F8::FileSelectFolder,x,,  ;面对这个窗口进行测试
F9::
	hwEx   := WinExist("A")
	ControlGet,hwtv,hwnd,,SysTreeView321,ahk_id %hwex%
	if hwtv=
		Return
	TV_Initialise(hwEx, hwTV)
	TV_SetPath("D:test")
	return

esc::ExitApp


TV_Initialise( hwParent, hwTV )
{
	global
	static init

	TV_hwHost		:= hwParent
	TV_hwTV			:= hwTV

	;API MESSAGES
	if !init
	{
		TVE_EXPAND		= 2

		TVM_EXPAND		= 0x1102
		TVM_GETITEM		= 0x110C
		TVM_GETNEXTITEM = 0x110A
		TVM_SELECTITEM  = 4363

		TVGN_ROOT		= 0
		TVGN_NEXT		= 1
		TVGN_CHILD		= 4
		TVGN_PARENT		= 3
		TVGN_CARET		= 9

		TVIF_STATE		= 8
		TVIS_SELECTED	= 2

		init := true
	}
}

TV_FindDrive( drive )
{
	global TV_hwTV, TVGN_ROOT, TVM_GETNEXTITEM
	myComputer := TV_GetResString("{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
	;get root

	SendMessage TVM_GETNEXTITEM, TVGN_ROOT, 0, ,ahk_id %TV_hwTV%
	root = %ErrorLevel%
	hwMC := TV_FindChild( root, myComputer )

	TV_Expand( hwMC )

  	return TV_FindChild( hwMC, drive, 1 )
; 	return 67071312

}

TV_SetPath( path )
{
	global TV_hwTV

	StringLeft drive, path, 2
 	parent := TV_FindDrive( drive )
; 	MsgBox %parent%
 	TV_Expand( parent )

	loop, Parse, path, 
	{
		;skip drive, I already set this
		if (A_Index = 1)
			 continue


		child := TV_FindChild(parent, A_LoopField)

		if (child = 0)
			return 0

		parent := child

		;it appers that when expanding drive it needs more time
		if (A_Index = 2)
			TV_Expand( parent, 200)
		else
			TV_Expand( parent )

	}

	return TV_Select(parent)
}

TV_Select( item )
{
	global
	SendMessage TVM_SELECTITEM, TVGN_CARET, item, ,ahk_id %TV_hwTV%
	return %ErrorLevel%
}

TV_Expand( item, waitTime=50 )
{
	global
	SendMessage TVM_EXPAND, TVE_EXPAND, item, ,ahk_id %TV_hwTV%
	Sleep %waitTime%	;allow it to expand
	return %ErrorLevel%
}

TV_FindChild( p_start, p_txt, p_mode=0 )
{
	global TV_hwHost, TV_hwTV, TVM_GETITEM, TVM_GETNEXTITEM, TVGN_CHILD, TVGN_NEXT

	;open remote buffers
	RemoteBuf_Open(bufID,TV_hwHost, 128)
	bufAdr  := RemoteBuf_Get(bufID)

	;Copy items name to the host adr space
	; so I can compare strings there, without transfering them here
	RemoteBuf_Open(r_txt,TV_hwHost, 128)
	;r_txtAdr := RemoteBuf_Get( text )
	;RemoteBuf_Write( r_txt, txt, strlen(txt) )

	RemoteBuf_Open(r_sTV,TV_hwHost, 40)
	r_stvAdr := RemoteBuf_Get(r_sTV)

	VarSetCapacity(sTV,   40, 1)    ;10x4 = 40
	NumPut(0x011,  sTV, 0)   ;set mask to TVIF_TEXT | TVIF_HANDLE  = 0x001 | 0x0010
	NumPut(bufAdr, sTV, 16)  ;set txt pointer
	NumPut(127,    sTV, 20)  ;set txt size


	;get first child
	SendMessage TVM_GETNEXTITEM, TVGN_CHILD, p_start, ,ahk_id %TV_hwTV%
	child = %ErrorLevel%
; /*
	loop
	{
		;set TVITEM item handle
		NumPut(child, sTV, 4)
	    RemoteBuf_Write(r_sTV, sTV, 40)

		;get the text
		SendMessage TVM_GETITEM, 0, r_stvAdr ,, ahk_id %TV_hwTV%
		VarSetCapacity(txt, 128, 1)
	    RemoteBuf_Read(bufID, txt, 64 )
		txt := StrGet(&txt,64,"CP0")
		if (p_mode=0)
			if (txt = p_txt)
				break

		if (p_mode=1)
			 if InStr(txt, p_txt)
				break


		;get next sybiling
		SendMessage TVM_GETNEXTITEM, TVGN_NEXT, child, ,ahk_id %TV_hwTV%
		child = %ErrorLevel%
		if (child=0)
			break
	}

	RemoteBuf_Close( r_sTV )
	RemoteBuf_Close( r_txt )
	RemoteBuf_Close( bufID )
; */
	return %child%
}


TV_GetTxt( item )
{
	global TV_hwHost, TV_hwTV, TVM_GETITEM

	;open remote buffers
	RemoteBuf_Open(bufID,TV_hwHost, 128)
	bufAdr  := RemoteBuf_Get(bufID)

	 RemoteBuf_Open(r_sTV,TV_hwHost, 40)
	r_stvAdr := RemoteBuf_Get(r_sTV)

	VarSetCapacity(sTV,   40, 1)    ;10x4 = 40
	NumPut(0x011,  sTV, 0)   ;set mask to TVIF_TEXT | TVIF_HANDLE  = 0x001 | 0x0010
	NumPut(bufAdr, sTV, 16)  ;set txt pointer
	NumPut(127,    sTV, 20)  ;set txt size

	;set TVITEM item handle
    NumGet(item, sTV, 4)
    RemoteBuf_Write(r_sTV, sTV, 40)

	;get the text
    SendMessage TVM_GETITEM, 0, r_stvAdr ,, ahk_id %TV_hwTV%

	;read from remote buffer
	VarSetCapacity(txt, 128, 1)
    RemoteBuf_Read(bufID, txt, 64 )

	RemoteBuf_Close( bufID )
	RemoteBuf_Close( r_sTV )

	return txt
}

TV_GetPath()
{
    global TV_hwHost, TV_hwTV, TVM_GETITEM, TVM_GETNEXTITEM, TVGN_PARENT, TVGN_NEXT, TVGN_ROOT, TVGN_CARET

   ;open remote buffers
	 RemoteBuf_Open(bufID,TV_hwHost, 64)
	bufAdr   := RemoteBuf_Get(bufID)

 RemoteBuf_Open(r_sTV,TV_hwHost, 40)
	r_stvAdr   := RemoteBuf_Get(r_sTV)

	;get root
	SendMessage TVM_GETNEXTITEM, TVGN_ROOT, 0, ,ahk_id %TV_hwTV%
	root = %ErrorLevel%

	;get current selection
	SendMessage TVM_GETNEXTITEM, TVGN_CARET, 0, ,ahk_id %TV_hwTV%
	item = %ErrorLevel%

	VarSetCapacity(sTV,   40, 1)     ;10x4 = 40
	NumPut(0x011,   sTV, 0)   ;set mask to TVIF_TEXT | TVIF_HANDLE  = 0x001 | 0x0010
	NumPut(bufAdr,  sTV, 16)  ;set txt pointer
	NumPut(127,     sTV, 20)  ;set txt size

	VarSetCapacity(txt, 64, 1)

	loop
	{
      ;set TVITEM item handle
      NumPut(item, sTV, 4)
      RemoteBuf_Write(r_sTV, sTV, 40)

      ;send tv_getitem message
      SendMessage TVM_GETITEM, 0, r_stvAdr ,, ahk_id %TV_hwTV%

      ;read from remote buffer and append the path
      RemoteBuf_Read(bufID, txt, 64 )

      ;check for the drive
      StringGetPos i, txt, :
      if i > 0
      {
         StringMid txt, txt, i, 2
         epath = %txt%%epath%
         break
      }
      else
         epath := txt "" epath

      ;get parent
      SendMessage TVM_GETNEXTITEM, TVGN_PARENT, item, ,ahk_id %TV_hwTV%
      item = %ErrorLevel%
      if (item = root)
         break
   }

	RemoteBuf_Close( bufID )
	RemoteBuf_Close( r_sTV )


	StringLeft epath, epath, strlen(epath)-1
	return epath
}

;-----------------------------------------------------------------------------------------
; PRIVATE
;-----------------------------------------------------------------------------------------

TV_getResString( p_clsid )
{
	key = SOFTWAREClassesCLSID%p_clsid%
	RegRead res, HKEY_LOCAL_MACHINE, %key%, LocalizedString

;get dll and resource id
	StringGetPos idx, res, -, R
    StringMid, resID, res, idx+2, 256
	StringMid, resDll, res, 2, idx - 2
	resDll := TV_ExpandEnvVars(resDll)

;get string from resource
	VarSetCapacity(buf, 256)
	hDll := DllCall("LoadLibrary", "str", resDll)
	Result := DllCall("LoadString", "uint", hDll, "uint", resID, "str", buf, "int", 128)

	return buf
}

;-----------------------------------------------------------------------------------------

TV_expandEnvVars(ppath)
{
	VarSetCapacity(dest, 2000)
	DllCall("ExpandEnvironmentStrings", "str", ppath, "str", dest, int, 1999, "Cdecl int")
	return dest
}

;---------------------------------------------------------------------------------------------------------------------
; Group: About
;      o Ver 1.0 by majkinetor. See 
;      o Licenced under Creative Commons Attribution-Noncommercial 

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

AHK调试工具

2020-3-21 1:43:00

其他

Cando_AHKCHM连查带搜

2020-3-21 11:54:55

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索