CRichTextCtrl(插入图片,右键菜单,字体,颜色设置及其它操作)

// RichTextCtrl.cpp : implementation file
//

#include "stdafx.h"
//#include "Exppp.h"
#include "RichTextCtrl.h"
#include <Richole.h>
#include <afxole.h>


//使用了QQ的图像处理控件
#import  "ImageOle.dll" named_guids

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CRichTextCtrl

CRichTextCtrl::CRichTextCtrl()
{
 
}

CRichTextCtrl::~CRichTextCtrl()
{
}


BEGIN_MESSAGE_MAP(CRichTextCtrl, CRichEditCtrl)
 //{{AFX_MSG_MAP(CRichTextCtrl)
 ON_WM_RBUTTONDOWN()
 ON_COMMAND(ID_RICH_COPY, OnCopy)
 ON_COMMAND(ID_RICH_CUT, OnCut)
 ON_COMMAND(ID_RICH_PASTE, OnPaste)
 ON_COMMAND(ID_RICH_SELECTALL, OnSelectall)
 ON_COMMAND(ID_RICH_UNDO, OnUndo)
 ON_COMMAND(ID_RICH_CLEAR, OnClear)
// ON_COMMAND(ID_RICH_SETFONT, OnSelectfont)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CRichTextCtrl message handlers

void CRichTextCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 
 //设置为焦点
 SetFocus();
 //创建一个弹出式菜单
 CMenu popmenu;
 popmenu.CreatePopupMenu();
 //添加菜单项目
 popmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo");
 popmenu.AppendMenu(0, MF_SEPARATOR);
 popmenu.AppendMenu(0, ID_RICH_CUT, "&Cut");
 popmenu.AppendMenu(0, ID_RICH_COPY, "C&opy");
 popmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste");
 popmenu.AppendMenu(0, ID_RICH_CLEAR, "C&lear");
 popmenu.AppendMenu(0, MF_SEPARATOR);
 popmenu.AppendMenu(0, ID_RICH_SELECTALL, "Select &All");

 //初始化菜单项
 UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
 popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND|nUndo);

 UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 : MF_GRAYED) ;
 popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND|nSel);
 popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND|nSel);
 popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND|nSel);
 
 UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
 popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND|nPaste);

 //显示菜单
 CPoint pt;
 GetCursorPos(&pt);
 popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
 popmenu.DestroyMenu();
 CRichEditCtrl::OnRButtonDown(nFlags, point);
}

void CRichTextCtrl::SetFont()
{
 CHARFORMAT cf;
 LOGFONT lf;
 memset(&cf, 0, sizeof(CHARFORMAT));
 memset(&lf, 0, sizeof(LOGFONT));
 //判断是否选择了内容
 BOOL m_bSelect = (GetSelectionType() != SEL_EMPTY) ? TRUE : FALSE;
 if (m_bSelect)
 {
  GetSelectionCharFormat(cf);
 }
 else
 {
  GetDefaultCharFormat(cf);
 }
 //得到相关字体属性
 BOOL bIsBold = cf.dwEffects & CFE_BOLD;
 BOOL bIsItalic = cf.dwEffects & CFE_ITALIC;
 BOOL bIsUnderline = cf.dwEffects & CFE_UNDERLINE;
 BOOL bIsStrickout = cf.dwEffects & CFE_STRIKEOUT;
 //设置属性
 lf.lfCharSet = cf.bCharSet;
 lf.lfHeight = cf.yHeight/15;
 lf.lfPitchAndFamily = cf.bPitchAndFamily;
 lf.lfItalic = bIsItalic;
 lf.lfWeight = (bIsBold ? FW_BOLD : FW_NORMAL);
 lf.lfUnderline = bIsUnderline;
 lf.lfStrikeOut = bIsStrickout;
 sprintf(lf.lfFaceName, cf.szFaceName);
 
 CFontDialog dlg(&lf);
 dlg.m_cf.rgbColors = cf.crTextColor;
 if (dlg.DoModal() == IDOK)
 {
  dlg.GetCharFormat(cf);//获得所选字体的属性
  if (m_bSelect)
   SetSelectionCharFormat(cf); //为选定的内容设定所选字体
  else
   SetWordCharFormat(cf); //为将要输入的内容设定字体
 }
}

void CRichTextCtrl::SetColor(COLORREF color)
{
 CHARFORMAT cf;
 cf.cbSize = sizeof(CHARFORMAT);
 cf.dwMask = CFM_COLOR;
 
 GetSelectionCharFormat(cf);
 cf.crTextColor = color;
 if( cf.dwEffects & CFE_AUTOCOLOR )
    { cf.dwEffects ^= CFE_AUTOCOLOR;
 }
 SetSelectionCharFormat(cf); 
}
void CRichTextCtrl::SetJustify(void)
{
 PARAFORMAT pf;   
 pf.cbSize     = sizeof(PARAFORMAT);
 pf.dwMask     = PFM_ALIGNMENT;   
 pf.wAlignment = PFA_JUSTIFY;
 
 SetParaFormat(pf); // Set the paragraph.
}

void CRichTextCtrl::SetWordWrap(const bool bOn, const int iLineWidth)
{
 if( bOn )
  SetTargetDevice(NULL, iLineWidth);
 
 else 
 {
  if( 0 == iLineWidth )
   SetTargetDevice(NULL, 1);
  else
   SetTargetDevice(NULL, iLineWidth);
 }
 
}

void CRichTextCtrl::InsertGraph(HBITMAP hBitmap)
{
 STGMEDIUM stgm;
 stgm.tymed = TYMED_GDI;    // Storage medium = HBITMAP handle
 stgm.hBitmap = hBitmap;
 stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
 
 FORMATETC fm;
 fm.cfFormat = CF_BITMAP;    // Clipboard format = CF_BITMAP
 fm.ptd = NULL;       // Target Device = Screen
 fm.dwAspect = DVASPECT_CONTENT;   // Level of detail = Full content
 fm.lindex = -1;       // Index = Not applicaple
 fm.tymed = TYMED_GDI; 
 
 //创建输入数据源
 IStorage *pStorage;
 
 //分配内存
 LPLOCKBYTES lpLockBytes = NULL;
 SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
 if (sc != S_OK)
  AfxThrowOleException(sc);
 ASSERT(lpLockBytes != NULL);
 
 sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
  STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
 if (sc != S_OK)
 {
  VERIFY(lpLockBytes->Release() == 0);
  lpLockBytes = NULL;
  AfxThrowOleException(sc);
 }
 ASSERT(pStorage != NULL);
 
 COleDataSource *pDataSource = new COleDataSource;
 pDataSource->CacheData(CF_BITMAP, &stgm);
 LPDATAOBJECT lpDataObject =
  (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
 
 //获取RichEdit的OLEClientSite
 LPOLECLIENTSITE lpClientSite;
 this->GetIRichEditOle()->GetClientSite( &lpClientSite );
 
 //创建OLE对象
 IOleObject *pOleObject;
 sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
  &fm,lpClientSite,pStorage,(void **)&pOleObject);
 if(sc!=S_OK)
  AfxThrowOleException(sc);
 
 //插入OLE对象
 REOBJECT reobject;
 ZeroMemory(&reobject, sizeof(REOBJECT));
 reobject.cbStruct = sizeof(REOBJECT);
 
 CLSID clsid;
 sc = pOleObject->GetUserClassID(&clsid);
 if (sc != S_OK)
  AfxThrowOleException(sc);
 
 reobject.clsid = clsid;
 reobject.cp = REO_CP_SELECTION;
 reobject.dvaspect = DVASPECT_CONTENT;
 reobject.poleobj = pOleObject;
 reobject.polesite = lpClientSite;
 reobject.pstg = pStorage;
 
 HRESULT hr = this->GetIRichEditOle()->InsertObject( &reobject );
 
 delete pDataSource;
}

void CRichTextCtrl::InsertGraph(CString strPicPath)
{
 LPLOCKBYTES  lpLockBytes  =  NULL; 
 SCODE  sc; 
 HRESULT  hr;                     
 //print  to  RichEdit'  s  IClientSite 
 LPOLECLIENTSITE  m_lpClientSite; 
 //A  smart  point  to  IAnimator 
 ImageOleLib::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 
 this->GetIRichEditOle()->GetClientSite(&m_lpClientSite); 
 ASSERT(m_lpClientSite  !=  NULL); 
 try 
 { 
  //Initlize  COM  interface 
  
  hr  =  ::CoInitialize(NULL)  ;//(  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(ImageOleLib::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  =  ( DWORD )m_lpAnimator;  //Save Animator
  //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;

  this->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,  hWndRT,  NULL); 
  m_lpObject->DoVerb(OLEIVERB_SHOW,  NULL,  m_lpClientSite,  0,  hWndRT,  NULL); 
  
  //redraw  the  window  to  show  animation 
  this->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();             
 }
}

 

/

#if !defined(AFX_RICHTEXTCTRL_H__23EF1C6E_820D_4C94_A980_4EC63A4650DA__INCLUDED_)
#define AFX_RICHTEXTCTRL_H__23EF1C6E_820D_4C94_A980_4EC63A4650DA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RichTextCtrl.h : header file
//
///定义消息ID/
#define ID_RICH_UNDO                    101
#define ID_RICH_CUT                     102
#define ID_RICH_COPY                    103
#define ID_RICH_PASTE                   104
#define ID_RICH_CLEAR                   105
#define ID_RICH_SELECTALL               106
#define ID_RICH_SETFONT                 107

/
// CRichTextCtrl window

class CRichTextCtrl : public CRichEditCtrl
{
// Construction
public:
 CRichTextCtrl();
// Attributes
public:

// Operations
public:

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CRichEditCtrl)
 //}}AFX_VIRTUAL

// Implementation
public:
 void InsertGraph( CString  strPicPath );
 void InsertGraph(HBITMAP hBitmap );
 void SetWordWrap(const bool bOn=true, const int iLineWidth=0);
 void SetColor(COLORREF color);
 void SetFont();
 void SetJustify(void);
 virtual ~CRichTextCtrl();

 // Generated message map functions
protected:
 //{{AFX_MSG(CRichTextCtrl)
 afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
 afx_msg void OnCopy() { Copy(); }
 afx_msg void OnCut() { Cut(); }
 afx_msg void OnPaste() { Paste(); }
 afx_msg void OnSelectall() { SetSel(0, -1); }
 afx_msg void OnUndo() { Undo(); }
 afx_msg void OnClear() { Clear(); }
 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_RICHTEXTCTRL_H__23EF1C6E_820D_4C94_A980_4EC63A4650DA__INCLUDED_)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值