2012년 5월 17일 목요일

MFC 강의 -4 컨트롤 다루기 - 버튼

MFC 강의 - 4 컨트롤 다루기 -버튼

일단 처음은 대화상자 기반으로 만듭니다.(컨트롤을 만들고 배치하기 편하기 때문에...)
1.
처음에 생성되는 버튼들을 전부 지웁니다.

도구상자에 있는 버튼을 클릭해서

이렇게 가운데 하나를 배치하고 아래에 세 개를 배치합니다.

배튼 한 개씩 클릭해서 옆에 있는 속성창의 caption과 ID를 수정합니다.
순서는 달라고 되니까 ID와 CAPTION이 일치하도록 해주세요.

제목 바꾸기 - IDC_BUTTON_TITLE
숨기기        - IDC_BUTTON_SHOW
사용하지 못하게 함 - IDC_BUTTON_DISABLE

그 다음 MFC 클래스 마법사를 실행하면 (오른쪽 클릭 후 클래스 마법사항목 선택)
개체 ID와 메시지라는 항목이 나옵니다.
메시지 항목은 왼쪽의 클릭된 객체의 메시지(버튼이 클릭되었을 경우라던가...)입니다.
우리가 만들었던 버튼들 중 IDC_BUTTON_TITLE를 빼고 전부 BN_CLICKED메시지를 클릭하여 처리기를 추가합니다.
이렇게 하면 버튼들이 클릭되었을 때(이벤트) 운영체제에서 해당 버튼이 클릭 되었다는 메시지(BN_CLICKED)를 보내는 처리기(함수)를 설정해 주는 것 입니다.



코드 창을 보면 클래스의 메소드 3개가 추가되어있는 것을 확인할 수 있습니다.

그럼 우선 OnClickedButtonDisable()이란 함수를 수정해 보도록 하겠습니다.
"사용하지 못하게 함"이라 써져 있던 버튼이 클릭되어 있을 때 실행되는 메소드입니다.

void CMFC4Dlg::OnClickedButtonDisable()
{
//현재 버튼이 어떤 상태인지를 기억하기 위한 변수를 선언합니다. 함수가 종료더라도 상태
//은 기억되야 하므로 정적변수로 선언합니다.
//처음 실행될 때의 상태는 사용할 수 있으므로 true로...
static bool bEnable = true;
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
//누르면 상태가 바뀌어야 하므로 !연산자을 한 자기 자신을 대입합니다.
bEnable = !bEnable;
//GetDlgItem()은 해당 ID인 컨트롤인 클래스의 주소를 반환합니다. 클래스의 메
//소드를 이용하여 컨트롤의 상태를 조절할 수 있습니다.
//컨트롤 클래스의 메소드인 EnableWindow()는 bool변수를 인수로 가지며,
//true일 경우 버튼을 사용할 수 있게, false일 경우 버튼을 사용불가로 만듭니
//다.
GetDlgItem(IDC_BUTTON_TAGET)->EnableWindow(bEnable);
if(bEnable)
{
//SetWindowText()메소드는 버튼의 텍스트를 설정하는 메소트입니다.

GetDlgItem(IDC_BUTTON_DISABLE)->SetWindowText(_T("사용하지 못하게
                함"));
}
else
{
GetDlgItem(IDC_BUTTON_DISABLE)->SetWindowText(_T("사용하게 함"));
}
}
다음은 "숨기기"라 써져있던 버튼이 클릭되었을 때 실행되는 메소드를 수정해 보겠습니다.
OnClickedButtonShow이란 메소드입니다.

void CMFC4Dlg::OnClickedButtonShow()
{
static bool bShow=true;
bShow = !bShow;
GetDlgItem(IDC_BUTTON_TAGET)->ShowWindow(bShow);
if(bShow)
{
GetDlgItem(IDC_BUTTON_SHOW)->SetWindowText(_T("숨기기"));
}
else
{
GetDlgItem(IDC_BUTTON_SHOW)->SetWindowText(_T("보이기"));
}
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
}
내용은 거의 같습니다. 다만 EnableWindow(bEnable)이 아닌  ShowWindow(bShow)인데
인수가 true면 보이는 상태로 false면 보이지 않는 상태로 변경합니다.

이제 제목 바꾸기 라는 버튼이 클릭되었을 때 실행되는 메소드를 수정해 보겠습니다.
OnClickedButtonTitle이란 메소드 입니다.


void CMFC4Dlg::OnClickedButtonTitle()
{
static bool bTitle =true;
bTitle = !bTitle;
if(bTitle)
{
GetDlgItem(IDC_BUTTON_TAGET)->SetWindowTextW(_T("바뀌었다."));
}
else
{
GetDlgItem(IDC_BUTTON_TAGET)->SetWindowTextW(_T("실험체"));
}
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
}
참고로 버튼(컨트롤)의 상태를 변경하는 메소드가 Window라고 써져있는 이유는
사실 컨트롤들은 일종의 윈도창입니다. 자세한 것은 인터넷에 검색해 보시길...

예제 파일 다운

wxWidgets튜토리얼03-2 버튼 만들기

1-단순한 창 띄우기
main.h
#include<wx/wx.h>

class MyApp: public wxApp
{
    public:
        virtual bool OnInit();
};

main.cpp
#include"main.h"
#include"CMainFrame.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    CMainFrame *MainFrame = new CMainFrame(wxT("My First Program"));
    MainFrame->Show(true);
    return true;
}

CMainFrame.h

#include<wx/wx.h>

class CMainFrame:public wxFrame
{
    public:
        CMainFrame(const wxString& title);
//기본 프로그램에서 추가된 함수
        void OnButton(wxCommandEvent & Event);
};

CMainFrame.cpp

#include"CMainFrame.h"

CMainFrame::CMainFrame(const wxString & title)
 : wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxSize(640,480))
{
    wxPanel * Panel = new wxPanel(this,wxID_ANY);
    wxButton * Button = new wxButton(Panel , wxID_OK , wxT("This is a button") , wxPoint(20,20) );
    Connect(wxID_OK , wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler
   (CMainFrame::OnButton));
    Centre();
}
void CMainFrame::OnButton(wxCommandEvent & WXUNUESED( Event ) )
{
    wxMessageBox(wxT("You click a button"),wxT("Info"),wxOK);
}

wxWidgets튜토리얼 03-첫프로그램

1-단순한 창 띄우기
main.h
#include<wx/wx.h>

class MyApp: public wxApp
{
    public:
        virtual bool OnInit();
};

main.cpp
#include"main.h"
#include"CMainFrame.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    CMainFrame *MainFrame = new CMainFrame(wxT("My First Program"));
    MainFrame->Show(true);
    return true;
}

CMainFrame.h

#include<wx/wx.h>

class CMainFrame:public wxFrame
{
    public:
        CMainFrame(const wxString& title);
};

CMainFrame.cpp

#include"CMainFrame.h"

CMainFrame::CMainFrame(const wxString & title)
 : wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxSize(640,480))
{
    Centre();
}
----------------------------------------------------설명---------------------------------------------------
MyApp 클래스
콘솔 프로그램이나 WinAPI의 GUI프로그램에서의 main이나 WinMain과 비슷한 역활을 한다.
프로그램이 시작할 때(OnInit메소드) 창을 생성하고(CMainFrame선언) 화면에 뜨게한다(MainFrame의 Show메소드)
IMPLEMENT_APP(MyApp)
MyApp클래스를 프로그램이 시작할 때 생성해 달라는 매크로, 이 매크로가 있어야만 MyApp클래스가 처음으로 생성되고, OnInit을 호출하여 창을 보여준다.
CMainFrame클래스에 대한 설명
CMainFrame은 wxFrame이라는 클래스을 상속받는다.

CMainFrame::CMainFrame(const wxString & title)
 : wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxSize(640,480))
CMainFrame의 생성자가 실행될 때  상속된 wxFrame의 생성자도 같이 실행된다.
wxFrame의 생성자는 여러 인자를 같고 있는 데 창을 생성할 때 필요한 정보들이다.
이외에도 더 많은 인수가 있지만, 디폴드 인수가 있어서 신경을 쓰지 않아도 된다.
Centre()
창을 화면 중앙에 배치해주는 함수.

2012년 5월 15일 화요일

wxWidgets 튜토리얼 01,02

wxWidgets 튜토리얼 01 소개


wxWidgets는 C++로 응용프로그램을 제작할 때 쓰는 GUI(그래픽 유저 인터페이스)툴킷입니다.
wxWidgets는 오픈소스이며 다중플랫폼 풀킷입니다.
wxWidgets는 윈도우즈,유닉스와 맥같은, 모든 주요 운영체제 플랫폼에서 구동됩니다.
wxWidgets프로젝트는 1992년에 Julian Smart가 시작했습니다.
wxWidgets는 툴킷, 그 이상의 것입니다.
wxWidgets는 파일입출력,데이터베이스,쓰레드,온라인도움 또는 응용프로그램셋팅등을 관리하는 크고 다양한 클래스들를 제공합니다.
wxWidgets는 widget들의 커다란 그룹으로 구성되어 있습니다.

wxWidgets 튜토리얼 02 보조 클래스 (helper classes)

wxString
wxString은 문자열을 표현하는 클래스입니다.
초기화 -
wxString str = wxT("This");
wxString str_2=wxT("is");
wxString str_3=wxT("wxWidget");

wxString str_joint = str+ wxT(" ") + str_2 + wxT(" ") + str_3;
메소드
Printf() : 해당문자열을 대입해준다.

ex)
int x = 50;
wxString OutPut;
OutPut.Printf(wxT(" Variable x is  %d "),x);

Len() 문자열의 길이를 반환해줍니다.

wxDataTime
wxDataTime은 시간및 날짜를 제공하는 클래스입니다.
wxFile
파일입출력을 제공하는 클래스입니다.
wxDir
파일과 디텍토리(폴더)를 열겨해주는 클래스입니다.

MFC강의 - 3 버튼을 만들어서 메시지 보내기

MFC강의 -3
MFC는 메시지처리를 상당히 편하게 해줍니다.
클래스 위저드를 통해서 메시지가 보내졌을 때 실행되는 함수를 설정할 수 있습니다.

우선 기본적으로 대화상자를 이용하여 버튼을 만들어서 메시지를 처리해 봅시다.
이렇게 '대화 상자 기반'으로만 설정해 주시고 넘어 갑니다.
생성을 하면 이러한 창이 뜹니다.
이때 가운데의 문장과 2개의 버튼을 전부 지웁니다.(연습을 위해서)
그다음

옆의 대화 상자 편집기에서 버튼을 하나 선택하여 만듭니다.
버튼을 오른쪽 마우스 버튼을 클릭하여서 속성으로가서 기타의 ID를 IDC_BUTTON_OK로
모양의 caption를 OK로 바꾸어 줍니다.
그다음 버튼을 더블 클릭하면
코드 편집창이 뜨는데 이중 아래 쪽의 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.이라고 씌여져 있는 함수 메쏘드안에다 MessageBox(_T("버튼을 클릭하였습니다"),_T("알림"),MB_OK);이라는 코드를 입력해 줍니다.

드러면 OK라 써져 있는 버튼을 누를 때 메시지 박스가 나타납니다.

---------------------------------------------------------------------------------
프로그램이 실행되었고, 만약 사용자가 OK라는 버튼을 누르면(이벤트 발생), 윈도우즈는 프로그램에게 이 버튼이 눌렸다는 메시지를 보냅니다. 이 때 버튼이 눌렸을 때 보내는 메시지는 WM_COMMAND라는 메시지입니다. WM_COMMAND 메시지는 어떠한 버튼이 눌렸는지를 알려주기위해서 부가정보와 같이 오는데 버튼을 만들 때 정한 ID로 구분해줍니다.
버튼을 대화상자위에 올리고, ID와 캡션의 정보를 변환한 뒤, 버튼을 더블클릭하는 순간 비주얼 스튜디오는 자동으로 WM_COMMAND가 보내졌을 때 ID가 IDC_BUTTON_OK일 때 실행할 함수를 자동으로 만들어 줍니다.

MessageBox함수는 그대로 메시지 박스를 출력해주는 함수로서
MessageBox(메시지박스안에 출력할 문자열,캡션에 출력할 문자열,기타 메시지박스 설정)
을 받습니다.

MFC 강의 -2 이벤트,메시지란?

MFC강의 -2
이벤트,메시지란 란?
윈도우 프로그램은 기본적으로 이벤트를 받았을 경우 그에 반응하는 것으로 이루어져 있습니다. 만일 사용자가 프로그램에 있는 버튼을 눌렀을 경우, 프로그램은 버튼을 눌렀다는 이벤트에 반응하여 행동을 합니다.
 이를 위해서 윈도우즈는 프로그램에게 메시지를 보냅니다.
즉 사용자 ->버튼을 눌름 ->운영체제 ->메시지를 보냄 ->프로그램 (메시지에 대한 처리)
로 이루어져 있습니다. 또한 운영체제는 메시지 큐라는 것을 메시지를 순서대로,사용자가 행동한 이벤트를 정확히 프로그램에게 주기 위해서,다른 프로그램에게 보내지지 않게 하기 위해서  만듭니다.

윈도우즈  API를 이용한 프로그램의 기본적인 구조는

1.윈도 창에 대한 기본적인 설정을 해준다.
2.윈도 창에 대한 설정을 윈도우즈에 알려준다.
3.윈도 창을 만든다.
4.윈도우 창을 표시한다.
5.메시지가 오기를 기다리며, 메시지가 올 경우 메시지를 처리하는 함수로 메시지에 대한 정보       를 건넨다(메시지 루프).
6.종료하겠다는 메시지가 오면 프로그램을 종료한다.

으로 이루어 져있습니다.

메시지 루프는 반복문으로 이루어져 있는데 C언어를 이용한 구현으로는

while(GetMessage(&Message,0,0,0))
{
       DispatchMessage(&Message);
}
으로 되어 있습니다.
GetMessage라는 함수는 메시지 큐에 메시지가 있을 때까지 대기했다가 있으면 DispatchMessage함수를 부릅니다.
DispatchMessage함수는 윈도 창에 대한 설정을 할 때, 설정한 메시지 처리 함수에게 메시지 정보를 주고 처리를 시킵니다.

윈도우의 기본적인 메시지는
WM_CREATE     : 윈도우 창이 생성될 때 보내시는 메시지 입니다.
WM_DESTROY   : 윈도우 창을 닫는다는 이벤트가 발생될 때 보내지는 메시지입니다.
WM_KEYDOWN  : 사용자가 키를 누를 때 보내지는 메시지입니다.
WM_MOUSEMOVE : 사용자가 마우스를 움직일 때 보내지는 메시지입니다.
WM_LBUTTONDOWN:사용자가 프로그램 창안에서 왼쪽 마우스 버튼을 눌렀을 때 보내지는 메시지 입니다.

등등이 있습니다.

2012년 5월 4일 금요일

MFC강의 - 1 MFC란?

MFC강의-1 MFC란?

MFC란 Microsoft Foundation Class Library의 약자이다.
즉 마이크로소프트사에서 만든 WinAPI 를 클래스로 묶어놓은 라이브러리 라는 뜻이다.
MFC의 장점은 WinAPI를 클래스로 묶어놓았기 때문에 WinAPI보다 쓰기 편하다는  것이고 또 비주얼 스튜디오에서 기본적인 틀을 만들어 주므로 그 기본적인 틀위에 컨트롤등을 올려 놓음으로써 빠르게 응용프로그램을 제작 할 수 있다는 것이다.
물론 그렇다고 해서 배우는 것이 쉽다는 것은 아니다.