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
[990] 컴포넌트 교체식으로 구현하는 탐색기로부터의 Drag&Drop 처리
김태선 [cppbuilder] 8146 읽음    2010-07-09 14:16
탐색기로부터 드래그&드롭을 받는 방법은 이미 여러차례 소개가 되어 있어
구현하기 조금도 어렵지 않습니다. 하지만, 폼위의 특정한 컨트롤로 드래그 받을 때의 처리 방법 중
컴포넌트를 직접 수정하는 방법은 소개되지 않은 것 같아 올려 둡니다.

사실은 코드를 복사 신공으로 넣으려는데, 제 소스를 찾는 것보다 여기에 올려두는게
찾기가 더 편리한 관계로... ㅡ..ㅡ;;


일반적으로 탐색기로부터 폼으로 드래그를 받는 방법은
class TForm...
{
	BEGIN_MESSAGE_MAP
		MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles)	// 드롭 메시지 받아 들이기.
	END_MESSAGE_MAP(inherited)

	// 드래그&드롭 메시지 핸들러
	//
	void __fastcall WMDropFiles(TWMDropFiles &msg)
	{
		int  nFileCount = DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0);
		for(int c = 0; c < nFileCount; c++)
		{
			char filename[MAX_PATH];
			int  nLength = DragQueryFile((HDROP)msg.Drop, c, filename, MAX_PATH);
			if (nLength)
				AddFile(filename);
		}
		DragFinish((HDROP)msg.Drop);
	}
};

대략 이런 식으로 하고,
FormCreate 핸들러에서
{
    DragAcceptFiles(Handle, true);
}
이렇게 해주면 폼으로 받는 것은 쉽게 됩니다.

그러면 폼 위의 특정한 컨트롤만 드래그를 받고 싶을때는 어떻게 할까요?
이때는 WM_DROPFILES 메시지를 받아서 처리해야 하므로 서브클래싱을 하면 되죠.
하지만 컴포넌트를 직접 수정하면 더 코드가 쉽고 깔끔해집니다.

가령 파일리스트를 나타내는 특정 TListView로 드래그를 받고 싶다면

//---------------------------------------------------------------------------
void    AddFile(String filename);  // 파일명이 통보될 때 처리할 전역 메소드.
//---------------------------------------------------------------------------
// TListView 에만 드래그&드롭을 받는 방법
class TListView : public Comctrls::TListView
{
	typedef Comctrls::TListView		inherited;
public:
	BEGIN_MESSAGE_MAP
		MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles)	// 드롭 메시지 받아 들이기.
	END_MESSAGE_MAP(inherited)

	// 드래그&드롭 메시지 핸들러
	//
	void __fastcall WMDropFiles(TWMDropFiles &msg)
	{
		int  nFileCount = DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0);
		for(int c = 0; c < nFileCount; c++)
		{
			char filename[MAX_PATH];
			int  nLength = DragQueryFile((HDROP)msg.Drop, c, filename, MAX_PATH);

			// Do something..
			if (nLength)
				AddFile(filename);
		}
		DragFinish((HDROP)msg.Drop);
	}
	// 드래그 받을 WinControl을 지정하는 부분. FormCreate 핸들러에서 호출하는게 좋음.
	//
	void	InitDragAccept()
	{
		DragAcceptFiles(Handle, true);
	}
};
#define TListView		::TListView
//---------------------------------------------------------------------------

이런식으로 코딩해주고

폼 선언 클래스 바로 위에
이 코드를 넣어주면 됩니다.

가령

class TForm1 : public TForm
{
...
}

이 클래스 선언 위에 바로 넣으면 된다는 것이죠.

그리고 폼 위의 TListView 중에 드래그 받을 ListView에 대해서만
FormCreate 핸들러에서
{
    ListView1->InitDragAccept();
}

이렇게만 호출해주면 됩니다.

위의 예에서는 파일명이 통보될때 처리할 AddFile(String filename);
함수만 구현해주면 끝입니다.
복수개를 드롭 할때는 차례대로 파일명이 담긴채 AddFile 메소드를 계속 호출해주는데
순서는 OS 맘대이고, 폴더인 경우는 폴더명으로 오기 때문에
폴더인지는 DirectoryExists(filename); 함수를 호출해서 검사해 주면 됩니다.


그럼.

+ -

관련 글 리스트
990 컴포넌트 교체식으로 구현하는 탐색기로부터의 Drag&Drop 처리 김태선 8146 2010/07/09
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.