본문 바로가기
Delphi Tip/컴포넌트

델파이 컴포넌트(Component) 7편

by MonoSoft 2023. 7. 24.
728x90
반응형

델파이 컴포넌트(Component) 7편

728x90

 

 

오브젝트 인스펙터(Object Inspector)

 

프로퍼티 탭을 보시면 어떤 녀석은 그냥 edit으로 되어 있구

어떤 녀석은 ComboBox로, 또 어떤녀석은 이름앞에 '+'가 붙어서

내용을 전개해서 볼수 있도록 되어 있음을 볼수 있을겁니다.

 

또, 특별한 경우 '...'버튼을 눌러서 대화상자를 호출해서

프로퍼티를 조작하는 경우도 있죠..

 

그밖에 프로퍼티에 대해서 자세히 알아보도록 합시다.

 

우선 Edit로 나타나는 경우에는 어떤값을 입력할수 있었나요?

 

Name, Caption, Hint등의 경우 문자를 입력할수 있게 됩니다.

Left, Right, Tag등의 경우 숫자만을 입력할수 있게 되죠..

 

거꾸로 생각하면 오브젝트 인스펙터에 Edit으로 나타나게 하려면

프로퍼티의 형은 string이나 integer등으로 되어야 한다는 말이 되겠죠?

 

property Left : integer; property Caption : string;

 

이 경우는 가장 단순한 경우에 속하므로 예제는 생략하겠습니다.

 

 

 

컴보박스로 보이는 프로퍼티 만들기

 

① Boolean형

 

폼에 관한 프로퍼티를 살펴보면 KeyPreview라는 녀석이 있지요?

이녀석을 클릭해보면 컴보박스로 되어서 True/False를 선택할수있다는 걸

발결할수 있죠

그렇다면 Boolean형으로 된 프로퍼티는

오스젝트 인스펙터상에 컴보박스로 나타난다는 것을 알수가 있네요

 

private

fCombo : boolean; ...

published

property Combo1 : boolean read fCombo write fCombo; ...

 

와 같이 되겠지요..

 

② 열거형

 

그럼 폼에 있는 프로퍼티중에 WindowState라는 녀석을 봅시다.

 

헬프를 보면 다음과 같이 되어 있지요..

 

type

  TWindowState = (wsNormal, wsMinimized, wsMaximized);

property

  WindowState: TWindowState;

 

TWindowState라는 type을 선언해 놓구

WindowState의 형을 이녀석으로 하였지요?

 

흐음.. 이것도 역시 간단하군요..

우리의 컴포에 넣어보자면..

 

type

TPCComm = ( pcHitel, pcNownuri, pcChollian, pcUnitel );

TMyButton = class(TButton)

private

fPCComm : TPCComm;

published

property PCComm : TPCComm read fPCComm write fPCComm;

end;

 

으로 하면 되겠네요..

 

 

③ TComponent형..

역시 폼을 보면 ActiveControl이라는 녀석이 있지요?

이녀석은 조금 희안한게 폼안에 있는 컨트롤들을 컴보박스에 보여주네요..

 

버튼을 하나 폼에 올려놓구 이녀석의 내용을 들춰보세요..

 

그런다음 다른 버튼을 추가한후에

다시한번 열어보면 방금 추가한 버튼이 콤보박스에 나타났나요?

 

만약 그렇지 않다면 여러분이 가지고 계신

델파이가 진짜 델파이인지를 확인해보셔야 될듯

그럼, ActiveControl에 방금 추가한 버튼을 연결해 보세요.

 

그런다음 폼에있는 버튼을 없애버리면..

 

ActiveControl에도 없어지는게 눈에 보일겁니다.

 

볼랜드에서 신경을 많이 쓴게 눈에 보이는 부분이죠..

 

그럼.. 이녀석을 우리가 이용해 봅시다.

방법이 약간 복잡하니 신경써서 따라오시길..

 

우선 지금까지와 같은 방법으로 해봅시다.

 

type

  TMyButton = class(TButton)

private

  fWinControl : TWinControl;

published

  property WinControl : TWinControl read fWinControl write fWinControl;

end;

 

자.. 위와 같이 첨가를 한다음 컴포넌트를 컴파일하고 우리의 버튼컴포를 봅시다.

 

프로퍼티중에 WinControl이라는 녀석이 생겼나요?

 

우리가 TWinControl형으로 했기때문에 이녀석에는

TWinControl에서 파생된 컴포들만 나타날 겁니다.

 

TImage나 TLabel등을 올려놓구 확인을 해보세요.

 

방금 추가한 TImage가 우리가 만든 WinControl프로퍼티에 나타나나요?

참고로 TWinControl은 핸들을 가지기 시작하는 컴포넌트이지요..

 

핸들이 있다는 의미를 아시지요?

 

비로서 윈도우 세계의 일원이 되었다는 것이지요..

여기까지 하고 마친다면 심각한 오류에 빠질수 있습니다.

 

우리의 WinControl에 Memo1을 연결했다면 폼위에서

Memo1을 지워버립시다.

그리고 WinControl을 확인해 보세요..

 

원하는 데로 지워졌나요? 제 경우 이런메시지가 떠있더군요..

(Access violation at address 0049F730 in module 'DELPHI32.EXE'. Read of address FFFFFFFF)

 

참 재수없는 메시지중의 하나지요..

왜 그럴까요? 크크.. 이유야 간단하겠지요?

 

우리의 WinControl에 Memo1을 지정해 주었다구 합시다.

 

실은 Memo1의 컴포넌트의 주소를 대입한 것이지요..

 

이때 델파이는 그 주소를 참고해서 Name을 얻어낸다음

우리에게 보여주는 것이겠지요?

 

그런데 Memo1이 할당되어 있던 영역이 날라가 버렸으니

Name를 참조할수가 없었던 것이겠지요

우리의 불쌍한 돌파이는 속상한 메시지를 출력할수 밖에 없었을테구요.

 

으.. 이를 어쩌면 좋을까요?

크크.. 방법이 없었다면 이 강좌를 쓰지도 못했겠지요?

 

델파이에서는 이런경우를 위해서 몇가지 함수를 준비해 두었습니다.

 

TComponent에 정의되어 있는 함수들입니다.

 

procedure FreeNotification(AComponent: TComponent);

procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;

 

의 두가지 함수이지요..

도데체 어디다 쓰는 함수냐구요? 크크..

 

나는 컴포넌트입니다.

내가 죽을 때가 되면 그동안 정들었던 친구들에게 소식을 알려서

나의 죽음을 슬퍼하도록 해야할것입니다.

 

더불어 나라는 존재가 세상에서 없어졌느니

내자리가 비었음을 나와 관계있는 이들에게 알려서 대처할수 있도록 하는 것이 도리겠지요.

 

그래서 다른이들(역시 컴포넌트..)에게 메시지를 보냅니다.

누구한테 보내야 할지는 걱정하지 않습니다.

 

그 동안 FreeNotification을 통해서 내가 죽을때 메시지를 남겨달라고

부탁한 동지들이 있으니깐요..

이해가 되시남유?

 

그럼.. 위에서 했던 작업을 약간 바꿔야 하겠지요?

 

type

  TMyButton = class(TButton)

private

  fWinControl : TWinControl;

  procedure SetWinControl(value : TWinControl);

  procedure Notification(AComponent: TComponent; Operation: TOperation); override;

published

  property WinControl : TWinControl read fWinControl write SetWinControl;

end;

 

SetWinControl에서 fWinControl에 값을 넣어주고

FreeNotification을 호출해서 니가 죽을때 내게 알려다오 하고

부탁을 해야 할겁니다.

 

그리고 Notification에서 누가 죽어서 메시지를 남겼는지를 확인합니다.

 

procedure TMyButton.SetWinControl(value : TWinControl);

begin

// fWinControl을 설정하구..

fWinControl := Value;

// 그 값이 nil이 아니라면

그녀석에게 FreeNotification을 해서

// 죽음을 알려달라구 부탁을 한다.

if Value <> nil then Value.FreeNotification(Self);

end;

 

procedure TMyButton.Notification(AComponent: TComponent; Operation: TOperation);

begin

// 다들 아실테구..

inherited Notification(AComponent, Operation);

// fWinControl가 죽음을 알려왔다면 fWinControl를 nil로..

if (Operation = opRemove) and

   (fWinControl <> nil) and

   (AComponent = fWinControl) then

  fWinControl := nil;

end;

 

이제.. 우리는 WinControl을 통해서 외부 컴포넌트를

어떻게 연결해서 쓸수 있는지를 배웠습니다.

 

우리의 버튼이 눌리면 WinControl로 연결된 녀석에

포커스를 주는둥의 일을 할수있겠지요?

 

728x90
반응형

댓글