• GetWindowLong和SetWindowLong函数


    我发现这两个函数的功能真的不是一般的有意思,贴上这两个函数函数原型:

    LONG WINAPI SetWindowLong(
      _In_ HWND hWnd,
      _In_ int  nIndex,
      _In_ LONG dwNewLong
    );
    LONG WINAPI GetWindowLong(
      _In_ HWND hWnd,
      _In_ int  nIndex
    );
    

    这两个函数的资料在度娘上面也是不胜枚举,同时本人在网络上翻看了诸多大牛的文章,大家对这两个函数的理解也都是入木三分。后来人便可综合大家的总结,更方便的理解这两个函数。但一是本人水平实在有限,二是为了不再给网络增加负担,所以本人决定理论的知识就不再赘述了,以免出现纰漏贻误后来人。而是通过亲身经历的两个小例子来展示一下这两个函数的强大之处。

    1.设置窗口的透明属性。

     这段代码实现的功能就是让我们电脑上的计算器再透明一点,本来是这样的,然后我们写个程序使其变成这个鬼样子。

      

    以SDK为例,我们新建一个默认工程,在默认工程的回调函数里,添加一个右键处理消息,当右键按下,获取计算器的句柄,其中类名或者窗口名,可以通过VS自带的SPY++获得(32位和64位版本要对应),然后通过这两个函数获取窗口属性,用SetLayeredWindowAttributes函数设置透明色。(前提是要打开计算器,使能够获取句柄成功)。代码如下:

     1 case  WM_RBUTTONDOWN:
     2     {
     3         //获取计算器窗口句柄(这里也可以设置QQ了,英雄联盟了,等一系列窗口)
     4         HWND hCalc=FindWindow(_T("CalcFrame"), NULL);//这个函数也是非常非常有意思的。
     5         if (hCalc!=NULL)
     6         {
     7             //通过GetWindowLong获得窗口的属性
     8             int ExdStyle = (int)GetWindowLong(hCalc, GWL_EXSTYLE);
     9             //通过SetWindowLong设置窗口的属性,多增加了一个WS_EX_LAYERED支持透明
    10             SetWindowLong(hCalc, GWL_EXSTYLE, ExdStyle | WS_EX_LAYERED);
    11             //设置窗口的透明色
    12             SetLayeredWindowAttributes(
    13                 hCalc, RGB(255, 255, 255),
    14                 100, LWA_ALPHA);//100代表透明度,0是全透明,255是不透明
    15         }
    16         
    17     }
    18         break;

    2.改写回调函数过滤消息。

    比如改写该进程下的回调函数,达到过滤右键按下的消息的目的

    旧回调函数:
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_CREATE:
        {
            //OldProc返回值是SetWindowLong原来的回调函数的地址
            OldProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)NewProc);
            //程序主窗口此时的回调函数是NewProc而不是WndProc;
        }
            break;
        case WM_RBUTTONDOWN:
        {
            MessageBox(hWnd, _T("旧的窗口回调函数里"), _T("提示"), NULL);
        }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    新回调函数
    LRESULT CALLBACK NewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_RBUTTONDOWN:
            {
                MessageBox(hWnd, _T("新的窗口回调函数里"), _T("提示"), NULL);
            }
            return 0;
            //达到过滤消息后,恢复原来的回调函数,在OldProc中保存着
            default:
                return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
        }
    }
  • 相关阅读:
    JavaScript——实现compose函数
    Typora——如何画流程图 | mermaid-js
    Electron——复制文件操作
    JavaScript——实现一些常用函数
    vue elementUI表单主动trigger某个rules校验
    [java]多线程——多线程debug调试(非常非常详细的调试)
    CompletableFuture supplyAsync() and thenApply() 用法区别
    CAS和MySql乐观锁实现下单
    TiDB集群手动安装
    Vue中 let _this = this的作用
  • 原文地址:https://www.cnblogs.com/wingss/p/5116602.html
Copyright © 2020-2023  润新知