프로그래밍/Let's Share it

scintilla editor example

초록생선 2023. 3. 30. 00:31

scintilla를 사용하는 간단한 example 입니다.

myeditor.zip
3.74MB

보통 scintilla를 사용하려면 .dll 빌드가 사용되는데, 본 예제는 static build로 진행합니다.

따라서, 다른 scintilla dll 없이 단독으로 실행됩니다.

정식으로 static build를 지원하지 않기에,

아래와 같이, 소스 코드에 강제로 *.cxx 파일등을 추가해야 합니다.

대상 project에 위 예처럼 scite523 source를 포함 시키면 됩니다.

- pch.h 오류가 뜨는 경우

와 같이 오류가 발생한 cxx 소스 파일을 오른쪽 클릭후 property에 다음과 같이 세팅합니다.

strcpy 같은 오류가 발생하면, 위 설정 창의 Preprocessor의 Preprocessor Definitions에 _CRT_SECURE_NO_WARNINGS 를 추가합니다.

 

소스내 주요 함수는 아래와 같습니다.

void CMainFrame::OnInitialUpdateView(CView& view) {
    // child edit의 hwnd 보관.
    m_hWndEdit = view.GetSafeHwnd();

    // scintilla call object를 세팅한다.
    auto fn = (Scintilla::FunctionDirect)view.SendMessage(SCI_GETDIRECTFUNCTION, 0, 0);
    auto ptr = (sptr_t)view.SendMessage(SCI_GETDIRECTPOINTER, 0, 0);
    scall().SetFnPtr(fn, ptr);

    // https://www.scintilla.org/ScintillaDoc.html#SCI_SETILEXER
    // 참고.
    // scall()은 c++ wrapper.

    scall().SetText("foobar");
    scall().StyleSetFont(0, "Consolas");
    scall().StyleSetSize(0, 14);
    scall().StyleSetFore(0, Scintilla::Colour(RGB(255, 0, 0)));
    scall().StyleSetBack(0, Scintilla::Colour(RGB(16, 16, 16)));

    scall().StyleSetBack(STYLE_DEFAULT,        Scintilla::Colour(RGB(128, 128, 128)));
    scall().StyleSetBack(STYLE_LINENUMBER,    Scintilla::Colour(RGB(128, 128, 128)));

    // scall().StyleSetHotSpot(0, true);
    scall().SetCaretLineBack(Scintilla::Colour(RGB(64, 64, 96)));
    scall().SetCaretLineBackAlpha(Scintilla::Alpha(Scintilla::Alpha::NoAlpha));
    scall().SetCaretLineVisible(true);

    scall().SetMultipleSelection(true);

    auto l = CreateLexer("props");
    scall().SetILexer(l);

    int qqq;
    qqq=1;
}

scintilla의 여러 기능을 c++로 호출가능한 예제로 진행되었습니다.

주요 기능은 https://www.scintilla.org/ScintillaDoc.html 참고 가능합니다.

CreateLexer("props")의 "props"는 문서의 서식 타입입니다.

props는 INI형식이며, python등 다른 형식 선언이 가능합니다.

(소스의 lexers에 다양한 문법이 포함되어 있는데, 불필요한 부분을 삭제하여 빌드 크기를 절약할 수 있습니다)

와 같이 실행됩니다. 배경및 붉은 색은 위 OnInitUpdateView로 강제 포매팅된 값입니다.

[section]등 부분은, "props"에 의해 서식으로 된 경우입니다.

LexProps.cxx에 의해 서식이 파싱되며, 그 관계된 서식은 메뉴얼이나 다른 예제 코드로 직접 참고하시기 바랍니다.

scintilla를 이용하여 editor에 fold(접기)기능도 넣을 수 있고,

auto complete도 구현할 수 있습니다.

다소 예제가 적어, 아직 관련 코드는 확인중입니다.

BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    // scintilla edit로 부터 notify message를 받는다.
    SCNotification* noti = (SCNotification*)lParam;
    if (noti->nmhdr.hwndFrom != m_hWndEdit) return CFrameWnd::OnNotify(wParam, lParam, pResult);
    ...
    if (ch == 'z') {
    ...

를 통해, 아래와 같이 빈 편집창에 z키를 입력하면, 강제로 auto complete를 발생시킬 수 있습니다.

MFC 사용법은, 

Building a simple C++ script compiler from Scintilla and CINT - CodeProject

Using Scintilla for syntax coloring in MFC - CodeProject

Scintilla (3) : MFC에 설치하기 : 네이버 블로그 (naver.com)

CScintillaCtrl, CScintillaView & CScintillaDoc v1.78 (naughter.com)

등 참고 가능합니다.

 

서식 포함하여 다양한 기능은 notepad2 github 를 참고하시면 됩니다.

scintilla를 잘 활용하면, 아래 notepad2 같은 UI를 개발할 수 있습니다.