たかせ様
ご返信ありがとうございます。
Dim FirstPtr As TREEDATA ではなく
Dim FirstPtr As *TREEDATAで定義してみてください。
なんという醜態……
そりゃそうだと、回答を拝見した時画面にチョップを入れてしました。
すいませんでした。
②BytePtrと*Byte型の違いについてですが
BytePtrと*Byte型はまったく同じものです。
AB V4.24のBASIC.SBPの28行目~46行目のソースコードに注目してください。
TYPEDEFステートメントを使用しています。
なるほど、ありがとうございました!
TYPEDEFステートメントは……定義付けみたいなものですね……?
何とか進んでいったのですが、今度はリエントラントで躓きました。
ツリービューで、各ノードにリスト構造体を持たせて、情報を管理しています。
リストの中身は、
・ノードのハンドル
・ノードのデータ(テキストデータ)
・次のリストへのポインタ
です。
ツリービューで、アイテムが追加されると、自動的にポインタも作られます。
その時、親ノードを閉じると、子ノードも自動的に消えますが、メモリは開放しません。
それをすべて解放しようとしています。
実験を重ねたところ、
hNext=SendMessage(hTree,TVM_GETNEXTITEM,TVGN_NEXT,hChild)
で、なぜか同列のノードが途中からかえらなくなっているところまでわかりました。
理由はわかりません……
子ノードは5つあるのに、上の関数では3つめまでしかループしていないという状況です。
ちょっと長いですが、おかしな所があればご教授ください。
よろしくお願いいたします。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]↓例のリスト構造体です
コード: 全て選択
Type TREEDATA 'ツリービューのリスト構造体
hHandle As HWND 'ノードのハンドル
buffer As BytePtr 'ノードのデータ
NextPtr As BytePtr '次のリストの構造体ポインタ
End Type
コード: 全て選択
/* 子ノードのハンドルをすべて削除する関数 */
Function DeleteChildNodePointer(hHandle As HWND) As HWND
Dim hChild As HWND
Dim hNext As HWND
'まず、削除対象のノードが子を持っていないかを確認する
hChild=SendMessage(hTree,TVM_GETNEXTITEM,TVGN_CHILD,hHandle)
If hChild<>0 Then
'持っていればそいつのハンドルを取得(リエントラント)
DeleteChildNodePointer(hChild)
End If
'持っていなければ次のノードを検索
hNext=SendMessage(hTree,TVM_GETNEXTITEM,TVGN_NEXT,hChild)
'ノードがあれば検出
If hNext<>0 Then
DeleteChildNodePointer(hNext)
End If
'ポインタを削除する
DeletePointer(hHandle)
End Function
コード: 全て選択
/* ハンドルから指定されたポインタリストを削除する */
Sub DeletePointer(hHandle As HWND)
Dim pt As *TREEDATA
Dim tp As *TREEDATA
pt=FirstPtr
tp=FirstPtr
Do
If pt=NULL Then
Exit Do
End If
If pt->hHandle=hHandle Then
If pt=FirstPtr Then
'ポインタが最後ならつなぎ替える
FirstPtr=pt->NextPtr
free(pt->buffer)
free(pt)
Else
tp->NextPtr=pt->NextPtr
free(pt->buffer)
free(pt)
End If
Exit Do
End If
tp=pt
pt=pt->NextPtr
Loop
End Sub