我想在一个TRichEdit控件中加入其它控件,比如加入按钮,要如何实现,
好像控件可以创建,但是TRichEdit中的文字却无法显示出来
大哥大姐们帮帮忙哦

解决方案 »

  1.   


    弄一個 frame  把這些BUTTON和RICHEDIT集成到一塊不就行了。
      

  2.   

    不知道你的“按钮”具体指的是什么东西。
    如果你想加入Delphi的按钮TButton控件(用于点击后执行某些操作),我觉得是不可能的,因为RichEdit不支持(起码我现在认为是这样的)
    如果你只是想加入一个按钮似的图片,这是可以的,具体算法等下贴出来
      

  3.   

    如果你将TButton类做成一个OLE对象,然后再嵌入到Richedit中,我认为也是可以的
      

  4.   

    呵呵,没有Delphi代码,给个C++的自己转吧
    定义类(此处定义的是一个GIF图类)
    [
      uuid(0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16),
      helpstring("IGifAnimator Interface"),
      dual,
      nonextensible
    ]
    dispinterface IGifAnimator {
        properties:
        methods:
            [id(0x00000001), helpstring("method LoadFromFile")]
            void LoadFromFile([in] BSTR FileName);
            [id(0x00000002), helpstring("method TriggerFrameChange")]
            VARIANT_BOOL TriggerFrameChange();
            [id(0x00000003), helpstring("method GetFilePath")]
            BSTR GetFilePath();
            [id(0x00000004), helpstring("method ShowText")]
            void ShowText([in] BSTR Text);
    };
    //声明库文件
    #import "ImageOle.dll" named_guids
    //
    // Created by Microsoft (R) C/C++ Compiler Version 12.00.8168.0 (9de7951a).
    //
    // d:\myproject\msger\debug\ImageOle.tlh
    //
    // C++ source equivalent of Win32 type library
    // D:\\Program files\\tencent\\qq\\ImageOle.dll
    // compiler-generated file created 10/25/04 at 22:00:58 - DO NOT EDIT!
    #pragma once
    #pragma pack(push, 8)
    #include <comdef.h>namespace ImageOleLib {//
    // Forward references and typedefs
    //struct /* coclass */ GifAnimator;
    struct __declspec(uuid("0c1cf2df-05a3-4fef-8cd4-f5cfc4355a16"))
    /* dual interface */ IGifAnimator;//
    // Smart pointer typedef declarations
    //_COM_SMARTPTR_TYPEDEF(IGifAnimator, __uuidof(IGifAnimator));//
    // Type library items
    //struct __declspec(uuid("06ada938-0fb0-4bc0-b19b-0a38ab17f182"))
    GifAnimator;
        // [ default ] interface IGifAnimatorstruct __declspec(uuid("0c1cf2df-05a3-4fef-8cd4-f5cfc4355a16"))
    IGifAnimator : IDispatch
    {
        //
        // Wrapper methods for error-handling
        //    HRESULT LoadFromFile (
            _bstr_t FileName );
        VARIANT_BOOL TriggerFrameChange ( );
        _bstr_t GetFilePath ( );
        HRESULT ShowText (
            _bstr_t Text );    //
        // Raw methods provided by interface
        //    virtual HRESULT __stdcall raw_LoadFromFile (
            BSTR FileName ) = 0;
        virtual HRESULT __stdcall raw_TriggerFrameChange (
            VARIANT_BOOL * pbChanged ) = 0;
        virtual HRESULT __stdcall raw_GetFilePath (
            BSTR * pFilePath ) = 0;
        virtual HRESULT __stdcall raw_ShowText (
            BSTR Text ) = 0;
    };//
    // Named GUID constants initializations
    //extern "C" const GUID __declspec(selectany) LIBID_ImageOleLib =
        {0x710993a2,0x4f87,0x41d7,{0xb6,0xfe,0xf5,0xa2,0x03,0x68,0x46,0x5f}};
    extern "C" const GUID __declspec(selectany) CLSID_GifAnimator =
        {0x06ada938,0x0fb0,0x4bc0,{0xb1,0x9b,0x0a,0x38,0xab,0x17,0xf1,0x82}};
    extern "C" const GUID __declspec(selectany) IID_IGifAnimator =
        {0x0c1cf2df,0x05a3,0x4fef,{0x8c,0xd4,0xf5,0xcf,0xc4,0x35,0x5a,0x16}};//
    // Wrapper method implementations
    //
    #include "d:\myproject\msger\debug\ImageOle.tli"} // namespace ImageOleLib
    #pragma pack(pop)// Created by Microsoft (R) C/C++ Compiler Version 12.00.8168.0 (79a657ba).
    //
    // ImageOle.tli
    //
    // Wrapper implementations for Win32 type library
    // D:\\Program Files\\Tencent\\qq\\ImageOle.dll
    // compiler-generated file created 10/11/04 at 18:24:40 - DO NOT EDIT!#pragma once//
    // interface IGifAnimator wrapper method implementations
    //inline HRESULT IGifAnimator::LoadFromFile ( _bstr_t FileName ) {
        HRESULT _hr = raw_LoadFromFile(FileName);
        if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
        return _hr;
    }inline VARIANT_BOOL IGifAnimator::TriggerFrameChange ( ) {
        VARIANT_BOOL _result;
        HRESULT _hr = raw_TriggerFrameChange(&_result);
        if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
        return _result;
    }inline _bstr_t IGifAnimator::GetFilePath ( ) {
        BSTR _result;
        HRESULT _hr = raw_GetFilePath(&_result);
        if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
        return _bstr_t(_result, false);
    }inline HRESULT IGifAnimator::ShowText ( _bstr_t Text ) {
        HRESULT _hr = raw_ShowText(Text);
        if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
        return _hr;
    }使用方法 
     LPLOCKBYTES lpLockBytes = NULL;
        SCODE sc;
        HRESULT hr;
        //print to RichEdit' s IClientSite
        LPOLECLIENTSITE m_lpClientSite;
        //A smart point to IAnimator
        IGifAnimatorPtr    m_lpAnimator;
        //ptr 2 storage    
        LPSTORAGE m_lpStorage;
        //the object 2 b insert 2
        LPOLEOBJECT    m_lpObject;    //Create lockbytes
        sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
        if (sc != S_OK)
            AfxThrowOleException(sc);
        ASSERT(lpLockBytes != NULL);
        
        //use lockbytes to create storage
        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);
        
        //get the ClientSite of the very RichEditCtrl
        GetIRichEditOle()->GetClientSite(&m_lpClientSite);
        ASSERT(m_lpClientSite != NULL);    try
        {
            //Initlize COM interface
            hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
            if( FAILED(hr) )
                _com_issue_error(hr);
            
            //Get GifAnimator object
            //here, I used a smart point, so I do not need to free it
            hr = m_lpAnimator.CreateInstance(CLSID_GifAnimator);    
            if( FAILED(hr) )
                    _com_issue_error(hr);
            //COM operation need BSTR, so get a BSTR
            BSTR path = strPicPath.AllocSysString();        //Load the gif
            hr = m_lpAnimator->LoadFromFile(path);
            if( FAILED(hr) )
                _com_issue_error(hr);
                
            TRACE0( m_lpAnimator->GetFilePath() );
            
            //get the IOleObject
            hr = m_lpAnimator.QueryInterface(IID_IOleObject, (void**)&m_lpObject);
            if( FAILED(hr) )
                _com_issue_error(hr);
            
            //Set it 2 b inserted
            OleSetContainedObject(m_lpObject, TRUE);
            
            //2 insert in 2 richedit, you need a struct of REOBJECT
            REOBJECT reobject;
            ZeroMemory(&reobject, sizeof(REOBJECT));        reobject.cbStruct = sizeof(REOBJECT);    
            CLSID clsid;
            sc = m_lpObject->GetUserClassID(&clsid);
            if (sc != S_OK)
                AfxThrowOleException(sc);
            //set clsid
            reobject.clsid = clsid;
            //can be selected
            reobject.cp = REO_CP_SELECTION;
            //content, but not static
            reobject.dvaspect = DVASPECT_CONTENT;
            //goes in the same line of text line
            reobject.dwFlags = REO_BELOWBASELINE; //REO_RESIZABLE |
            reobject.dwUser = 0;
            //the very object
            reobject.poleobj = m_lpObject;
            //client site contain the object
            reobject.polesite = m_lpClientSite;
            //the storage 
            reobject.pstg = m_lpStorage;
            
            SIZEL sizel;
            sizel.cx = sizel.cy = 0;
            reobject.sizel = sizel;
            HWND hWndRT = this->m_hWnd;
            
            //Sel all text
    //        ::SendMessage(hWndRT, EM_SETSEL, 0, -1);
    //        DWORD dwStart, dwEnd;
    //        ::SendMessage(hWndRT, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
    //        ::SendMessage(hWndRT, EM_SETSEL, dwEnd+1, dwEnd+1);        //Insert after the line of text
            GetIRichEditOle()->InsertObject(&reobject);
            ::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
            VARIANT_BOOL ret;
            //do frame changing
            ret = m_lpAnimator->TriggerFrameChange();
            //show it
            m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, 
                                                                 m_hWnd, NULL);
            m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, m_hWnd, 
                                                                           NULL);
            
            //redraw the window to show animation
            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);
        }
        catch( _com_error e )
        {
            AfxMessageBox(e.ErrorMessage());
            ::CoUninitialize();    
        }