一直在用Lingoes作为翻译工具,占用空间小,运行比较稳定,词典可以任意切换,使用起来要比Kingsoft的词霸感觉--“轻松”~
Lingoes有个没法和词霸相比的功能--生词本。对于我这样记性不好的人来说,如果能够记录自己曾经“认真”背诵过的单词,然后再“强化”一下,应该会有好的效果(实际差不多,一样过三天就记不住了),因此这个功能对我来说比较--实用。但,Lingoes无此功能~
在网上查找,发现很有些人跟我有同感,并也有人士完成了此功能,大喜,下载使用,嗯,功能都有,只是我用起来不太顺手。于是,发扬“轮子精神”,然后便有了这个--LingosHook~
如其名字,由于无法知道Lngoes内部实现,只能走旁门--HOOK了。而如我们所知,要想用Hook,DLL是少不了的,前期关于DLL的练习也做了很久了,但上周才把可用的DLL刚刚调试完成,然后加上一个测试的App,就有了下面的截图。
上图中,显式了由Lingoes结果窗口(未截图)中Hook到的HTML和TEXT内容,这样在加上SQLite和一些管理策略代码,一个生词本应该就可以完成了.
实现的关键还是Hook的DLL,有兴趣,请点击这里下载。其中包括了测试用的App。DLL的exports如下:
CreateHookThread用于“注册”,RemoveHookThread用于“卸载”。下面是调用的主要代码,我使用的开发测试环境是XP SP3+VCExpress 9.0+wxWidgets 2.8.10,还有lingoes 2.63。如果测试的app不能运行,请先到MS下载相应的VC发布包试试。
实现步骤如下:
1.向Lingoes注册截取消息的Hook DLL;
2.创建线程,用于等待Hook发现Lingoes“截取到文本”触发的WM_COPYDATA消息后的事件;
3.线程收到事件后,向注册进程发送内部消息,转发Lingoes的翻译结果,其中结果分为HTML和TEXT两种结果;
4.注册线程收到消息后,显式结果。
注册代码:
void
MyFrame::OnBtnHook(wxCommandEvent
&
event
)
{
_hDll
=
::LoadLibrary(_T(
"
../Debug/LingosHook.dll
"
));
if
(_hDll
!=
NULL)
{
CreateHookThreadPtr pch
=
(CreateHookThreadPtr)GetProcAddress(_hDll,
"
CreateHookThread
"
);
if
(pch
!=
NULL)
{
if
(pch((HWND)
this
->
GetHandle(), NULL, NULL,
&
_nMsgID)
!=
TRUE)
{
wxMessageBox(_(
"
call CreateHookThread() failed.
"
));
::FreeLibrary(_hDll);
}
}
else
{
wxMessageBox(_(
"
Get CreateHookThread address failed.
"
));
}
}
else
{
wxMessageBox(_(
"
Load LingosHook dll failed.
"
));
}
//
event.Skip();
//
wxLogDebug(wxT("Event handler (MyFrame::OnBtnHook) not implemented yet"));
//
notify the user that he hasn't implemented the event handler yet
}
卸载代码:
void
MyFrame::OnBtnUnhook(wxCommandEvent
&
event
)
{
if
(_hDll
!=
NULL)
{
RemoveHookThreadPtr prh
=
(RemoveHookThreadPtr)GetProcAddress(_hDll,
"
RemoveHookThread
"
);
if
(prh
!=
NULL)
{
if
(prh()
!=
TRUE)
{
wxMessageBox(_(
"
call RemoveHookThread() failed.
"
));
}
}
else
{
wxMessageBox(_(
"
Get RemoveHookThread address failed.
"
));
}
::FreeLibrary(_hDll);
_hDll
=
NULL;
}
//
event.Skip();
//
wxLogDebug(wxT("Event handler (MyFrame::OnBtnUnhook) not implemented yet"));
//
notify the user that he hasn't implemented the event handler yet
}
消息处理代码:
WXLRESULT MyFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
if
(message
==
_nMsgID)
{
wxLogDebug(_(
"
msg:%d, wparam:%d, lparam:%d
"
), message, wParam, lParam);
struct
_HookData_t
*
hd
=
(reinterpret_cast
<
struct
_HookData_t
*>
(lParam));
wxString str;
if
(hd
!=
NULL
&&
hd
->
data
!=
NULL)
{
str.append(hd
->
data, hd
->
size);
//
, wxMBConvUTF16, hd->size);
//
delete [] hd->data;
}
//
if(wParam == HKT_CATCH)
//
{
//
wxLogDebug(_T("get CATCH message."));
//
_textEdit->AppendText(_("CATCH:") + str + _("\n"));
//
}
//
else
if
(wParam
==
HKT_RESULT_TEXT)
{
wxLogDebug(_T(
"
get RESULT_TEXT message.
"
));
_textEdit
->
AppendText(_(
"
\n---------------TEXT---------------\n
"
)
+
str);
}
else
if
(wParam
==
HKT_RESULT_HTML)
{
wxLogDebug(_T(
"
get RESULT_HTLM message.
"
));
_textEdit
->
AppendText(_(
"
\n---------------HTML---------------\n
"
)
+
str);
}
else
{
wxLogDebug(_T(
"
get UNKNOWN message.
"
));
}
}
return
wxFrame::MSWWindowProc(message, wParam, lParam);
}