读取其他进程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 如下
 
 


版权声明:本文为kql01原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。