. 옵션 구조체

ApiEdit는 이제 아주 많은 설정 변수를 가지게 되었으며 이 변수들을 실행중 언제라도 바꾸면 모양과 동작방식에 즉각적인 변화가 생기게 된다. 하지만 아직 옵션을 변경할 수 있는 사용자 인터페이스가 없기 때문에 사용자들이 직접 ApiEdit의 설정을 변경할 방법이 없다. 이 절에서는 설정 대화상자를 통해 ApiEdit의 현재 설정상태를 사용자에게 보여주고 또한 변경할 수 있도록 할 것이다. 뿐만 아니라 호스트 프로그램인 Dangeun의 설정상태도 설정 대화상자를 통해 변경할 수 있다.

설정 대화상자를 만들기 전에 먼저 설정의 대상이 되는 옵션 구조체를 만들도록 하자. ApiEdit각각에 흩어져 있는 설정상태를 설정 대화상자가 일일이 관리하기는 어렵기 때문에 모든 설정 대상 변수들을 한 구조체에 모으도록 한다. 이 구조체는 당근 프로젝트의 동작을 보조하므로 Dangeun.cpp에 직접 작성하지 말고 Util.h에 선언한다. 설정 대화상자를 만드는 실습은 코드량이 많기 때문에 직접 실습을 하는 것보다는 CD-ROM에 있는 예제를 분석해보는 것이 더 좋을 것 같다.

 

struct SOption

{

     SOption() { Init(); }

     void Init();

     int GetMaxMru();

     int GetUndoLimit();

     void Load(TCHAR *Key);

     void Save(TCHAR *Key);

 

    int StartAction;

    BOOL bExplorerPopup;

    BOOL bAllowMulti;

    BOOL bMaxFirstChild;

    int MaxMru;

    TCHAR DefExt[12];

    BOOL Hangul;

    BOOL bShowOutput;

    int OutputHeight;

    BOOL bInitFind;

    BOOL bInitNextFind;

    BOOL bShowToolBar;

    BOOL bShowStatus;

    BOOL bShowFileWnd;

    int FileWndWidth;

    BOOL bShowFileTab;

    BOOL bShowHidden;

    int FilterIndex;

    BOOL bToolBarBig;

    BOOL bToolBarText;

    BOOL bBrowseMode;

    BOOL bSoundFindFail;

    BOOL bWatchChange;

    BOOL bReloadNoAsk;

    BOOL bReloadProject;

 

     int LineRatio;

     BOOL bWrap;

     int nWrap;

     int RightWrap;

     int ColMark;

     int HideSelType;

     int nShowCurLine;

     LOGFONT logfont;

     BOOL bShowMargin;

     BOOL bShowLineNum;

     BOOL bShowEnter;

     BOOL bShowTab;

     BOOL bShowSpace;

     int TabWidth;

     BOOL bNoFirstSpace;

     COLORREF MarColor1;

     COLORREF MarColor2;

     COLORREF NumColor;

     COLORREF MarkColor;

     int ShowTabType;

     int ShowEnterType;

     int ShowSpaceType;

     COLORREF CodeColor;

     COLORREF CurColor;

     COLORREF cBack;

     COLORREF cFore;

     COLORREF cSelFore;

     COLORREF cSelBack;

     BOOL bUseLineEnd;

     BOOL bAllowDrag;

     int CaretWidth;

     BOOL bHideCurLine;

     BOOL bCalcTabWithAvg;

    int UndoLimit;

    BOOL bSpaceForTab;

    BOOL bAutoIndent;

    BOOL bBlockIndentWithTab;

    BOOL bHomeToFirstChar;

    int FindDlgPos;

};

 

생성자와 파괴자를 포함한 몇 개의 멤버함수가 정의되어 있으며 그 외 아주 많은 변수들이 이 구조체에 포함되어 있다. 멤버함수를 가지고 있지만 모든 멤버를 구조체 외부에서 자유 자재로 액세스할 수 있어야 하므로 클래스로 만들지 않았으며 구조체로 만들었다. 물론 클래스로 만든 후 모든 멤버를 public으로 선언해도 효과는 동일하지만 이 경우는 모든 멤버가 공개해야 하는 데이터들이므로 구조체를 사용하는 것이 더 합리적이다.

SOption 구조체에는 정말 많은 옵션 변수들이 있는데 크게 두 종류로 구분된다. 첫 번째 종류는 ApiEdit에 이미 있는 멤버들에 대한 사본 변수이다. LineRatio, HideSelType, bShowMargin 등의 변수들은 ApiEdit에 멤버로 포함되어 있고 우리는 이미 그 의미를 잘 파악하고 있다. 이 변수들이 ApiEdit의 설정값을 가지며 이 변수들을 변경함으로써 ApiEdit의 설정을 간접적으로 변경한다.

구조체의 변수들을 보면 ApiEdit 컨트롤에 있는 대부분의 설정 변수들이 모두 포함되어 있다. 그러나 제외된 변수들도 있으며 변수가 값을 기억하는 방식이 약간 달라지는 것들도 있다. bComp, bCapture 같은 임시 정보는 실행중의 상태 저장에 사용되므로 설정 변수라 할 수 없다. bWantTab도 동작에 영향을 미치기는 하지만 사용자가 지정할 수 있는 옵션이 아니라 프로그래밍 인터페이스이므로 이 구조체에 포함되지 않는다.

자동개행 옵션을 표현하는 방식도 다르다. ApiEdit nWrap 하나로 자동개행 방식을 지정하지만 SOption은 두 개의 변수를 따로 쓴다. bWrap은 자동개행을 할 것인가 아닌가를, nWrap은 하게 된다면 어떤 방식으로 정렬할 것인가를 지정하는 것이다. 이렇게 두 개의 변수를 사용하는 이유는 자동개행 상태를 쉽게 토글할 수 있도록 하기 위해서이다. 마진 출력 여부를 기억하는 방식도 ApiEdit와는 다르다. 마진의 폭을 기억하는 것이 아니라 보여 줄 것인가 아닌가만 기억하므로 SOption::bShowMargin BOOL 타입으로 선언되어 있다. 색상을 표현하는 방법도 완전히 다른데 이 구조체가 색상을 어떻게 정의하는지는 색상 페이지에서 보도록 하자.

두 번째 종류는 ApiEdit와 상관이 없는 StartAction, bExplorerPopup 같은 옵션들이다. 이 옵션들은 호스트 프로그램 즉, Dangeun의 옵션이다. 호스트 프로그램도 당연히 설정값을 가지는데 이 장의 후반부에서부터 하나씩 만들어 나갈 것이다. 굵게 표시된 것들은 아직까지 구현되지 않았지만 앞으로 만들게 될 옵션들인데 미리 넣어 두었다. 일종의 실습 편의를 위한 예비 동작이라고 할 수 있다. 이 옵션들이 추가될 때마다 SOption에 추가하고 Init에서 초기화하고 Load, Save에서 입출력하고 옵션 대화상자에서 관리를 해야 하는데 비슷비슷한 코드를 매번 실습하기가 번거로워 미리 포함시켜 둔 것이다.

이 외에도 SOption에는 문법 설정상태나 인쇄 관련 설정값들이 추가로 더 들어가야 한다. 이 설정값은 단순 변수가 아니라 타입이기 때문에 미리 포함시킬 수가 없으며 관련 부분에서 따로 추가할 것이다.