2011-03-22 23 views
3

我在試圖找出如何檢測Windows桌面Aero Peek模式是否開啓。特別是我需要檢測我的窗口內容是否顯示或繪製爲具有透明背景的框架。我知道我可以從Aero Peek中排除我的窗口,但這不是我現在需要的。如何檢測Aero Peek模式是否在

TIA

+0

你可以使用DwmSetIconicThumbnail()並檢查WM_DWMSENDICONICTHUMBNAIL消息嗎?請參閱http://msdn.microsoft.com/en-us/library/ff819048(v=VS.85).aspx – 2011-03-22 01:52:21

回答

2

您的桌面將進入這個「航空皮克」模式。如果顯示「任務切換器」對象,並且結合其上的DWM模式,則可以使用windows event hook追蹤用戶是否正在窺視窗口。下面是我測試這個想法的一個應用程序(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

這是你所追求的?當用戶通過在任務欄的圖標鼠標懸停偷看窗口

[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."); 
     } 
    } 
+0

您是否確實需要IsAeroActive方法?爲什麼不直接調用API? – 2011-03-22 02:09:16

+0

您不必擁有IsAeroActive方法,只是我編寫代碼的方式,以便更容易閱讀 – BigCheekyBird 2011-03-22 02:25:02

+0

謝謝,但這不是我要找的,您的代碼檢測到DWM是否打開,而我試圖檢測桌面目前是否處於Aero Peek模式。如果將鼠標懸停在任務欄按鈕上,每當窗口縮略圖彈出意味着Aero Peek處於開啓狀態 – Nadine 2011-03-22 02:45:43

0

如果從Windows註冊表中讀取,那裏你可以找到航空的狀態皮克

\ HKEY_CURRENT_USER \ SOFTWARE \微軟\的Windows \ DWM

是一個名爲的DWORD值EnableAeroPeek設置如下:

=啓用 =禁用

只是比較爲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"); 

你也可以改變這些值,並立即航空皮克狀態會發生變化。

相關問題