C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[63350] Re:Re:Re:Re:Re:Re:Re:Re:빌더에서 이벤트 만드는 법?
나그네 [kdaek] 1843 읽음    2010-12-24 22:19
지금 시작 님이 쓰신 글 :
: 나그네 님이 쓰신 글 :
: : 드디어 해냈습니다. 그래서 성공한 소스를 올리겠습니다. (물론 소스 복사해서)
: : 먼저 콘솔 모드에서의 예제입니다.(비교적 쉬움)
: :
: : //---------------------------------------------------------------------------
: : 
: : #include 
: : #include 
: : #pragma hdrstop
: : 
: : //---------------------------------------------------------------------------
: : 
: : #pragma argsused
: : typedef void (*TEvent)(); //함수 포인터를 선언하되 이벤트 변수를 만들기위해 typedef로 선언함
: : class EventClass{
: :         private:
: :                 TEvent FEvent; //이벤트
: :         public:
: :                 __property TEvent Event = {read=FEvent, write=FEvent}; //이벤트 핸들러(프로퍼티)
: :                 //void AddEvent(TEvent event); 메서드 방식의 이벤트 핸들러
: :                 void Fire(); //이벤트를 발생시키게 될 메서드
: : };
: : 
: : /* 메서드 방식의 이벤트 핸들러 본체
: : void EventClass::AddEvent(TEvent event)
: : {
: :        FEvent = event;
: : }
: : */
: : 
: : void EventClass::Fire() //이벤트 발생용 메서드의 내부
: : {
: :         if (Event!=NULL)
: :         {
: :                 Event(); // 여기서 이벤트 발생!
: :         }
: : }
: : 
: : void Func()
: : {
: :         printf("이벤트가 발생했습니다.\n"); //이벤트가 실행할 함수
: : }
: : 
: : int main(int argc, char* argv[]) //메인 함수
: : {
: :         EventClass *t = new EventClass(); //이벤트 클래스를 객체화함(포인팅)
: :         t->Event = Func; //위 객체의 Event의 이벤트 핸들러로 위 Func()함수를 지정함
: :         //t->AddEvent(Func); 메서드 방식일경우의 이벤트 연결
: :         t->Fire(); //이벤트를 발생시키는 함수 호출
: :         scanf("."); //대기를 위해 변수 없는 scanf()함수 호출
: :         return 0;
: : }
: : //---------------------------------------------------------------------------
: : 

: : 위 프로그램을 실행하면 콘솔창(혹은 도스화면)에 '이벤트가 발생했습니다'라고 출력된후 그아래에 커서가 껌벅거릴것이다. (종료를 원하면 엔터키를 두들겨주면 됨)
: :
: : 이번에는 내가 가장 많이 해맸던(?) 클래스 투 클래스이다. 즉 윈도우 프로그램에서의 사용법이다.
: : 먼저 유닛을 하나 만든후 (그러면 원래있던 unit1과 unit2 둘 생긴다. 각각에 둘의 헤더파일을 모두 인클루두 해줄것)
: : 먼저 새로생긴 유닛의 헤더파일(unit2.h)에 아래 코드를 작성
: :
: : typedef void (__closure *TOnEvent)(); //콘솔과 같은기능이나 앞에 __closure를 반드시 붙일것
: : class Test{ //임시로 만든 테스트 클래스
: :         private:
: :                 TOnEvent FOnEvent; //이벤트
: :         public:
: :                 void FireEvent(); //이벤트 발생용 메서드
: :                 __property TOnEvent OnEvent = {read = FOnEvent, write = FOnEvent}; //이벤트 핸들러(프로퍼티)
: :                 //void AddEvent(TOnEvent event); 메서드방식 이벤트 핸들러
: : };
: : 

: : 그리고 새로 생긴 유닛의 소스파일(unit2.cpp)에 아래 코드(이벤트 발생용 함수)를 작성하고
: :
: : /*메서드 방식의 이벤트 핸들러 본체
: : void Test::AddEvent(TOnEvent event)
: : {
: :        FOnEvent = event;
: : }
: : */
: : 
: : void Test::FireEvent()
: : {
: :         FOnEvent(); //이벤트 발생
: : }
: : 

: :
: : 폼 클래스가있는 유닛의 헤더파일(unit1.h)의 폼 클래스에서
: : public멤버에 void Run(); 선언해주고
: : 폼 클래스를 디자인 보기 한후 버튼 하나 드리워 놓고 더블클릭한후 버튼의 이벤트 핸들러 메서드에는 아래의 코드를 넣고
: :
: :   Test *t = new Test();
: :    t->OnEvent = Run;
: :    //t->AddEvent(Run);
: :    t->FireEvent();
: : 

: : 빈곳에 아래 메서드를 넣어주면 됩니다.
: :
: : void TForm1::Run()
: : {
: :         ShowMessage("이벤트가 발생했어요~");
: : }
: : 

: : 그리고 컴파일하고 실행하면 '이벤트가 발생했어요~'가 메시지박스에 출력되어 뜹니다.
: : 여기서 처음에 테스트를 윈도(폼)에서 하려고 했을때 __closure를 몰라서 해맸던거 같네요(일반 메서드 포인터 처럼
: : type void (Test::*TEvent)(); 했으니.... 에러뜨는건 당연지사죠..
: :
: : 주석처리 된 코드는 메서드 방식으로 구현했을때의 코드 입니다.
: :
: : 둘리.CSIEDA 님이 쓰신 글 :
: : : 원하시는 답이 정확히 뭔지를 정리해주셔야 답을 찾으실수 있습니다.
: : : 물어보시는 분이야 몰라서 물어본다고 어쩔수 없지만, 그래도 어느정도 정리를 해보시고 정확히 물어보셔야
: : : 좋은 답을 찾으실 수 있을 듯 합니다.
: : :
: : : 제가 답을 단건 프로퍼티에 메소드 연결하는 것입니다. 컴포넌트 이벤트가 아닙니다. 컴포넌트 이벤트는 다른 분이 설명
: : :
: : : 참조 사이트 붙여 주셨고요
: : :
: : : 질문을 잘못하신건지 답변을 잘못한건지 모르겠군요...ㅠ.ㅠ
: : :
: : : 설마해서 생각해 봤는데 , 혹시 MESSAGE_MAP 을 원하시는건가요?
: : :
: : : 수고하세요~~~
: : :
: : : 나그네 님이 쓰신 글 :
: : : : 답변을 잘못달았네요.. 프로퍼트에 일반 함수 연결은 이미 알고있었고요..(예전에 끄적거리다..) 컴포턴트 이벤트는 제 질문과 거리가 멉니다. 제가 원하는건 사용자 정의 이벤트 만들기 입니다.(프로퍼트에 메소드 포인터인가 연결하는..)
: : : : 둘리.CSIEDA 님이 쓰신 글 :
: : : : : component event 는 아래에 올리셨네요.. class __property 에 연결된 함수 연결에 대하여 적어 봅니다.
: : : : :
: : : : : 제 블로그에 있는거 옮겨 copy 해 왔어요..
: : : : : http://opensourceforge.tistory.com/368
: : : : :
: : : : : 이하  paste 된 문장.------------------------------------------------------------------------------
: : : : :
: : : : : C++ Builder 의 class 에서 __property 에 의한 함수의 호출이 어떻게 이루어 지는지를 간략하게 설명하고자 한다.
: : : : :
: : : : : 
: : : : :
: : : : : 우선 C++ Builder 의 c++ 키워드로 __property 가 있다.  키워드 중 __ 가 붙은 즉 _ 가 두개 붙은 경우는 해당 컴파일러 만의 기능인 것을 인식해야 한다. 즉 __property 는 VC++ 에는 없다. 만약에 있다고 하더라도 그 기능은 다를 수 있다.
: : : : :
: : : : : 
: : : : :
: : : : : 일단 클래스 A 를 만들어 본다.
: : : : :
: : : : : 
: : : : :
: : : : : class A
: : : : :
: : : : : {
: : : : :
: : : : :           int Fdata;
: : : : :
: : : : :     protected:
: : : : :
: : : : :           int getData()
: : : : :
: : : : :           {
: : : : :
: : : : :                  return Fdata;
: : : : :
: : : : :           }
: : : : :
: : : : :           void setData(int v)
: : : : :
: : : : :           {
: : : : :
: : : : :                  Fdata = v;
: : : : :
: : : : :           }
: : : : :
: : : : :     public:
: : : : :
: : : : : 
: : : : :
: : : : :           __property int data = {read=getData,write=setData};
: : : : :
: : : : : };
: : : : :
: : : : : 
: : : : :
: : : : : 위와 같은 class 에 의하여 객체를 하나 만들어 보자.
: : : : :
: : : : : 
: : : : :
: : : : : A a;
: : : : :
: : : : : 
: : : : :
: : : : : 이제 a 라는 객체는 int Fdata 라는 private member 변수를 하나 갖게 되며 getData() 와 setData 라는 member 함수를 갖게 된다.
: : : : :
: : : : : 
: : : : :
: : : : : 우리가 클래스 객체에 있어서 내부 데이터의 접근 보호를 위하여 hiding 을 시키는 경우가 있으며 그 데이터 메모리에 접근 하는 방법을 제한적으로 설정하기를 원할 때가 있다. 이러한 경우 우리는 일반적인 c++ 프로그래밍에서 get 과 set 메소드를 만들어 접근하도록 하는 방법을 사용하고 있다.
: : : : :
: : : : : 이는 모든 객체 지향 프로그래밍의 기본으로 사용되고 있는 방식이다.
: : : : :
: : : : : 그러나 이러한 get 과 set 을 이용할 경우 우리는 함수의 형태를 갖는다는 것을 알 수 있으며 실제 접근 자체에서 해당 객체의 멤버함수의 호출 형식으로 이루어 진다.
: : : : :
: : : : : C++ Builder 의 __property (Delphi 도 마찬가지) 는 바로 이러한 객체 멤버함수에 접근하는 방법을 변수 형식으로 일관된 이름을 통하여 구현하도록 해 주는 것이다.
: : : : :
: : : : : 
: : : : :
: : : : : 즉 위의 class 에 의하여 만들어진 객체 a 에 대하여
: : : : :
: : : : : 
: : : : :
: : : : : a.getData() 에 의하여 Fdata 에 대한 read  접근, a.setData() 에 의하여 Fdata 에 대한 write 접근을 하게 된다. 이러한 연결 채널을
: : : : :
: : : : : __property int data = {read=getData,write=setData};
: : : : :
: : : : : 가 해주는 것이다.
: : : : :
: : : : : 
: : : : :
: : : : : a.data 라는 property 에 우리는 두 가지의 접근이 있을 수 있다는 것을 알 수 있다.
: : : : :
: : : : : 1. write 접근
: : : : :
: : : : : 2. read 접근
: : : : :
: : : : : 
: : : : :
: : : : : write 접근 과 read 접근이 과연 무엇일까???    별거 아니다. 바로 대입 연산자(operator)의 왼쪽에 있는 피 연산자(operand) 인지 오른쪽에 있는 피 연산자 인지를 나타낸다.. 대입 연산자의 왼쪽에 있으면 write 접근이고 오른쪽에 있으면 read 접근이 된다.
: : : : :
: : : : : 이렇게 어떤 메모리에 데이터가 갱신 되어질 경우와 해당 데이터를 읽어 오는 경우로 나뉘며 이를 분석하여 C++ Builder 는 a.data 에 대한 연결된 메소드를 어떤 것을 컴파일 시간에 링크하여 호출해야 할지를 컴파일러가 알아서 할당한 다는 것이다.
: : : : :
: : : : : 즉
: : : : :
: : : : : 
: : : : :
: : : : :       int i = a.data;   와    a.data = 10;    에서 data 접근은 서로 다른 함수가 호출된다는 것이다.
: : : : :
: : : : : 나그네 님이 쓰신 글 :
: : : : : : 두가지 종합입니다.
: : : : : : 프로퍼티에 연결된 메서드로 이벤트를 만들어서 프로그램의 흐름 중간에서 이벤트를 발생사켜서 사용해보려고 합니다.
: : : : : : 그런데 프로퍼티에 연결된 메서드만드는거 부터가 안되네요..
: : : : : : 둘리.CSIEDA 님이 쓰신 글 :
: : : : : : : TForm 에 OnMouseDown 과 같은 event 를 말씀하시는건가요??
: : : : : : : 아니면 __property 에 연결된 class method 를 말씀하시는 건가요?
: : : : : : :
: : : : : : : 나그네 님이 쓰신 글 :
: : : : : : : : C++빌더에 보면 이벤트 핸들러런게 있네요.. 실제로 C++빌더로 짠 프로그램도 이 이벤트에 따라 움직이고요..
: : : : : : : : 그렇다면 사용자 정의 이벤트를 만들어 사용 할 수도 있을거 같은데.. 이벤트를 만드는 방법은 없나요?
:
:
:
:
:
:
:
: 안녕하세요~ 나그네님께서 작성해주신 이벤트 등록방법을 보고 연습중인대요...
: 제가 이해 하기로는 위 방법대로 하면 프로퍼티 창에 이벤트가 등록된다는 것으로 이해를 하고 했는데 프로퍼티 창에 나타나지 않내요....
:
: 그리고 한가지 의문인것은 위 소스는 버튼을 눌렀을때 해당 사용자 이벤트가 발생하는 구조인것 같습니다. 그러면 그냥 버튼 클릭이벤트에다가 showmessage한거랑 어떤 차이가 있는지 잘 이해가 안되내요...
:
: 저같은 경우 외부에서 IO카드로 입력신호가 들어왔을때 발생하는 이벤트를 만들고자 합니다... 지금까지는 타이머를 사용하거나 반복문 루틴안에서 계속 입력신호를 확인하는 부분을 넣었는데요... 이런경우 프로세스의 점유율이 높거나 여러 타이머가 동시에 돌아갈경우 제대로 처리하지 못하는 문제가 발생해서 이벤트방식으로 처리하려고 합니다.
:
: 조언좀 부탁드립니다
1년전? 글에 답글을 다셨네요..
참고로 저는 C++을 배운 적이 없어서..(가끔? 인터넷 보고 혼자 해보긴하지만..) VC++갖고 간단한거 만들어보다가.. 너무 어려워서 포기하고 있던 차에 학교(대학)에서 교제로 쓰던 책에서 C++ 빌더가 소개되 VB(혹은 C#)만큼 쉬운 C++ 개발 툴도 있구나 하여 어둠의 경로서 다운 받아 해보곤한게 전부입니다.(C++에 대한건 기본만 압니다.. 라이브러리같은건 모릅니다.. ㅡㅡ;) 따라서 조언을 못해주겠네요 죄송합니다. 제전공은 VB.NET(VB7버전), C#(1.1 버전) 이고요,, 현제 취업 목적으로 자바를 배우곤있습니다만.. C++은 여전히 모릅니다.. 다른 님의 조언을 기다려주세야 겠네요..

+ -

관련 글 리스트
56303 빌더에서 이벤트 만드는 법? 나그네 1947 2009/02/27
56311     Re:빌더에서 이벤트 만드는 법? 둘리.CSIEDA 1746 2009/02/28
56313         Re:Re:빌더에서 이벤트 만드는 법? 나그네 1647 2009/02/28
56316             Re:Re:Re:빌더에서 이벤트 만드는 법? 둘리.CSIEDA 1740 2009/02/28
56320                 Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 나그네 1566 2009/02/28
56322                     Re:Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 둘리.CSIEDA 1643 2009/03/01
56342                         Re:Re:Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 나그네 1926 2009/03/02
63344                             Re:Re:Re:Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 지금 시작 1474 2010/12/24
63350                                 Re:Re:Re:Re:Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 나그네 1843 2010/12/24
56310         Re:Re:빌더에서 이벤트 만드는 법? 나그네 1491 2009/02/28
56315             Re:Re:Re:빌더에서 이벤트 만드는 법? 김권영 1868 2009/02/28
56319                 Re:Re:Re:Re:빌더에서 이벤트 만드는 법? 나그네 1671 2009/02/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.