델파이 4 프로그래밍의이해 (Understandings of Delphi 4 Programming) 오브젝트파스칼과심도있는델파이프로그래밍의세계로들어가기전에, 이번장에서는델파이를사용하여첫번째윈도우어플리케이션을제작하고전반적인델파이의환경에대해서알아볼것이다. 내용의수준이높지는않겠지만, 흔히알고있었던내용이라고하더라도별생각없이넘어갔던것들도많을것이다. 그러면, 델파이 4 의세계의역사적인첫발을들여놓도록하자! 첫번째어플리케이션 델파이를일단시작하면기본적으로새로운프로젝트가하나시작되며, 비어있는폼이나타난다. 아마도오브젝트인스펙터에는현재가리킬수있는컴포넌트가 Form1 뿐일것이므로 Form1 의프로퍼티값들을표시하고있을것이다. 오브젝트인스펙터의사용법을익히기위해먼저폼의캡션을바꾸어보자. 오브젝트인스펙터의 Caption 프로퍼티를 Form1 에서 Hello 로한번바꾸어보자. 이간단한동작만으로폼의타이틀바의이름이바뀌는것을관찰할수있을것이다. 이제 Run 명령을선택하거나화살표모양의스피트버튼을클릭하면이어플리케이션이다음과같이실행되는것을관찰할수있을것이다.
이제델파이환경에서실행된어플리케이션을종료하고다시폼디자이너로돌아오자. 많은작업을하지는않았지만, 시스템메뉴와기본적으로제공되는전체화면표시버튼과최소화표시버튼, 닫기버튼을가지는완전한어플리케이션을방금하나만든것이다. 이폼을마우스를이용해크기를조절할수도있고, 전체화면으로보거나최소화할수도있다. 어플리케이션의저장과파일의종류 이제이렇게만든어플리케이션소스를저장해보자. File 메뉴에서 Save All 을선택하면, 델파이는폼과관련된소스코드와프로젝트파일에이름을붙여저장하게된다. 먼저파스칼소스코드인.pas 파일의이름을물어오는데, 여기에는 U1_Exam1.pas 라고명명하고적당한디렉토리에저장한다. 마찬가지로프로젝트파일인.dpr 파일은 Exam1.dpr 로명명한다. 참고 : 이책에서소스코드의이름을명명할때에는 Exam 이라는문자열에다가그장에서제작하는예제가몇번째것인지에따라일련번호를붙여서사용한다. 이번장과같은경우 3 장의첫번째예제이므로 Exam1.dpr 이되며, 각유닛파일에는접두어로유닛의개수에따라 U1, U2 등의문자열을사용한다. 각장의예제는다른디렉토리에저장된다. 프로젝트파일에붙인이름은실행시에디폴트로어플리케이션의제목으로사용되어윈도우의작업표시줄에나타나게된다. 그러므로, 만약프로젝트의이름이메인폼의제목과같으면이이름은작업표시줄의이름과도일치하게된다. 그러면, 델파이에서사용하는파일의종류와이들이어떤파일들인지에대해서알아보도록하자. 델파이프로젝트는폼, 유닛, 옵션설정과리소스에대한파일들로구성된다. 이런모든정보가각각다른파일로저장되며, 델파이에서어플리케이션을제작할때에생성된다. 다음표는델파이 4 에서사용되는파일들의종류와이들의역할에대해서나열한것이다. 파일의종류 프로젝트그룹파일 (.bpg) 설명 델파이 4 에서새롭게추가된프로젝트그룹에대한파일로, 여러프로 젝트를관리할수있는프로젝트그룹의내용을담고있는파일이다. 프로젝트파일 (.dpr) 폼, 유닛등에대한정보를저장하는데사용되는파일이다. 유닛파일 (.pas) 코드를저장하는데사용되는파일로, 폼과연관되기도하며어떤것들 은함수와프로시저만을저장하기도한다. 폼에대한정보를저장하기위해생성되는이진파일이다. 각폼파 폼파일 (.dfm) 일은유닛파일과연관되어있다. mine.dfm 이라는폼파일을가진다. 예를들어, mine.pas 유닛파일은
프로젝트옵션파일 (.dfo) 프로젝트의옵션설정이이파일에저장된다. 패키지정보파일 (.dfr) 델파이를패키지와함께사용하는이진파일이다. 프로젝트에서사용하는각종리소스를저장하는파일이다. 이파일은 리소스파일 (.res) 개발자가생성하거나변경하는것이아니고델파이가계속적으로고치 거나다시생성한다. 프로젝트, 폼, 유닛파일들에대한백업파일이다. 여러번고친경우 백업파일 (.~dp, ~df, ~pa) 에는확장자의앞글자 2 자뒤에고칠때마다하나씩증가하는정수로 명명된다. 예를들어유닛파일의경우.pa1,.pa2,.pa3 등이다. 실행파일 (.exe) 어플리케이션의실행파일로, 단독실행이가능하다. 유닛객체파일 (.dcu) 유닛파일의컴파일된형태로, 최종실행파일에링크된다. 타입라이브러리 (.tlb) 액티브 X/COM 에서사용되는타입라이브러리파일 델파이프로젝트 일반적으로프로젝트란어플리케이션에있는모든객체를포함하는최상위컨테이너를말한다. 즉, 어플리케이션을생성하는각각의파일들을서로연결한다. 하나의프로젝트는모든객체의저장소 (repository) 와같은역할을하게된다. 델파이의프로젝트역시하나의어플리케이션을구성하는모든파일들의목록을가지고있다. 그런데, 다른개발툴과는달리그자체의기능을가지는프로그램소스코드를포함하는데, 이를볼수도있고필요에따라서수정해서쓸수도있다. 그렇지만, 프로젝트파일의코드는대부분델파이가알아서코딩을해주기때문에건드릴필요가거의없다. 프로젝트파일의이해 별로건드릴필요가없는파일이더라도, 어떻게프로젝트를이루는코드가되어있는지는알아야할것이다. 그렇다면, 프로젝트파일의소스코드를이해해보도록하자. 프로젝트파일의소스코드를보기위해서는 Project View Source 명령을선택하면된다. Exam1.dpr 프로젝트의소스코드는다음과같다. program Exam1; uses Forms, U1_Exam1 in 'U1_Exam1.pas' {Form1}; {$R *.RES}
begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. - program 키워드 컴파일러에게이파일은실행파일이된다는것을알려준다. DLL 이거나유닛일경우에 는 library 나 unit 키워드를사용하게된다. - Uses 구문 Uses 구문은델파이가실행파일을만들때링크할오브젝트파스칼유닛들을나열할 때사용한다. - $R 지시자 $R 컴파일러지시자는컴파일러에게지정된윈도우리소스를사용하라고알려주는역할을한다. $R 뒤에나오는별표 (asterisk * ) 는리소스파일이프로젝트와같은이름을사용한다는것을나타낸다. 프로젝트를빌드하면델파이는프로젝트자체와각폼에대한리소스파일을생성하게된다. - Application.CreateForm Application.CreateForm 구문은프로젝트의폼을메모리로읽어들인다. 일반적으로프로젝트의모든폼은여기에나열된다. Option Project 메뉴를이용해폼을자동으로생성할것인지여부를지정해줄수있는데, 각각의폼은각폼의인스턴스변수 ( 예를들어 Form1) 에저장되며이들은각폼유닛의 interface 섹션에정의되어있다. Application.CreateForm 구문은지정된폼을메모리로읽어들이고, 인스턴스변수에그폼에대한포인터를저장한다. 프로젝트파일에서의 Application.CreateForm 구문의순서는실제로폼이생성되는순서이며, 첫번째로생성되는폼이메인폼이된다. 이순서를바꾸려면 Project Option 메뉴의 Application 탭을이용하면된다. - Application.Run 이구문에의해애플리케이션이동작하게된다. 유닛파일의이해
델파이의각폼은그에해당한유닛파일을하나씩가지고있다. 여기에는폼의모양을나타내는클래스정의가포함된다. 새로운컴포넌트를폼에추가할때마다델파이의폼디자이너는이를반영하기위해폼의클래스선언부분을변경한다. 또한, 이벤트핸들러를추가할때마다여기에해당되는코드가유닛파일에저장된다. 유닛파일은기본적으로 interface, implementation, initialization, finalization 섹션으로구분된다. 현재의폼에대한유닛파일인 U1_Exam1.pas 파일의소스코드는다음과같다. unit U1_Exam1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(tform) btnok: TButton; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} end. - interface 섹션 여기에는유닛의헤더정보가기록된다. 즉, 각종함수, 프로시져의선언부와유닛의
외부에서접근할수있는변수, 상수, 타입의정의가위치하게된다. 과거에 C 를써본경험이있는사람이라면이부분의 C 의헤더파일과비슷한역할을한다고생각하면된다. C 와는달리이섹션을분리된소스코드파일로저장하지않지만, 다른모듈들이이를참조할수있다. 컴파일된유닛은인터페이스정보를헤더부분에저장하기때문에다른모듈이 Uses 구문을이용해서유닛을참조하면델파이는소스코드를직접찾는것이아니라, 컴파일된유닛 (dcu 파일 ) 의헤더의정보를사용한다. 그렇기때문에델파이의유닛을컴파일된 dcu 파일 ( 오브젝트코드 ) 로배포할수있는것이다. - implementation 섹션 implementation 섹션은유닛의실제프로그래밍코드가담겨있는부분이다. 여기에적힌코드는 interface 섹션에서나열된부분만외부에서볼수있게되며, 보통은 interface 섹션에서나열한부분을구현하는코드가존재한다. 참고 : 폼인스턴스변수 (form instance variable) 각유닛의 interface 섹션에보면폼인스턴스변수를선언한부분이있다. var Form1: TForm1; 즉, TForm1 이라는타입 (type) 의 Form1 이라는변수를선언하는구문인데, 이때 TForm1 은 TForm 클래스를상속받아서델파이폼디자이너에의해생성된새로운클래스이다. 이렇게선언된폼인스턴스변수는프로젝트파일의 Application.CreateForm 이호출될때초기화되며, 유닛의 interface 섹션에선언되어있으므로다른모듈에서 Uses 구문을사용해서이를사용하여폼에접근할수있게된다. - initialization, finalization 섹션앞의소스에는존재하지않지만, 필요할때선언해서사용하면된다. 유닛이처음로드될때실행해야하는코드가있으면, 이를 initialization 섹션에위치시키면된다. 또한, 어플리케이션이메모리에서해제될때마지막으로실행해야하는코드가있으면, 이는 finalization 섹션에위치시키면된다. 보통유닛에서사용한리소스등을해제하는코드등을여기에사용한다. 델파이폼파일의이해 델파이의폼디자이너에서작업한내용들은폼파일에저장된다. 그러므로, 폼디자이너에 서비주얼한환경으로폼을다룰수도있지만, 텍스트파일을직접변경하는것도가능하다
( 마치 HTML 문서를만들때, 텍스트에디터를쓸수도있고프론트페이지같은비주얼 툴을사용할수도있는것처럼 ). 컴포넌트의사용 폼이델파이신전을이루는기둥이라고하면, 컴포넌트는기둥을이루는벽돌이라고할수있다. 이러한컴포넌트들은오브젝트파스칼소스코드로만들어져있다. 그러면벽돌을이용해서집을지어보도록하자. 폼에컴포넌트를추가하는방법은컴포넌트팔레트에서컴포넌트를클릭하고, 마우스커서를폼으로이동시킨후, 왼쪽버튼을눌러서컴포넌트의좌상부꼭지점을지정하고계속버튼을누른채로컴포넌트의우하부꼭지점까지드래그하면컴포넌트의크기가알맞게정해진다. 또는, 그냥컴포넌트를선택하고폼의적당한위치에클릭하면디폴트크기의컴포넌트가생성되며, 컴포넌트팔레트에서컴포넌트를더블클릭하면폼의한가운데에컴포넌트가생성된다. Standard 페이지에서버튼컴포넌트하나를선택해서폼에올려놓도록하자. 프로퍼티편집하기 앞에서폼의캡션을변경한것과마찬가지로, 다른컴포넌트들도오브젝트인스펙터를이용해서프로퍼티를편집할수있다. 버튼의캡션을바꾸기위해서는먼저마우스로버튼객체를선택하고오브젝트인스펙터의 Caption 프로퍼티를변경하면된다. 참고로, 컴포넌트의캡션프로퍼티는보통컴포넌트의 Name 프로퍼티에우선적으로영향을받는다. 물론이름과캡션의문자열은달라도되지만, Name 프로퍼티를변경하면 Caption 이처음에자동으로설정된다. 보통컴포넌트의이름을붙일때에는일반적으로따르는관습이있는데, 많은경우에영어자음으로된소문자 2~3 자를붙이는이름규칙이가장많이쓰인다. 예를들어버튼의경우 btn 이라는문자열을접두어로사용하는경우가많다. 참고 : Name 과 Caption 프로퍼티는처음으로델파이를접하는사람들이혼돈스러워하는것중에하나이
다. 분명히말해서 Name 프로퍼티는어디까지나내부에서사용되는것으로컴포넌트를나타내는변 수의이름이라고생각하면된다. 그러므로, Name 프로퍼티는기본적으로파스칼의변수의이름규칙 을따라야한다. 이에비해 Caption 프로퍼티는바깥에보이는부분으로내부적인컴포넌트의이름 과는전혀상관이없다. 어쨌든 Button1 의 Name 프로퍼티를 btnok 로설정하고 Caption 은 OK 라고정하자. 이런형식으로모든델파이컴포넌트의속성을정할수있게된다. 이벤트핸들러의작성 폼이나컴포넌트에서마우스버튼을누르면, 윈도우는어플리케이션에메시지를보내서그이벤트를알려준다. 델파이에서의이벤트는크게 2 가지의미로생각할수있다. 하나는각컴포넌트별로윈도우의메시지를포장한것이다. 즉, 이벤트의발생이라는측면에서접근하면어디까지나윈도우메시지와동일하다는것이다. 예를들어, 마우스키를누르면해당윈도우에는 WM_MOUSEDOWN 이라는메시지가전송되고, 델파이의컴포넌트는이를 OnMouseDown 이라는이벤트로발생시킨다는것이다. 이보다조금언어적인측면에서접근하면델파이의이벤트는개발자가작성한함수나프로시저의주소를윈도우메시지가발생했을때연결해주는함수포인터이다. 즉, 오브젝트인스펙터에서객체의 published 프로퍼티로선언된프로시저형데이터로눈으로볼때에는오브젝트인스펙터의이벤트탭에서나열된메소드를선택하여이벤트와메소드를단순히연결하는것으로생각할수있지만, 내부적으로는호환가능한프로시저형의메소드포인터를이벤트탭에서열거하면, 이를선택하는것으로함수포인터와같은역할을하는것이다. 다소설명이어려웠을지도모르지만, C 를공부했던독자라면조금은쉽게이해했을것으로믿는다. 그리고, 잘이해가되지않더라도델파이로여러프로그램을만들다보면이해가될날이올것이다. 어쨌든이번장의목적은가장단순한형태의어플리케이션을한번제작해보는것이므로, 실전에들어가보도록하자. 먼저폼에올려놓은버튼을선택하고, 오브젝트인스펙터의이벤트 (Event) 탭을선택한다. 버튼을클릭할때의이벤트핸들러를작성하려면 OnClick 이벤트오른쪽옆의하얀부분을더블클릭하거나, 여기에새로운메소드의이름을입력하고 Enter 를치면이벤트핸들러를입력할수있는화면이다음과같이생성된다. procedure TForm1.btnOKClick(Sender: TObject); begin end;
이제이벤트핸들러의코드를 begin~end; 사이에집어넣으면된다. 오브젝트파스칼에대한문법을모르더라도걱정하지말고, Hello 라는메시지를출력하기위해다음과같이코드를입력하도록하자. procedure TForm1.btnOKClick(Sender: TObject); begin ShowMessage('Hello!'); end; ShowMessage 는메시지박스를보여주는것으로, 파라미터로넘어간문자열을단순히보여주는역할을하는것이다. 그러면, 화살표스피드버튼을누르거나 Run 메뉴를선택하여어플리케이션을컴파일하고실행해보자. 버튼을누르면다음과같은화면이나타날것이다. 어플리케이션을실행하면, 델파이내부에서는폼을구성하는파스칼소스코드를컴파일하 고, 프로젝트파일을컴파일한후해당되는라이브러리와링크할실행파일을만들게된다. 그리고나서, 디버그모드에서실행파일을실행하는것이다. 정리 델파이를이용해서프로그래밍을하는방법을대단히간단히알아보았다. 물론우리가이번장에서제작한프로그램은그렇게큰의미가있는것이아니다. 하지만, 이프로그램이실제로어떻게구성되고기본적인작동방법은어떻게하는것인지를익히는데에는충분했을것이다.
이책의목표가초급자에게델파이에대해서아주자세하게가르치려는것이아니기때문에, 아마도다소내용이상세하지못하다고불평할지도모르겠다. 하지만, 이런상세한내용들은차차프로그래밍을해가면서, 그리고도움말을찾아가면서익히면되는것이므로많은연습을통해배우도록하자. 다음장에서는오브젝트파스칼의가장핵심적이고기초적인문법에대해서알아보도록한다.