我想用vc++做聊天程序,怎么实现图片和文字混排,像qq里面的图片和文字可以混排。
RichtextBox可以实现,但是不知道怎么提取控件里面的数据。
或者有没有别的更好的方法实现。
分数不够可以在加
多谢赐教!

解决方案 »

  1.   

    楼主去这里看看:http://www.codeproject.com/KB/edit/csexrichtextbox.aspx
    看那个上面是怎么弄的
      

  2.   

    http://www.codeproject.com/KB/edit/richeg.aspx
      

  3.   

    topic.csdn.net/t/20030115/13/1360865.html 
      

  4.   

    Insert any HBITMAP (Bitmap) in your RichEdit Control 
    http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
      

  5.   

    DWORD InsertGif( CRichEditCtrl * edit , CString strPicPath , DWORD dwUserData)
    {
    LPLOCKBYTES  lpLockBytes = NULL; 
    IRichEditOle *ole = NULL;
    SCODE  sc;  
    HRESULT  hr;                      
    LPOLECLIENTSITE  m_lpClientSite;  
    ImageOleLib::IGifAnimatorPtr  m_lpAnimator;                 
    LPSTORAGE  m_lpStorage;  
    LPOLEOBJECT   m_lpObject;  
    REOBJECT  reobject;  
    sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);   if (sc != S_OK)  
    {
    AfxThrowOleException(sc); 
    }
    ASSERT(lpLockBytes != NULL);  
     
    sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,  
    STGM_SHARE_EXCLUSIVE  |STGM_CREATE  |STGM_READWRITE, 0, &m_lpStorage);  
    if (sc != S_OK)  
    {  
    VERIFY(lpLockBytes->Release() == 0);  
    lpLockBytes = NULL;  
    AfxThrowOleException(sc);  
    }  
    ASSERT(m_lpStorage != NULL);  
    ole = edit->GetIRichEditOle(); 
    if(ole == NULL) 

    return -1; 

     
    ole->GetClientSite(&m_lpClientSite);  
    ASSERT(m_lpClientSite != NULL);  
    try  
    {   
    hr = ::CoInitialize(NULL) ;  
    if( FAILED(hr))  
    _com_issue_error(hr);   hr = m_lpAnimator.CreateInstance(ImageOleLib::CLSID_GifAnimator);  if( FAILED(hr))  
    _com_issue_error(hr);   
    BSTR  path = strPicPath.AllocSysString();   hr = m_lpAnimator->LoadFromFile(path);  
    TRACE("\n BSTR path Success!\n");
    if( FAILED(hr))  
    _com_issue_error(hr);   TRACE0( m_lpAnimator->GetFilePath() );   hr = m_lpAnimator.QueryInterface(IID_IOleObject, (void**)&m_lpObject);  
    if( FAILED(hr))  
    _com_issue_error(hr);   OleSetContainedObject(m_lpObject, TRUE);   ZeroMemory(&reobject, sizeof(REOBJECT));   reobject.cbStruct = sizeof(REOBJECT);              
    CLSID  clsid;  
    sc = m_lpObject->GetUserClassID(&clsid);  
    if  (sc != S_OK)  
    AfxThrowOleException(sc);  
    reobject.clsid = clsid;  
    reobject.cp = REO_CP_SELECTION;  
    reobject.dvaspect = DVASPECT_CONTENT;  
    reobject.dwFlags = REO_BELOWBASELINE;  //REO_RESIZABLE    |  
    reobject.dwUser = dwUserData;//(DWORD)100; //(DWORD)m_lpAnimator;  //Save Animator
    reobject.poleobj = m_lpObject;   
    reobject.polesite = m_lpClientSite;  
    reobject.pstg = m_lpStorage;   SIZEL  sizel;  
    sizel.cx = sizel.cy = 0;  
    reobject.sizel = sizel;  
    HWND  hWndRT = edit->m_hWnd; ole->InsertObject(&reobject);  
    TRACE("\nEnd Insert Object!\n");
    ::SendMessage(hWndRT,  EM_SCROLLCARET,  (WPARAM)0,  (LPARAM)0);  
    VARIANT_BOOL  ret;  
     
    ret = m_lpAnimator->TriggerFrameChange();   
    m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, hWndRT, NULL);  
    m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, hWndRT, NULL);   edit->RedrawWindow();   if  (m_lpClientSite)  
    {  
    m_lpClientSite->Release();  
    m_lpClientSite = NULL;  
    }  
    if  (m_lpObject)  
    {  
    m_lpObject->Release();  
    m_lpObject = NULL;  
    }  
    if  (m_lpStorage)  
    {  
    m_lpStorage->Release();  
    m_lpStorage = NULL;  
    }   SysFreeString(path);  
    ole->Release(); 
    lpLockBytes->Release(); 
    TRACE("\nEnd Free Sring!\n"); 
    ::CoUninitialize();  }  
    catch(  _com_error  e  )  
    {  
    AfxMessageBox(e.ErrorMessage());  
    ::CoUninitialize();              

    return reobject.dwUser;
    }
    DWORD insertbmptorich(CRichEditCtrl* re, LPCTSTR szimage, DWORD dwUserData)   
      {   
              IRichEditOle   *richole;   
              SendMessage(re->m_hWnd,   EM_GETOLEINTERFACE,   0,   int(&richole));   
        
              ILockBytes   *flockbytes;   
              CreateILockBytesOnHGlobal(0,1,&flockbytes);   
        
              IStorage   *fstorage;   
              StgCreateDocfileOnILockBytes(flockbytes,STGM_SHARE_EXCLUSIVE |   
                              STGM_CREATE |   STGM_READWRITE ,0,&fstorage);   
        
              FORMATETC   formatetc;   
              formatetc.cfFormat=0;   
              formatetc.ptd=NULL;   
              formatetc.dwAspect=DVASPECT_CONTENT;   
              formatetc.lindex=-1;   
              formatetc.tymed=TYMED_NULL;   
        
        
              LPWSTR   wszimage   =   new   WCHAR[strlen(szimage)+1];   
      MultiByteToWideChar(CP_ACP,   0,   szimage,   -1,   wszimage,   strlen(szimage)+1);   
        
              IOleObject   *fole;   
              OleCreateFromFile(CLSID_NULL,   wszimage,   ::IID_IOleObject,   
                          0,   &formatetc,   NULL,   fstorage,   (void**)&fole);   
              delete[]   wszimage;   
              OleSetContainedObject(fole,   true);   
        
              REOBJECT   reobject;   
              ZeroMemory(&reobject,   sizeof(reobject));   
              reobject.cbStruct=sizeof(reobject);   
              CLSID   xt;   
              fole->GetUserClassID(&xt);   
              reobject.clsid=xt;   
              reobject.cp=REO_CP_SELECTION;   
              reobject.dvaspect=DVASPECT_CONTENT;   
              reobject.dwFlags=REO_RESIZABLE | REO_BELOWBASELINE;   
              reobject.dwUser= dwUserData;   
              reobject.poleobj=fole;   
        
              IOleClientSite     *fclientsite;   
              richole->GetClientSite(&fclientsite);   
              reobject.polesite=fclientsite;   
              reobject.pstg=fstorage;   
              reobject.sizel.cx=0;   
              reobject.sizel.cy=0;   
        
              richole->InsertObject(&reobject);   
      }
      

  6.   

    上面两个函数, 一个是向RichEdit控件插入GIF的(这个没完整,需要导入ImageOle.dll)
    一个是向RichEdit控件插入BMP位图的。DWORD InsertGif( CRichEditCtrl * edit , CString strPicPath , DWORD dwUserData) 
    DWORD insertbmptorich(CRichEditCtrl* re, LPCTSTR szimage, DWORD dwUserData) 形参dwUserData就是跟图片或GIF关联起来的数据,
    就是通过这个赋值语句来关联的,reobject.dwUser= dwUserData;当IRichEditOle* pRichEditOle = m_RichEdit.GetIRichEditOle();
    REOBJECT reobject;
    reobject.cbStruct = sizeof(REOBJECT); 
    reobject.cp = 5;  ///////////HRESULT hr = pRichEditOle->GetObject(REO_IOB_USE_CP, &reobject, REO_GETOBJ_POLEOBJ);if (SUCCEEDED(hr))
    {
       //成功说明第5个位置(reobject.cp指定)是一个RichEditOle对象,可能是图片,也可能是GIF
       //reobject.dwUser  这个值就是我们在插入GIF或图片时指定的值,通过这个值可以知道这个对象是什么东东
    }
    else
    {
       //失败说明这个位置的东东只是一个普通的文本
    }
      

  7.   

    DWORD InsertGif( CRichEditCtrl * edit , CString strPicPath , DWORD dwUserData) 
    DWORD insertbmptorich(CRichEditCtrl* re, LPCTSTR szimage, DWORD dwUserData) 调用这两个函数时,dwUserData的值由你来规划
      

  8.   

    楼主去这里看看:http://www.codeproject.com/KB/edit/csexrichtextbox.aspx 
    看那个上面是怎么弄的
      

  9.   

    谢谢各位,已经解决了。我没有使用richtextbox控件,使用的是richedit控件。参考网址:http://codeguru.earthweb.net/forum/showthread.php?t=326551