. 왜 저렇게 복잡할까?

스타일 색상이 초기화되고 레지스트리에 저장되었다가 다시 읽혀지는 일련의 과정을 상상해보고 정리해보도록 하자. 한 번도 실행한 적이 없는 깨끗한 상태에서부터 이 과정을 살펴 볼 것이다. 즉 누군가가 Dangeun.exe를 다운로드받아서 실행해 본다고 가정한다.

 

최초 실행시 레지스트리는 비어 있으며 어떤 정보도 기록되어 있지 않다. OnCreate에서 Option GetStyleColor 함수를 호출하며 이 함수는 ApiEdit의 모든 분석기를 순서대로 생성하면서 디폴트 색상을 조사하여 Option.arStyle에 기록할 것이다.

Dangeun은 분석기가 선택될 때마다 SelectParser 함수를 부른 직후에 Option.SetStyleColor 함수를 호출하여 분석기에게 색상 정보를 제공한다. 각 분석기의 내부 멤버인 arStyle 배열은 호스트가 전달한 값으로 초기화되며 이 값대로 화면에 출력된다.

최초 실행 후 종료될 때 Option.Save 함수에 의해 Option.arStyle 배열이 레지스트리에 그대로 기록된다. 사용자가 옵션을 바꾸지 않았다면 이 값은 분석기의 디폴트값과 같다.

두 번째 실행시 OnCreate에서 Option.Load 함수를 호출하며 이 함수에 의해 레지스트리에 기록된 정보가 Option.arStyle 배열로 다시 읽혀진다. 최초 실행상태가 아니므로 Option GetStyleColor 함수는 더 이상 호출되지 않는다. 분석기들은 생성자에서 일단 디폴트 색상을 초기화하지만 선택될 때마다 이 정보대로 색상이 다시 초기화된다. 즉 생성자보다 외부에서 주어지는 정보가 우선이다.

 

즉 분석기 객체의 생성자에서 초기화되는 디폴트 색상값은 최초 실행시 한 번만 사용되며 이후부터는 이 값을 조사하여 기록한 레지스트리의 값이 유효하다. 도대체 왜 저렇게 복잡하게 스타일 색상을 관리하는 것일까? 분석기나 호스트 둘 중 하나만 정보를 가지면 될 것을 분석기가 초기화한 값의 사본을 호스트가 또 유지하는 이유는 무엇일까? 이렇게 만들어야만 하는 여러 가지 이유가 있다.

 

ApiEdit는 다른 프로그램의 부품으로 사용되는 컨트롤이다. 컨트롤은 레지스트리에 자신의 영구적인 정보를 저장할 권한이 없다. 에디트나 리스트박스가 레지스트리에 어떤 정보를 쓰는 것을 본 적이 있는가? 그것은 아주 주제넘은 짓이다.

분석기의 생성자에서 초기화되는 색상 정보는 컴파일을 다시 해야 변경할 수 있지만 Option이 가지는 색상 정보는 실행중에 언제든지 바꿀 수 있다. 즉 사용자가 마음대로 바꿀 수 있는 설정 대상이 된다.

색상 정보가 구조체든 배열이든 어떤 형태로든 한 곳에 모아져야 한다. 그래야 설정 대화상자를 띄우기 전에 사본을 만들 수 있다. 취소를 하기 위해서는 사본을 쉽게 만들 수 있어야 하며 사본을 대상으로 설정 입력을 받아야 한다. 실컷 고쳐 놓고 마음에 안 드는군하면서 취소할 때를 대비해야 한다. 그래서 분석기의 생성자가 만든 정보를 Option에 수집한 것이다.

 

이 세 가지 조건을 만족시키기 위해서는 Dangeun이 애초에 설정정보를 초기화하고 이 정보를 분석기에게 일방적으로 제공하기만 하면 된다. 그러나 이렇게 하지 않고 분석기의 생성자가 초기화하고 Dangeun이 그 정보를 복사하도록 했는데 그 이유는 다음과 같다.

 

사용자가 설정한 설정상태는 다시 최초 상태로 돌아갈 수 있어야 한다. 설정 대화상자에는 항상 기본 설정으로 돌아가는 명령이 있게 마련이다. 이 기본 설정을 가진 주체가 바로 분석기의 생성자이며 분석기 객체를 다시 생성하면 디폴트 스타일 색상을 조사할 수 있다. 이 작업을 하는 함수가 바로 SOption::GetStyleColor 함수이다.

가장 중요한 이유는 컨트롤의 독립성을 유지하기 위해서이다. SetStyleColor 함수를 불러주지 않아도 컨트롤은 스스로 스타일 색상을 초기화할 수 있어야 한다. Dangeun이 아닌 다른 호스트와 함께 사용되더라도 ApiEdit는 스스로 정의한 디폴트 색상으로 문법 해석을 할 수 있다.

 

이런 복잡한 이유 때문에 스타일 색상을 초기화하는 곳과 유지하는 곳이 분리되어 있고 두 정보가 원활하게 교환될 수 있는 장치가 필요해진 것이다. 게다가 실행속도를 고려하여 매번 같은 정보를 조사하는 동작을 최소화하다 보니 코드가 저렇게 복잡해졌다.