上午被“美帝國主義”放了鴿子,這樣也好,把安排的review提前做完了,下午也就空了點,于是就想起了昨天的一個和LingosHook相關的問題了--不是所有單詞的查詢都是來自于鼠標方式,還有一種更加常用的方式:直接輸入查詢。應該是當時被HOOK給迷住,一門心思就想著去Hook Lingoes的消息了,完全沒有考慮實際的使用。
于是發揚“源碼在手,天下我有”的精神,很快添加Hotkey對象用于注冊熱鍵,用于需要提取查詢結果時使用。
#ifndef __HOTKEYOBJECT_H__
#define __HOTKEYOBJECT_H__

#include "wx/wx.h"

class LingosHookFrame;

class CHotkeyObject


{
public:
CHotkeyObject(LingosHookFrame* frame);
virtual ~CHotkeyObject();

int Register(UINT mod, UINT key);

int MessageProc(WXUINT msg, WXWPARAM wparam, WXLPARAM lparam);
protected:
void Unregister();

int GetResult(WXWPARAM wparam, WXLPARAM lparam);
int GetIEDocResult(HWND hwnd);

static int _wincount;
static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam);
private:
LingosHookFrame* _objFrame;
int _id;
};

#endif

int CHotkeyObject::Register(UINT mod, UINT key)


{
_id = ::GlobalAddAtom(_T("LingosHook"));
if(_id == 0)
return -1;
if(::RegisterHotKey((HWND)_objFrame->GetHWND(), _id, mod, key) != TRUE)
return -1;
return 0;
}

void CHotkeyObject::Unregister()


{
if(_id != 0)

{
::UnregisterHotKey((HWND)_objFrame->GetHWND(), _id);
_id = 0;
}
}
模塊化設計的好處就是添加新的模塊,完全不需要涉及其它模塊的代碼。新的CHotkeyObject幾乎十五分鐘就可以使用,然后模仿提取Lingoes懸浮窗口的方法,開始提取其主窗口的IE控件窗口的結果,登時傻了。其主窗口遠比懸浮窗口復雜,所使用的IE控件窗口遠不是一個。所有使用到的IE窗口都有著相同的Class - 'Internet Explorer_Server',且都沒有Title,這讓我沒法區分哪個是結果窗口。折騰了很久,耐心全部被消耗后,拿出了最終的方法來 -- 硬編碼!這種方法對我來說,有些像原子彈--反對使用,但卻很有效。 怎么個硬編碼,看下面代碼就知道了。
BOOL CALLBACK CHotkeyObject::EnumChildProc(HWND hwnd, LPARAM lparam)


{
++ _wincount;

if(_wincount == 0x24)

{
*(HWND*)lparam = hwnd;
return FALSE;
}
return TRUE;
}
看出來了嗎?0x24!就是直接找主窗口上的第36個子窗口(控件)就是需要的結果窗口。。。
緊接著在結果的處理上,我原以為通過兩種方式得到的TEXT結果應該是一樣,使用原有的CDictionaryObject應該可以正常工作,然而實際情況確實兩者差了一個\r\n,導致無法解析。看來使用TEXT解析結果的方法不能再使用,只有HTML方式才是靠譜。但想起前面被0x24的折磨,頓時“老羞成怒”,不再考慮什么使用“優雅”的方式分解HTML,比如寫一個好看的CHtmlAnalseObject什么的,直接來硬的吧 --把HTML當TEXT使用 --
唉,又是硬編碼了,太暴力了。。。但誰叫Lingoes招惹我呢?!(。。。)
<---自我原諒的分割線---->
硬編碼是編程中非常不好的習慣和做法,但這種方法實際在被經常使用著,比如我們常說的‘魔數’。硬編碼的一個主要害處就是使代碼失去了靈活性和可讀性。
這里使用硬編碼是么辦法啊,不過再說了,LingosHook本身使用Hook方式就已經失去了自身的靈活了,完全和Lingoes的實現息息相關了。當前Lingoes版本是2.6.3,懸浮只有一個IE窗口,使用WM_COPYDATA消息,結果是HTML格式的,等等等等,隨便一個因素稍微的變化,都會導致LingosHook的無法使用。