_GUICtrlTreeView_GetTree() 函数返回值为空
本帖最后由 jiarqq 于 2021-1-15 17:16 编辑最近在做QQ文件自动接收的小工具。任务栏图标闪烁检测,【全另存为】按钮自动化点击都还顺利,可是在点击【全另存为】按钮之后选择保存位置时遇到了麻烦。
先说一下我的整体思路吧。
第一步:
检测QQ图标是否闪烁,如果闪烁则说明两种可能,一是【来文件了】,二是【来消息了】。不管是来消息还是来文件,一律自动化点击闪烁的托盘图标以弹出聊天窗口做进一步的判断。
第二步:
检查聊天窗口是否存在【全另存为】的按钮,如果存在则判定是 【来文件了】,然后寻找该按钮的相对于窗口的坐标,然后自动化点击。这两步骤不难实现。
第三步:(卡这了)
点击【全另存为】后,会立即弹出一个浏览文件夹对话框,让你选择接收文件的路径。
我用的是思路是这样的:
A.先使用 _GUICtrlTreeView_FindItemEx(控件句柄,树目录路径) 函数,检索(树视图)指定树目录路径的项目。成功则返回:匹配树目录路径的第一个项目句柄。
B.再使用 _GUICtrlTreeView_Expand(控件 ID 或句柄,项目句柄, True)展开项目
可是,我发现 AB两个步骤都出了问题,于是我试试注册表,发现一点问题都没有。真是奇怪。
以下是我的实验过程:
测试注册表时成功展开,见下图:
#RequireAdmin
#include <GuiTreeView.au3>
Opt("GUIDataSeparatorChar", "\");定义分隔符
;~ $hTreeView = ControlGetHandle('浏览文件夹', '', 'SysTreeView321');获取树控件句柄
$hTreeView = ControlGetHandle('注册表编辑器', '', 'SysTreeView321');获取树控件句柄
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hTreeView = ' & $hTreeView & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;~ $hTreeView_Path = _GUICtrlTreeView_FindItemEx($hTreeView,'桌面\此电脑\');注意:不同系统【浏览文件夹】对话框显示的名称和路径有可能不一样,测试的时候记得改一下。
$hTreeView_Path = _GUICtrlTreeView_FindItemEx($hTreeView,'计算机\HKEY_CURRENT_USER\SOFTWARE\AutoIt v3');注意:不同系统【注册表】显示的名称或路径有可能不一样,测试的时候记得改一下。
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hTreeView_Path = ' & $hTreeView_Path & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
_GUICtrlTreeView_Expand($hTreeView,$hTreeView_Path,True);【浏览文件夹】指定路径展开失败,【注册表】指定路径展开成功,此函数没有返回值,只能看到状态:展开/折叠
测试QQ的浏览文件夹对话框,项目句柄及展开均失败。
#RequireAdmin
#include <GuiTreeView.au3>
Opt("GUIDataSeparatorChar", "\");定义分隔符
$hTreeView = ControlGetHandle('浏览文件夹', '', 'SysTreeView321');获取树控件句柄
;~ $hTreeView = ControlGetHandle('注册表编辑器', '', 'SysTreeView321');获取树控件句柄
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hTreeView = ' & $hTreeView & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$hTreeView_Path = _GUICtrlTreeView_FindItemEx($hTreeView,'桌面\此电脑\');注意:不同系统【浏览文件夹】对话框显示的名称和路径有可能不一样,测试的时候记得改一下。
;~ $hTreeView_Path = _GUICtrlTreeView_FindItemEx($hTreeView,'计算机\HKEY_CURRENT_USER\SOFTWARE\AutoIt v3');注意:不同系统【注册表】显示的名称或路径有可能不一样,测试的时候记得改一下。
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hTreeView_Path = ' & $hTreeView_Path & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
_GUICtrlTreeView_Expand($hTreeView,$hTreeView_Path,True);【浏览文件夹】指定路径展开失败,【注册表】指定路径展开成功,此函数没有返回值,只能看到状态:展开/折叠
对QQ的gui判断会有问题,我更建议是屏幕像素检测。 试试这样#include <GuiTreeView.au3>
#RequireAdmin
#AutoIt3Wrapper_UseX64 = n
DllCall('User32.dll', 'BOOL', 'SetProcessDPIAware')
Local $hWnd_Control = ControlGetHandle('','','SysTreeView321')
Local $sExpandPath = '此电脑\Desktop\新建文件夹' , $sName
Local $aSplit = StringSplit($sExpandPath, '\', 2)
For $i = 0 To UBound($aSplit) - 1
$sName = $aSplit[$i]
_Expand($hWnd_Control ,$sName)
If @error Then Exit MsgBox(0,0,'Err')
If $i <> UBound($aSplit) -1 Then Sleep(800)
Next
ControlClick('','','')
Func _Expand($hWnd_Control, $sName)
Local $hItem = _GUICtrlTreeView_FindItem($hWnd_Control,$sName)
If Not $hItem Then Return SetError(1,0,'')
_GUICtrlTreeView_Expand($hWnd_Control, $hItem, True)
_GUICtrlTreeView_SetSelected($hWnd_Control,$hItem , True)
_GUICtrlTreeView_ClickItem($hWnd_Control, $hItem)
EndFunc ;==>_Expand
zghwelcome 发表于 2021-1-15 21:24
试试这样
这样测试好像不行亲 控件句柄都没获取到,后面怎么可能继续…
建议贴上窗口探测信息以参考 afan 发表于 2021-1-16 19:26
控件句柄都没获取到,后面怎么可能继续…
建议贴上窗口探测信息以参考
窗口句柄获取到了, jiarqq 发表于 2021-1-16 19:41
窗口句柄获取到了,
控件
窗口何用? afan 发表于 2021-1-16 19:46
控件
窗口何用?
控件句柄已经获取到了 jiarqq 发表于 2021-1-16 20:07
控件句柄已经获取到了
不说了。
afan 发表于 2021-1-16 20:32
不说了。
确实是函数的问题,这样改一下就可以了。
Func _GUICtrlTreeView_GetText32($hWnd, $hItem = 0)
If Not IsHWnd($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hWnd, $hItem)
If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
If $hItem = 0x00000000 Then Return SetError(1, 1, "")
; All 8 byte data types for a 64 bit system changed to 4 byte uint's for a 32 bit system
Local $tagTVITEMEX32 = "struct; uint Mask;struct; uint hItem;uint State;uint StateMask;uint Text;int TextMax;int Image;int SelectedImage;int Children;uint Param; endstruct;" & _
"int Integral;uint uStateEx;uint hwnd;int iExpandedImage;int iReserved; endstruct"
Local $tTVITEM = DllStructCreate($tagTVITEMEX32)
Local $tText
Local $fUnicode = _GUICtrlTreeView_GetUnicodeFormat($hWnd)
If $fUnicode Then
$tText = DllStructCreate("wchar Buffer"); create a text 'area' for receiving the text
Else
$tText = DllStructCreate("char Buffer"); create a text 'area' for receiving the text
EndIf
DllStructSetData($tTVITEM, "Mask", $TVIF_TEXT)
DllStructSetData($tTVITEM, "hItem", BitShift( $hItem, -32 )) ; 8 byte value --> 4 byte value
DllStructSetData($tTVITEM, "TextMax", 4096)
If _WinAPI_InProcess($hWnd, $__ghTVLastWnd) Then
DllStructSetData($tTVITEM, "Text", DllStructGetPtr($tText))
_SendMessage($hWnd, $TVM_GETITEMW, 0, $tTVITEM, 0, "wparam", "struct*")
Else
Local $iItem = DllStructGetSize($tTVITEM)
Local $tMemMap
Local $pMemory = _MemInit($hWnd, $iItem + 4096, $tMemMap)
Local $pText = $pMemory + $iItem
DllStructSetData($tTVITEM, "Text", BitShift( $pText, -32 )) ; 8 byte value --> 4 byte value
_MemWrite($tMemMap, $tTVITEM, $pMemory, $iItem)
If $fUnicode Then
_SendMessage($hWnd, $TVM_GETITEMW, 0, BitShift( $pMemory, -32 ), 0, "wparam", "ptr") ; 8 byte value --> 4 byte value
Else
_SendMessage($hWnd, $TVM_GETITEMA, 0, $pMemory, 0, "wparam", "ptr")
EndIf
_MemRead($tMemMap, $pText, $tText, 4096)
_MemFree($tMemMap)
EndIf
Return DllStructGetData($tText, "Buffer")
EndFunc
参考链接:https://www.autoitscript.com/forum/topic/173529-guictrltreeview-udf-64bit-script-on-x86-control/?tab=comments#comment-1255321
另附32位的UDF
大工告成:
本帖最后由 jiarqq 于 2021-1-17 02:16 编辑
jiarqq 发表于 2021-1-17 02:03
确实是函数的问题,这样改一下就可以了。
试了下标准函数 ControlTreeView 也同样不能获取到项目句柄。
看了下备注:在 64 位 Windows 系统上运行 32 位的 AutoIt 时,部分命令可能无效, 此时请使用 64 位 AutoIt 版本.
另一处备注:使用 32 位 Autoit 进程读取 64 位进程时,命令可能会失败. 同理,反之也可能失败.
也许如此吧!
本帖最后由 jiarqq 于 2021-1-17 16:00 编辑
jiarqq 发表于 2021-1-17 02:14
试了下标准函数 ControlTreeView 也同样不能获取到项目句柄。
看了下备注:在 64 位 Windows 系统上运 ...
QQ是32位进程,而我使用的是AutoIt3_x64运行的脚本。
页:
[1]