1

ここで、ファイル名とそれに関連するアイコンをvirtualtreeviewに追加する簡単なコード

  PFileInfoRec = ^TFileInfoRec;
  TFileInfoRec = record
    strict private
      vFullPath: string;
      vFileName: string;
      vFileIcon: hIcon;
    public
      constructor Create(const FullPath: string);
      property FullPath: string read vFullPath;
      property FileNam : string read vFileName;
      property FileIcon: hIcon read vFileIcon;
  end;

shGetFileInfo Apiを使用してアイコンハンドルを取得した後

procedure TMainFrm.VSTGetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer);
var
  FileInfo: PFileInfoRec;
  Icon: TIcon;
begin
  FileInfo := Sender.GetNodeData(Node);
  Icon := TIcon.Create;
  try
    Icon.Handle := FileInfo.FileIcon;
      if Kind in [ikNormal , ikSelected] then
      begin
        if Column = 1 then ImageIndex := ImageList.AddIcon(Icon);
      end;
  finally
    Icon.Free; //here the probelme
  end;
end;

Icon.Free; を削除するときに混乱するのは何ですか。コードは問題なく動作します アイコン付きのファイルが追加されましたが、無料の TIcon オブジェクトの場合、アイコンの追加は失敗します!! 誰でも私に説明してくださいこのコードの何が問題なのですか??

事前に助けてくれてありがとう...

4

1 に答える 1

1

まず、電話をかけるのをやめなければなりませImageList.AddIconOnGetImageIndex。アドバイスを詳しく繰り返すことはしませんが、以前の質問を参照してください

ここで起こっていることに関しては、これが起こっていることです:

  1. アイコン ハンドルを作成しますvFileIcon
  2. 次に、そのアイコンの所有権をTIconインスタンスに渡します。
  3. アイコン インスタンスを解放すると、アイコン ハンドルが削除されます。
  4. 次に を呼び出すOnGetImageIndexと、アイコン ハンドルvFileIconは破棄されたハンドルを参照するため、当然、そのアイコンを使用しようとすると失敗します。

このアイコンをイメージ リストに追加する最も簡単な方法は、インスタンスImageList_AddIconを作成するのではなく、使用することです。TIcon

FileInfo := Sender.GetNodeData(Node);
ImageList_AddIcon(ImageList.Handle, FileInfo.FileIcon);

インスタンスが破棄TIconされたときにハンドルを破棄せずに使用することは可能です。TIconを呼び出して、アイコン ハンドルを所有していないことをインスタンスReleaseHandleに伝えます。TIcon

Icon := TIcon.Create;
try
  Icon.Handle := SomeIconHandle;
  SomeImageIndex := ImageList.AddIcon(Icon);
  Icon.ReleaseHandle;
finally
  //because ReleaseHandle was called, this no longer destroys the icon handle
  Icon.Free;
end;
于 2012-06-23T15:23:39.273 に答える