??? 一直在用Lingoes作為翻譯工具,占用空間小,運(yùn)行比較穩(wěn)定,詞典可以任意切換,使用起來(lái)要比Kingsoft的詞霸感覺(jué)--“輕松”~
??? Lingoes有個(gè)沒(méi)法和詞霸相比的功能--生詞本。對(duì)于我這樣記性不好的人來(lái)說(shuō),如果能夠記錄自己曾經(jīng)“認(rèn)真”背誦過(guò)的單詞,然后再“強(qiáng)化”一下,應(yīng)該會(huì)有好的效果(實(shí)際差不多,一樣過(guò)三天就記不住了),因此這個(gè)功能對(duì)我來(lái)說(shuō)比較--實(shí)用。但,Lingoes無(wú)此功能~
??? 在網(wǎng)上查找,發(fā)現(xiàn)很有些人跟我有同感,并也有人士完成了此功能,大喜,下載使用,嗯,功能都有,只是我用起來(lái)不太順手。于是,發(fā)揚(yáng)“輪子精神”,然后便有了這個(gè)--LingosHook~
??? 如其名字,由于無(wú)法知道Lngoes內(nèi)部實(shí)現(xiàn),只能走旁門(mén)--HOOK了。而如我們所知,要想用Hook,DLL是少不了的,前期關(guān)于DLL的練習(xí)也做了很久了,但上周才把可用的DLL剛剛調(diào)試完成,然后加上一個(gè)測(cè)試的App,就有了下面的截圖。

??? 上圖中,顯式了由Lingoes結(jié)果窗口(未截圖)中Hook到的HTML和TEXT內(nèi)容,這樣在加上SQLite和一些管理策略代碼,一個(gè)生詞本應(yīng)該就可以完成了.
??? 實(shí)現(xiàn)的關(guān)鍵還是Hook的DLL,有興趣,請(qǐng)點(diǎn)擊這里下載。其中包括了測(cè)試用的App。DLL的exports如下:

??? CreateHookThread用于“注冊(cè)”,RemoveHookThread用于“卸載”。下面是調(diào)用的主要代碼,我使用的開(kāi)發(fā)測(cè)試環(huán)境是XP SP3+VCExpress 9.0+wxWidgets 2.8.10,還有l(wèi)ingoes 2.63。如果測(cè)試的app不能運(yùn)行,請(qǐng)先到MS下載相應(yīng)的VC發(fā)布包試試。
??
? ? 實(shí)現(xiàn)步驟如下:
??? 1.向Lingoes注冊(cè)截取消息的Hook DLL;
??? 2.創(chuàng)建線程,用于等待Hook發(fā)現(xiàn)Lingoes“截取到文本”觸發(fā)的WM_COPYDATA消息后的事件;
??? 3.線程收到事件后,向注冊(cè)進(jìn)程發(fā)送內(nèi)部消息,轉(zhuǎn)發(fā)Lingoes的翻譯結(jié)果,其中結(jié)果分為HTML和TEXT兩種結(jié)果;
??? 4.注冊(cè)線程收到消息后,顯式結(jié)果。
??? 注冊(cè)代碼:
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);
}