显示“ Alt” Alt; Tab Windows的列表。 (甚至全屏UWP窗口)并检索用户选择的手柄

发布于 2025-01-25 06:32:43 字数 864 浏览 1 评论 0 原文

我需要检索用户选择的窗口的句柄,然后检索其手柄。按下Alt+选项卡时,此窗口必须是显示的窗口之一。

我尝试使用 >,但它不会列举全屏UWP窗口。例如,如果您用照片应用程序打开图片并将其放入全屏幕,则枚举将不会枚举它。

然后,我尝试了

方法显示了Windows的列表,用户可以选择一个,但是它返回a graphicsCaptureItem ,我想您无法从中获得窗口句柄。

是否可以重复使用Alt+Tab窗口来执行此操作(或任何其他显示Windows列表的方式)并检索用户选择的窗口的句柄?

注意:我需要全部按下Alt+选项卡时显示的窗口,甚至全屏UWP窗口,而没有其他窗口。

I need to retrieve the handle of a window selected by the user and then retrieve its handle. This window must be one of those shown when ALT+TAB is pressed.

I tried enumerating the windows using EnumWindows, but it does not enumerate the full screen UWP windows. For example, if you open a picture with the Photos app and put it in full screen, EnumWindows will not enumerate it.

Then I tried EnumChildWindows because I thought it could enumerate everything, even fullscreen UWP windows, but probably not.

The GraphicsCapturePicker.PickSingleItemAsync method shows a list of windows and the user can pick one, but it returns a GraphicsCaptureItem and I guess you can't get the window handle from it.

Is it possible to reuse the ALT+TAB window to do this (or any other way that shows a list of windows) and retrieve the handle of the window selected by the user?

Note: I need all the windows shown when ALT+TAB is pressed, even the full screen UWP windows, and no others.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

多像笑话 2025-02-01 06:32:43

我已经使用 spy ++ Enumwindows nor EnumChildWindows 检索全屏UWP Windows的根所有者的手柄。但是, enumchildWindows 检索他们的子窗口,每个UWP窗口都有一个子窗口,其类名称为 applicationframeInputSinkwindow (和其他子女窗口)。然后,您可以使用getancestor检验根所有者窗口。

因此,要检索“标准”窗口,您可以调用 Enumwindows

但是要检索全屏UWP Windows:

该示例显示了如何同时使用 Enumwindows EnumChildWindows 来枚举所有“ Alt+Tab Windows”,甚至是全屏UWP Windows。这些以两列 datagridview 表格列出,并且与用户单击的行相对应的窗口句柄。

const int GWL_EXSTYLE = -20;
const uint DWMWA_CLOAKED = 14;
const uint DWM_CLOAKED_SHELL = 0x00000002;
const uint GA_ROOTOWNER = 3;
const uint WS_EX_TOOLWINDOW = 0x00000080;
const uint WS_EX_TOPMOST = 0x00000008;
const uint WS_EX_NOACTIVATE = 0x08000000;

private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    dataGridView1.MultiSelect = false;
    dataGridView1.ReadOnly = true;
    dataGridView1.Click += dataGridView1_Click;
    
    EnumWindows(GetAltTabWindows, IntPtr.Zero);
    EnumChildWindows(GetDesktopWindow(), GetFullScreenUWPWindows, IntPtr.Zero);
}

private bool GetAltTabWindows(IntPtr hWnd, IntPtr lparam)
{
    if (IsAltTabWindow(hWnd))
        AddWindowToGrid(hWnd);

    return true;
}

private bool GetFullScreenUWPWindows(IntPtr hWnd, IntPtr lparam)
{
    // Check only the windows whose class name is ApplicationFrameInputSinkWindow
    StringBuilder className = new StringBuilder(1024);
    GetClassName(hWnd, className, className.Capacity);
    if (className.ToString() != "ApplicationFrameInputSinkWindow")
        return true;

    // Get the root owner of the window
    IntPtr rootOwner = GetAncestor(hWnd, GA_ROOTOWNER);

    if (IsFullScreenUWPWindows(rootOwner))
        AddWindowToGrid(rootOwner);

    return true;
}

private bool IsAltTabWindow(IntPtr hWnd)
{
    // The window must be visible
    if (!IsWindowVisible(hWnd))
        return false;

    // The window must be a root owner
    if (GetAncestor(hWnd, GA_ROOTOWNER) != hWnd)
        return false;

    // The window must not be cloaked by the shell
    DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out uint cloaked, sizeof(uint));
    if (cloaked == DWM_CLOAKED_SHELL)
        return false;

    // The window must not have the extended style WS_EX_TOOLWINDOW
    uint style = GetWindowLong(hWnd, GWL_EXSTYLE);
    if ((style & WS_EX_TOOLWINDOW) != 0)
        return false;
    
    return true;
}

private bool IsFullScreenUWPWindows(IntPtr hWnd)
{
    // Get the extended style of the window
    uint style = GetWindowLong(hWnd, GWL_EXSTYLE);

    // The window must have the extended style WS_EX_TOPMOST
    if ((style & WS_EX_TOPMOST) == 0)
        return false;

    // The window must not have the extended style WS_EX_NOACTIVATE
    if ((style & WS_EX_NOACTIVATE) != 0)
        return false;

    // The window must not have the extended style WS_EX_TOOLWINDOW
    if ((style & WS_EX_TOOLWINDOW) != 0)
        return false;

    return true;
}

private void AddWindowToGrid(IntPtr hWnd)
{
    StringBuilder windowText = new StringBuilder(1024);
    GetWindowText(hWnd, windowText, windowText.Capacity);
    var strTitle = windowText.ToString();
    var strHandle = hWnd.ToString("X8");
    dataGridView1.Rows.Add(new string[] { strHandle, strTitle });
}

private void dataGridView1_Click(object sender, EventArgs e)
{
    var dgv = (DataGridView)sender;

    if (dgv.SelectedRows.Count == 0)
        return;

    // Get the value of the first cell of the selected row
    var value = dgv.SelectedRows[0].Cells[0].Value;
    if (value == null)
        return;

    // Convert the value to IntPtr
    var strValue = value.ToString();
    var intValue = int.Parse(strValue, System.Globalization.NumberStyles.HexNumber);
    var windowHandle = new IntPtr(intValue);

    // Do what you want with the window handle
}

当然,只要回调函数具有过滤不同窗口的所有必要的过滤器,您也可以只使用 EnumchildWindows 获取所有“ Alt+Tab Windows”。

I have investigated with Spy++ and neither EnumWindows nor EnumChildWindows retrieve the handles of the root owners of full screen UWP windows. However EnumChildWindows retrieves their child windows, and each UWP window has a child window whose class name is ApplicationFrameInputSinkWindow (and other child windows). Then, you can retrive the root owner window with GetAncestor.

So, to retrieve "standard" windows, you could call EnumWindows.

But to retrieve full screen UWP windows:

This sample shows how to use both EnumWindows and EnumChildWindows to enumerate all "ALT+TAB windows", even full-screen UWP windows. These are listed in a Form with a two-column DataGridView and the window handle corresponding to the row the user clicks on is retrieved.

const int GWL_EXSTYLE = -20;
const uint DWMWA_CLOAKED = 14;
const uint DWM_CLOAKED_SHELL = 0x00000002;
const uint GA_ROOTOWNER = 3;
const uint WS_EX_TOOLWINDOW = 0x00000080;
const uint WS_EX_TOPMOST = 0x00000008;
const uint WS_EX_NOACTIVATE = 0x08000000;

private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    dataGridView1.MultiSelect = false;
    dataGridView1.ReadOnly = true;
    dataGridView1.Click += dataGridView1_Click;
    
    EnumWindows(GetAltTabWindows, IntPtr.Zero);
    EnumChildWindows(GetDesktopWindow(), GetFullScreenUWPWindows, IntPtr.Zero);
}

private bool GetAltTabWindows(IntPtr hWnd, IntPtr lparam)
{
    if (IsAltTabWindow(hWnd))
        AddWindowToGrid(hWnd);

    return true;
}

private bool GetFullScreenUWPWindows(IntPtr hWnd, IntPtr lparam)
{
    // Check only the windows whose class name is ApplicationFrameInputSinkWindow
    StringBuilder className = new StringBuilder(1024);
    GetClassName(hWnd, className, className.Capacity);
    if (className.ToString() != "ApplicationFrameInputSinkWindow")
        return true;

    // Get the root owner of the window
    IntPtr rootOwner = GetAncestor(hWnd, GA_ROOTOWNER);

    if (IsFullScreenUWPWindows(rootOwner))
        AddWindowToGrid(rootOwner);

    return true;
}

private bool IsAltTabWindow(IntPtr hWnd)
{
    // The window must be visible
    if (!IsWindowVisible(hWnd))
        return false;

    // The window must be a root owner
    if (GetAncestor(hWnd, GA_ROOTOWNER) != hWnd)
        return false;

    // The window must not be cloaked by the shell
    DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out uint cloaked, sizeof(uint));
    if (cloaked == DWM_CLOAKED_SHELL)
        return false;

    // The window must not have the extended style WS_EX_TOOLWINDOW
    uint style = GetWindowLong(hWnd, GWL_EXSTYLE);
    if ((style & WS_EX_TOOLWINDOW) != 0)
        return false;
    
    return true;
}

private bool IsFullScreenUWPWindows(IntPtr hWnd)
{
    // Get the extended style of the window
    uint style = GetWindowLong(hWnd, GWL_EXSTYLE);

    // The window must have the extended style WS_EX_TOPMOST
    if ((style & WS_EX_TOPMOST) == 0)
        return false;

    // The window must not have the extended style WS_EX_NOACTIVATE
    if ((style & WS_EX_NOACTIVATE) != 0)
        return false;

    // The window must not have the extended style WS_EX_TOOLWINDOW
    if ((style & WS_EX_TOOLWINDOW) != 0)
        return false;

    return true;
}

private void AddWindowToGrid(IntPtr hWnd)
{
    StringBuilder windowText = new StringBuilder(1024);
    GetWindowText(hWnd, windowText, windowText.Capacity);
    var strTitle = windowText.ToString();
    var strHandle = hWnd.ToString("X8");
    dataGridView1.Rows.Add(new string[] { strHandle, strTitle });
}

private void dataGridView1_Click(object sender, EventArgs e)
{
    var dgv = (DataGridView)sender;

    if (dgv.SelectedRows.Count == 0)
        return;

    // Get the value of the first cell of the selected row
    var value = dgv.SelectedRows[0].Cells[0].Value;
    if (value == null)
        return;

    // Convert the value to IntPtr
    var strValue = value.ToString();
    var intValue = int.Parse(strValue, System.Globalization.NumberStyles.HexNumber);
    var windowHandle = new IntPtr(intValue);

    // Do what you want with the window handle
}

Of course, you can also just use EnumChildWindows to get all "ALT+TAB windows", as long as the callback function has all the necessary filters to filter the different windows.

永不分离 2025-02-01 06:32:43

这就是Microsoft在他们的“ nofollow noreferrer”>屏幕捕获示例示例的方式。

您会在 win32windowenumeration.h


#pragma once
#include <dwmapi.h>

struct Window
{
public:
    Window(nullptr_t) {}
    Window(HWND hwnd, std::wstring const& title, std::wstring& className)
    {
        m_hwnd = hwnd;
        m_title = title;
        m_className = className;
    }

    HWND Hwnd() const noexcept { return m_hwnd; }
    std::wstring Title() const noexcept { return m_title; }
    std::wstring ClassName() const noexcept { return m_className; }

private:
    HWND m_hwnd;
    std::wstring m_title;
    std::wstring m_className;
};

std::wstring GetClassName(HWND hwnd)
{
    std::array<WCHAR, 1024> className;

    ::GetClassName(hwnd, className.data(), (int)className.size());

    std::wstring title(className.data());
    return title;
}

std::wstring GetWindowText(HWND hwnd)
{
    std::array<WCHAR, 1024> windowText;

    ::GetWindowText(hwnd, windowText.data(), (int)windowText.size());

    std::wstring title(windowText.data());
    return title;
}

bool IsAltTabWindow(Window const& window)
{
    HWND hwnd = window.Hwnd();
    HWND shellWindow = GetShellWindow();

    auto title = window.Title();
    auto className = window.ClassName();

    if (hwnd == shellWindow)
    {
        return false;
    }

    if (title.length() == 0)
    {
        return false;
    }

    if (!IsWindowVisible(hwnd))
    {
        return false;
    }

    if (GetAncestor(hwnd, GA_ROOT) != hwnd)
    {
        return false;
    }

    LONG style = GetWindowLong(hwnd, GWL_STYLE);
    if (!((style & WS_DISABLED) != WS_DISABLED))
    {
        return false;
    }

    DWORD cloaked = FALSE;
    HRESULT hrTemp = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));
    if (SUCCEEDED(hrTemp) &&
        cloaked == DWM_CLOAKED_SHELL)
    {
        return false;
    }

    return true;
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    auto class_name = GetClassName(hwnd);
    auto title = GetWindowText(hwnd);

    auto window = Window(hwnd, title, class_name);

    if (!IsAltTabWindow(window))
    {
        return TRUE;
    }

    std::vector<Window>& windows = *reinterpret_cast<std::vector<Window>*>(lParam);
    windows.push_back(window);

    return TRUE;
}

const std::vector<Window> EnumerateWindows()
{
    std::vector<Window> windows;
    EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&windows));

    return windows;
}

This is how Microsoft did it in their Screen Capture example.

You'll find it in the Win32WindowEnumeration.h.


#pragma once
#include <dwmapi.h>

struct Window
{
public:
    Window(nullptr_t) {}
    Window(HWND hwnd, std::wstring const& title, std::wstring& className)
    {
        m_hwnd = hwnd;
        m_title = title;
        m_className = className;
    }

    HWND Hwnd() const noexcept { return m_hwnd; }
    std::wstring Title() const noexcept { return m_title; }
    std::wstring ClassName() const noexcept { return m_className; }

private:
    HWND m_hwnd;
    std::wstring m_title;
    std::wstring m_className;
};

std::wstring GetClassName(HWND hwnd)
{
    std::array<WCHAR, 1024> className;

    ::GetClassName(hwnd, className.data(), (int)className.size());

    std::wstring title(className.data());
    return title;
}

std::wstring GetWindowText(HWND hwnd)
{
    std::array<WCHAR, 1024> windowText;

    ::GetWindowText(hwnd, windowText.data(), (int)windowText.size());

    std::wstring title(windowText.data());
    return title;
}

bool IsAltTabWindow(Window const& window)
{
    HWND hwnd = window.Hwnd();
    HWND shellWindow = GetShellWindow();

    auto title = window.Title();
    auto className = window.ClassName();

    if (hwnd == shellWindow)
    {
        return false;
    }

    if (title.length() == 0)
    {
        return false;
    }

    if (!IsWindowVisible(hwnd))
    {
        return false;
    }

    if (GetAncestor(hwnd, GA_ROOT) != hwnd)
    {
        return false;
    }

    LONG style = GetWindowLong(hwnd, GWL_STYLE);
    if (!((style & WS_DISABLED) != WS_DISABLED))
    {
        return false;
    }

    DWORD cloaked = FALSE;
    HRESULT hrTemp = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));
    if (SUCCEEDED(hrTemp) &&
        cloaked == DWM_CLOAKED_SHELL)
    {
        return false;
    }

    return true;
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    auto class_name = GetClassName(hwnd);
    auto title = GetWindowText(hwnd);

    auto window = Window(hwnd, title, class_name);

    if (!IsAltTabWindow(window))
    {
        return TRUE;
    }

    std::vector<Window>& windows = *reinterpret_cast<std::vector<Window>*>(lParam);
    windows.push_back(window);

    return TRUE;
}

const std::vector<Window> EnumerateWindows()
{
    std::vector<Window> windows;
    EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&windows));

    return windows;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文