向Vista學(xué)習(xí),實(shí)現(xiàn)XP下重命名文件忽略選取擴(kuò)展名
這兩天對于HOOK的技術(shù)有了一個入門的學(xué)習(xí),用過vista的同學(xué)會發(fā)現(xiàn)vista重命名一個文件比如vista.exe,他會自動選中vista忽略掉擴(kuò)展名,帶來比較方便的用戶體驗(yàn),學(xué)了一些hook我也想試試xp下能不能做這樣的事情。于是參考一些文章,勉強(qiáng)實(shí)現(xiàn)了,有一點(diǎn)兒缺陷(請看最后)。
經(jīng)過觀察我發(fā)現(xiàn)重命名時,資源管理器會向他的子窗口listview發(fā)送一個LVM_EDITLABELA的控制消息,所以我使用了WH_CALLWNDPROCRET類型的全局掛鉤,這個掛鉤可以在sendmessage結(jié)束以后處理傳送和返回的數(shù)據(jù)。發(fā)送了LVM_EDITLABELA消息后,會在lParam得到一個編輯窗口的句柄,只需之后對這個窗口發(fā)送EM_SETSEL控制消息就能夠改變重命名時候的高亮區(qū)域。hook回調(diào)函數(shù)如下:
1: static LRESULT CALLBACK msghook(UINT nCode, WPARAM wParam, LPARAM lParam)
2: {
3: if(nCode < 0)
4: {
5: CallNextHookEx(hook,nCode,wParam,lParam);
6: return 0;
7: }
8: LPCWPRETSTRUCT msg = (LPCWPRETSTRUCT) lParam;
9: if(msg->message == LVM_EDITLABELA || msg->message == LVM_EDITLABELW)
10: {
11: GetClassName(msg->hwnd,className,255);
12: GetWindowText(msg->hwnd,wndName,255);
13: if(0==_tcscmp(className,_TEXT("SysListView32")))
14: {
15: if(0==_tcscmp(wndName,_TEXT("FolderView")))
16: {
17: hEditWnd = (HWND)msg->lResult;
18: GetWindowText(hEditWnd,className,255);//暫時放入className
19: SendMessage(hEditWnd,EM_SETSEL,0,findDot(className));
20: }
21: }
22: }
23: return CallNextHookEx(hook,nCode,wParam,lParam);
24: }
className與wndName是兩個TCHAR數(shù)組,從hwnd獲取信息存在那里進(jìn)行判斷是否為Shell中的listview,避免在其它使用listview的應(yīng)用程序里會進(jìn)行之后的處理。
工程文件下載,點(diǎn)這里
程序下載,點(diǎn)這里
使用方法,編譯以后直接運(yùn)行GRnamer就可以,如果不想用了,從任務(wù)管理器把它關(guān)閉,沒有做trayicon之類的東西,因?yàn)橹皇莻€demo。
最后說一下缺陷,缺陷就是這樣做沒有辦法判斷文件與文件夾的區(qū)別,所以會有如圖的效果,我自己沒有想到解決的方法,請達(dá)人們指點(diǎn)。:)
參考的文章:
msdn Hooks hook的全部參考
codeproject Hooks and DLLs 我的hook dll都是照著它寫的。
posted on 2008-05-17 02:05 Gohan 閱讀(3023) 評論(17) 編輯 收藏 引用 所屬分類: C++ 、MFC/SDK