본문 바로가기

Library/Windows Programming

WTL::CString 문제 : WTL::CFileDialog Filter WTL의 CFileDialog의 필터(filter) 관련 기능은 한 가지 문제가 있다. 필터란 다들 알다시피 파일 관련 대화상자를 열었을 때, 화면에 표시할 파일의 확장자를 선택하여 그것만 보여주는 기능이다. 보통 MFC에서는 CString 형식으로, 구분자로 '|' 표시를 사용하여 정의하고 이 CString을 필터로 그냥 넘겨주면 잘 동작한다. 그러나, WTL의 CFileDialog는 WTL::CString을 사용하여 같은 방법으로 코드를 작성하면, 원하는 결과를 얻지 못한다. 이것은 WTL의 CFileDialog가 MFC와 달리 API를 래핑하는 정도로 작성되어 있기 때문이고, 또 템플릿을 사용한 코드다보니 기능 구현에 어느 정도 제약이 있기 때문이다. 즉, WTL에서는 MFC의 CString '|'.. 더보기
ATL/WTL의 메세지 핸들러 매크로 MFC와 ATL/WTL에서 메세지 핸들러를 작성할 때 가장 피부로 느껴지는 차이점은 미리 정의된 메세지 매크로의 존재이다. MFC에서는 이미 잘 포장되어 있는 각각의 컨트롤들의 메세지 핸들러들이 있고, 용도에 맞게 잘 분류되어 있다. 예를 들어, 버튼 메세지에 관한 것이라면 ON_BN_CLICKED과 같은 매크로를 사용하여 메세지 맵에 추가하면 된다. 그러나, ATL/WTL에서는 그러한 지원이 좋은 편이 아니다. ATL 자체가 그러한 것을 위한 고안된 것이 아니니 어쩔 수 없고, WTL의 atlcrack.h에서 이런 용도를 위해 미리 정의해 둔 메세지 매크로를 제공하지만, MFC의 그것처럼 세세하게 구분되어 있지 않다. 예를 들어, 어떤 컨트롤을 클릭했을 때 발동되는 함수를 정의하기 위해서 COMMAND.. 더보기
ATL/WTL 멀티미디어 타이머 사용하기 WTL을 사용할 때 WM_TIMER 메세지가 때때로 오지 않을 경우가 있다. 현재 실행하고 있는 프로세스 안에서 무엇인가가 바쁘게 돌아가고 있다면 WM_TIMER 메세지가 제대로 오지 않을 수도 있다. 어떤 일을 타이머에 맞춰서 간단하게 처리하고 싶을 때, 딱 이런 목적으로 만들어진 WM_TIMER가 제대로 동작하지 않는다면 곤란할 것이다. 그러나, 다른 스레드에서 그 정도로 복잡한 일을 하고 있어서 메세지가 제대로 오지 않는다면, WM_TIMER를 쓰는 것은 맞지 않다. WM_TIMER는 메세지 처리 과정에서 우선 순위가 낮으며, 경우에 따라서 윈도우가 무시해버릴 수도 있기 때문이다. 이런 경우, 멀티미디어 타이머를 사용하는 것이 좋다. 멀티미디어 타이머는 WM_TIMER와 달리 다른 스레드에서 생성되.. 더보기
WTL C4003 error : SelectObject 계열 함수 사용에서의 에러 WTL을 사용할 때, GDI 개체를 만들고, SelectObject 계열의 함수들을 사용할 때 C4003 에러를 만나는 경우가 있다. Visual C++ 컴파일러가 주는 에러는 'warning C4003: not enough actual parameters for macro...'와 같은 것일텐데, 에러가 날 곳이 없어 보이는 워낙 단순한 함수라 당황스러울 것이다. WTL 소스 코드를 봐도 SelectObject 계열의 함수들(SelectBitmap, SelectFont..)은 함수로 구현되어 있지 매크로로 구현되어 있지 않기 때문에 더더욱 이것의 원인을 알기가 어렵다. 이 문제는, WTL이 메세지 크래킹을 지원하기 위해 포함한 windowsx.h에서 정의한 SelectObject 계열 매크로와 충돌하기.. 더보기
CxImage LNK2019 CxImage는 현재 6.0 버전이 릴리즈되고 있지만, 실제로는 5.99c 버전의 버그를 약간 손 본 것이며, 릴리즈에 포함된 문서들은 6.0 버전임에도 불구하고 아직까지 5.99c로 표기되고 있다. 6.0 버전은 Visual C++ 6.0에 맞추어서 작성된 것이므로, Visual Studio 7.0 이상에서 빌드하고자 할 때 약간의 문제가 있다. 보안 문제로 인해 deprecated 문자열 함수들이 컴파일 경고를 무수하게 쏟아내며, 디폴트 세팅으로 라이브러리를 빌드했다면 링크 문제가 발생한다. 주로 LNK2019 에러가 쏟아져 나올텐데, 이것을 해결하는 방법은 CxImage를 빌드할 때 자신의 프로젝트에서 사용하는 스레딩 타입과 코드 타입을 일치시켜서 컴파일하는 것이다. 즉, Visual Studio .. 더보기
MFC와 ATL/WTL에서의 메세지 전달 메커니즘 C/C++을 사용하여 간단한 Windows Application을 만든다고 할 때, MFC나 ATL과 같은 커다란 라이브러리를 사용하는 것은 달갑지 않은 일이다. MFC로 빌드하여 생성되는 바이너리와 링크되는 DLL의 크기는 무시할 수 없을 정도이며, ATL의 경우 코드의 크기는 매우 작지만 단순히 코드의 크기가 이 글의 주제는 아니다. 중요한 프로젝트에 사용할 일이 아니라면, 사용자 인터페이스가 잘 포장되어 있는 이런 라이브러리를 사용하는 것이 마냥 좋다고는 할 수 없다. 편리한만큼 라이브러리 디자인의 발상과 내부 구현 기법을 지나치기 쉽기 때문이다. MFC와 ATL은 비슷한 메세지 전달 방식을 가지고 있지만, 그 구현 방법은 매우 다르다. 가장 큰 이유는 MFC가 만들어질 당시에는 C++ 표준이란게 .. 더보기
MinGW : gcc 4.4.0 Release! 오랫동안 기다려왔던 gcc 버전 4를 포함하는 MinGW가 릴리즈되었다. MinGW의 가치는 굳이 말을 하지 않아도 모두 알고 있을 것이다. 지구상에서 가장 널리 퍼진 크로스 컴파일러인 gcc의 윈도우 포트라는 것, 그리고 표준을 잘 준수하는 편에 속하는 좋은 컴파일러라는 점 말이다. 더구나, 무상으로 다양한 언어의 컴파일러와 그 소스까지 제공되니, 진정으로 GNU는 가난한 개발자들에게 신이 내린 선물이 아닐 수 없다. 하지만, 특히 MinGW의 가치는 이게 전부가 아니다. cygwin과 별도로, 정말 필요한 패키지가 있을 때 최소의 수정만으로도 포트를 할 수 있도록 도와주는 툴이기도 하다. 물론, 소스를 수정하지 않고 make를 두들겨서 바이너리를 얻을 수 있는 경우는 극히 드물지만, 경우에 따라서는 .. 더보기
POSIX PTHREAD for Win32 Win32 환경에서 스레드 프로그래밍을 한다면, 당연히 Win32 스레드를 사용할 것이다. 스레드와 동기화 매커니즘은, 그 플랫폼에서 제공하는 관련 라이브러리를 사용하는 것이 가장 성능이 좋고, 안정성도 뛰어나기 때문이다. 다만, 문제는 Win32 스레드는 특정 벤더의, 특정 플랫폼에서의 구현이라는 점이다. Win32 스레드도 사용하기 쉬운 편에 속하지만, 윈도우를 어느 정도 알고 있어야 한다. 간단히 말해, 널리 알려진 POSIX PTHREAD와 다르기 때문에, Win32 환경에서 스레드 프로그래밍을 시작하려는 사람에게는 적당하지 않다. 특히, GNU 환경을 Win32에 포팅한 MinGW에서 스레드 관련 라이브러리를 제공하지 않기 때문에, 이런 아쉬움은 더욱 크다. 이런 사람들을 위해 POSIX PTH.. 더보기
Windows Template Library Startup 3 이제 원하는 윈도우의 메세지 핸들러까지 작성했으니, 실제로 WTL 프로그램의 인스턴스화 작업을 준비해보자. PCH를 사용할 stdafx.h과 윈도우 메세지 핸들러를 구현한 mywnd.h가 준비되었다면, 다음은 MFC를 오랫동안 사용해온 사람에게는 기억에서도 흐릿할 WinMain이다. #include "stdafx.h" #include "mywnd.h" CAppModule _Module; 이제, WTL의 MFC에서의 CWinApp에 해당하는 CAppModule을 전역 변수로 선언한다. CAppModule은 ATL의 CComModule을 상속받은 것이며, CWinApp와 비슷한 역할을 하지만 그 성격은 좀 다르다. VC7 이상에서는 이것을 명시적으로 선언할 필요는 없지만, 메세지 루프를 등록하고 윈도우 메세.. 더보기
Windows Template Library Startup 2 WTL을 사용하여 윈도우를 생성하는 것은, 기본적으로 ATL의 윈도우 생성 방식과 동일하다. WTL은 어느 날 갑자기 새롭게 생긴 혁신적인 물건이 아니라, ATL의 골격에 살을 덧붙인 것이다. WTL의 interface / implementation 분리 정책은 사실 ATL에서 온 것이며, ATL이 템플릿을 적극적으로 활용하는 것 또한 HP의 STL 구현 경험에서 영향을 받은 것이다. WTL을 이해하기 위해는, 먼저 ATL의 윈도우 생성, 메세지 전달 방식을 이해해야 한다. ATL에서의 MFC CWnd와 같은 존재라면 CWindow인데, CWindow는 CWnd과 같지 않다. 인터페이스와 구현 모두를 가지고 있는 CWnd과 비교해서 CWindow는 그야말로 인터페이스만 가지고 있으며, 윈도우에 필요한 핸.. 더보기