[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (5) Events
본문
프로그래밍하는 개념을 전환해야 할 필요가 있습니다. C 언어를 처음 공부할 때 main() 으로 시작해서 일렬로 주욱 씌어진 일감의 나열이 아니라, 사용자, 혹은 시스템의 요구에 따라 내 프로그램이 어떻게 반응해야 할 것인지를 정의해 나가는 것이 윈도우 기반 프로그래밍의 기술입니다.
예전에도 한 번 사용했던 타이머 이벤트부터 한 번 다시 써먹어 볼까요?
--- TimerEvent.h ---
#include
void InstallTimerEventHandler( WindowRef window ) ;
pascal void TimerEventHandler( EventLoopTimerRef inTimer, void* timeData ) ;
--- TimerEvent.c ---
#include "TimerEvent.h"
#include
void InstallTimerEventHandler( WindowRef window )
{
EventLoopTimerUPP timerUPP ;
timerUPP = NewEventLoopTimerUPP( TimerEventHandler ) ;
InstallEventLoopTimer( GetCurrentEventLoop(),
0,
kEventDurationMillisecond,
timerUPP,
(void *)window,
NULL ) ;
}
int inc = 0 ;
pascal void TimerEventHandler( EventLoopTimerRef inTimer, void* timeData )
{
WindowRef window = (WindowRef)timeData ;
CGContextRef myContext ;
int cx = 300, cy = 300 ;
double radius = 200.0, i ;
int px, py ;
SetPortWindowPort( window ) ;
QDBeginCGContext( GetWindowPort( window ), &myContext ) ;
for( i = 0.0 ; i < 60.0 ; i+=0.1 ) {
CGContextSetRGBStrokeColor( myContext,
1.0 - (float)i / 60.0,
1.0,
1.0 - (float)i / 60.0,
1.0 ) ;
px = (int)( cos( ( (double)inc + i ) * M_PI / 180.0 ) * radius ) + cx ;
py = (int)( sin( ( (double)inc + i ) * M_PI / 180.0 ) * radius ) + cy ;
CGContextMoveToPoint( myContext, cx, cy ) ;
CGContextAddLineToPoint( myContext, px, py ) ;
CGContextStrokePath( myContext ) ;
}
inc++ ;
inc %= 360 ;
QDEndCGContext( GetWindowPort( window ), &myContext ) ;
}
지금까지의 예제와 마찬가지로, InstallTimerEventHandler() 함수를 main 에서 호출해야 합니다. 모르시는 분은 앞의 강좌를 참조하시고요.
UPP 란 무엇인고, UPP 란 Universal Procedure Pointer 입니다. 이렇게 요란스러운 이름을 갖고 있어서 참 사람들을 암담하게 합니다만, 윈도우 프로그래밍 옛날부터 공부해 보신 분들은 void FAR PASCAL WinProc( HANDLE wndHandle... 라는 이상한 마술 주문같은 것도 나오지 않습니까? ㅎㅎㅎ 도찐 개찐이죠.
카본이라고 부르기 전에 매킨토시의 시스템 루틴을 툴박스라고 부르던 시절, 초창기 매킨토시의 핵심 루틴은 파스칼로 만들어졌습니다. 1984년 당시에는 C 언어보다도 파스칼이 훨씬 더 유망했죠. UCSD Pascal 을 당연히 채택하게 되었습니다. 그러나 세상이 바뀌어 강호의 본좌를 C 가 차지하게 되면서 파스칼은 급격히 퇴출당하게 되었는데요, 매킨토시의 핵심 루틴을 통째로 바꿀 수는 없는 노릇이었지요. 카본으로 자리를 잡으면서는 많이 나아진 편입니다만, 예전에는 전부 Str255 라든지 하는 파스칼 데이터 형식을 써야만 했습니다. 지금도 호환성 문제로 그 루틴은 남아있습니다.
하지만, pascal 형의 좋은 점이 한 가지 있었으니, 함수 콜 부문에서는 파스칼 타입이 좀 더 속도가 빠릅니다. C 형식은 전달 인수를 끝에서부터 스택에 저장하는 방식이고, 파스칼은 앞에서부터 저장을 합니다. C 형식의 장점은, printf() 함수에서 볼 수 있듯이, 가변적인 인수 갯수를 채택할 수 있다는 점이 있습니다. 그런데 C 언어 세계에서도 C++ 로 진화하면서 C++ 타입은 모두 파스칼 형식의 함수 호출 방법을 쓰고 있지요. 그래서 옛날 C 형식의 함수를 쓸 때에는 extern "C" 같은 예약어를 사용해야 합니다. 어쨌든, 프로그래밍 세계도 참 복잡한 편입니다. ㅎㅎㅎ
어쨌든, 타이머 이벤트가 발생했을 때 어떤 함수가 그 이벤트를 받아서 처리할 것인지를 결정하도록 만들어 주는 것이 바로 InstallEventLoopTimer 함수입니다. 타이머란 일정한 시간이 되면 시스템이 우리 쪽으로 호출을 해 줍니다. 프로그램은 그에 따라서 필요한 일을 하지요. 이를 응용하면 시계 같은 프로그램을 만들 수 있고, 자동으로 알아서 무엇인가를 해야 하는 프로그램을 만들 때 유용하게 쓸 수 있습니다.
이번 예제에서는 HIView 판을 깔지 않고 그대로 퀵드로우 포트에서 코어 그래픽스 컨텍스트를 얻어내는 방법을 택하였습니다. 역시 카본은 융통성이 있지요? ㅎㅎㅎ 자세한 내용은 직접 소스를 살펴보시면서 확인하시면 되겠습니다.
최신글이 없습니다.
최신글이 없습니다.
댓글목록 1
악동시니님의 댓글
흐흐흐.. 잼나게.. 감사합니당...