오늘은 대화상자의 특정 색을 투명하게 처리하겠습니다.
결론만 말씀 드리면 제일 핵심적인 코드는 아래와 같습니다.
LONG_PTR lExtStyle = ::GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ); // 현재 스타일 얻어오기
::SetWindowLongPtr( m_hWnd, GWL_EXSTYLE, lExtStyle | WS_EX_LAYERED ); // 투명 속성 추가
::SetLayeredWindowAttributes( m_hWnd, RGB(0,255,0), 0, LWA_COLORKEY ); // 특정 색(RGB(0, 255, 0)을 투명 처리
이 속성을 설정 하면 RGB(0, 255, 0)은 표시하지 않고 투명하게 처리 됩니다.
저는 이번 글에서 위 코드를 이용하여 게임 캐릭터가 걸어다니는 모습을 어떻게 표시하는지 알아보고자 합니다.
일반적인 도트 게임에서는 게임 캐릭터의 움직임이 리소스로 모두 그려져 있습니다.
아래와 같이 게임 캐릭터가 있다고 봅시다.
![](https://3001ssw.com/wp-content/uploads/2023/07/img.bmp)
캐릭터가 정지해 있는 모습, 오른발을 내딛는 모습, 왼발을 내딛는 모습이 하나의 BMP 파일에 저장되어 있습니다.
개발자는 이 리소스를 읽어다가, 이동 명령이 없을 땐 맨 왼쪽에 가만히 서있는 모습만 출력 하고, 이동 할 때는 자연스럽게 오른발을 내딛는 그림과, 왼발을 내딛는 그림을 번갈아 표시합니다.
그럼과 동시에 배경으로 있는 초록색 부분을 투명 처리합니다.
프로젝트를 하나 생성 하신 후, 위 리소스 파일을 res 폴더에 넣어서 리소스 뷰에 추가해줍니다.
![](https://3001ssw.com/wp-content/uploads/2023/07/img-min-10.png)
![](https://3001ssw.com/wp-content/uploads/2023/07/img_1-min-11.png)
![](https://3001ssw.com/wp-content/uploads/2023/07/img_2-min-9.png)
![](https://3001ssw.com/wp-content/uploads/2023/07/img_3-min-7.png)
그런 다음 IDB_BITMAP_TEST로 아이디를 변경해 줍니다.
![](https://3001ssw.com/wp-content/uploads/2023/07/img_4-min-5-1024x426.png)
그리고 헤더 파일에 아래와 같이 변수를 선언합니다.
HDC m_hdc; // 그릴 위치
CImage m_img; // BMP 이미지 로드
int m_iStatus; // 캐릭터의 상태 0 : 멈춤, 1 : 오른발, 2 : 왼발
OnInitDialog에 아래와 같이 코딩합니다.
m_hdc = ::GetDC( m_hWnd );
m_img.LoadFromResource( ::AfxGetInstanceHandle(), IDB_BITMAP_TEST );
LONG_PTR lExtStyle = ::GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ); // 현재 스타일 얻어오기
::SetWindowLongPtr( m_hWnd, GWL_EXSTYLE, lExtStyle | WS_EX_LAYERED ); // 투명 속성 추가
::SetLayeredWindowAttributes( m_hWnd, RGB( 0, 255, 0 ), 0, LWA_COLORKEY ); // 특정 색(RGB(0, 255, 0)을 투명 처리
확인 버튼을 더블클릭하여 이벤트 처리 함수를 만든 뒤 아래와 같이 코딩합니다.
void CMFCApplication1Dlg::OnBnClickedOk()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
// m_hdc 위치의 (0,0)위치에 (가로 20, 세로 40) 크기로 그림.
m_img.Draw( m_hdc, 0, 0, 20, 40, m_iStatus * 20, 0, 20, 40 );
if ( 0 == m_iStatus )
{
m_iStatus = 1;
}
else if ( 1 == m_iStatus )
{
m_iStatus = 2;
}
else if ( 2 == m_iStatus )
{
m_iStatus = 1;
}
}
이미지 크기가 60×40(가로x세로)인데, 세 모션이 있으므로 한 모션당 가로 20, 세로 40 입니다.
그래서 한 모션만 보여주기 위해, m_iStatus 변수를 사용하여 20, 40 크기만 보여준 겁니다.
취소 버튼을 더블클릭하여 이벤트 처리 함수를 만든 뒤 아래와 같이 코딩합니다.
void CMFCApplication1Dlg::OnBnClickedCancel()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
m_iStatus = 0;
m_img.Draw( m_hdc, 0, 0, 20, 40, m_iStatus * 20, 0, 20, 40 );
}
취소 버튼은 멈춰 있는 상태를 표시합니다.
이 상태로 실행 시킨 후 확인 버튼과 취소 버튼을 눌러 봅니다.
![](https://3001ssw.com/wp-content/uploads/2023/07/img-min-7.gif)
간단하게 구현만 하기위해서 만들었지만, 개념을 익히셔서 클래스화 시킨 후 방향키 입력을 받아서 만들면 게임 캐릭터가 이동하는 것 처럼 만들 수 있습니다.
대화상자가 투명하게 보이는건 아까 설명 드린 함수로 Bitmap에 있는 RGB(0, 255, 0)값을 투명처리 해서 초록색이 보이지 않게 된 것입니다.
LONG_PTR lExtStyle = ::GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ); // 현재 스타일 얻어오기
::SetWindowLongPtr( m_hWnd, GWL_EXSTYLE, lExtStyle | WS_EX_LAYERED ); // 투명 속성 추가
::SetLayeredWindowAttributes( m_hWnd, RGB(0,255,0), 0, LWA_COLORKEY ); // 특정 색(RGB(0, 255, 0)을 투명 처리