要回答您预先存储窗口文本的问题:我真的不知道,任何给定的窗口也不知道。要获得该信息,您必须改为询问窗口管理器。
与窗口有关的所有信息都存储在由窗口管理器维护的内部结构中。窗口管理器由 Win32k.sys 实现,因此这些内部结构驻留在内核内存中。AHWND
用作窗口管理器控制的表的索引。即使表条目以只读方式映射到用户空间内存,获取所需信息也相当乏味。
到目前为止,很糟糕。然而,还没有全部丢失。您仍然可以获得所需的信息。
最简单的选择是使用 Spy++ (Spyxx.exe)。它作为 Visual Studio 的一部分提供,有助于检索窗口特定信息,除其他方面外,它将显示窗口的文本。鉴于您的要求,您可以转到Spy -> Find Window...(或按[Ctrl]+ F)并输入窗口的句柄(以十六进制表示,不带 0x 前缀)。但是,信息不会自动刷新。您需要手动单击刷新按钮。
如果您想在 Visual Studio 的调试器中获得实时信息,则必须编写一个调试器表达式评估插件。Microsoft 不正式支持表达式求值器。因此没有官方文档。如何为 Visual Studio 2012 调试器编写自定义本机可视化工具 DLL?如果您想沿着这条路线走,它会提供有用的信息。显示窗口文本条目的表达式求值器如下所示:
HwndEEAddin.h:
// HwndEEAddin.h : main header file for the NatvisAddIn DLL
//
#if !defined( INC_HWNDEEADDIN_H_ )
#define INC_HWNDEEADDIN_H_
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#define ADDIN_API extern "C" __declspec(dllexport)
/* DebugHelper structure used from within the */
typedef struct tagDEBUGHELPER
{
DWORD dwVersion;
BOOL (WINAPI *ReadDebuggeeMemory)( struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot );
// from here only when dwVersion >= 0x20000
unsigned __int64 (WINAPI *GetRealAddress)( struct tagDEBUGHELPER *pThis );
BOOL (WINAPI *ReadDebuggeeMemoryEx)( struct tagDEBUGHELPER *pThis, unsigned __int64 qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot );
int (WINAPI *GetProcessorType)( struct tagDEBUGHELPER *pThis );
} DEBUGHELPER;
/* Exported Functions */
ADDIN_API HRESULT WINAPI AddIn_HWND( DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t maxResult, DWORD reserved );
#endif // !defined( INC_HWNDEEADDIN_H_ )
HwndEEAddin.cpp:
#include "HwndEEAddin.h"
#include <strsafe.h>
ADDIN_API HRESULT WINAPI AddIn_HWND( DWORD dwAddress, DEBUGHELPER* pHelper, int /*nBase*/, BOOL bUniStrings, char *pResult, size_t maxResult, DWORD /*reserved*/ )
{
HRESULT hr = E_FAIL;
HWND hWnd = reinterpret_cast< HWND >( dwAddress );
if ( hWnd != NULL )
{
bool bGotWindowText = false;
CHAR asciiWindowText[ 128 ] = { 8 };
if ( IsWindowUnicode( hWnd ) )
{
WCHAR buffer[ 128 ] = { 0 };
if ( GetWindowTextW( hWnd, buffer, ARRAYSIZE( buffer ) ) )
{
if ( WideCharToMultiByte( CP_THREAD_ACP, 0x0, buffer, -1, asciiWindowText, ARRAYSIZE( asciiWindowText ), NULL, NULL ) > 0 )
{
bGotWindowText = true;
}
}
}
else
{
if ( GetWindowTextA( hWnd, asciiWindowText, ARRAYSIZE( asciiWindowText ) ) )
{
bGotWindowText = true;
}
}
if ( bGotWindowText )
{
hr = StringCbPrintfA( pResult, maxResult, "{pText=\"%s\"}", asciiWindowText );
}
}
return hr;
}
要在 Visual Studio 2010 及更高版本中注册插件,您必须将 .dll 与以下文件一起复制到 %USERPROFILE%\Documents\Visual Studio 2012\Visualizers。
HwndEEAddin.natvis:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<!-- Place this file and the AddIn-DLL to this folder: %USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\ -->
<Type Name="HWND__">
<DisplayString LegacyAddin="HwndEEAddin.dll" Export="_AddIn_HWND@28"></DisplayString>
</Type>
</AutoVisualizer>
在 2010 之前的 Visual Studio 版本中,您必须通过将以下条目添加到 [AutoExpand] 部分来编辑 autoexp.dat:
HWND__ = $ADDIN(HwndEEAddin.dll,_AddIn_HWND@28)
.dll 必须位于 devenv.exe 目录或 PATH 中。否则,您将不得不使用完全限定的路径名。有关 VS 2010 之前的 Visual Studio 表达式评估器的更多信息,请参阅自定义 Visual Studio 调试器显示您的数据。