我對Windows桌面任務欄自動隱藏功能的一點小小改進--不再自動彈出(2013-02-26更新)


tfref  由於是筆記本電腦, 由於屏幕太小, 也可能是不想讓別人看見自己打開了哪些窗口, 所以選擇了把桌面的任務欄的自動隱藏選項給鈎上了, 現在只要任務欄失去焦點, 它就會自己隱藏了. 但很不爽的是, 任務欄在屏幕的最下面(其它位置也一樣), 只要鼠標稍微碰到就會顯示出任務欄, 太不爽了, 所以打算進行一點小的修改, 於是就有了下面的一小段代碼...
  當然, 采用了最簡單的辦法, DLL注入, Explorer.exe 在啟動的時候會默認加載system32目錄下的msimg32.dll, 由於這個dll導出的函數非常少, 所以我就把它"替換"成我自己的了.
  如果想試試效果的, 可以按如下方式使用:
    1.把下面的程序生成的msimg32.dll放到Explorer.exe的目錄下(C:\Windows), 可能需要先在任務管理器中結束Explorer.exe桌面進程.
    2.然后從命令提示符,或任務管理器的文件->新建任務(運行...)中執行explorer命令即可重新啟動桌面進程.
  最終的效果:
    桌面的任務欄會自己隱藏(自己設置的,右鍵菜單->屬性->自動隱藏任務欄), 然后鼠標放到任務欄上它也不會再出來了
  要想再顯示出任務欄的方式:
      1.按住左邊的Ctrl鍵(可能會不方便, 還是用第3種方法好), 再把鼠標移到任務欄上面去就可以了.
      2.當前台窗口是桌面的時候, 任務欄會顯示(2013-01-10)
      3.用鼠標左鍵單擊一下任務欄(在屏幕的最下邊).(2013-01-11)

  主要實現代碼:
  

    //當鼠標在NC區移動時會產生這個消息
    if(uMsg == WM_NCHITTEST){
        HWND hForeground = GetForegroundWindow();
        if(hForeground!=hDesktopWindow && //前台窗口不是桌面
            hForeground!=NULL && hForeground!=hTaskBar &&//前台窗口不是任務欄
            !(GetAsyncKeyState(VK_LCONTROL)&0x8000)) //左Ctrl未按下
        {
            return 0;
        }
    }

 



好了, 幾句代碼而已, 不過功能倒是基本實現了, 沒什么多說的.
下面是代碼, 最后有項目下載:

 
         
#include <windows.h>
#include <process.h>

//導出msing32.dll原來的所有函數
#pragma comment(linker, "/EXPORT:vSetDdrawflag=_AheadLib_vSetDdrawflag,@1")
#pragma comment(linker, "/EXPORT:AlphaBlend=_AheadLib_AlphaBlend,@2")
#pragma comment(linker, "/EXPORT:DllInitialize=_AheadLib_DllInitialize,@3")
#pragma comment(linker, "/EXPORT:GradientFill=_AheadLib_GradientFill,@4")
#pragma comment(linker, "/EXPORT:TransparentBlt=_AheadLib_TransparentBlt,@5")

//裸代碼
#define NAKED __declspec(naked)

//原來的msimg32模塊
HMODULE hModMsimg32 = NULL;

//加載原模塊
void Load(void)
{
    char msimg32_path[MAX_PATH];
    GetSystemDirectory(msimg32_path, sizeof(msimg32_path));
    strcat(msimg32_path, "\\msimg32.dll");
    hModMsimg32 = LoadLibrary(msimg32_path);
    if(hModMsimg32 == NULL){
        MessageBoxW(NULL, L"無法加載原始的 msimg32.dll, 請移除該修改程序 !", NULL, MB_OK);
        ExitProcess(1);
    }
}

//取得原模塊中的函數地址
FARPROC WINAPI GetAddress(char* ProcName)
{
    FARPROC pAddress = NULL;
    pAddress = GetProcAddress(hModMsimg32, ProcName);
    if(pAddress == NULL){
        MessageBox(NULL, "獲取函數地址失敗!", ProcName, MB_ICONERROR);
        ExitProcess(1);
    }
    return pAddress;
}

//卸載原模塊
void Unload(void)
{
    if(hModMsimg32){
        FreeLibrary(hModMsimg32);
        hModMsimg32 = NULL;
    }
}

//任務條原來的窗口函數地址
WNDPROC OldWindowProc = NULL;
//在桌面的時候可以響應
HWND hDesktopWindow = NULL;

//子類后的窗口函數地址
LRESULT CALLBACK NewWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  //2013-02-26更新一個hForeground!=hTaskBar的判斷
    //當鼠標在NC區移動時會產生這個消息
    if(uMsg == WM_NCHITTEST){
        HWND hForeground = GetForegroundWindow();
        if(hForeground!=hDesktopWindow && //前台窗口不是桌面
            hForeground!=NULL && hForeground!=hTaskBar &&//前台窗口不是任務欄
            !(GetAsyncKeyState(VK_LCONTROL)&0x8000)) //左Ctrl未按下
        {
            return 0;
        }
    }
//其它的消息全部忽略 return CallWindowProc(OldWindowProc, hwnd, uMsg, wParam, lParam); } //臨時用的新線程, 主要是保證DLL能正確加載 unsigned int WINAPI ThreadProc(PVOID pv) { HWND hShellTrayWnd = NULL; //DLL加載時窗口還沒被創建,所以要等等 while(!(hShellTrayWnd=FindWindow("Shell_TrayWnd", NULL))) Sleep(100); //取得桌面窗口 while(!(hDesktopWindow = FindWindow("Progman", "Program Manager"))) Sleep(100); //更改窗口函數地址為我的窗口函數地址,處理自己想處理的消息 OldWindowProc = (WNDPROC)SetWindowLong(hShellTrayWnd, GWL_WNDPROC, (LONG)NewWinProc); return 0; } BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved) { if(dwReason == DLL_PROCESS_ATTACH){ DisableThreadLibraryCalls(hDllHandle); Load(); _beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL); }else if(dwReason == DLL_PROCESS_DETACH){ Unload(); } return TRUE; } //直接轉到原來msimg32.dll中的函數調用 NAKED AheadLib_vSetDdrawflag(void) { GetAddress("vSetDdrawflag"); __asm jmp eax; } NAKED AheadLib_AlphaBlend(void) { GetAddress("AlphaBlend"); __asm jmp eax; } NAKED AheadLib_DllInitialize(void) { GetAddress("DllInitialize"); __asm jmp eax; } NAKED AheadLib_GradientFill(void) { GetAddress("GradientFill"); __asm jmp eax; } NAKED AheadLib_TransparentBlt(void) { GetAddress("TransparentBlt"); __asm jmp eax; }
 
         

 

 


最后需要聲明一點:
  由於msimg32本身是系統文件(位於C:\Windows\System32目錄下), 所以在使用, 被安全軟件報病毒, 系統文件被替換之類的是很正常的, 自己知道沒問題就行了.
我的系統是XPSP3, 沒試過Win7,Win8,不知道能否工作~

2013-03-14 更新:
  已在Win7做測試, 完美運行.

項目下載:http://files.cnblogs.com/nbsofer/HookTaskBar.7z
女孩不哭(QQ:191035066)@2013-01-09 20:27:41 http://www.cnblogs.com/nbsofer

      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM