ページ 11

GetOpenFileNameの挙動

Posted: 2017年1月18日(水) 14:45
by 駆け出し
こんにちは。VisualStudio 2015/Win32 でプログラミングしている者です。
今日、GetOpenFileNameの挙動がおかしくなり、自己解決できそうにありませんので質問します。
状況なのですが、
(1)GetOpenFileName()を呼び出し、ダイアログが出てきます。(正常)
(2)複数のファイルないしは一つのファイルを選択して、「開く」もしくは「キャンセル」のボタンを押します。(正常)
(3)するとなぜか、複数選択したときは選択されたファイルの一つ上の階層へ、単数のときはファイルが既に選択された状態で出てきてしまいます。
キャンセルのときはダイアログが出てくるのみです。(異常)

(4)そして、なぜかメモリリークしてしまいます(昨日まで、すなわち異常な状態になっていないときは発生していませんでした)

という感じで、自分も初めてのことでちんぷんかんぷんです。

コードをzip方式で添付しておきますので、それのどこが誤り/原因になっているかをご教示ください。よろしくお願いします。

また、使えるかどうかはわかりませんが出力も置いておきます。
(イタリックになっているところが、GetOpenFileName呼び出し部分、太字がメモリリーク部分です)

出力
► スポイラーを表示
[追記]
適当なファイルを選択→二回目のダイアログで「キャンセル」を選択しても
01/18 Wed 19:50:42][Debug]{[userinterface.cpp at GetFileNames(112)]}if(GetOpenFileNameW(&ofn)) は 'true' として評価されました。
と出力されるようです....

Re: GetOpenFileNameの挙動

Posted: 2017年1月18日(水) 20:42
by 駆け出し
すいません。自己解決しました。

コード:

#define IF(x)                             OutputExeLogA("if(%s) は \'%s\' として評価されました。\n",OPTP(x),(x)==1 ? "true" : "false"); if(x)
このマクロを使うと

コード:

(x)==1 ? "true" : "false")
の部分で一度xが実行され、

コード:

 if(x)
の部分で2度目が実行されるようです。
完全に読み違えていました。

なので
Main.cpp

コード:

#if defined _DEBUG
//IFマクロの本体
VOID *p;
#endif
strdef.h

コード:

#ifdef _DEBUG
extern VOID *p;
#define IF(x)                             OutputExeLogA("if(%s) は \'%s\' として評価されました。\n",OPTP(x),(p = (VOID*)(x)) == NULL ? "false" : "true"); if(p)
#endif
とすることで一応バグは回避できました。


この解釈をすると、メモリがリークしたこと、ダイアログが2度出てくることも説明できそうです。

Re: GetOpenFileNameの挙動

Posted: 2017年1月18日(水) 21:10
by Math
今度も自己解決しましたね。また掲示板に来てください。

Re: GetOpenFileNameの挙動

Posted: 2017年1月18日(水) 22:35
by 駆け出し
今度も自己解決しましたね。また掲示板に来てください。
申し訳ないです...releaseビルドすると、バグらなかったので、気付くことができました。
難しいです...プログラミングは...

解決つけ忘れてましたね、これにて解決とさせていただきます。

Re: GetOpenFileNameの挙動

Posted: 2017年1月18日(水) 22:37
by みけCAT
一般に、マクロの引数に副作用がある式を使うときは注意が必要です。
PRE31-C. 安全でないマクロの引数では副作用を避ける

Re: GetOpenFileNameの挙動

Posted: 2017年1月23日(月) 16:27
by 駆け出し
一般に、マクロの引数に副作用がある式を使うときは注意が必要です。
PRE31-C. 安全でないマクロの引数では副作用を避ける
返事が遅れて申し訳ないです。
ご返信感謝します。ブクマして、少しづつ理解しながら読んでいこうと思います。