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);
    }
}

 


免責聲明!

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



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