//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);
//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;
弄一個 frame 把這些BUTTON和RICHEDIT集成到一塊不就行了。
如果你想加入Delphi的按钮TButton控件(用于点击后执行某些操作),我觉得是不可能的,因为RichEdit不支持(起码我现在认为是这样的)
如果你只是想加入一个按钮似的图片,这是可以的,具体算法等下贴出来
定义类(此处定义的是一个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();
}