查找窗口并更改其名称

Find Window and change it's name

本文关键字:窗口 查找      更新时间:2023-10-16

Sup

正在尝试做的是一种查找窗口的方法,尽管它是进程 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")

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

不,这不能做。多个窗口可以具有相同的 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;
}


编辑,说明:

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

如果您在 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;
}

你可以看看这个旧的基于MFC的应用程序,发布于15年前 www.codeguru.com(时间过得很快......

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

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

Z.