2008년 5월 25일 일요일

bool과 BOOL의 차이

 






1.요약
bool과 BOOL의 차이에 대해 알아본다.


2.본문
- bool : 기본 C++의 데이터 타입, 1바이트의 크기
true, false값만 갖는다. true와 false 역시 C++의 기본 키워드
- BOOL : MFC에서 정의되어 있는 데이터 타입, 1바이트가 아니라 4바이트의 크기
TRUE, FALSE 값을 갖고 true와 false 역시 가능
TRUE와 FALSE역시 MFC에서 정의되어 있는 키워드

3.예제

CString msg; 

msg.Format("bool's sizeof : %d, BOOL's sizeof : %d",sizeof(bool), sizeof(BOOL)); 

AfxMessageBox(msg); 

4.결과 bool's sizoef : 1, BOOL's sizeof : 4


사용자 삽입 이미지

5.참고

MSDN 에서 찾아보니 아래와 같은 글이 있었습니다.

Microsoft Specific

In Visual C++4.2, the Standard C++ header files contained a typedef that equated bool with int. In Visual C++ 5.0 and later, bool is implemented as a built-in type with a size of 1 byte. That means that for Visual C++ 4.2, a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the same call yields 1. This can cause memory corruption problems if you have defined structure members of type bool in Visual C++ 4.2 and are mixing object files (OBJ) and/or DLLs built with the 4.2 and 5.0 or later compilers.

즉, 4.2에서는 int 와 같은 형으로 선언이 되어 있었는데, 후에 built-in type 으로 바뀌면서 1 byte로 바뀌었다는 군요..



- 2001.08.13 Smile Seo -

출처 : http://www.debuglab.com/knowledge/bool.html

[Win] 윈도우에서 소켓 프로그래밍 하기 위한 환경 설정

MFC Socket
#include <afxsock.h>


만들고자하는 App 클래스의 InitInstanceApp() 함수에서

AfxSocketInit();

로 소켓 사용을 초기화 한다

내부적으로는 WSAStartup() 으로 구현되어있으며, 해제시의 WSACleanup() 은 자동 호출된다.


CAsyncSocket은 비동기 소켓(non-blocking)
CSocket은 동기 소켓(blocking)





Win32 API Socket (WSA)


1]. 윈도우즈 소켓을 위한 헤더와 라이브러리 설정

1. Header : 헤더파일 추가
          Win32 : winsock.h
          Win32-II : winsock2.h

2. Import Library : winsock2.h 헤더파일을 포함하기위해 WS2_32.LIB 라이브러리를
                            링크시켜야 한다.
          Win32 : wsock32.lib
          Win32-II : ws2_32.lib  VC++ 에서 Alt-F7 프로젝트 속성에서 Link에 추가한다.
사용자 삽입 이미지


2]. 윈속 초기화 하기


WSADATA       wsaData;                                                     //WinSock을 위한 내부 자료구조

WORD            wVersionRequested = MAKEWORD(2, 2);    
// WinSock 버전을 위한 부분(WinSock 2.2 를 의미한다,
// MAKEWORD 매크로함수는 winsock2.h에 구현되어 있음)


WSAStartup(wVersionRequested, &wsaData);                   //WinSock 사용 초기화






3]. 윈속 리소스 해제

WSACleanup();



4]. 참고

BSD계열 API로

socket()

bind()

listen()

connect()

send()

recv()

closesocket()          
// close 대신 closesocket()을 사용한다


ioctlsocket()            
//  ioctl 이나  fcntl 대신 ioctlsocket()을 사용한다(non-Blocking mode로 변경시 주로 사용)


기본적으로  WSA 소켓은 디폴트로 Blocking I/O 모드로 작동하며, ioctlsocket()으로
non-Blocking 모드로 변경이 가능하다



참고 : http://blog.naver.com/agnazz?Redirect=Log&logNo=100018139151

2008년 5월 18일 일요일

Window 관련 API

1. IsWindow()

사용자 삽입 이미지


2. IsWindowEnabled()

사용자 삽입 이미지


3. EnumWindows() - 윈도우 열거

사용자 삽입 이미지


4. EnumWindows() - 윈도우 열거
    BOOL EnumWindows(
      WNDENUMPROC
lpEnumFunc// pointer to callback function  
      LPARAM
lParam            // application-defined value
    );



@

2008년 5월 15일 목요일

MFC SDI 프로그램 최대화 시작

MFC SDI 프로그램 최대화 시작






 BOOL CInternetTamApp::InitInstance() 함수 안에 보면 다음과 같은 코드가 있다.
사용자 삽입 이미지
ShowWindows(SW_SHOW); 를 다음과 같이 변경
ShowWindows(SW_SHOWMAXIMIZED);

사용자 삽입 이미지

MFC TiltleBar(타이틀 바) 글씨 변경하기

MFC TiltleBar(타이틀 바) 글씨 변경하기






 MFC에서 윈도우의 제목을 변경하는 방법에는 여러 가지가 있다.


(방법 1)
사용자 삽입 이미지                                                                  ↕
사용자 삽입 이미지


CWinApp에서 파생한 클래스의 InitInstance()에서 CWnd의 멤버함수 SetWindowText를 사용한다.

새 파일을 열게 되면 원래대로 바뀐다. 계속 바뀐 제목을 유지하려면 파일을 열거나 새 파일을
선택할 때 불리는 함수에도 적당히 처리해 주어야 할 것이다.

        .................
        // The one and only window has been initialized, so show and update it.
        m_pMainWnd->ShowWindow(SW_SHOW);
        m_pMainWnd->UpdateWindow();

        m_pMainWnd->SetWindowText("개인 정보관리");

        return TRUE;
}



(방법 2)

String Table에 필요한 내용을 보관한 다음 필요할 때(런타임시) 그 문자열을 로드하여 사용하는
방법이 있다.

1. String Table에 다음 그림과 같이 문자열 리소스를 추가한다. String Table 아무데나 추가해도
상관은 없다.

사용자 삽입 이미지
코드는 애플리케이션 클래스의 Initinstance()에서 다음과 같이 처리한다.

        // The one and only window has been initialized, so show and update it.
        m_pMainWnd->ShowWindow(SW_SHOW);
        m_pMainWnd->UpdateWindow();

        CString strTitle;
        strTitle.LoadString(IDS_PIMTITLE);
        m_pMainWnd->SetWindowText(strTitle);
        return TRUE;
}


(방법 3)
프로그램 코드를 수정하지 않고, String Table 에 있는 'IDR_MAINFRAME' 문자열의 맨 처음
문자열이 메인 프레임의 제목을 나타내기 때문에 이것을 '개인 정보관리'로 변경하는 수도
있다.


사용자 삽입 이미지
이렇게 하면 'IDR_MAINFRAME' 문자열의 2번째 문자열의 2번째 문자열(\n과 \n사이)에 아무 것도
저정되어 있지 않기 때문에 MFC 프레임워크는 메인 프레임의 제목에 '제목없음 - '라고 표시한다.


사용자 삽입 이미지

문서 이름과 애플리케이션의 이름을 바꾸려면 FWS_PREFIXTITLE 스타일을 제거하면 된다.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
        if( !CFrameWnd::PreCreateWindow(cs) )
                return FALSE;
        // TODO: Modify the Window class or styles here by modifying
        //  the CREATESTRUCT cs
       
        cs.style &= ~FWS_PREFIXTITLE;
        return TRUE;
}



사용자 삽입 이미지

'제목없음 - '이라고 표시된 내용을 없애려면 CMainFrame 클래스에서 PreCreateWindow 메시지를
잡아 해당 문서 이름이 없을 때에 '제목없음 - ' 가 표시되게 하는 내용을 제거하도록 코드를 수정하는
 것이다.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
        if( !CFrameWnd::PreCreateWindow(cs) )
                return FALSE;
        // TODO: Modify the Window class or styles here by modifying
        //  the CREATESTRUCT cs

        cs.style &= ~FWS_ADDTOTITLE;
        return TRUE;
}



(Tip) MFC로 SDI 프로젝트 생성 시  기본적으로 생성되는 윈도우 스타일에는  FWS_ADDTOTITLE  스타일이 추가 된다.
 FWS_ADDTOTITLE  는 프레임 워크에서 창의 캡션에 문서 제목을 추가하도록 명령하는  MFC 관련 스타일 이다.
 이 속성을 제거해야 타이틀 바의 이름이 변경되지 않음을 확신 할 수 있다.

BOOL CMainFrmae::PreCreateWindow(CREATESTRUCT& cs);
{
      // 이미 설정된 정보에서 FWS_ADDTOTITLE 속성의 제거.. 
      cs.style &= ~FWS_ADDTOTITLE;
      // cs.style = cs.style & (~FWS_ADDTOTITLE); 
      return CFrameWnd::PreCreateWindow(cs);

MFC icon 변경하기

MFC 아이콘 변경하기




 MFC에서 아이콘 변경하기는 정말 별것 아니기 때문에
인터넷에서 도는 자료도 빈약하게 설명...
그래서 난 헤매었다. -_-;;;

 일반적인 화면의 아이콘

일반적인 화면 아이콘






변경해보자!!

1. 원하는 아이콘을 프로젝트의 res 폴더에 넣어주자.
사용자 삽입 이미지




2. Resource View 에서 Icon 에서 원하는 아이콘 파일을 Import 해주자import


3.  현재 아이콘은 IDR_MAINFRAME 에 정의되어 있다.
   IDR_MAINFRAME을 선택하여 아이콘 그림을 지우자 (Delete 키를 누르면 쏙~ 지워짐)

IDR_MAINFRAME



4. Import 한 아이콘을 선택하여 복사를 한다. (ctrl + c)
   그런 후 IDR_MAINFRAME 에서 붙여넣기를 한다. (ctrl + v)

붙여넣기



5. 보통 여기서까지 하면 끝일꺼 같지만 이렇게 하고 컴파일 해보면
  바껴있지가 않다 -_-;;;;
  프로그램에서 사용하는 아이콘은 2가지가 필요하다
  하나는 16 * 16 사이즈 아이콘
  또다른 하나는 32 * 32 사이즈 아이콘
  위에서 바꿘것은 보다싶이 32 *32 사이즈 아이콘만 바꿔준 것이다.
  (Device : Standard(32 * 32))
  16 * 16 사이즈를 선택하여 위와 같이 바꾸어 주자
  사용자 삽입 이미지



6. 실행시켜 보면 아이콘은 바껴 있기는 한데 색이 깨져있다.
 사용자 삽입 이미지

Visual C++ 에서는 기본적으로 256색 아이콘만 지원한다 하던데 그래서 그런건가???
다른 방법이 있는지는 모르겠다 -_ㅜ








256색 이상의 이미지 리스트 만드는 방법 





출처 : http://blog.naver.com/yadangcs/50012456667





2008년 5월 8일 목요일

direct.h 의 디렉토리 관련 함수

#include <direct.h>


_getcwd()                // 현재 작업중인 디렉토리 전체 경로
_chdir()                 // 현재 작업중인 디렉토리 변경하기
_getdirve()             // 현재 작업중인 드라이브명 구하기
_chdirve()              // 현재 작업중인 드라이브 변경하기


함수별 인수는 MSDN 참조하자!!






1. 현재 디렉토리 전체경로 구하기



    #include <direct.h>

    // 현재 디렉터리 표시
    char buff[256];
    _getcwd(buff, 255);

사용자 삽입 이미지



2. 현재 디렉토리 변경 - _chdir()



   
    #include
 <direct.h>
   
    CString m_strLocaldir;

    // 디렉터리 변경
    _chdir(m_strLocalDir);


사용자 삽입 이미지

_chdir() 함수로 현재 작업중인 디렉토리를 변경해
준 다음 _getcwd() 함수로 경로를 구하면
바뀐 경로가 구해진다.
 따라서 _chdir(), _getcwd() 함수를 이용하면
사용자 컴퓨터의 디렉토리 구조를 탐색할 수 있다.

CF). 폴더 및 파일 출력은 여러 방법이 있지만
       가장 쉬운 방법은
        ListBox 컨트롤의 .Dir 함수를 이용하면
        쉽게 출력 가능
        - Visual C++ 6.0 완벽가이드 2nd Edition
           김용성 저, p)1394
























@

2008년 5월 7일 수요일

Dialog based 프로그램 작성시 Enter, ESC Key 처리

Dialog based 프로그램 작성시 Enter, ESC Key 처리

 보통 Dialog based 기반으로 프로그램 작성시
특별하게 Enter key 에 대한 처리 루틴을 만들지 않으면
Enter key를 누르면 프로그램이 종료 된다.

(VC++로 생성한 모든 프로그램은 특별히 변경시키지 않는 이상 Ente Key를 누르면
 'IDOK' 라는 메시지가 발생함. 이런 이유 때문에 Dialog 기반으로 만든 프로그램에서는
 엔터키를 누르면 프로그램이 종료됨.)





방법1. Enter Key 처리
IDOK 에 대한 메시지 처리기를 만들지 않아도 자동적으로 먹는거 같다.

사용자 삽입 이미지

특별히 Enter key 에 대한 메시지 처리 루틴이 없다면
아무 동작도 하지 않게 작성해 놓는 것이 좋다.

사용자 삽입 이미지




방법2. Enter, ESC key 처리
PreTranslateMessage 함수 Overriding
아직 공부하지 않았지만 "후킹" 이란 방법을 이용한 것임.

BOOL CManagerClientDlg::PreTranslateMessage(MSG* pMsg)
{
  if (pMsg->message == WM_KEYDOWN) {
        if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) {
      // VK_RETURN  : Enter Key
      // VK_ESCAPE  : ESC key
           
      return TRUE;
        }
    }
 
  return CDialog::PreTranslateMessage(pMsg);
}




@

2008년 5월 6일 화요일

SYSTEM_INFO 구조체를 이용한 사용자 정보 얻기

SYSTEM_INFO 구조체를 이용한 사용자 정보 얻기





1. Processor(CPU) 의 개수 얻기 - .dwNumberOfProcessors

    #include <windows.h>

    SYSTEM_INFO systemInfo;
    CString strTemp;

    GetSystemInfo(&systemInfo);
    strTemp.Format("Processor(CPU)의 개수 :
                             %d"
, systemInfo.dwNumberOfProcessors);
    dc.TextOut(10, 10, strTemp);

CPU 개수
         cf). CPU가 1개 이어도 듀얼코어 일 경우 2개라고 체크 된다고 한다.



이밖에도 많은 멤버가 있는데
필요할때 찾아보면 될듯....
http://msdn.microsoft.com/en-us/library/ms724958.aspx




사용자 정보 구하는 API

사용자 정보 구하는 API



1. system32 폴더의 위치 알아내기 - GetSystemdirectory()
 
  char
 sysDir[MAX_PATH];
  GetSystemDirectory(sysDir, MAX_PATH);


system32 폴더의 위치


2. Windows 가 설치된 폴더의 전체 경로 얻기 - GetWindowsDirectory()




    #include
 <windows.h>

    char windir[MAX_PATH];
    CString strTemp;
    GetWindowsDirectory(windir, MAX_PATH);

Windows 가 설치된 폴더의 전체 경로





3. 실행 프로그램의 경로 얻기 - GetCurrentDirectory()




    char current[256];
    GetCurrentDirectory(256, current);




4. 사용자 이름 얻기 - GetUserName()
 
    #include
 <windows.h>

    CString m_strComName;
    char szBuffer[MAX_COMPUTERNAME_LENGTH+1];
    DWORD dwcNameSize = MAX_COMPUTERNAME_LENGTH +1;

    GetUserName(szBuffer, &dwcNameSize);
    m_strComName.Format("사용자 이름 : %s", szBuffer);
    dc.TextOut(10, 10, m_strComName);

사용자 이름

    cf) #include<windows.h> -> #define MAX_COMPUTERNAME_LENGTH 31



5. 사용자 컴퓨터 이름 얻기 - GetComputerName()

    #include <windows.h>
   
    CString m_strComName;
    char szBuffer[MAX_COMPUTERNAME_LENGTH+1];
    DWORD dwcNameSize = MAX_COMPUTERNAME_LENGTH +1;

    GetComputerName(szBuffer, &dwcNameSize);
    m_strComName.Format("컴퓨터 이름 : %s", szBuffer);
    dc.TextOut(10, 10, m_strComName);

Computer 이름 얻기



6. 사용자 컴퓨터 로컬 시간 얻기 - GetLocalTime()                         VOID GetLocalTime(LPSYSTEMTIME lpSystemTime);
로컬 시간을 조사해 준다. 로컬 시간이란 시스템이 유지하는 시스템 시간(UTC)에서

현재 컴퓨터가 실행되고 있는 시간대와 일광절약 설정을 계산하여 변환한 시간이다.

대한민국의 로컬 시간은 UTC 시간보다 9시간 더 빠르므로 시스템 시간에서 9시간만큼

더해주어야 로컬 시간이 구해진다. 일반적으로 현지 시간이라고 하면 이 함수로 구해지는로컬 시간을 의미한다.

    SYSTEMTIME tm;
    GetLocalTime(&tm);              // 정보 얻은 현재 시간 구함
    wsprintf(str, "(마지막으로 조사한 시간: %d시 %d분 %d초)",
                               tm.wHour, tm.wMinute, tm.wSecond);
    TextOut(hDC, 25, 215, str, strlen(str));







--------- # Network, Socket 관련 ----------
7. 호스트 컴퓨터 IP Address 얻기
    #include <winsock2.h>
    #include <windows.h>

    char localHostName[256];
    IN_ADDR in_addr;
    HOSTENT *pHost;
    char ip[20];

    memset(localHostName, 0x00, 256);
    gethostname(localHostName, 256);
    pHost = gethostbyname(localHostName);
    memcpy(&in_addr, pHost->h_addr, 4);
    strcpy(ip, inet_ntoa(in_addr));

    CString strTemp;
    strTemp.Format("IP Address : %s", ip);
    dc.TextOut(10, 10, strTemp);

사용자 삽입 이미지
         cf). DLL을 불러오고 초기화, 해제 시켜주는 추가 작업 필요함!!









--------- ----------



8. 컴퓨터가 부팅된 모드 알아내기 - GetSystemMetrics(SM_CLEANBOOT)
    #include <windows.h>

    int iBootMode;
    CString strTemp;

    strTemp.Format("Booting Mode : ");
    iBootMode = GetSystemMetrics(SM_CLEANBOOT);

    switch (iBootMode) {
    case 0:
      strTemp = strTemp + "일반모드";
      dc.TextOut(10, 10, strTemp);
      break;
    case 1:
      strTemp = strTemp + "안전모드";
      dc.TextOut(10, 10, strTemp);
      break;
    case 2:
      strTemp = strTemp + "네트워크 연결 안전모드";
      dc.TextOut(10, 10, strTemp);
      break;
    }

Booting mode


<< 추가중 !! >>



// EnumWindows procedure

BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam)

{

        char str[BUFSIZE];                                                            // 리스트박스에 넣어주기위해 문자저장

        char Cap[BUFSIZE];   // 캡션저장

        char sClass[BUFSIZE]; // 클래스저장

        DWORD dwStyle;

       

        // 열거된 윈도우의 스타일 조사

        dwStyle = GetWindowLong(hwnd, GWL_STYLE); 

       

        // 현재 style이 visible & overlapped인 윈도우를 찾는다.

        if ((dwStyle & WS_VISIBLE) == WS_VISIBLE

                && (dwStyle & WS_OVERLAPPED) == WS_OVERLAPPED

                && (dwStyle & WS_SYSMENU) == WS_SYSMENU) {

                GetWindowText(hwnd, Cap, 256);// 각 열거된 윈도우의 캡션 구함

                GetClassName(hwnd, sClass,256);// 각 열거된 윈도우의 클래스 명 구함

                strcpy(ClientInfor.window[ClientInfor.cbWindow].caption, Cap);// ClientInfor 구조체에 캡션명 저장

                // ClientInfor 구조체에 클래스 명 저장                    

               strcpy(ClientInfor.window[ClientInfor.cbWindow].classname, sClass);

                wsprintf(str, "%s", Cap);

                SendMessage(hList,LB_ADDSTRING,0,(LPARAM)str);

                ClientInfor.cbWindow++;

        }

               

        return TRUE;

}