본문으로 바로가기

Rich Edit 사용법 메모

category 개발언어/c++ 2016. 6. 13. 10:12

Rich Edit

VS의 Resource view 에서 컨틀롤만 등록하는것으로 동작 하는 것이 아니기 때문에

사용방법을 메모 해둔다.

사용방법이 어렵다기 보다, 종종 한줄 누락 시켜고서 왜 동작 안되는지 혼란스러워 할때가 있다.

 

리치에디트를 사용하기 위해서 맨처음에 해줘야 할게 있다

리치에디터에서 사용하는 구조체

출력

   

리치에디트다 저런식으로 VS의 Resource view 에서 직접 그려서 사용할수도 있다.

그런데 이렇게 해줘도 class wizad의  member valiables 에는 안보인다 그래서

이것이 쓰이는 **.h 파일과 ***.cpp 에 직접 넣어주었다.

   

   

헤더 파일(아래)에는 원래 그냥 생기는건대.. 그걸 할수 없어서 그냥 직접 써줌

   

 enum { IDD = IDD_RICHEDIT_DIALOG };
 CEdit m_EditView4;
 CEdit m_EditView3;
 CEdit m_EditView2;
 CEdit m_EditView;
 int  m_FontColor;
 int  m_FontFont;
 CRichEditCtrl m_RichEdit;

   

cpp 파일 여기도 직접 해줬다.

   

CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CRichEditDlg)
 DDX_Control(pDX, IDC_EDIT_VIEW4, m_EditView4);
 DDX_Control(pDX, IDC_EDIT_VIEW3, m_EditView3);
 DDX_Control(pDX, IDC_EDIT_VIEW2, m_EditView2);
 DDX_Control(pDX, IDC_EDIT_VIEW, m_EditView);
 DDX_Radio(pDX, IDC_RADIO_COLOR_RED, m_FontColor);
 DDX_Radio(pDX, IDC_RADIO_FONT1, m_FontFont);
 DDX_Control(pDX, IDC_RICHEDIT3, m_RichEdit);
 //}}AFX_DATA_MAP

   

리치에디트를 사용하기 위해서 맨처음에 해줘야 할게 있다.

   

BOOL CRichEditApp::InitInstance()
{
 AfxEnableControlContainer();
 AfxInitRichEdit();   //이선언이 필요하다

   

   

**.cpp 파일에서 아래같은 내용이 필요하다.

HINSTANCE m_hinstRichEdit2 = NULL;  //<-- 이거 전역스럽게 한거다.

 m_hinstRichEdit2 = LoadLibraryA("RICHED20.DLL");

   

   

위와 같이 해놓으면 이제 사용할수 있다.

m_RichEdit 이것을 제어하면서 리치에디트를 활요한다.

   

간단한 예이다.

   

// RichEditDlg.cpp : implementation file
//

#include "stdafx.h"
#include "RichEdit.h"
#include "RichEditDlg.h"

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

#define BLACK RGB(0x00,0x00,0x00)
#define YELLOW RGB(0xff,0xff,0x00)
#define RED  RGB(0xff,0x00,0x00)
#define GREEN RGB(0x00,0xff,0x00)
#define BLUE RGB(0x00,0x00,0xff)
#define WHITE RGB(0xff,0xff,0xff)

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
HINSTANCE m_hinstRichEdit2 = NULL;
class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRichEditDlg dialog

리치에디터에서 사용하는 구조체


CHARFORMAT2 CharForm;   // 리치에디터에서 사용하는 구조체

void ChangeCharFormat(COLORREF rgbFont, COLORREF rgbBack, CString FontName, int nHeight)
{
 ASSERT( nHeight>0 );

 CharForm.cbSize = sizeof(CharForm);
 //CharForm.dwMask = CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT | CFM_UNDERLINE | CFM_FACE | CFM_SIZE | CFM_CHARSET | CFM_PROTECTED | CFM_COLOR
 // |CFM_BACKCOLOR;
 CharForm.dwMask = CFM_EFFECTS | CFM_COLOR | CFM_SIZE | CFM_FACE | CFM_BACKCOLOR | CFM_CHARSET;
 
 CharForm.dwEffects = CFE_BOLD;
 CharForm.yHeight = nHeight;
 CharForm.crTextColor = rgbFont; // 글자색 설정
 CharForm.crBackColor = rgbBack; // 바탕색 설정 
 //CharForm.bCharSet = JOHAB_CHARSET; //HANGUL_CHARSET;
    strcpy(CharForm.szFaceName, FontName);
}

CRichEditDlg::CRichEditDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CRichEditDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CRichEditDlg)
 m_FontColor = -1;
 m_FontFont = -1;
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CRichEditDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CRichEditDlg)
 DDX_Control(pDX, IDC_EDIT_VIEW4, m_EditView4);
 DDX_Control(pDX, IDC_EDIT_VIEW3, m_EditView3);
 DDX_Control(pDX, IDC_EDIT_VIEW2, m_EditView2);
 DDX_Control(pDX, IDC_EDIT_VIEW, m_EditView);
 DDX_Radio(pDX, IDC_RADIO_COLOR_RED, m_FontColor);
 DDX_Radio(pDX, IDC_RADIO_FONT1, m_FontFont);
 DDX_Control(pDX, IDC_RICHEDIT3, m_RichEdit);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CRichEditDlg, CDialog)
 //{{AFX_MSG_MAP(CRichEditDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_RADIO_COLOR_AMBER, OnRadioColorAmber)
 ON_BN_CLICKED(IDC_RADIO_COLOR_RED, OnRadioColorRed)
 ON_BN_CLICKED(IDC_RADIO_COLOR_GREEN, OnRadioColorGreen)
 ON_BN_CLICKED(IDC_RADIO_FONT1, OnRadioFont1)
 ON_BN_CLICKED(IDC_RADIO_FONT2, OnRadioFont2)
 ON_BN_CLICKED(IDC_RADIO_FONT3, OnRadioFont3)
 ON_BN_CLICKED(IDC_BUTTON1, OnButtonCodeView)
 ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
 ON_BN_CLICKED(IDC_BUTTON_GET_RTF, OnButtonGetRtf)
 ON_BN_CLICKED(IDC_BUTTON_SET_RTF, OnButtonSetRtf)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRichEditDlg message handlers

BOOL CRichEditDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog.  The framework does this automatically
 //  when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 // TODO: Add extra initialization here
 m_hinstRichEdit2 = LoadLibraryA("RICHED20.DLL");
 InitRichEdit();
 sprintf(FileName,"%s","myfile.rtf");
 return TRUE;  // return TRUE  unless you set the focus to a control
}
void CRichEditDlg::InitRichEdit()
{
 // 리치에디터 디폴트 셋팅

 m_FontColor = 2;
 m_FontFont = 0;

 UpdateData(FALSE);


 ChangeCharFormat( YELLOW, WHITE, _T("굴림"), 300 );
 ChangeCharacterFormat();
 


// ::SendMessage(m_RichEdit.GetSafeHwnd(), EM_SETLANGOPTIONS, 0, 0);
 
 
 // 아래 명령은 필요없을듯
 // SetFocus의 Event를 받아 처리하지도 않음
// m_RichEdit.SetEventMask( m_RichEdit.GetEventMask() | EN_SETFOCUS ); 
}

DWORD CRichEditDlg::GetSelectionCharFormat(CRichEditCtrl &rec, CHARFORMAT2& cf)
{
 cf.dwMask = CFM_ALL2;
    cf.cbSize = sizeof( cf );
    return rec.SendMessage(
        EM_GETCHARFORMAT,
        SCF_SELECTION,
        ( LPARAM ) &cf );
}

DWORD CRichEditDlg::SetSelectionCharFormat(CRichEditCtrl &rec, CHARFORMAT2& cf)
{
    cf.cbSize = sizeof( cf );
    return rec.SendMessage(
        EM_SETCHARFORMAT,
   //     SCF_SELECTION,
   SCF_ALL,
        ( LPARAM ) &cf );
}

void CRichEditDlg::ChangeCharacterFormat()
{
 // m_FontColor와 m_FontFont에 따라 SetSelectionCharFormat을 호출한다
 // font Color
 // 0 : Red, Blue
 // 1 : Green, Yellow
 // 2 : Yellow, Black (Default)
 // FontFont
 // 0 : "굴림"   (Default)
 // 1 : "궁서"
 // 2 : "HY엽서L"

 GetSelectionCharFormat( m_RichEdit, CharForm);

 COLORREF rgbFont = YELLOW, rgbBack = BLACK;
 CString strFontName = _T("굴림");

 switch ( m_FontColor)
 {
 case 0:
  rgbFont = RED; rgbBack = BLUE;
  break;
 case 1:
  rgbFont = GREEN; rgbBack = YELLOW;
  break;
 default:
 case 2:
  rgbFont = YELLOW; rgbBack = WHITE;
  break;
 }

 switch ( m_FontFont)
 {
 default:
 case 0:
  strFontName = _T("굴림");
  break;
 case 1:
  strFontName = _T("궁서");
  break;
 case 2:
  strFontName = _T("HY엽서L");
  break;
 }

 ChangeCharFormat( rgbFont, rgbBack, strFontName, 300 ); //Font Size는 300으로 고정
 SetSelectionCharFormat( m_RichEdit, CharForm);
 
}

void CRichEditDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CRichEditDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CRichEditDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CRichEditDlg::OnRadioColorAmber()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnRadioColorRed()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnRadioColorGreen()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnRadioFont1()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnRadioFont2()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnRadioFont3()
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);

 ChangeCharacterFormat();
}

void CRichEditDlg::OnButtonCodeView()
{
 // TODO: Add your control notification handler code here
 AnalysisRTF();
}
#define MAX_STRING_QUANTITY  1024
void CRichEditDlg::AnalysisRTF()
{
 // 리치에디터의 문자열을 문자열과 폰트,색상을 분석한다.
 
 BYTE StringCodeBuf[MAX_STRING_QUANTITY];
 BYTE StringColorBuf[MAX_STRING_QUANTITY];
 BYTE StringFontBuf[MAX_STRING_QUANTITY];
 BYTE StringBackColorBuf[MAX_STRING_QUANTITY];


 CHARFORMAT2 cf;
 long length=m_RichEdit.GetTextLength();
 long pos=0;
 long count=0;
 CString strBuF;
 char charBuf[10];
 BYTE color;
 BYTE byteBackColor;
 BYTE font;
 if(length>=MAX_STRING_QUANTITY)
  length=MAX_STRING_QUANTITY;

 while(length)
 {
  m_RichEdit.SetSel(count,count+1);

  GetSelectionCharFormat(m_RichEdit, cf);
  if(cf.crTextColor==RED)
   color='R';
  else if(cf.crTextColor==GREEN)
   color='G';
  else
   color='Y';

  if(cf.crBackColor==BLACK)
   byteBackColor='K';
  else if(cf.crBackColor==YELLOW)
   byteBackColor='Y';
  else
   byteBackColor='B';

  if(strcmp(cf.szFaceName,"굴림")==0)
   font='0';
  else if(strcmp(cf.szFaceName,"궁서")==0)
   font='1';
  else 
   font='2';   // HY엽서L

  strBuF=m_RichEdit.GetSelText();
  strcpy(charBuf, (const char *)strBuF);
  if(charBuf[0] & 1<<7)
  {
   // 2바이트 문자
   memcpy(&StringCodeBuf[pos],charBuf,2);
   StringColorBuf[pos+0]=color;
   StringColorBuf[pos+1]=color;
   StringBackColorBuf[pos+0]=byteBackColor;
   StringBackColorBuf[pos+1]=byteBackColor;
   StringFontBuf[pos+0]=font;
   StringFontBuf[pos+1]=font;
   pos+=2;
   length-=2;
  }
  else
  {
   // 1바이트 문자
   StringCodeBuf[pos]=(BYTE)charBuf[0];
   StringColorBuf[pos]=color;
   StringBackColorBuf[pos]=byteBackColor;
   StringFontBuf[pos]=font;
   pos++;
   length--;
  }

  count++;
 }
 
 StringCodeBuf[pos]=0x00;
 StringColorBuf[pos]=0x00;
 StringBackColorBuf[pos]=0x00;
 StringFontBuf[pos]=0x00;
 

출력

m_RichEdit.SetSel(-1,-1);

//////////////////////////////////////////////////////////////////////////
 // 테스트용 디스플레이 (문자열 , 글자색 , 폰트)
 // 문자열
 m_EditView.SetSel(0,-1);
 strBuF.Format("%s",StringCodeBuf);
 m_EditView.ReplaceSel(strBuF);
 // 글자색
 m_EditView2.SetSel(0,-1);
 strBuF.Format("%s",StringColorBuf);
 m_EditView2.ReplaceSel(strBuF);
 // 배경색
 m_EditView4.SetSel(0,-1);
 strBuF.Format("%s",StringBackColorBuf);
 m_EditView4.ReplaceSel(strBuF);
 // 폰트
 m_EditView3.SetSel(0,-1);
 strBuF.Format("%s",StringFontBuf);
 m_EditView3.ReplaceSel(strBuF);

}

void CRichEditDlg::OnButton2()
{
 // TODO: Add your control notification handler code here
 m_RichEdit.SetSel(-1,-1);
}

void CRichEditDlg::OnButtonGetRtf()
{
 // TODO: Add your control notification handler code here
 GetRTF();
}

void CRichEditDlg::OnButtonSetRtf()
{
 // TODO: Add your control notification handler code here
 m_RichEdit.SetSel(0,-1);
 SetRTF(m_RichEdit.GetSelText());
 m_RichEdit.SetSel(0,0);
}

void CRichEditDlg::GetRTF()
{
 CFile cFile(TEXT(FileName), CFile::modeRead);
 EDITSTREAM es;

 es.dwCookie = (DWORD) &cFile;
 es.pfnCallback = CBStreamIn;
 m_RichEdit.StreamIn(SF_RTF, es);
}

void CRichEditDlg::SetRTF(CString sRTF)
{
 CFile cFile(TEXT(FileName), CFile::modeCreate|CFile::modeWrite);
 EDITSTREAM es;

 es.dwCookie = (DWORD) &cFile;
 es.pfnCallback = CBStreamOut;
 m_RichEdit.StreamOut(SF_RTF, es);
}

DWORD CALLBACK CRichEditDlg::CBStreamIn(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
 CFile* pFile = (CFile*) dwCookie;
 *pcb = pFile->Read(pbBuff, cb);
 return 0;
}

DWORD CALLBACK CRichEditDlg::CBStreamOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
 CFile* pFile = (CFile*) dwCookie;
 pFile->Write(pbBuff, cb);
 *pcb = cb;
 return 0;
}

   

'개발언어 > c++' 카테고리의 다른 글

#progrma 의 사용 및 외부링크 Library  (0) 2016.06.13
VC++ 6.0 64Bit x64 컴파일 환경 만들기  (0) 2016.06.13
ATL 프로젝트 디버깅 팁  (0) 2016.06.13
RGB 색상 관련글  (0) 2016.06.13
List Column 고정하기  (0) 2016.06.13