日期:2014-05-20  浏览次数:21061 次

200分继续求[C#屏幕取词]
上个帖子结贴继续求屏幕取词。

以下是找到的一些资料
这是取词的原理
C# code
0 判断鼠标是否在一个地方停留了一段时间 
1 取得鼠标当前位置 
2 以鼠标位置为中心生成一个矩形 
3 挂上API钩子 
4 让这个矩形产生重画消息 
5 在钩子里等输出字符 
6 计算鼠标在哪个单词上面,把这个单词保存下来 
7 如果得到单词则摘掉API钩子,在一段时间后,无论是否得到单词都摘掉API钩子 
8 用单词查词库,显示解释框。 


C# code

1. 安装鼠标钩子,通过钩子函数获得鼠标消息。

  使用到的API函数:SetWindowsHookEx

  2. 得到鼠标的当前位置,向鼠标下的窗口发重画消息,让它调用系统函数重画窗口。

  使用到的API函数:WindowFromPoint,ScreenToClient,InvalidateRect

  3. 截获对系统函数的调用,取得参数,也就是我们要取的词。
使用到的API函数TextOutA


这些API在C#中怎么使用?如何安装鼠标钩子,更重要的是如何向鼠标下的窗口发重画消息。

金山词霸的方案基本不可行,因为会涉及到版权问题。除此之外还有调用系统API,或者直接用nhw32.dll这个别人写好的取词DLL。但是没有C#的使用方法。自己试了下,不可以。

nhw32.dll说明

nhw32.dll 主要引出两个函数:

1. DWORD WINAPI BL_SetFlag32(UINT nFlag,
  HWND hNotifyWnd,
  int MouseX, 
  int MouseY)
  功能:
启动或停止取词。
  参数:
  nFlag 
  [输入] 指定下列值之一:
  GETWORD_ENABLE: 开始取词。在重画被取单词区域前设置此标志。nhw32.dll是通过
  重画单词区域,截取TextOutA, TextOutW, ExtTextOutA, 
  ExtTextOutW等Windows API函数的参数来取词的。
  GETWORD_DISABLE: 停止取词。
  hNotifyWnd 
  [输入] 通知窗口句柄。当取到此时,向该通知窗口发送一登记消息:GWMSG_GETWORDOK。
  MouseX 
[输入] 指定取词点的X坐标。
  MouseY 
  [输入] 指定取词点的Y坐标。
  返回值:
  可忽略。
2. DWORD WINAPI BL_GetText32(LPSTR lpszCurWord, 
  int nBufferSize, 
  LPRECT lpWordRect)
  功能:
从内部缓冲区取出单词文本串。对英语文本,该函数最长取出一行内以空格为界的三个英文单词串,遇空格,非英文字母及除‘-’外的标点符号,则终止取词。对汉字文本,该函数最长取出一行汉字串,遇英语字母,标点符号等非汉语字符,则终止取词。该函数不能同时取出英语和汉语字符。
  参数:
  lpszCurWord
  [输入] 目的缓冲区指针。
  nBufferSize
  [输入] 目的缓冲区大小。
  lpWordRect
  [输出] 指向 RECT 结构的指针。该结构定义了被取单词所在矩形区域。
  返回值:
  当前光标在全部词中的位置。

C# code

--我在C#中的引用方法,可能是错误的。
  [DllImport(@"C:\Users\xxxx\Documents\Visual Studio 2008\Projects\getWord\getWord\bin\Debug\nhw32.dll")]
        private static extern uint BL_SetFlag32(uint nFlag, IntPtr hNotifyWnd, int MouseX, int MouseY);
         [DllImport(@"C:\Users\xxxxx\Documents\Visual Studio 2008\Projects\getWord\getWord\bin\Debug\nhw32.dll")]
        private static extern uint BL_GetText32([MarshalAs(UnmanagedType.LPStr)]StringBuilder lpszCurWord, int nBufferSize, ref Rectangle lpWordRect);



------解决方案--------------------
个人觉得 完全依靠API 都很困难, 可能需要非常手段去切入其他进程

尽管可以用C#代码来实现,但是C#这时仅是一个包装了。

还是要老 unsafe代码实现。 建议楼主去C++版问
------解决方案--------------------
探讨
。。。

现在我不太明白
4 让这个矩形产生重画消息
这一步怎么实现。
有那位大哥知道么