대부분의 컴포넌트는 마우스가 해당 컴포넌트 위에 올라 왔을때와
해당 컴포넌트를 벗어났을 때를 감지하지 못하죠.
TLabel 컴포넌트 경우는 OnMouseEnter 와 OnMouseLeave 이벤트가 있어서
마우스가 라벨위에 올라 왔을때를 감지할 수 있어, 마우스 커서가 라벨위에
있을때만 라벨 캡션에 밑줄을 넣어 표시하는 등의 효과를 낼 수 있습니다.
하지만 다른 대부분의 컴포넌트에는 이 이벤트가 없습니다.
그런데 실무에서는 마우스가 컨트롤 위에 올라올때와 컨트롤을 벗어날 때를 처리하는
OnMouseEnter 와 OnMouseLeave 이벤트가 필요할 때가 있습니다.
그래서 이를 어떻게 만드는가 하는 방법을 소개합니다.
이런 기능이 필요하다고 써드파티(3th party) 컴포넌트를 찾아 헤매는 것도 시간 낭비에
실행화일 크기 낭비가 될 수도 있습니다.
C++빌더로 컴포넌트 만들어 보신 분들이야 이런거 쯤이야 눈감고도 만들겠지만,
델파이에 비해 상대적으로 컴포넌트 제작이나 컴포넌트의 기능을 추가하는 등의
소스가 부족한 빌더에서는 어떻게 처리하는지 잘 모르시는 분을 위해 간단히 소개합니다.
뭘로 할까 하다가 TImage가 효과를 위해 기능이 필요할 것 같아서 여기에 넣어 보겠습니다.
물론 방법은 동일하므로 TImage 뿐만 아니라 대부분 다 적용할 수 있습니다.
TImageOver 컴포넌트인데 이 컴포넌트를 이용해 마우스가 위에 가면 그림이 변하게 하면
아주 예쁜 화면을 꾸미는데 도움이 되겠죠.
그럼 소스 보시죠.
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "TImageOver.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// 마우스 오버를 감지를 하는 이미지 컴포넌트
// 마우스가 그림위에 올라올때와 떠날때를 감지해서 이벤트를 발생시킨다.
// 이벤트는 Deactivate 된 폼일 경우도 발생한다.
class TImageOver : public TImage
{
private:
TNotifyEvent FOnMouseEnter;
TNotifyEvent FOnMouseLeave;
public:
__fastcall TImageOver(TComponent *Owner) : TImage(Owner)
{
FOnMouseEnter = NULL;
FOnMouseLeave = NULL;
}
virtual __fastcall ~TImageOver() { }
virtual void __fastcall Dispatch(void *Message);
__published:
__property TNotifyEvent OnMouseEnter = { read = FOnMouseEnter, write = FOnMouseEnter };
__property TNotifyEvent OnMouseLeave = { read = FOnMouseLeave, write = FOnMouseLeave };
};
void __fastcall TImageOver::Dispatch(void *Message)
{
TMessage *msg = (PMessage)Message;
switch (msg->Msg)
{
case CM_MOUSEENTER :
TImage::Dispatch(Message);
if (!Enabled)
return;
if (FOnMouseEnter)
FOnMouseEnter(this);
return;
case CM_MOUSELEAVE :
TImage::Dispatch(Message);
if (!Enabled)
return;
if (FOnMouseLeave)
FOnMouseLeave(this);
return;
}
TImage::Dispatch(Message);
}
// 컴포넌트 클래스 끝.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// 테스트
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TImageOver *img = new TImageOver(this); // 코딩으로 생성.
img->Parent = this;
img->Left = 100;
img->Top = 100;
img->AutoSize = true;
img->OnMouseEnter = ImageEnter;
img->OnMouseLeave = ImageLeave;
img->Picture->LoadFromFile("3m.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ImageEnter(TObject *Sender)
{
Caption = "Enter"; // 들어왔구나.
}
void __fastcall TForm1::ImageLeave(TObject *Sender)
{
Caption = "Leave"; // 나갔구나.
}
//---------------------------------------------------------------------------
// 다음은 헤더파일입니다.
//---------------------------------------------------------------------------
#ifndef TImageOverH
#define TImageOverH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall ImageEnter(TObject *Sender);
void __fastcall ImageLeave(TObject *Sender);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
소스는 너무 간결하고 쉽죠..
예... 이와 같이 아무나 쉽게 만들 수 있습니다.
그리고 컴포넌트로 등록해서 사용해도 됩니다.
그러면 위에 코딩으로 생성하는 OnCrate 이벤트 쪽 코드는 한줄도 안들어 가도 되겠죠.
저는 그냥 코딩으로 처리하는 것을 즐기는 편이라 ... ~..~;
원리는 ... 소스 보시면 금방 이해 될거 같은 느낌이 들어 생략하겠습니다.
그럼..