VC2010 Unicode字符集下通过ReadProcessMemory跨进程读取SysListView32控件总是乱码

反弹让他 2013-07-21 07:10:22
//----------------------------------------------------------------------------------
// 将 宽字节wchar_t* 转换 单字节char*
inline char* UnicodeToAnsi( const wchar_t* szStr )
{
int nLen = WideCharToMultiByte( CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL );
if (nLen == 0)
{
return NULL;
}
char* pResult = new char[nLen];
WideCharToMultiByte( CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL );
return pResult;
}


void MyGetListViewItem(HWND hwndLV)
//void GetListViewInfo(HWND h)
//VC2010测试通过
//自己修改为C#的吧
{

if(hwndLV==NULL)
{
return;
}

//目标进程ID与句柄
DWORD PID;
HANDLE hProcess;
int nBufferLength=50; //缓冲区大小

int nRowCount=0; //行数
nRowCount =(int)::SendMessage(hwndLV,LVM_GETITEMCOUNT,0,0); //获取ListView行数
if(nRowCount<=0)
return;

int nColCount=0; //列数
HWND hHeader = (HWND)::SendMessage(hwndLV,LVM_GETHEADER, 0,0);
nColCount =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0); //获取ListView列数
if(nColCount<=0)
return;

//远程虚拟空间地址
LVITEM *pVirtualItem;
wchar_t *pVirtualBuffer;

GetWindowThreadProcessId(hwndLV,&PID);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID); //获取目标进程句柄失败
if(!hProcess)
return;

//在目标进程地址空间分配内存
pVirtualItem =(LVITEM *)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM) , MEM_COMMIT, PAGE_READWRITE);
pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength*2, MEM_COMMIT, PAGE_READWRITE);
if ((!pVirtualItem)||(!pVirtualBuffer))
{
return;
}

for(int i=0;i<nRowCount;i++)
{
String^ strInfo = "";
for(int j=0;j<nColCount;j++)
{
wchar_t *buffer =new wchar_t[nBufferLength];
wmemset(buffer,0,nBufferLength);

LVITEM lvitem;
lvitem.cchTextMax=nBufferLength*2;
lvitem.iSubItem=j;
lvitem.pszText=pVirtualBuffer;
//核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本
WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL);
::SendMessage(hwndLV, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)pVirtualItem);
ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength*2,NULL);


//Char* UnicodeToAnsi()
char* ctemp=UnicodeToAnsi(buffer);
String^ stemp=""; //gcnew String(buffer);
stemp=System::Runtime::InteropServices::Marshal::PtrToStringUni((IntPtr)ctemp);

delete []buffer;
}
//MessageBox(strInfo); //---------输出一行
}

//释放目标进程里分配的内存
VirtualFreeEx(hProcess,pVirtualItem ,sizeof(LVITEM) ,MEM_RELEASE);
VirtualFreeEx(hProcess,pVirtualBuffer,nBufferLength*2,MEM_RELEASE);
CloseHandle(hProcess);
}


在这之前已经忙了三天,试过n中方法了,结束是要么导致进程崩溃,要么取不到数据,这段代码可以取到文字,但是是乱码,无论我怎么转换,始终都无法正确显示中文,网络上有很多类似的例子实际上是只能在VC6下运行的。本人初学者实在没办法了上来求助,这个版本的作者说在VC2010下通过,可我运行却是乱码。顺便说一下,我的程序不是MFC,我把Cstring替换成了System::String

此段代码来自: http://bbs.csdn.net/topics/350200042 作者 @ZengHD

另外,@jackyjkchen 特别在这个帖子 http://bbs.csdn.net/topics/340256535 里提到,二进制需要转成16进制再通过Cstring获取,如果是这个问题,哪位可以指点一下在STL(非MFC)下怎么实现这个转换呢?

谢谢!我分不多,可以全部给你。
...全文
941 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
无非就是写几个函数转换一下编码而已。上面几个函数都试试。实在不行自己改改。
  • 打赏
  • 举报
回复
void CCommonProcess:: StringCharToUnicode(CString &str) { char *szBuf = new char[str.GetLength() + 1];//注意“+1”,char字符要求结束符,而CString没有 memset(szBuf, '\0',str.GetLength()); int i; for ( i = 0 ; i < str.GetLength(); i++) { szBuf[i] = (char)str.GetAt(i); } szBuf[i] = '\0';//结束符。否则会在末尾产生乱码。 int nLen; WCHAR *ptch; CString strOut; if(szBuf == NULL) { return ; } nLen = MultiByteToWideChar(CP_ACP, 0, szBuf, -1, NULL, 0);//获得需要的宽字符字节数 ptch = new WCHAR[nLen]; memset(ptch, '\0', nLen); MultiByteToWideChar(CP_ACP, 0, szBuf, -1, ptch, nLen); str.Format(_T("%s"), ptch); if(NULL != ptch) delete [] ptch; ptch = NULL; if(NULL != szBuf) delete []szBuf; szBuf = NULL; return ; } //1. ANSI to Unicode wstring CCommonProcess:: ANSIToUnicode( const CString& str ) { int len = 0; len = str.GetLength(); int unicodeLen = ::MultiByteToWideChar( CP_ACP, 0, str , -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, str , -1, (LPWSTR)pUnicode, unicodeLen ); wstring rt; rt = ( wchar_t* )pUnicode; delete pUnicode; return rt; } //2. Unicode to ANSI string CCommonProcess:: UnicodeToANSI( const wstring& str ) { char* pElementText; int iTextLen; // wide char to multi char iTextLen = WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL ); pElementText = new char[iTextLen + 1]; memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) ); ::WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL ); string strText; strText = pElementText; delete[] pElementText; return strText; } //3. UTF-8 to Unicode wstring CCommonProcess:: UTF8ToUnicode( const string& str ) { int len = 0; len = str.length(); int unicodeLen = ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen ); wstring rt; rt = ( wchar_t* )pUnicode; delete pUnicode; return rt; } //4. Unicode to UTF-8 CString CCommonProcess:: UnicodeToUTF8( const wstring& str ) { char* pElementText; int iTextLen; // wide char to multi char iTextLen = WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL ); pElementText = new char[iTextLen + 1]; memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) ); ::WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL ); CString strText; strText = pElementText; delete[] pElementText; return strText; }
反弹让他 2013-07-22
  • 打赏
  • 举报
回复
看样子通过GB2312可以解决乱问题,哪位大侠给个参考?

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧