OS버전이 업데이트 되면서 윈도우즈 콘트롤이 구현되어 있는 COMCTL32.DLL도 버전 업이 되어 왔습니다.
기존의 'COMCTL32.DLL'이라는 Name Space는 그대로 사용할 수 있도록 하되, 다른 버전의 COMCTL32.DLL이
바인딩 될 수 있도록 하기 위해서...
Manifest 설정을 통해 COMCTL32의 버전을 선택할 수 있는 메카니즘이 제공 되고 있는데...(OS의 프로젝션 기능)
컴파일 옵션에서...
'Project > Options > Application > Runtime Themes'에서 'Enable runtime themes'를 선택해주면...
컴파일러가 바이너리를 생성할 때...
미리 정의해 놓은 아래와 같은 Manifest를 리소스 섹션에 집어 넣게 되는데...
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
위와 같이 ... Common-Controls 버전이 6으로 되어 있죠.
저런 식으로 컴파일 해서 프로그램이 실행되게 되면... VCL 프레임웍에서 'COMCTL32.DLL' 네임으로 DLL을 Import 하고 있지만
Manifest 에...
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
위와 같은 식으로 설정되어 있기 때문에... OS 로더가 'COMCTL32.DLL'이라는 Name Space를...
실제적으로는...
Windows/WinSxS/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200........./COMCTL32.DLL
으로 바인딩을 하게 됩니다. 이런 메카니즘을 'Projection'이라고 하죠. (6.0 버전의 COMCTL32.DLL이 사욛 됨)
만약 컴파일 할 때...
'Project > Options > Application > Runtime Themes'에서 'None'을 선택해서 컴파일 하면...
컴파일러가 바이너리의 리소스 섹션에 Manifest 자체를 넣지 않게 됩니다.
이런 상태로 컴파일 되서 실행되면... Common Control에 대한 Manifest 정보가 없기 때문에...
OS 로더는 하위 호환성을 위해서 디폴트로 구버전의 'COMCTL32.DLL'이 프로젝션 되도록 합니다.
예를 들면...
Windows/WinSxS/x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200....../COMCTL32.DLL
이 되는 식이죠. (5.82 버전의 구버전 COMCTL32.DLL이 사용 됨. 9200은 빌드 넘버를 나타내는 거고)
Manifset가 없으면 위와 같이 디폴트 Old Version의 다른 COMCTL32.DLL 이 사용되게 된다는 겁니다.
VCL 프레임웍 라이브러리를 설계할 때...
구버전의 COMCTL32.DLL이 프로젝션에 의해서 바인딩 되어 사용될 때도... 문제가 없도록..
Sub Classing 해서 버전 간의 차이를 에뮬레이션 해주는 식으로 구현해줬어야 하는 건데... 그렇지를 못한 거죠.
Debug 빌드와 Release 버전에서 다른 반응이 나타나는 것은...
Debug/Release 빌드에서 Exception이 처리되는 방식의 차이 때문인 거고요.
OS 버그가 아닌, VCL 프레임웍 라이브러리의 잘못 설계된 디자인 오류 때문 입니다.
...