C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[789] SpeedButton을 이용한 나 만의 버턴을 만들자.
김태선 [cppbuilder] 8099 읽음    2008-07-30 15:19
자기만이 버턴을 만들고 싶을 때, 당연히 버턴 컴포넌트를 새로 만들어야죠.
뭐 별거 아닌거 일수도 있지만, 사실 제대로 된 버턴을 만들려면 상당한 노력이 들어갑니다.

그런데 이미 있는 VCL에서 제공되는 버턴에서 기능을 살짝 바꾸어 사용하는 방법도 있습니다.
이 방법은 그렇게 많이 쓰이지 않는데, 컴포넌트를 새로 들여서 해결할 수 없는 특이한 경우나
새로 버턴을 설치하는게 귀찮은 경우 등 특별한 경우 가장 버턴을 간단히 만드는 방법입니다.
그것도 새로 컴포넌트를 만들 필요도 없이 스피드 버턴을 이용하는 방법입니다.

빌더6에 폼에 스피드 버턴 하나 올려 놓고 아래 코드를 추가합니다.(기존에 없는 부분만)

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include 

	// 이건 내부 변수를 참조해가며 직접 Paint 할때.
	// private 영역에 있어 엑세스가 안되므로 이렇게 같은 변수 모양을 만들어 제어함.
	struct TFVar
	{
		int FGroupIndex;
		void *FGlyph;
		bool FDown;
		bool FDragging;
		bool FAllowAllUp;
		TButtonLayout FLayout;
		int FSpacing;
		bool FTransparent;
		int FMargin;
		bool FFlat;
		bool FMouseInControl;
	};
	

//---------------------------------------------------------------------------
// 간단히 해결하는 색깔 버턴.

class TSpeedButton : public Buttons::TSpeedButton
{
public:
	__fastcall virtual TSpeedButton(TComponent* Owner) : Buttons::TSpeedButton(Owner)
	{
	}
	void __fastcall Paint()
	{
		TRect r = ClientRect;
		int	  v;
		int   edge;

		if (FState == bsDown)
		{
			Canvas->Brush->Color = clLime;
			v = 2;
			edge = EDGE_SUNKEN;
		}
		else
		{
			Canvas->Brush->Color = clYellow;
			v = 0;
			edge = EDGE_RAISED;
		}
		Canvas->Rectangle(r);
		DrawEdge(Canvas->Handle, &r, edge , BF_RECT );
		Canvas->TextOutA(r.Width() / 2 - Canvas->TextWidth(Caption) / 2 + v,
			r.Height() / 2 - Canvas->TextHeight(Caption) / 2 + v, Caption);
	}
};
#define TSpeedButton		::TSpeedButton
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
	TSpeedButton *SpeedButton1;
private:	// User declarations
public:		// User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


보시면 아시겠지만 스피드버턴에서 Paint() 메소드만 오버라이더해서 새로 버턴 모양을 그려주면 그만입니다.
원래는 좀 더 근사하게 만들려고 했으나, 지금 당장 쓸것도 아니고 예제 정도면 충분하다 싶어 그냥 간단히만
만들었습니다.
그냥 버턴이 눌려졌을 때와 아닐때만을 구분하기 때문에 기존의 스피드 버턴과 조금 동작이 틀립니다.
그기에 예제에서는 glypy 도 적용하지 않았습니다.

원래의 스피드 버턴 모습을 그리려면  Paint() 메소드 내에서
Buttons::TSpeedButton::Paint();
호출해 주면 되고, 여기에 추가적으로 작업을 해주는 방법도 쓸수 있습니다.

또 원래의 스피드 버턴과 구분하기 위해 Tag등에 구분 값을 넣어줘 구분 값이 있는 경우만
위와 같은 모양의 버턴이 동작하게 할 수도 있으며, 이 경우 원래의 스피드 버턴은 전혀 영향을 주지 않으면서
마치 새로운 버턴을 만든 것 처럼 동작하게 됩니다.

원래의 스피드버턴 Paint() 메소드 소스를 보면 아시겠지만,
적당한 모양을 그려주려면 조금 노력이 필요합니다. 그기에 스피드 버턴을 제대로 그리려면 클래스 내부의
private 영역 변수를 참조해야 하는데, 상속 받은 클래스는 private 영역 참조가 되지 않습니다.
C++이나 델파이 모두 해당되는 사항이죠. 그러고 보면 새로 그리기 위해 또 여러가지 클래스를 정의하고
변수를 사용하는 코드를 만든다는 것은, 스피드버턴의 Paint() 메소드가
필요치 않은 코드 덩어리인 오버헤드를 많이 남긴다는 사실을 알수 있습니다.
스피드버턴 코드를 보니 왜 그리 private 코드가 많은지.... 영역자 문제를 다시 한번 생각하게 하는군요.
저는 대체로 public 성향이라서.(아, 귀쟈니즘의 발로인가 -_-;)

위 코드는 전혀 새로운 버턴 콤포넌트를 만들지 않고, 따로 긴 코드를 쓰지 않고도 멋진 버턴을
간편하게 만들 수 있는 방법을 제시하고 있습니다.
저런 식으로 컴포넌트를 만들어 사용해도 되고, 디자인 타임의 편의를 위한 저런식의
동명의 클래스 명을 쓰지 않고 TColorButton 등으로 새로 지어서 동적 생성을 하는 방법을 쓰는 것도 좋을 것입니다.

그럼.
김태선 [jsdkts]   2008-08-02 22:08 X
레이블도 아래처럼 아주 간단히 모양을 바꿀 수 있습니다.
//---------------------------------------------------------------------------
class TLabel : public Stdctrls::TLabel
{
    typedef Stdctrls::TLabel    inherited;
public:
    __fastcall TLabel(TComponent *Owner) : Stdctrls::TLabel(Owner)
    {
    }
    void virtual __fastcall Paint()
    {
        TRect r = ClientRect;
        //Font->Style = TFontStyles() << fsBold;
        inherited::Paint();
        DrawEdge(Canvas->Handle, &r, EDGE_SUNKEN, BF_RECT );
    }
};
#define TLabel        ::TLabel
//---------------------------------------------------------------------------

+ -

관련 글 리스트
789 SpeedButton을 이용한 나 만의 버턴을 만들자. 김태선 8099 2008/07/30
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.