读取其它进程richedit控件的内容

和Edit控件不同的是,Richedit支持RTF格式,采用WM_GETWINDOWTEXT消息只能得到文本信息,因此如果需要获取完整的RTF文件,则需要处理EM_STREAMOUT消息,将控件中的内容写出。有些控件对EM_STREAMOUT进行了过滤,则需要进一步处理EM_STREAMIN来在读入时截获原始数据。

       处理的步骤如下:
1、 获取目标Richedit窗口句柄;
2、 Hook窗口对应的进程,并子类化该窗口;
3、 截获EM_STREAMIN、EM_STREAMOUT消息,将对应的内容写出。
具体的实现如下:
1、 在HookDll中实现子类化操作
LRESULT HookProc (
int code,       // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam   // keystroke-message information
)
{   
     if( pCW->message == WM_HOOKSPY ) {
         ::MessageBeep(MB_OK);      
         
         // subclass the g_hWnd
         if( g_wndProc == NULL )
              g_wndProc = (WNDPROC)::SetWindowLongPtrA( g_hWnd, GWLP_WNDPROC,(LONG_PTR)RichEdit_WndProc );
        
     }
     return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}
        
用于替换的窗口过程如下:
static LRESULT CALLBACK
RichEdit_WndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
     if( Msg == EM_STREAMIN ) // 拦截本消息,将内容写入到文本
     {
              IStream * lpStream = NULL;
              HRESULT hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
              if( SUCCEEDED( hr ) && lpStream != NULL )
              {
                           // 将内容写入到Stream,并发送到Hook进程
                           // Do Write to
                             SendMessage( g_hLocalREdit,WM_COPYDATA ,(WPARAM)hWnd,(LPARAM)&cds );
                               
             }
             
    
         return 0;
     }
     if( Msg == WM_HOOKSPY )
     {
        
         if( wParam != 0 )
         {
             
              ::SetWindowLongPtrA( hWnd, GWLP_WNDPROC,(LONG_PTR)g_wndProc );
              g_wndProc = 0;
         }
         return 0;
     }
     if( g_wndProc )
         return ::CallWindowProcA( g_wndProc, hWnd, Msg, wParam, lParam );
     else
         return 0;
}
2、 在Hook Dll 中导出Hook 函数
int HookRemoteWindow( HWND hRemoteWnd, HWND hLocalWnd, BOOL bHook )
{
g_hWnd = hRemoteWnd;
g_hLocalREdit = hLocalWnd;
if( bHook == TRUE )
{
       // Hook the thread, that "owns" our PWD control
       g_hHook = SetWindowsHookEx( WH_CALLWNDPROC,(HOOKPROC)HookProc,
                                        hDll, GetWindowThreadProcessId(g_hWnd,NULL) );
       if( g_hHook==NULL )
            return 0;
       if (WM_HOOKSPY == NULL)
            WM_HOOKSPY = ::RegisterWindowMessage( "WM_HOOKSPY_RK" );
      
       SendMessage( g_hWnd, WM_HOOKSPY,0,0 );
}
else
{
       if( g_hHook != NULL )
       {
            if( g_wndProc )
            {
               
                SendMessage( hRemoteWnd,WM_HOOKSPY,1,1 );
               
            }
           
           
            ::UnhookWindowsHookEx( g_hHook );
           
       }
           
}   
return TRUE;
}
3、 在对话框中接受Hook Dll发送的数据并显示
static DWORD CALLBACK
MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
   COPYDATASTRUCT* lpcds = (COPYDATASTRUCT*) dwCookie;
LONG realSize = min( lpcds->cbData, cb );
   memcpy( pbBuff,lpcds->lpData, realSize );
   *pcb = realSize;
   LPBYTE ptr = (LPBYTE)lpcds->lpData;
   ptr += realSize;
   lpcds->lpData = ptr;
   lpcds->cbData -= realSize;
   
   return 0;
}
BOOL CCrackDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
      
       // 读入到Richedit控件
       EDITSTREAM es;
       es.dwCookie = (DWORD)pCopyDataStruct;
       es.dwError = 0;
       es.pfnCallback = MyStreamInCallback;
       m_richEdit1.StreamIn( pCopyDataStruct->dwData, es );
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
4、 Demo 如下

 

读取其它进程richedit控件的内容_第1张图片

 

from:http://hi.baidu.com/li_guotao/blog/item/2850bc456e3b8f22cefca34f.html

你可能感兴趣的:(Stream,null,dll,callback,hook,rtf)