• 我对Windows桌面任务栏自动隐藏功能的一点小小改进不再自动弹出(20130226更新)


    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做测试, 完美运行.

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

          

  • 相关阅读:
    怎样将文件夹打包为jar包或war包
    tomcat6.0安装
    jdk安装
    spring cloud深入学习(十一)-----服务网关zuul
    spring cloud深入学习(十)-----配置中心和消息总线(配置中心终结版)
    spring cloud深入学习(九)-----配置中心服务化和高可用
    spring cloud深入学习(八)-----配置中心svn示例和refresh
    spring cloud深入学习(七)-----配置中心git示例
    spring cloud深入学习(六)-----熔断监控Hystrix Dashboard和Turbine
    dubbo入门学习(一)-----分布式基础理论、架构发展以及rpc、dubbo核心概念
  • 原文地址:https://www.cnblogs.com/memset/p/2853618.html
Copyright © 2020-2023  润新知