Perl / Win32::GUI / BrowseForFolder : 폴더 선택 창에서 새 폴더 만들기 구현
| 분류: Perl | 최초 작성: 2011-12-04 00:44:33 |
1. Win32::GUI의 폴더 선택 창에서 새 폴더 만들기?
Win32::GUI 는 그 자신의 GUI 환경에서 사용자가 특정한 폴더를 선택할 수 있도록 BrowseForFolder 함수를 제공합니다. 상당히 익숙한, 다음과 같은 창을 열고 사용자가 선택한 폴더까지의 절대 경로를 돌려주게 되죠.
폴더 선택 화면. 무언가 버튼 하나가 빠져 있다.
그런데, 이 기능에는 한 가지 아쉬운 점이 있습니다. 위 이미지를 보면 바로 눈치챌 수 있으실 텐데, 윈도우 XP 이후의 윈도우즈에서 (당연히) 가능한, 새 폴더를 만든 후 해당 폴더를 선택할 수 있는 [새 폴더 만들기] 버튼이 보이지 않습니다. 그래서 특정한 작업을 수행할 폴더를 지정하기 위해서는 미리 윈도우 탐색기 등을 이용하여 폴더를 만들어 놓고 폴더 선택을 해야 하죠. 은근히 불편합니다.
처음 이 기능(BrowseForFolder)을 사용했던 건 2010년 초 간단한 확장자 변경 프로그램을 만들면서였는데, 이 때는 폴더 만들기 기능이 필요가 없었습니다. 특정한 폴더 안에 들어 있는 모든 .AVI 파일의 확장자만 .SVI 로 바꾸는 프로그램이었기 때문이죠. (똑같은 파일인데도 .AVI 확장자는 거부하고 .SVI 확장자만 받아먹는 망할 눔의 삼성 Yepp Player 때문에... 뿌득) 그런데, 2010년 후반에 M3U Copier 라는 프로그램을 짜기 시작하면서(.M3U 파일 목록에 있는 모든 MP3 파일을 특정한 폴더로 복사해 주는 프로그램입니다), 복사할 대상 폴더를 정할 때에 폴더를 만들 수 있다면 훨씬 편리하게 쓸 수 있다는 사실을 깨달았지요.
문제는, Win32::GUI 의 BrowserForFolder 함수를 아무리 뒤져봐도, 새 폴더 만들기를 지정할 수 있는 방법이 없었다는 것입니다. 구글링을 해 보니, 저와 같은 문제를 겪은 사람이 메일링 리스트에 문의를 한 것이 있었는데, (외국에선 요즘도 Win32::GUI 를 그럭저럭 많이 사용하나 봅니다.) 결론은 Win32::GUI 1.06 버전에서 이 기능을 사용하는 것은 불가능하다. 라는 것이었습니다. [
참고 링크]
참고로,
현재 CVS 에 올라가 있는 최신의 Win32::GUI 코드에는 이 기능이 포함되어 있습니다. (개발자가 이 질문을 보고 이 기능을 코딩해 넣었더군요. 2011년 7월에 CVS 에 Commit 되었습니다.) 그러나 아직 이 기능이 포함된 새로운 Win32::GUI 가 빌드되지 않았기 때문에, 이 기능을 당장은 사용할 수 없습니다. 필자가 컴파일한 최신 CVS 버전의 Win32::GUI 1.06 PPM 파일(Perl 5.10/5.14 버전)을 여기에 링크해 두겠으니, 필요하신 분은 사용하시기 바랍니다. 다만, 정식으로 공개된 버전이 아니기 때문에 예상치 못한 문제가 발생할 수도 있으므로, 이 점은 각자의 위험 부담으로 해 주시기 바랍니다.
5.10 :
다운로드 (크기: 2MB)5.14 :
다운로드 (크기: 2MB)2. 정말 방법이 없는 것일까? Win32::API? Win32::FileOp!
그 덕분에, 최근까지 이 기능을 사용한 제 모든 프로그램에는, 폴더 선택 창에서 새 폴더를 만드는 기능이 없었습니다. 그러나 생각해보면 아예 방법이 없는 것은 아닙니다.
이를테면, (아직 글로 직접 쓰지는 않았지만, 곧 쓸 예정인) Win32::Clipboard 에서는 지원하지 않는, 텍스트가 아닌 이미지를 클립보드에 집어넣는 기능이 Win32::API 를 이용하여 윈도우 API를 직접 호출함으로써 가능했기 때문에, 역시 같은 기능을 하는 윈도우 API 인 SHBrowseForFolder (shell32.dll) 를 호출하면 이 기능을 사용 못할 바 아닙니다. (쓸 줄 모른다면 별문제이지만, 이미 한 번 Win32::API 를 사용하면서 대충 어떻게 쓰는지 감을 잡은 후입니다. 한번 쓴 기능, 두 번은 못 쓰겠습니까.)
그러나, 엉뚱한 데에서 더 쉬운 해결의 실마리가 잡혔습니다. CPAN을 검색하다가, Win32::FileOp 라는 모듈이 2011년 초에 한 번 버전업이 된 것을 우연히 알게 된 것이죠. 이 모듈은 이미 2010년 당시에도 알고 있었고, 실제로 확장자 변경 프로그램을 짤 때 사용했던 모듈이지만(그 이후에 Win32::GUI 내에도 이 함수가 있다는 걸 알고 굉장히 허무했었지요.), 2010년 당시 이 모듈의 최신 버전은 0.14.1 (2003년에 릴리즈) 이었고, 이 버전에서는 폴더 선택 창에서 폴더의 생성이 불가능했었습니다. 그러나, 2011년 1월에 0.16.0 버전이 릴리즈되면서 이 기능을 사용할 수 있도록 버전업이 되었더군요!
제가 사용하는 윈도우용 Perl 은 ActivePerl 5.10.1.1007 버전인데, 이 버전의 PPM 에서는 아무리 검색을 해 봐도 (현재도) 이 모듈의 최신 버전은 여전히 0.14.1 입니다. 그 덕분에 새 버전이 나온 지 1년이 다 지나도록 버전업 사실을 몰랐던 거였습니다. 이런...
덕분에, 다시 윈도우 API 레퍼런스를 뒤지면서 삽질해야 할 필요가 없어졌습니다. 바로 CPAN으로부터 Win32::FileOp 를 수동으로 업데이트한 후, 이 기능을 적용했습니다. 다음은 코드입니다.
# msgOutput 서브루틴은 소스가 UTF-8 인코딩으로 되어 있는 관계로,
# UTF-8 Output 을 지원하지 않는 Win32::GUI 창에서 메시지가 깨지지
# 않도록 하기 위해 출력 전에 내부 UTF-8 인코딩을 euc-kr 인코딩으로
# 변경하는 기능을 하는 자작 서브루틴임을 참고하십시오.
sub BrowseForFolderNewUI {
my $folder;
my $title = msgOutput("음악 파일을 복사할 폴더를 선택하세요.");
use Win32::FileOp qw(:DIALOGS);
$folder = BrowseForFolder( $title, CSIDL_DRIVES, BIF_USENEWUI );
undef $title;
return $folder;
}
폴더가 선택되면 $folder 에는 선택된 폴더의 절대 경로(예: D:\My Documents\My Music) 가 반환되고, 폴더가 선택되지 않았다면 undef 가 반환되므로 실제 사용자가 폴더를 선택하였는지 여부를 즉시 확인 가능합니다. 실행한 결과는 다음과 같습니다. [새 폴더 만들기] 버튼이 떡하니 나타나 있죠.
Win32::FileOp 모듈을 사용한 결과. 새 폴더 만들기 버튼이 나타난다.
한 줄 요약 : 새 폴더 만들기 기능이 있는 폴더 선택 창을 사용하려면 Win32::FileOp 의 최신 버전을 사용하세요.[참고 링크]
Win32::FileOp 0.16.0 - [
CPAN 링크]
(.pm 파일만으로 구성된 모듈이고, 소스를 확인해 보면 Win32::API 를 이용하여 shell32.dll 의 SHBrowseForFolder 를 호출합니다. 의존성 있는 모듈이 존재하므로 설치 시 이들이 함께 설치되어야만 합니다.)
위 기능을 처음 사용해 본 .M3U Copier 프로그램은 다음 링크에 공개되어 있습니다.
.M3U Copier -
http://www.nightowl.pe.kr/software/m3ucopier