この日記はGNSで生成しています。 |
*1: フォルダ"c:\hoge\"にフォルダ"01"と実行ファイル"01.exe"があるとき、"c:\hoge\01"というパスがフォルダでなく実行ファイルを指してしまうケースがある。これを回避するためにも、「ディレクトリ名には"\"を付けて格納する」ほうが安全。
_ ということで、手許のソースから貼り付けてみる。
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <shlwapi.h> int myGetOpenFileNameMulti( TCHAR *startpath, TCHAR ***ret_pathlist, int *ret_npathlist ) { OPENFILENAME ofn; TCHAR dir[MAX_PATH]; TCHAR *p; TCHAR *file; TCHAR path[MAX_PATH*256]; TCHAR **pathlist; TCHAR **newpathlist; int pathlistsize; int npathlist; int i; int dirlen; int filelen; // 初期化 pathlistsize = 16; pathlist = (TCHAR **)GlobalAlloc( GPTR, pathlistsize*sizeof(TCHAR *) ); if ( pathlist == NULL ) { return (-1); } npathlist = 0; *(ret_pathlist) = NULL; *(ret_npathlist) = npathlist; // API発行 lstrcpyn( path, startpath, sizeof(path) ); lstrcpyn( dir, startpath, sizeof(dir) ); PathRemoveFileSpec( dir ); PathAddBackslash( dir ); if ( !lstrcmpi( path, dir ) ) { lstrcpyn( path, "", sizeof(path) ); } ZeroMemory( &ofn, sizeof(ofn) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFilter = "すべてのファイル (*.*)\0*.*\0"; ofn.lpstrFile = path; ofn.lpstrInitialDir = dir; ofn.nMaxFile = sizeof(path); ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ALLOWMULTISELECT; if ( GetOpenFileName( &ofn ) == FALSE ) { GlobalFree( pathlist ); return (0); } // 単一ファイル選択ならすぐ終了 if ( ( !(ofn.Flags & OFN_ALLOWMULTISELECT) ) || ( path[ lstrlen( path )+1 ] == '\0' ) ) { p = (TCHAR *)GlobalAlloc( GPTR, lstrlen( path )+1 ); if ( p == NULL ) { goto err_allocpath; } lstrcpy( p, path ); pathlist[npathlist++] = p; goto ret_ok; } // 複数ファイルのpathを展開しながらストア lstrcpyn( dir, path, sizeof(dir) ); PathAddBackslash( dir ); dirlen = lstrlen( dir ); file = path+lstrlen( path )+1; while ( file[0] ) { filelen = lstrlen( file ); p = (TCHAR *)GlobalAlloc( GPTR, dirlen+filelen+1 ); if ( p == NULL ) { goto err_allocpath; } while ( npathlist >= pathlistsize ) { pathlistsize *= 2; newpathlist = (TCHAR **)GlobalReAlloc( pathlist, pathlistsize*sizeof(TCHAR *), GMEM_MOVEABLE|GMEM_ZEROINIT ); if ( newpathlist == NULL ) { goto err_allocpath; } pathlist = newpathlist; } PathCombine( p, dir, file ); pathlist[npathlist++] = p; file += filelen+1; } goto ret_ok; ret_ok:; *(ret_pathlist) = pathlist; *(ret_npathlist) = npathlist; return (npathlist); err_allocpath:; for ( i=0; i<npathlist; i++ ) { GlobalFree( pathlist[i] ); } GlobalFree( pathlist ); return (-1); } int main( int argc, char *argv[] ) { TCHAR **pathlist; int npathlist; int ret; int i; if( argc == 1 ) { printf( "usage: %s [startpath]\n", argv[0] ); exit( EXIT_SUCCESS ); } ret = myGetOpenFileNameMulti( argv[argc-1], &pathlist, &npathlist ); if ( ret < 0 ) { printf( "error.\n" ); exit( EXIT_SUCCESS ); } if ( ret == 0 ) { printf( "no file selected.\n" ); exit( EXIT_SUCCESS ); } for ( i=0; i<npathlist; i++ ) { printf( "%d: %s\n", i, pathlist[i] ); GlobalFree( pathlist[i] ); } GlobalFree( pathlist ); return( EXIT_SUCCESS ); } // [EOF]
_ 追記。「!(ofn.Flags & OFN_ALLOWMULTISELECT)」の"&"がダブっていた。感謝。
_
もともとこのコード、このまま使うだけならofn.Flagsの値なんぞチェックしなくていい。コピペ&修正でこのコードを使いまわすとき、上のOFN_ALLOWMULTISELECTを外してしまった場合の対策で、今回ここに書くために追記したもの。それでミスってちゃ世話ない・・・(苦笑)。
メールはこちらへ...[後藤浩昭 / Hiroaki GOTO / GORRY / gorry@hauN.org]