【问题标题】:Find Window and change it's name找到窗口并更改它的名称
【发布时间】:2016-03-10 12:52:41
【问题描述】:

支持

我想做的是找到一个窗口,尽管它是进程 ID,获取该窗口的名称并将其更改为我想要的东西。

我发现了一些关于它的东西:(代码 1)

 int WINAPI GetWindowText(
   _In_  HWND   hWnd,
   _Out_ LPTSTR lpString,
   _In_  int    nMaxCount
    );

这个:(代码2)

    CWnd* pWnd = GetDlgItem(); GetDlgIt
pWnd->SetWindowText(_T("WindowName"));


CString str;
pWnd->GetWindowText(str);
ASSERT(str == _T("WindowName"));

还有这个(代码 3)

    HWND WindowHandel = FindWindowA(0, "WindowName"); 

    DWORD proccesID = 0

    GetWindowThreadProcessId(WindowHandel, &proccesID);

我的问题是: 我如何获取进程 ID,获取该进程的窗口名称,将其放入以便代码可以将 Hwnd 识别为我的窗口名称并将其更改为我想要的东西。 像这样:

Process = "anyprocess.exe"
Get Process ID <
Process ID = 1234567
Get window name from the ProcessID we have <
Window name = "ILoveYou"
Change "ILoveYou" to "IHaveYou"

如果我有多个同名窗口,有办法检查第一个打开的窗口,这样我就不会更改其他窗口?

在我的脑海中,从进程 ID 中获取 WindowName 似乎更安全,问题是我不想对代码说我知道窗口名称,我希望它像 Liam Neeson 一样找到并更改它对那些坏人做了。

而且我还想了解更多关于使用“(0,....”或“(NULL,....”)的信息,“FindWindowA”命令只是一个例子,我总是看到这个并且不要不知道怎么正确使用:

    FindWindowA(0, "WindowName")

我想要的一个例子对我有很大帮助 =) 感谢您的耐心等待。

【问题讨论】:

    标签: c++ windows window pid hwnd


    【解决方案1】:

    不,这是不可能的。多个窗口可以有相同的 PID。

    但是,假设目标应用程序是单线程的,只有一个可见窗口,您可以遍历所有窗口并检查它们的 PID 以找到匹配项。您必须跳过不可见的窗口。或者更好的是,跳过非 Alt-Tab 窗口。这是它是如何完成的。

    注意,我写这个只是为了好玩,我自己不会把它放在任何应用程序中。

    BOOL IsAltTabWindow(HWND hwnd)
    {
        if (!IsWindowVisible(hwnd)) return FALSE;
    
        HWND next = NULL;
        HWND parent = GetAncestor(hwnd, GA_ROOTOWNER);
        while (parent != next)
        {
            next = parent;
            parent = GetLastActivePopup(parent);
            if (IsWindowVisible(parent)) break;
        }
        if (next != hwnd) return FALSE;
    
        TITLEBARINFO ti = { 0 };
        ti.cbSize = sizeof(ti);
        GetTitleBarInfo(hwnd, &ti);
        if (ti.rgstate[0] & STATE_SYSTEM_INVISIBLE) return FALSE;
    
        if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) return FALSE;
    
        return TRUE;
    }
    
    BOOL CALLBACK enumProc(HWND hwnd, LPARAM lp)
    {
        DWORD search_pid = DWORD(lp);
        if (!IsAltTabWindow(hwnd))
            return 1;
        DWORD pid = 0;
        GetWindowThreadProcessId(hwnd, &pid);
        if (pid != search_pid) return 1;
        SetWindowText(hwnd, "un-advised code");
        return 0;
    }
    
    int main()
    {
        DWORD search_pid = 0;
        HWND hwnd = FindWindow(0, "Find me");
        GetWindowThreadProcessId(hwnd, &search_pid);
    
        EnumWindows(enumProc, LPARAM(search_pid));
    
        return 0;
    }
    


    编辑,解释:

    试试下面的代码。首先运行 Window 的记事本,确保只有一个记事本实例。

    如果您在 Windows 10 上运行以下代码,它将显示的不是一个,而是 3 个与记事本具有相同 PID 的窗口。其中 2 个窗口是不可见的,它们被操作系统使用,我们不应该触摸它们。

    所以我们至少要跳过不可见的窗口。还有许多其他系统窗口,我们也不希望与它们有任何关系。

    IsAltTabWindow 是避开这些窗口的好方法。这确保我们只查看可通过 Alt-Tab 键访问的窗口。

    int main()
    {
        HWND hwnd = FindWindow("Notepad", 0);
        if (!hwnd) return 0;
        DWORD search_pid = 0;
        GetWindowThreadProcessId(hwnd, &search_pid);
    
        for (hwnd = GetWindow(GetDesktopWindow(), GW_CHILD); 
            hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT))
        {
            char buf[300];
            GetWindowText(hwnd, buf, 300);
    
            DWORD pid = 0;
            GetWindowThreadProcessId(hwnd, &pid);
            if (pid == search_pid)
                std::cout << pid << "\n";
        }
    
        return 0;
    }
    

    【讨论】:

    • 为什么不在应用程序中使用它?那是if (next != hwnd) return FALSE; TITLEBARINFO ti = { 0 }; ti.cbSize = sizeof(ti); GetTitleBarInfo(hwnd, &amp;ti); if (ti.rgstate[0] &amp; STATE_SYSTEM_INVISIBLE) return FALSE; if (GetWindowLong(hwnd, GWL_EXSTYLE) &amp; WS_EX_TOOLWINDOW) return FALSE; return TRUE;
    • 假设目标exe。我正在寻找只有一个窗口,我想在执行程序时更改它的名称一次,就在我启动它时,然后它停止尝试查找 ID 和窗口并更改它,是不是可能?
    • 查看编辑以获得更多解释。我不会使用的原因主要是因为没有实际原因。如果外部窗户是我的,那么我应该想办法找到它们。例如,使用类名,或者窗口之间的某种消息传递,会更加可靠和高效。
    【解决方案2】:

    您可能会看看 15 年前在 www.codeguru.com 上发布的这个基于 MFC 的旧应用程序(时间过得真快……)。

    您可能会对基于鼠标点击屏幕获取 HWND 的机制感兴趣。

    http://www.codeguru.com/cpp/misc/samples/article.php/c1465/Password-Retrieval-Application.htm

    Z.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多