VS2005에서 플랫폼 SDK를 업데이트 하고 나면 컴파일 잘 되던 프로젝트가 afxsock.h 파일에서 에러를 내면서 컴파일이 안 될 수가 있다.
에러의 내용은 아래와 같다.
- 오류 1 error C2065: 'IPPROTO_IPV6' : 선언되지 않은 식별자입니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\atlsocket.inl 130
오류 2 error C2065: 'SOCKADDR_STORAGE' : 선언되지 않은 식별자입니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 381
오류 3 error C2146: 구문 오류 : ';'이(가) 'sockAddr' 식별자 앞에 없습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 381
오류 4 error C2065: 'sockAddr' : 선언되지 않은 식별자입니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 381
오류 5 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 382
오류 6 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 384
오류 7 error C2227: '->sin_port' 왼쪽은 클래스/구조체/공용 구조체/제네릭 형식을 가리켜야 합니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 394
오류 8 error C2146: 구문 오류 : ';'이(가) 'sockAddr' 식별자 앞에 없습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 402
오류 9 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 403
오류 10 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 405
오류 11 error C2227: '->sin_port' 왼쪽은 클래스/구조체/공용 구조체/제네릭 형식을 가리켜야 합니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 415
오류 12 error C2146: 구문 오류 : ';'이(가) 'sockAddr' 식별자 앞에 없습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 423
오류 13 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 424
오류 14 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 426
오류 15 error C2227: '->sin_port' 왼쪽은 클래스/구조체/공용 구조체/제네릭 형식을 가리켜야 합니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 436
오류 16 error C2146: 구문 오류 : ';'이(가) 'sockAddrSelf' 식별자 앞에 없습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 450
오류 17 error C2065: 'sockAddrSelf' : 선언되지 않은 식별자입니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 450
오류 18 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 451
오류 19 error C2070: ''unknown-type'': sizeof 피연산자가 잘못되었습니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 453
오류 20 error C2228: '.ss_family' 왼쪽에는 클래스/구조체/공용 구조체가 있어야 합니다. C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\afxsock.h 470
이때는 _WIN32_WINNT 버전을 0x0501 이상으로 설정해 주면 된다.
자세한 사항은 Microsoft 고객지원 페이지에서 확인할 수 있다.
이 글은 스프링노트에서 작성되었습니다.
C-Runtime Library에 보면 환경 변수를 등록하고 가져오는 함수가 있다.
- #include "stdafx.h"
#include <Windows.h>
#include <cstdlib>
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR* pEnv = NULL ;
pEnv = _tgetenv(TEXT("path")) ; // 대소문자 구분없음
_tprintf(TEXT("%s\r\n\r\n"), pEnv) ;
_tputenv(TEXT("aa=myVal")) ;
pEnv = _tgetenv(TEXT("AA")) ;
_tprintf(TEXT("%s\r\n\r\n"), pEnv) ;
return 0;
}
이렇게 등록한 환경변수는 프로그램이 실행되는 동안에는 유지되는데 프로그램이 끝나도 환경변수가 유지되도록 하려면 레지스트리를 만지면 된다.
환경 변수들은 레지스트리 경로는 HKEY_CURRENT_USER\Environment 키와 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\Session Manager\Environment 키의 하위 값으로 존재한다.
당연히 HKE_CRRET_UER\nvronmnt 키의 값들은 현재 사용자에 대한 사용자 변수이고 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\Session Manager\Environment 키의 값들은 시스템 변수이다.
이 글은 스프링노트에서 작성되었습니다.
보통 윈도우에서 그리기를 할 때 메모리 DC(CompatibleDC)와 메모리 Bitmap(CompatibleBitmap)를 사용하여 BitBlt 함수로 드로잉 작업을 한다.
그래서 이에 대해 개인적으로 정리를 하고자 한다.
BitBlt 함수 정리
- 메모리 DC는 CreateCompatibleDC를 사용하여 생성할 수 있다.
- 이렇게 생성한 DC는 더블 버퍼링등에 활용한다.
- DC의 전경색은 SetTextColor로 변경할 수 있다.
- DC의 배경색은 SetBkColor로 변경할 수 있다.
- 메모리 비트맵은 CreateCompatibleBitmap을 사용하여 만들어진다.
- CreateCompatibleBitmap 함수는 인자로 넘겨지는 DC와 호환되는 비트맵을 생성한다.
-
- 인자로 CPaintDC 등이 넘어오면 screen 과 같은 Color Format이 만들어진다.
- 인자로 CreateCompatibleDC 함수로 생성된 메모리 DC가 넘어오면 흑백 비트맵이 만들어진다.
-
- 메모리 DC은 초기에 1-by-1의 흑백 비트맵이 선택된 상태로 생성된다.
- 이 때 전경색은 흑색(Black)이고 배경색은 흰색(White)이다.
- 크기를 인자로 주면 그 크기의 메모리 비트맵이 초기 전경색인 흑색으로 채워진(Fill) 상태로 생성된다.
- CPaintDC 등도 초기 기본 값은 전경색은 흑색이고 배경색은 흰색이다.
- 메모리 비트맵은 메모리 DC에 선택(SelectObject, SelectBitmap) 한 다음 사용한다.
- 메모리 비트맵의 이미지를 출력하기 위해선 메모리 DC를 소스 DC인자로 여러 그리기 함수를 호출한다.
- BitBlt 함수는 다음과 같은 특성을 가진다.
- 마지막 인자인 dwRop 인자로 여러가지 그리기 모드를 설정할 수 있다.
- 소스와 대상 DC의 칼라 포맷이 다르다면 이 함수는 소스 칼라 포맷을 대상 칼라 포맷에 맞도록 변환한다. 이때 대상 비트맵(DC가 아닐까)의 전경색과 배경색이 변환에 사용된다.
- 흑백 비트맵을 칼라 비트맵으로 변환할 때, white bit(1)을 배경색으로 변환하고 black bit(0)을 전경색으로 변환한다. 이 때는 대상 DC의 전경색과 배경색이 사용된다.
- 칼라 비트맵을 흑백 비트맵으로 변환할 때, 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다. 이 때는 칼라 DC의 전경색과 배경색을 사용한다.
이 글은 스프링노트에서 작성되었습니다.
보통 윈도우에서 그리기를 할 때 메모리 DC(CompatibleDC)와 메모리 Bitmap(CompatibleBitmap)를 사용하여 BitBlt 함수로 드로잉 작업을 한다.
여기서는 BitBlt 함수 개념 정리 내용을 바탕으로 흑백 메모리 비트맵과 BitBlt 함수에 대해서 알아본다.
위의 내용에서 눈여겨 봐 둘 점은 BitBlt 함수는
- 흑백 비트맵을 칼라 비트맵으로 변환할 때, white bit(1)을 배경색으로 변환하고 black bit(0)을 전경색으로 변환한다. 이 때는 대상 DC의 전경색과 배경색이 사용된다.
라는 점이다.
메모리 비트맵을 생성하여 CPaintDC에 출력
CPaintDC dc( m_hWnd ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
전경색인 흑색으로 채워진 비트맵이 생성된다.
-
흑백 비트맵(dcMem)을 칼라 비트맵(dc)으로 변환하나(흑백 비트맵의 흰색->칼라 비트맵의 배경색, 흑백 비트맵의 검정색->칼라 비트맵의 전경색) CPaintDC도 기본 배경색이 흰색이고 전경색이 흑색이다.
-
비트맵 바깥쪽의 흰색 바탕은 윈도우에서 배경색으로 칠해주는 색이다. WM_ERASEBKGND 에서 아무것도 해 주지 않으면 컨토롤의 기본 배경색인 회색 계통의 색이 나타난다.
- atlcrack.h를 사용한 OnPaint 함수는 인자로 CDCHandle이 넘어오는데 이 DC는 아무값도 가지고 있지 않다(NULL). 그래서 사용할 수 없다.
- WTL 7.5(? 8.0)에서 부터 사용할 수 있는 CMemoryDC는 생성자에서 인자로 넘겨받는 CPaintDC를 가지고 CreateCompatibleBitmap의 인자로 넘겨주므로 흑백이 아닌 screen과 같은 칼라 포맷을 가진 비트맵이 생성된다.
메모리 비트맵에 글자 찍기
CPaintDC dc( m_hWnd ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
메모리 비트맵 생성시 초기에 무조건 전경색인 검정색으로 채워진 비트맵이 생성되고 메모리 DC에 적용한 전경색인 배경색은 그 다음의 그리기 연산을 할 때 적용된다.
-
글자의 배경이 기본 배경색인 흰색, 글자색이 기본 전경색인 흑색으로 출력된다.
CPaintDC의 배경색을 Green으로 변경
CPaintDC dc( m_hWnd ) ;
dc.SetBkColor( RGB(0, 255, 0) ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
TextOut 출력시 배경색인 흰색이 CPaintDC의 배경색인 초록색으로 출력된다.
-
TextOut 출력시 전경색인 검정색은 CPaintDC의 전경색인 검정색으로 출력된다.
CPaintDC의 전경색을 Red로 변경
CPaintDC dc( m_hWnd ) ;
dc.SetTextColor( RGB(255, 0, 0) ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
TextOut 출력시 전경색인 검정색이 CPaintDC의 전경색인 빨강색으로 출력된다.
-
TextOut 출력시 배경색인 흰색은 CPaintDC의 배경색인 흰색으로 출력된다.
CPaintDC의 배경색을 Green으로, 전경색을 Red로 변경
CPaintDC dc( m_hWnd ) ;
dc.SetBkColor( RGB(0, 255, 0) ) ;
dc.SetTextColor( RGB(255, 0, 0) ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
TextOut 출력시 배경색인 흰색은 CPaintDC의 배경색인 초록색으로 출력된다.
-
TextOut 출력시 전경색인 검정색은 CPaintDC의 전경색인 빨강색으로 출력된다.
CPaintDC의 배경색은 Green으로, 전경색을 Red로, 메모리 DC의 배경색을 Black으로, 전경색을 White로 반전
- 원래 메모리 DC의 배경색이 White이고 전경색이 Black이다
CPaintDC dc( m_hWnd ) ;
dc.SetBkColor( RGB(0, 255, 0) ) ;
dc.SetTextColor( RGB(255, 0, 0) ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
dcMem.SetBkColor( RGB( 0, 0, 0 ) ) ;
dcMem.SetTextColor( RGB( 255, 255, 255 ) ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
메모리 비트맵 생성시 초기에 무조건 전경색인 검정색으로 채워진 비트맵이 생성되고 메모리 DC에 적용한 전경색인 배경색은 그 다음의 그리기 연산을 할 때 적용된다.
-
그러므로 전체가 검정색인 비트맵에서 글자를 찍을 때 배경색을 변경된 배경색인 검정색으로 글자색을 변경된 전경색인 흰색으로 찍는다.
-
이 결과 메모리 비트맵에서 검정색 부분은 대상 DC의 전경색인 빨강색으로, 흰색 부분은 대상 DC의 배경색인 초록색으로 출력된다.
CPaintDC의 배경색은 Green, 전경색 Red, 메모리 DC의 전경색과 배경색을 같게
- 메모리 DC의 전경색, 배경색을 모두 White로
dcMem.SetTextColor( RGB( 255, 255, 255 ) ) ;
[메모리 비트맵] [출력]
- 메모리 DC의 전경색, 배경색을 모두 Black로
dcMem.SetTextColor( RGB( 0, 0, 0 ) ) ;
[메모리 비트맵] [출력]
메모리 DC의 전경색과 배경색을 흰색과 검정색 이외의 색으로, CPaintDC의 배경색은 Green, 전경색은 Red
여기서 메모리 DC의 전경색 및 배경색을 희색과 검정색 이외의 색으로 지정해 준다면 어떻게 될까?
- 메모리 DC의 배경색을 RGB(255, 255, 0)으로 지정
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
dcMem.SetBkColor( RGB( 255, 255, 0 ) ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
결과는 배경을 흰색으로 지정했을 때와 같다
-
즉 RGB(255, 255, 0)은 흰색으로 계산된다.
- 메모리 DC의 배경색을 RGB(128, 127, 127)로 지정
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
dcMem.SetBkColor( RGB( 128, 127, 127 ) ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
결과는 배경을 검정색으로 지정했을 때와 같다
-
즉 RGB(128, 127, 127)은 검정색으로 계산된다
결과를 보면 알겠지만 흰색과 검정색 이외의 색도 결과적으로 흰색과 검정색으로 변환된다.
이는 현재 메모리 DC는 흑백 비트맵을 장착하고 있다. 그 말은 흰색과 검정색만 표현할 수 있다는 말이다.
그렇다면 흰색과 검정색으로 변환되는 기준은 무엇일까?
SetBkColor에 들어 갈 수 있는 값은 RGB(0, 0, 0)에서 RGB(255, 255, 255)까지의 값이다. 이 사이의 값들 중에서 RGB(0, 0, 0)에 가까운 값은 RGB(0, 0, 0)인 검정색으로 변환되고 RGB(255, 255, 255)에 가까운 값은 RGB(255, 255, 255)인 흰색으로 변환된다.
기준은 RGB 매크로의 인자인 r, g, b 의 최고값인 255, 255, 255를 합하여 검정색과 흰색 두 색으로만 나뉘어지므로 2를 나눈 값이다.
그런데 소수점은 RGB의 값으로 사용할 수 없으므로 r, g, b의 값을 합한 값이 382 이하이면 검정색을 나타내고 383 이상이면 흰색을 나타낸다.
첫 번째 예는 255 + 255 + 0 = 510 이므로 흰색을 나타내고 두 번째 예는 128 + 127 + 127 = 382 이므로 검정색을 나타낸다.
그럼 RGB(129, 127, 127)의 경우는 어떨까? 이 값은 합이 383이므로 흰색을 나타낼 것이다.
- 메모리 DC의 배경색을 RGB(129, 127, 127)로 지정
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMem ;
dcMem.CreateCompatibleDC( dc ) ;
dcMem.SetBkColor( RGB( 129, 127, 127 ) ) ;
CBitmap bitmapMem ;
// 100x100의 흑색으로 칠해진 흑백 비트맵 생성
bitmapMem.CreateCompatibleBitmap( dcMem, 100, 100 ) ;
dcMem.SelectBitmap( bitmapMem ) ;
dcMem.TextOut( 0, 0, TEXT("MY TEST") ) ;
dc.BitBlt( 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY ) ;
[메모리 비트맵] [출력]
-
결과는 예상대로 메모리 비트맵의 배경이 흰색으로 나왔다
-
RGB(255, 128, 0)으로 해도 메모리 비트맵의 배경이 흰색이 된다.
-
RGB(254, 128, 0)으로 했을 경우에는 메모리 비트맵의 배경이 검정색이 된다.
결론은 지금껏 보아 왔듯이 다음과 같다.
- 메모리 DC를 인자로 CreateCompatibleBitmap 함수를 호출하면 검정색으로 채워진 흑백 비트맵이 생성된다.
- 흑백 비트맵은 당연히 검정색과 흰색만 나타낼 수 있다.
- BitBlt 함수 사용시 dwRop인자의 영향을 받겠지만 메모리 비트맵의 흰색은 대상 DC의 배경색으로, 검정색으로 대상 DC의 전경색으로 나타난다.
칼라 메모리 비트맵을 흑백 메모리 비트맵으로 Bit-Blit할 때의 칼라 변환은 칼라 메모리 비트맵과 BitBlt를 참조해라.
이 글은 스프링노트에서 작성되었습니다.
보통 윈도우에서 그리기를 할 때 메모리 DC(CompatibleDC)와 메모리 Bitmap(CompatibleBitmap)를 사용하여 BitBlt 함수로 드로잉 작업을 한다.
여기서는 BitBlt 함수 개념 정리 내용을 바탕으로 흑백 메모리 비트맵과 BitBlt 함수에 대해서 알아본다.
위의 내용에서 눈여겨 봐 둘 점은 BitBlt 함수는
- 칼라 비트맵을 흑백 비트맵으로 변환할 때, 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다. 이 때는 칼라 DC의 전경색과 배경색을 사용한다.
라는 점이다.
칼라 메모리 비트맵을 생성하여 CPaintDC에 출력
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
// CPaintDC와 같은 칼라 포맷을 가진 칼라 메모리 비트맵을 사용하므로 칼라가 그대로 적용된다.
dc.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
[칼라 메모리비트맵] [출력]
-
칼라 메모리 비트맵이라도 처음에는 검정색(기본 전경색)으로 채워진 메모리 비트맵이 생성된다.
-
칼라 메모리 비트맵을 칼라 비트맵(CPaintDC에 기본으로 장착된)에 나타내므로 색상 변환이 없다.
-
비트맵 바깥쪽의 흰색 바탕은 윈도우에서 배경색으로 칠해주는 색이다. WM_ERASEBKGND 에서 아무것도 해 주지 않으면 컨토롤의 기본 배경색인 회색 계통의 색이 나타난다.
칼라 메모리 비트맵을 생성하여 글자 출력
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
// CPaintDC와 같은 칼라 포맷을 가진 칼라 메모리 비트맵을 사용하므로 칼라가 그대로 적용된다.
dc.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
[칼라 메모리비트맵] [출력]
-
칼라 메모리 비트맵이라도 초기 전경색은 검정색인 RGB(0, 0, 0), 배경색은 흰색인 RGB(255, 255, 255)의 값을 가진다.
-
칼라 메모리 비트맵을 칼라 비트맵(CPaintDC에 기본으로 장착된)에 나타내므로 색상 변환이 없다.(참조: 흑백 메모리 비트맵과 BitBlt)
칼라 메모리 비트맵의 전경색을 흰색으로 배경색을 검정색으로 치환
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 0 ) ) ;
dcMemColor.SetTextColor( RGB( 255, 255, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
// CPaintDC와 같은 칼라 포맷을 가진 칼라 메모리 비트맵을 사용하므로 칼라가 그대로 적용된다.
dc.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
[칼라 메모리비트맵] [출력]
-
기본 검정색으로 채워진 칼라 비트맵이 생성되고 변경된 배경색과 전경색은 변경 후 호출하는 gdi 함수에 의해 사용된다.
-
칼라 메모리 비트맵을 칼라 비트맵(CPaintDC에 기본으로 장착된)에 나타내므로 색상 변환이 없다.(참조: 흑백 메모리 비트맵과 BitBlt)
칼라 메모리 비트맵의 배경색을 Blue, 전경색을 RGB(255, 0, 255)로 변경
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.SetTextColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
// CPaintDC와 같은 칼라 포맷을 가진 칼라 메모리 비트맵을 사용하므로 칼라가 그대로 적용된다.
dc.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
[칼라 메모리비트맵] [출력]
-
변경된 배경색, 전경색들이 메모리 비트맵에도 출력에도 그대로 나타난다.
-
흑백 비트맵을 출력할 때와 같은 칼라 변환은 일어나지 않는다.
칼라 메모리 비트맵의 배경색을 Blue, 전경색을 RGB(255, 0, 255)로 변경하여 텍스트 출력
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.SetTextColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
// CPaintDC와 같은 칼라 포맷을 가진 칼라 메모리 비트맵을 사용하므로 칼라가 그대로 적용된다.
dc.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dc.TextOut( 0, 15, TEXT("PaintDC") ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
[칼라 메모리비트맵] [출력]
-
칼라 메모리 비트맵의 색상도 변경없이 출력되고 Paint DC 에서 출력한 내용도 Paint DC에서 설정한 전경색, 배경색 대로 출력된다.
칼라 비트맵을 흑백 비트맵으로 출력
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.SetTextColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
CDC dcMemMono ;
dcMemMono.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemMono ;
// 모노 칼라(흑백) 비트맵 생성
bitmapMemMono.CreateCompatibleBitmap( dcMemMono, 100, 100 ) ;
CBitmapHandle bitmapOldMono = dcMemMono.SelectBitmap( bitmapMemMono ) ;
// 칼라 비트맵을 흑백 비트맵으로 변환할 때,
// 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다.
// 이 때는 칼라 DC의 전경색과 배경색을 사용한다
dcMemMono.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
// 칼라 비트맵을 bit-blit한 흑백 비트맵을 CPaintDC에 출력
dc.BitBlt( 0, 0, 100, 100, dcMemMono, 0, 0, SRCCOPY ) ;
dc.TextOut( 0, 15, TEXT("PaintDC") ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
dcMemMono.SelectBitmap( bitmapOldMono ) ;
[칼라 메모리비트맵] [흑백 메모리비트맵] [출력]
-
처음에 언급한 "칼라 비트맵을 흑백 비트맵으로 변환할 때, 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다. 이 때는 칼라 DC의 전경색과 배경색을 사용한다."라는 내용의 결과를 볼 수 있다.
-
처음에 칼라 비트맵은 설정한 대로 잘 나타난다.
-
두 번째 칼라 비트맵을 흑백 비트맵으로 출력할 때 칼라 DC의 배경색과 일치하는 파랑색은 흑백 비트맵에서 흰색으로 그렇지 않은 색들은 검정색으로 나타난다.
-
흑백 메모리 비트맵을 다시 칼라 DC인 Paint DC로 출력할 때는 흑백 메모리 비트맵과 BitBlt에서 설명한 "흑백 비트맵을 칼라 비트맵으로 변환할 때, white bit(1)을 배경색으로 변환하고 black bit(0)을 전경색으로 변환한다. 이 때는 대상 DC의 전경색과 배경색이 사용된다"는 원칙에 따라서 흰색 부분은 Paint DC의 배경색인 RGB( 0, 255, 0 )로 나타나고 검은 부분은 Paint DC의 전경색인 RGB( 255, 0, 0 )로 나타난다.
칼라 비트맵을 흑백 비트맵으로 출력, 흑백 비트맵의 전경색을 White, 배경색을 Black로 변경
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.SetTextColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
CDC dcMemMono ;
dcMemMono.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemMono ;
// 모노 칼라(흑백) 비트맵 생성
bitmapMemMono.CreateCompatibleBitmap( dcMemMono, 100, 100 ) ;
CBitmapHandle bitmapOldMono = dcMemMono.SelectBitmap( bitmapMemMono ) ;
// 흑백 비트맵의 배경색을 검정색으로, 전경색을 흰색으로 바꾼다.
dcMemMono.SetBkColor( RGB( 0, 0, 0 ) ) ;
dcMemMono.SetTextColor( RGB( 255, 255, 255 ) ) ;
// 칼라 비트맵을 흑백 비트맵으로 변환할 때,
// 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다.
// 이 때는 칼라 DC의 전경색과 배경색을 사용한다
dcMemMono.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
// 칼라 비트맵을 bit-blit한 흑백 비트맵을 CPaintDC에 출력
dc.BitBlt( 0, 0, 100, 100, dcMemMono, 0, 0, SRCCOPY ) ;
dc.TextOut( 0, 15, TEXT("PaintDC") ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
dcMemMono.SelectBitmap( bitmapOldMono ) ;
[칼라 메모리비트맵] [흑백 메모리비트맵] [출력]
-
흑백 메모리 비트맵의 전경색과 배경색을 바꿔 줬으나 바꾸지 않았을 때와 같은 결과이다.
-
이것은 칼라 비트맵에서 흑백 비트맵으로 bit-blit 할 때 흑백 비트맵의 전경색과 배경색이 아무런 영향을 끼치지 않는다는 것을 나타낸다.
-
결국 칼라 비트맵을 흑백 비트맵으로 변환 할 때나 흑백 비트맵을 칼라 비트맵으로 전환할 때 흑백 비트맵의 전경색과 배경색이 무슨 색이냐하는 것은 칼라 변환 자체에는 영향을 끼치지 않는다. 흑백 비트맵의 어떤 부분인 흰 부분인가 검은 부분인가 하는 문제와 칼라 비트맵의 전경색과 배경색이 무엇인가 하는 것만이 칼라 변환에 영향을 끼친다.
흑백 메모리 DC의 전경색과 배경색을 바꾸고 텍스트 출력
CPaintDC dc( m_hWnd ) ;
COLORREF crBackground = RGB( 0, 255, 0 ) ;
COLORREF crForeground = RGB( 255, 0, 0 ) ;
dc.SetBkColor( crBackground ) ;
dc.SetTextColor( crForeground ) ;
CRect rect ;
dc.GetClipBox( rect ) ;
CDC dcMemColor ;
// dcMemColor의 배경색과 전경색은 초기 생성시
// dc의 배경색 및 전경색과 상관없이 배경:RGB(0, 0, 0), 전경:RGB(255, 255, 255)이다.
dcMemColor.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemColor ;
// 비메모리 DC 전달, 검정색으로 채워진 칼라비트맵 생성
// CPaintDC인 dc와 같은 칼라 포맷을 가진 칼라 비트맵 생성
bitmapMemColor.CreateCompatibleBitmap( dc, 100, 100 ) ;
CBitmapHandle bitmapOldColor = dcMemColor.SelectBitmap( bitmapMemColor ) ;
dcMemColor.SetBkColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.SetTextColor( RGB( 0, 0, 255 ) ) ;
dcMemColor.TextOut( 0, 0, TEXT("MY TEST") ) ;
CDC dcMemMono ;
dcMemMono.CreateCompatibleDC( dc ) ;
CBitmap bitmapMemMono ;
// 모노 칼라(흑백) 비트맵 생성
bitmapMemMono.CreateCompatibleBitmap( dcMemMono, 100, 100 ) ;
CBitmapHandle bitmapOldMono = dcMemMono.SelectBitmap( bitmapMemMono ) ;
// 흑백 비트맵의 배경색을 검정색으로, 전경색을 흰색으로 바꾼다.
dcMemMono.SetBkColor( RGB( 0, 0, 0 ) ) ;
dcMemMono.SetTextColor( RGB( 255, 255, 255 ) ) ;
// 칼라 비트맵을 흑백 비트맵으로 변환할 때,
// 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다.
// 이 때는 칼라 DC의 전경색과 배경색을 사용한다
dcMemMono.BitBlt( 0, 0, 100, 100, dcMemColor, 0, 0, SRCCOPY ) ;
dcMemMono.BitBlt( 0, 30, TEXT("Mono") ) ;
// 칼라 비트맵을 bit-blit한 흑백 비트맵을 CPaintDC에 출력
dc.BitBlt( 0, 0, 100, 100, dcMemMono, 0, 0, SRCCOPY ) ;
dc.TextOut( 0, 15, TEXT("PaintDC") ) ;
dcMemColor.SelectBitmap( bitmapOldColor ) ;
dcMemMono.SelectBitmap( bitmapOldMono ) ;
[칼라 메모리비트맵] [흑백 메모리비트맵] [출력]
-
위에서 살펴본 봐야 같이 흑백 비트맵의 흰 부분인가 검은 부분이가 하는 문제와 칼라 비트맵의 전경색과 배경색 만이 영향을 끼친다.
이상의 내용을 정리하면 다음과 같다.
- 칼라 비트맵을 흑백 비트맵으로 변환할 때, 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다. 이 때는 칼라 DC의 전경색과 배경색을 사용한다.
- 흑백 비트맵을 칼라 비트맵으로 변환할 때, white bit(1)을 배경색으로 변환하고 black bit(0)을 전경색으로 변환한다. 이 때는 대상 DC의 전경색과 배경색이 사용된다.
- 결국 칼라 비트맵을 흑백 비트맵으로 변환 할 때나 흑백 비트맵을 칼라 비트맵으로 전환할 때 흑백 비트맵의 전경색과 배경색이 무슨 색이냐하는 것은 칼라 변환 자체에는 영향을 끼치지 않는다. 흑백 비트맵의 어떤 부분인 흰 부분인가 검은 부분인가 하는 문제와 칼라 비트맵의 전경색과 배경색이 무엇인가 하는 것만이 칼라 변환에 영향을 끼친다.
[참조] 흑백 비트맵과 BitBlt
이 글은 스프링노트에서 작성되었습니다.
BOOL BitBlt (HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop)
-
인자
-
-
hdcDest
- 목적지의 DC 핸들
-
nXDest
- 목적지의 좌상을 기준으로 한 x 좌표(논리 단위)
-
nYDest
- 목적지의 좌상을 기준으로 한 y 좌표(논리 단위)
-
nWidth
- 소스와 목적지의 너비(논리 단위)
-
nHeight
- 소스와 목적지의 높이(논리 단위)
-
hdcSrc
- 소스의 DC 핸들
-
nXSrc
- 소스의 좌상을 기준으로 한 x 좌표(논리 단위)
-
nYSrc
- 소스의 좌상을 기준으로 한 y 좌표(논리 단위)
-
dwRop
-
- 래스트 연산 코드
- 최종 칼라를 얻기 위해 소스 영역의 칼라가 목적지 영역의 칼라와 어떻게 결합할 것인지를 결정하는 코드
-
BLACKNESS
- 0x00000042
- 물리 팔레트의 인덱스 0에 해당하는 색(디폴트는 검정색)으로 목적지의 사각 영역을 채운다.
- CAPTUREBLT
- 0x40000000
- 사용자 창 위에 놓인 창들이 생성되는 이미지에 포함된다. 기본적으로 이미지에는 사용자 창만 포함된다. 이것은 인쇄 장치 컨텍스트에는 대개 사용할 수 없다.
-
DSTINVERT
- 0x0050009
- 목적지 영역의 색을 반전한다.
-
MERGECOPY
- 0x00C000CA
- 소스 영역의 색이 Boolean AND 연산자를 사용하여 대상 장치 컨텍스트의 선택된 브러시 색과 병합된다.
-
MERGEPAINT
- 0x00BB0226
- 반전된 소스 영역의 색이 Boolean OR 연산자를 사용하여 대상 영역의 색과 병합된다.
- NOMIRRORBITMAP
- 0x80000000
- 비트맵이 미러링되지 않는다.
-
NOTSRCCOPY
- 0x00330008
- 반전된 소스 영역이 대상에 복사된다.
-
NOTSRCERASE
- 0x001100A6
- 소스 및 대상 색이 Boolean OR 연산자를 사용하여 결합된 다음 생성된 색이 반전된다.
-
PATCOPY
- 0x00F00021
- 대상 장치 컨텍스트에서 현재 선택된 브러시가 대상 비트맵에 복사된다.
- PATINVERT
-
- 0x005A0049
- 대상 장치 컨텍스트에서 현재 선택된 브러시 색이 Boolean XOR 연산자를 사용하여 대상 색과 결합된다.
- PATPAINT
- 0x00FB0A09
- 대상 장치 컨텍스트에서 현재 선택된 브러시 색이 Boolean OR 연산자에 의해 반전된 소스 영역의 색과 결합된다. 이 연산의 결과는 Boolean OR 연산자를 사용하여 대상 영역의 색과 결합된다.
-
SRCAND
- 0x008800C6
- 소스 및 대상 영역의 색이 Boolean AND 연산자를 사용하여 결합된다.
-
SRCCOPY
- 0x00CC0020
- 소스 영역이 직접 대상 영역에 복사된다.
-
SRCERASE
- 0x00440328
- 대상 영역의 반전된 색이 Boolean AND 연산자를 사용하여 소스 영역의 색과 결합된다.
-
SRCINVERT
- 0x00660046
- 소스 및 대상 영역의 색이 Boolean XOR 연산자를 사용하여 결합된다.
-
SRCPAINT
- 0x00EE0086
- 소스 및 대상 영역의 색이 Boolean OR 연산자를 사용하여 결합된다.
-
WHITENESS
- 0x00FF0062
- 물리 팔레트의 인덱스 1에 해당하는 색 (디폴트는 흰색)을 사용하여 대상 영역을 채운다.
- .NET Framework 2.0의 System.Drawing에도 이에 해당하는 CopyPixelOperation 열거형이 있다.
-
-
반환값
- 성공하면 0 이외의 값
- 실패하면 0
-
설명
- 소스 디바이스 컨텍스트로부터 대상 디바이스 컨텍스트에 지정된 영역의 픽셀의 칼라 데이터의 비트 블록 전송을 수행한다.
- 오직 대상 DC에 클리핑을 한다.
- 소스 DC에 깍기나 회전 등의 변환이 있다면 이 함수는 에러를 리턴한다. 소스 DC에 다른 변환이 있다면 (그리고 매치되는 변환이 대상 DC에 없다면) 대상 DC의 영역은 필요에 따라서 늘어나거나 압축되거나 회전되거나 한다.
- 소스와 대상 DC의 칼라 포맷이 다르다면 이 함수는 소스 칼라 포맷을 대상 칼라 포맷에 맞도록 변환한다. 이때 대상 비트맵(DC가 아닐까)의 전경색과 배경색이 변환에 사용된다.
- 흑백 비트맵을 칼라 비트맵으로 변환할 때, white bit(1)을 배경색으로 변환하고 black bit(0)을 전경색으로 변환한다. 이 때는 대상 DC의 전경색과 배경색이 사용된다.
- 칼라 비트맵을 흑백 비트맵으로 변환할 때, 배경색과 일치 하는 픽셀을 white로 그렇지 않은 픽셀을 black로 변환한다. 이 때는 칼라 DC의 전경색과 배경색을 사용한다.
- Enhanced Metafile 이 기록되고 있을 때 소스 DC가 Enhanced-Metafile DC라면 에러가 발생한다.
- 모든 디바이스가 이 함수를 지원하지는 않는다. 보다 많은 정보는 MaskBlt, PlgBlt, StretchBlt 를 사용할 때처럼 GetDeviceCaps 함수의 RC_BITBLT raster capability 요소로 확인할 수 있다.
- 이 함수는 소스와 대상 디바이스 컨텍스트가 다른 디바이스를(호환되지 않는) 나타낸다면 에러를 리턴한다. 다른 디바이스들의 DC 간 데이터 전송을 위해서는 메모리 비트맵을 GetDIBits 를 호출하여 DIB로 변환해야한다. DIB를 두번째 디바이스에 디스플레이하기 위해서는 SetDIBits나 StretchDIBits를 호출해야 한다.
- blit 이 발생할 때 칼라 매니지먼트는 실행되지 않는다.
이 글은 스프링노트에서 작성되었습니다.
HBITMAP CreateCompatibleBitmap (HDC hdc, int nWidth, int nHeight)
-
인자
-
hdc
- DC의 핸들.
- 이 DC와 호환하는 비트맵을 작성한다.
-
nWidth
- 작성하는 비트맵의 가로 사이즈(픽셀 단위)
-
nHeight
- 작성하는 비트맵의 세로 사이즈(픽셀 단위)
-
-
반환값
- 성공하면 호환되는(DDB) 비트맵의 핸들
- 실패하면 NULL
-
설명
- 인자로 주어진 DC에 호환하는 비트맵을 생성하여 반환한다.
- 생성되는 비트맵의 칼라 포맷(색형식)은 hdc 인자의 칼라 포맷과 같다. 생성된 비트맵은 hdc와 호환되는 어떤 메모리 DC에서도 선택되어 질 수 있다.
- 메모리 DC는 칼라와 흑백 비트맵 둘다 취할 수 있기 때문에 인자로 지정된 DC가 메모리 DC일 때 생성되어 리턴되는 비트맵의 포맷은 다르다.
-
하지만 메모리 DC가 아닌 DC(비메모리 DC - nonmenory device context)에 의해 생성되는 호환 비트맵은 항상 주어진 인자 DC와 같은 칼라 포맷을 가지고 같은 칼라 팔레트를 사용한다.
- 메모리 DC가 생성되었을 때 메모리 DC는 처음에 1x1 흑백 비트맵을 선택하고 있다(배경색이 White(255, 255, 255)이고 전경색이 Black(0, 0, 0)). 만약 이 메모리 DC가 CreateCompatibleBitmap 함수에 사용되어 진다면 생성되는 비트맵은 흑백 비트맵이다. 칼라 비트맵을 생성하기 위해서는 이 메모리 DC를 생성할 때 사용된 hDC를 사용해야한다.
- HDC memDC = ::CreateCompatibleDC ( hDC ) ;
- HBITMAP memBM = ::CreateCompatibleBitmap ( hDC, nWidth, nHeight ) ;
- SelectObject ( memDC, memBM ) ;
- 만약 어플리케이션이 nWidth나 nHeight를 0으로 지정한다면 이 함수는 1x1(1-by-1) 픽셀의 흑백 비트맵의 핸들을 리턴한다.
- CreateDIBSection 함수로 생성된 DIB section이 hdc인자의 DC에 선택되어져 있다면 이 함수는 DIB section을 생성한다.
- 비트맵이 더 이상 필요하지 않다면 DeleteObject를 호출하여 비트맵을 지워야 한다.
- Windows 95/98/Me에서는 16MB을 넘는 사이즈의 비트맵은 생성할 수 없다.
이 글은 스프링노트에서 작성되었습니다.
HDC CreateCompatibleDC (HDC hDC)
-
인자
-
hDC
- 기존의 디바이스 컨텍스트(DC)의 핸들
- 이 DC에 관련하는 디바이스와 호환성 있는 메모리 디바이스 컨텍스트 생성
- NULL을 지정하면 어플리케이션의 현재의 스크린과 호환성 있는 메모리 디바이스 컨텍스트 생성
-
-
반환값
- 성공하면 작성한 메모리 DC의 핸들
- 실패하면 NULL
-
설명
-
- 이 함수는 인자로 주어진 디바이스에 호환되는 메모리 디바이스 컨텍스트를 생성하여 반환한다.
-
메모리 DC가 생성되면 이 메모리 DC의 표면(surface)은 1x1 픽셀의 흑백이다(1x1 픽셀의 흑백 비트맵이 선택된 상태가 되어 있다).
- 처음 생성시 배경색(BkColor)이 White(255, 255, 255)이고 전경색(TextColor)이 Black(0, 0, 0)이다.
- 처음 표면은 전경색(검정색)으로 채워진다.
- 표면의 배경색 및 전경색은 SetBkColor과 SetTextColor로 변경가능하다.
- CPaintDC 등도 처음 생성하면 배경색은 White이고 전경색은 Black이다.
- 어플리케이션은 드로잉 작업을 위해 메모리 DC를 사용하기 전에 올바른 사이즈의 비트맵을 DC에 선택(select)해야 한다. DC에 비트맵을 선택하기 위해서 필요한 사이즈와 칼라를 지정하여 CreateCompatibleBitmap 함수를 사용해라.
- 메모리 DC가 생성되면 모든 속성들은 기본 값이 설정된다. 메모리 DC는 일반 DC처럼 사용될 수 있다. 특정 속성을 다른 값으로 지정할 수도 있고 현재 속성들로부터 값을 얻을 수도 있고 펜, 브러쉬, 영역 등을 선택할 수도 있다.
- CreateCompatibleDC 함수는 오직 래스터(raster) 연산을 지원하는 디바이스와 사용될 수 있다. 어플리케이션은 디바이스가 GetDeviceCaps 함수를 호출함으로써 래스터 연산을 지원하는지 여부를 확인할 수 있다.
메모리 DC가 더 이상 필요하지 않을 땐 DeleteDC 함수를 호출해야 한다. - Windows 2000 이후부터는 스레드에서 hDC인자를 NULL로 CreateCompatibleDC를 호출하면 그 스레드에 종속적인 HDC를 생성하여 넘겨준다. 스레드가 종료되면 넘겨받은 HDC는 더 이상 유효하지 않다. 그래서 어떤 스레드에서 HDC를 생성하고 다른 스레드로 넘겨주고 스레드가 종료된다면 다른 스레드에서 넘겨받은 HDC를 사용할 수 없다.
- 인자로 넘겨지는 DC가 Image Color Management(ICM)에 대해 가능하다면, 리턴값으로 받는 DC도 ICM-enabled 이다. 소스와 목적지 칼라 공간은 DC에서 열거된다.
이 글은 스프링노트에서 작성되었습니다.
프로그램을 짜다 보면 HEAP CORRUPTION DETECTED 에러를 만날 수 있다.
이것은 할당한 데로 해제 하지 못했을 경우에 나타나는 에러로 나 같은 경우에는 할당한 이상으로 해제를 한 경우에 나타났다.
COM 작성시 문자열을 다루는데 경우에 주의해야 할 점 중의 하나로
CComBSTR의 인스턴스의 Length()를 사용하여 문자열의 길이를 얻고 이를 Muiti-Bytes로 변환하는 과정에서 에러가 생긴 것이다.
CComBSTR.Length()는 Unicode로 각 문자(영문,한글)을 하나로 취급하여 길이를 반환하는데
이를 받아서 문자열의 길이만큼 char 메모리를 할당한 후 CComBSTR의 문자열을 카피 해 주는 경우 한글이 있을 경우 한글은 Multi-Bytes에서는 2bytes를 차지하므로 CComBSTR.Length()로 받은 길이보다 더 많은 버퍼를 사용하게 된다. 그리고 이를 해제할 경우 HEAP CORRUPTION DETECTED가 발생하였다.
m_FName.AppendBSTR(name);
int len = m_FName.Length();
USES_CONVERSION ;
TCHAR* buf ;
buf = (TCHAR*)malloc(len+1); // MBCS 으로 컴파일시 char로 할당됨.
ZeroMemory(buf, len+1) ;
wsprintf(buf, "%s", W2T(name));
int nLen = _tcslen(buf) ; // 위의 m_FName.Length() 와 다른 값이 나옮
free(buf);

Prev

Rss Feed