📄 extrichedit.cpp
字号:
// 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 + -