양병규님의 글인데 정확한 출처를 몰라서 출처없이 작성하였습니다.
어플에서 드래그해서 바탕화면이나 탐색기, 내컴퓨터등으로 드롭했을때 드롭이되는 경로는 알 수 없습니다.
정상적인 드래그&드롭에 대해서 간략하게 개념 설명을 하자면...
드래그&드롭은
IEnumFormatEtc, IDropTarget, IDropSource, IDataObject
이 네개의 인터페이스로 모두 구현됩니다.
IEnumFormatEtc은 드래그할 데이터의 포맷에 대한 정보를 주고 받는 인터페이스로써 드래그하는 쪽에서 구현합니다.
드래그를 시작하면 "내가 가지고 있는 데이터의 종류는 이런것들이 있다"라고 알려주는겁니다. 머... Text와 Rtf등 두가지를 처리할 수 있는 경우가 있을수 있겠지요....
IDropTarget은 드롭을 받는 쪽이 구현합니다. 드롭(혹은 Enter, Over)이 발생하면 상대가 가지고 있는 포맷이 뭐가 있는지 확인해서 그중에서 내가 원하는 것이 있으면 그 포맷으로 데이터를 달라고하면됩니다. 가량 Text와 Rtf중에서 Text만 처리할 수 있다면 Text를 달라고합니다. 상대가 구현해 놓은 IDataObject를 이용해서 데이터를 받아옵니다.
IDropSource는 드래그를 하는 쪽에서 구현합니다. IEnumFormatEtc를 이용해서 내가 가지고 있는 포맷의 종류를 알려주고 IDataObject를 이용해서 데이터를 넘겨 줍니다.
IDataObject는 데이터를 주고 받는 역할을 합니다.IEnumFormatEtc에 정의된 포맷의 인덱스에 따라 0번째를 달라고하면 Text를 주고 1번째를 달라고하면 Rtf를 주면됩니다.
드래그&드롭은 모두 이렇게 만들어지는게 정상인데....
그래서 탐색기에서 드롭이 될때 어느 경로에 떨어지는지를 알만한 규격은 없습니다.
그에 대한 해결책은 두가지 정도가 있겠는데....
하나는 꽁수입니다. 폴더카피훅을 구현해서 설치해 놓고...
임시디렉토리를 만들어서 드래그합니다.
탐색기에서 드롭이 되면 임시디렉토리가 복사가 되거나 이동이 될겁니다.
그때에 폴더카피훅이 동작해서 경로명이 임시디렉토리이면 드롭을 중단시키고 드롭되는 경로를 알려주는 방법입니다.
동작은 잘하는데 깔끔하지 못합니다. 약간의 인터벌이 발생하는데 영 껄쩍찌근해서 실제로 써먹기 좀 그렇습니다.
두번째 방법은....
아웃룩익스프레스에서 메일 하나를 드래그해서 탐색기에 드롭하면 그 경로에 이메일파일이 하나 생기고....
탐색기로 FTP를 열어서 서버에 있는 파일 하나를 드래그해서 다른 탐색기나 바탕화면에 떨구면 그 경로로 다운로드가 되는데...
그 와 동일한 방법이 두번째 방법입니다.
여기에서 사용한 방법은 대상의 경로를 알아내는 방법이 아니라
데이터 포맷을 CFSTR_FILEDESCRIPTORW와 CFSTR_FILECONTENTS를 사용한 방법입니다.
흔히 파일을 드래그할때는 CFSTR_FILENAMEMAPA를 사용하는데 이것은 파일명 자체를 가리키는것으로 파일명만 전달이 되고 전달 받은 파일명을 복사할지 이동할지 삭제할지는 드롭받는 대상이 알아서 할일입니다.
CFSTR_FILEDESCRIPTORW는 파일 정보로써 파일명을 가지고 있습니다. CFSTR_FILENAMEMAPA와는 조금 다른데 CFSTR_FILENAMEMAPA는 파일을 복사하거나 이동 삭제등을 할때 사용되는 것으로 실제 존재하는 파일의 전체 경로명을 다루는데 CFSTR_FILEDESCRIPTORW는 아직 생성되지 않은 파일명을 가리키는것으로 전체 경로나 경로명 없는 파일명으로도 사용됩니다.
CFSTR_FILECONTENTS는 파일의 내용을 다루는 포맷입니다. 텍스트일수도 있고 바이너리 일수도 있지요.
결국 아웃룩익스프레스나 탐색기FTP에서는 드롭대상이 어디다가 드롭하는지 그 경로를 알아와서 거기에다가 이메일 파일을 만들거나 다운로드하는게 아니라 CFSTR_FILEDESCRIPTORW와 CFSTR_FILECONTENTS를 이용하여 새로 만들어질 파일명과 파일의 내용을 드래그하는것입니다. 물론 그것을 드롭 받는쪽에서는 그걸 가지고 뭘할지는 자기 마음이지만 탐색기는 그것을 새 파일로 생성하도록 구현해 놓았습니다.
그러므로...
결론은 드롭이 되는 경로에 파일을 만드실 생각이시면 이 방법이 정답이구요..
그게 아니라 드롭되는 경로를 알아내서 거기에 있는 파일들을 정리한다거나 뭐가있는지 알아내서 뭔가를 한다거나 하는 등 새 파일을 만드는 일이 아닌 다른 일을 할려고하면 CFSTR_FILEDESCRIPTORW와 CFSTR_FILECONTENTS를 이용해서는 답이 안나옵니다. 그런 경우는 첫번째 방법대로 폴더카피훅을 이용하는등 꽁수를 써서 경로를 알아내는 방법밖에 없습니다.
설명은 대략 간단하게 했는데.. 드래그앤드롭을 한두번하고 말거라면 여기저기 다 뒤져서 소스를 구하거나 콤포넌트를 구해서 사용하시면 되겠지만 자주 사용하실거라면 IEnumFormatEtc, IDropTarget, IDropSource, IDataObject 이 네가지 인터페이스를 자유자재로 구현하고 CF_TEXT를 비롯 기본 포맷과 더불어 새로운 포맷을 처리하는 방법까지 정도는 자유롭게 구현하실수 있으면 평생토록 드래그&드롭은 지긋지긋한 기능이 아니라 신나고 즐거운 기능이 될수 있습니다. 드래그&드롭은 잘 할 줄 알면 참 편리하고 재밌거든요....
또...
IEnumFormatEtc와 IDataObject는 클립보드에서도 동일하게 사용되므로 드래그&드롭이 자유롭게 구현되면 클립보드도 그냥 거저먹기로 자유롭게 됩니다.
CFSTR_FILEDESCRIPTORW와 CFSTR_FILECONTENTS를 사용한 방법의 단점은 탐색기에서는 잘 되는데 토탈커멘더등 다른 파일관리프로그램들에서는 대부분 안된다는겁니다. 글쎄... 제 생각에는 토탈커멘더 정도되는 파일관리 전문 프로그램이라면 이 정도는 구현을 했어야하는게 아닌가라는 생각이 드는데... 할줄몰라서인지 이런게 있는지 몰라서인지 아니면 필요없다고 생각이 되서 그런지 암튼 그런데서는 안됩니다. --;
'프로그래밍 팁 > etc' 카테고리의 다른 글
다이얼로그 구멍내기 (0) | 2011.11.25 |
---|---|
비스타에서 권한무시 메세지 전송방법 (0) | 2011.10.12 |
CreateEvent를 활용한 WaitForSingleObject (0) | 2011.10.05 |
바로가기 복사하기 (0) | 2011.07.26 |
OS가 64비트인지 32비트인지 확인하는 방법 (0) | 2011.07.19 |