2008년 6월 25일 수요일

MFC 에서 구조체 전역 변수로 사용하기

MFC 에서 구조체 전역 변수로 사용하기




 프로그램을 작성 하던중 클래스의 멤버 함수가 아닌 전역 함수를 사용 하려다 보니
자연스래 전역변수가 필요하게 되었다. 물론 전역변수의 사용은 좋은 현상은 아니지만...
 Win32 API 에선 쉽게 전역변수를 사용 했는데 MFC 프로젝트에서 사용 하려다 보니
쉽지만은 않은것 같다. c/c++ 문법책 본지는 오래 되었고, MFC 구조는 깊숙히는 모르다 보니...
그래도 한번 시도해 봤다.

 MFC wizard 가 생성한 프로젝트 에서는 stdafx.cpp 파일을 제외하고선
모두 stdafx.h 파일을 포함한다. (#include "stdafx.h")
따라서 이곳에 전역변수를 선언해 두면 프로젝트 내에 모든 cpp 파일에서 참조할 수 있다.
(변수 뿐만 아니라 함수, 상수등도 정의 가능)



1. 일반 변수의 전역변수 사용의 예

// StdAfx.h
extern int g_nData;

// StdAfx.cpp
int g_nData = 0;

프로젝트 내 cpp 파일에서 바로 g_nData 전역변수에 접근 가능




2. 구조체의 전역변수 사용의 예
    - 헤더 파일(.h)에 구조체를 정의 한다.
    - 변수의 선언과 초기화는 소스파일(.cpp)에 해준다.
    - 다른 소스파일에서 위에 선언한 변수를 사용하기 위해선
      헤더파일에 "extern" 키워드를 이용해서 선언해 주고
      소스 파일에서 사용해 주면 된다.

// stdafx.h
struct CLIENTDATA {
  char arrUserName[32];         
  char arrComName[32];        
  int iAppNum;             
};



// stdafx.cpp
#include "stdafx.h"

CLIENTDATA structClientData;



// main.h




extern CLIENTDATA structClientData;


// main.cpp
structClientData.iAppNum = 10;






참고)
1. Compile 의 대상은 header 파일이 아니라 Source 파일이다.
    (Compiler 수업을 좋은 성적에 클리어 했는데 벌써 긴가민가....)
2. Header 파일에 변수를 선언 할 수 없다.
   선언하면 다음과 같은 에러 메시지가 출력된다.
   error LNK2005: "int a" (?a@@3HA) already defined in ManagerClient.obj

@

2008년 6월 21일 토요일

VC++ 버그 - Document보다 View가 먼저 include 될때

VC++ 버그 - Document보다 View가 먼저 include 될때




사용자 삽입 이미지

 VC++ 의 대표적인 버그로서
Document 보다 View 부분이 먼저 include 되서 생기는 문제 이다.

해결방법은
Error 가 난 클래스의 cpp 파일에 있는 #include "***.h"  부분을
클래스의 헤더파일(.h)로 이동시키면 된다.

2008년 6월 9일 월요일

[PictureCtrl] Picture Control 에 icon 파일 출력 시키기

Picture Control 에 icon 파일 출력 시키기




 내가 보는 책에는 Picture contro 에 대한 예제가 없더라.
그리 활용성, 유용성이 떨어지나??




 

1. 출력에 사용할 icon 파일을 리소스에 import
사용자 삽입 이미지

       - IDI_ICON1 등록




2. 출력할 Dialog 에 Picture control 을 추가

     속성에서

       - Type : Icon

       - Image : IDI_ICON1 (위에서 등록한 아이콘의 ID를 선택한다.)
사용자 삽입 이미지

 
3. 이것으로 Dialog 에 아이콘 파일이 출력이 된다.
사용자 삽입 이미지

@









MFC 에서 파일을 다룰때 실행 프로그램의 경로

MFC 에서 파일을 다룰때 실행 프로그램의 경로


 VC++(MFC) 에서 파일을 다룰 때 ".\\" 를 사용하면
현재 프로그램이 실행되는 폴더를 기준으로 파일 관련 동작을 하게 된다.

 이 점을 몰랐을때는 GetCurrentDirectory() API 를 사용했었는데
이렇게 간단할 줄이야.

2008년 6월 6일 금요일

GetForegroundWindow() 시스템의 최상위 윈도우(프로그램) 구하기

GetForegroundWindow() 
시스템의 최상위 윈도우(프로그램) 구하기




■ 함수 원형

HWND GetForegroundWindow(void);




■ 사용 예

HWND hForeWindow;

hForeWindow=GetForegroundWindow();

if (hForeWindow == hwnd) {

        GetWindowText(hwnd, strTemp, BUFSIZE);

}

wsprintf(str, "Active Window          :  %s", strTemp);

TextOut(hDC, 25, 195, str, strlen(str));




■ Semantic

즉, 현재 OS(window)에서 한글 프로그램을 사용중이면 한글 윈도우의 핸들을

winamp 를 실행중이면 winamp의 핸들을 리턴한다.

2008년 6월 4일 수요일

GetLogicalDriveStrings(), GetDriveType()

GetLogicalDriveStrings(), GetDriveType()




사용자 삽입 이미지
  cf). LPTSTR : NULL문자로 끝나는 유니코드 도는 윈도우 문자열의 포인터
        성공시 : 버퍼에 복사된 문자열의 길이(끝의 NULL 문자는 포함하지 않은 길이)
        실패시 : zero

  cf). char pTmp[256];
        GetLogicalDriveStrings(256, pTmp);

    pTmp[256]




사용자 삽입 이미지
GetDriveType(strDrive);
// 인수에는 각, "C:\", "D:\", "E:\" 가 들어간다.


사용자 삽입 이미지



예제 소스
CString strStatus;    // 드라이브 타입명 저장
  CString strDrive;    // 논리적 드라이브명 임시 저장
  char pTmp[256];      // local drive 이름의 나열 저장
  memset(pTmp, '\0', 256);
 
  // 논리적 드라이브 정보 얻기
  GetLogicalDriveStrings(256, pTmp);

  for(int i=0 ; i<256 ; i++) {
    if(pTmp[i] == '\0' && pTmp[i+1] == '\0')
      break;
   
    strDrive.Empty();
    while(pTmp[i] != '\0')
      strDrive += pTmp[i++];

    switch(GetDriveType(strDrive)) {
    case DRIVE_CDROM:
      strStatus = "CD-ROM 드라이브";
      break;
    case DRIVE_REMOVABLE:
      strStatus = "플로피 디스크";
      break;
    case DRIVE_FIXED:
      strStatus = "로컬 디스크";
      break;
    default :
      strStatus = "알수없는 디스크";
      break;
    }
  }
}






@

OnPaint() OnDraw() 에 관하여

OnPaint() OnDraw() 에 관하여




1. OnPaint(), OnDraw() 함수는 Client영역을 다시그려줘야 할 필요가 있을 때 호출되는 함수 이다.
사용자 삽입 이미지

2. Client영역을 다시 그려줘야함 → WM_PAINT → OnPaint → OnDraw
   즉, OnPaint 는 윈도우 메시지에 의해 호출되는 메시지 처리기 함수 이고,
   OnDraw 는 OnPaint 함수에서 호출되는 함수 이다.

                                       virtual void OnDraw( CDC* pDC ) = 0;
                                       afx_msg void OnPaint( );

사용자 삽입 이미지


@