Windows デスクトップのAero Peekモードがオンになっているかどうかを検出する方法を見つけようとしています。特に、ウィンドウのコンテンツが透明な背景を持つフレームとして表示または描画されているかどうかを検出する必要があります。ウィンドウを Aero Peek から除外できることはわかっていますが、これは現時点で必要なものではありません。
ティア
これはあなたが求めているものですか?
[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.");
}
}
ユーザーがマウスをタスクバー アイコンの上に置いてウィンドウを覗くと、デスクトップはこの「Aero Peek」モードになります。Windows イベント フックを使用して、" 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;
}
これが役に立てば幸いです、よろしく
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 のステータスが変更されます。