【问题标题】:how to detect if Aero Peek mode is on如何检测 Aero Peek 模式是否开启
【发布时间】:2011-03-22 01:26:34
【问题描述】:

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

TIA

【问题讨论】:

标签: c# windows pinvoke aero peek


【解决方案1】:

这就是你所追求的吗?

    [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?
  • 你不必拥有 IsAeroActive 方法,就像我编写的那样,试图让它更容易阅读
  • 谢谢,但这不是我想要的,你的代码检测 DWM 是否打开,而我试图检测桌面当前是否处于 Aero Peek 模式。如果将鼠标悬停在任务栏按钮上,则可以启动它,每当弹出窗口缩略图时意味着 Aero Peek 已打开
  • @Nadine 当且仅当 DWM 组合启用时,AeroPeek 肯定会开启?
【解决方案2】:

当用户通过将鼠标悬停在任务栏图标上查看窗口时,您的桌面会进入这种“Aero Peek”模式。您可以使用windows event hook 来跟踪是否显示了“Task Switcher”对象,结合其上的 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;
}

希望这会有所帮助,问候

【讨论】:

    【解决方案3】:

    如果你从 windows Registry 中读取,你可以在那里找到 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 状态会立即更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-10
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多