質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

7756閲覧

GetOpenFileNameの実行が変

BeatStar

総合スコア4958

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/11/02 05:04

C/C++ ( Windows API実装 ) でやっています。

今までは 書籍についていたコンパイラ MinGW でやっていました。

今は Dialog.dll という自分用のダイアログを表示したりするDLLを作成しようとしています。

書籍についていたコンパイラから 比較的最新の MinGW ( minimalでない方 ) を 使ってコンパイルしたからなのか、

GetOpenFileName関数がうまくいきません。

DLLの方ではなく、実行ファイルの方にやっても同じでした。

GUIのひな形(?) に

C++

1// GetOpenFileName関数を使って "ファイルを開く"ダイアログ を表示し、ファイルパス取得する。 2/* 3 HWND hWnd := 親ウィンドウハンドル 4 int DefaultIndex := 初期のインデックス 5 const char *DefaultDir := 初期ディレクトリ 6 const char *DefaultFileName := 初期ファイル名 7 char *result := 戻り値。ファイルパスが格納される。 8*/ 9int ShowOpenFile( HWND hWnd, int DefaultIndex, const char *DefaultDir, const char *DefaultFileName, char *result ){ 10 OPENFILENAME ofn; 11 12 string filter; 13 14 char temp[MAX_PATH+1]; 15 16 int tempIndex; 17 18 if( DefaultIndex <= 0 ){ 19 tempIndex = OF_INDEX_ALL; 20 }else{ 21 tempIndex = DefaultIndex; 22 } 23 24 // これをやらないと失敗する 25 memset( &ofn, 0, sizeof(OPENFILENAME) ); 26 27 28 ofn.lpstrFilter = TEXT("画像ファイル (*.gif, *.jpg, *.jpeg, *.png, *.bmp)\0*.gif;*.jpg;*.jpeg;*.png;*.bmp\0") 29 // 中略 30 TEXT("BATファイル (*.bat)\0*.bat\0") 31 TEXT("PHPファイル (*.php)\0*.php\0") 32 TEXT("PYファイル (*.py)\0*.py\0") 33 TEXT("コンパイル済みPythonファイル (*.py)\0.pyc\0") 34 TEXT("RBファイル (*.rb)\0*.rb\0") 35 TEXT("RERLファイル (*.pl)\0*.pl\0") 36 TEXT("Cファイル (*.c)\0*.c\0") 37 TEXT("CCファイル (*.cc)\0*.cc\0") 38 TEXT("CPPファイル (*.cpp)\0*.cpp\0") 39 TEXT("Oファイル (*.o)\0*.o\0") 40 TEXT("OBJファイル (*.obj)\0*.obj\0") 41 TEXT("LIBファイル (*.lib)\0*.lib\0") 42 TEXT("ヘッダファイル (*.h,*.hpp)\0*.h;*.hpp\0") 43 44 // 圧縮ファイル関係 45 TEXT("ZIPファイル (*.zip)\0*.zip\0") 46 TEXT("RARファイル (*.rar)\0*.rar\0") 47 TEXT("LZHファイル (*.lzh)\0*.lzh\0") 48 TEXT("ISOファイル (*.iso)\0*.iso\0") 49 50 // OFFICE製品 51 TEXT("DOCファイル (*.doc)\0*.doc\0") 52 TEXT("DOCXファイル (*.docx)\0*.docx\0") 53 TEXT("XLSファイル (*.xls)\0*.xls\0") 54 TEXT("XLSXファイル (*.xlsx)\0*.xlsx\0") 55 TEXT("PPTファイル (*.ppt)\0*.ppt\0") 56 TEXT("PPTXファイル (*.pptx)\0*.pptx\0") 57 58 // リソースファイル 59 TEXT("ANIファイル (*.ani)\0*.ani\0") 60 TEXT("CURファイル (*.cur)\0*.cur\0") 61 TEXT("ICOファイル (*.ico)\0*.ico\0") 62 TEXT("TTFファイル (*.ttf)\0*.ttf\0") 63 TEXT("OTFファイル (*.otf)\0*.otf\0") 64 65 // リソースファイル 66 TEXT("ショートカットファイル (*.lnk)\0*.lnk\0") 67 TEXT("インターネットショートカットファイル (*.url)\0*.url\0") 68 69 // すべてのファイル 70 TEXT("全てのファイル(*.*)\0*.*\0\0"); 71 72 73 ofn.lStructSize = sizeof(OPENFILENAME); 74 ofn.hwndOwner = hWnd; 75 ofn.nFilterIndex = tempIndex; // 最初に指定するインデックス 76 ofn.lpstrInitialDir = DefaultDir; 77 ofn.lpstrFile = temp; // 戻り値用 78 ofn.nMaxFile = MAX_PATH+1; // 戻り値の最大の長さ 79 ofn.Flags = OFN_FILEMUSTEXIST; // フラグ 80 81 if( GetOpenFileName( &ofn ) != 0 ){ 82 strcpy( result, temp ); 83 return 0; 84 }else{ 85 DWORD r = CommDlgExtendedError(); 86 if( r == 0 ){ 87 return -1; // "キャンセル"された 88 }else if( r == CDERR_DIALOGFAILURE ){ 89 return -2; // 無効なウィンドウハンドルが指定された等でダイアログ生成失敗 90 }else if( r == CDERR_FINDRESFAILURE ){ 91 return -3; // リソースが見つからなかった 92 }else if( r == CDERR_INITIALIZATION ){ 93 return -4; // メモリ不足等によりダイアログ初期化失敗 94 }else if( r == CDERR_LOADRESFAILURE ){ 95 return -5; // リソースのロード失敗 96 }else if( r == CDERR_LOADSTRFAILURE ){ 97 return -6; // 指定した文字列のロード失敗 98 }else if( r == CDERR_LOCKRESFAILURE ){ 99 return -7; // 指定したリソースのロック失敗 100 }else if( r == CDERR_MEMALLOCFAILURE ){ 101 return -8; // 内部の構造体用のメモリ割り当てに失敗 102 }else if( r == CDERR_MEMLOCKFAILURE ){ 103 return -9; // ハンドルに関連付けられているメモリをロック失敗 104 }else if( r == CDERR_REGISTERMSGFAIL ){ 105 return -10; // コモンダイアログボックス関数が呼び出した RegisterWindowMessage 関数が、エラーコードを返した 106 }else if( r == CDERR_STRUCTSIZE ){ 107 return -11; // 該当するコモンダイアログボックス用の初期化構造体の lStructSize メンバが無効 108 }else if( r == FNERR_BUFFERTOOSMALL ){ 109 return -12; // 構造体の lpstrFile メンバが指すバッファが小さすぎて、ユーザーが指定したファイル名を格納できない 110 // lpstrFile バッファの最初の 2 バイトは、名前全体を受け取るために必要なサイズを TCHAR 単位で格納します。 111 }else if( r == FNERR_INVALIDFILENAME ){ 112 return -13; // ファイル名が無効 113 }else if( r == FNERR_SUBCLASSFAILURE ){ 114 return -14; // メモリ不足のため、リストボックスのサブクラス化失敗 115 }else{ 116 return -15; // それ以外 117 } 118 } 119} 120 121// メッセージボックス表示 122void MsgBox( const char *text ){ 123 MessageBox( NULL, text, "結果", MB_OK ); 124} 125 126 127//自作 ShowOpenFile関数 に引数を与えて表示する 128void ShowDialogEx( HWND hWnd ){ 129 char result[MAX_PATH+1]; 130 131 int r = ShowOpenFile( hWnd, -1, NULL, NULL, result ); 132 133 if( r == 0 ){ 134 MsgBox( result ); 135 }else{ 136 char str[20]; 137 138 sprintf( str, "error: %d", r ); 139 MsgBox( str ); 140 } 141} 142 143// ... 144 145// ウィンドウプロシージャ内の WM_CREATE メッセージで 146 ShowDialogEx( hWnd ); 147 148

としたところ、

実行結果が

"error: -13"

というメッセージボックスが出ます。

( "開く"ダイアログは表示されない。 )

以前までのコンパイラなら普通にできたような気が...

なぜなのでしょうか。

回避方法が知りたいです。

[環境等]
言語: C/C++
コンパイラ: MinGW ( g++ (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 6.2.0 )

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

"error: -13"の-13は、ShowOpenFile関数の下記コードの部分に由来するものでしょうから、ファイル名に不正な文字列を与えたのだろうと思われます。

}else if( r == FNERR_INVALIDFILENAME ){ return -13; // ファイル名が無効

そこで気になるのが、ShowDialogEx関数のコードの中でShowOpenFileの第3引数と第4引数がNULLになっているところです。
これらは、*DefaultDir と *DefaultFileName ですから、NULLは無効なファイル名なのではないでしょうか?

int r = ShowOpenFile( hWnd, -1, NULL, NULL, result );

ご確認ください。

投稿2016/11/02 05:26

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

OPENFILENAME構造体lpstrFileメンバに設定するバッファは、あらかじめ初期化しておく必要があります。質問コードの場合、temp配列を空文字列で初期化しておけばOKです。

C++

1char temp[MAX_PATH+1] = "";

以前までのコンパイラなら普通にできたような気が...

おそらく、偶然動いていただけです。

投稿2016/11/02 05:21

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2016/11/02 05:27

なるほど。 試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問