デバッグの方法でご相談

[戻る]
ナオーバ 2002/10/08(火) 16:36:30
CTreeView,CFormView,CListViewを使用したアプリで
CTreeViewにはデータとして2つ持っていて、
CFormViewのデータによりツリーデータを切り替えます。
ルートのみの状態もあります(この時CListViewには何も表示されません)
CListViewにはCTreeViewからのデータを表示します

win2000では問題なく動作するんですが、WIN98SEでは落ちます。
探っていくと、ツリービューの更新の時に落ちるようなのです。


データがあるツリーの状態からルートのみツリーの状態に更新するときに
CFormViewからUpdateAllViews(this)して
CTreeView::OnUpdate-->CTreeView::InitialTree(自作関数)
自作関数の最初で行っている。

    CTreeCtrl&    wndTree = GetTreeCtrl( );  // ツリーコントロール取得
    wndTree.DeleteAllItems();                // 全アイテム削除

全アイテム削除のあとに落ちます。

デバッグ情報付きのEXEをWIN98SEで実行するとアサート(afxcoll.inl 123行)がでます。
内容はUIntArray::GetAtのIndexがおかしいって事。

そこで、UIntArrayのGetAtを探してすべてにIndexチェックを追加しましたが、
症状は変わりません。


で、こんな症状のときはどんな方法でデバッグしますか?
それと、これが原因ではって事でもお願いします。


長文で申し訳ありませんが、よろしくお願いします。

WIN2000 SP2
VC6.0   SP5
MFC使用

暇人 2002/10/08(火) 17:58:32
>CListViewにはCTreeViewからのデータを表示します
この部分はどういうふうにプログラムされていますか?
UpdateAllViewsを呼ぶ->
CListViewがCTreeViewのルートアイテムを見に行く->
アイテムがないので落ちる   とか・・・?

>で、こんな症状のときはどんな方法でデバッグしますか?
WIN98SEにVCをインストールするのが一番だと思います。

ナオーバ 2002/10/08(火) 18:24:49
回答ありがとうございます。

>CListViewにはCTreeViewからのデータを表示します
>この部分はどういうふうにプログラムされていますか?
CTreeView::OnSelchanged内に来たらCListViewの関数を呼んで表示しています

で少し進展しました、暇人さんの言う通りアイテムがないので落ちるみたいです。
メッセージボックスをいろんなところにいれてチェックしていたら
wndTree.DeleteAllItems()の後にOnSelchangedにとんでいました。

なのでここら変が怪しいです。

SPY++等でTVN_SELCHANGEDとかのWM_NOTIFY系のメッセージを見る方法はないでしょうか?

>WIN98SEにVCをインストールするのが一番だと思います。
そうですよね、でもできないな。

よろしくお願いします。

暇人 2002/10/08(火) 19:11:25
>SPY++等でTVN_SELCHANGEDとかのWM_NOTIFY系のメッセージを見る方法はないでしょうか?
あまり使わないので知りません。
というかSPY使ってるとフリーズするのはMyMachineだけ?

>WIN98SEにVCをインストールするのが一番だと思います。
>そうですよね、でもできないな。
あ、やっぱり。

とりあえず
OnSelchangedの中で CTreeCtrl::GetCount() の戻り値によって処理を分けてみたら?

kazuma 2002/10/10(木) 01:29:40
Win2000が入っているマシンとWin98SEが入っているマシンが別のマシンで、
なおかつネットワークでつながっているなら、
「リモートデバッグ」という方法もあります。

ナオーバ 2002/10/10(木) 09:24:01
暇人さん、レスありがとうございます。いろいろ調べていて遅れました。

原因はだいたいわかりました。
いろんな事が複雑に絡み合っているようです。

まず、CTreeViewのデータはnewで作ったUIntArrayを含んだツリー構造を持ったクラスで
CTreeViewに片方をSetItemDataしています。これをCFormViewの条件で切り換えるので

CFormViewからCTreeViewの片方のデータを削除します。
(この時はdeleteのみでNULLにしていません、NULLの文を入れても通ってくれない)
この後にUpdateAllViews(this)してCTreeViewのDeleteAllItems()をすると
CTreeViewのOnSelchangedに飛んでNULLしていない所にアクセスしておちるようです。

DeleteAllItemsしたのにOnSelchanged内で、
CTreeCtrl::GetCount(),CTreeCtrl::GetSelectedItem() をしても正常な値が返ってきます
なので異常の時に通る分岐に行きません。
それで削除したデータにアクセスしておちるようです

TVN_DELETEITEMよりもTVN_SELCHANGEDが先に来る事がWIN98SEには有るようです。
で、削除できていない状態なのでGetCount、GetSelectedItemをした時に
正常な値が返ってくるようです。


DeleteAllItemsをする前にフラグを立てて、OnSelchanged内でフラグで判断する方法で
回避できましたが
    m_bDeleteItemFlg = TRUE;
    wndTree.DeleteAllItems();
    m_bDeleteItemFlg = FALSE;
なにか間抜けなソースになってしまいます。

他にいい解決方法は無いものでしょうか?
タイトルと違う内容になりますが、よろしくお願いします。

kazumaさん
リモートデバッグ 早速調べます。

暇人 2002/10/10(木) 14:45:02
>CFormViewからCTreeViewの片方のデータを削除します。
>この後にUpdateAllViews(this)・・・
CFormViewからCTreeView::InitialTree(自作関数)を
直接呼んでDeleteAllItems()してからデータを削除するか
DeleteAllItems()の前にSetItemDataでNULLにしておくか・・・
他に解決策はなくはないけどどれが良いとは(^_^;)

#リモートデバッグ面白そう。マシンが2台あればやってみたい。

ナオーバ 2002/10/15(火) 09:49:15
[[解決]]
暇人さん、遅くなりましたがレスありがとうございます。

>DeleteAllItems()の前にSetItemDataでNULLにしておくか・・・
で解決できました。

これをする事でOnSelchanged内でGetItemDataをすると当然NULLが返ってくるので、
ここで抜けることが出来ました。

いろいろ貴重な意見ありがとうございました。

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