點(diǎn)擊下載范例代碼
很久以前就有個(gè)朋友問過,怎么實(shí)現(xiàn) Outlook Express 的工具條。
當(dāng)時(shí)因?yàn)槔斫忮e(cuò)了,僅僅寫了個(gè) Outlook 2000 插件的范例,以為能夠滿足他。
后來又因?yàn)闀r(shí)間比較忙,事情就不了了之了(慚愧)。
最近又有個(gè)朋友要做這玩意(這玩意很吃香嗎?),雖然最近一直很忙,不過還是抽空寫了個(gè)范例,效果很不錯(cuò)。
希望這個(gè)工程對其他要做這方面開發(fā)的朋友有所幫助。
其實(shí),Outlook Express 并不能像 Office 系列軟件那樣能支持插件。
所以我們只能通過一些非正常手段來實(shí)現(xiàn),比如 HOOK,或者遠(yuǎn)程注入等。
個(gè)人覺得 HOOK 還是要比遠(yuǎn)程注入要安全,也穩(wěn)定得多(當(dāng)然也容易掌握得多,汗一個(gè))!
我因?yàn)橐M(jìn)入 Outlook Express 的進(jìn)程空間,所以 HOOK 必須是全局的,也就是說必須以 DLL 形式加載(這樣有一個(gè)不方便的地方就是必須要有一個(gè)程序來先加載這個(gè) DLL ,并將 HOOK 掛入系統(tǒng))。
恩,現(xiàn)在就先來講一下實(shí)現(xiàn)方法:
1、在系統(tǒng)中掛入 WH_SHELL 鉤子,這個(gè)鉤子會(huì)在頂級窗口(進(jìn)程主窗口)創(chuàng)建、注銷等事件時(shí)收到消息,這是個(gè)好機(jī)會(huì),我們要的就是窗口創(chuàng)建時(shí)判斷窗口是否 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 窗口句柄(其實(shí)微軟叫他:ReBarWindow32,簡稱 ReBar 好了,ReBar 其實(shí)是一個(gè)容器,可以包容工具條、ComboBox 等各種控件)。得到這個(gè)句柄之后,我們就可以將我們創(chuàng)建的工具條插入 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、現(xiàn)在問題來了,我們怎么響應(yīng)我們插入的工具條的消息呢?其實(shí)簡單,只要在 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("呵呵,你點(diǎn)我干嘛?"),NULL,MB_OK | MB_ICONINFORMATION);
break;
default:break;
}
break;
.
// 其他處理
好了,這樣就基本完成了 Outlook Express 工具條。
當(dāng)然還有其他一些細(xì)節(jié)要處理,比如工具條的創(chuàng)建、退出 Outlook Express、中途退出 HOOK 等情況。
不多說了吧,具體看范例代碼(VC6 的工程)。