こんにちは。じゅこと言います。
環境:MFC6.0
OS:WinXP
を使用しています。
スプラッシュスクリーンを使用したいと思い、この掲示板の履歴にあるように
コンポーネントの追加でスプラッシュスクリーンを追加しみました。
瞬間にして、スプラッシュが起動され、まったく何の作業も無しに出来てしまい、
これは本当に凄いと感動したのも束の間(T_T)、下記の2点の不具合が発覚しました。
1.スプラッシュ起動中にスプラッシュBMPをクリックするとハングアップする
2.何故かダイアログ中にEditBoxの文字が4倍で入力される。
1は、sprash.cpp内の
void CSplashWnd::PostNcDestroy()
{
delete this;
}
でハングアップするみたいです。
2.は全く関係ないダイアログ内で『1』を押すと何故か『1111』とエディットボックス
に入力されます。
この情報ではおそらく、何が悪いのか分からないかと思いますが、同様のケースが
発生した等、何か情報があればと思い投稿させてもらいました。
場所が分かっていても修正方法が分からない初心者です。
よろしくお願いします。
あなたが付加したり削ったりしたのはどんなコードですか?
スプラッシュに関しては本当に何も追加して無いんですけどね。
元々あったソースの出来はおいとくとしまして、スプラッシュを追加して、コードを
何も修正しない時から、このような現象が発生しました。
本当に謎です。何かいけない事をしてるのでしょうか?
スプラッシュを全てソースから外すと正常に動作します。
>ハングアップするみたい
デバッガのエラー報告はどんなですか?
次のようなダイアログが出ます。
タイトル:Microsoft Visual C++ Debug Library
Debug Assertion Failed!
Proguram:D:\xxxxxxx\yyyyyyy.exe
File:wincore.cpp
Line:875
For information on how your program cause an assertion
failure, see the Visual C++ documentatiion on asserts.
と、『中止』と『再試行』と『無視』のボタンが表示されます。
こんな感じで何かわかりますでしょうか?
えーと、VC6でいいんでしょうか。
VC6付属のwincore.cppの875行には何も無いですが、行番号間違えてないですか?
私の環境では875行目ありますけどね。
下記がそのソースになります。ちなみにデバッグモードです。
パス:C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC
環境:SP5
#ifdef _DEBUG
void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid
// check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd));
// ここが問題の875行目です↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);
CObject* p;
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
ASSERT((CWnd*)p == this); // must be us
}
}
あらま。
sp6がwincore.cppを改変したのかな…
作成日時・更新日時が共に2004年1月28日0:00:00となっているし多分そうかも。
失礼しました。
で、そのときデバッガのコールスタックウィンドウの内容はどうなってますか?
コールスタックウインドウを使った事が無いので良くわかりませんが、下記のようには
なっています。
USER32! 77cfa166()
NTDLL! 77f75da3()
デバッグをしていっても、ソース上ではなく、混合モード上でハングアップしているよう
です。
スプラッシュがどんな物か知りませんが...
> ASSERT(::IsWindow(m_hWnd));
>// ここが問題の875行目です↑↑↑↑↑↑↑↑↑↑↑↑↑↑
これの意味わかりますよね。
m_hWndがIsWindowでない。と言う意味です。(そのまんま)
>1は、sprash.cpp内の
>void CSplashWnd::PostNcDestroy()
>{
> delete this;
>}
>でハングアップするみたいです。
ここではなくてOnDestroy()内の
CWnd::OnDestroyでASSERTされているような気がしますが...
そこから推測してみると...
(1) CWnd::DestroyWindowが呼ばれる前にm_hWndがDetatch等で切り離されてる。
(2) APIのDestroyWindowを呼んでしまっている。
(3) m_hWndの親が破棄された場合、子であるm_hWndは破棄されてしまいますが、
親の指定がきちんとされていない。
(4)ダイアログベースのスケルトンを作成すると、モーダルで表示させますが、
モードレスに変更ないときちんと機能しない。
(4)あたりが怪しそうな気がします。
>この掲示板の履歴にあるように
参考にしたURL見せて
MSDNサンプルに「superpad」って言うのがあってこっちは参考にしましたかね?
「Debug assertion Failed!」のダイアログが出たら、
「中止」「再試行」「無視」のうちの『再試行』を押してください。
そうするとこのダイアログを出したASSERT()のある行
(この場合wincore.cppの875行目)に飛びますが、
その時のコールスタックの内容を教えて下さい。
たぶんこう↓ではないと思うので。最初から書いときゃよかったんですが。
> USER32! 77cfa166()
> NTDLL! 77f75da3()
下記の修正をしました。
BOOL CMyProgamXXXApp::PreTranslateMessage(MSG* pMsg)
{
BOOL bRet = CWinApp::PreTranslateMessage(pMsg); // <- ①
// CG: 以下のブロックはスプラッシュ スクリーン コンポーネントによって追加されました
CSplashWnd::PreTranslateAppMessage(pMsg); // <- ②
return CWinApp::PreTranslateMessage(pMsg);
}
②を削除する事で、スプラッシュ時のハングアップがなくなりました。
マウスクリックで消えないので当然ですが。
後で気付きましたが、この現象はリリース版では発生しないのですね。
これで我慢しようと思います。
①を削除する事で、何故かダイアログに入力する文字が4倍になるのが直りました。
よく分からない現象です。
皆様、大事なお時間を頂き、貴重なご意見ありがとうございました。
本来、コンポーネント追加だけで作成されるスプレッドがよく分からない動作をする
ので、他の方の所でも発生するのかと思い、投稿させて頂きました。
いろいろと貴重な情報を頂きましたが、初心者の私には修正する事が困難かと思い、
この対応を選択しました。
せっかく投稿頂きました方々、中途半端な解決ですが、ご理解頂きますようお願い
致します。
本当にありがとうございました。
vc6 + sp6 だと初期状態でこうですが…。
BOOL CSplashApp::PreTranslateMessage(MSG* pMsg)
{
// CG: 以下のブロックはスプラッシュ スクリーン コンポーネントによって追加さ
れました
if (CSplashWnd::PreTranslateAppMessage(pMsg))
return TRUE;
return CWinApp::PreTranslateMessage(pMsg);
}
nさん。
完璧に治りました。全て正常に動作しているようです。
一体何が悪かったのでしょう?
バグ?
ドキュメントビューアーキテクチャーを使用しているのが悪いのでしょうか?
とりあえず完璧に治って良かったです。
本当にありがとうございます。