cómo detectar si el modo Aero Peek está en marcha
Pregunta
Estoy tratando de averiguar cómo detectar si Windows Desktop Mirada aerodinámica El modo está encendido. En particular, necesito detectar si el contenido de mi ventana se muestra o se dibuja como un marco con fondo transparente. Sé que puedo excluir mi ventana de Aero Peek, pero esto no es lo que necesito en este momento.
TIA
Solución
Tu escritorio entraría en esto "Mirada aerodinámica"Modo cuando el usuario es mirada Windows al pasar el mouse sobre los iconos de la barra de tareas. Puedes usar Gancho de eventos de Windows rastrear si "Conmutador de tareas"Se muestra el objeto, combinado con el modo DWM en él, debería decirle si el usuario está mirando una ventana. A continuación se muestra una aplicación que hice para probar esta idea (C ++, avíseme si hay problemas para convertirla en 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;
}
Espero que esto ayude, Saludos
Otros consejos
¿Es esto lo que buscas?
[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.");
}
}
Si lee en el registro de Windows, puede encontrar el estado de Aero Peak
Hkey_current_user software Microsoft Windows dwm
Es un valor dWord nombrado EnableAeropeek que se establece de la siguiente manera:
1 = Habilitado 0 = discapacitado
Simplemente compare con 0 o 1 para averiguar si Aeropeek está encendido.
En C# algo como esto:
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");
También puede cambiar esos valores e instantáneamente cambiará el estado de PEEK AERO.