ひきこもりプログラマ

C++のこととか。

フォーカスをもつウィンドウの親の親(の親の...)を非表示にすると無限ループ

2008-10-10 | Program

プロパティページの中に別のプロパティシートがあるようなダイアログを作っていたのですが。

Dialog
+ Property Sheet S1
 + Property Page P1A
  + Property Sheet S2
   + Property Page P2A
    + Control
 + Property Page P1B
  ...

Controlにフォーカスがある状態で,P1Bのタブをクリックすると,アプリケーションが無限ループに入ってしまいました。

デバッグしてみると,P1AがしきりにWM_GETDLGCODEという見慣れないメッセージを子ウィンドウに投げまくっていました。そこでこのメッセージについてぐぐってみたところ,[wx-dev] Endless WM_GETDLGCODE loopなるページが見つかりました。それによると,コントロールがフォーカスを持っているときに,その親の親(またはさらにそのずっと親)が非表示になることが無限ループの発生条件だそうです。ふーむ。

それについて言及しているMicrosoftのドキュメントを探したのですが見つからず。結局P1AのOnShowWindow()関数内で,「自分の子供がフォーカスを持っていたら自分自身に移す」という処理を書いて事なきを得ました。


ボリューム D:\ は現在使用できません。別のボリュームを選択してください。

2008-10-01 | Program

わけあって,デフォルトのインストール先がDドライブなWindows Installerを作っていたのですが。Cドライブしかないコンピュータでインストーラを起動して,インストール先を変更しようとボタンをクリックすると,上記のようなエラーが表示されてインストールが失敗してしまいます。ひどい。

とりあえずインストーラのログを有効にしてみたところ,以下のようになっていました。

アクション 20:46:43: DestinationFolder。 Dialog created
MSI (c) (6C:E0) [20:46:45:205]: PROPERTY CHANGE: Adding _BrowseProperty property. Its value is 'INSTALLDIR'.
エラー 1313。 ボリューム D:\ は現在使用できません。別のボリュームを選択してください。
(Message in English: The volume [2] is currently unavailable. Please select another.)

エラーはDestinationFolderダイアログ上のChangeFolderボタンをクリックしたときに発生しています。そしてChangeFolderボタンのイベントは

  • SpawnDialog InstallChangeFolder
  • [_BrowseProperty] INSTALLDIR

の2つ。_BrowsePropertyにINSTALLDIRを代入するときにはすでにInstallChangeFolderダイアログが生成されているので,原因はInstallChangeFolderダイアログ上のコントロールにちがいありません。

ということでInstallChangeFolderを調べると,_BrowsePropertyと関連付けられているコントロールが3つありました。

  • DirectoryCombo
  • DirectoryList
  • PathEdit

ひとつずつプロパティを別の値にして調べた結果,INSTALLDIRをセットした瞬間にエラーを吐いているのはPathEditであることが判明。

…したのですが,このエラーを抑制する方法まではわかりませんでした。くそう。とりあえず_BrowsePropertyにはC:\を突っ込んでおきます。みっともないなあ。