'Programming/Windows Programming'에 해당되는 글 11건
- 2009.09.23 BitBlt 개념 정리
- 2009.03.18 Visual Studio 2005/2008에서 WM_INITDIALOG
- 2009.03.18 Visual Studio 2005에서 다이알로그의 OnTimer 메세지 함수 추가하기
- 2009.03.18 [펌] strncpy()와 strncpy_s()에 대한 오해 + snprintf_s() 버그 (_TRUNCATE)
- 2008.07.24 극강 MFC Tips!
- 2008.07.04 더블 버퍼링 2
- 2008.05.29 [펌] VC++를 더욱 막강하게 해주는 ADD -IN Seriese 소개. 1
- 2008.04.21 MFC Tips and 에디트 박스에서 엔터키 입력
- 2007.12.10 Visual C++을 써서 개발할 때는...
- 2007.07.09 References
출처: 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의 전경색과 배경색을 사용한다.
Visual Studio 2005/2008에서 WM_INITDIALOG

어제 2003을 지우고 2008을 깔았다... 포맷없이 걍 이대로 갈지도.. 귀찮기도 하고 -_-;
아직 VS6.0에 익숙해서 인지... 편하기도 하고 불편하기도 한데
WM_INITDIALOG가 메세지가 아니라 함수 오버라이드 해서 써야한단다..
virtual BOOL OnInitDialog();
해주고
BOOL BlackBox::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE;
}
뭐 이렇게 해주면 되는 식... 클래스 위자드에서 샥샥 해버려서-_-;; 없어지니 좀 불편;;
Visual Studio 2005에서 다이알로그의 OnTimer 메세지 함수 추가하기

다이알로그에서 OnTimer 메세지 함수 추가하려고
그냥 코드에서 OnTimer를 추가해 보았지만 이벤트가 발생하지 않았다. -.-;;
그래서 열심히 찾다 보니까 메세지 함수를 추가하는 방법이 있었다.
먼저 메세지 함수를 추가하려는 다이알로그를 클래스 뷰에서 선택한다.
선택한 다이알로그에서 Alt + Enter를 누르던가
오른쪽 클릭을 해서 속성을 선택하면 아래같이 속성창이 나타난다.
속성창에서 밑에 메세지를 선택하면 메시지 리스트가 표시된다.
WM_TIMER를 선택하면 <추가> OnTimer가 표시되고 <추가> OnTimer를 선택하면
아래 그림과 같이 OnTimer함수가 추가되어진다.
[펌] strncpy()와 strncpy_s()에 대한 오해 + snprintf_s() 버그 (_TRUNCATE)

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); \
끝.
물론 인터넷 뒤져서 낼름 한거지만...
개념도 그렇고...
[펌] 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
MFC Tips and 에디트 박스에서 엔터키 입력

에디트 박스에서 엔터키 인식...
위 팁엔 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도 땜빵식 야메로 하는거 같아서 씁쓸-_-
인생자체가 야메였어 ㅡ.ㅜ
최종으로 가면 Release 모드로 컴파일하자 -_-
누구냐-_-기본이 Debug 모드인 것을 Release 모드로만 컴파일한 녀석이 -_-+
쌓이고 쌓여서 Debug 모드는 에러가 방방 뜨자나~
수정하지 말까... 쩝 ㄱ-
Prev
Rss Feed