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使用
>CListViewにはCTreeViewからのデータを表示します
この部分はどういうふうにプログラムされていますか?
UpdateAllViewsを呼ぶ->
CListViewがCTreeViewのルートアイテムを見に行く->
アイテムがないので落ちる とか・・・?
>で、こんな症状のときはどんな方法でデバッグしますか?
WIN98SEにVCをインストールするのが一番だと思います。
回答ありがとうございます。
>CListViewにはCTreeViewからのデータを表示します
>この部分はどういうふうにプログラムされていますか?
CTreeView::OnSelchanged内に来たらCListViewの関数を呼んで表示しています
で少し進展しました、暇人さんの言う通りアイテムがないので落ちるみたいです。
メッセージボックスをいろんなところにいれてチェックしていたら
wndTree.DeleteAllItems()の後にOnSelchangedにとんでいました。
なのでここら変が怪しいです。
SPY++等でTVN_SELCHANGEDとかのWM_NOTIFY系のメッセージを見る方法はないでしょうか?
>WIN98SEにVCをインストールするのが一番だと思います。
そうですよね、でもできないな。
よろしくお願いします。
>SPY++等でTVN_SELCHANGEDとかのWM_NOTIFY系のメッセージを見る方法はないでしょうか?
あまり使わないので知りません。
というかSPY使ってるとフリーズするのはMyMachineだけ?
>WIN98SEにVCをインストールするのが一番だと思います。
>そうですよね、でもできないな。
あ、やっぱり。
とりあえず
OnSelchangedの中で CTreeCtrl::GetCount() の戻り値によって処理を分けてみたら?
Win2000が入っているマシンとWin98SEが入っているマシンが別のマシンで、
なおかつネットワークでつながっているなら、
「リモートデバッグ」という方法もあります。
暇人さん、レスありがとうございます。いろいろ調べていて遅れました。
原因はだいたいわかりました。
いろんな事が複雑に絡み合っているようです。
まず、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さん
リモートデバッグ 早速調べます。
>CFormViewからCTreeViewの片方のデータを削除します。
>この後にUpdateAllViews(this)・・・
CFormViewからCTreeView::InitialTree(自作関数)を
直接呼んでDeleteAllItems()してからデータを削除するか
DeleteAllItems()の前にSetItemDataでNULLにしておくか・・・
他に解決策はなくはないけどどれが良いとは(^_^;)
#リモートデバッグ面白そう。マシンが2台あればやってみたい。
暇人さん、遅くなりましたがレスありがとうございます。
>DeleteAllItems()の前にSetItemDataでNULLにしておくか・・・
で解決できました。
これをする事でOnSelchanged内でGetItemDataをすると当然NULLが返ってくるので、
ここで抜けることが出来ました。
いろいろ貴重な意見ありがとうございました。