타입 변환 연산자

C/C++/VC++ / MFC 2009. 8. 13. 17:05

C++ 에서는 타입 변환 연산자라는 기능이 있습니다.
이걸 사용하면은 클래스가 일반 타입처럼 암시적 변환이 가능합니다.

아래는 예제 클래스 입니다.
차때고 포때고 간단하게 작성했습니다.
클래스의 목적은 int의 기능을 대신하는 클래스입니다.
class MyInt
{
private:
    int m_nNum;

public:
    MyInt(int i) : m_nNum(i)  {}
    operator int() const {
      return m_nNum;
    }
    MyInt& operator =(int i)  { 
         m_nNum = i; return *this; 
    }
};
보통 연산자 오버로딩 후에는 반환값이 있습니다.
    MyInt& operator =(int i)      {   m_nNum = i; return *this; }
이런것 들 말이죠
그렇지만

연산자 오버로딩은 연산자가 함수 형태라고 해서 
리턴값을 써주면 안됩니다.
    operator int() const    {  return m_nNum;  }         // 컴파일됨
    int operator int() const    {  return m_nNum;  }     // 에러


참고 : The C++ Programming Language
posted by 뚱2

MFC만 사용하다 API만으로 버튼 클릭 메세지를 만들기

::SendMessage(::GatParent(hWnd)
              , WM_COMMAND 
              , (WPARAM)MAKELONG(::GetDlgCtrlID(hWnd))
              , BN_CLICKED) 
              , (LPARAM)hWnd ); 


여기서 hWnd 핸들은 클릭할려는 버튼의 핸들값 입니다.
posted by 뚱2

Windows 2008 Server Standard + Visual Studio 2005 에서 Window Mobile 5.0로 크로스 컴파일 하는데
계속 해서 위와 같은 메세지 Warring이 뜨네요...
너무 신경쓰여서 구글링 한 결과 무시하면 된다고 합니다.
그렇지만 굳이 신경쓰이는 걸 안보이게 하려면

"프로젝트 --> 속성 --> 구성 속성 --> C/C++ --> 코드 생성 --> 버퍼 보안 검사 "에서 "예"를 "아니오"로
해주심 Warring 메세지가 없어집니다.

posted by 뚱2

오늘 제대로 삽질 한번 했습니다.

WinCE+EVC 로 어플리케이션을 개발하고 있습니다.

클라이언트 요구사항이 숫자필드는 오른쪽 정렬을 원하더군요

숫자 보여주는 컨트롤을 CEdit를 서브글래싱해서 사용하고 있었습니다.

그런데 아무리 해도 오른쪽 정렬이 안되는 것입니다.

리소스뷰에서 설정해도 안되고

서브클래싱한 PreSubclassWindos에서도 안되고..

그래서 결국 구글링한 결과 WinCE에서는 Singleline으로 하면은

왼쪽 정렬만 먹고

오른쪽 정렬, 가운데 정렬을 할려면 Multiline으로 해야한다고 하네요 ㅠㅠ

Win32에서는 모든 속성이 정상적으로 먹습니다.

MS가 오늘 제대로 삽질하게 만들었네요...


http://www.codeguru.com/forum/showthread.php?p=186903
posted by 뚱2

제가 윈키 또뀨세이버를 사용하고 있습니다.
이번에 스위치를 변경해보려고 하는데 일반 나사가 아니라 육각볼트네요.
그래서 자주가는 사이트의 카프리옹님께 여쭤보고
몇가지 알게되었습니다.

또뀨의 육각렌치는 2.5mm가 맞습니다.
옥션등에서 '육각렌치'로 검색하시면 엄청 나올겁니다.
그중에 2.5mm가 있는 놈으로 사면 됩니다.
참고로 356N이나 356L은 2mm, 무선마제는 레치 머리에 구멍이 뚫린 T9 규격의 별렌치 입니다.
posted by 뚱2

Blog API를 사용하다.

뚱2's 이야기 2009. 3. 27. 13:58


블로그의 장점은 자신의 개인적 생각을 글로 자유롭게 표현하는 것이라고 생각합니다.

그런데 웹에서 편집하고 올리다 보면 생각정리가 쉽지 않고 편집이 쉽지 않습니다.

그래서 사용하게 된 것이 Blog API…

자신의 글을 여러 번 확인하고 보다 좋게 편집해서 자유롭게 올릴 수 있는 것 같습니다.

이제부터 새로운 블로그 생활을 할수 있겠네요. 

저 같은 경우는 Windows Live Writer를 이용해서 블로그에 게시하고 있습니다.

Windows Live Writer 다운로드

posted by 뚱2

 

출처 http://fahnel.net/4

-> Server
1. SourceSafe 설치
2. Server에 SourceSafe로 사용 할 폴더를 생성함.
3. Network 공유 설정
4. Network 상에서 공유 할 권한 부여 (읽기/쓰기)
5. File -> New Database 에서 지정한 폴더 설정로 연결. (srcsafe.ini이 생성 됨.)
6. SourceSafe Administrator에서 SourceSafe에 사용 할 User 추가

-> Client (SourceSafe)
1. SourceSafe 설치
2. Open SourceSafe Database 에서 Add로 추가
 - Connect to an existing database 선택
 - Location 설정 : 공유 되어 있는 폴더에서 srcsafe 선택
- Connection Name 설정
3. Create Project로 프로젝트 단위로 추가

-> Client (Visual Studio)
1. Project를 솔루션에 연결
2. 전체 솔루션 빌드
3. 파일 -> 소스 제어 -> 소스 제어 변경 메뉴로 들어감.
4. 솔루션/프로젝트에 맞게 SourceSafe에 생성한 Project로 바인딩 시킴.
5. SourceSafe에 올라가 있는 버전과 내가 가지고 있는 버전 확인 하며 Check In 시킴.
 - Server 버전이 최근 것이면 새로 받기 진행.

posted by 뚱2

선이 맞게 연결되었는지 테스트 한다고 8시간이나 걸렸습니다.
그래서 완성된 뚱2표 조이스틱

1. 무선조이스틱
2. 동조버튼과 헤드셋은 제외 (별 사용을 안해서 제외)

다음번에 할때는 LED를 달고 싶습니다.



'뚱2's 이야기' 카테고리의 다른 글

또뀨세이버 육각렌치 사이즈  (0) 2009.04.20
Blog API를 사용하다.  (0) 2009.03.27
조이스틱을 개조해 보자  (0) 2009.03.04
T61P 14.1 UXGA  (2) 2009.02.28
Tistroy 카테고리를 펼쳐보자...  (0) 2009.02.18
posted by 뚱2

'뚱2's 이야기' 카테고리의 다른 글

Blog API를 사용하다.  (0) 2009.03.27
뚱2표... 스트리트파이터4 조이스틱 완성  (2) 2009.03.08
T61P 14.1 UXGA  (2) 2009.02.28
Tistroy 카테고리를 펼쳐보자...  (0) 2009.02.18
최근에 사용한 문서 지우기  (0) 2008.09.12
posted by 뚱2

T61P 14.1 UXGA

뚱2's 이야기 2009. 2. 28. 23:17

그동안 계속 생각만 있었는데 이번에 큰맘 먹고 개조를 단행했습니다.
물론 제가 한것 아닙미다. ^^;
액정 개조후 가장 큰 장점은 세로 픽셀이 1050 에서 1200으로 바뀐것 입니다.
주로 Visual Studio를 사용하는 저로써는 소스를 전체적으로 보기 편하게
화면이 넓직한게 좋습니다.



'뚱2's 이야기' 카테고리의 다른 글

뚱2표... 스트리트파이터4 조이스틱 완성  (2) 2009.03.08
조이스틱을 개조해 보자  (0) 2009.03.04
Tistroy 카테고리를 펼쳐보자...  (0) 2009.02.18
최근에 사용한 문서 지우기  (0) 2008.09.12
Takata04-neo  (0) 2008.08.17
posted by 뚱2

티스토리를 사용하면서 다양한 스킨과 플러그인... 참 좋은데 다만 하나!!
이넘의 카테고리를 트리구조로 선택하면... 페이지를 클릭할때마다 내가
펼쳤던 카테고리가 닫히는 문제가 발생하네요... ㅡㅡ;

이랬던 페이지가 링크를 클릭하거나
새로고침을 하면은....















이렇게 되버리는 아주 XX 같은 경우










기능상의 한계인가보다 생각하고 카테고리를 트리구조로 만들지 않고 평범하게
1 Level로 사용했었습니다.
그런데 여기 저기 방문하다 보니 어느분의 티스토리는 분명.. 펼쳐저 있는겁니다.
그래서 다시 한번 옵션을 찾아봤지만 안보이네요... ㅡㅡ;
그렇지만 남이되면 나도 안될 이유는 없기에 욜심히 찾아봤습니다.
그래서 찾아낸것은 쉽게 옵션으로 조정은 안되구요

1. Admin에 들어와서 'HTML/CSS 편집' 에
들어갑니다.












2. 위와 같이 <body> 태그에 'OnLoad="expandTree();"' 이벤트를 넣어주심 됩니다.


3. 다른방법으로는 jQuery 를 이용해서 할 수도 있습니다.
* jQuery $(window).load 이벤트가 IE8에서 오류가 나서 수정
//jQuery.noConflict();
(function($) {
    var that = this;
    that.doLoad = function() {
        expandTree();
    };

    $(document).ready(function() {
        SyntaxHighlighter.config.bloggerMode = true;
        //SyntaxHighlighter.defaults['html-script'] = true;
        SyntaxHighlighter.all();

        if ( window.addEventListener ) { 
            window.addEventListener( "load", that.doLoad, false );
        }
        else if ( window.attachEvent ) { 
            window.attachEvent( "onload", that.doLoad );
        } 
        else if ( window.onLoad ) {
            window.onload = that.doLoad;
        }
    });//$(document).ready(function() {
})(jQuery);


'뚱2's 이야기' 카테고리의 다른 글

조이스틱을 개조해 보자  (0) 2009.03.04
T61P 14.1 UXGA  (2) 2009.02.28
최근에 사용한 문서 지우기  (0) 2008.09.12
Takata04-neo  (0) 2008.08.17
Sony HANDYCAM HDR-TG1  (0) 2008.07.19
posted by 뚱2
MFC에서 COM를 사용하기 위해서는 스레드 로딩시에  CoInitialize()를 호출해 주어야 합니다.
저는 ADO를 통해서 Oracle에 접근하기 위해서 사용했습니다.
단순한 생각으로 처음부터 DB에 연결해서 주구장창 하나로 사용하려고 했습니다.
그래서 다중접속 부분의 동시접속 문제는 CriticalSection을 이용했는데
알고 보니 이게 좋은 방법이 아니었습니다.
그래서 각 유저가 접속할때마다 DB를 Open하고 쿼리 날리고 DB를 Close 할려고 했는데
CreateInstance를 생성할때마다 스마트포인터가 NULL로 되더군요..
알고 봤더니 COM을 MFC에서 사용하기 위해서는
CoInitialize를 호출하는데 이건 스레드당 한개씩 오픈해야 한다는 것 입니다.
제가 다중접속을 위해서 별도의 스레드로 소켓을 이용한 프로그래밍을 했는데
각각 별도의 스레드에서 DB를 접속할려고 하니 안되는 거였습니다. ㅡㅡ;
결국 스레드당 접속을 한 결과 접속을 잘 해결되었습니다.

ADO ? COM 사용시 주의사항??

1. CoInitialize()와 CoUninitialize()는 꼭 짝으로 이뤄서 사용하자 :
   C++이라면 클래스로 만들어서 생성자에서 CoInitialize()하고 소멸자에서 CoUninitialize()하면
   좋겠죠
2. ADO 사용을 편하게 하기 위해서 스마트 포인터를 사용하는데... 스마트 포인터는 내부적으로
   소멸자에서 Release()를 호출해 줍니다. 따라서 명시적으로 Release()를 호출하면은 안됩니다.

하나라도 정확하게 알고 사용하는거와
모르고 사용하는건 큰 차이가 있을을 다시 한번 느꼇습니다.
이거 배워야 할게 너무도 많네요... ^^

 
posted by 뚱2

Release에서 디버깅 하기 ...

OS/Windows 2008. 11. 21. 10:54

저같은 경우 통신 프로그램을 개발 할 때
로컬에서 작업을 마치고 나서 실 서버에 서버 프로그램을 올립니다.
그런데 거의 대부분 실서버 올렸다고 바로 릴리즈 하지 못합니다.
쏟아지는 버그와 수정 사항들 ... (저만 그런가요? ^^; )
이럴때 디버깅 하기가 참 곤란 합니다.
다시 로컬 작업하던 컴퓨터에서 디버깅 모드로 디버깅하고 컴파일 하고
다시 실 서버로 올려서 돌아가는지 확인하고.... 에휴~~~~
그럴대 참으로 유용한 방법입니다.

디버그 모드에서 출력창에 스트링을 TRACE 구문이 있는데요
WIN32 API 중에 OutputDebugString()이라는 API가 있습니다.
이건 릴리즈에서도 출력창에 스트링을 출력할 수 있습니다.
그런데 이렇게 막연하게 설명하면은
출력은 어디서 봐????
이러실텐데요....
출력을 보는 프로그램은 Win32 API로 직접만들수도 있지만...
저 같은 경우는 DebugView 라는 프로그램을 사용합니다.
DebugView의 사용법은 헬프 파일을 살펴보세요.
암튼...

OutputDebugString 사용법은 참으로 간단합니다.
void WINAPI OutputDebugString(
  __in_opt  LPCTSTR lpOutputString
);

그냥 문자열을 넘기면 됩니다.
그런데 여기서 문제가 살짝 발생하네요.... 다 좋은데.... 전 printf 같이
인자도 넘기고 싶습니다.
그래서 전 이렇게 했습니다.

void OutputDebugPrintf(TCHAR* pszFormat, ...)
{
    //가변인자의 길이를 모르기때문에 동적으로 생성하기 위한 포인터 변수
    TCHAR* pBuffer = NULL;
    va_list args;

    va_start(args, pszFormat);
    // 가변인자 스트링의 길이를 구한다.
    int nLen = _vsctprintf(pszFormat, args) + sizeof(TCHAR);
    // 가변인자 길이만큼 문자열을 생성한다.
    pBuffer = new TCHAR[nLen];
    // 복사한다.
    _vstprintf_s(pBuffer, nLen, pszFormat, args);
    va_end(args); // Windows에서는 필요없음
 
   // 출력해준다.
   ::OutputDebugString(pBuffer);
    if (pBuffer)
    {
        delete[] pBuffer;
        pBuffer = NULL;
    }
}

va_list, va_start, va_end는 printf와 같이 가변인자를 받아서 처리하는
매크로 들입니다.
이걸이용하면은 인자가 몇개든 출력할수 있습니다.
사용법은 printf와 같습니다.




posted by 뚱2

PDA 업체에서 제공 하는 API를 사용하기 위해서 .Lib 을 링크하고 .h파일을 인클루드 했는데
위와 같은 에러가 발생했다.
구전(VC++ 6.0 이하)에서는 허용되었던 함수의 리턴값 생략이 VC++ 7.0이상으로 오면서
명시적으로 바뀌면서 생기는 오류이다.
컴파일 옵션을 바꿔서 해도 되지만... 그것보다는
함수를 명시적으로 바꾸는게 바른 방법인데...
이거... 내가 만든것도 아니고 .h 바꾸면 찝찝한데... ㅡㅡ;
그렇다고 컴파일 옵션을 바꾸자니 그건 더 찝찝하고...
결국 난 .h를 변경했다.
posted by 뚱2

C, C++는 파일을 작성할때는

보통 헤더파일에는 선언

구현파일에는 정의를 많이 넣는데요

템플릿을 사용할때는 헤더와 정의를 헤더파일에 넣어야 합니다.

이유인즉슨 컴파일 과정에서 템플릿의 정의부분이 필요하기 때문입니다.


ps. 한파일에 넣지 않고 하는 방법도 있다고 하는데 가장 손쉬은 방법은

      헤더에 다 작성하는 방법입니다.
posted by 뚱2

오늘 작업중인 노트북을 새로 밀었다.
프로젝트 진행중이던 프로그램들은 USB 하드에 백업해구도 다시 복구하니...
헉!!!! Visual Studio 2005에서 실행이 안되는 것이다.
그 첫번째 에러메세지는 공유 MFC DLL을 사용했는데 디버그용
mfc80ud.dll을 찾을 수 없다는 것이다 그래서 정적 MFC 로 컴파일 해보니
잘된다... 그래도 찜찜해서
다시 공유 DLL로 하고 직접 mfc80ud.dll을 옮겨서 해봤으나 이번에는
C 런타임 dll vmsvcr80d.dll 을 찾을수 없다고 한데..
역쉬 찾아서 넣어줬지만 이젠 알 수 없는 에러가 나버린다..
여기 저기 찾고... 별 방법을 다 해봤으나 안되는데
갑자기 든 생각이 새로 노트북을 밀면서 FAT32 방식으로 포맷을 바꿨다.
기존의 방식은 NTFS 방식이었다
결국 다시 노트북을 밀고 NTFS 방식으로 해보니
제대로 된다...
왜 이렇게 되는지 이유는 모르겠고 무엇때문에 안되는지는 알았는데
찜찜하다....
posted by 뚱2

오늘 하루종일 바보 같은 짓을 한 하루 였습니다.
제가 MFC 클래스 구조를 잘 모르는 상태에서 쓰기 급급했는데
스택으로 생성한 다이알로그도 PostNcDestroy를 상속받아서 거기서
delete this; 해줬습니다.
평소에는 이렇게 해도 괜찮았는데
CString를 선언해주면은 스택오버플로우가 나버립니다.
정확하게는 모르겠으나 스택으로 생성한 것을 자신이 delete this;
해버리는 바람에 CString 안에서 힙으로 생성한걸 해제하지 못해서
오버플로우가 나는것 같습니다.

하나 하나 정확하게 알고 사용해야 한다는 교훈을 ㅡㅡ;
MFC는 심오하네요~~
posted by 뚱2

이번에 하는  PDA 프로젝트에서는 특이하게 다이알로그 기반으로하여
메인 다이알로그에 여러가지 다이알로그를 차일드로 동적 생성하여
화면을 교체(SW_HIDE, SW_SHOW)하면서 MDI같은 효과를 주었습니다.

이럴경우 화면이 바뀔때 마다 셋팅해 주어야 하는 경우 어디에서
해야 할찌 난감하더군요~~~
이리 저리 찾아보니 WM_SHOWWINDOW 메세지가 있어서 열심히 코딩
하고 테스트 해보니 메세지가 안먹습니다. ㅠㅠ
이러 저리 해보다가 정 안돼서 Spy++로 메세지를 살펴보니 이런~~~~
메세지가 안날라오는 이런 X떡같은 일이.....
그래서 할 수 없이 다른 메세지 WM_WINDOWPOSCHANGED라는 메세지를
잡았더니 잘~~~~~ 되네요....
이거 초보는 정말 매일 매일 삽질을 합니다.
posted by 뚱2
예)

if (m_hThread) { DWORD dwExitCode = 0; ::GetExitCodeThread(m_hThread, &dwExitCode); if (dwExitCode == STILL_ACTIVE) { AfxMessageBox(_T("실행중인 스레드")); } }


사실 GetExitCodeThread는 스레드 핸들을 인자로 해서 스레드 종료코드를 알아내는 함수이다.
그렇지만 스레드가 종료되기전 GetExitCodeThread를 호출하면 종료코드에 'STILL_ACTIVE'가
담겨져 있다 따라서 스레드가 실행중인지 확인 할 수 있다.

'OS > Windows' 카테고리의 다른 글

CoInitialize(), CoUninitialize() 호출시 주의사항  (0) 2009.02.03
Release에서 디버깅 하기 ...  (0) 2008.11.21
InternetSetOption의 Timeout 설정 버그  (0) 2008.09.16
WM_DESTROY 메세지  (0) 2008.07.21
초보 DLL 사용하기  (0) 2008.02.21
posted by 뚱2

재미있는 기능도 많이 있고 가장큰 이점은 코드를 만들어 주는 기능이다.
아래에서 다운받을수 있다.
Visual Studio .net Visual Studio 2500

http://www.cupla.net/CodeWiz2/
posted by 뚱2

간단하지만 요긴한 단축키 입니다. ^^;

우선 주석을 하고 싶은 구간을 선택하세요
주석 : Ctrl+K+C
해제 : Ctrl+K+U

PS. Visual Studio C++ 6.0 이하에서는 안됩니다.
posted by 뚱2

오류를 처리하는 가장 발전적이고 효과적인 방법이 C++ 예외 처리 기능입니다.
그런데 VC++ (6 or 7)의 설명서에 약간 오해의 소지가 있는 부분이 있습니다.
예를 들어,

try 
{ 
    int* p = 0; 
    *p = 0; 
} 
catch (...) 
{ 
    // do something 
} 

이렇게 하면, 위 *p = 0 줄에서 access violation 예외가 발생하고
그 예외가 아래 catch 블럭에서 잡힙니다.

문제는 debug 빌드인 경우에는 예상대로 예외 처리가 되는데
release 빌드일 때는 그렇지 않다는 데 있습니다.

MSDN이나 VC++ 도움말에서 예외 처리에 관련된 부분을 보면
항상 컴파일러 옵션 /GX 또는 /EHsc를 지정하라는 말이 나옵니다.
"win32 structured exception" 방식을 쓰려면 /GX 없이 그냥 컴파일하고
C++ 예외 처리 방식을 쓰려면 /GX로 컴파일하라..." 이런 식으로 설명되고 있죠.

디폴트 옵션도 /EHsc 입니다.
/EHs 는 syncronous 예외 처리 모델을 가리키고
/EHc 는 C 함수는 예외를 throw하지 않는 다고 가정하는 것을 가리킵니다.

syncronous 모델은 뭐냐하면, 명시적으로 throw가 사용되지 않은 함수에 대해서는
예외 처리에 대한 지원을 하지 않는 것을 말합니다.

따라서

try 
{ 
    int* p = 0; 
    *p = 0; 
} 
catch (...) 
{ 
    // do something 
} 

이런 프로그램은 디버그 빌드일 때는 잘 돌아가고
예외 처리도 잘 되고,
잘못된 동작이 있을 때 이쁘게 메시지 박스 띄우고 부드럽게 종료하고
다 잘 됩니다.

그러다가 릴리즈 빌드로 바꾸면 디폴트로 /EHsc 옵션이 먹으면서
예외 처리도 안 되고
access violation 같은 거 발생할 때 프로그램이 죽어버립니다.

해결책은 단순하죠.
컴파일러 옵션 대화상자에서 C++ 예외 처리를 사용하지 않음으로 선택하고
직접 /EHa 옵션을 추가해주면 됩니다.

/EHa 옵션을 주고
메인 프로그램 진입점을

try 
{ 

} 
catch (...) 
{

} 

이런 블럭으로 감싸면 프로그램이 예기치 않게 종료되는 일을 방지할 수 있습니다.
위 내용은 VC6, VC7 공통입니다.
이상입니다.

** 경고
예외 처리는 복잡한 고려사항이 많기 때문에
충분히 공부한 후 사용해야 합니다.
예외 처리는 체계적으로 사용해야만 효과적이며
그렇지 않으면 부작용이 더 클 수 있습니다.

posted by 뚱2

LNK 4099 에러관련

C/C++/VC++ / MFC 2008. 9. 18. 16:27
posted by 뚱2

Platform SDK 설치

IDE/Tool/Visual Studio 2008. 9. 18. 15:23

Visual Studio 만을 설치하는 것으로는 부족합니다.
VS 가 지난 97 년에 나왔고, 지금 쓰고 있는 것도 VC98 폴더명을 통해서 유추해봐도 98 년 정도에 나온 것을
대부분의 개발자들이 그대로 쓰고 있는 실정입니다.

하지만, 하루가 다르게 기존 개발환경은 업데이트 되고 있기 때문에, 98 년도에 나온 Windows 개발관련 Header 파일은
내용이 많이 부실한 상황입니다.

이런저런 이유로, MS 에서는 Platform SDK 를 내놓았습니다.
물론, 무료이고
http://www.microsoft.com/msdownload/platformsdk/sdkupdate
사이트에서 다운로드 받을 수 있습니다. 만약, 자신이 근무하는 회사가 "MSDN Universal" 을 받고 있다면, 그 때 받게 되는
묵직한 "CD" 박스에 "Platform SDK" CD 가 들어 있으니, 그걸로 설치하셔도 됩니다.

해당 웹페이지에 가면, Windows SDK 라고 해서 "Core SDK", "DirectX SDK", "Internet Development SDK", "IIS SDK",
"MDAC SDK", "Windows Installer SDK", "WMI SDK" 로 나뉘어져 있습니다.

마음같아서는 모두 설치하고 싶으시겠지만, 웹상에서 다운로드 받는 것이기 때문에 "Core SDK" 만 설치하는 데도
시간단위로 걸립니다. 나머지는 해당 분야에 맞게 골라서 설치하시면 되고, 기본적으로 꼭 "Core SDK" 는 설치를 하십시오.

"Platform SDK" 를 설치하는 경우 부가적으로 "Platform SDK" 도움말 파일도 설치가 됩니다. MS 행사에서 간혹, "MSDN
Library" 를 나누어 주는 경우가 있는데요. 그 MSDN Library 도움말의 대부분을 차지하고 있는 것이 "Platform SDK"
도움말입니다. MSDN Library 와 많은 부분에서 중복이 되기 때문에 하드 디스크의 공간이 GB 단위로 손실이 발생합니다.
더군다나, 거기다가 Visual Studio.NET 까지 설치하면 .NET 도움말에도 MSDN Library 가 있어서, 3중으로 중복된 파일이
존재하게 됩니다. 그래서 저같은 경우에는 아예 "MSDN Library" 를 제거했고, 그냥 Platform SDK 설치와 함께 제공되는
도움말을 쓰고 있습니다.

설치가 완전히 되고 나면, Visual Studio IDE 에 Platform SDK 의 존재를 알려야 됩니다. "Platform SDK" 설치과정중에
자동적으로 해주는 단계가 있는데, 그 단계를 무시했다고 해도 상관없습니다. 수동으로 다음과 같이 입력해 주면 됩니다.

VC++ IDE 에서 "Tools/Options" 메뉴에 "Directories" 탭을 누른후,

오른쪽 윗편에 "Include files" 를 선택하신 후, 다음과 같은 순서인지 확인합니다.
C:\Program Files\Microsoft Platform SDK\include
C:\Program Files\Microsoft Platform SDK\include\ATL30
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE

"Library files" 에도 Platform SDK 의 존재를 알립니다.
C:\Program Files\Microsoft Visual Studio\VC98\LIB
C:\Program Files\Microsoft Visual Studio\VC98\MFC\LIB
C:\Program Files\Microsoft Platform SDK\lib

위에서 보면 Include File 같은 경우에 Platform SDK 폴더의 것을 상위에 놓았고, Library 의 경우에는 맨 하위에 놓은 것을
볼 수 있습니다.
왜냐면... 개발을 하다 보니, 새로 나온 Platform SDK 의 Lib 파일을 사용하는 경우, 불안정하게 동작하는 것을 많이 경험
했습니다. 그래서, 헤더파일만 위에 놓고, Lib 파일은 우선순위를 가장 아래로 두었습니다.

여러분이 저를 기준으로 삼을 필요는 없습니다. Library 역시 Platform SDK 를 가장 상위에 놓아도 됩니다. 단지, 저는 그렇게
하고 싶지 않을 뿐입니다.

출처 http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&pageno=11&detail=1&wid=20
posted by 뚱2

동기화 모드로 InternetOpenUrl 함수를 사용하다 보니 블러킹 상태에 대한
조치가 필요해서 InternetSetOption 함수의 Timeout 인자를 설정했지만
안먹더군요... 그래서 인터넷을 뒤진 결과 MS 버그 ㅡㅡ;
결국 MS에서 알려준 방법대로 스레드로 처리하긴 했습니다.
뭐 이건 배보다 배꼽이 더큰 경우라고 할 수 있네요...
#include "windows.h"
#include "wininet.h"
#include "iostream.h"

DWORD WINAPI WorkerFunction( LPVOID ); 
HINTERNET g_hOpen, g_hConnect;

typedef struct 
{
   CHAR* pHost;
   CHAR* pUser;
   CHAR* pPass;
} PARM;

void main()
{
   CHAR    szHost[] = "localhost";
   CHAR    szUser[] = "JoeB";
   CHAR    szPass[] = "test";
   CHAR    szLocalFile[] = "localfile";
   CHAR    szRemoteFile[] = "remotefile";
   DWORD   dwExitCode;
   DWORD   dwTimeout;
   PARM    threadParm;

   g_hOpen = 0;
   if ( !( g_hOpen = InternetOpen ( "FTP sample", 
                                    LOCAL_INTERNET_ACCESS, 
                                    NULL, 
                                    0, 
                                    0 ) ) )
   {         
       cerr << "Error on InternetOpen: " << GetLastError() << endl;
       return ;
   }

   // Create a worker thread 
   HANDLE   hThread; 
   DWORD    dwThreadID;
   threadParm.pHost = szHost;
   threadParm.pUser = szUser;
   threadParm.pPass = szPass;

   hThread = CreateThread(
                 NULL,            // Pointer to thread security attributes 
                 0,               // Initial thread stack size, in bytes 
                 WorkerFunction,  // Pointer to thread function 
                 &threadParm,     // The argument for the new thread
                 0,               // Creation flags 
                 &dwThreadID      // Pointer to returned thread identifier 
             );    

   // Wait for the call to InternetConnect in worker function to complete
   dwTimeout = 5000; // in milliseconds
   if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
   {
       cout << "Can not connect to server in " 
            << dwTimeout << " milliseconds" << endl;
       if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
       // Wait until the worker thread exits
       WaitForSingleObject ( hThread, INFINITE );
       cout << "Thread has exited" << endl;
       return ;
   }

   // The state of the specified object (thread) is signaled
   dwExitCode = 0;
   if ( !GetExitCodeThread( hThread, &dwExitCode ) )
   {
       cerr << "Error on GetExitCodeThread: " << GetLastError() << endl;
       return ;
   }

   CloseHandle (hThread);
   if ( dwExitCode )
   // Worker function failed
      return ;

   if ( !FtpGetFile ( g_hConnect, 
                      szRemoteFile,
                      szLocalFile,
                      FALSE,INTERNET_FLAG_RELOAD, 
                      FTP_TRANSFER_TYPE_ASCII,
                      0 ) )
   {
       cerr << "Error on FtpGetFile: " << GetLastError() << endl;
       return ;
   }

   if ( g_hConnect )
       InternetCloseHandle( g_hConnect );
   if ( g_hOpen )
       InternetCloseHandle( g_hOpen );

   return ;
}

/////////////////// WorkerFunction ////////////////////// 
DWORD WINAPI 
WorkerFunction(
   IN LPVOID vThreadParm
)
/*
Purpose:
   Call InternetConnect to establish a FTP session  
Arguments:
   vThreadParm - points to PARM passed to thread
Returns:
   returns 0  
*/ 
{
   PARM* pThreadParm;
   // Initialize local pointer to void pointer passed to thread
   pThreadParm = (PARM*)vThreadParm;
   g_hConnect = 0;

   if ( !( g_hConnect = InternetConnect (
                            g_hOpen, 
                            pThreadParm->pHost,
                            INTERNET_INVALID_PORT_NUMBER,
                            pThreadParm->pUser,
                            pThreadParm->pPass,
                            INTERNET_SERVICE_FTP, 
                            0,
                            0 ) ) )
   {
       cerr << "Error on InternetConnnect: " << GetLastError() << endl;
       return 1; // failure
   }
   
   return 0;  // success
}

원본은 요기 ↓
http://support.microsoft.com/default.aspx?scid=kb;en-us;224318

posted by 뚱2

예외 처리에 관해서

일반 2008. 9. 16. 00:09

전 아직 초보 프로그래머 입니다.
그래서 더 많이 배우고 공부하는 중입니다. ^^;

대부분의 사람들이 말중에서 예외처리==에러처리 같은 단어로 사용합니다.
저도 예외상황에서 예외처리라고 말하기 보다는
'뭐야~~~ 에러났네...' 이렇게 이야기 합니다.
프로그램이 컴파일되고 실행이 되면은 이후부터는 예외사항라고 보는게
맞을겁니다. 물론 문맥에 따라서 같은 말도 다른의미로 사용되니까 적절히
사용하면 될거라고 생각됩니다. (이런걸 다형성이라고 하나요...???)

모든 걸 다 예외처리를 할 수는 없고 나름데로 중요한걸 정해야 하는것 같습니다.

제 나름데로 일반적으로 꼭 처리해야할 예외상황은
1. 파일 오픈이 제대로 되는지...
2. 포인터가 엉뚱한 곳을 가리키는지...
3. 리소스나 메모리 부족한지...

그리고 이제 프로그램에 따라서 중요도가 틀려지니
자신이 특히 중요하다고 생각되는 함수나 메소드는 예외처리를
꼭 해줘야 겠지요...

예외처리 다 해주면 좋지만 이또한 성능에 직결되는 문제고, 소스도 복잡해 집니다.
과유불급이라고 적정한 곳에 적절히 사용하는 지혜가 필요할것 같습니다.

ps. 이넘의 '적절히'라는 단어가 무지 어렵네요

posted by 뚱2
* 그룹정책 프로그램 실행
[시작] -> [실행] -> [gpedit.msc] 입력 Enter

* 설정
[사용자구성] -> [관리템플릿] -> [작업 표시줄 및 시작 메뉴]

// 오른쪽 메뉴에서
[최근에 사용한 문서 기록을 보관 안 함] 사용
[종료 시 최근에 사용한 문서 기록 지우기] 사용

'뚱2's 이야기' 카테고리의 다른 글

T61P 14.1 UXGA  (2) 2009.02.28
Tistroy 카테고리를 펼쳐보자...  (0) 2009.02.18
Takata04-neo  (0) 2008.08.17
Sony HANDYCAM HDR-TG1  (0) 2008.07.19
SanDisk Extreme III  (2) 2008.07.19
posted by 뚱2

Takata04-neo

뚱2's 이야기 2008. 8. 17. 14:18

울딸이 100일이 넘어서 이제 슬슬 카시트를 살펴봤습니다.
구입목록에 있던 제품은 브라이텍스, 레카로인데
브라이텍스는 좀 더워보이더군요
특히 우리딸이 더위를 많이 타서 결국 제외, 레카로를 구입할려고 알아 봤습니다.
그런데 환율이 올라서 올해 초보다 레카로 가격이 많이 올랐더군요
그렇게 며칠을 고민하던 차에 타카타라는 제품을 알게되었습니다.
우선 가장 중요한 안전성도 좋고 만든 짜임세도 좋고 승차감도 좋고
사람들 평을 읽어보니 다 좋았습니다.
다만 이번에 정식 수입된 제품인데 가격이 엄하더군요 ㅡㅡ;
가격을 비교하셔 구입하려고 준비중에 일본이랑 수입제품이랑 가격차이가
많이 나서 바로 배송대행으로 구입하였습니다.
시험삼아 집에서 딸 며칠 앉혀보니 울딸이 잘 앉아있어서 좋더라구요
다른 부분보다 쿠션 부분이 부드럽게 되어 있고 안전띠 부분을 쿠션으로 커버해서
아기 피부가 상처나지 않고 답답하지 않게 잘 만들어진게 마음에 듭니다.


사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

'뚱2's 이야기' 카테고리의 다른 글

Tistroy 카테고리를 펼쳐보자...  (0) 2009.02.18
최근에 사용한 문서 지우기  (0) 2008.09.12
Sony HANDYCAM HDR-TG1  (0) 2008.07.19
SanDisk Extreme III  (2) 2008.07.19
드디어 노트북 밀었다~~~!!  (0) 2008.06.20
posted by 뚱2

VC++ 빠르게 컴파일 하기 위해서 Precompiled header 라는 것을 만들어둡니다.
그런데 다른 외부의 컴파일러로 만들어진 라이브러리(소스)에서는 이게 없습니다.
그래서  VC++에서는 프리컴파일 헤더가 필요하다고 에러를 발생시킵니다.

해결방법은 포함하는 라이브러리 소스(.cpp) 맨 윗줄에 #include "stdafx.h"
추가해 주시면 됩니다.

posted by 뚱2

RasAPI를 사용하여 간단하게 접속하는 프로그램을 작성했습니다.
그런데 디버그 모드에서는 너무나도 잘 되는게 릴리즈 모드에서만 되면은
안되더라구요.

이것 저것 하루종일 삽질(?)을 하다가 결국 초기화 문제였습니다. ㅠㅠ
초기화 되지 않은 포인터의 경우 디버그 모드에서는 자동으로 임의값 0xCD로
초기화를 수행하지만 릴리즈에서는 수행하지 않는다고 합니다.
그래서

// 수정전
m_RasDialParams.dwSize = sizeof(RASDIALPARAMS);

...

// 수정후
ZeroMemory(&m_RasDialParams, sizeof(RASDIALPARAMS));
m_RasDialParams.dwSize = sizeof(RASDIALPARAMS);

...

이렇게 해주니까 잘~~~~~ 됩니다.
정말 단순한거지만 너무 중요한 사항같습니다.
초기화 생활화 합시다.

posted by 뚱2