일단 소스 보시고 ....
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "Calendar.hpp"
#include <ComCtrls.hpp>
#include <DockTabSet.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <Tabs.hpp>
//---------------------------------------------------------------------------
// TStaticText는 Handle이 있지만 Paint() 메소드가 없다.
// 하지만 핸들이 있으므로 직접 메시지를 받아서 화면을 다시 그리는 방법을 쓴다.
class TStaticText : public Stdctrls::TStaticText
{
typedef Stdctrls::TStaticText inherited;
public:
__fastcall TStaticText(TComponent *Owner) : Stdctrls::TStaticText(Owner)
{
}
void virtual __fastcall Paint()
{
// 이렇게하는 것은 소용없고 WndProc 메시지 핸들러에서 적당히 다시 그리는 방법을 써야 한다.
}
};
#define TStaticText ::TStaticText
//---------------------------------------------------------------------------
// TLabel 은 윈도우 핸들은 없어 직접 윈도우 메시지를 받을 수 없다.
// 화면을 다시 그리는 방법은 자신이 소속된 parent 컨트롤에서
// 화면을 다시 그려야 할 일이 있으면 WM_PAINT 메시지를 받아서
// 이 메시지가 오면 Paint() 메소드를 불러 화면을 다시 그리는 방법을 쓴다.
void display(TMessage& Message);
class TLabel : public Stdctrls::TLabel
{
typedef Stdctrls::TLabel inherited;
private:
THandle FHandle;
public:
__fastcall TLabel(TComponent *Owner) : Stdctrls::TLabel(Owner)
{
FHandle = 0;
HandleNeeded();
}
__fastcall virtual ~TLabel()
{
if (HandleAllocated())
DeallocateHWnd((void*)FHandle);
}
void virtual __fastcall Paint()
{
TRect r = ClientRect;
//Font->Style = TFontStyles() << fsBold;
inherited::Paint();
DrawEdge(Canvas->Handle, &r, EDGE_SUNKEN, BF_RECT );
}
//---------------------------------------------------------------------------
// 핸들을 생성하고 핸들 관련 처리를 위한 부분. 옛날 파워오브델파이 강좌 참조했음.
//---------------------------------------------------------------------------
// 핸들이 할당되어 있는가?
bool __fastcall HandleAllocated()
{
return FHandle != 0;
}
// 핸들이 필요하면 할당한다.
void __fastcall HandleNeeded()
{
if (!HandleAllocated())
FHandle = (THandle)AllocateHWnd(WndProc);
}
// 핸들얻기.
THandle __fastcall GetHandle()
{
HandleNeeded();
return FHandle;
}
// 윈도우 메시지 핸들러.
void virtual __fastcall WndProc(TMessage& Msg)
{
if (Msg.Msg == WM_MOUSEMOVE)
{
display(Msg); // check
}
Dispatch((void*)&Msg);
}
__published:
__property THandle Handle = { read=GetHandle };
};
#define TLabel ::TLabel
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published: // IDE-managed Components
TShape *Shape1;
TStaticText *StaticText1;
TLabel *Label1;
private: // User declarations
public: // User declarations
__fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
void display(TMessage& Message)
{
char buf[100];
wsprintf(buf, "Msg:%d %d %d", Message.Msg, Message.LParamLo, Message.LParamHi);
OutputDebugString(buf);
}
#endif
따로 설명을 안 달아도 웬만한 분은 다 알아 보시는 모양이군요.
주석에 설명 같은 것을 달아 놨으니 그 정도로 충분한가 봅니다.
컴포넌트나 클래스가 핸들을 갖으려는 이유는 윈도우 메시지를 받기 위함이죠.
VCL에서는 핸들을 갖는 방법을 위의 예제처럼 하고 있습니다.
위에 표시한대로 옛날 파워오프델파이라는 매우 얇은 정기 간행물을 구독한 적이 있는데
그기에 이미 나와 있는 방법이고 그 코드를 빌더로 옮겨 약간 수정한 것입니다.
신통하게도 매우 쉽게 윈도우 메시지를 받을 수 있을 뿐 아니라,
그 처리 또한 상당히 손쉽습니다.
위의 TLabel 예제의 Paint 에서 모클래스의 Paint()를 부르지 않는다면
Label이 아니라 어떤 것을 표현하는 다른 형태의 컴포넌트가 될 수 도 있습니다.
그러면서 TLabel이 가졌던 모든 핸들러와 프로퍼티는 유효하고, 없는 것은 새로 핸들을 얻는 윈도우 메시지 핸들러를 통해 만들 수 있습니다. 즉 아주 쉽게 컴포넌트를 만들 수 있는 것이죠.
새로 만든 TLabel은 기존 TLabel에 비해 4바이트가 늘었났습니다.
하지만, 필자의 PC 경우에는 sizeof로 찍어보면 8바이트가 증가된 것으로 나오는데, 이는 컴파일러가 기본 8바이트 메모리 경계 정렬을 해서입니다. #pragma pack(4)로 해서 검사해보면 4바이트가 증가한 것이 맞다는 것을 알수 있습니다.
위에서 보인 기존 컴포넌트를 새 컴포넌트로 대치하는 기술은 예전에 저의 팁을 찾아보시면 쉽게 이해 될 것입니다.
TLabel과 TStaticText의 차이점은 위에 주석에 써 놓은 대로입니다.
실제 적용에서는 둘 간에 차이는 그다지 있어 보이지 않습니다.
TStaticText는 표준적인 static text 윈도 클래스를 래핑하여 VCL화 한 것이고,
TLabel 은 VCL 특성에 맞게 새로 디자인 된 레이블입니다.
척 보면 아실만한 내용들이라 군더더기 설명은 마칩니다.
|
Non-Visual 컴포넌트같은경우에 SendMessage로 메세지를 받고 싶을때는
이걸 쓰면 좋지만..
기존에 TGraphicControl을 상속받은 Control에 굳이 Handle을 갖게 할필요가 있는것인지요?
잘 몰라서...