2009. 9. 23. 17:31

BitBlt 개념 정리

출처: http://1and0.tistory.com/entry/BitBlt-개념-정리

 

보통 윈도우에서 그리기를 할 때 메모리 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의 전경색과 배경색을 사용한다.
2009. 3. 18. 14:57

Visual Studio 2005/2008에서 WM_INITDIALOG

퍼올라 그랬는데 복사 안되서...

어제 2003을 지우고 2008을 깔았다... 포맷없이 걍 이대로 갈지도.. 귀찮기도 하고 -_-;

아직 VS6.0에 익숙해서 인지... 편하기도 하고 불편하기도 한데

WM_INITDIALOG가 메세지가 아니라 함수 오버라이드 해서 써야한단다..

virtual BOOL OnInitDialog();

해주고

BOOL BlackBox::OnInitDialog()
{
    CDialog::OnInitDialog();

    return TRUE;
}

뭐 이렇게 해주면 되는 식... 클래스 위자드에서 샥샥 해버려서-_-;; 없어지니 좀 불편;;
2009. 3. 18. 14:49

Visual Studio 2005에서 다이알로그의 OnTimer 메세지 함수 추가하기

Visual Studio 2005에는 클래스 위져드가 없어졌다.

다이알로그에서 OnTimer 메세지 함수 추가하려고
그냥 코드에서 OnTimer를 추가해 보았지만 이벤트가 발생하지 않았다. -.-;;
그래서 열심히 찾다 보니까 메세지 함수를 추가하는 방법이 있었다.

먼저 메세지 함수를 추가하려는 다이알로그를 클래스 뷰에서 선택한다.

사용자 삽입 이미지

선택한 다이알로그에서 Alt + Enter를 누르던가
오른쪽 클릭을 해서 속성을 선택하면 아래같이 속성창이 나타난다.

사용자 삽입 이미지

속성창에서 밑에 메세지를 선택하면 메시지 리스트가 표시된다.

사용자 삽입 이미지

WM_TIMER를 선택하면 <추가> OnTimer가 표시되고 <추가> OnTimer를 선택하면
아래 그림과 같이 OnTimer함수가 추가되어진다.


사용자 삽입 이미지

2009. 3. 18. 11:17

[펌] strncpy()와 strncpy_s()에 대한 오해 + snprintf_s() 버그 (_TRUNCATE)

원문 : http://xyz2.net/bbs/zboard.php?id=notes&no=76


strncpy()는 복사되었으면 하는 문자열의 길이를 넘어서지 않게 복사해 준다.
그리고 대상 버퍼를 넘어서게 되면 NULL로 끝나지 않는 문자열까지 복사하게 된다. 예를 들면 아래와 같다.

strncpy(dest, 8, "1234567"); // dest == { '1', '2', '3', '4', '5', '6', '7', NULL }
strncpy(dest, 8, "12345678"); // dest == { '1', '2', '3', '4', '5', '6', '7', '8' }


strncpy_s() 는 대상 버퍼가 실제 수용가능한 크기와 복사되었으면 하는 문자열의 길이 두가지를 넘긴다.
strncpy()와 strncpy_s()의 다른점이 있다면 strncpy_s()는 '복사 되었으면 하는 문자열의 길이'를 넘어서서 복사를 할 때 마지막을 항상 NULL로 끝나게 해준다는 점이다.

다음과 같은 코드는 런타임 에러를 발생시킨다.

// 이 코드는 buf에 1, 2, 3, 4, 5, 6, 7, 8, NULL .. 총 9개의 문자열을 넣으려다가 에러가 나게 된다.
char dest[8];
strncpy_s(buf, _countof(buf), "123456789000", _countof(buf));


따라서 strncpy_s()를 사용할 때는 버퍼 크기와, 복사하고 싶은 길이를 다르게 주어야 한다.

char dest[8];
strncpy_s(buf, _countof(buf), "123456789000", _countof(buf)-1);



참고.

strcpy_s()를 사용하면 버퍼 크기를 넘어서는 데이터를 넘을 때
자동으로 막아준다고 착각하는 경우가 있다. (strncpy처럼)

strcpy_s()에 넘기는 2번째 인자인 dest_size는 '내가 이 정도까지만 복사하고싶다'의 의미가 아니라
'여기 지정한 크기를 넘어서 복사하려고 하면 프로그램을 멈추고 에러창을 띄워라' 의 의미로 보아야 한다.

// 이 코드는 이쁘게 dest에 1234567까지만 복사해 주는 것이 아닌, 프로그램을 뻗게 하는 코드다.
char dest[8];
strcpy_s(dest, _countof(dest), "123456789");


연장해서 sprintf_s() 와 _snprintf_s() 에도 똑같이 적용된다.

sprintf_s(buf, _countof(buf), "%s 1234567", "1212"); // 프로그램 오류를 내는 코드
_snprintf_s(buf, _countof(buf), _countof(buf), "123456789%d", 121212); // strncpy_s()와 같은 이유로 오류를 내는 코드
_snprintf_s(buf, _countof(buf), _countof(buf)-1, "1234567%d", 121212); // 정상적으로 작동하며, 이렇게 써야 하는 코드



* gpg의 비회원님의 내용 추가 - 보충 감사드립니다.

strncpy_s(), _snprintf_s() 함수의 복사하고 싶은 길이(size_t count)에 _TRUNCATE 를 넣으면

수용가능한 버퍼 크기(size_t sizeOfBuffer)에 지정한 값 -1 을 넣은것과 같게 동작한다.

다음 두개의 코드는 결과가 같다.
strncpy_s(buf, _countof(buf), "123456789000", _countof(buf)-1);
strncpy_s(buf, _countof(buf), "123456789000", _TRUNCATE);


** _TRUNCATE와 관련한 버그 안내 (2008-04-02, VS2005 VC8.0.50727.762 - SP.050727.7600 기준)

다음 프로토타입을 갖는 함수에는 count에 _TRUNCATE를 사용해도 된다.
int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );

다음 프로토타입을 갖는 함수의 count에 _TRUNCATE를 사용하면 스택이 깨진다.
template <size_t> int _snprintf_s( char (&buffer)[size], size_t count, const char *format [, argument] ... ); // C++ only

템플릿버전에서는 내부적으로 매크로를 사용하고 있는데 sizeOfBuffer와 count값 두가지가 모두 -1 로 넘어가면서 코드 내부적으로 buffer[(size_t)-1] = NULL; 이라는 코드를 실행하면서 잘못된 메모리를 쓰게 된다.



** 티벳의 독립을 지지하는 아이스닥님이 알려주신 버그 수정법

CRTDEFS.h 파일 열어서
모든 _Size를 _SUCKS_MS_BUG_Size 등 다른 이름으로 수정하면 된다. (원작자 표현 존중)

다만, 자기 컴퓨터의 버그만 고쳐지는 것이므로 되도록 혼자 작업하는게 아니라면 우회해서 사용하는것이 좋겠다.


- 버그내용 설명
stdio.h의 매크로 선언부와 crtdefs.h의 매크로 내용 정의부의 인자이름 _Size가 서로 겹쳐서 발생하는 버그라고 한다.

[stdio.h]
__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST(int, _snprintf_s, _vsnprintf_s, __out_bcount(_Size) char, _Dest, __in size_t, _Size, __in_z __format_string const char *,_Format)

[crtdefs.h]
#define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_2_ARGLIST(_ReturnType, _FuncName, _VFuncName, _DstType, _Dst, _TType1, _TArg1, _TType2, _TArg2) \
    extern "C++" \
    { \
        __pragma(warning(push)); \
        __pragma(warning(disable: 4793)); \
    template <size_t _Size> \
    inline \
    _ReturnType __CRTDECL _FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1, _TType2 _TArg2, ...) \
    { \
        va_list _ArgList; \
        _crt_va_start(_ArgList, _TArg2); \
        return _VFuncName(_Dst, _Size, _TArg1, _TArg2, _ArgList); \

끝.

2008. 7. 24. 13:11

극강 MFC Tips!

2008. 7. 4. 10:17

더블 버퍼링

별거 아니네-_-ㅋ

물론 인터넷 뒤져서 낼름 한거지만...

개념도 그렇고...


2008. 5. 29. 13:27

[펌] VC++를 더욱 막강하게 해주는 ADD -IN Seriese 소개.

1.Visual Assist X

  : 말이 필요없는 Add-in으로 코딩 속도를 높여주는 툴입니다. 2006년 4월 최신 버전을 설치하면 Visual Studio 6, 2002,2003,2005 버전 모두에서 동작합니다. 가격에 비해서 높은 생산성이 있다고 생각합니다.

    URlL = http://www.wholetomato.com


 

2. Devpartner

  : Memory leak 을 잡아주는 boundschecker를 비롯한 몇가지 툴로 구성되어 있는 Add-in 입니다. 특히 boundschecker는 경험이 부족한 프로그래머에게 memory leak에 관해선 상당히 잘 잡아줍니다.  2006년 4월 최신 버전 8.0을 설치하면 Visual Studio 6, 2002,2003,2005 버전 모두에서 동작합니다.  단점은 가격이 비싸다는 것입니다. (Visual Studio 가격보다도 비싼 경우도 있음)

   URL = http://www.compuware.com


 

3. IncrediBuild

   : 컴파일 속도를 높여주는 Add-in 입니다. 프로그램 크기가 크면 클수록 속도 차이가 최고 6배 정도 난다고 합니다. 재미있는 것은 다른 PC에 Agent를 설치해 분산 컴파일링을 할 수 있다는 것입니다. 2006년 4월 현재 안정버전은 Visual Studio 6, 2002,2003에서 동작하면 2005는 RC버전이 있습니다.

     URL = http://www.xoreax.com


 

4. Visual Studio Booster

   : Visual Studio 6.0 전용 Add-in으로 에디터 창에 탭을 추가해줍니다. wndTab 이라는 Add-in과 많이 비슷한데 약간 다른 분위기가 납니다. 기능은 단순히 한번 열기한 소스나 리소스을 탭에 등록시켜주고 종류에 따라 그룹핑 을 해주는 정도입니다. 그런데 한번 써보니 정말 괜찮다는 생각이 듭니다.

     URL = http://www.visual-studio-booster.com


 

이상 4가지가 제가 알고 있는 상용 Add-in 이었습니다.  혹시 제가 소개해 드린것을 제외하고 좋은 Add-in을 알고 계시면 모두가 알수 있게 댓글을 달아 주시면 감사하겠습니다. ㅎㅎ

PS. 위에 있는 Add-in을 1가지 이상 설치할 경우 충돌을 일으킬때가 있었습니다. 제 경우에는 Visual Assist 를 설치한 후 Visual Studio Booster를 설치하니 에러가 발생했습니다. 그래서 Booster를 먼저 설치하고 Assist를 나중에 설치했더니 잘 동작했습니다. ㅎㅎ


 

출처:http://www.kallru.com/blog/1169361615

2008. 4. 21. 09:13

MFC Tips and 에디트 박스에서 엔터키 입력

http://hunpyoa.tistory.com/entry/MFC%EA%B4%80%EB%A0%A8-%EC%9C%A0%EC%9A%A9%ED%95%9C-%ED%8C%81

에디트 박스에서 엔터키 인식...

위 팁엔 Subclassing방법을 소개했는데

에디트 컨트롤이 한두개가 아니라 -0-

http://t1tan1c.tistory.com/entry/%EC%97%90%EB%94%94%ED%84%B0-%EB%B0%95%EC%8A%A4%EC%97%90%EC%84%9C-%EC%97%94%ED%84%B0%EB%A5%BC-%EB%88%8C%EB%A0%80%EC%9D%84-%EB%95%8C

요게 더 간편...

MFC도 땜빵식 야메로 하는거 같아서 씁쓸-_-

인생자체가 야메였어 ㅡ.ㅜ
2007. 12. 10. 15:10

Visual C++을 써서 개발할 때는...

Debug 모드로 개발하다

최종으로 가면 Release 모드로 컴파일하자 -_-

누구냐-_-기본이 Debug 모드인 것을 Release 모드로만 컴파일한 녀석이 -_-+

쌓이고 쌓여서 Debug 모드는 에러가 방방 뜨자나~

수정하지 말까... 쩝 ㄱ-
2007. 7. 9. 08:20

References