调试WIN32集中错误 [英] Debugging WIN32 focus bugs

查看:157
本文介绍了调试WIN32集中错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个包含主窗口和很多子窗口的WIN32 / C ++应用程序,并且正在寻找可以帮助我追踪焦点错误的工具。



特别是,我想要一个可以突出显示当前焦点的控件的工具(或者告诉我目前没有控件的焦点)。此外,我读过的地方,使用远程调试器可能会帮助这种类型的错误。任何想法如何做到这一点?



更新:Jeffrey Richter在1997年写了一篇文章,其中包含一个找到重点的工具: http://www.microsoft.com/msj/0397/Win32/Win320397.aspx

解决方案

Spy ++消息日志将给出焦点更改的完整记录,但尝试解码发生了什么日志是一件苦差事。 Spy ++的讨厌的用户界面并没有帮助。

远程调试是有帮助的,因为调试器不会干扰你的应用程序的激活和焦点,但我不确定有一个简单的从调试器确定聚焦窗口的方法。以下是情侣。 microsoft.com/en-us/library/bt727f1t%28v=vs.71%29.aspxrel =nofollow noreferrer>关于配置的文章。提示:如果不起作用,仔细检查你的DCOM和防火墙设置。

很明显,最好找到一个完全符合你想要的工具,但是我不能和我无聊,所以我写这个代码。它创建一个半透明的蓝色窗口,位于聚焦控件的顶部。它是透明的点击,所以它不应该干扰使用您的应用程序。



初始化它只需在您的程序的初始化代码中的某处创建一个计时器:

  //每秒检查焦点十次
//将hwndMain更改为主应用程序窗口
//注意:没有工作,如果你有多个UI线程
:: SetTimer(hwndMain,1,100,HighlightTimerProc);

并添加以下代码:

<$ p


$ $
case WM_NCHITTEST:
返回HTTRANSPARENT;
默认值:
返回DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;

$ b $ 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 = LHighlightWindowClasss;
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);

//设置不透明度为200/255
SetLayeredWindowAttributes(hwndHighlight,0,200,LWA_ALPHA);

initialised = true;
}

static HWND hwndCurrentHighlight = 0;

HWND hwndFocus = GetFocus(); (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;
}
}


I'm developing a WIN32/C++ application containing a main window and a lot of child windows, and I'm looking for tools that could assist me in tracking down focus bugs.

In particular, I'd like a tool that can highlight the control that currently has the focus (or tell me that no control currently has the focus). Also I've read somewhere that using a remote debugger may assist in this kind of bugs. Any idea how to do that?

UPDATE: Jeffrey Richter wrote an article in 1997 which contains a tool for finding the focus among other things: http://www.microsoft.com/msj/0397/Win32/Win320397.aspx

解决方案

A Spy++ message log will give a complete record of focus changes, but trying to decode what was happening from the log is a chore. Spy++'s nasty UI doesn't help.

Remote debugging is helpful because the debugger won't interfere with your application's activation and focus, but I'm not sure there's a simple way to determine the focused window from the debugger. Here are a couple of articles on configuring it. Hint: if it doesn't work, double-check your DCOM and firewall settings.

Obviously it would be best to find a tool that does exactly what you want but I couldn't and I was bored so I wrote this code. It creates a semi-transparent blue window that sits on top of the focused control. It's transparent to clicks so it shouldn't interfere with using your app.

To initialise it simply create a timer somewhere in your program's initialisation code:

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

and add the following code:

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;
    }
}

这篇关于调试WIN32集中错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆