1. 程式人生 > >使用 HOOK 實現 Outlook Express 工具條

使用 HOOK 實現 Outlook Express 工具條

點選下載範例程式碼

很久以前就有個朋友問過,怎麼實現 Outlook Express 的工具條。
當時因為理解錯了,僅僅寫了個 Outlook 2000 外掛的範例,以為能夠滿足他。
後來又因為時間比較忙,事情就不了了之了(慚愧)。
最近又有個朋友要做這玩意(這玩意很吃香嗎?),雖然最近一直很忙,不過還是抽空寫了個範例,效果很不錯。
希望這個工程對其他要做這方面開發的朋友有所幫助。

其實,Outlook Express 並不能像 Office 系列軟體那樣能支援外掛。
所以我們只能通過一些非正常手段來實現,比如 HOOK,或者遠端注入等。
個人覺得 HOOK 還是要比遠端注入要安全,也穩定得多(當然也容易掌握得多,汗一個)!

我因為要進入 Outlook Express 的程序空間,所以 HOOK 必須是全域性的,也就是說必須以 DLL 形式載入(這樣有一個不方便的地方就是必須要有一個程式來先載入這個 DLL ,並將 HOOK 掛入系統)。

恩,現在就先來講一下實現方法:
1、在系統中掛入 WH_SHELL 鉤子,這個鉤子會在頂級視窗(程序主視窗)建立、登出等事件時收到訊息,這是個好機會,我們要的就是視窗建立時判斷視窗是否 Outlook Express 主視窗。
LRESULT CALLBACK shellProc(int nCode,WPARAM wParam,LPARAM lParam)
{
switch(nCode)

    {
case HSHELL_WINDOWCREATED:
if(isOutlookExpress((HWND)wParam))  // 如果是 Outlook Express 視窗
        {
// 處理
        }
break;
default:break;
    }
return CallNextHookEx(hHook,nCode,wParam,lParam);
}

2、如果是的,則遍歷 Outlook Express 的子視窗,找到 ReBar 視窗控制代碼(其實微軟叫他:ReBarWindow32,簡稱 ReBar 好了,ReBar 其實是一個容器,可以包容工具條、ComboBox 等各種控制元件)。得到這個控制代碼之後,我們就可以將我們建立的工具條插入 ReBar 中。

HWND WINAPI findCoolbar(HWND hwnd)
{
    HWND hWnd = NULL;
    EnumChildWindows(hwnd,enumChildProc,(LPARAM)&hWnd);
return hWnd;
}

BOOL CALLBACK enumChildProc(HWND hwnd,LPARAM lParam)
{
    TCHAR szClass[MAX_PATH] = TEXT("");
    GetClassName(hwnd,szClass,MAX_PATH);
if(lstrcmpi(szClass,TEXT("ReBarWindow32")) == 0)
    {
        *((HWND*)lParam) = hwnd;
return FALSE;
    }
return TRUE;
}

3、現在問題來了,我們怎麼響應我們插入的工具條的訊息呢?其實簡單,只要在 HOOK 過程中(本例中為 shellProc)重置 Outlook Express 的主視窗過程就 OK 了:)
    .
    hWndOE = (HWND)wParam;  // 儲存視窗控制代碼
if(insertToolbar(hWndOE))lpfnOldOEWindowProc = (WNDPROC)SetWindowLong(hWndOE,GWL_WNDPROC,(LONG)newOEWindowProc);     // 插入工具條成功之後,重置視窗過程
    .

4、在新的視窗過程中接收 WM_COMMAND 訊息:
LRESULT CALLBACK newOEWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
    {
case WM_COMMAND:
switch(LOWORD(wParam))
        {
case IDC_SAMPLE:
            MessageBox(hWnd,TEXT("呵呵,你點我幹嘛?"),NULL,MB_OK | MB_ICONINFORMATION);
            break;
default:break;
        }
break;
    .
// 其他處理

好了,這樣就基本完成了 Outlook Express 工具條。
當然還有其他一些細節要處理,比如工具條的建立、退出 Outlook Express、中途退出 HOOK 等情況。
不多說了吧,具體看範例程式碼(VC6 的工程)。