VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 191|回复: 3

[求助] VB如何读取网页中鼠标右击时产生菜单选项中的文字

[复制链接]
发表于 2017-4-27 12:31:14 | 显示全部楼层 |阅读模式
        在vb运行过程中,我在任意浏览器打开的网页中,右击鼠标,得到一个菜单,然后用上下键移动光标到某一个选项上面(一般会自动加深背景色)。

         这时VB的立即窗口中要显示出这个选项中的文字。

请问代码如何写呢?听说与屏幕取词有关,但我找到的取词软件不太合适,原因是:1、它会关闭浏览器,只读取word右击菜单 ;2、如果不关闭浏览器,就读取不了。具体见附件。

屏幕取词.rar

50.87 KB, 下载次数: 4

发表于 2017-5-1 22:47:39 | 显示全部楼层
如果是IE浏览器应该可以通过获得IE对象来操作,如果是别的浏览器,估计要学一下JAVA写插件。
再就是以前看过一个鼠标取词的原理,就是获得迫使鼠标处的文字在屏幕上从新绘制,接管后获得文字,这样只要是显示的文本都可以捕获。不过作者只是讲了原理。也不是VB能做出来的。
还有一种就是屏幕识图,这个VB到可以,就是ocr技术,虽然VB效率不高,但确实可以做出来。如果要简单马上做出来,可以将菜单截图,保存,然后通过动态刷屏比较。或者是将字体提取作字模,然后识别,也是可行的。
当然,最简单的就是操作IE对象。如果是IE对象,在浏览器弹出一个对话框后,程序会卡住,VB也没有什么多线程,不过可以写一个针对弹窗处理的功能软件。

评分

参与人数 1威望 +5 人气 +1 收起 理由
bruly + 5 + 1 赞一个

查看全部评分

回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
有点进展,但不成功,具体如下:
1. 在窗体上添加一个timer,设置其Interval为200毫秒;
2. 用GetCursorPos获取鼠标位置
3. 用WindowFromPoint获取鼠标所指向的窗口hwnd,用GetClassName获取类名,如果类名为"#32768",说明它是弹出菜单(整个系统的弹出菜单都是这个类名,必要的话可通过进程名称进一步判断,但这不是重点)
4. 对于弹出菜单,向这个hwnd发送一个MN_GETHMENU消息(Const MN_GETHMENU = &H1E1)得到菜单句柄hMenu,语法hMenu = SendMessage(hwnd, MN_GETHMENU, 0, 0)
5. 用GetMenuItemCount(hMenu)可以获取正确的菜单项数目
6. 用for...next遍历所有菜单项,用If GetMenuState(hMenu, i, MF_BYPOSITION) And MF_HILITE可以判断当前高亮的菜单项索引
到第6步都没有问题,但是获取菜单项文字时遇到困难,用GetMenuString和GetMenuItemInfo均告失败,希望有高手能接力完成
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
补充说明一下,对于VB本身窗体上用PopupMenu弹出的菜单,用GetMenuString(hMenu, i, VarPtr(buffer(0)), 256, MF_BYPOSITION)或者GetMenuString(hMenu, i, sBuffer, 256, MF_BYPOSITION)可以获得正确的菜单项标题(前者的GetMenuString声明时第三个参数用ByVal lpString As Long并用Ridim buffer(255)初始化数组,后者用ByVal lpString As Long并用sBuffer=Space(256)初始化缓冲字符串),所以初步判断是跨进程的问题
之后用GetWindowThreadProcessId、OpenProcess/CloseHandel、VirtualAllocEx/VirtualFreeEx、ReadProcessMemory在获取菜单所在进程并在其中分配内存缓冲区域用于接收菜单标题,试验了一下,对于VB当前进程仍然可以用下列代码获取正确的菜单项标题,但对于其他窗口(包括IE或者记事本)的右键菜单,程序就会闪退。
  1. Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
  2. Private Type POINTAPI
  3.         X As Long
  4.         Y As Long
  5. End Type

  6. Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
  7. Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
  8. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  9. Private Const MN_GETHMENU = &H1E1

  10. Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
  11. Private Declare Function GetMenuState Lib "user32" (ByVal hMenu As Long, ByVal wID As Long, ByVal wFlags As Long) As Long
  12. Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As Long, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long
  13. Private Const MF_BYPOSITION = &H400&
  14. Private Const MF_BYCOMMAND = &H0&
  15. Private Const MF_HILITE = &H80
  16. Private Const MAX_PATH = 260


  17. Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
  18. Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
  19. Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
  20. Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
  21. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  22. Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long

  23. Private Const PROCESS_QUERY_INFORMATION = 1024
  24. Private Const PROCESS_VM_OPERATION = &H8
  25. Private Const PROCESS_VM_READ = &H10
  26. Private Const PROCESS_VM_WRITE = &H20
  27. Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
  28. Private Const MEM_COMMIT = &H1000
  29. Private Const MEM_RELEASE = &H8000
  30. Private Const PAGE_READWRITE = &H4



  31. Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  32.     '测试代码,在窗体上添加一个名为aaa的菜单,并添加一个以上子菜单项
  33.     PopupMenu aaa
  34. End Sub

  35. Private Sub Timer1_Timer()
  36.     Dim hwnd As Long, hMenu As Long
  37.     Dim sClassName As String
  38.     Dim p As POINTAPI
  39.     Dim lItemCount As Long
  40.     Dim i As Long
  41.     Dim lRet As Long
  42.    
  43.     GetCursorPos p
  44.     hwnd = WindowFromPoint(p.X, p.Y)
  45.     sClassName = Space(255)
  46.     lRet = GetClassName(hwnd, sClassName, 255)
  47.     sClassName = Left(sClassName, lRet)
  48.     If sClassName = "#32768" Then
  49.         hMenu = SendMessage(hwnd, MN_GETHMENU, 0, 0)
  50.         lItemCount = GetMenuItemCount(hMenu)
  51.         For i = 0 To lItemCount - 1
  52.             If GetMenuState(hMenu, i, MF_BYPOSITION) And MF_HILITE Then
  53.                 Dim pID As Long
  54.                 Dim pHandle As Long
  55.                 Dim pStrBuffer As Long
  56.                 GetWindowThreadProcessId hwnd, pID
  57.                 pHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, pID)
  58.                 pStrBuffer = VirtualAllocEx(pHandle, 0, MAX_PATH, MEM_COMMIT, PAGE_READWRITE)

  59.                
  60.                 lRet = GetMenuString(hMenu, i, ByVal pStrBuffer, MAX_PATH, MF_BYPOSITION)
  61.                 If lRet > 0 Then
  62.                     Dim buffer() As Byte
  63.                     ReDim buffer(lRet)
  64.                     ReadProcessMemory pHandle, ByVal pStrBuffer, buffer(0), lRet, 0
  65.                     Debug.Print StrConv(buffer, vbUnicode)
  66.                 End If
  67.                 VirtualFreeEx pHandle, pStrBuffer, MAX_PATH, MEM_RELEASE
  68.                 CloseHandle pHandle
  69.             End If
  70.         Next
  71.     End If
  72. End Sub
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2017-5-28 12:48

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表