如何检测Aero Peek模式是否开启

3

我想知道如何检测Windows桌面Aero Peek模式是否开启。特别是我需要检测我的窗口内容是否显示为带有透明背景的框架。我知道我可以将我的窗口从Aero Peek中排除,但这不是我现在需要的。

TIA


你能使用DwmSetIconicThumbnail()并检查WM_DWMSENDICONICTHUMBNAIL消息吗?请参阅http://msdn.microsoft.com/en-us/library/ff819048(v=VS.85).aspx。 - Brian Lyttle
3个回答

3

这是您想要的吗?

    [DllImport("dwmapi.dll", PreserveSig = false)]
    public static extern bool DwmIsCompositionEnabled();

    public bool IsAeroActive()
    {
        // Check if Aero is enabled;
        if (DwmIsCompositionEnabled())
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bool aeroEnabled = IsAeroActive();

        if (aeroEnabled)
        {
            MessageBox.Show("Aero is enabled.");
        }
        else
        {
            MessageBox.Show("Aero is disabled.");
        }
    }

你真的需要IsAeroActive方法吗?为什么不直接调用API呢? - Robert Levy
你不必拥有IsAeroActive方法,只需要按照我编写代码的方式尝试让它更易于阅读即可。 - BigCheekyBird
谢谢,但这不是我正在寻找的,您的代码检测到DWM是否开启,而我正在尝试检测桌面当前是否处于Aero Peek模式。当您将鼠标悬停在任务栏按钮上时,如果弹出窗口缩略图,则表示Aero Peek已开启。 - Nadine
@Nadine,AeroPeek肯定是在DWM合成启用的情况下才会开启的,对吧? - David Heffernan

2
当用户将鼠标悬停在任务栏图标上并查看窗口时,您的桌面会进入“Aero Peek”模式。您可以使用 Windows事件钩子 来跟踪是否显示了“任务切换器”对象,结合 DWM 模式,就可以告诉您用户是否正在查看窗口。以下是我制作的一个应用程序来测试这个想法(使用C++编写,如果转换为C#有问题,请告诉我)。
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <objbase.h>
#include <Oleacc.h>
#include <iostream>

#define THREAD_MESSAGE_EXIT     WM_USER + 2000

HWINEVENTHOOK eventHook;
HWND taskSwitcherHwnd = 0;

// process event
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd, 
                             LONG idObject, LONG idChild, 
                             DWORD dwEventThread, DWORD dwmsEventTime)
{
    if (event == EVENT_OBJECT_SHOW) 
    {
        IAccessible* pAcc = NULL;
        VARIANT varChild;       
        HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);  
        if (hr == S_OK && pAcc != NULL)
        {
            BSTR accName;
            pAcc->get_accName(varChild, &accName);
            if (wcscmp(accName, L"Task Switcher")==0)
            {
                std::cout << "Aero Peek on\n";
                taskSwitcherHwnd = hwnd;
            }
            SysFreeString(accName);
            pAcc->Release();
        }
    }
    else if (event == EVENT_OBJECT_HIDE && taskSwitcherHwnd!=0 && taskSwitcherHwnd==hwnd)
    {
        std::cout << "Aero Peek off\n";
        taskSwitcherHwnd = 0;
    }
}

// thread proc for messages processing
// needed for event's hook to work
DWORD WINAPI TreadProc(LPVOID n)
{
    std::cout << "InitializeEventHook\n";
    CoInitialize(NULL);
    eventHook = SetWinEventHook(
        EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE,   
        NULL, HandleWinEvent, 0, 0, 
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);   

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.message==THREAD_MESSAGE_EXIT) 
        {
            break;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    std::cout << "ShutdownEventHook\n";
    UnhookWinEvent(eventHook);
    CoUninitialize();
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "Detect Aero Peek\n";

    DWORD threadId;
    int value = 0;
    HANDLE hThread = CreateThread( NULL, 0, TreadProc, &value, 0, &threadId);

    char a;
    std::cin >> a;

    PostThreadMessage(threadId, THREAD_MESSAGE_EXIT, 0, 0);
    WaitForSingleObject(hThread, 10000);
    CloseHandle(hThread);

    return 0;
}

希望这有所帮助,敬礼。

0

如果你从Windows注册表中读取,你可以找到Aero Peek的状态。

\HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM

有一个名为EnableAeroPeek的DWORD值,其设置如下:

1 = 启用 0 = 禁用

只需将其与0或1进行比较即可确定是否启用了AeroPeek。

在C#中,可以使用以下代码:

Using Microsoft.Win32;

...

RegistryKey AeroPeek = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\DWM", true);
       if ((int)AeroPeek.GetValue("EnableAeroPeek") == 1)
        {
            MessageBox.Show("Aero Peek is ON");
        }
        else MessageBox.Show("Aero Peek is OFF");

您还可以更改这些值,即可立即更改 Aero Peek 状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接