首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows 按鍵突破原理實作:EnableWindow + 滑鼠座標追蹤

     編輯:關於VC++

前言

所謂「按鍵突破」實為啟用被停用的視窗控制項。核心 API 僅需 EnableWindow(hWnd, TRUE),關鍵在於如何即時取得滑鼠所指控制項的 HWND。本文完整實作從座標轉換、子視窗遞迴搜尋到多執行緒輪詢的完整流程。

核心 API

BOOL EnableWindow(
    HWND hWnd,   // 目標視窗/控制項
    BOOL bEnable // TRUE=啟用, FALSE=停用
);

取得滑鼠下控制項 HWND 的關鍵函數

1. WindowFromPoint - 取得最上層視窗

POINT pt;
GetCursorPos(&pt);           // 螢幕座標
HWND hTop = WindowFromPoint(pt); // 含透明/無回應視窗

2. ScreenToClient - 座標系轉換

ScreenToClient(hParent, &pt); // 螢幕座標 → 客戶區座標

3. RealChildWindowFromPoint - 子視窗點擊測試

HWND RealChildWindowFromPoint(
    HWND hParent,        // 父視窗
    POINT ptClientCoords // 客戶區座標
);

限制:僅回傳第一層子視窗,無法穿透重疊視窗取得最深層控制項。

4. 遞迴尋找最深層子視窗


void GetRealWindow(HWND* phWnd)
{
    POINT pt;
    GetCursorPos(&pt);                 // 1. 取得螢幕座標
    HWND hTop = WindowFromPoint(pt);   // 2. 最上層視窗
    HWND hParent = GetParent(hTop);    // 3. 取得頂層父視窗
    ScreenToClient(hParent, &pt);      // 4. 轉為客戶區座標

    // 5. 遞迴向下尋找最深層子視窗
    while (TRUE)
    {
        HWND hChild = RealChildWindowFromPoint(hParent, pt);
        if (hChild && hChild != hParent)
            hParent = hChild; // 繼續往下
        else
            break;
    }
    *phWnd = hParent;
}

多執行緒輪詢實作

工作執行緒函數


DWORD WINAPI BreakThread(LPVOID lpParam)
{
    HWND hTarget = NULL;
    while (g_bRunning) // 全域旗標控制
    {
        GetRealWindow(&hTarget);
        if (hTarget)
            EnableWindow(hTarget, TRUE); // 啟用控制項
        Sleep(100); // 降低 CPU 佔用
    }
    return 0;
}

啟動/停止控制


// 啟動按鈕處理
void CMyDlg::OnStartBreak()
{
    g_bRunning = TRUE;
    CreateThread(NULL, 0, BreakThread, NULL, 0, &g_dwThreadId);
}

// 停止按鈕處理
void CMyDlg::OnStopBreak()
{
    g_bRunning = FALSE;
    // 可選:WaitForSingleObject(hThread, INFINITE);
}

完整視窗類別對比

函數用途備註
WindowFromPoint螢幕點 → 最上層視窗含透明/禁用視窗
ChildWindowFromPoint父視窗客戶區點 → 子視窗不遞迴,含隱藏/禁用
RealChildWindowFromPoint同上,但跳過隱藏/禁用/透明較實用
GetParent取得父視窗單層
GetAncestor(hWnd, GA_ROOT)取得頂層視窗跨進程亦可

編譯環境需求

需安裝 Windows SDK (含 windows.h 更新版、lib、dll),並將 include/lib 目錄加入 VC++ 專案設定。SDK 提供 RealChildWindowFromPoint 等較新 API。

進階:模擬「按鍵突破專家」全域啟用功能

原理:取得滑鼠下的 頂層父視窗,遞迴 EnumChildWindows 將所有停用子視窗啟用:


BOOL CALLBACK EnableAllChildren(HWND hChild, LPARAM lParam)
{
    EnableWindow(hChild, TRUE);
    return TRUE; // 繼續列舉
}

void EnableAllDisabledInWindow(HWND hWnd)
{
    EnumChildWindows(hWnd, EnableAllChildren, 0);
}

在輪詢執行緒中呼叫 EnableAllDisabledInWindow(hParent) 即可達到同樣效果。

結語

按鍵突破核心技術鏈:GetCursorPos → WindowFromPoint → ScreenToClient → 遞迴 RealChildWindowFromPoint → EnableWindow(TRUE)。配合多執行緒輪詢即可即時生效。理解此原理不僅能自製工具,更能深入掌握 Windows 視窗階層與座標系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved