200分,求抓金山词霸Listview内容的解决方法 ( 积分: 200 )

  • 主题发起人 主题发起人 citypanther
  • 开始时间 开始时间
这种风格的 ListView控件, 的确有另外一种方法取出表项:<br><br>function ListView_GetItemText_Mz(hListView: HWnd; iItem, iSubItem: Integer; pszText: PChar; cchTextMax: Integer): Integer;<br>var<br> &nbsp;DispInfo: TLVDispInfo;<br>begin<br> &nbsp;DispInfo.hdr.hwndFrom := hListView;<br> &nbsp;DispInfo.hdr.idFrom := GetDlgCtrlID(hListView);<br> &nbsp;DispInfo.hdr.code := LVN_GETDISPINFO;<br><br> &nbsp;ZeroMemory(@DispInfo.item, SizeOf(DispInfo.item)); &nbsp;<br> &nbsp;DispInfo.item.mask := LVIF_TEXT;<br> &nbsp;DispInfo.item.iItem := iItem;<br> &nbsp;DispInfo.item.iSubItem := iSubItem;<br> &nbsp;DispInfo.item.pszText := pszText;<br> &nbsp;DispInfo.item.cchTextMax := cchTextMax;<br><br> &nbsp;Result := SendMessage(GetParent(hListView), WM_NOTIFY, GetDlgCtrlID(hListView), Integer(@DispInfo));<br>end;<br><br>利用Hook进入Delphi自带例子&quot;Virtual Listview&quot;, 可以用成功读取, 但是, 利用Hook进入词霸进程, 读到的仍然是&quot;1234567890..&quot;, :)
 
另外, 我试了一下, 象这种LVS_OWNERDATA风格的 ListView, 也可以用 LVM_GETITEMTEXT 读出信息的, :)
 
至于《金山词霸2002》, 列表用的是TreeView, 倒可以读出来的, 测试代码如下:<br><br>--------------------<br>unit TreeViewEx;<br><br>interface<br><br>uses Windows;<br><br> &nbsp;// 读取TreeView存至ListBox, ^^<br>procedure TreeView_To_ListBox_Mz(hTreeView, hListBox: HWnd);<br><br>implementation<br><br>uses Messages, CommCtrl;<br><br> &nbsp;// 跨进程的 TreeView_GetItem<br>function TreeView_GetItem_Ex(hwndTV: HWND; var TVItem: TTVItem): Bool;<br>var<br> &nbsp;ProcessID, ProcessHD, Temp: DWORD;<br> &nbsp;pszText, MemPoint: Pointer;<br>begin<br> &nbsp;Result := FALSE;<br><br> &nbsp;GetWindowThreadProcessId(hwndTV, ProcessID);<br><br> &nbsp;ProcessHD := OpenProcess(<br> &nbsp; &nbsp;PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, FALSE, ProcessID);<br> &nbsp;if (ProcessHD = 0) then Exit;<br><br> &nbsp;MemPoint := VirtualAllocEx(ProcessHD, nil,<br> &nbsp; &nbsp;SizeOf(TTVItem) + TVItem.cchTextMax + 1,<br> &nbsp; &nbsp;MEM_COMMIT, PAGE_READWRITE);<br> &nbsp;if (MemPoint = nil) then Exit;<br><br> &nbsp;pszText := TVItem.pszText; // 保存本进程地址<br> &nbsp;PChar(pszText)^ := #0;<br> &nbsp;TVItem.pszText := PChar(Integer(MemPoint) + SizeOf(TTVItem));<br> &nbsp;if (WriteProcessMemory(ProcessHD, MemPoint, @TVItem, SizeOf(TVItem), Temp) = FALSE) then Exit;<br> &nbsp;if (WriteProcessMemory(ProcessHD, TVItem.pszText, pszText, 1, Temp) = FALSE) then Exit;<br><br> &nbsp;Result := (SendMessage(hwndTV, TVM_GETITEM, 0, LongInt(MemPoint)) &lt;&gt; 0);<br><br> &nbsp;if (ReadProcessMemory(ProcessHD, TVItem.pszText, pszText, TVItem.cchTextMax + 1, Temp) = FALSE) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := FALSE;<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br> &nbsp;TVItem.pszText := pszText; // 恢复本进程地址<br><br> &nbsp;VirtualFreeEx(ProcessHD, MemPoint, SizeOf(TTVItem) + TVItem.cchTextMax + 1, MEM_DECOMMIT);<br> &nbsp;VirtualFreeEx(ProcessHD, MemPoint, 0, MEM_RELEASE);<br>end;<br><br> &nbsp;// 读取指定 TreeView 子项目文字<br>function TreeView_GetItem_Text(hwndTV: HWND; hitem: HTreeItem): string;<br>var<br> &nbsp;Buffer: array[0..50] of Char;<br> &nbsp;TVItem: TTVItem;<br>begin<br> &nbsp;TVItem.hItem := hitem;<br> &nbsp;TVItem.mask := TVIF_TEXT;<br> &nbsp;TVItem.pszText := @Buffer[0];<br> &nbsp;TVItem.cchTextMax := 50;<br><br> &nbsp;if TreeView_GetItem_Ex(hwndTV, TVItem) then<br> &nbsp; &nbsp;Result := Buffer<br> &nbsp;else<br> &nbsp; &nbsp;Result := '';<br>end;<br><br> &nbsp;// 读取TreeView存至ListBox, ^^<br>procedure TreeView_To_ListBox_Mz(hTreeView, hListBox: HWnd);<br>var<br> &nbsp;CurNode: HTreeItem;<br> &nbsp;CurText: string;<br>begin<br> &nbsp;CurNode := TreeView_GetRoot(hTreeView);<br> &nbsp;while (CurNode &lt;&gt; nil) do<br> &nbsp;begin<br> &nbsp; &nbsp;CurText := TreeView_GetItem_Text(hTreeView, CurNode);<br> &nbsp; &nbsp;if (CurText &lt;&gt; '') then SendMessage(hListBox, LB_ADDSTRING, 0, Integer(PChar(CurText)));<br><br> &nbsp; &nbsp;CurNode := TreeView_GetNextSibling(hTreeView, CurNode); // Next ..<br> &nbsp;end;<br>end;<br><br>end.<br><br>--------------------<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;TreeView_To_ListBox_Mz(xxxx, ListBox1.Handle);<br>end;<br><br>--------------------
 
对于2005版, 想到一个变通的方法, 没有试啊.. 界面上不是有一个 Edit, 显示当前选中的单词吗? 这个内容是可以读出来的, 那么, 我们可以用程序, 依次选中列表中各个项目, 同时读取之, 即可…… [:D]
 
麻子的这种方法跟我想的一样,只要写一个简单的机器人就可以搞定了<br>但是速度可能比较慢,另外就是如何判断读取完毕<br><br>麻子可真是厉害啊,什么都难不倒你啊!
 
我已经用变通的方法将列表全部读取了. &nbsp; 就是在窗口激活的情况下向listview发key_down消息. &nbsp;开始的时候遇到一点困难: 那就是循环时发key_down消息的频率和读取Tedit的频率不一样. 导致读到的词比列表中的词少很多.<br>后来以edit窗口中单词改变为trigger出发key_down事件,成功. <br>整个读取过程大概用了半个小时(什么都不碰,干看着:) &nbsp; 一共抓了457000+个单词.....差点把listbox给撑死:).<br><br>To 麻子哥 &nbsp; &nbsp;你给我的代码没有收到:) 能不能再给发一个.<br><br>感谢大家参与. 现在散分;)
 
发了, 如果还收不到, 请到此处, http://liumazi.ys168.com/ ,下载&quot;临时目录&quot;中的Hook_xdict.rar
 
临时目录中怎么没有这个文件?
 
呵呵, 刚刚上传, 不好意思, :~)
 
看到了,有了. 难道是我太快?.......汉
 
后退
顶部