VBGood网站全文搜索 Google

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

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
12
返回列表 发新帖
楼主: hd37

[原创] 全局拦截并修改输入法输入的模块(源码)

[复制链接]
发表于 2009-2-18 19:02:44 | 显示全部楼层
貌似现在好多火星文输入法软件都都是用这个源码改也的,确切的说,那输入法不是真正的IME,而是外挂。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-2-18 23:14:15 | 显示全部楼层
那个hxwdllwx.dll的源码也在压缩包里面的,有个文件夹hxwdllwx里面就是了,不过是VC的。因为比较稳定又简单的全局API HOOK似乎还是用DLL的比较普遍,而制作标准DLL用VB比较的难,所以只好用C来写咯。个人觉得用VB来做界面,C来完成系统方面的事也是个不错的主意,可以发挥各自的特点嘛。
回复 支持 反对

使用道具 举报

发表于 2009-4-12 01:19:21 | 显示全部楼层
支持。
回复 支持 反对

使用道具 举报

发表于 2009-4-15 21:16:13 | 显示全部楼层
好东西,收藏。
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2009-4-21 17:27:34 | 显示全部楼层
下来收藏啊,研究研究,谢谢啊!
回复 支持 反对

使用道具 举报

发表于 2010-8-8 09:48:23 | 显示全部楼层
很需要!k[[e[lpiop0-=[ljj''/.
回复 支持 反对

使用道具 举报

发表于 2010-9-28 10:16:39 | 显示全部楼层
很想知道,在C的IDE里,在这个函数上(按F9)下断点,为什么断不下来?
LONG WINAPI myImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
{
        LONG myReturn=0;
        LONG tempLen=0;
        int StrBufLen=0;
        if (dwIndex==GCS_RESULTSTR && g_HOOKflag)
        {
                memset(g_IMEString,0,256);
                tempLen=255;
                g_myHOOK1.HookStatus(false);
                ImmGetCompositionStringA(hIMC,GCS_RESULTSTR,g_IMEString,tempLen);
                g_myHOOK1.HookStatus(true);
                g_IMEString[tempLen]=0;
                if (lstrcmp(g_IMEString,g_StringBuf1)!=0)
                {
                        memset(g_StringBuf1,0,256);
                        lstrcpy(g_StringBuf1,g_IMEString);
                        SendMessage(g_hMainhWnd,WM_HXWDLLWX_QQBTX,0,0);
                        memset(g_StringBuf2,0,256);
                        lstrcpy(g_StringBuf2,g_IMEString);
                }
                if (lpBuf==NULL || dwBufLen==0)
                {
                        myReturn=lstrlen(g_StringBuf2);
                }
                else
                {
                        StrBufLen=lstrlen(g_StringBuf2);
                        memset(lpBuf,0,dwBufLen);
                        if (dwBufLen>=StrBufLen)
                        {
                                dwBufLen=StrBufLen;
                                myReturn=StrBufLen;
                        }
                        else
                        {
                                myReturn=0;
                        }
                        memcpy(lpBuf,g_StringBuf2,dwBufLen);
                }
        }
        else
        {
                g_myHOOK1.HookStatus(false);
                myReturn=ImmGetCompositionStringA(hIMC,dwIndex,lpBuf,dwBufLen);
                g_myHOOK1.HookStatus(true);
        }
        return myReturn;
}
回复 支持 反对

使用道具 举报

发表于 2010-9-28 11:13:17 | 显示全部楼层
?似火星字外?的??,可以?繁??等?好?西哦 ?起
回复 支持 反对

使用道具 举报

发表于 2014-6-29 06:13:08 | 显示全部楼层
我下载了一下,并且用了一下,挺不错的,但我也发现了一个小BUG,那就是在DLL源码中的DLLstartHOOK函数体,代码是这样的:

        if (g_hMainhWnd==NULL)
        {

                g_hMainhWnd=myhWnd;
        }

我们首先来定义一下两个程序,第一个程序是调用这个DLL的程序,我们称之为“服务程序”,第二个程序是将要被修改拦截输入的程序,我们称之为“目标程序”。

这段代码的意思,就是要先判断一下g_hMainhWnd是否为0,如果为0,才将它设为传进来的参数myhWnd,如果不为0就直接跳过,但这样的话,有时候重启服务程序的时候,拦截修改会失效,经过我的试验发现,只要将这一句if判断语句注释掉,也就是说无论什么时候调用DLLstartHOOK,都将g_hMainhWnd设置为myhWnd,就不会出现失效的问题,原因的话,因为时间有限,我没有进行深究考验,只是进行了一下推测,具体如下:
因为DLL代码使用的g_hMainhWnd是全局变量,在DLL中的全局变量是共享互通的,在启动服务程序和目标程序后,DLL都被各自加载到两个程序的内存空间中,即使服务程序退出了,但目标程序仍然还在的话,DLL就不会被卸载掉,那么全局变量g_hMainhWnd的值还是不为0的,是第一次加载服务程序的时候由服务程序传进来的值,因此下次再运行服务程序的时候,因为DLL没有被卸载掉,因此这个全局变量g_hMainhWnd的值不为0,由于那句if语句的作用,g_hMainhWnd就无法更新为最新的服务程序的窗口句柄,自然之后当有输入法事件来临的时候,DLL也就无法向最新的服务程序发送消息了,所以就会失效了,因此我个人认为,最简单的解决方法就是将这句if语句注释掉,经我试验,是可以解决这个失效的问题的。
希望其他的人也注意一下这个小问题,总的来说作者的分享精神是很不错的,有我当年的感觉,我们VBGOOD能作为国内数一数二的VB论坛,就是因为有这样的会员,哈哈!

点评

是的,的确是要放到共享的节中,才是互通的,而我没有细究作者的代码是否有做此动作,所以修正的原因,都只是我的推测,由于我的修改可用,所以我做此推测。  发表于 2014-6-30 15:16
DLL中的全局变量是共享互通的?不对吧,除非你把那个变量设置到共享节里面了  发表于 2014-6-29 10:50
回复 支持 反对

使用道具 举报

发表于 2015-5-19 16:40:57 | 显示全部楼层
试试看 谢谢分享
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2022-7-5 12:09

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