. 시스템 색상 처리

운영체제는 일관된 색상 관리를 위해 시스템 색상을 정의하고 있는데 응용 프로그램들은 항상 고정된 색상값 대신 시스템 색상을 사용해야 한다. 그렇지 않으면 사용자가 선택해놓은 배색 설정을 무시하는 꼴이 되어 좋지 않다. 또한 시스템 색상은 언제든지 사용자에 의해 변경될 수 있으며 프로그램이 실행중인 동안에도 변경 가능하기 때문에 응용 프로그램은 시스템 색상 변화에 대해 반응할 수 있어야 한다.

운영체제는 시스템 색상이 변경될 때 WM_SYSCOLORCHANGE 메시지를 모든 탑 레벨 윈도우에게 보내 주는데 이 메시지를 받았을 때 참조하고 있는 시스템 색상을 다시 조사하고 작업영역을 다시 그려야 한다. 당근과 ApiEdit도 시스템 색상을 많이 사용하므로 이 메시지에 반응할 필요가 있다. DGWndProc에 이 메시지에 대한 핸들러를 추가한다.

 

LRESULT CALLBACK DGWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

          ....

        case WM_SYSCOLORCHANGE:OnSysColorChange(hWnd,wParam,lParam);return 0;

     }

     return(DefFrameProc(hWnd,g_hMDIClient,iMessage,wParam,lParam));

}

 

시스템 색상이 변경될 때 OnSysColorChange 함수를 호출하도록 하여 시스템 색상 변경에 따른 처리를 하도록 한다. 이 메시지는 차일드에게는 전달되지 않으므로 메인 윈도우는 시스템 색상 변경에 영향을 받는 모든 컨트롤에게 이 메시지를 전달해야 한다. 일반적으로 공통 컨트롤들은 모두 이 메시지를 받아야 하며 표준 컨트롤들은 그럴 필요가 없다.

 

void OnSysColorChange(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

     HWND hChild;

     SInfo *pSi;

 

     SendMessage(hToolBar,WM_SYSCOLORCHANGE,wParam,lParam);

     SendMessage(hStatus,WM_SYSCOLORCHANGE,wParam,lParam);

     SendMessage(hFileTree,WM_SYSCOLORCHANGE,wParam,lParam);

     SendMessage(hFileTab,WM_SYSCOLORCHANGE,wParam,lParam);

     SendMessage(hList,WM_SYSCOLORCHANGE,wParam,lParam);

     InitSysColor();

 

     hChild=GetWindow(g_hMDIClient,GW_CHILD);

     while (hChild) {

          pSi=(SInfo *)GetWindowLong(hChild,0);

          if ((Option.cFore & 0xff000000) == 0) {

              pSi->Ae.SetForeColor(-1);

          }

 

          if ((Option.cBack & 0xff000000) == 0) {

              pSi->Ae.SetBackColor(-1);

          }

 

          if ((Option.cSelFore & 0xff000000) == 0) {

              pSi->Ae.SetSelForeColor(-1);

          }

 

          if ((Option.cSelBack & 0xff000000) == 0) {

              pSi->Ae.SetSelBackColor(-1);

          }

          hChild=GetWindow(hChild,GW_HWNDNEXT);

     }

}

 

당근의 차일드로 존재하는 모든 공통 컨트롤에게 이 메시지를 전달하여 컨트롤이 시스템 색상 변경을 스스로 처리하도록 했다. 설정 대화상자가 열려 있는 경우 기본 색상들도 다시 초기화하도록 했다.

ApiEdit는 전경색, 배경색 및 선택 전경, 선택 배경 색이 시스템 색상을 참조하는데 만약 이 옵션들이 기본값이라면 새로 시스템 색상을 조사하도록 하였다. 다른 공통 컨트롤처럼 자신이 직접 WM_SYSCOLORCHANGE 메시지를 처리하도록 하는 것이 좋으나 ApiEdit의 경우는 이 메시지를 직접 처리하기 곤란한 점이 있다. cFore, cBack RGB 색상을 직접 기억하는데다 사용자들이 이 값을 바꿀 수 있기 때문에 현재 설정된 색상이 시스템 색상인지 아니면 사용자들이 지정한 값인지 구분할 수가 없다.

하지만 호스트인 당근의 Option 구조체에는 이 옵션이 디폴트인지 아닌지가 기억되어 있으므로 호스트가 이 메시지를 직접 처리하여 ApiEdit가 색상을 다시 설정해야 할 필요가 있으면 관련 함수를 호출하였다. 컨트롤이 스스로 처리해야 할 일을 호스트가 대신 하고 있는데 이는 컨트롤의 독립성을 해치는 좋지 않은 구조이다. ApiEdit의 색상 변수에 시스템 색상 여부를 따로 기억하고 색상 변화에 스스로 반응하도록 하는 것이 더 좋다.