2012-01-15 59 views
2

我正在開發包含一個主窗口和大量的子窗口的WIN32/C++應用程序,我尋找能幫助我在跟蹤對焦錯誤的工具。調試WIN32焦點錯誤

我特別想要一個工具,它可以突出顯示當前具有焦點的控制(或告訴我,沒有控制當前具有焦點)。另外,我讀過使用遠程調試器可能會幫助解決這類錯誤的地方。任何想法如何做到這一點?

UPDATE:傑弗裏裏希特寫於1997年的一篇文章包含的工具尋找除其他事項外的焦點:http://www.microsoft.com/msj/0397/Win32/Win320397.aspx

回答

2

間諜++消息日誌會給焦點更改的完整記錄,而是試圖解碼什麼從日誌中發生的事情是件苦差事。間諜++的討厭的用戶界面不起作用。

遠程調試是有用的,因爲調試器不會與應用程序的啓動和重點干預,但我不知道有一個簡單的方法來確定從調試器的焦點窗口。這裏有一個couplearticles配置它。提示:如果不起作用,請仔細檢查您的DCOM和防火牆設置。

顯然,這將是最好找不正是你想要的東西的工具,但我不能,我很無聊,所以我寫了這個代碼。它創建一個半透明的藍色窗口,位於聚焦控件的頂部。它對點擊是透明的,所以它不應該干擾使用你的應用程序。

初始化它只是在你的程序的初始化代碼的地方創建一個定時器:

// Check the focus ten times a second 
// Change hwndMain to your main application window 
// Note that this won't work if you have multiple UI threads 
::SetTimer(hwndMain, 1, 100, HighlightTimerProc); 

,並添加以下代碼:

LRESULT CALLBACK HighlightWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
    case WM_NCHITTEST: 
     return HTTRANSPARENT; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    return 0; 
} 

VOID CALLBACK HighlightTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) 
{ 
    // static locals are bad 
    static bool initialised = false; 
    static HWND hwndHighlight = 0; 

    if (!initialised) 
    { 
     HINSTANCE hInstance = 0; 

     WNDCLASSEX wcex; 

     wcex.cbSize = sizeof(WNDCLASSEX); 

     wcex.style   = CS_HREDRAW | CS_VREDRAW; 
     wcex.lpfnWndProc = HighlightWndProc; 
     wcex.cbClsExtra  = 0; 
     wcex.cbWndExtra  = 0; 
     wcex.hInstance  = hInstance; 
     wcex.hIcon   = 0; 
     wcex.hCursor  = 0; 
     wcex.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHTTEXT); 
     wcex.lpszMenuName = 0; 
     wcex.lpszClassName = L"HighlightWindowClasss"; 
     wcex.hIconSm  = 0; 

     ATOM atomHighlightClass = RegisterClassEx(&wcex); 

     hwndHighlight = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW, 
      (LPCTSTR)atomHighlightClass, L"", WS_POPUP, 
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 

     // Set opacity to 200/255 
     SetLayeredWindowAttributes(hwndHighlight, 0, 200, LWA_ALPHA); 

     initialised = true; 
    } 

    static HWND hwndCurrentHighlight = 0; 

    HWND hwndFocus = GetFocus(); 
    if (hwndFocus != hwndCurrentHighlight) 
    { 
     if (hwndFocus == 0) 
     { 
      ShowWindow(hwndHighlight, SW_HIDE); 
     } 
     else 
     { 
      RECT rect; 
      GetWindowRect(hwndFocus, &rect); 
      MoveWindow(hwndHighlight, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, false); 
      ShowWindow(hwndHighlight, SW_SHOW); 
     } 
     hwndCurrentHighlight = hwndFocus; 
    } 
} 
+0

非常酷,謝謝!你見過我添加到裏希特工具的鏈接嗎? – 2012-01-27 13:52:29

+0

乾杯。我看到了這個工具,但是使用spy ++我知道將窗口句柄映射到實際的窗口可能是一件難事,所以我做了覆蓋。 BrendanMcK建議的檢查工具看起來可能是兩全其美,儘管我還沒有嘗試過。 – arx 2012-01-27 14:40:53

0

我認爲你可以使用間諜++這是一部分哦Visual Studio或Windows SDK中。 它告訴你很多其他信息,你也可以捕獲發送到選定窗口的消息。

http://msdn.microsoft.com/en-us/library/dd460760.aspx

+0

不幸的是,Spy ++沒有這樣做,Winspector也不如此。 – 2012-01-15 11:46:56

2

Inspect工具,在Windows SDK下載的一部分,可以在這裏很有用。它旨在測試兩個與Accessibility相關的API - MSAA和UI自動化 - 以及這兩個API都允許可訪問性和測試工具跟蹤焦點的事情之一。

使用它跟蹤焦點的最簡單方法是將其置於MSAA模式,檢查選項以僅跟蹤焦點更改(即,關閉鼠標指針後關閉),然後打開黃色高光矩形。現在焦點發生變化,您可以看到矩形移動。作爲獎勵,如果焦點轉移到隱藏或離屏的地方,您將看不到矩形,但控件的名稱和Win32類將顯示在窗口中。

注意檢查顯示焦點事件的一個超集:你不只是HWND重點的變化,也通知時一定控制範圍內的重點動作 - 比如在列表框中的項目之間。自動化測試和可訪問性需要這些,但爲了您的目的,您應該可以忽略這些;這是額外的信息,但不應該太多。