⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extrichedit.cpp

📁 类似QQ,MSN表情的richedit,用来测试表情控件的
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ExtRichEdit.cpp : implementation file
//

#include "stdafx.h"
#include "CFaceEditDemo.h"
#include "ExtRichEdit.h"
#include "richole.h"
#include <vector>
#include <algorithm>
using namespace  std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define EDIT_CAT      1000
#define EDIT_COPY     1001
#define EDIT_PASTE    1002
#define EDIT_DELET    1003
/////////////////////////////////////////////////////////////////////////////
// CExtRichEdit
extern "C" VOID WINAPI recursive_create_dir(LPCTSTR dir)
{
	CString str(dir);
	CString path;
	int idx = 0;

	while(1)
	{
		idx = str.Find('\\');
		if( idx == -1 )
			break;

		path += str.Left(idx);
		if( path.Right(1) != _T(":") )	// like C:
		{
			CreateDirectory(path, NULL);
		}
		path += _T("\\");
		str.Delete(0, idx+1);
	}
}

#if 0
void UnmanagedInsertGif(int hwndRichEdit,wchar_t * pFilePath)
{
	HWND h=(HWND)hwndRichEdit;

	LPRICHEDITOLE	lpRichEditOle=NULL;
	LPOLEOBJECT		lpObject=NULL;
	LPSTORAGE       lpStorage=NULL;
	LPOLECLIENTSITE	lpClientSite=NULL;
	LPLOCKBYTES		lpLockBytes = NULL;

	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);	

	HRESULT hr=S_OK;
	CLSID clsid=CLSID_NULL;
	do{
		::SendMessage(h, EM_GETOLEINTERFACE, 0, (LPARAM)&lpRichEditOle);
		if(lpRichEditOle==NULL)break;
		hr= ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
		if (hr != S_OK||lpLockBytes==NULL)	break;
		hr= ::StgCreateDocfileOnILockBytes(lpLockBytes,
			STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage);
		if (hr!= S_OK||lpStorage==NULL)	break;
		hr=lpRichEditOle->GetClientSite(&lpClientSite);
		if (hr!= S_OK||lpClientSite==NULL)	break;
		try
		{
			ImageOleLib::IGifAnimatorPtr	lpAnimator;
			hr = lpAnimator.CreateInstance(ImageOleLib::CLSID_GifAnimator);	
			if( FAILED(hr) )	_com_issue_error(hr);
			_bstr_t bstrPath(pFilePath);
			hr = lpAnimator->LoadFromFile(bstrPath);
			if( FAILED(hr) )	_com_issue_error(hr);
			hr = lpAnimator.QueryInterface(IID_IOleObject, (void**)&lpObject);
			if( FAILED(hr)||lpObject==NULL)	_com_issue_error(hr);
			hr=OleSetContainedObject(lpObject, TRUE);
			if( FAILED(hr) )	_com_issue_error(hr);
			hr=lpObject->GetUserClassID(&clsid);
			if( FAILED(hr) )	_com_issue_error(hr);
			reobject.clsid = clsid;
			reobject.cp = REO_CP_SELECTION;
			reobject.dvaspect = DVASPECT_CONTENT;
			reobject.dwFlags = REO_BELOWBASELINE;
			reobject.dwUser = 0;
			reobject.poleobj = lpObject;
			reobject.polesite = lpClientSite;
			reobject.pstg = lpStorage;
			SIZEL sizel={0,0};
			reobject.sizel = sizel;
			hr=lpRichEditOle->InsertObject(&reobject);
		}
		catch( _com_error e )
		{
			LPCTSTR lpszErrMessage=e.ErrorMessage();
		}

	}while(FALSE);
	if(lpLockBytes)
		lpObject->Release();	
	if(lpLockBytes)
		lpLockBytes->Release();
	if(lpClientSite)
		lpClientSite->Release();
	if(lpRichEditOle)
		lpRichEditOle->Release();
}
void UnmanagedGifTriggerFrameChange(int hwndRichEdit)
{
	HWND h=(HWND)hwndRichEdit;

	LPRICHEDITOLE	lpRichEditOle=NULL;
	LPOLECLIENTSITE	lpClientSite=NULL;
	LPOLECONTAINER	lpContainer=NULL;
	LPENUMUNKNOWN	lpEnumUnknown=NULL;
	HRESULT hr=S_OK;	
	do{
		::SendMessage(h, EM_GETOLEINTERFACE, 0, (LPARAM)&lpRichEditOle);
		if(lpRichEditOle==NULL)break;
		hr=lpRichEditOle->GetClientSite(&lpClientSite);
		if (hr!= S_OK||lpClientSite==NULL)	break;
		hr=lpClientSite->GetContainer(&lpContainer);
		if (hr!= S_OK||lpClientSite==NULL)	break;
		hr=lpContainer->EnumObjects(OLECONTF_EMBEDDINGS,&lpEnumUnknown);
		if (hr!= S_OK||lpEnumUnknown==NULL)	break;		

		IUnknown* pUnk=NULL;
		ULONG uFetched=0;
		for (UINT i = 0; S_OK == lpEnumUnknown->Next(1, &pUnk, &uFetched); i++)
		{
			ImageOleLib::IGifAnimator*	pAnimator=NULL;
			do{
				hr=pUnk->QueryInterface(__uuidof(ImageOleLib::IGifAnimator),(LPVOID*)&pAnimator);
				if (hr!= S_OK)	break;
				try{
					ImageOleLib::IGifAnimatorPtr	lpAnimator;
					lpAnimator.Attach(pAnimator,true);
					lpAnimator->TriggerFrameChange();
				}
				catch( _com_error e )
				{
					LPCTSTR lpszErrMessage=e.ErrorMessage();
				}
			}
			while(FALSE);
			pUnk->Release();
			if(pAnimator)
				pAnimator->Release();
		}
	}while(FALSE);
	if(lpEnumUnknown)
		lpEnumUnknown->Release();
	if(lpContainer)
		lpContainer->Release();
	if(lpRichEditOle)
		lpRichEditOle->Release();
	if(lpClientSite)
		lpClientSite->Release();
}
#endif

_AFX_RICHEDITEX_STATE::_AFX_RICHEDITEX_STATE()
{
    m_hInstRichEdit20 = NULL ;
}



_AFX_RICHEDITEX_STATE::~_AFX_RICHEDITEX_STATE()
{
    if( m_hInstRichEdit20 != NULL )
    {
        ::FreeLibrary( m_hInstRichEdit20 ) ;
    }
}



_AFX_RICHEDITEX_STATE _afxRichEditStateEx ;



BOOL PASCAL AfxInitRichEditEx()
{
    if( ! ::AfxInitRichEdit() )
    {
        return FALSE ;
    }
    _AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx ;
    if( l_pState->m_hInstRichEdit20 == NULL )
    {
        l_pState->m_hInstRichEdit20 = LoadLibraryA("RICHED20.DLL") ;
    }
    return l_pState->m_hInstRichEdit20 != NULL ;
}
 
//泛型算法sort()的排序条件函数,实现按stFace.nPos域排序
bool less_than(FacePosition &face1, FacePosition &face2)
{
	return face1.nPos < face2.nPos ? true : false;
}
CExtRichEdit::CExtRichEdit()
{
	m_facecount = 0;
	m_bmpcount = 0;
	InitFaceStr();
}

CExtRichEdit::~CExtRichEdit()
{
}

BOOL CExtRichEdit::Create(DWORD in_dwStyle,  const RECT& in_rcRect,
                             CWnd* in_pParentWnd, UINT in_nID)
{
    if( ! ::AfxInitRichEditEx() )
    {
        return FALSE ;
    }
    CWnd* l_pWnd = this ;
    return l_pWnd->Create( _T( "RichEdit20A" ), NULL, in_dwStyle, 
                           in_rcRect, in_pParentWnd, in_nID );
}


BOOL CExtRichEdit::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
		LPCTSTR lpszWindowName, DWORD dwStyle,
		const RECT& rect, CWnd* pParentWnd, UINT nID,
		LPVOID lpParam /* = NULL */)
{
/*	return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
		rect,(pParentWnd != NULL) ? pParentWnd->GetSafeHwnd() : NULL,
		(HMENU) nID, lpParam);
*/
	if( ! ::AfxInitRichEditEx() )
    {
        return FALSE ;
    }

	CWnd* l_pWnd = this ;
    return l_pWnd->CreateEx(dwExStyle, _T( "RichEdit20A" ), NULL, dwStyle, 
                           rect, pParentWnd, nID, NULL );
}

BEGIN_MESSAGE_MAP(CExtRichEdit, CRichEditCtrl)
	//{{AFX_MSG_MAP(CExtRichEdit)
	ON_WM_ERASEBKGND()
	ON_CONTROL_REFLECT(EN_HSCROLL, OnHscroll)
	ON_WM_CHAR()
	ON_WM_RBUTTONUP()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CExtRichEdit message handlers



void CExtRichEdit::InitSettings()
{	
	////////////////////////////////////////////////////////////

	////////////////////////////////////////////////////////////
	unsigned mask = ::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0);
    ::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, mask | ENM_LINK  | ENM_MOUSEEVENTS | ENM_SCROLLEVENTS | ENM_KEYEVENTS);
    ::SendMessage(m_hWnd, EM_AUTOURLDETECT, true, 0);
	
	CHARFORMAT cf;
	cf.cbSize = sizeof (CHARFORMAT);  
	cf.dwMask = CFM_FACE | CFM_SIZE |CFM_BOLD;
	cf.dwEffects = ~CFE_BOLD;
	cf.yHeight = 180;
	sprintf(cf.szFaceName, "宋体"); 
	SetDefaultCharFormat(cf);
}

BOOL CExtRichEdit::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class
	return CRichEditCtrl::PreCreateWindow(cs);
}

BOOL CExtRichEdit::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	
	return CRichEditCtrl::OnEraseBkgnd(pDC);
	
}

void CExtRichEdit::OnHscroll() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CRichEditCtrl::OnInitDialog()
	// function to send the EM_SETEVENTMASK message to the control
	// with the ENM_SCROLL flag ORed into the lParam mask.
	
	// TODO: Add your control notification handler code here
	
	
}

void CExtRichEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags);
	
}


//右键弹出菜单
void CExtRichEdit::OnRButtonUp(UINT nFlags, CPoint point) 
{
	unsigned long    index ;
	int menu_index = 0;
	//-----------------------------------创建菜单---------------------------------------//
	popup_menu   m_popmenu ;
	CString      str ;
	str = _T("-> 剪切(X) <-") ;
	m_popmenu.add_item(str, EDIT_CAT);
	menu_index ++;
	str = _T("-> 复制(C)<-");
	m_popmenu.add_item(str, EDIT_COPY);
	menu_index ++;
	str = _T("-> 粘贴(V)<-");
	m_popmenu.add_item(str, EDIT_PASTE);
	menu_index ++;
	str = _T("-> 删除(D)<-");
	m_popmenu.add_item(str, EDIT_DELET);
	menu_index ++;	index = m_popmenu.popup(this) ;	
	if (index == EDIT_CAT)  //断开时实图象
	{   
		cut_data();
	}
	else
	{

		if(index == EDIT_COPY)
		{

			copy_data();
			CRichEditCtrl::OnRButtonUp(nFlags, point);

		}
		else
			if(index == EDIT_PASTE)
			{
				paste_data();
				CRichEditCtrl::OnRButtonUp(nFlags, point);

			}
			else
				if(index = EDIT_DELET)
				{

					delet_data();
					CRichEditCtrl::OnRButtonUp(nFlags, point);

				}
	}
	CRichEditCtrl::OnRButtonUp(nFlags, point);
}


void CExtRichEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	/*int i ;
	switch(nChar)
	{		
	case 'C' :   //退出全屏显示
		if(GetKeyState(VK_CONTROL) < 0)   
			copy_data();
		break;
	case 'X':   //全屏显示

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -