■ 파일 열고 닫기 함수 : Open()과 Close()

 CFile file ;

 file.Open(_T("File.txt"), CFile::modeCreate| CFile::modeWrite ) ;

 // ... 파일에 데이터를 읽거나 쓰는 작업 수행

 file.Close() ;

 

。Open 함수의 매개 변수

- 첫번째 arg : 파일명 

- 두번째 arg : 파일 접근 모드와 공유모드 정의. OR(|) 연산자를 이용하여 여러 개 조합.

- 기존에 이 파일이 없으면 새로운 파일이 생성되고 있으면 기존 파일의 맨 뒤에 새로 쓰는 데이터를 덧붙인다.

 

。 파일 접근 모드

 접근 모드  설명
 CFile::modeRead  파일 읽기만 가능
 CFile::modeWrite  파일 쓰기만 가능
 CFile::modeReadWrite  파일 읽고 쓰기 모두가능
 CFile::modeCreate  파일 새로 생성
 CFile:modeNoTruncate  기존에 파일 데이터가 존재 시 맨 뒤에 추가하지 않고 덮어쓴다.

 

。파일 공유 모드

 공유 모드  설명
 CFile::shareDenyNone  공유하도록 파일 열기
 CFile::shareDenyRead  다른 프로그램의 읽기 접근 거부
 CFile::shareDenyWrite  다른 프로그램의 쓰기 접근 거부
 CFile::shareExclusive  다른 프로그램의 읽기, 쓰기 모두 거부

 

 

■ 파일 데이터 쓰기 함수 : Write()

- 우선 파일을 '쓰기 모드'로 연다.

 int buffer[1000] ;

 CFile file ;

 file.Open( _T("File.dat", CFile::modeCreate | CFile::modeWrite ) ;

 file.Write( buffer, 1000 * sizeof(int) ) ;

 file.Close() ;

 

。Write 함수의 매개 변수

- 첫번째 arg : 파일에 쓰고자 하는 데이터가 저장된 메모리 포인터를 넘겨준다.

- 두번째 arg : 데이터의 크기를 바이트 단위로 넘겨준다.

 

 

■ 파일 데이터 읽기 함수 : Read()

- 우선 파일을 '읽기 모드'로 파일을 연다.

 int buffer[1000] ;

 CFile file ;

 file.Open( _T("File.dat"), CFile::modeRead ) ;

 file.Read( buffer, 1000 * sizeof(int) ) ;

 file.Close() ;

 

。Read 함수의 맴개 변수

- 첫번째 arg : 읽은 데이터를 저장할 메모리의 포인터를 넘겨 준다.

- 두번째 arg : 읽고자 하는 데이터의 크기를 바이트 단위로 넘 겨준다.

 

 

■ 파일의 길이를 알아내는 함수 : GetLength()

- 파일의 크기를 알아내고 그 크기만큼 데이터를 읽어 온다.

 CFile file ;

 file.Open( _T("File.dat"), CFile::modeRead ) ;

 int nLength = file.GetLength() ;

 int *buffer = new BYTE [nLength] ;

 file.Read( buffer, nLength ) ;

 file.Close() ;

 

 

■ 에러 처리 : TRY ~ CATCH 블록

- TRY 블록 안의 루틴을 수행하다가 실행 중 에러가 발생할 경우에만 CATCH 블록이 실행된다.

- CFileException 함수의 ReportError 함수를 호출한다.

-  ReportError 함수는 사용자에게 어떤 에러가 발생했는지 알려주는 메세지 박스를 출력해 준다.

 TRY

 {

     int buffer[1000] ;

     CFile file ;

     file.Open( _T("File.dat"), CFile::modeCreate | CFile::modeWrite ) ;

     file.Write( buffer, 1000 * sizeof(int) ) ;

     file.Close() ;

 }

 CATCH(CFileException e )

{

     e->ReportError() ;

 }

 END_CATCH

 

 

■ 파일 포인터

。현재 파일 포인터 위치 얻기 : GetPosition

- [TBD]

 

。파일 포인터 옮기기 : Seek

 file.Seek( 1000, CFile::current ) ;

 file.Read( buffer1, sizeof(int) * 10 ) ;

 file.Seek( -2000, CFile::end ) ;

 flie.Read( buffer2, sizeof(int) * 10 ) ; 

 

- Seek 함수의 매개변수

첫번째 arg : 이동 거리

두번째 arg : 이동 시 파일 포인터 기준 위치

 

- 파일 포인터의 기준 

 매개변수  설명 
 CFile::begin  기준은 파일의 처음 위치
 CFile::current  기준은 현재 파일 포인터의 위치
 CFile::end  기준은 파일의 끝 위치

 

 

■ 그 밖에 파일 처리 (기타 멤버 함수)

GetFilePath : 파일의 전체 경로명 반환

GetFileName : 파일 이름 반환

GetFileTitle : 확장자를 제외한 파일 이름 반환

GetStatus : 파일이 생성된 시간, 최종 변경된 시간, 크기, 속성 등 파일의 상태 얻기

SetStatus : 파일의 상태를 지정

Remove : 파일 지우기

Rename : 파일 이름 변경

Posted by 모과이IT
,

- 윈도우 프로그램은 하나 이상의 윈도우(윈도우 단위로 구성)를 가지고 메세지 구동 방식으로 실행됩니다.

 

■ WinMain 함수 매개변수

- 윈도우 프로그램의 main 함수

 

 int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,

                               int nCmdShow)

 

hInstance : 현재 실행을 시작하는 프로그램의 인스턴스 핸들

hPrevInstance : 이전에 실행된 동일 프로그램의 인스턴스 핸들

lpCmdShow : main 함수의 argv와 같은 기능  

nCmdShow : 프로그램의 윈도우가 어떤 모습으로 실행될 것인지 결정

                   옵션은 최소화 상태, 감춰진 상태, 보통 상태 등이 있음

 

※ 용어

인스턴스 : 프로그램이 실행되어 메모리에 로딩된 상태에 있을 때.

핸들 : 메모리에 로딩된 인스턴스 식별하기 위해 사용. 즉 윈도우 식별자

이외에도 윈도우 프로그래밍에서 '핸들'은 특정 메모리 블록을 식별하기 위한 포인터.

 

 

■ WinMain 함수의 구성

1. 프로그램을 초기화 한다.

2. 인스턴스를 초기화 한다.

3. 메세지 루프를 돈다.

 #include <windows.h>

 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

                                  LPSTR lpCmdLine, int nCmdShow)

 {

     // 프로그램 초기화

     if( !hPrevInstance )     // 인스턴스가 처음 생성되는 경우에만 실행

          if( !InitApplication(hInstance) )

               return FALSE ;

 

     // 인스턴스 초기화

     if( !hInitInstance(hInstance, nCmdShow ) )

          return FALSE ;

 

     // 메세지 루프

     return Run()

 } 

 

프로그램 초기화 : 프로그램의 인스턴스가 메모리에 처음 로딩될 때 수행해야 하는 초기화 작업

인스턴스 초기화 : 각각의 인스턴스가 메모리에 로딩될 때마다 수행해야 하는 초기화 작업

즉, 프로그램이 이미 실행되어 메모리에 인스턴스가 존재하면 두 번째 인스턴스가 생성될 때 프로그램 초기화 작업은 하지 않아도 된다. 인스턴스 초기화 작업만 하면 된다.

 

 

□ 프로그램 초기화 : 윈도우 클래스 등록

- Edit 컨트롤, Combo Box 컨트롤, List Box 컨트롤 등의 윈도우는 운영체제에 이미 클래스가 등록되어 있다. => 파생클래스로 상속을 받아 조작

- 그러나 우리가 만드는 윈도우는 새로운 기능을 가진 윈도우므로 이 윈도우 클래스를 운영체제에 새로 등록해 주어야 한다.

1. WNDCLASS 구조체에 값을 채움

2. RegisterClass 함수를 호출하여 윈도우 클래스 등록

 BOOL InitApplication( HINSTANCE hInstance )

 {

     WNDCALSS wc ;

     wc.style = CS_HREDRAW | CS_VERDRAW ;

     wc.lpfnWndProc = WndProc ;     // 함수 포인터

     wc.hInstance = hInstance ;

     wc.hIcon = LoadIcon( NULL, IDI_APPLICATION )

     wc.hCursor = LoadCursor( NULL, IDC_ARROW ) ;

     wc.hbrBackgroud = (HBRUSH)GetStockObject( WHITE_BRUSH ) ;

     wc.lpszMenuName = NULL ;

     wc.lpszClassName = "ExampleCalss" ;

     wc.cbClsExtra = 0 ;

     wc.cbWndExtra = 0 ;

 

     reutnr RegisterClass( &wc ) ;

 }

 

。WNDCLASS 구조체

 typedef struct _WNDCLASS {

     UNIT          style ;            // 윈도우 스타일

     WNDPROC lpfnWndProc ; // 윈도우 프로시저(메세지를 처리할 함수)

     int             cbClsExtra ;   // (사용하지 않음) 미래 확장을 위해 사용된 값

     int             cbWndExtra ;  // (사용하지 않음) 미래 확장을 위해 예약된 값

     HANDLE     hInstance ;    // 인스턴스 핸들

     HICON       hIcon ;           // 윈도우가 최소화 되었을 때 표시될 아이콘의 핸들

     HCURSOR  hCursor ;       // 윈도우 위로 마우스 커서가 올라갔을 때 보여질 커서의 핸들

     HBRUSH     hbrBackground ;  // 배경을 지우는데 사용할 브러시의 핸들

     LPCTSTR   lpszMenuName ;  // 이 윈도우가 소유할 메뉴

     LPCTSTR   lpszClassName ;  // 윈도우 클래스의 이름

 } WNDCLASS ;

 

 

□ 인스턴스 초기화 : 윈도우 생성

1. 핸들 정의

2. 윈도우를 생성 값을 핸들에 넘김

 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

 {

     HWND hWnd ;

     if( !(hWnd = CreateWindow("ExampleClass", "C로 만든 프로그램",     

                                           WS_OVERLAPPEDWINDOW,

                                           CW_USEDEFAULT, CW_USEDEFAULT,

                                           CW_USEDEFAULT, CW_USEDEFAULT,

                                           NULL, NULL, hInstance, NULL ) ) )

          return FALSE ;

 

     ShowWindow( hWnd, nCmdShow ) ;  // 메인 프레임 윈도우를 화면에 보이게 한다.

     UpdateWindow( hWnd ) ;                  // 메인 프레임 윈도우를 다시 그려준다.

     return TRUE ;

 }

 

。CreateWindow 함수의 매개변수

 매개변수  의미 
 lpClassNamae  프로그램 초기화 부분에서 등록한 윈도우 클래스의 이름
 lpWindowName  윈도우 타이틀 바에 출력될 문자열
 dwStyle  윈도우 스타일
 x, y, nWidth, nHeight  윈도우의 위치와 가로 세로 길이
 hWndParent  부모 윈도우의 핸들
 hMenu  메뉴의 핸들
 hInstance  인스턴스의 핸들
 lpParam  CREATESTRUCT 구조체로 지정되는 윈도우 생성에 필요한 추가 정보

 

 

□ 메세지 루프

- 프로그램에 어떤 이벤트가 발생하면 윈도우 운영체제가 이를 감지하여 프로그램의 메세지 큐에 적당한 메세지를 넣어준다.

1. 프로그램의 메세지 큐에서 메세지를 가져온다.

2. 이 메세지의 정보를 알려준다.

3. 메세지를 윈도우 프로시저에 전달한다.

 int Run()

 {

     MSG msg ;

     while( GetMessage( &msg, NULL, NULL, NULL ) )

     {

          TranslateMessage( &msg ) ;

          DispatchMessag( &msg ) ;

      }

      return (int)msg.wParam ;

 }

 

GetMessage 함수는 프로그램의 메세지 큐에서 메세지를 가져오는 기능을 수행합니다.

이 함수는 프로그램을 종료하라는 WM_QUIT 메세지를 가져오면 TRUE를 반환하고, 그렇지 않으면 FALSE를 반환한다. FALSE를 만나면 while문을 빠져나온다.

키보드가 눌리면 WM_KEYDOWN 메시지가, 키보드가 떼지면 WM_KEYUP 메세지가 발생한다. Translatemessage 함수는 이 메세지 조합을 이용하여 KEY_CHAR, KEY_DEADCHAR, KEY_SYSCHAR 등의 메세지를 발생하여 실제로 어떤 문자가 눌렸는지 정보를 알려준다.

DispatchMessage 함수는 이 메세지를 윈도우 프로시저에 전달한다.

 

 

□ 윈도우 프로시저 : 메세지 처리

- 윈도우 메세지를 처리하는 함수로 이 함수를 어떻게 만드냐에 따라 윈도우 기능이 결정된다.

 

 LRESIT WINAPI WndProc(HANDLE hWnd, UNIT message, WPARAM wParam,

                                     LPARAM lParam)

 {

     switch( message )

     {

          case WM_KEYDOWN :          // 키보드가 눌렸을 때의 처리

               break ;

          case WM_LBUTTONDOWN :  // 마우스 왼쪽 버튼이 클릭되었을 때

               break ;

          case WM_MOUSEMOVE :     // 마우스가 움직였을 때

               break ;

     }

     return DefWindowProc( hWnd, message, wParam, lParam ) ;

 }

 

DefWindowProc 함수는 윈도우 운영체제가 미리 정해둔 윈도우의 기본 기능을 수행하도록 한다. 

 
Posted by 모과이IT
,

 #include "stdafx.h"

 /********************************************************************

                                              클래스 선언

 *********************************************************************/

 class CTestApp : public CWinApp

 {

     public :

          virtual BOOL InitInstance() ;

 } ;

 class CTestFrame : public CFrameWnd

     public :

          CMainFrame() {

                    Create(NULL, "MFC로 만든 프로그램") ;

          }

          // 메세지 처리기

          afx_msg void ONPaint() ;

          afx_msg void ONLButtonDown( UNIT nFlags, CPoint point ) ;

          DECLARE_MESSAGE_MAP()

 } ;

 /********************************************************************

                          전역변수로 클래스의 인스턴스 선언

 *********************************************************************/

 CTestApp : theApp ;

 /********************************************************************

                                            멤버 함수 구현

 *********************************************************************/

 BEGIN_MESSAGE_MAP( CMainFrame, CFrameWnd )

     ON_WM_PAINT()

     ON_WM_LBUTTONDOWN()

 END_MESSAGE_MAP()

 

 // 인스턴스 초기화

 BOOL CTestApp::InitInstance()

 {

     // 메인 프레임 윈도우 생성

     m_pMainWnd = new CMainFrame ;

     m_pMainWnd->ShowWindow( m_nCmdShow ) ;

     m_pMainWnd->UpdateWindow() ;

     return TRUE ;

 }

 

 void CMainFrame::OnPaint()

 {

     CPaintDC dc( this ) ;

     CRect rect ;

     GetClientRect( &rect ) ;

     dc.DrawText( "마우스 버튼을 클릭해 보세요." -1, &rect,

                          DT_SINGLELlNE | DT_CENTER | DT_VCENTER ) ;

 }

 

 void CMainFrame::OnLButtonDown( UNIT nFlags, CPoint point )

 {

     AfxMessageBox( "마우스 버튼이 클릭 되었습니다." ) ;

 }

 

헤더파일 stdafx.h를 열어 "#include <afxwin.h>"를 추가해준다. 

 
Posted by 모과이IT
,

■ SDK와 MFC

- SDK에서 제공하는 모든 기능이 다 MFC에 캡슐화 되어 있는 것은 아니라는 점에서 주의하라.

- 굳이 클래스 형태로 캡슐화 할 필요가 없는 기능들도 많이 있는데 MFC에서는 이런 함수들을 굳이 클래스로 만들지 않고, 그냥 SDK 형태로 사용하도록 두었다.

- 예를들어 GlobalAlloc 처럼 메모리를 할당하는 일은 특정 클래스에서만 하는 것이 아니라 언제, 어디서든 사용할 수 있는 기능이기 때문에 그냥 SDK 함수 형태로 사용한다.

 

 

■ WinMain 은 어디에?

- MFC는 어떠한 프로그램을 작성하더라도 WinMain 함수를 건드리지 않고 작성할 수 있도록 모든 것을 완벽하게 처리해 놓았다.

- MFC 내부에 들어 있는 WinMain 함수를 간략히 보면 다음과 같다.

 int APIENTRY WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,

                                   int nCmdShow )

 {

     CWinApp *pApp = AfxGetApp() ;

     pApp->InitApplication() ;

     pApp->InitInstance() ;

     pApp->Run() ;

     pApp->ExitInstance() ;

 }

 

InitApplication 함수는 프로그램 초기화 기능을 수행하고, InitInstance 함수는 보통 재정의되는 함수로 도큐먼트 뷰를 등록하고, 메인 프레임 윈도우를 생성하는 일을 수행한다. Run 함수는 WM_QUIT 메세지를 만날 때까지 무한 루프를 돌면서 메세지를 윈도우 프로시저에 전달하는 기능을 한다. 

 

Posted by 모과이IT
,

■ 도큐먼트의 종류

 도큐먼트  설명

 단일 도큐먼트

 ( SDI : Single Document Interface )

 한번에 하나의 도큐먼트만 처리할 수 있기 때문에 프로그램의 프레임 윈도우가 하나이다.

 메인 프레임 윈도우가 도큐먼트, 뷰를 품고 있다.

 다중 도큐먼트

 ( MDI : Multiple Document Interface )

 하나의 프로그램에서 여러 개의 문서를 동시에 작업할 때 사용하며 프로그램의 프레임 윈도우가 여러 개이다.

 자식 프레임 윈도우가 도큐먼트, 뷰를 품고 있다.

 

 

■ 단일 도큐먼트

하나의 프레임 윈도우에 대해 CFrameWnd 클래스에서 파생된 하나의 클래스만 갖는다.

메인 프레임이 윈도우에서 도큐먼트 뷰를 품고 있기 때문에 따로 윈도우를 생성하지 않아도 된다.

 

 

■ 다중 도큐먼트

。다중 프레임 윈도우의 계층 구조

CWnd

   CFrameWnd

      CMDIFrameWnd

      CMDIChildWnd

。두 종류의 프레임 윈도우가 있다.

메인 프레임 윈도우 : 프로그램 전체를 둘러싸고 있다. CMDIFrameWnd 클래스

자식 프레임 윈도우 : 메인 프레임 윈도우 안쪽의 작은 프레임 윈도우로 뷰 윈도우를 품고

                             있다. CMDIChildWnd 클래스. 

Posted by 모과이IT
,

■ RTTI (Run-Time Type Information)

 

- C++에서는 RTTI를 완벽하게 지원하지 않는다. 때문에 MS는 Compiler 차원에서 RTTI를 지원해 주기 위한 방법을 구현해낸 것이 CRuntimeClass와 여러가지 매크로 함수를 제공하고 있다.

 

■ CRuntimeClass

- 본질적으로 특정 클래스에 대한 정보를 담고 있는 구조체이다.

- 일반화된 객체 생성 : 클래스 이름을 사용하지 않고 객체를 생성하는 기능

기반 클래스를 가지고 있지 않다.

 

- 세 종류의 매크로를 제공한다.

DECLARE_DYNCREATE()

IMPLEMENT_DYNCREATE()

RUNTIME_CLASS()

 

 

■ IMPLEMENT_DYNCREATE(CSimpleCalc, CCmdTarget)

- 첫번째 변수는 동적으로 생성하고자 하는 객체 클래스 이름

- 두번째 변수는 그 클래스가 상속 받는 기반 클래스의 이름

ex) 메인 프레임의 경우, 기반 클래스가 CFrameWnd 이면 단일 도큐먼트(SDI), CMDIFrameWnd 이면 다중 도큐먼트(MDI) 형식이다.

 

 

■ RUNTIME_CLASS 매크로 

- class 정보를 구하는 매크로

- 주로 현재 사용하는 클래스가 유효한 클래스인지 판단

Posted by 모과이IT
,

■ 디버그 모드 컴파일

디버깅을 할 수 있는 대신 실행 파일의 크기가 커지고, 실행 속도도 느려진다.

 

■ 릴리즈 모드 컴파일 

디버깅을 할 수 없지만 실행 파일의 크기도 작아지고 실행 속도도 빨라진다.

 

디버깅 정보를 실행 코드 안에 넣느냐 안 넣느냐의 차이이다.

따라서 디버그 모드로 개발하고 개발이 완료되고 난 후에는 릴리즈 모드로 컴파일해서 배포한다. 

 

Posted by 모과이IT
,


스크롤이 이동될때 내부적으로 자동으로 해주므로

void CWebDlgFormView::OnMouseMove(UINT nFlags, CPoint point)
{
 //Invalidate();

}

위 과정은 생력해도 된다

Posted by 모과이IT
,

ActiveX 컨트롤 테스트 인증서

밑에 글(ActiveX 컨트롤에서 IObjectSafety 구현하기)에서 개인개발자나 시험용으로 만든 ActiveX 컨트롤을 컨테이너(IE)에서 사용할 때, 인증문제에 대한 것이 있었다.

이 파일은 그 문제를 잠시나마 해결하기 위해 ActiveX컨트롤에 인증서를 포함하여 Cab파일을 작성하게 하는 프로그램이다.

테스트 인증서 작성 -> Cab 작성 -> SignCode -> Check 등의 작업이 배치파일(sign50.bat)로 작성되어 있다.

inf파일을 문법에 맞게 구성한 후,  sign50.bat를 실행하면 작성된다.

Test.html은 웹페이지에서 ActiveX 컨트롤을 사용하는 예제이고, 이 압축파일은 미니프로제트를 수행했을때 만들었던 ActiveX 컨트롤을 포함하고 있다.

 

--------------------------------------------------------------------------
배포


1) ActiveX 컨트롤을 각 PC에 복사
2) 그 컨트롤을 레지스트리에 등록
3) 필요한 DLL이 있다면 복사
=> 자동으로...

Cab 파일을 통해 위의 내용들을 자동화 시켜줌...
1) .inf 파일 작성
2) .ocx 파일과 .inf 파일을 .cab 파일로 압축
3) .cab 파일을 서명
4) .cab 파일을 웹페이지에 등록

//
1) .inf 파일 생성
    => VC 6.0 제공이 안됨...
    => 배포될 .ocx및 dll의 정보를 담고 있다...

2) .cab 파일 생성
    => cabarc.exe 유틸리티를 통해 생성...

         cabarc.exe N test.cab test.ocx test.inf (step1.bat)
   
          => test.cab 파일 생성( 압축파일..)

3) .cab 서명
     makecert -sv "mycert.pvk" -n "CN=TEST ActiveX" mycert.cer
          => 대화상자 생성 => 암호 입력 => 개인 키 파일(mycert.pvk, mycert.cer)
               생성

     cert2spec mycert.cer mycert.spc
          => mycert.cer로부터 mycert.spc를 생성 ( makespc.bat 사용)

     컨트롤 서명
     signcode -v mycert.pvk -spc mycert.spc test.cab
     => test용 .cab 파일을 인증하는 코드
         인증기관에서 제대로된 인증을 받으려면 위 명령줄에 -t 인증기관 URL을 추가

   
     setreg -q 1 TRUE
     => test용 인증서가 인식되도록 설정

     chktrust test.cab
     => CAB 파일이 올바르게 서명되었는지 확인...(step2.bat..)

Posted by 모과이IT
,


char szProgrampath[_MAX_PATH], szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
GetModuleFileName( NULL, szProgrampath, _MAX_PATH);
_splitpath(szProgrampath,szDrive,szDir,NULL,NULL);

// 멤버변수 m_strPath에 담는다.
m_strPath.Format("%s%s", szDrive, szDir);

Posted by 모과이IT
,