Notice»

Recent Post»

Recent Comment»

Recent Trackback»

Archive»

« 2024/3 »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

 
 
:
Visual C++ 2005 및 이전 버전의 변경 내용 - MSDN

배포 방법 변경(Redistributable Package - 재배포패키지)과
최신라이브러리 사용
(2008)


1. 2005부터는 배포방법이 바뀌었다.
2. 2008에서는 sp1등의 업데이트를 설치해도 프로젝트 생성시 최신 라이브러리를 기본으로 사용하지 않는다.
 -> _BIND_TO_CURRENT_VCLIBS_VERSION를 미리 선언해야 최신 라이브러리를 사용한다.

위의 두가지 내용은 아래 페이지에 정리해놨음.
VC++ 버전별 배포방법과 재배포패키지(Redistributable Package)

Visual C++ 2005 라이브러리의 변경 사항 - MSDN

CRT 함수의 보안버전
Security-Enhanced Versions of CRT Functions - MSDN

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

버퍼의 길이체크를 하기 위한 _s접미사가 붙는 보안 버전의 CRT 함수가 추가되었다. 사용방법은 기존 함수에 _s를 붙이고 버퍼의 길이를 인자로 더 추가해주면 된다. 당장은 VC에만 존재하지만 앞으로 C++표준에 추가될 수 있다고 한다.

참고사항
1. _s관련 함수는 errno_t를 반환하게 변경되었다.(에러발생)
2. _CRT_SECURE_CPP_OVERLOAD... 관련 3개의 define을 사용하면 버퍼가 배열형일 경우 Template overloads를 이용해서 기존 코드를 자동으로 _s관련 함수로 변경할 수 있다.

Default 값과 설명
_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
  -> secure함수에 길이 인자관련을 생략해준다.
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0
  -> 기존함수 지원 ex) strcpy
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 0
  -> 길이체크하는 기존함수 지원 ex) strncpy


위와같이 편한 방법이 있지만 포인터형의 버퍼변수 일경우는 기존과 같이 길이값을 인자로 넣어야 한다.
char  a[100];                    // 가능
strcpy_s(a, "hello");
char * p = new char[100]; // 불가능
(컴파일 에러)
strcpy_s(p, 10, "hello");

위와 같은 코드는 혼란만 올뿐이다. 결론은 secure함수를 사용할꺼라면 인자값을 사용하지말고 overload함수도 사용하지 말자.

해결방법
_CRT_SECURE_NO_DEPRECATE를 정의하면 secure함수를 사용하지 않는다.
또는
_CRT_SECURE_NO_WARNINGS 나 #pragma warning( disable : 4996 )를 사용해서
경고만 무시한다.

참고
http://blog.naver.com/kyuniitale?Redirect=Log&logNo=40021387400
C/C++ Secure Function 에 대해서
secure function 쉽게 사용하는 팁


POSIX 호환(compliant)
Deprecated CRT Functions - MSDN
warning C4996: 'stricmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp. See online help for details.

ISO C++의 명명 규칙을 준수하기 위해 POSIX 이름이 이제 사용되지 않는다. 예를 들어, getch 대신 _getch를 사용한다.
보안 함수와 똑같은 4996 경고가 뜬다. 표준이므로 지키자.

해결방법(임시)
_CRT_NONSTDC_NO_DEPRECATE를 정의하거나
#pragma warning( disable : 4996 )를 사용한다.

안전한 문자열 함수(strsafe.h)
Using the Strsafe.h Functions - MSDN
안전한 문자열 함수들(strsafe.h)

warning C4995: 'wsprintf': 이름이 #pragma deprecated로 표시되었습니다.

c/c++ 문자열의 오버플로우를 막기 위해 MS가 제공하는 방안으로 strsafe.h를 선언해서 관련 함수를 사용할 수 있다.

해결방법
#define STRSAFE_NO_DEPRECATE를 정의하거나
#pragma warning(disable : 4995)를 사용한다.

time_t
Time Management - MSDN
time_t가 기본 64비트로 변경되었다. (기존 32비트로 3000년까지만 처리 가능했던걸 확장)

실제선언코드
// VC6
// c:\Program Files\Microsoft Visual Studio\VC98\Include\TIME.H

#ifndef _TIME_T_DEFINED
typedef long time_t;        /* time value */
#define _TIME_T_DEFINED     /* avoid multiple def's of time_t */
#endif

/////////////////////////////////////////////////////////////////////////
// VC9(2008)
// c:\program files\microsoft visual studio 8\vc\include\crtdefs.h

#ifndef _TIME64_T_DEFINED
#if     _INTEGRAL_MAX_BITS >= 64
typedef __int64 __time64_t;     /* 64-bit time value */
#endif
#define _TIME64_T_DEFINED
#endif

문제점

이부분은 기존 long형으로 처리되던 부분들이 에러없이 자동으로 64비트로 변경되므로 32비트로 처리되던 코드들은 메모리주소가 밀려서 쓰레기값으로 처리될수 있다.

해결방법(임시)
_USE_32BIT_TIME_T 를 정의한다.
MSDN을 참고해보면 위와 같이 define해놓으면 time_t를 32비트로 쓸수 있다.

사용자 정의(User-Defined) 메세지

User-Defined Handlers - MSDN
아래 내용은 기존에 정의되어 사용되고 있던 것이지만 VC6에서 대충 넘어가던것을 2005부터는 정확하게 사용되어야 하는 것들이다.

1. ON_MESSAGE
MFC에서 사용자 정의 메세지를 사용시 User-Defined Handlers의 원형은 아래와 같은데
afx_msg LRESULT memberFxn( WPARAM, LPARAM );
VC6에선 반환값을 void형으로 선언하고 사용해도 문제가 없었지만 2005부터는 컴파일 에러가 발생한다

해결방법
1.
ON_MESSAGE를 ON_MESSAGE_VOID로 변경한다.
 -> AFXPRIV.H에 선언되어 있는 ON_MESSAGE_VOID를 사용하면 문제는 해결할 수 있지만 AFXPRIV.H파일 자체가 MFC 버젼이 바뀔경우 예고없이 바뀔 수 있는 파일이므로 조심해야하고 위매크로를 사용시 함수의 인자값이 이상하다는 글을 본적이 있으므로 사용시 주의하자. 매크로의 선언은 아래와 같다.(VC6,2008 sp1)
// like ON_MESSAGE but no return value
#define ON_MESSAGE_VOID(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_vv, \
        (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&memberFxn },
2. LRESULT를 반환하게 함수를 변경한다.
 -> 이게 표준이니 이렇게 사용하자.


2. ON_THREAD_MESSAGE
ON_THREAD_MESSAGE - MSDN
CWinThread를 상속한 클래스내에서는 ON_MESSAGE가 아닌 ON_THREAD_MESSAGE를 사용해야한다.
사용법은 동일하지만 함수원형에 반환 값이 없다.
afx_msg void memberFxn( WPARAM, LPARAM );

매크로의 선언을 비교해보자.(AFXMSG_.H)
// for Windows messages
#define ON_MESSAGE(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_lwl, \
        (AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&memberFxn },

// for Thread messages
#define ON_THREAD_MESSAGE(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_vwl, \
        (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&memberFxn },

Visual C++ 2005 컴파일러, 언어 및 도구의 변경 내용

for 루프 범위의 강제 규칙
/Zc:forScope(for 루프 범위의 강제 규칙) - MSDN
/Zc:forScope가 기본적으로 활성화되어 있다. 이부분은 VC6에서 비표준으로 지원 되던 부분의 수정이므로 표준을 준수하자.

해결방법(임시)
속성 -> 구성속성 -> C/C++ -> 언어 -> For 루프 범위 강제 규칙 -> 아니요
또는 #pragma conform(forScope, on) ,
컴파일 옵션에 /Zc:forScope
위방법중 하나를 선택하면 되겠다.

wchar_t
/Zc:wchar_t(wchar_t를 네이티브 형식으로 인식) - MSDN
/Zc:wchar_t가 기본적으로 사용된다.

속성 -> 구성속성 -> C/C++ -> 언어 -> wchar_t를 기본 제공 형식으로 처리 -> 아니요

error C2668(함수 오버로드)
함수 오버로드에 대한 묵시적 형변환을 사용할 수 없다. VC6에선 상관없던 코드가 최신툴에선 error를 발생한다.

error C2668: 'pow' : 오버로드된 함수에 대한 호출이 모호합니다.
error C2668: 'sqrt' : 오버로드된 함수에 대한 호출이 모호합니다.

위의 에러는  double pow(double x, double y)인 pow함수등을 pow(2,2)같이 호출했을때 발생한다. 이때는 형변환을 하거나 숫자뒤에 '.'를 표시해서 실수로 만들어준다. 표준이므로 지키자.

※표준 준수를 더욱 강화하기 위해 pow의 오버로드 double pow(int, int)가 제거되었습니다. - MSDN
-> int형의 인자를 받던 pow함수가 제거되었다. 그리고
_Pow_int라는 템플릿함수가 추가되었다.


VC 프로젝트 기본 설정

WINVER 설정
VC6프로젝트를 2005이상으로 업그레이드시 WINVER 가 정의 되지 않아 Default 값을 설정한다는 메세지를 볼수 있다.

WINVER not defined. Deafaulting to 0x0502 (Windows Server 2003)
-> 2008은 Vista가 기본이다.

VS2005이상으로 프로젝트를 새로 생성시는 stdafx.h에 #include "targetver.h"가 선언되며 이곳에 프로젝트가 최소로 지원하는 플랫폼을 정의해놨다.

참고
WINVER값이 잘못설정되어 있으면 API나 라이브러리에서 윈도우의 버젼이 잘못 설정되어 이상하게 동작하거나 에러가 발생할 수도 있으므로 업데이트 후 WINVER관련을 잘 체크하자.
->_WIN32_WINNT값을 0x0500으로 선언하고 필자의 경우 CFileDilog를 사용하면 error가 발생한다. 이유는 OPENFILENAME구조체의 선언때문인데 아래 링크를 참조하자.
MFC 프로젝트를 Visual C++ .NET 이나 대상 운영 체제에서 Visual C++ 2005 변경 이식 - MSDN

해결방법
Using the Windows Headers - MSDN

What's the difference between WINVER, _WIN32_WINNT, _WIN32_WINDOWS, and _WIN32_IE? (구글번역)
-> 윈도우 버젼관련 매크로가 아래와 같이 진행되어온 과정을 설명해준다.(참고)

WINVER _WIN32_WINNT _WIN32_WINDOWS Product release
0x0400 not used 0x0400 Windows 95
0x0400 not used Windows NT 4.0
0x0410 not used 0x0410 Windows 98
0x0500 not used 0x0500 Windows Me
0x0500 not used Windows 2000
0x0501 0x0501 not used Windows XP
0x0502 0x0502 not used Windows Server 2003
0x0600 0x0600 not used Windows Vista

아래코드를 stdafx.h의 젤 윗부분에 선언해주면 되며 설정값을 변경하고 싶으면 위 MSDN링크를 참고한다.
#ifndef WINVER 
    #define WINVER 0x0400 
#endif                              

#ifndef _WIN32_WINNT  
    #define _WIN32_WINNT 0x0400 
#endif                        

#if (_MSC_VER > 1200) 
    #ifndef _WIN32_WINDOWS 
        #define _WIN32_WINDOWS 0x0410
    #endif
#endif    // _MSC_VER     

#ifndef _WIN32_IE   
    #define _WIN32_IE 0x0400 
#endif                              

Hotfix

912790
http://support.microsoft.com/kb/912790
2005의 버그인데 2008에도 똑같이 존재한다.

ANSI로 인코딩된 소스코드를 VS.NET 2005 (한글판)에서 빌드하면서 발생하는 문제로 일본판의 경우에도 비슷한 문제가 발생하였고 영문판 VS.NET 2005에서는 발생하지 않는 것으로 알려져있다. 그냥 무시해도 무방할 듯 하다.

해결방법
#pragma warning(disable: 4819) // <- 이 부분을 소스에 추가하거나.

2005버전 이상인 경우는 프로젝트 옵션에서
"프로젝트->속성->구성속성->C/C++->고급->특정 경고 사용 안함" 에 4819를 넣어주거나.

'파일->저장 고급 옵션'
"유니코드 - 코드페이지 1200" 형태로 저장하면 된다.


참고
http://blog.naver.com/khs01016?Redirect=Log&logNo=44587778
http://www.killereco.pe.kr/134


99%'s Code
위 정리된 사항을 필자는 아래코드로 헤더파일 하나에 넣고 stdafx의 상위에서 설정해서 사용한다.
sy는 필자 이름이므로 헷갈리지 말자 ㅎㅎ
// syDef.h

#pragma once

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 최소로 지원하는 플랫폼 정의

// Modify the following defines if you have to target an OS before the ones
// specified in the following code. See MSDN for the latest information
// about corresponding values for different operating systems.
#ifndef WINVER                // Permit use of features specific to Windows 95 and Windows NT 4.0 or later.
#    define WINVER 0x0400  // Change this to the appropriate value to target
#endif                        // Windows 98 and Windows 2000 or later.

#ifndef _WIN32_WINNT            // Permit use of features specific to Windows NT 4.0 or later.
#    define _WIN32_WINNT 0x0400    // Change this to the appropriate value to target
#endif                            // Windows 98 and Windows 2000 or later.          

#if (_MSC_VER > 1200)    // VC6 초과
#    ifndef _WIN32_WINDOWS                // Permit use of features specific to Windows 98 or later.
#        define _WIN32_WINDOWS 0x0410    // Change this to the appropriate value to target
#    endif
#endif    // _MSC_VER                        // Windows Millennium Edition or later.

#ifndef _WIN32_IE                // Permit use of features specific to Internet Explorer 4.0 or later.
#    define _WIN32_IE 0x0400    // Change this to the appropriate value to target
#endif                            // Internet Explorer 5.0 or later.

// #include "targetver.h" -> .net툴에서 위코드가 포함된 헤더파일
// http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx - Using the Windows Headers(MSDN)


///////////////////////////////////////////////////////////////////////////////////
// Visual C++ 8이상 세팅

//#define SYUTIL_USE_CRT_SECURE        // CRT 보안관련 함수 사용
#define SYUTIL_NOTUSE_NONSTDC_NO    // POSIX관련 CRT사용안함
#define SYUTIL_USE_32BIT_TIME_T        // time_t를 32비트로 사용함

// VC8(VS2005) 이상 컴파일러설정.
#if defined(_MSC_VER) && (_MSC_VER >= 1400)

    // 최신버젼의 VC라이브러리 사용
    // Redistributing an Application and Binding It to Specific Libraries - MSDN
    // http://msdn.microsoft.com/en-us/library/cc664727.aspx
#    ifdef _BIND_TO_CURRENT_VCLIBS_VERSION
#        undef _BIND_TO_CURRENT_VCLIBS_VERSION
#        define _BIND_TO_CURRENT_VCLIBS_VERSION 1
#    else
#        define _BIND_TO_CURRENT_VCLIBS_VERSION 1
#    endif

    // CRT 보안관련 라이브러리 설정
    // Security-Enhanced Versions of CRT Functions - MSDN
    // http://msdn.microsoft.com/ko-kr/library/wd3wzwts.aspx
#    ifdef SYUTIL_USE_CRT_SECURE
#        define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES            0
#        define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES            0
#        define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT    0
#    else
#        ifndef _CRT_SECURE_NO_DEPRECATE
#            define _CRT_SECURE_NO_DEPRECATE
            //#define _CRT_SECURE_NO_WARNINGS
            //#pragma warning(disable : 4996)
#        endif
#    endif // SYUTIL_USE_CRT_SECURE

    // POSIX관련 CRT 사용
    // Deprecated CRT Functions - MSDN
    // http://msdn.microsoft.com/en-us/library/ms235384.aspx
#    ifdef SYUTIL_NOTUSE_NONSTDC_NO
#        ifndef _CRT_NONSTDC_NO_DEPRECATE
#            define _CRT_NONSTDC_NO_DEPRECATE
            //#pragma warning(disable : 4996)
#        endif
#    endif // SYUTIL_USE_NONSTDC_NO

    // 안전한 문자열 사용(오버플로우 방지)
    // Using the Strsafe.h Functions
    // http://msdn.microsoft.com/ko-kr/library/ms647466(en-us,VS.85).aspx
#    define STRSAFE_NO_DEPRECATE
    //#pragma warning(disable : 4995)

    // time_t 64비트 처리
    // Time Management - MSDN
    // http://msdn.microsoft.com/ko-kr/library/w4ddyt9h.aspx
#    ifdef SYUTIL_USE_32BIT_TIME_T
#        define _USE_32BIT_TIME_T
#    endif // SYUTIL_USE_32BIT_TIME_T

    // 유니코드 형식으로 저장하라는 경고 무시 -> VS 버그임
    // http://support.microsoft.com/kb/912790
#    pragma warning(disable: 4819)
#endif // _MSC_VER



정리중...

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 문자 집합이 기본 유니코드이다.
속성 -> 구성속성 -> 일반 -> 프로젝트 기본값에서 문자 집합 -> 멀티코드 문자 집합 사용

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 런타임라이브러리(CRT)이 기본 /MD, CRT라이브러리에 대해서는 고민해보아야 하고
// 기존라이브러리들과 맞춰주는게 좋다.
속성 -> 구성속성 -> C/C++ -> 언어 -> 런타임 라이브러리 -> /MT

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 비증분 링크
LINK : warning LNK4076: '.\Debug/IIS.ilk' 증분 상태 파일이 잘못되었습니다. 비증분 링크합니다.

프로젝트 -> 속성 -> 링커 -> 일반 -> 증분 링크 사용 -> 아니요(/INCREMENTAL:NO)

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 증분 링크
LNK4075: '/EDITANDCONTINUE'이(가) '/INCREMENTAL:NO' 사양으로 인해 무시됩니다.

프로젝트 -> 속성 -> 링커 -> 일반 -> 증분 링크 사용 -> 예(/INCREMENTAL)

증분링크란?
obj를 합치는과정에서 메모리배치랑 순서 함수들 코드, 데이터 영역등을 계산하게 되는데 이걸 매번 재계산하게되면 시간이 오래 걸리게되죠
그래서 변한건만 재계산하는 과정을 말합니다. 위의 속성은 "증분 링크" 하겠다는거죠.간간히 이전obj가 껴있어 문제가 생기는데
이땐 rebuild all해서 풀링크 하면된다고 하네요 ^^;;
 
http://cafe.naver.com/bit1004/554
http://blog.naver.com/amoros21?Redirect=Log&logNo=140061746992
http://blog.naver.com/blue7water?Redirect=Log&logNo=10051860035
http://hongyver.pe.kr/ttblog/entry/VC6-%EC%97%90%EC%84%9C-VS2005%EB%A1%9C-%EC%98%AE%EA%B8%B0%EA%B8%B0
:
배포시에는 Dependency Walker(depends.exe)와 같은 도구를 사용하여 종속 DLL의 목록을 확인한다. 또한 2005이상의 VS(Visual Studio)는 manifest를 꼭 확인해서 사용한 dll과 버전을 확인해야한다.

VC++ Library
그림 1(VS2005 기준)

그림은 VS2005를 기준으로 하고 있지만 다른 버젼도 위와 같은 규칙으로 명명되고 있다. xx는 각각의 버전을 나타내며 플랫폼 별로 x86,ia64,x64용이 따로 있다. u는 Unicode버전을 나타내고 m은 managed code를 사용했을때 사용되며 배포시 .NET Framework이 필요하다. 배포폴더에 manifest가 존재하면 같이 배포한다.

참고
Visual C++ Libraries as Shared Side-by-Side Assemblies - MSDN


컴파일러와 라이브러리의 버젼을 나타내는 매크로

Predefined Macros - MSDN

_MSC_VER(MS 컴파일러)

  Visual Studio 4.0  1000
  Visual Studio 5.0  1100
  Visual Studio 6.0  1200
  Visual Studio .NET 2002  1300
  Visual Studio .NET 2003  1310
  Visual Studio 2005  1400
  Visual Studio 2008  1500

_MFC_VER(MFC 버젼)

 Visual Studio 6.0   0x0600
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900

_ATL_VER(ATL 버젼)

 Visual Studio 6.0   0x0300
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900


VC 6 이하(~ VS6)
VC6관련 DLL은 98이후부터는 운영체제에 포함되어 있다. 그러므로 현재는 배포시에 거의 문제될게 없다.

참고
ActiveX 배포를 위한 cab파일(MS) - inf파일에 링크를 추가해준다.
Vcredist.exe로 Visual C++ 응용 프로그램용 최신 런타임 구성 요소가 설치된다 - MSDN고객지원

VC 7.1(VS 2003)
VC7.1관련 DLL은 최신 운영체제라고 해서 더는 기본 내장을 해주지않기 때문에 응용 프로그램이 알아서 자기 디렉터리나 윈도우 시스템 디렉터리에다 구비해야 한다.



VC 8이후(VS 2005~)

Side by Side Asembly
2005부터는 side by side asembly라는 기술이 도입되어 VC관련 라이브러리들이 Windows 디렉토리 밑에 WinSxS (Windows Side-by-Side)라는 공유 폴더(native assembly cache)로 관리된다. side by side asembly는 DLL 충돌문제를 해결해서 각각의 어플리케이션에게 독립적인 DLL환경을 제공하기 위한것으로 여러버젼의 DLL들이 등록될수 있다. 복잡한 이과정을 간단하게 해결하는 방법으로 VC8부터는 재배포 패키지(Redistributable Package)라는 배포용 설치파일이 도입되어 공용 라이브러리를 자동으로 설치/등록해준다. 또한 프로젝트에서 자동 생성해주는 Manifest Flie에 사용된 DLL과 버전이 자동으로 입력되니 배포시는 꼭 확인하도록 한다.
프로그래머나 사용자입장에선 관련 DLL을 포함만 하면 되는 기존 작업과 달리 설치파일이 하나 더생겼으니 귀찮은 작업이지만 최신 운영체제의 기본 관리 방법이기도 하고 .Net의 기술과도 무관하지 않으니 지금 정리하도록 하자.


최신 라이브러리를 Manifest에 기술하기(VC9)
배포방법을 알아보기 전에 알아두어야 할사항이 있다. VC9는 VC8과 달리 sp1같은 최신 라이브러리를 개발자PC에 설치했다고 해도 프로젝트가 최신라이브러리를 사용한다고 명시해주지 않으면 기존라이브러리를 기본으로 사용하므로 주의해야한다. 이것은 개발자가 sp1을 설치했어도 프로젝트는 기존 DLL버전을 사용하므로 배포시 sp1용 재배포 패키지를 사용하면 제대로 실행될 수 없음을 나타낸다. 방법은 아래와 같다.

'_BIND_TO_CURRENT_VCLIBS_VERSION'를 프로젝트 설정에서 선언해준다.
-> stdafx.h의 상단에 #define으로 입력해도 일반적인 프로젝트에선 상관없지만 프리컴파일드 헤더를 사용안하거나 외부라이브러리가 프로젝트에 미리 세팅되었을 경우 두개의 버전을 중복 사용하는 경우가 발생할 수 있으므로 프로젝트 설정에서 선언하길 권장한다. 이값은 CRT,MFC,ATL,OPENMP 4개의 '_BIND_TO_CURRENT...' 선언을 다 쓰겠다고 선언하는것이고 _BIND_TO_CURRENT_VCLIBS_VERSION의 기본값은 0으로 세팅되어있다.


참고

응용 프로그램 재배포 및 특정 라이브러리에 바인딩 - MSDN

최신 라이브러리를 메니페스트에 기술하기


배포방법
그림1과 참고에 MSDN링크가 2005의 공용DLL 목록과 설명이다. side by side asembly로 인해 배포문제가 좀 복잡해져서 depends 만을 확인해서 관련 DLL을 포함한다고 제대로 실행된다는 보장을 받을 수 없게되었다. 일반적인 방법과 재배포 패키지를 사용하는 방법을 알아보자.

1. 정적 라이브러리(Static Library)를 사용한다.
실행파일이 커지긴 하나 제일 간단하다. MFC 라이브러리를 사용시는 MFC라이브러리를 정적으로 포함하면 CRT도 자동으로 /MT로 변경된다. 용량은 기본 MFC 다이얼로그 프로젝트가 52k정도에서 308k 정도로 커진다.
ATL과 OPENMP까지 사용한다면 웹에서 배포되는 ActiveX 같은 상황이면 용량때문에 고민해봐야할 문제이고 정적라이브러리도 동적라이브러리와 똑같다고는 하지만 몇가지 버그가 있으므로 주의하자.

참고
MFC Static으로 소켓사용시..

2. Manifest를 참조해서 기본 DLL을 배포한다.(Private Assembly)
배포방법이 바뀌었다곤 하나 관련 DLL을 포함해서 배포할수도 있다. VS의 설치폴더에 있는 공용DLL(Private Assembly)을 같이 배포하면 된다. 우선 Manifest로 사용한 DLL을 확인한후 "..\Microsoft Visual Studio X\VC\redist\"에서 관련 DLL(그림1참고)을 프로젝트 폴더에 포함한다. 이방법도 쉬운편이긴 하나 3MB정도의 크기인 재배포 패키지에 비하면 사용하는 라이브러리가 많을 수록 용량이 너무 큰편이다.(기본 CRT와 MFC라이브러리만 4.76MB - 2008sp1 기준)

3. 인스톨쉴드(Install Shield), 설치 프로젝트를 이용해서 재배포 패키지가 자동으로 설치되게 한다.
 -> 모든 프로젝트를 이렇게 만들긴 좀 귀찮다;;

4. .Net Framework(최신)를 설치한다.
.Net Framework를 설치하면 CRT관련 DLL만 같이 설치된다.(fx 3.5설치시 8.0과 9.0이 같이 설치됨)
managed로 컴파일했다면 .Net Framework는 필수이므로 고민할 문제가 아니지만 용량이 100메가도 훨씬 넘는다..;;

5. 재배포 패키지 - 아래에서 따로 설명한다.

위 방법 외에도 몇가지가 더 있으며 아래링크를 참조하기 바란다.
RedistributingVisualCppRunTimeLibrary
Bootstrapper for the VC++ 2005 Redists (with MSI 3.1) - codeproject

재배포 패키지(Redistributable Package)
재배포 패키지는 Windows Installer 3.1을 필요로 하는 인스톨 파일이다. 한번 실행하기만 하면 자동으로 설치되지만 사용자 입장에선 불편한 사항이다. 하지만 Windows Installer의 Command line을 이용해서 몰래설치하는 방법이 있다. 이를 이용해서 런처형식의 프로그램을 만들면 Windows Installer 3.1의 설치유무와 재배포 패키지 자동 설치를 하고 프로그램을 실행하게 할 수 있다. 좀더 범용적으로 사용하면 파일로 설치필요 설정값을 받아와서 COM관련 등록이나 웹배포시 ActiveX등록등을 자동으로 하게 만들수도 있다. 관련 소스가 정리되는 대로 블로그에 올리도록 하고 우선 VC6으로 재배포 패키지의 설치유무와 자동 실행하기 위한 코드를 설명하겠다.

1) 재배포 패키지 설치 유무 확인
재배포 패키지는 설치폴더에서 받거나(..\Microsoft Visual Studio X\SDK\v2.0\BootStrapper\Packages\vcredist_x86) 아래 링크를 통해 MS의 다운로드에서 받는다.

2-1) 일반 적인 인스톨러 사용처럼 추가/제거 목록에 표시되므로 레지스트리 값으로 확인할 수 있다.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ProductCode"

2-2) MsiQueryProductState API를 이용해서 확인한다.
리턴값으로 INSTALLSTATE_DEFAULT인지만 확인하면 설치유무를 판단할 수 있다.

위 2개의 방법에서 모두 필요한 ProductCode는 아래와 같다.

Visual C++ 2005 runtime files

Visual C++ 2005 SP1 runtime files

Visual C++ 2008 runtime files

Visual C++ 2008 SP1 runtime files

위코드는 영문 버전이고 한글버전은 다르고 설치시 중복될수 있다. ProductCode와 추가/제거에 표시되는 이름외에 다른점은 없다. 참고로 2008 sp1 x86 한글버전은 {887868A2-D6DE-3255-AA92-AA0B5A59B874}이다.
Window7에서도 테스트 했음.

참고
How to detect the presence of the VC 8.0 runtime redistributable package
How to detect the presence of the Visual C++ 9.0 runtime redistributable package
NSIS로 VC8.0 Redistributables 체크방법
MsiQueryProductState를 통한 VC 2005 Redistribute 라이브러리 설치체크 방법


2) 재배포 패키지 몰래 설치하기(Command Line)
명령행으로 실행시 Windows Installer 로 만들어진 패키지는 /?로 명령어 종류를 볼수 잇다.

VS2005
VC2005의 경우는 재배포 패키지가 VS기본 폴더에 존재하는 설치파일과 웹에서 받은 파일이 좀 다른데 웹에서 받은 재배포 패키지의 경우 압축이 한번더 되어있어서 인자값 설정 방법이 다르다. 또한 압축이 몇번에 걸쳐 되어있으므로 한글로 계정이 되어있어 한글 경로가 있을 경우 잘 설치가 안될수도 있다. 필자는 2008을 사용하므로 2005에 대한 사항은 관련 링크로 정확한 정보를 얻자.
How to perform a silent install of the Visual C++ 8.0 runtime files (vcredist) packages
- VS기본 폴더에 포함된 재배포 패키지 설치
VC 8.0 런타임 (vcredist) 패키지 몰래 인스톨하기 - 웹에서 받은 재배포 패키지 설치(번역)
Visual C++ 2005 재배포 패키지가 설치안될때



VS2008
2008에서는
<full path>\vcredist_x86.exe /qb
<full path>\vcredist_x86.exe /qb!
<full path>\vcredist_x86.exe /q   -> 화면에 전혀 보이지 않음
위 3가지 방법중 선택해서 사용하면 되며 Vista이상의 경우는 /q로 설정해도 UAC가 보이므로 필자는 /qb!를 사용한다. 직접 사용해보고 판단하자.

참고
How to perform a silent install of the Visual C++ 2008 redistributable packages

99%'s Code
위 재배포 패키지 몰래설치하기 코드를 간단하게 정리했음.

1. 설치유무 판단후 재배포 패키지를 설치하고 원하는 파일을 실행한다.
 // 2008 sp1
    CString csProduct = "{887868A2-D6DE-3255-AA92-AA0B5A59B874}";  
//{9A25302D-30C0-39D9-BD6F-21E6EC160475}

    INSTALLSTATE t = MsiQueryProductState(csProduct);
    if(INSTALLSTATE_DEFAULT != t)
    {
        AfxMessageBox("재배포 패키지를 설치하겠습니다.");
 //    WinExec("vcredist_sp1_x86.exe /q",SW_SHOW);
        WinExec("vcredist_sp1_x86.exe /qb!",SW_SHOW);
        AfxMessageBox("설치 완료");
 // xp에선 설치완료후 정확하게 뜨지만 Windows7에선 완료되지 않았는데 뜬다.
    }
    else
        AfxMessageBox("이미 설치됨");
  
    // 아래 레지스트리값의 유무로 판단할수도 있다.(win7에서도 똑같다.)
    //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{887868A2-D6DE-3255-AA92-AA0B5A59B874}
  
    while(INSTALLSTATE_DEFAULT != MsiQueryProductState(csProduct))
        Sleep(30);
    WinExec("test.exe",SW_SHOW);    // 원하는 프로그램 실행
2. 제거
    WinExec("vcredist_sp1_x86.exe /qu",SW_SHOW);
    AfxMessageBox("제거 완료");

:
Profile - 분석표라고 정의하는게 맞는것 같다.

Visual C++ Profiling

Visual C++에서는 함수별 실행 시간, 수행 횟수 비율 등 다양한 기능을 보여주는 프로파일링 기능을 제공한다. 참고로 자바에서는 JProfiler, UNIX/Linux에서는 gprof라는 프로그램이 있다.

사용방법

1. Project Setting(Alt+F7) 에서 Ling탭의 Enable profiling을 체크한다.

3. Rebuild(재빌드)한다.

4. Build -> Profile을 선택한다.

5. Profile에서 원하는 값을 선택후 OK를 누른다.

6. 프로그램을 실행후 종료하면
Output창에 Profile이 선택되어 결과가 출력된다.


※ Window2000에서 profile 메뉴가 활성화되지 않는 문제점

Visual Studio가 설치될 때 Profile과 관련된 레지스트리 정보를 HKEY_CURRENT_USER 아래에 써넣는다. 그래서 Visual Studio를 설치할 때 사용했던 계정으로 로그인하지 않으면 profile이 활성화되지 않는다.

이를 해결하려면 VC를 설치할 때 접속했던 계정으로 로그인을 하던가, 아니면 레지스트리에 값을 써넣어주면 된다. 메모장으로 아래의 내용을 복사한후 *.reg파일로 저장한다.(파일이름은 상관없음)

    REGEDIT4
    [HKEY_LOCAL_MACHINE\Software\Microsoft\DevStudio\6.0\General]
    "ProfilerInstalled"=dword:1

이 파일을 더블클릭하면 레지스트리에 값이 써지고 VC에 profile 메뉴가 활성화된다.

이 정보는 MSDN에서 Q224382로 찾아보시면 되겠다.


수행시간 측정

1. clock()
ANSI C 함수이며 time.h에 정의되어 있어 UNIX/Linux에서도 잘 수행된다.
현 프로세스가 실행한지 얼마 되었는지에 대한 CPU 시간을 clock tick의 개수 단위로 반환해준다.

#include "time.h"

// 시작
clock_t beginTime;
clock_t endTime;
beginTime = clock();

// 작업 수행

// 수행 종료
endTime = clock();

// 값 출력
CString tmp = _T("");
tmp.Format("작업 수행 시간 - clock() : %5.3f",
           (double)(endTime - beginTime) / CLOCKS_PER_SEC); 

2. timeGetTime(), GetTickCount()
1/1000초 단위로 정확하게 제어할 수 있는 타이머가 바로 멀티미디어 타이머이다. 자세하게 말한다면 Timer Event Callback Notification 메커니즘을 적용하고 있는 타이머이다. 이 멀티미디어 타이머의 단점은 많이 사용할수록 시스템에 상당한 부하를 일으키며, 이외에 제대로 사용하지 못하면 예측할 수 없는 결과가 초래된다고 알려져있다. 이 타이머는 수행 시간 기준으로 일정한 시간이 되면 어떠한 행동을 취하는데 사용된다.
GetTickCount() 함수와 timeGetTime() 함수의 차이점은 운영체제의 정밀도에 차이가 있다. 예를 들어 GetTickCount()함수는 윈도우 9X에서는 기본으로는 약 55 밀리 초이지만, timeGetTime() 함수는 윈도우 9X에서는 1밀리 초이다. 따라서 부정확해질 수 있다. 그러므로 결국 timeGetTime()을 사용하는 게 유리하다. 다만 두 함수는 윈도우 2000, XP등 으로 올라갈수록 정밀도가 현격하게 벌어지게 된다. 따라서 최소의 타이머 해상도를 결정하는 timeBeginPeriod()함수와 timeBegindPeriod에 의해 만들어진 타이머 해상도를 제거하는 timeEndPeriod() 함수를 추가해 줌으로써 정밀도를 보정해 줄 수 있다. 정확한 시간을 구하지 않는 다는 가정 하에서는 두 함수 중에서 편한대로 선택한다.

#include "Mmsystem.h"
#pragma comment(lib,"winmm.lib")

// 시작
timeBeginPeriod(1);
DWORD tStart,tEnd;
tStart = timeGetTime();
// tStart = GetTickCount();

// 작업수행

// 수행 종료
tEnd = timeGetTime();
// tEnd = GetTickCount();
timeEndPeriod(1);

// 값 출력
CString tmp = _T("");
tmp.Format("작업 수행 시간 - timeGetTime() : %5.3f", (tEnd-tStart)/1000.0); 
 
3. QueryPerformanceCount()
초당 증가값을 주파수(frequency)라고 한다면, 그 값을 구하며 부팅 후 절대로 변하지 않는 방식을 적용한 QueryPerformanceCount() 함수는 7~8백만분의 1초까지 더 정밀하게 구하기 위해 사용한다.
 
// 시작
LARGE_INTEGER frequency, tStart, tEnd;
QueryPerformanceFrequency( &frequency );
QueryPerformanceCounter( &tStart );

// 작업 수행

// 수행 종료
QueryPerformanceCounter( &tEnd );
double tElpased =  \
(double)(tEnd.QuadPart - tStart.QuadPart)/(double)frequency.QuadPart;

// 값 출력
CString tmp = _T("");
    tmp.Format("작업 수행 시간 -  QueryPerformanceCounter() : %5.3f", tElpased); 

CRunTimeChk


위에서 소개한 clock,
QueryPerformanceCount
를 각각 사용해서 수행시간을 체크하는 클래스이다.


참고
CxImage를 이용한 Visual C++ 디지털 영상처리(정성호,이문호) - p.106
:

Visual Studio ATL 보안 업데이트

Microsoft Visual Studio 2008 서비스 팩 1 보안 업데이트에 대한 설명: 2009년 7월 28일

Active Template Library Security Update for Developers

2009년 7월 30일 MS 긴급 보안공지 - 찌롱님 정리

M$가 Visual Studio 2003~2008을 위한 ATL관련 보안 업데이트를 발표했다. 아래 링크와 해당 버젼이 다를경우는 아래 관련 링크에서 원하는 툴의 버젼을 찾을 수 있다.(서비스팩에 따른 버젼 제공)
Visual Studio 2008 Service Pack 1 ATL Security Update

위 업데이트를 설치하면 VC가 사용하는 CRT,MFC,ATL등의 DLL버젼이 달라진다.
재배포 패키지(Redistributable Package)
Microsoft Visual C++ 2008 Service Pack 1 Redistributable Package ATL Security Update

설치가 잘 안될경우 아래 링크를 참조하자.
Hotfix KB 971092 for Visual Studio 2008 SP1 install problems

설치후 컴파일 에러가 날경우
Visual Studio 2008의 ATL 보안업데이트 이후 발생하는 컴파일 에러 문제

2005부터는 재배포패키지라는 개념이 도입되어 배포방법이 까다로워(?) 졌다. 서비스팩이 업데이트 될경우 재배포 패키지 또한 변경해줘야한다. 사용자 입장에선 이게 좀 불편한편인데.. 물론 대상 컴퓨터가 x86의 일반적인 CPU를 사용하는 환경이라면 재배포 패키지에서 사용하는 DLL만 가져온후 같이 배포하면 이문제가 거의 대부분 해결되기는 한다.

하지만 이번에 업데이트된 프로그램 배포시는 재배포 패키지가 항상 필요할 듯 하다. 아래 내용참고.

재배포 패키지의 DLL 버젼(VS 2008 기준)

9.0.21022.8 - 2008 기본 버젼

9.0.30729.1 - sp1

9.0.30729.4148 - sp1에 ATL관련 보안 업데이트시


Manifest에 명시되는 사용 DLL버젼
- crt와 mfc 기본만 사용할 경우.

기존 sp1 프로그램
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
9.0.30729.1 버젼의 crt와 mfc라이브러만 명시되어 있음.

sp1에 ATL 보안 업데이트시
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
9.0.30729.1과 9.0.30729.4148 CRT를 둘다 필요로 한다. 버젼은 달라도 CRT의 이름은 다르므로 DLL만 포함하면 실행이 안된다. 그러므로 일반적으로 dll을 포함하던 방법으론 프로그램이 제대로 실행되지 않을 것이다.

배포할 일에 많은 개발자가 아무생각없이 자동 업데이트 했다가는 사무실이 뒤집어 질꺼다;(필자의 경험담? ㅡ.ㅡa)

ATL 보안업데이트 삭제

위와 같이 바뀌어도 인스톨쉴드에 파일 하나만 바꾸면 되는거 아니나는 분들에겐 할말 없지만 조금이라도 불편해서 삭제하고 싶은 분들은 참고하기 바란다.(아래는 필자의 경험담이며 공식문서 확인시 변경될수 있다)

위 보안 업데이트를 삭제하는 방법은 공식 문서에는 프로그램 추가/삭제에서 제거 해주면 된다고 명시되어 있다. 하지만 재배포 패키지 관련 업데이트만 목록에 존재하며 삭제를 해도 VS와는 전혀 상관없다. 윈도우 복원을 날짜를 되돌려도 설정은 바뀌지 않는다. 그래서 필자가 택한 방법은 VS를 전체 삭제하고 재설치 하는거였다 ㅡ.ㅡ; 전체삭제하고 재설치를 해도 기본 설정값들은 전부 남아있어서 크게 불편한점은 없었고 안전하게(?) 이전 버젼의 DLL을 사용한다.

위방법 적용후 필자의 결론은 추가/제거에서 관련 업데이트를 삭제후 기존에 사용하던 서비스팩만 재설치해도 문제가 해결될꺼같다는 거다.


인스톨에 대한 거부감과 DLL업데이트후 재배포 패키지를 설치해야된다는 말에 지대로 거부감 날려주신 클라이언트로 인해 이번업데이트에 대해 정리해본다. 사실 별 내용은 아닌데 결론은 개발자용 PC에 아무리 중요한 업데이트라도 아무생각없이 막 설치해서는 안된다는거다.(응?)

원본 글
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNO=20&no=8351&page=1

:
Visual Studio관련 다운로드
(서비스팩,재배포,Platform SDK,Windows SDK,DirectX SDK)


Microsoft Download 링크입니다.

아래 링크는 자주 바뀌므로 링크가 없을시는 이름으로 검색하시면 됩니다.

64-bit 모드는 x86페이지를 따라가서 받자. 페이지가 너무 길어짐;;

Microsoft Windows SDK Blog

Windows SDK MSDN Developer Center
Windows SDK -> Platform SDK + .Net로 이름이 변경됨.

DirectX Developer Center


※ ATL관련 긴급보안 업데이트 관련 내용은 따로 정리했음. (2003~2008 sp1까지 해당됨)
Visual Studio ATL Security Update

VC 9.0(VS2008)

설치 순서 (SP1을 SDK보다 먼저 깔면 CRT라이브러리가 최신버젼으로 적용안됨)
SDK -> SP1 -> ATL

Windows® SDK for Windows Server® 2008 and .NET Framework version 3.5
- Windows Server® 2008와 .Net3.5를 위한 최신 버젼(2009년 4월 30일 기준으로 window7용 sdk가 나왔지만 아직은 beta)

Microsoft Visual Studio 2008 서비스 팩 1(iso)

MSDN Library for Visual Studio 2008 SP1 (2008년 12월 버전)

Microsoft Visual C++ 2008 SP1 재배포(Redistributable) 가능 패키지(x86)


VC 8.0(VS2005)

Windows® Server 2003 R2 Platform SDK Full Download
- 이버젼 이후로 Windows SDK로 변경, 2003(마지막),2005지원

Microsoft® Windows® Software Development Kit Update for Windows Vista - 2005 sp1이상

Microsoft® Visual Studio® 2005 Team Suite 서비스 팩 1


Microsoft Visual C++ 2005 SP1 재배포(Redistributable) 가능 패키지(x86) - 2.6MB




VC 6

Platform SDK february 2003
VC6 지원 마지막 버젼

DirectX SDK : DirectX 9.0 SDK Update - (Summer 2004)
VC6 지원 마지막 버젼

Visual Studio 6.0 Service Pack 6

Visual Studio 6.0 Service Pack 5 - Processor Pack을 깔기위해선 서비스팩 5가 필요함

Processor Pack -  인텔의 MMX 함수를 사용하기 위해 꼭 깔아야 한다. 코덱등의 작업을 하려면 필수.

Microsoft Visual C++ 6 배포


참고
최근 Microsoft® Windows® Software Development Kit (MS Windows SDK) 릴리즈 기간에 대한 상념

:
1. 소개

  Feature Pack은 2008 sp1부터 추가된 BCGSoft의 MFC확장 라이브러리이다.
office2007의 Ribbon UI가 포함되어 있어 출시전부터 기존 mfc코드처럼 office의 소스도 볼수 있는거 아닌가 하는 개발자들의 기대와는 다르게 상용 라이브러리를 사서 MFC에 확장형식으로 넣어버렸다. (당근 소스까지)

기존 MFC 사용라이브러리중에 CodeJock의 XTP를 더 선호하는 사람이 많아서 그런지 아쉬워 하는 사람도 많은 것 같다.

상용이 공짜가 됐다는 거에 일단 무조건 떙큐~!


M$도 욕좀 먹었나보다. 그래서 라이브러리들을 추가한건 좋은데 sp1에 추가된 Feature Pack이나 TR1이 전부 외부에서 사온거라고 하니 역시 눈가리고 아웅인가? ㅡ.ㅡ; 어쨌든 그래도 필자는 반갑다.


2. 준비

sp1을 먼저 깔고 프로젝트 생성시 _BIND_TO_CURRENT_VCLIBS_VERSION를 전처리기에 선언하면 sp1라이브러리를 사용하게 된다. 당연히 배포할때는 2008 sp1용 재배포패키지로 배포해야된다.

아래 sp1용 샘플코드가 있으니 받아서 참고할것.(Peature Pack 폴더)
Microsoft Visual C++ 2008 SP1 Sample Library

MSDN은 web에선 MFC Feature Pack for Visual C++ 2008 이곳을 참조하면 되며 로컬에선 sp1이 적용된 msdn을 설치해야된다. sp1을 설치할때 같이 설치하자.

3. 리본 UI 라이센스

이 UI를 사용하는 오피스의 5가지 제품의 경쟁제품이 아니어야 한다.("we don’t want to be in the position of having to compete against our own innovation and IP"라고 이유를 듭니다). 출처

Office UI Licensing

결론은 리본 UI를 쓰고 싶으신 분은 마음대로 쓰셔도 되지만 오피스 경쟁 제품 개발할 때는 쓰지말자.


4. 참고

Ribbon? Ribbon! - An Innovative User Interface 리본 UI에 대해 분석해주셨다.

[MFC]Visual C++ 2008 Feature Pack 예제 - VC++2008 Example Feature Pack예제 코드를 캡쳐해서 올려주셨다.



MFC Hierarchy Chart 9.0 (sp1적용, 화면이 짤리면 다운받거나 링크를 따라가서 보자.)

The three hierarchy charts in this topic include classes that were added to the MFC Library as part of the Visual C++ 2008 Feature Pack.

The following illustration represents the MFC classes derived from CObject:

MFC Classes Derived From CObject

The following illustration represents the MFC classes derived from CWnd and CCmdTarget:

MFC Classes Derived From CWnd or CCmdTarget

The following illustration represents the MFC classes not derived from CObject:

Bb982033.MFCnotderivedCObject(en-us,VS.90).png

You can download the complete chart from the following location: http://go.microsoft.com/fwlink/?LinkId=112301.



:
설명
http://bit1010.tistory.com/47

아래코드를 초기화용으로 한번 호출하자.
MFC라이브러리 버그란다. 2008에서도 해결안됐더라..
  void SocketThreadInit()
   {
   #ifndef _AFXDLL
   #define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
   #define _afxSockThreadState AfxGetModuleThreadState()

      _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
      if (pState->m_pmapSocketHandle == NULL)
         pState->m_pmapSocketHandle = new CMapPtrToPtr;
      if (pState->m_pmapDeadSockets == NULL)
         pState->m_pmapDeadSockets = new CMapPtrToPtr;
      if (pState->m_plistSocketNotifications == NULL)
         pState->m_plistSocketNotifications = new CPtrList;

   #endif
   }
:

WinExec, FindWindow..

프로그래밍/Win32 API & MFC | 2009. 4. 16. 01:16 | Posted by 99%

WinExec는 실행되는 프로그램이 초기화 될때까지 기대리게 만든다. CreateProcess에선 뭔가 설정이 있을듯 한데..

Dialog에 OnInitDialog에서 별짓 다하고;; 쓰레드도 생성했더니
WinExec호출한 프로세스가 한참을 멈춰있더라 ㅡ.ㅡ;;


잘생각해서 쓸것;


///////////////////////////////////////////////////////


FindWindow도 마찬가지로 간단한 함수지만!!

첫인자를 사용안할시 무심코 ""라고 입력하면;;

절대 제대로 돌아가지 않는다. 뭔말인지 알지? ㅡ.ㅡ;

: