调试WIN32集中错误 [英] Debugging WIN32 focus bugs
问题描述
我正在开发一个包含主窗口和很多子窗口的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屋!