⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileviewer.pas

📁 Jedi Code Library JCL JVCL 组件包 JCL+JVCL超过300个组件的非可视/可视大型组件包。
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit FileViewer;

{$I JCL.INC}

{.$DEFINE UsePeImagesCache}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ExtCtrls, Menus, JclPeImage;

type
  TFileViewerChild = class(TForm)
    DependencyTreeView: TTreeView;
    Splitter1: TSplitter;
    ListViewsPanel: TPanel;
    Splitter2: TSplitter;
    ImportListView: TListView;
    ExportListView: TListView;
    PopupMenu1: TPopupMenu;
    Copy1: TMenuItem;
    Save1: TMenuItem;
    N1: TMenuItem;
    Selectall1: TMenuItem;
    Win32helpkeyword1: TMenuItem;
    ModulesListView: TListView;
    Splitter3: TSplitter;
    DumpPEfile1: TMenuItem;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure ExportListViewData(Sender: TObject; Item: TListItem);
    procedure ImportListViewData(Sender: TObject; Item: TListItem);
    procedure ExportListViewColumnClick(Sender: TObject;
      Column: TListColumn);
    procedure ImportListViewColumnClick(Sender: TObject;
      Column: TListColumn);
    procedure FormDestroy(Sender: TObject);
    procedure DependencyTreeViewChange(Sender: TObject; Node: TTreeNode);
    procedure DependencyTreeViewDeletion(Sender: TObject; Node: TTreeNode);
    procedure ModulesListViewInfoTip(Sender: TObject; Item: TListItem;
      var InfoTip: String);
    procedure ExportListViewDblClick(Sender: TObject);
    procedure ModulesListViewDblClick(Sender: TObject);
  private
    FAnyRootError: Boolean;
    FBasePath: string;
    FCurrentImportDirIndex: Integer;
    FFileName: TFileName;
    FModulesList: TStringList;
    FExportViewImage, FParentImportViewImage: TJclPeImage;
    FPeImagesCache: TJclPeImagesCache;
    function GetModuleName: string;
    procedure SetFileName(const Value: TFileName);
    procedure ExportListViewSort;
    function ModuleToFileName(const ModuleName: string): TFileName;
    procedure ImportListViewSort;
    procedure InitTree;
    function IsListViewActiveAndFocused( ListView: TListView): Boolean;
    procedure UpdateExportView(Node: TTreeNode);
    procedure UpdateModulesView;
    procedure UpdateParentImportView(Node: TTreeNode);
    class procedure UpdateSortData(Column: TListColumn);
    function GetSelectedFileName: TFileName;
  public
    function GetWin32Function: string;
    property FileName: TFileName read FFileName write SetFileName;
    property ModuleName: string read GetModuleName;
    property SelectedFileName: TFileName read GetSelectedFileName;
  end;

var
  FileViewerChild: TFileViewerChild;

implementation

uses DependViewMain, ToolsUtils, JclSysInfo, JclStrings, JclFileUtils;

{$R *.DFM}

type
  TPeModuleState = (
    modNoErrors,             // Normal module with no errors.
    modFwdNoErrors,          // Forwarded module with no errors.
    modDupNoErrors,          // Duplicate module with no errors.
    modDupFwdNoErrors,       // Forwarded duplicate module with no errors.
    modExportMissing,        // Module with one or more missing export functions
    modFwdExportMissing,     // Forwarded module with one or more missing export functions
    modDupExportMissing,     // Duplicate module with one or more missing export functions
    modDupFwdExportMissing,  // Forwarded duplicate module with one or more missing export functions
    modMissing,              // Missing module.
    modFwdMissing,           // Missing forwarded module.
    modInvalid,              // Invalid module.
    modFwdInvalid,           // Invalid forwarded module.
    modRoot                  // Root node.
    );

  TPeModuleImageInfo = record
    ImageIndex, StateIndex: Integer;
  end;

  PPeModuleNodeData = ^TPeModuleNodeData;
  TPeModuleNodeData = record
    State: TPeModuleState;
    ImportDirectoryIndex: Integer;
  end;

const
  imgModule               =  0;
  imgDupModule            =  1;
  imgModExportMissing     =  2;
  imgDupExportMissing     =  3;
  imgMissingModule        =  4;
  imgInvalidModule        =  5;
  imgForwardFlag          =  6;
  imgRoot                 =  7;
  imgExport               =  8;
  imgFwdExport            =  9;
  imgImport               = 10;
  imgUnresolvedImport     = 11;
  imgSortAsceding         = 12;
  imgSortDesceding        =  3;

  ErrorModules = [modMissing, modFwdMissing, modInvalid, modFwdInvalid];
  MissingExportModules = [modExportMissing, modFwdExportMissing, modDupExportMissing,
    modDupFwdExportMissing, modMissing, modFwdMissing, modInvalid, modFwdInvalid];
  ForwardedModules = [modFwdNoErrors, modDupFwdNoErrors, modFwdExportMissing,
    modDupFwdExportMissing];

  ModuleImages: array[TPeModuleState] of TPeModuleImageInfo = (
    (ImageIndex: imgModule; StateIndex: -1),
    (ImageIndex: imgModule; StateIndex: imgForwardFlag),
    (ImageIndex: imgDupModule; StateIndex: -1),
    (ImageIndex: imgDupModule; StateIndex: imgForwardFlag),
    (ImageIndex: imgModExportMissing; StateIndex: -1),
    (ImageIndex: imgModExportMissing; StateIndex: imgForwardFlag),
    (ImageIndex: imgDupExportMissing; StateIndex: -1),
    (ImageIndex: imgDupExportMissing; StateIndex: imgForwardFlag),
    (ImageIndex: imgMissingModule; StateIndex: -1),
    (ImageIndex: imgMissingModule; StateIndex: imgForwardFlag),
    (ImageIndex: imgInvalidModule; StateIndex: -1),
    (ImageIndex: imgInvalidModule; StateIndex: imgForwardFlag),
    (ImageIndex: imgRoot; StateIndex: -1)
  );

{ TFileViewerChild }

procedure TFileViewerChild.FormCreate(Sender: TObject);
begin
  FModulesList := TStringList.Create;
  FModulesList.Sorted := True;
  FModulesList.Duplicates := dupIgnore;
  FExportViewImage := TJclPeImage.Create;
  FPeImagesCache := TJclPeImagesCache.Create;
{$IFNDEF UsePeImagesCache}
  FParentImportViewImage := TJclPeImage.Create;
{$ENDIF}
  FCurrentImportDirIndex := -1;
  ExportListView.Height := ListViewsPanel.ClientHeight div 2;
  ImportListView.Tag := $100;
  UpdateSortData(ImportListView.Columns[0]);
  ExportListView.Tag := $100;
  UpdateSortData(ExportListView.Columns[0]);
  ModulesListView.Columns[0].Width := ColumnTextWidth;
end;

procedure TFileViewerChild.FormDestroy(Sender: TObject);
begin
  FModulesList.Free;
  FExportViewImage.Free;
  FPeImagesCache.Free;
{$IFNDEF UsePeImagesCache}
  FParentImportViewImage.Free;
{$ENDIF}
end;

procedure TFileViewerChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Fix_ListViewBeforeClose(Self);
  Action := caFree;
end;

function TFileViewerChild.GetModuleName: string;
begin
  Result := ExtractFileName(FFileName);
end;

procedure TFileViewerChild.InitTree;
var
  RootNode: TTreeNode;

  procedure SetNodeState(Node: TTreeNode; State: TPeModuleState);
var
  I: Integer;
begin
  PPeModuleNodeData(Node.Data)^.State := State;
  Node.ImageIndex := ModuleImages[State].ImageIndex;
  Node.SelectedIndex := ModuleImages[State].ImageIndex;
  Node.StateIndex := ModuleImages[State].StateIndex;
  if State in (MissingExportModules + ErrorModules) then
  begin
    if Node.Parent = RootNode then FAnyRootError := True;
    I := FModulesList.IndexOf(Node.Text);
    Assert(I >= 0);
    FModulesList.Objects[I] := Pointer(State);
  end;
end;

  function AddNode(Node: TTreeNode; const Text: string; State: TPeModuleState): TTreeNode;
var
  Data: PPeModuleNodeData;
begin
  Result := DependencyTreeView.Items.AddChild(Node, Text);
  New(Data);
  Result.Data := Data;
  SetNodeState(Result, State);
end;

  procedure ScanModule(const ModuleName: string; Node: TTreeNode; Forwarded, ErrorsOnly: Boolean);
var
  ExeImage: TJclPeImage;
  I, Found: Integer;
  S: string;
  TempNode: TTreeNode;
  AddedNodes: array of TTreeNode;
  AddedNodesCount: Integer;
begin
  ExeImage := FPeImagesCache[ModuleToFilename(ModuleName)];
  case ExeImage.Status of
    stOk:
      if not ErrorsOnly then
      begin
        with ExeImage.ImportList do
        begin
          SetLength(AddedNodes, Count);
          AddedNodesCount := 0;
          CheckImports(FPeImagesCache);
          SortList(ilName);
          for I := 0 to Count - 1 do
          begin
            S := Items[I].Name;
            Found := FModulesList.IndexOf(S);
            if Found = -1 then
            begin
              Found := FModulesList.Add(S);
              FModulesList.Objects[Found] := Pointer(modNoErrors);
              if Items[I].TotalResolveCheck = icUnresolved then
                TempNode := AddNode(Node, S, modExportMissing)
              else
                TempNode := AddNode(Node, S, modNoErrors);
              AddedNodes[AddedNodesCount] := TempNode;
              Inc(AddedNodesCount);
            end else
            begin
              if Items[I].TotalResolveCheck = icUnresolved then
                TempNode := AddNode(Node, S, modDupExportMissing)
              else
                TempNode := AddNode(Node, S, modDupNoErrors);
              ScanModule(TempNode.Text, TempNode, False, True); // !
            end;
            PPeModuleNodeData(TempNode.Data)^.ImportDirectoryIndex := Items[I].ImportDirectoryIndex;
          end;
        end;
        for I := 0 to AddedNodesCount - 1 do
          ScanModule(AddedNodes[I].Text, AddedNodes[I], False, False);
        with ExeImage.ExportList do
        begin
          CheckForwards(FPeImagesCache);
          for I := 0 to ForwardedLibsList.Count - 1 do
          begin
            S := ForwardedLibsList[I];
            Found := FModulesList.IndexOf(S);
            if Found = -1 then
            begin
              Found := FModulesList.Add(S);
              FModulesList.Objects[Found] := Pointer(modNoErrors);
              if TJclPeResolveCheck(ForwardedLibsList.Objects[I]) = icUnresolved then
                AddNode(Node, S, modFwdExportMissing)
              else
                AddNode(Node, S, modFwdNoErrors);
            end else
            begin
              if TJclPeResolveCheck(ForwardedLibsList.Objects[I]) = icUnresolved then
                TempNode := AddNode(Node, S, modDupFwdExportMissing)
              else
                TempNode := AddNode(Node, S, modDupFwdNoErrors);
              ScanModule(TempNode.Text, TempNode, True, True); // !
            end;
          end;
        end;
      end;
    stNotFound:
      if Forwarded then SetNodeState(Node, modFwdMissing) else SetNodeState(Node, modMissing);
  else
     if Forwarded then SetNodeState(Node, modFwdInvalid) else SetNodeState(Node, modInvalid);
  end;
end;

begin
  with DependencyTreeView do
  begin
    Items.BeginUpdate;
    try
      Items.Clear;
      Screen.Cursor := crHourGlass;
      RootNode := AddNode(nil, ModuleName, modRoot);
      FModulesList.AddObject(ModuleName, Pointer(modRoot));
      ScanModule(FFileName, RootNode, False, False);
      RootNode.Expand(False);
      Selected := RootNode;
    finally
      Items.EndUpdate;
      Screen.Cursor := crDefault;
    end;
  end;
  UpdateModulesView;
{$IFNDEF UsePeImagesCache}
  FPeImagesCache.Clear;
{$ENDIF}
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -