• 基于Duilib控件库实现的仿qq表情选择框(整理)


          闲下来,研究下Duilib富文本框的显示图片的功能,通过参考共享demo里的OLE gif,制作相当炫的qq表情选择框,效果如下:

                                         


          但此demo使用的UIRichEdit进行了一些处理,而256版本的Duilib并没有做这个修改,现在将最近用到的富文本显示图片的功能整理一下,除对UIRichEdit添加CRichEditOleCallback类外,还需要用到一个GifSmiley动态库。

          现将实现方式整理如下:

    a、改一下Duilib256版本下UIRichEdit.cpp,UIRichEdit.h两个文件,具体如何改,可以下载这两个文件比对一下;

    b、下载GifSmiley.dll,这里有源码可以编译一个出来;

    c、调用的cpp里加入:

    View Code
      1 void CTABComments::InsertGif(CRichEditUI* pRichEdit)
      2 { 
      3     _bstr_t bstrFileName1="c:\\Pic\\0.png"; 
      4     InsertAniSmiley(pRichEdit,(long)m_pPaintManager->GetPaintWindow(), bstrFileName1, ::GetSysColor(COLOR_WINDOW), 0);
      5     _bstr_t bstrFileName2="c:\\Pic\\1.gif"; 
      6     InsertAniSmiley(pRichEdit,(long)m_pPaintManager->GetPaintWindow(), bstrFileName2, ::GetSysColor(COLOR_WINDOW), 0);
      7     _bstr_t bstrFileName3="c:\\Pic\\2.gif"; 
      8     InsertAniSmiley(pRichEdit,(long)m_pPaintManager->GetPaintWindow(), bstrFileName3, ::GetSysColor(COLOR_WINDOW), 0);
      9     _bstr_t bstrFileName4="c:\\Pic\\3.gif"; 
     10     InsertAniSmiley(pRichEdit,(long)m_pPaintManager->GetPaintWindow(), bstrFileName4, ::GetSysColor(COLOR_WINDOW), 0);
     11 }
     12 
     13 bool CTABComments::InsertAniSmiley(CRichEditUI* pRichEdit, long hwndHostWindow, BSTR bstrFileName, OLE_COLOR clr, INT cy)
     14 {  
     15     GifSmiley::IGifSmileyCtrl* lpAnimator;
     16     ::CoCreateInstance(GifSmiley::CLSID_CGifSmileyCtrl,NULL,CLSCTX_INPROC,GifSmiley::IID_IGifSmileyCtrl,(LPVOID*)&lpAnimator); 
     17 
     18     if (lpAnimator==NULL)
     19     {
     20         return false;
     21     }
     22 
     23     COLORREF backColor = (COLORREF)(clr);
     24     HWND hwnd = (HWND)(hwndHostWindow);
     25     HRESULT hr;
     26  
     27 
     28     IRichEditOle *pRichEditOle = pRichEdit->GetRichEditOle();
     29     if (NULL==pRichEditOle)
     30     {
     31         return false;
     32     } 
     33 
     34     LPSTORAGE lpStorage=NULL;
     35     LPOLEOBJECT    lpObject=NULL;
     36     LPLOCKBYTES lpLockBytes = NULL;
     37     LPOLECLIENTSITE lpClientSite = NULL;   
     38     BSTR path = NULL;
     39 
     40     //Create lockbytes
     41     hr = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
     42     if (FAILED(hr))
     43     {
     44         return     false;
     45     }
     46     //use lockbytes to create storage
     47     SCODE sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage);
     48     if (sc != S_OK)
     49     {
     50         lpLockBytes->Release();
     51         return false;
     52     }
     53     // retrieve OLE interface for richedit   and  Get site
     54     pRichEditOle->GetClientSite(&lpClientSite);
     55     
     56     try
     57     { 
     58         //COM operation need BSTR, so get a BSTR
     59         path = bstrFileName;
     60 
     61         //Load the gif
     62         lpAnimator->LoadFromFileSized(path, cy);
     63 
     64         //Set back color
     65         OLE_COLOR oleBackColor=(OLE_COLOR)backColor;
     66         lpAnimator->put_BackColor(oleBackColor); 
     67 
     68 
     69         //get the IOleObject
     70         hr = lpAnimator->QueryInterface(IID_IOleObject, (void**)&lpObject);
     71         if (FAILED(hr))
     72         {
     73             return     false;
     74         }
     75 
     76         //Set it to be inserted
     77         OleSetContainedObject(lpObject, TRUE);
     78 
     79         //to insert into richedit, you need a struct of REOBJECT
     80         REOBJECT reobject;
     81         ZeroMemory(&reobject, sizeof(REOBJECT));
     82 
     83         reobject.cbStruct = sizeof(REOBJECT);    
     84 
     85         CLSID clsid;
     86         hr =  lpObject->GetUserClassID(&clsid);
     87 
     88 
     89         //set clsid
     90         reobject.clsid = clsid;
     91         //can be selected
     92         reobject.cp = REO_CP_SELECTION;
     93         //content, but not static
     94         reobject.dvaspect = DVASPECT_CONTENT;
     95         //goes in the same line of text line
     96         reobject.dwFlags = REO_BELOWBASELINE;
     97         //reobject.dwUser = (DWORD)myObject;
     98         
     99         //the very object
    100         reobject.poleobj = lpObject;
    101         //client site contain the object
    102         reobject.polesite = lpClientSite;
    103         //the storage 
    104         reobject.pstg = lpStorage;
    105 
    106         SIZEL sizel={0};
    107         reobject.sizel = sizel;
    108 
    109 
    110         LPOLECLIENTSITE lpObjectClientSite = NULL;   
    111         hr =lpObject->GetClientSite(&lpObjectClientSite);
    112         if(FAILED(hr) || lpObjectClientSite==NULL)
    113           lpObject->SetClientSite(lpClientSite); 
    114 
    115         pRichEditOle->InsertObject(&reobject); 
    116         //redraw the window to show animation
    117         ::RedrawWindow(hwnd,NULL, NULL, RDW_INVALIDATE);
    118 
    119         if (lpClientSite)
    120         {
    121             lpClientSite->Release();
    122             lpClientSite = NULL;
    123         }
    124         if (lpObject)
    125         {
    126             lpObject->Release();
    127             lpObject = NULL;
    128         }
    129         if (lpStorage)
    130         {
    131             lpStorage->Release();
    132             lpStorage = NULL;
    133         }
    134 
    135         if(lpAnimator)
    136         {
    137              lpAnimator->Release();    
    138              lpAnimator=NULL;
    139         }
    140   
    141     }
    142     catch( ... )
    143     {
    144         if (lpClientSite)
    145         {
    146             lpClientSite->Release();
    147             lpClientSite = NULL;
    148         }
    149         if (lpObject)
    150         {
    151             lpObject->Release();
    152             lpObject = NULL;
    153         }
    154         if (lpStorage)
    155         {
    156             lpStorage->Release();
    157             lpStorage = NULL;
    158         }
    159  
    160         if(lpAnimator)
    161         {
    162             lpAnimator->Release();    
    163             lpAnimator=NULL;
    164         }
    165 
    166         return false;
    167     }
    168     return true;
    169 }

    运行一下自己实现的效果:

    可以看的出不仅支持gif,还支持png的。

     

    下载地址:UIRichEdit.rar

     

     

  • 相关阅读:
    spring配置详解
    表单重复提交解决办法
    Java 两个变量交换值
    spring @ExceptionHandler注解方式实现异常统一处理
    mybatis实战
    使用soapui调用webservice接口
    使用火狐的restclient发送http接口post及get请求
    很多网站301重定向
    邮件发布google blogger 博客
    php file取重复
  • 原文地址:https://www.cnblogs.com/sunsmile/p/ningmengxiu3.html
Copyright © 2020-2023  润新知