CFile클래스를 이용하면 데이터를 쓰고 읽을수 있다.

그러나 CArchive클래스를 이용 하면 더 쉽게 파일을 열고 읽고 쓸 수 있다..

 

CArchive클래스는 읽기모드(CArchive::load)와 쓰기모드(CArchive::store)로 구분되어 있다.

 

CFile file;

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

CArchive ar(&file,CArchive::store);

ar<<data;

 

CFile file;

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

CArchive ar(&file,CArchive::load);

ar>>data;

 

CArchive클래스 이용한 읽고 쓰기

 

데이터를 읽고 쓰기 위해 CArchive클래스는 CFile클래스와 동일한 함수가 있다.(Write(),Read())

Write(),Read()    함수는 CFile과 동일 하다..그리고.>>,<<연산자 를 이용하여 데이터를 읽고 쓰기두 가능 하며 ReadString(), WriteString() 함수를 이용하여 데이터를 텍스트로 읽고 쓸 수 있다.

 

다음과 같이 작성 하면 double형 데이터를 바이너리 형태로 파일에 읽고 쓸수 있다..

 

double pi =3.141592653;

ar.Write(&pi, sizeof(double));

ar.Read(&pi, sizeof(double));

 

이걸 연산자로 표현 하면

 

double pi=3.141592653;

ar<<pi;

ar>>pi;

 

다음과 같이 하면 double형 데이터를 텍스트 형태로 파일에 읽고 쓸 수 있다.

 

double pi =3.141592653;

CString str;

str.Format(TEXT("%f\n"),pi);

ar.WriteString(str);

ar.ReadString(str);

 

바이너리형태로 파일에 저장 될때는 double형의 크기인 8바이트로 저장 되지만

텍스트형으로 저장 될때는 '3', '.', '1', '4', '1', '5','9','2', '6', '5', '3', '\n'

위에 처럼 각각 하나의 문자로 각각 char형 1바이트씩 총... 12바이트를 소비 하게 된다.

 

 

 

<<나 >>연산자로 CArchive에 저장하고 읽어 올수 있는 데이터형

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

                                    저장하고 읽어 올 수 있는 데이터 형식

───────────────────────────────────────────── 

기본 데이터             BYTE, WORD, LONG, DWORD, float, double, int, UINT, short, char

───────────────────────────────────────────── 

MFC클래스              CSize, CPoint, CRect, CString, CTime, CTimeSpan, COleVarient

                             COleCurrencym COleDateTime, COleDateTimeSpan

───────────────────────────────────────────── 

이외의 클래스를 Serialize클래스를 이용해서 저장하고 읽어 올려면

다음과 같은 조건을 충족 해야 한다.

 

1. CObject클래스로부터 직접 또는 간접적으로 상속을 받는다.

2. 생성자를 만들어 준다.

3. 헤더파일에 DECLARE_SERIAL매크로를 적어준다.

4. 소스 파일에 IMPLEMENT_SERIAL 매크로를 적어 준다.

5. Serialize함수를 오버라이딩(재정의)해서 데이터를 저장하는 루틴을 넣어준다.

6. <<,>>연산자를 오버로딩 한다.


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

class CPoint3D : public CObject
{

public:
 DECLARE_SERIAL(CPoint3D);
 int m_x, m_y, m_z;

 CPoint3D();
 CPoint3D(int x, int y, int z);
 void Serialize(CArchive& ar);
};

IMPLEMENT_SERIAL(CPoint3D, CObject, 1);

CPoint3D::CPoint3D( )//생성자.
{
     m_x = m_y = m_z = 0;
}

 

CPoint3D::CPoint3D(int x, int y, int z)
{
     m_x = x; m_y = y; m_z = z;
}

 

void CPoint3D::Serialize(CArchive& ar)
{
      CObject::Serialize(ar);
      if(ar.IsStoring())
       ar << m_x << m_y << m_z;
      else
       ar >> m_x >> m_y >> m_z;
}

CArchive& AFXAPI operator<<(CArchive& ar, CPoint3D& point)
{
      point.Serialize(ar);
      return ar;
}

CArchive& AFXAPI operator>>(CArchive& ar, CPoint3D& point)
{
      point.Serialize(ar);
      return ar;
}

void main()
{
      TRY  // 쓰기
      {
       CPoint3D point(10, 20, 30);
       CFile file;
       file.Open(_T("File.dat"), CFile::modeCreate | CFile::modeWrite);
       CArchive ar(&file, CArchive::store);
  
       ar << point;
      }
      CATCH(CFileException, e)
      {
            e->ReportError();
      }
      END_CATCH

 

      TRY  // 읽기
      {
            CPoint3D point;
            CFile file;
            file.Open(_T("File.dat"), CFile::modeRead);
            CArchive ar(&file, CArchive::load);
  
            ar >> point;
            TRACE("(%d, %d, %d)\n", point.m_x, point.m_y, point.m_z);
      }
      CATCH(CFileException, e)
      {
            e->ReportError();
      }
      END_CATCH
}

 

 

'개발지식창고 > MFC' 카테고리의 다른 글

MFC와 Excel 연동 관련 자료  (0) 2012.06.29
Excel Automation ( 1. 생성 및 변수 초기화 )  (0) 2012.06.29
MFC SDI 객체 간의 접근  (0) 2012.04.14
MDI 구조  (0) 2012.04.05
MFC에서 콘솔창 띄워기 (디버그용도)  (0) 2012.02.05
Posted by 모과이IT
,

SDI 형식 에서의 객체간 접근 방법

AfxGetMainWnd()-MFC 전역 함수로 응용 프로그램의 최상위 프레임 윈도우의 주소를 반환 한다.

                          어느 곳에서나 사용가능 하고.CMainFrame의 주소를 반환..

 

AfxGetApp()- 역시 전역 함수로 응용 프로그램의 자체 객체의 주소를 반환 한다.

                 -CSdiApp의 주소를 반환..

 

메인프레임 윈도우 에서 클라이언트 뷰 윈도우에 접근 하고자 할때는 GetActiveView()

만일 여러개의 뷰를 사용중 이라면 활성화된 뷰의 주소 반환.

 

메인프레임 윈도우에서 클라이언트 도큐먼트 에 접근 하고자 할 경우 GetActiveDocument()

만일 여러개의 도큐먼트를 사용중 이라면 활성화된 문서의 주소 반환.

 

클라이언트 뷰 윈도우 에서 문서에 접근 할때는 메인 프레임 윈도우 에서와 달리

GetDocument()함수를 사용한다.

 

문서에서 뷰 윈도우에 접근 할때는 m_viewList멤버를 사용 이멤버는 CDocument클래스의 멤버로서 등록된 윈도우의 주소를 목록으로 관리 한다. 이 멤버는 CPtrList 클래스의 GetHead()메서드를 호출하여 목록의 첫번째에 등록된 뷰 윈도우의 주소를 알아낼 수 있다.

 

 

 

'개발지식창고 > MFC' 카테고리의 다른 글

Excel Automation ( 1. 생성 및 변수 초기화 )  (0) 2012.06.29
CArchive클래스  (0) 2012.04.14
MDI 구조  (0) 2012.04.05
MFC에서 콘솔창 띄워기 (디버그용도)  (0) 2012.02.05
[MFC] CWebBrowser2 클래스 추가하기  (0) 2012.01.11
Posted by 모과이IT
,

MDI 프로그램 구조

 mdi

 

 MDI 형태의 프로그램 작성할 때 CWinApp, CFrameWnd, CChildWnd, CView, CDocument 클래스가 필요. 이 5가지 클래스를 상속받아 프로그램을 작성한다.

Application : CWinApp 클래스를 상속받아 작성한 클래스

MainFrame : CFrameWnd 클래스를 상속받아 작성한 클래스, 부모 윈도우 외곽 경계담당, 메뉴, 툴바, 상태바를 가짐

ChildFrame : CChildWnd 클래스를 상속받아 작성한 클래스, 자식 윈도우의 외곽 경계담당

View : CView 클래스를 상속받아 작성한 클래스, 윈도우의 실제 화면 처리를 담당

Document : CDocument 클래스를 상속받아 작성한 클래스, 데이터를 저장하는 기능을 가짐

Document와 View는 쌍으로 움직인다(데이터를 보관하고, 적당히 처리해서 화면에 출력하는 형식)

ChildFrame, View, Document를 하나로 묶은 것(리소스 정보도 같이 묶는다)을 Template(윈도우를 출력하는 형태)이라고 한다. MDI 프로그램에서는 만들어진 Template을 복제하여 화면에 출력한다. 또한 여러개의 Template을 가질 수 있다. MDI 프로그램은 여러개의 SDI을 포함한 프로그램

 

DemoMdiimg 

 

MDI형태에서는 SDI형태와 다르게 자식프레임(CChildFrame)과 View윈도우(CDemoMdiView), 도큐먼트(CDemoMdiDoc)클래스가 템플릿으로 설정되고, 메인프레임은 따로 설정된다.

 

①~⑥까지는 CDemoMdiApp클래스의 InitInstance() 함수에서 실행된다.

 

자식 윈도우로 사용할 템플릿을 생성한다(CChildFrame, CDemoMdiView, CDemoMdiDoc, 자식윈도우의 Resource ID - 자식 윈도우용으로 쓰일 메뉴, 아이콘, 문자열).

 

부모 윈도우의 메인프레임을 로드하여, 어플리케이션 클래스(CDemoMdiApp)에 등록한다.

 

어플리케이션 셸이 초기화될 때 자식 프레임, View 윈도우, Document가 결합되어 하나의 템플릿으로 형성.

 

⑦, ⑧

CMainFrame의 OnCreate() 함수에서 실행된다.

 

 

CDemoMdiApp의 InitInstance() 함수 분석
// CDemoMdiApp 초기화

BOOL CDemoMdiApp::InitInstance()
{
 // 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
 // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요. 
 // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);


 // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록 설정
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 

 // OLE 라이브러리를 초기화
 if (!AfxOleInit())
 {
  AfxMessageBox(IDP_OLE_INIT_FAILED);
  return FALSE;
 }

// ActiveX 콘트롤을 사용할 수 있게 초기화

AfxEnableControlContainer();


 SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));
 LoadStdProfileSettings(4);  // MRU를 포함하여 표준 INI 파일 옵션을 로드

 // 위 그림의 ②,③

 // 응용 프로그램의 문서 템플릿을 등록. 문서 템플릿은 문서, 프레임 창 및 뷰 사이의 연결 역할을 함.

 // MDI에서 템플릿을 만들 때 CMultiDocTemplate 사용
 CMultiDocTemplate* pDocTemplate;
 pDocTemplate = new CMultiDocTemplate(

  IDR_DemoMdiTYPE, // 자식 프레임 리소스
  RUNTIME_CLASS(CDemoMdiDoc),
  RUNTIME_CLASS(CChildFrame), // 사용자 지정 MDI 자식 프레임
  RUNTIME_CLASS(CDemoMdiView));
 // 문서 템플릿 등록

 if (!pDocTemplate)
  return FALSE;
 AddDocTemplate(pDocTemplate);

 

 // 위 그림의 ④

 // 메인 MDI 프레임 창을 만듬.
 CMainFrame* pMainFrame = new CMainFrame;
 if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
 {
  delete pMainFrame;
  return FALSE;
 }
 m_pMainWnd = pMainFrame;

 // 표준 셸 명령, DDE, 파일 열기에 대한 명령줄을 구문 분석
 CCommandLineInfo cmdInfo;
 ParseCommandLine(cmdInfo);

 

 // 위 그림의 ⑤

 // 이부분이 실행되면서 템플릿이 서로 연결되고 만들어진다.

 // 모든 템플릿이 만들어지고 ProcessShellCommand에 의해서 각 템플릿 클래스를 메모리에 할당하면,

 // 메인 윈도우가 화면에 출력될 때, 자식 윈도우도 함께 출력된다.
 // 명령줄에 지정된 명령을 디스패치한다.
 if (!ProcessShellCommand(cmdInfo)) return FALSE;


 // 위 그림의 ⑥

 // 메인 창이 초기화되었으므로 이를 표시하고 업데이트
 pMainFrame->ShowWindow(m_nCmdShow);
 pMainFrame->UpdateWindow();

 return TRUE;
}

'개발지식창고 > MFC' 카테고리의 다른 글

CArchive클래스  (0) 2012.04.14
MFC SDI 객체 간의 접근  (0) 2012.04.14
MFC에서 콘솔창 띄워기 (디버그용도)  (0) 2012.02.05
[MFC] CWebBrowser2 클래스 추가하기  (0) 2012.01.11
VS2005 -> VS2008 변환시 주의할점  (0) 2011.07.22
Posted by 모과이IT
,

MFC에서 작업을 할 때, printf구문을 이용하여 출력문을 사용하면 화면상에서 확인을 할 수가 없는 불편한 점이 있다.그래서 MFC에서 코딩을 할때 간단하게 prinf구문을 이용하기 위해서는 콘솔창을 따로 띄워주는 방법이 있다.MFC에서 콘솔창을 띄우는 방법은 여러가지가 있지만, 아래와 같이 2 가지 방법으로 적용하면 된다.

● Method 1

App의 InitInstance에서 AllocConsole()을 호출한다. 

#ifdef _DEBUG

    if( !
AllocConsole() )
    {
        AfxMessage(_T("Failed to create the console!"), MB_ICONEXCLAMATION);
    }
#endif

해제하기 위해서는 ExitInstance에서 FreeColsole()을 호출한다.

#ifdef _DEBUG
    if( !FreeConsole() )
    {
        AfxMessage(_T("Failed to free the console!"), MB_ICONEXCLAMATION);
    }
#endif



● Method 2

stdafx.h에서 다음과 같이 입력한다.( 디버그 모드가 아닐때도 사용할 것이면  #ifdef #endif를 적용하지 않으면 된다. )

#ifdef _DEBUG
#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")
#endif

출력은 일반적인 콘솔 프로그램과 같이 cout이나 printf 등을 사용하면 된다.
(참고로 printf()는 stdio.h에 포함되어져있다) 

'개발지식창고 > MFC' 카테고리의 다른 글

MFC SDI 객체 간의 접근  (0) 2012.04.14
MDI 구조  (0) 2012.04.05
[MFC] CWebBrowser2 클래스 추가하기  (0) 2012.01.11
VS2005 -> VS2008 변환시 주의할점  (0) 2011.07.22
CCmdUI 클래스 : 사용자 인터페이스 갱신  (0) 2011.07.19
Posted by 모과이IT
,

[MFC] CWebBrowser2

 1. 개요

Dialog Viewwebpage를 띄울수 있는 Controller이다. 정확한 용도나 사용법은 모르나, 후배가 면접을 위해 과제를 하는데 나도 처음 만져보고 접혔던 Class이다. 다른 것과는 달리 매우 사용법이 쉬워서 자주 사용할듯하다.
서론이 길면 안좋다. 바로 사용법이다.


2. 클래스 추가하기




일단 이렇게 클래스추가후 AxtiveX 컨트롤의 MFC 클래스를 선택한다



Microsoft Web Browser <1.0> 선택한후



Interface WebBowser2 고른다. 그냥 WebBrowser와는 무슨 차이인지는 모르겠다.
원하는 이름으로 바꿔도 용이하다.

이렇게 되면 해당 클래스의 생성은 완료다.

3. 변수 추가


위처럼
하면 해당하는 Header file cpp 파일이 생성이 된다.

해당 header file Include 변수를 선언하자.

1.#include "CWebBrowser2.h"
2.//...................
3./....................
4.CWebBrowser2  m_Page_Viewer;
5./.................

 

4. 초기화

 

해당 header file Include 변수를 선언하자.

Dialog 띄워야 했기 때문에 OnInitDialog 재정의 하여서 해당 부분을 넣었지만. View 경우는

OnCreate함수를 재정의 하면 되는 같다.

 

01.BOOL CDlg_WebViewer::OnInitDialog()
02.{
03.    CDialog::OnInitDialog();
04.    CRect rectCurrent;
05.    //View가 들어갈 Rect 수정도 용이하다.
06.    GetClientRect(rectCurrent);
07.    rectCurrent.right-=45;
08.    if (m_Page_Viewer.Create("Web Control", WS_CHILD | WS_VISIBLE, rectCurrent, this, 1010) == FALSE)
09.    {
10.        AfxMessageBox("웹브라우저컨트롤생성실패\n");
11.        return  FALSE;
12.        //정확한 Return값을 잘 모르겠다.
13.    }
14.    // TODO:  여기에추가초기화작업을추가합니다.
15.    return TRUE;  // return TRUE unless you set the focus to a control
16.    // 예외: OCX 속성페이지는FALSE를반환해야합니다.
17.}

 

 

5. Run


많이
쉽다. CString path 저장한후에 Navigate라는 함수를 실행하면

이쁘게 뜬다.

1.void CDlg_WebViewer::OnBnClickedConnect()
2.{
3.    //TODO: 여기에컨트롤알림처리기코드를추가합니다.
4.  
5.    CString sFilePath;
6.    sFilePath.Format("http://hantor.net");
7.    m_Page_Viewer.Navigate(sFilePath, NULL, NULL, NULL, NULL);
8.}




<완성 사진>

Posted by 모과이IT
,
Posted by 모과이IT
,

■ CCmdUI 클래스

。기능

- 사용자 인터페이스 갱신과 관련된 기능을 수행하며 ON_UPDATE_COMMAND_UI 매크로로 연결되는 이벤트 처리기에 사용한다.

- 연결된 이벤트 처리기는 ON_COMMAND로 이미 등록되어 있는 이벤트 상태에 변경이 있을 때 이를 업데이트 시킨다.

 

- 연결된 이벤트 처리기는 이 클래스의 인스턴스 포인터를 매개변수로 넘겨받는다.

- 이벤트명이 ID_BEGIN이라면 이를 갱신하는 이벤트 처리기는 OnUpdateBegin()이 된다.

 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

     . . .

     ON_UPDATE_COMMAND_UI( ID_BEGIN, OnUpdateBegin)

     ON_UPDATE_COMMAND_UI( ID_END, OnUpdateEnd)

 END_MESSAGE_MAP()

 

 void CCmdUIView::OnUpdateBegin(CCmdUI *pCmdUI)

 {

   pCmdUI->Enable(!m_bStart) ;

 } 

 void CCmdUIView::OnUpdateEnd(CCmdUI *pCmdUI)

 {

   pCmdUI->Enable(!m_bStart) ;

 }

 

。주요 멤버변수 : 갱신할 사용자 인터페이스의 이벤트 ID를 나타내는 UNIT 형의 m_nID가 있다.

。주요 멤버 함수

 멤버 함수  기능 
 Enable  BOOL형 매개변수를 받아 사용자 인터페이스를 활성화/비활성화 시킴.
 SetText  사용자 인터페이스의 텍스트를 변경시킴.
 SetCheck  int형 매개변수를 받아 체크 표시를 하거나 없앰.
 SetRadio  SetCheck 함수와 비슷한 기능. 단, 체크 표시대신 점이 찍힘.

 

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

 

- 우선 다음과 같은 이벤트 처리기가 정의되어 있다고 가정한다.

 BEGIN_ MESSAGE_MAP(CCmdUIView, CView)

      ...

      ON_COMMNAD( ID_BEGIN, OnBegin )

      ON_COMMAND( ID_END, OnEnd )

 END_MESSAGe_MAP()

 

 void CCmdUIView::OnBegin()

 {

     m_bStart = TRUE ;

 }

 

 void CCmdUIView::OnEnd()

 {

     m_bStart = FALSE ;

 }

 

 

■ Enable 함수

- 메뉴 항목을 상황에 다라 활성화 시키거나 비활성화 시킨다.

 

。상태변수 만들기

- 활성화인지 비활성화 인지의 상황을 기억하는 상태 변수가 필요하다.

 class CCmdUIView : public CView

 {   ...

     BOOL m_bStart ;

 }

 

- 상태 변수를 클래스 생성자 함수에서 초기화 해 준다.

 CCmdUIView::CCmdUIView()

 {  ...

     m_bStart = FALSE ;

 }

 

。사용자 인터페이스 갱신 메세지 처리기 등록  

- ON_UPDATE_COMMAND_UI로 등록한다.

 BEGIN_ MESSAGE_MAP(CCmdUIView, CView)

      ...

      ON_UPDATE_COMMNAD_UI( ID_BEGIN, OnBegin )

      ON_UPDATE_COMMNAD_UI( ID_END, OnEnd )

 END_MESSAGe_MAP()

 

。메세지 처리기 활성/비활성 상태 제어

- Enable 함수를 호출하여 매개변수로 TRUE(활성화) 또는 FLASE(비활성화)를 넘긴다.

- 이벤트 처리기에 넘겨지는 매객변수 pCmdUI에는 메뉴 항목에 대한 정보가 담겨 있다.

- CCmdUI 클래스의 멤버 함수들을 호출하면 해당 메뉴 항목을 제어할 수 있다.

 void CCmdUIView::OnUpdateBegin(CCmdUI *pCmdUI)

 {

     pCmdUI->Enable(!m_bStart) ;

 }

 void CCmdUIView::OnUpdateEnd(CCmdUI *pCmdUI)

 {

     pCmdUI->Enable(!m_bStart) ;

 }

 

'개발지식창고 > MFC' 카테고리의 다른 글

[MFC] CWebBrowser2 클래스 추가하기  (0) 2012.01.11
VS2005 -> VS2008 변환시 주의할점  (0) 2011.07.22
ON_COMMAND 와 ON_MESSAGE 의 차이점  (0) 2011.07.19
클립보드 사용법2  (0) 2010.10.27
클립보드 사용법 1  (0) 2010.10.27
Posted by 모과이IT
,

Visual C++ ,MFC 를 사용한 프로그램시 나오는 내용입니다.

 

ON_COMMAND와 ON_MESSAGE 모두 macro로 코딩을 편하게 하기위해 사용한다고 볼수 있습니다.

 

차이점은 ON_COMMAND는 command id의 핸들러를 설정하는 함수로

사용법이 ON_COMMAND(id, memberFxn) 입니다.

즉  command id가 실행되면 memberfFxn 멤버 함수를 호출하라는 뜻입니다.

 

여기서 command id란 버튼의 ID 또는 menu의 ID입니다.

각 메뉴, 버튼에는 자신을 구분하기 위한 ID를 가지고 있고 사용자가 메뉴의 항목을 실행하거나 버튼을 누르면 WM_COMMAND 메세지가 발생하고 이 메세지의 인자중 하나가 선택한 항목의 ID입니다.

MFC 라이브러리는 WM_COMMAND의 인자로 전달된 ID를 ON_COMMAND macro에 설정된 값들과 비교해서 같은 값을 발견하면 그 ID의 멤버함수로 설정된 함수를 호출합니다.

 

ON_COMMAND가 ID의 멤버함수를 설정하는 것에 반해

ON_MESSAGE는 상용자 정의 메시지의 핸들러(멤버함수)를 설정하는 함수입니다.

 

WM_ 으로 시작하는 기본윈도우 메시지 이외에 사용자가 메시지를 정의할수 있습니다.

예를 들어 WMU_USERMSG 라고 사용자 정의 메세지를 정의하고

 

ON_MESSAGE(WMU_USERMSG, OnMyMsg)

 

이렇게 하면 WMU_MESSAGE가 발생하면 OnMyMsg 멤버함수가 호출됩니다.

 

다시 간단히 정리하면

ON_COMMAND 는 ID의 handler를

ON_MESSAGE는 사용자 정의 메시지의 handler를  멥핑시키는 macro입니다

Posted by 모과이IT
,
클립보드

클립보드는 특정 프로그램에서 데이터를 다른 프로그램으로 넘어갈수 있도록 해주는 윈도우의 기능입니다. 보통 “복사하기” 나 "Copy"항목을 이용하면 현재 설정된 데이터가 클립보드로 넘어갑니다. 클립보드로 넘어간 데이터를 다른 프로그램에서 "붙여넣기“ 나 "Paste”를 이용하면 클립보드에 있는 데이터를 넘겨 받을수 있습니다. 클립보드에는 문자,그림 등의 형태를 저장할수 있으며 OLE를 이용하게 되면 다양한 형태의 데이터를 클립보드로 저장하고 저장된 데이터를 클립보드에서 얻을수 있습니다. 본항목에서는 클립보드에 데이터를 넣는 방법과 데이터를 읽는 방법에 대해서 설명합니다.


클립보드 상태 알기

클립보드를 열고자 할경우에는 OpenClipboard와 CloseClipboard 함수를 사용하면 됩니다.

OpenClipboard();//클립보드를 연다.

  :  클립보드에 데이터를 넣던지 또는 데이터를 얻는다.

CloaseClipboard()//클립보드를 닫는다.

클립보드에는 다양한 포맷형태로 데이터가 저장되어 있습니다. 이런 클립보드에서 현재 원하는 형식의 데이터가 있는지를 확인할 때 사용하는 함수가IsClipboardFormatAvailable  입니다.


BOOL IsClipboardFormatAvailable(

UINT format //클립보드 데이터 포맷

); 

format는 다음과 같은 값을 가집니다.


CF_BITMAP : HBITMAP 형태의 데이터

CF_DIB : 장치독립적인 비트맵 데이터 보통 bmp파일에서 로드된 데이터

CF_TEXT : 문자 데이터

CF_PALETTE  : 팔레트 데이터

CF_RIFF : 멀티미디어에서 사용하는 오디오 음성등의 데이터

CF_WAVE : 웨이브 파일 포맷

CF_TIFF : 태그 이미지 파일 포맷


위의 플러그들외에서 다양한 플러그들이 있는데 그만큼 클립보드에 저장할 데이터는 광범위하다는 의미입니다. 예를 들어 현재 복사할 텍스트가 있는가를 확인하고자 한다면

 BOOL check;

 check=IsClipboardFormatAvailable(CF_TEXT);

하시면 됩니다.

만일 CF_TEXT 형의 데이터가 클립보드에 있다면 check는 TRUE값이 그렇지 않다면 FALSE값이 설정됩니다.

실제 클립보드에서 텍스트를 얻고자 한다면 다음과 같은 방법을 취할수 있습니다.


OpenClipboard();//클립보드를 연다.

if(IsClipboardFormatAvailable(CF_TEXT))//클립보드에 텍스트 데이터가 있으면

{

    클립보드에서 데이터를 얻는다..

}

CloaseClipboard()//클립보드를 닫는다.


때로는 클립보드에 있는 데이터를 삭제하고자 할경우가 있습니다. 이때 사용하는 함수가 EmptyClipboard입니다.

만일 어떤 데이터를 클립보드에 넣고자 한다면 그리고 현재 있는 데이터를 삭제하고자 한다면 다음과 같이 할수 있습니다.


OpenClipboard();//클립보드를 연다.

EmptyClipboard();//클립보드에서 데이터를 지운다.

CloaseClipboard()//클립보드를 닫는다.


클립보드에서 데이터 얻기와 데이터 쓰기

클립보드에서 데이터를 얻고자 할 경우 GetClipboardData 함수를 사용합니다.

예를 들어서 클립보드에서 텍스트 데이터를 얻고자 한다면 다음과 같이 할수 있습니다.

         HANDLE hClipboard;

hClipboard=GetClipboardData(CF_TEXT);

만약 텍스트 데이터가 없다면 hClipboard에는 NULL값이 전송될것입니다. 넘겨주는 형식이 메모리 핸들러 형식이기 때문에 이데이터를 사용허가권을 받기 위해서는 GlobalLock를 사용해야 합니다.


 HANDLE hClipboard;

 LPASTR pClipboard;

hClipboard=GetClipboardData(CF_TEXT);

pClipboard=GlobalLock(hClipboard);

 //pClipboar를 사용한다.


위와 같이 하면 클립보드에 있는 데이터를 바로 사용하는 형식이 됩니다. 때로는 클립보드에 있는 데이터를 자신의 프로그램 내로 복사하고자 할경우가 있습니다. 이럴경우에는 클립보드에 저장된 데이터 크기만큼 메모리를 확보한후에 데이터를 복사하면 됩니다. 다음은 클립보드에서 데이터를 복사하는 예입니다.



           //클립보드를 연다

        OpenClipboard(hwnd);

        //문자형식의 데이터를 클립보드에서 얻는다.

        hClipboard=GetClipboardData(CF_TEXT);

        //hClipboard가 NULL이면 클립보드를 닫는다.

        if(!hClipboard)

        {

                CloseClipboard();

                 return 0;

        }

        //클립보드 데이터를 넣을 메모리 할당

        szBuff=GlobalReAlloc(szBuff,GlobalSize(hClipboard),GMEM_MOVEABLE);

        //메모리 사용 허가권을 받는다.

        pBuff=(LPSTR)GlobalLock(szBuff);

        //클립보드 메모리 사용허가권을 받는다.

        pClipboard=GlobalLock(hClipboard);

        //클립보드 데이터를 복사한다.


클립 보드에 데이터를 넣고자 한다면 SetClipboardData를 사용하여 간단하게 넣을 수 있습니다.


HANDLE SetClipboardData(

UINT uFormat, // 클립 보드 데이터 포맷

HANDLE hMem // 데이터 적재 메모리 핸들

); 


위의 예에서 pBuff에 있는 데이터를 수정한후 다시 클립보드에 넘기고자 할 때 있대 pBuff를 넘겨주는 것이 아니라 szBuff를 넘겨주어야 합니다. 클립보드로 넘어가는 것은 메모리 사용 허가 포인터 변수가 아니라 메모리 핸들러 이기 때문입니다.

 SetClipboardData(CF_TEXT,szBuff); 

// ex)

void CAddPeerDlg::OnBnClickedCopyInfo()
{

 if ( !OpenClipboard() )
 {
  AfxMessageBox( "Cannot open the Clipboard" );
 }

 // Remove the current Clipboard contents  
 if( !EmptyClipboard() )
 {
  AfxMessageBox( "Cannot empty the Clipboard" );
 }

 LPTSTR  lptstrCopy; 
 HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, 100 * sizeof(char));

 lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);

 UpdateData(TRUE);

 memcpy( lptstrCopy, m_cstrLocalIP.GetBuffer(), 15 );
 memcpy( lptstrCopy + 15, &m_uiLocalPORT, 2 );
 memcpy( lptstrCopy + 15 + 2, m_cstrExternalIP.GetBuffer(), 15 );
 memcpy( lptstrCopy + 15 + 2 + 15, &m_uiExternalPORT, 2 );
 lptstrCopy[99] = 0;

 GlobalUnlock(hglbCopy);

 // For the appropriate data formats...
 if ( ::SetClipboardData( CF_TEXT, lptstrCopy ) == NULL )  
 {
  AfxMessageBox( "Unable to set Clipboard data" );    
  CloseClipboard();
 }

 // ...  
 CloseClipboard();

}

 

 

 

void CAddPeerDlg::OnBnClickedPasteInfo()
{

 if ( !OpenClipboard() )
 {
  AfxMessageBox( "Cannot open the Clipboard" );
 }

 LPTSTR  lptstrCopy; 
 HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, sizeof(char)*100);     // 전역메모리할당
 hglbCopy = GetClipboardData( CF_TEXT );

 lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);

 m_cstrLocalIP = "";
 m_uiLocalPORT = 0;
 m_cstrExternalIP = "";
 m_uiExternalPORT = 0;

 char cTemp[100];
 memcpy( cTemp, lptstrCopy, 15 );
 m_cstrLocalIP = cTemp;
 memcpy( &m_uiLocalPORT, lptstrCopy + 15, 2 );
 m_uiLocalPORT = m_uiLocalPORT&0xffff;

 memcpy( cTemp, lptstrCopy + 15 + 2, 15 );
 m_cstrExternalIP = cTemp;
 memcpy( &m_uiExternalPORT, lptstrCopy + 15 + 2 +15, 2 );
 m_uiExternalPORT = m_uiExternalPORT&0xffff;

 UpdateData(FALSE);

 GlobalUnlock(hglbCopy);

 // ...  
 CloseClipboard();

}

Posted by 모과이IT
,
http://www.devpia.com/forum/BoardView.aspx?no=438217&page=1&Tpage=6&forumname=vc_qa&stype=&ctType=&answer=&KeyR=title&KeyC=
클립보드에 Text 설정하기
===========================================================================


            HGLOBAL         hMem; 

            if( OpenClipboard() )

            {

                if( EmptyClipboard() )

                {

                    hMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, 

                                        sizeof("원하는텍스트") );

                    if( hMem )

                    {

                        LPTSTR pClipData = (LPTSTR) GlobalLock(hMem);

                        pClipData[0] = 0;



                        strcpy( pClipData, "원하는텍스트" );



                        SetClipboardData( CF_OEMTEXT, hMem );



                        GlobalUnlock( hMem );

                    }



                    CloseClipboard();



                    GlobalFree( hMem );

                }

            }



클립보드 열고 -> 메모리생성해서 거기다 데이타 복사주해고 ->  클립보드 닫고, 메모리해제


클립보드는 락,언락을 해주어야 합니다..푸힛~리소스를 공유하기 때문이죠.

==========================================================================




http://www.devpia.com/forum/BoardView.aspx?no=438217&page=1&Tpage=6&forumname=vc_qa&stype=&ctType=&answer=&KeyR=title&KeyC=
비트맵 화면에 뿌려주가
==========================================================================
    HDC hdc;

    PAINTSTRUCT ps;

    HBITMAP hBit,hOldBitmap;

    HDC hMemDC;

    BITMAP bmp;

    if(::OpenClipboard(m_hWnd)){

        hBit=(HBITMAP)GetClipboardData(CF_BITMAP);

        CloseClipboard();

        hdc=::GetDC(m_hWnd);

        hMemDC=CreateCompatibleDC(hdc);

        hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBit);

        GetObject(hBit,sizeof(BITMAP),&bmp);

        BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hMemDC,0,0,SRCCOPY);

        SelectObject(hMemDC,hOldBitmap);

        DeleteDC(hMemDC);

        ::ReleaseDC(m_hWnd,hdc);

    }

===========================================================================






http://www.devpia.com/forum/BoardView.aspx?no=438217&page=1&Tpage=6&forumname=vc_qa&stype=&ctType=&answer=&KeyR=title&KeyC=

클립보드에 데이터 복사 및 가져오기

===========================================================================
programming windows , charles petzold의 p679 내용 입니다.



<클립보드에 복사>



HGLOBAL hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (lstrlen(pText) + 1) *sizeof(TCHAR));

PTSTR pGlobal = GlobalLock(hGlobal);

lstrcpy(pGlobal, TEXT("Hello"));

GlobalUnlock(hGlobal);



OpenClipboard(윈도우 핸들);

EmptyClipboard();

SetClipboardData(CF_TCHAR, hGlobal);

CloseClipboard();



<클립보드에서 가져오기>

OpenClipboard(윈도우 핸들);


HGLOBAL hGlobal = GetClipboardData(CF_TEXT); 
char a[1024];
if(hGlobal) 


        PTSTR pGlobal = (char*)GlobalLock(hGlobal); 

        lstrcpy( a,pGlobal); 

        GlobalUnlock(hGlobal); 



CloseClipboard();
Posted by 모과이IT
,