ボタンが生成されない場合がある

[戻る]
JILL 2011/01/17(月) 15:19:49
WindowsCE5.0/eMbeddedVC++4.0SP4/SDK(MFC未使用)にて開発

お世話になります。
標準のボタンをスーパークラス化して使用しています。
スーパークラス化して行っているのは
・ボタンにフォーカスがある場合にダイアログにキー入力を通知
・クリックされずにボタンにフォーカスがあるままの状態の場合ダイアログに
 フォーカスをセットする
等のためです。
複数の画面で統一して使用したかったのでサブクラスではなくスーパークラスに
しました。
【現象】
 目的は達成できたのですが、30画面(ダイアログ)くらいある中で
不特定にボタンが消える(生成されていない?)現象が発生しました。
・いつも同じボタンが消える訳ではない。
・消えるという現象も非常に稀で再現性がかなり低い。
・ボタンが消えたダイアログを終了し、再度同じダイアログを開くと表示される。
・消えるだけでなくボタン部分を押しても何の反応もありません。
・他にエディットもスーパークラス化して生成していますが、エディットは
 今のところ消えたことはありません。ただし、ボタンに比べ数はかなり少ないです。
という感じです。
【質問】
 ボタンの生成で失敗することがないと考えて(甘い?)CreateWindowの戻り値
=NULLの場合ではエラー処理を行っていませんでした。
@CreateWindowで失敗する原因に思い当たるところはないのですが、
 ときどき(稀に)失敗する原因というのはどんなことがあるのでしょうか?
ACreateWindowで失敗した場合、ボタン生成をリトライするとしたら
 何回分の失敗を想定すればよいのでしょうか?
 業務アプリなので、そうそうエラーメッセージを出せず、できるなら
 ボタン生成失敗→リトライ。。で表面上何事もなかったようにしたいのですが、
 問題ありますか?(原因にもよると思いますが)
Bとりあえず、CreateWindowの戻り値=NULLの場合にログを残して、ボタンが消えた
 場合=CreateWindowが失敗していたか?の確認をしようと思っていますが、
 他にしておくべきことは何かありますか?

よろしくお願いいたします。

仲澤@失業者 2011/01/21(金) 10:30:10
れす、付きませんねぇ。

意図したとおりにウインドウ(コントロール)が
表示されないケースはいろいろあるので、CreateWindow()に失敗した
と仮定するとはまる場合もあります。

 1.CreateWindow()に失敗した
 2.WS_VISIBLEになっていない
 3.親のクライアント外に生成された、又は移動した。
 4.サイズが0,0になっている。

等が考えられますので、まず、発生時にSpy++で確認しましょう。

AR 2011/01/21(金) 12:42:03
以前経験した内容を元に、参考になれば程度ですが紹介させていただきます。

コントロールの生成数が多く、GDIリソース不足でCreateWindowが失敗することがありま
す。
この場合、規則性があまりなく、成功したり失敗したりという現象が発生し、原因の切
り分けが非常に難しかった記憶があります。
もちろん、このケースに当てはまるなら失敗をリトライしてはならず、不要なコントロ
ールを開放してコントロールの数を減らす対応をするしかありません。

あと、余談ですが失敗しない関数なら戻り値は無いものと設計されるはずです。
個人的な極論ですが、失敗する可能性がある=戻り値がある関数は全て使うべきだと思
ってます。
たとえば今回のような原因の調査には必要ですよね?ということですね。

tenteku 2011/01/25(火) 15:02:29
デスクトップヒープが枯渇してしまったのでしょうかね?
その場合は一応例外が投げられるようですけど。
皆さんが仰るようにコントロールの生成数を減らしてみるのが一番な気がします。

古いスレッドには追加発言できません。