如何在调试时获取CEdit(或CWnd)文本
How to get CEdit (or CWnd) text in debug time
当我调试项目时,CEdit
对象的文本发生了更改,我希望看到新的值。但是监视窗口不显示文本成员
文本存储在哪里?
编辑:我忘了写我使用Visual C++6.0('98版)
观察窗口中的CEdit树看起来是这样的:
m_editBox
|
+ [CWnd]
|
+ CCmdTarget
+ classCWnd
+ m_hWnd
+ wndTop
+ wndBottom
+ wndTopMost
+ wndNoTopMost
+ m_hWndOwner
- m_nFlags
- m_pfnSuper
- m_nMsgDragList
- m_nModalResult
+ m_pDropTarget
+ m_pCtrlCont
+ m_pCtrlSite
+ _messageEntries
+ messageMap
+ CWnd
|
+ CCmdTarget
+ m_hWnd
+ m_hWndOwner
- m_nFlags
- m_pfnSuper
- m_nModalResult
+ m_pDropTarget
- m_pCtrlCont
- m_pCtrlSite
要回答您的问题,窗口的文本存储在哪里:我真的不知道,任何给定的窗口也不知道。要获得这些信息,您必须询问窗口管理器。
与窗口有关的所有信息都存储在由窗口管理器维护的内部结构中。窗口管理器由Win32k.sys实现,因此这些内部结构位于内核内存中。CCD_ 2用作窗口管理器控制的表的索引。即使表条目以只读方式映射到用户空间内存中,获取所需信息也是相当乏味的。
到目前为止,太糟糕了。然而,并不是所有的东西都失去了。你仍然可以获得你需要的信息。
最简单的选择是使用Spy++(Spyxx.exe)。它作为Visual Studio的一部分提供,有助于检索窗口特定的信息,以及显示窗口文本的其他方面。根据您的要求,您将转到间谍->查找窗口(或按[Ctrl]+F),然后输入窗口的句柄(十六进制,不带0x前缀)。但是,信息不会自动刷新。您需要手动单击刷新按钮。
如果希望在VisualStudio的调试器中获得实时信息,则必须编写调试器表达式评估加载项。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 DocumentsVisual Studio 2012Visualizers -->
<Type Name="HWND__">
<DisplayString LegacyAddin="HwndEEAddin.dll" Export="_AddIn_HWND@28"></DisplayString>
</Type>
</AutoVisualizer>
在Visual Studio 2010之前的版本中,您必须通过在[AutoExpand]部分添加以下条目来编辑autoexp.dat:
HWND__ = $ADDIN(HwndEEAddin.dll,_AddIn_HWND@28)
.dll必须位于devenv.exe目录或PATH上。否则,您将不得不使用完全限定的路径名。有关VS 2010之前的Visual Studio表达式计算器的其他信息,请参阅自定义数据的Visual Studio调试器显示。
实际文本保存在控件的某种关联内存中,您无法直接访问该内存。只有控件的句柄HWND
封装到CEdit
类中。为了从那里获取文本,您需要提前将代码CEdit::GetWindowText
中的文本写入本地内存,然后使用调试器对其进行检查。
如果您想查看新值,那么您必须使用一个变量并从窗口中检索文本。
CString text;
GetDlgItemText(ID, text);
CEdit的"GetWindowText"方法简单地发送一条Windows消息来获取文本,而不是使用简单的文本访问器方法的函数调用。。m_hWnd是O/S深层内部中某些数据结构的"句柄",只有窗口的O/S代码知道如何检索文本。
我希望它更简单,但MFC只是Win32 API的包装器。您可以尝试使用C#,它可以更好地将UI呈现为对象(相对于间接访问的C/Pascal/汇编结构的包装器)
- 文本文件中的单词链表
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何将内容数组写入文本文件?
- 无法通过空白将文本文件行分隔为矢量
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- C++将文本文件中的数据读取到结构数组中
- 在指针的帮助下,文本文件中单词的频率
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 将值从二维数组输出到文本文件
- 如何在c++中从文本文件中逐行读取整数
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 从文本文件中读取时钟时间和事件时间并进行处理
- 如何从文本文件中读取值和数组
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何根据单词在文本中出现的概率输出单词
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- C++试图读取一个文件并输出到另一个文本文件
- 如何在调试时获取CEdit(或CWnd)文本