2012-01-15 17 views
2

メインウィンドウと多くの子ウィンドウを含むWIN32/C++アプリケーションを開発しています。フォーカスバグの追跡に役立つツールを探しています。WIN32フォーカスバグのデバッグ

特に、現在フォーカスを持っているコントロールを強調表示するツールが必要です(または、コントロールに現在フォーカスがないことを教えてください)。また、私は、リモートデバッガを使用すると、この種のバグを助けるかもしれないと読んだところです。どのようにそれを行うにはどのようなアイデア?

UPDATE:私はあなたがその一部である++スパイを使用することができると思うhttp://www.microsoft.com/msj/0397/Win32/Win320397.aspx

答えて

2

Aスパイ++メッセージログには、フォーカスの変更の完全な記録を与えるが、ログから起こっていたものを解読しようとする雑用であるだろう。 Spy ++の厄介なUIは役に立たない。

リモートデバッグは、デバッガがアプリケーションのアクティブ化とフォーカスに干渉しないので便利ですが、デバッガからフォーカスされたウィンドウを簡単に特定する方法がないかどうかはわかりません。設定時には、のcoupleがあります。ヒント:動作しない場合は、DCOMとファイアウォールの設定を再確認してください。

明らかに、あなたが望むものを正確に実行するツールを見つけるのは最善でしょうが、私はできないし、退屈してこのコードを書きました。フォーカスされたコントロールの上に置かれた半透明の青色のウィンドウを作成します。クリックには透過的なので、アプリの使用に支障はないはずです。 、Inspectツール、WindowsのSDKのダウンロードの一部をすることができます

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

これは非常にクールです、ありがとう!私はリヒテルのツールに追加したリンクを見たことがありますか? –

+0

乾杯。私はツールを見ましたが、spy ++を使用していると、ウィンドウハンドルを実際のウィンドウにマップする手間になるので、オーバーレイを行いました。 BrendanMcKによって提案されたInspectツールは、まだ試していないが、両方の世界で最高のものがあるようだ。 – arx

0

オハイオ州のVisual StudioまたはWindows SDK:ジェフリー・リヒターは、他のものの間でフォーカスを見つけるためのツールが含まれている1997年の記事を書きました。 これは他の情報がたくさんあることを伝え、選択したウィンドウに送信されたメッセージをキャプチャすることもできます。

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

+0

残念ながら、Spy ++はそれを実行せず、Winspectorもそうではありません。 –

2

// 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); 

、次のコードを追加します。単にどこかにあなたのプログラムの初期化コードでタイマーを作成し、それを初期化するために

ここで便利です。アクセシビリティ関連の2つのAPI(MSAAとUIオートメーション)をテストし、両方のAPIがアクセシビリティとテストツールでフォーカスを追跡できるようにすることを目的としています。

フォーカスを追跡する最も簡単な方法は、MSAAモードにすることです。焦点の変更のみに従うようにオプションをオンにします(つまり、マウスポインタの後にオフにします)。黄色のハイライトの矩形をオンにします。フォーカスが変わると、矩形の動きを見ることができます。ボーナスとして、フォーカスが隠されているものや画面外にあるものに行くと、四角形は表示されませんが、コントロールの名前とWin32クラスがウィンドウに表示されます。

Inspectは、フォーカスイベントのスーパーセットを示しています.HWNDフォーカスの変更だけでなく、フォーカスが特定のコントロール内を移動したとき(たとえば、リストボックス内のアイテム間など)も通知されます。自動化されたテストとアクセシビリティにはこれらが必要ですが、あなたの目的のためにはこれらを無視するだけでOKです。余分な情報ですが、あまりにも多くの情報を得るべきではありません。