??? 一直在用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);
}