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
[1173] 투영 레이어 컴포넌트:패널 밑 컨트롤을 투영시켜 그대로 보여 줍니다.
김태선 [cppbuilder] 7477 읽음    2016-05-04 21:25
폼 위에 사용자 입력을 받기 위한 TEdit와 TLabel TShape 등 화면을 꾸미기 위한 컴포넌트 등 여러 컴포넌트가 있습니다.



그냥 입력 받고 하면 되겠죠.
그런데 요즘 터치 스크린을 많이 쓰는 추세니
마우스 안쓰고 화면 터치로 입력 받고 싶다고 옆에서 요구 합니다.
그러면 컨트롤도 키워야 하고 화면상 입력이 가능하게 화면 키보드도 넣어야 합니다.
그런데 표시할 컨트롤 숫자가 위 그림처럼 몇개 안되면 문제가 없는데
만드는 프로그램에는 너무 많아 컨트롤 자체를 키우는 일은 어려운 상황입니다. 미적으로도 꽝이고요.


그러면 각 파트별로 화면을 터치하면 그 부분만 별도 폼으로 다시 좀 크게 표시하고 입력을 화면상에서
할수 있도록 해달라고 합니다.
이걸 하려면 각 컨트롤에 Click 이벤트 등을 모두 설정해야 하는 매우 번거로운 작업을 해야 합니다.
컨트롤이 몇개 안되면 간단히 해결되겠지만, 수백개 수준이면 매우 귀잖은 일이 됩니다.

그래서 프로그래머는 또 궁리를 합니다.
각 파트별로 이미 만들어진 화면 위에 투명한 컨트롤을 올려 놓고
Click 이벤트를 설정해서 클릭 되면 다른 큰 폼을 그 위에 표시하고 화면 키보드로 입력을 받으면 되겠구나 하고
짱구를 굴립니다.
아, 그런데 이걸 해주는 간단한 컴포넌트를 찾기 어렵네요.
그래서 TPanel 컴포넌트를 조금 수정해서 만들었습니다.
아래에 Panel이 가장 상위에 올려져 있는데도 아래에 컨트롤이 다 보이지요.



이 투영화 기법으로, 원래 만들었던 화면을 그대로 손상없이 유지하면서
특정 파트 부분을 클릭하면 이 패널 컴포넌트의 클릭 이벤트가 감지해서
더 큰 화면을 보여준다든지 하는 일을 할수 있습니다.

아래에 소스가 있는데,
그냥 패널을 위에 올려두고  Tag값이 100000 이상인 경우만 투영 레이어로 동작하게 했습니다.
위 그림에서 컨트롤이나 레이블이나 TShape이나 뭘 클릭해도
TPanel 컴포넌트가 그 위에서 이벤트를 먼저 받아 버립니다. 그러니 각 개별 컨트롤로는 전달될수 없는 거지요.
원래 TPanel을 위에 올리면 아래 컨트롤이 다 가려져 버리는 것이지만,
아래 컨트롤의 모양과 변화는 모두 드러나게 하면서 사실상 그 위에 TPanel이 올려져 있는  것입니다.


이 투영화 기법은 이미 알려진 것인데,
당장 프로그램에 적용할만한 컴포넌트를 발견하지 못한 관계로,
TPanel에 적용해서 만들어 올립니다.

컴포넌트 교체식으로 헤더파일에 간단히 코딩 했습니다.


처음에는 TShape을 최상위에 올리고 브러시 특성을  bsClear를 주면 되겠구나 했는데,
TShape은 그게 안되더군요.
윈도 핸들이 있는 컴포넌트여야 하기 때문에  TPanel을 응용했습니다.



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

#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include "dxButtons.hpp"
#include "dxCore.hpp"
#include 
//---------------------------------------------------------------------------
// PanelLayer Component. Written by KTS.
//
// 패널을 패널 아래에 있는 컨트롤이 투영되어 보이게 처리한다.
// 즉 패널 아래 컨트롤이 보이도록 처리한다.
// 이로 인해 이 패널 밑에 있는 Edit Memo등에 커서가 깜빡거리는 것도 보인다.
// 하지만 그것을 윗 레이어에서 클릭하는 것을 가로 막고 있는 패널이다.

class TPanel : public Extctrls::TPanel
{
public:
	__fastcall TPanel(TComponent *Owner) : Extctrls::TPanel(Owner)
	{
	}
	// 여기서 이 패널 아래에 컨트롤이 보이도록 한다.
	void __fastcall CreateParams(TCreateParams& params)
	{
		inherited::CreateParams(params);
		if (Tag >= 100000)
		{
			params.ExStyle += WS_EX_TRANSPARENT;
			ControlStyle = ControlStyle >> csOpaque << csAcceptsControls;
		}
	}
	virtual void __fastcall Paint()
	{
		if (Tag < 100000)
			inherited::Paint(); // 원래 메소드를 호출하면 아래 컨트롤을 다 덮어 버리면서 페인팅한다.
	}
};
#define TPanel         ::TPanel
//---------------------------------------------------------------------------
class TFormSKeyBoard : public TForm
{
__published:	// IDE-managed Components
	TdxButton *dxButton1;
	TdxButton *dxButton2;
	TdxButton *dxButton3;
	TdxButton *dxButton4;
	TdxButton *dxButton5;
	TdxButton *dxButton6;
	TdxButton *dxButton7;
	TdxButton *dxButton8;
	TdxButton *dxButton9;
	TdxButton *dxButton10;
	TdxButton *dxButton11;
	TdxButton *dxButton12;
	TMemo *Memo1;
	TEdit *Edit1;
	TPanel *Panel1;
	TLabel *Label1;
	TEdit *Edit2;
	TShape *Shape1;
	TLabel *Label2;
	void __fastcall FormCreate(TObject *Sender);
	void __fastcall Panel1Click(TObject *Sender);
private:	// User declarations
public:		// User declarations
	__fastcall TFormSKeyBoard(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormSKeyBoard *FormSKeyBoard;
//---------------------------------------------------------------------------
#endif

김태선 [cppbuilder]   2016-05-13 10:43 X
참고로,
JEDI의 JvPanel를 쓰면
훨씬 더 깔끔하게 투영이 잘 됩니다.

+ -

관련 글 리스트
1173 투영 레이어 컴포넌트:패널 밑 컨트롤을 투영시켜 그대로 보여 줍니다. 김태선 7477 2016/05/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.