이 Visual Source Safe(이하 VSS)는  Visual C++(이하 VC) 또는 Visual Studio(이하 VS)를

디폴트로 설치할 때 늘 같이 설치되는 Application 입니다.

이 프로그램의 역할을 잘 알지 못하는 사람이 대부분 이여서 설치되어 있어도 그냥 방치하거나

VS을 설치할 때 Custom을 선택해서 설치 옵션에서 빼버리기도 합니다. 하지만 조금만 내용을 아시게 되면 이 프로그램을 꼭 설치할

수 있게 됩니다. 일단 VSS를 설명하기 전 소스 버전 관리라는 것을 먼저 알려드려야 할 것 같습니다.

 

1. 소스 버전 관리 (Source Version Management)

하나의 Application을 만들 때 많은 개발자가 함께 개발을 하게 됩니다. 다양한 사람들이 다양한 생각을 가지고 소스를

다루게 되죠. 이 때 소스의 많은 부분이 붙었다가 떼어졌다가 하게 됩니다. 일부분이 수정되어 지기도 하고 일부분이 추가 되기도

하죠. 물론 회사 나름대로의 정책을 세워 만들어 나가 정리할 수 있겠지만, 악의가 전혀 없는 한 개발자의 실수로 만든

프로그램이 실행도 안되게 만들 수 있겠죠. 이런 것이 누적되었으면 누가 어디를 수정했는지 알 수 없게 되고,

그 실수한 사람이 원래대로 돌릴 수 없는 불상사가 벌어지게 됩니다.

이런 문제를 발생하지 않게 하기 위해 하는 방법이 버전 관리입니다.

즉 소스에 변화가 발생된 시점을 나누어 해당 소스를 저장해 놓는 것이죠. 그래서 변화된 것이 이상이 없는지 확인한 후

버전 대로 Release를 하게 되는 것입니다. 만일 문제가 생겼으면 이전 버전을 다시 돌려놔서 문제가 발생한 부분을 적절하게

고치고 문제가 발생시킨 개발자에게 응징(?)을 날리죠 ^^;;;;;

여러 가지 Application 의 About를 보시면 (V.11.516.589) 이런 것을 보실 수 있을 텐데 이게 바로 Release 버전을 말합니다.

즉 소스에서 버전을 매기고 만든 결과 입니다. 물론 해당 회사의 버전 정책에 따라 틀리겠지만 일반적으로 다음을 말합니다.

11번의 큰 틀의 변경과 516번의 주요 모둘 변경, 그리고 516번째에서 589의 작은 변경을 한 것이죠.

 

대충 이 정도로 하도록 하죠. 버전을 나누는 방법은 상당히 전문적인 내용이 될 수 있습니다.

특히 그룹단위 프로그래머 팀에서야 엄청난 정책이 난무하게 되죠.

하지만 여기는 제목을 보시면 아시겠지만, 혼자 짜는 Application 을 위한 VSS 입니다 ^^;

그러므로 이 기준은 자신이 알기 편하게 나누시기 바랍니다 단순 소스 변화에서도 넣으셔도 좋고, 굵직한 모듈을

붙이고 떼셔도 무방합니다.

 

2. About VSS

일단 버전 관리라는 것을 대략적으로 대충은 아셨으리라 봅니다.

그럼 이 VSS란 무엇일까요? 바로 그 버전 관리를 편하게 도와주는 툴입니다.자동으로 버전을 매겨주고

그 정보를 자동으로 보관해줍니다.게다가, MS에서 만든 것이라서 MS에서 만들어진 개발 툴 모두를 지원합니다.

하지만 워낙 가볍게 만들다 보니 큰 단위의 프로젝트에서 보다는 중,소 규모의 팀 단위 작업에 보통 이용됩니다.

(MS에 다니시는 분들은 다른 툴을 쓰시는 지... 아니면 여러 개의 VSS를 연결해서 쓰시는 지는 잘 모르겠습니다 ^^;;)

워낙 VC 나 VB같은 MS 제품은 VSS에 연계가 잘돼서 상당히 편하게 작업할 수 있게 됩니다.

보통 설치되면 프로그램 메뉴 안에 "Microsoft Visual SourceSafe" 안에 있게 됩니다.  

 

3. 그럼 VSS이 왜 필요할까요?

버전 관리에 여러 사람이 붙어서 개발할 때는 쓸모가 있겠지만,

과연 홀로 프로그래밍하는 사람에게 이 버전 관리 도구가 필요할까요? 라는 반문이 올지 모르겠습니다.

물론 1000 라인 이하의 Source나 2~3개의 Class로 충분히 Application을 만든다면 별 필요는 없을 것입니다.

되려 번거럽기만 하겠죠. 단순히 Source내에 주석만으로 충분히 Version 관리를 수행할 수 있기 때문이죠.

그러나 그 이상의 규모의 Application을 짠다고 한다면, 이야기가 틀려지게 됩니다.

 

VC로 제작하다 보면 Wizard로 소스가 자동으로 생성되고 거기에 자신의 소스를 붙이기 시작합니다. 그러다

이런 저런 생각이 치밀어 올라 CodeProejct 나 CodeGuru 같은 데서 이런저런 소스를 퍼와서 적용하기 시작합니다

그렇게 이곳 저곳을 고치고 난 뒤 다른 곳에서 빌려온 소스를 추가 했습니다.

경험이 있으신 분은 아시겠지만, 처음에는 잘 되다가 어느 순간부터 생각 치도 못한 오류가 발생하기도 합니다.

다행이 늘 소스를 백업을 했다면 다행이지만, 그렇지 않다면 슬슬 문제가 돌출하기 시작합니다.

어디를 고치고 어디를 삭제하고 어디를 추가했는지 모르기 때문에, 전부 실행하면서 Trace를 하게 되고

그 문제점을 찾기에 여념이 없게 됩니다.

그러면서 혼자 "아.... 백업을 충실하게 할걸...." 이라고 한숨을 쉬며 후회를 합니다.

 

이럴때 버전관리를 하고 VSS를 이용하면 손쉽게 위의 문제를 벗어날 수 있게 됩니다. 버전을 되돌려 가면서 어디서 부터는 제대로 돌아갔다는

것을 알기 시작하면 손쉽게 처리 되기 시작합니다. 그리고 그 당시로 소스를 되돌려 찬찬히 다시 작업을 할 수 있겠죠.

지금 부터 홀로 프로그램을 짜시는 분들을 위해 VSS를 설명하기로 하겠습니다.

 

아, 먼저 이 강좌를 실천하려면 VSS가 필요하므로 만일 VSS가 설치되지 않았다면 Visual C++ / Visual Studio 시디로

프로그램 추가/삭제 를 통해 VSS를 설치해 주시기 바랍니다.

VSS를 설치했으면 다음과 같은 메뉴를 보실 수 있습니다.



Analyze & Fix VSS DB, Analyze VSS DB, Microsoft Visual SourceSafe 6.0, Visual SourceSafe 6.0 Admin

이렇게 메뉴가 있을 겁니다. 여기서 실제로 자주 사용하는 것은 두가지 입니다.

Microsoft Visual SourceSafe 6.0 / Visual SourceSafe 6.0 Admin

위의 프로그램을 중심으로 설명해 드리도록 하겠습니다.
728x90

아래의 글은 제가 작성한 것이 아닙니다. 데브피아의 Q/A에서 발췌한 것으로써,
아직 제 머릿속이 정리가 안되 임시적으로 올린 것입니다.
이 내용이 정리되면 제가 다시 쓰겠습니다.


DLL에서 리소스를 사용할 때 흔히 발생하면서도 아주 고약한 문제중 하나입니다.
다음과 같은 전용 클래스를 만들어서 사용하시면 사용하기도 편하고 문제도 간단히 해결됩니다.



    
//=======================================================================
// XTDLLState.h 파일
//=======================================================================
#ifndef __EXTDLLSTATE_H__
#define __EXTDLLSTATE_H__
class CEXTDLLState  
{
public:
CEXTDLLState();
    virtual ~CEXTDLLState();
protected:
    HINSTANCE m_hInstOld;
};

//extern static AFX_EXTENSION_MODULE TextEffectDllDLL; #endif // !defined(AFX_EXTDLLSTATE_H__300ABF7E_3541_4AE3_8080_978EA6E1399D__INCLUDED_)

//======================================================================= // XTDLLState.cpp 파일 //======================================================================= #include "stdafx.h" #include "EXTDLLState.h" CEXTDLLState::CEXTDLLState() {    CString strDll;    // FCubic Common DLL 연결 #ifdef _DEBUG    strDll = _T("MyDll_d.dll");        // 디버그용으로 생성한 Dll 이름 #else    strDll = _T("MyDll.dll");            // 릴리즈용으로 생성한 Dll 이름 #endif

  m_hInstOld = AfxGetResourceHandle();   AfxSetResourceHandle( ::GetModuleHandle(strDll) ); }

CEXTDLLState::~CEXTDLLState() {   AfxSetResourceHandle(m_hInstOld); }


위와 같이 간단한 클래스를 만드세요.
단 "MyDll_d.dll" 과 "MyDll.dll" 부분을 자신의 Dll 이름으로 바꾸세요.
보니까 님께서는 대화상자 리소스를 쓰려고 하시는 것 같은데요..
이런 경우엔 대화상자 클래스에서 DoModal()을 오버라이딩해서 함수를 만들고 그안에 다음과 같이 코딩해 보세요.

// 헤더를 추가
#include "EXTDLLState.h"
// DoModa() 함수 오버라이딩
int CMyDlg::DoModal()
{
   // 서로 다른 DLL이 각각의 리소스를 올바로 사용하기 위해
   // DoModal() 이 호출될때 CEXTDLLState 클래스의 인스턴스를 생성하고
   // DoModal() 함수가 종료될때 CEXTDLLState 클래스가 소멸하면서 리소스 연결처리를 자동으로 해준다.
   // 자세한 처리는 CEXTDLLState 클래스의 생성자와 소멸자를 참고한다.
   CEXTDLLState State;
   return CDialog::DoModal();
}

단지 위CEXTDLLState의 인스턴스인  State를 정의함으로써 자동으로 리소스를 연결하고 해제하도록 해줍니다.
이유는 생성자와 소멸자의 호출 메카니즘에 의해서이죠...
그럼 즐프하세요... ^^

728x90
Platform SDK 또는 WTL  라이브러리를 설치하고 난뒤
현재 사용중인 프로그램 안에서 ATL을 사용할때 간혹 발생할 수 있는 오류이다.

이 오류의 원인은 InlinesEqualGUID 라는 인라인 함수에 의해 발생된다.
이 문제의 원인 Platform SDK 안의 헤더 파일인 Guiddef.h 와 ATL에 자체적으로 가진 AtlBase.h 안에서 선언과
함께 namespace가 틀리기 때문에 발생한다.
즉 Guiddef.h 안의 함수와 ATL안의 AtlBase.h안의 함수가 이름은 똑같은데 헷갈리게 이름은 똑같은 문제인것이다.
그래서 만약 using namespace ATL; 이라고 선언하면 자폭하게 되는 것이다.

이를 해결하는 방법은 InlienEqualGUID를 호출 할때 앞부분에 " ::ATL:: "을 붙이는 것이다.
InlineIsEqualGUID(xxxxx, xxxxx) 라고 되어 있으면 ::ATL::InlineIsEqualGUID(xxxxx, xxxxx) 라고 수정하면 된다.


                       
728x90
C++에 들어왔다면 바로 이 객체라는 것을 이해할 필요가 있습니다.

OOP(Object Oriented Programming) 라고 불리는 이 내용은 물론 단순하게
C++이라고 이야기할 수도 있지만, 더 광범위한 부분입니다.
OOP는 객체라는 개념으로 시작한 일종의 명세서 같은 것입니다.
이 명세서를 기반으로 C를 확장한것이 바로 C++입니다.
흔히 JAVA를 이야기하는데, 오히려 OOP에 가까운 것이 바로 JAVA입니다.
더 가까운것은 smalltalk 이구요.

자 그렇다고 OOP를 하기 위해서라면 위의 언어들을 통달해야 하냐?
그것은 아닙니다. 모로가도 서울로 가면 된다는 말이 있듯이
어떤 말로 하든 원하는 기능을 구현할 수 있다면 아무런 문제가 없습니다.

단지 여기서는 수많은 OOP 언어중 C++을 택한 것 뿐입니다.
자 이정도로 거두를 하고.. 객체에 대해서 이야기하죠.

객체란 데이터(Data)와 함께 실행할 수 있는 메소드(Method)가 있는 것입니다.
이것이 가장 기본적인 유형이자 형태 인데, 저리 말을 해놓고 보면 쉬이 이해가 안될 수도 단빡에 이해할 수도 있습니다.

자, 이 것은 Microsoft에서 객체를 설명하기 위한 예제였습니다.
풍선이 있습니다.

풍선을 가만히 바라 보면 여러가지를 판단해 낼 수 있습니다.
먼저 다양한 유형, 또는 모양의  풍선이 있습니다.
크기, 색, 바람넣은 양에 따라 그 풍선을 정의할 수 있습니다.
또 풍선을 가지고 할 수 있는 일들이 있습니다.
먼저 풍선에 바람넣기 빼기, 던지기, 터트리기, 띄우기 등입니다.

자, 위의 이야기를 근거로 무엇을 단빡에 알아낼 수 있을까요? 객체지향에 대해서 조금이라도 이해하고 계신분은
바로 나올 것입니다.
먼저 이야기한 다양한 유형/모양이 바로 DATA 입니다.
그리고 가지고 할 수 있는 일이 바로 Method 입니다.

이런 객체를 정의할 때 아래와 같이 정의하는 것이죠.

* 풍선
- Data
  색
  크기
  바람 넣은 양

- Method
  바람 넣기
  바람 빼기
  띄우기
  던지기

하지만, 이것은 우리가 개념적으로 생각하는 내용입니다. 풍선이라는 것을 정의했지만
실제 풍선이 아닙니다. 헷갈리죠?
존재하는 풍선과 개념적인 풍선과의 차이를 이해할 수 있다면 쉬이 아아.. 하겠지만, 그렇지 않다면
쉬이 이해할 수 없는 것입니다.

다른 예제로 들죠.
건물이 있습니다. 건물을 지으려면 수많은 공정이 있겠지만, 단순하게 생각하면 두개로 나눌 수 있습니다.
설계하는 작업 / 건물 짓는 작업.
설계에서는 높이도 있고 층도 있고 다양한 내용이 들어 갈 수 있습니다.
이렇게 하는 일들이 있겠구나 하면서 이런 저런 기능도 넣게 됩니다.
건물을 짓는 일은 바로 그 설계를 보고 실제 콘크리트를 넣고 실제 층수로 올리고 이런 저런 기능을
위한 작업을 합니다.

자 여기서 설계작업때 도면에 그린 건물에서 실제 실생활에 그 건물을 사용하실 수 있나요?
못하죠? 실제 건물을 지어야 그 안에서 벽지도 바꿔 보고, 외면의 타일도 바꾸고 그 안에서 주거 할 수 있게되죠?

이 개념을 잊지 말아야 합니다.
여기서 객체라는 것을 정의하는 것은 두가지라는 것을 기억하세요. Data 와 Method
그리고 그 객체를 실존시키는 작업이 필요하다는 것도 기억하세요. 이것이 바로 instance 입니다.

정의하는 것과 instancing(instance 시키기/실존 시키기)는 엄연히 차이가 있습니다.

여기서는 네가지를 배우게 됩니다.
객체 = Object = Class
객체 구성요소 : Data , Method
객체의 실존화 : Instance

먼저 이렇게 기억을 해두세요.




728x90
내가 가진 지식의 정리라는 차원이 맞을 것입니다.
처음에는 WikiWiki에 기록해 나갈려고 했었는데, 이런저런 여건상 결국 게시판으로 돌아왔네요.

VC++ 을 처음 접하고 그것으로 이런 저런 작업을 하면서 느낀 것들입니다.
아마도 제가 죽더라도 이것을 남기면 좋을것 같기도 하고...

요즘은 4GL의 발전과 Web Server 기반 Scrpit의 발전으로 VC++의 입지는 상당히 앝은 편입니다.
하지만, C++이라는 개념에서 출발한 VC++은 정말이지 다양한 기능을 제공합니다.
간단히는 Windows App를 만드는 데서 ActiveX라는 장르로 Web 상에서 제어하는 것에
심지어는 Windows Kernel을 헤집어 놓을 수 있을 만큼 강력합니다.

하지만 강력한 만큼 툴 자체가 가진 기능을 사용하려면 망망 대해에서 무엇을 출발해야 될지
모르는 경우가 많습니다.
게다가, 너무도 넓은 길때문에, 전혀 다른 쪽의 작업을 하려면 쉬이 전환이 불가능한 경우가 많습니다.

아직 제가 하는 이야기를 잘 이해가 안될지도 모르고, 반박할지는 모르겠지만...
일단 제가 느낀 VC++ 아니, C++의 느낌은 그렇습니다.

타이틀은 비록 VC++이지만 C++이기도 합니다.

그점은 알아주시기 바랍니다.
728x90
WM_ 으로 시작하는 윈도우 메시지를 만들었을때, MFC에서 제공하는 On_ 으로 처리되는 함수들이
자동으로 생성되는 것 보면 편해보이기 까지한다.
이를 수동적으로 생성하는 방법을 알아보자.

WM_USERDEFINE 이라는 메시지가 있다고 하자.
사용자가 만든 메시지여서, 실제 MFC Wizard로 만들수 없다.
게다가, MessageMap 매크로 안에 넣으려해도, afxmsg OnUserDefine 을 만들려고 하면
그 함수와 Message와 연결 할 방법이 없다.
이를 처리하려면, MessageMap 안에서 함수와 Message를 연결해주는 무언가를 만들어 줘야 한다.
그리고, 각 함수를 살펴보면, 윈도우 메시지를 그냥 받는 것이 아니고 각 유형 별로 파라미터로 받는 경우가 있다.
예를 들자면 OnLButtonDown(UINT nFlags, CPoint point) 같은 것은 nFlags 나 point를 받는다.
하지만, 현재는 파라미터가 없는 버젼만을 생각하여 만들도록 하자.

WM_USERDEFINE을 가지고 한번 만들어 보자.

.H 을 열어 보면,
   //{{AFX_MSG(CUserDefine)
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
이라는 부분이 있다.
실제로 "//{{AFX_MSG(CUserDefine)",  "//}}AFX_MSG" 이 두 문장은 단순히 클래스 위자드에서 사용하기 위해
만들어진 내용이므로 삭제해도 무방하다. 단 클래스 위자드에 의존하는 분들은 이 부분을 지우게 되면 새로운 메시지
처리를 추가/삭제/수정이 절대 불가능하니, 조심한다.
일단, "//}}AFX_MSG" 아래에다 자신이 만든 메시지 핸들러 함수를 선언한다.
afx_msg 를 맨 앞에 붙이고 그 뒤에 함수 선언을 한다. On 이라는 이름이 붙은 형태의 함수를 만든다.
   afx_msg OnUserDefine()
그러면 .H에서 다 기록한 것이다.

.CPP를 열어보면,
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
가 보일 것이다. 이 안이 바로 Message와 함수를 연결해주는 부분이다. 그러나 그 안에 보면 단순히
ON_WM_PAINT()와 같은 단순 무식한 한줄의 함수만 보인다. 그렇다면 이를 어떻게 해야 하는 것인가?
간단하다. ON_WM..  시리즈를 직접 만드는 것이다.
   #define ON_WM_USERDEFINE()
   { WM_USERDEFINE, 0, 0, 0, AfxSig_vv,
   (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnUserDefine },
위의 세줄을 넣어준다.  이 부분이 바로 ON_WM 시리즈의 실체가 된다.
실제 사용되는 WM_ 메시지를 넣고 맨 뒤의 On.. 시리즈 함수를 대체해서 만들어 주면 된다.
위의 예제는 WM_USERDEFINE을 기준으로 넣었다. 그러면 BEGIN_... 안에다 자신이 만든것을 넣어 주면 된다.
   BEGIN_MESSAGE_MAP(CUserDefine,CWnd )
           //{{AFX_MSG_MAP(CUserDefine)
           ON_WM_PAINT()        
           //}}AFX_MSG_MAP
                ON_WM_USERDEFINE()
   END_MESSAGE_MAP()
이렇게 하면 모든것이 해결!

파라미터가 있다면 그 뒤에 다시 생각해보도록한다.
참고로 AfxSig_xxx 라는 값을 이용하면 다양한 형태로 구성할 수 있는 데, 이는 정해진 내용만 적용가능하다.
        AfxSig_bD,      // BOOL (CDC*)
        AfxSig_bb,      // BOOL (BOOL)
        AfxSig_bWww,    // BOOL (CWnd*, UINT, UINT)
        AfxSig_hDWw,    // HBRUSH (CDC*, CWnd*, UINT)
        AfxSig_hDw,     // HBRUSH (CDC*, UINT)
        AfxSig_iwWw,    // int (UINT, CWnd*, UINT)
        AfxSig_iww,     // int (UINT, UINT)
        AfxSig_iWww,    // int (CWnd*, UINT, UINT)
        AfxSig_is,      // int (LPTSTR)
        AfxSig_lwl,     // LRESULT (WPARAM, LPARAM)
        AfxSig_lwwM,    // LRESULT (UINT, UINT, CMenu*)
        AfxSig_vv,      // void (void)

        AfxSig_vw,      // void (UINT)
        AfxSig_vww,     // void (UINT, UINT)
        AfxSig_vvii,    // void (int, int) // wParam is ignored
        AfxSig_vwww,    // void (UINT, UINT, UINT)
        AfxSig_vwii,    // void (UINT, int, int)
        AfxSig_vwl,     // void (UINT, LPARAM)
        AfxSig_vbWW,    // void (BOOL, CWnd*, CWnd*)
        AfxSig_vD,      // void (CDC*)
        AfxSig_vM,      // void (CMenu*)
        AfxSig_vMwb,    // void (CMenu*, UINT, BOOL)

        AfxSig_vW,      // void (CWnd*)
        AfxSig_vWww,    // void (CWnd*, UINT, UINT)
        AfxSig_vWp,     // void (CWnd*, CPoint)
        AfxSig_vWh,     // void (CWnd*, HANDLE)
        AfxSig_vwW,     // void (UINT, CWnd*)
        AfxSig_vwWb,    // void (UINT, CWnd*, BOOL)
        AfxSig_vwwW,    // void (UINT, UINT, CWnd*)
        AfxSig_vwwx,    // void (UINT, UINT)
        AfxSig_vs,      // void (LPTSTR)
        AfxSig_vOWNER,  // void (int, LPTSTR), force return TRUE
        AfxSig_iis,     // int (int, LPTSTR)
        AfxSig_wp,      // UINT (CPoint)
        AfxSig_wv,      // UINT (void)
        AfxSig_vPOS,    // void (WINDOWPOS*)
        AfxSig_vCALC,   // void (BOOL, NCCALCSIZE_PARAMS*)
        AfxSig_vNMHDRpl,    // void (NMHDR*, LRESULT*)
        AfxSig_bNMHDRpl,    // BOOL (NMHDR*, LRESULT*)
        AfxSig_vwNMHDRpl,   // void (UINT, NMHDR*, LRESULT*)
        AfxSig_bwNMHDRpl,   // BOOL (UINT, NMHDR*, LRESULT*)
        AfxSig_bHELPINFO,   // BOOL (HELPINFO*)
        AfxSig_vwSIZING,    // void (UINT, LPRECT) -- return TRUE

        // signatures specific to CCmdTarget
        AfxSig_cmdui,   // void (CCmdUI*)
        AfxSig_cmduiw,  // void (CCmdUI*, UINT)
        AfxSig_vpv,     // void (void*)
        AfxSig_bpv,     // BOOL (void*)

        // Other aliases (based on implementation)
        AfxSig_vwwh,                // void (UINT, UINT, HANDLE)
        AfxSig_vwp,                 // void (UINT, CPoint)
        AfxSig_bw = AfxSig_bb,      // BOOL (UINT)
        AfxSig_bh = AfxSig_bb,      // BOOL (HANDLE)
        AfxSig_iw = AfxSig_bb,      // int (UINT)
        AfxSig_ww = AfxSig_bb,      // UINT (UINT)
        AfxSig_bv = AfxSig_wv,      // BOOL (void)
        AfxSig_hv = AfxSig_wv,      // HANDLE (void)
        AfxSig_vb = AfxSig_vw,      // void (BOOL)
        AfxSig_vbh = AfxSig_vww,    // void (BOOL, HANDLE)
        AfxSig_vbw = AfxSig_vww,    // void (BOOL, UINT)
        AfxSig_vhh = AfxSig_vww,    // void (HANDLE, HANDLE)
        AfxSig_vh = AfxSig_vw,      // void (HANDLE)
        AfxSig_viSS = AfxSig_vwl,   // void (int, STYLESTRUCT*)
        AfxSig_bwl = AfxSig_lwl,
        AfxSig_vwMOVING = AfxSig_vwSIZING,  // void (UINT, LPRECT) -- return TRUE

        AfxSig_vW2,                 // void (CWnd*) (CWnd* comes from lParam)
        AfxSig_bWCDS,               // BOOL (CWnd*, COPYDATASTRUCT*)
        AfxSig_bwsp,                // BOOL (UINT, short, CPoint)
위에서 보듯이 딱 정해진 기능만 하므로... 그 외의 것이라면 다시 생각해보도록 한다.

PS. 혹여 AfxSig_lwl 를 사용하면 WPARAM, LPARAM 이니까... 다양하게 이용할 수 있을지도 모르겠다.

728x90
Winsock의 형태는 다양하게 변모되어 우리에게 다가왔다
sock 라이브러리를 Windows에 맞게 처음 도입한 Winsock 1.x에서 2.x로 발전하고,
MFC로 재 제작하여 배포하고 있다.

여기서 winsock 1.x 때와 2,x 때 include하는 내용이 틀리다.

1. 일반적으로 winsock1.x 라이브러리를 사용하려면,
winsock.h만 include하면 된다. (lib는 일반적으로 섞여 처리된다.)

2. winsock 2.x대에서는 다음의 추가적인 처리가 필요하다.
Winsock2.h 와 ws2tcpip.h 를 include 처리하고
ws2_32.lib를 link시 연결해 주면 된다.

3. MFC 인경우에는 MFC 4.x 대 library안에 lib는 내장되어 있고 단지, 해당 클래스만 include 처리하면 된다.
afxsock.h 가 바로 그 include해야 될 내용이다.
728x90
간혹 VC++을 설치했는데, VC++에 제대로 등록이 안되어 있어
소스세이프를 사용하지 못하는 경우가 있다.
이 경우 간단하게 초기화 시키는 방법이 있다.

VSS 프로그램이 있는 폴더를 찾아낸다.
만일 VC++과 같이 설치되어 있다면...
설치된드라이브:Program FilesMicrosoft Visual StudioCommonVSSwin32
의 위치에 있고 대부분, VSSwin32의 위치를 찾으면 된다.

그 폴더에 있는 내용중 ssint.exe 를 실행해 주면 된다.
728x90

+ Recent posts

728x90