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

📄 uresource.pas

📁 在delphi中实现windows核心编程.原书光盘代码核心编程.原书光盘代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit UResource;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls, ComCtrls, Menus, RXMisc, UHexDump,
  ImgList,UResourceFunction,UPEConst,TypInfo,math;

type
  TfrmResource = class(TForm)
    StatusBar: TStatusBar;
    TreeViewPanel: TPanel;
    Panel1: TPanel;
    ImageViewer: TImage;
    ListView: TListView;
    Splitter: TPanel;
    Notebook: TNotebook;
    ListViewPanel: TPanel;
    ListViewCaption: TPanel;
    FileSaveDialog: TSaveDialog;
    MainMenu: TMainMenu;
    miFile: TMenuItem;
    miFileExit: TMenuItem;
    miFileSave: TMenuItem;
    miView: TMenuItem;
    miViewStatusBar: TMenuItem;
    miViewLargeIcons: TMenuItem;
    miViewSmallIcons: TMenuItem;
    miViewList: TMenuItem;
    miViewDetails: TMenuItem;
    miHelp: TMenuItem;
    miHelpAbout: TMenuItem;
    Large: TImageList;
    StringViewer: TMemo;
    Small: TImageList;
    TreeView: TTreeView;
    procedure FileExit(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ListViewEnter(Sender: TObject);
    procedure SaveResource(Sender: TObject);
    procedure SelectListViewType(Sender: TObject);
    procedure ToggleStatusBar(Sender: TObject);
    procedure TreeViewChange(Sender: TObject; Node: TTreeNode);
    procedure SplitterMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SplitterMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure SplitterMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ViewMenuDropDown(Sender: TObject);
    procedure NotebookEnter(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    HexDump: THexDump;
    Base:pointer;
    ResourceRVA:DWORD;
    ResourceBase:PImageResourceDirectory;
    SplitControl: TSplitControl;
    procedure LoadResources(ResourceDirectory:PImageResourceDirectory; Node: TTreeNode; ParentResType:TResourceType);
    procedure ExtractIconCursorLink;
    procedure UpdateViewPanel;
    procedure UpdateListView(TreeNode: TTreeNode);
  end;

var
  frmResource: TfrmResource;

implementation

uses UMain;

{$R *.DFM}

const
  itBitmap: TResType = ImgList.rtBitmap;
  ImageExt: array[0..MAXResourceType-1] of string = ('', '.CUR', '.BMP', '.ICO', '', '', '', '', '', '', '', '', '', '', '', '', '');
  ResFiltMap: array[0..MAXResourceType-1] of Byte = (1, 4, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);


{进行递归调用,读取PE文件中的所有资源,
第一次调用此函数时,因为是第一级资源,所以ResList=FExeFile.Resources, Node=nil}
procedure TfrmResource.LoadResources(ResourceDirectory:PImageResourceDirectory; Node: TTreeNode; ParentResType:TResourceType);
var
  I,J: Integer;
  CNode: TTreeNode;
  CNodeCaption:string;
  ResourceDirectoryEntry:PImageResourceDirectoryEntry;
  ResType: TResourceType;
  CursorData: PCursorResInfo;
  IconData: PIconResInfo;
  RawData:pointer;
begin
  ResourceDirectoryEntry:=PImageResourceDirectoryEntry(DWORD(ResourceDirectory)+sizeof(TImageResourceDirectory));
  for I := 0 to ResourceDirectory^.NumberOfIdEntries + ResourceDirectory^.NumberOfNamedEntries - 1 do
  begin
      ResType:=ParentResType;
      CNodeCaption:=ResourceGetName(ResourceDirectoryEntry,ResType);
      if ResType=rtFirstEntry then ResType:=rtUnknown0;
      //Node是当前节点,Name是资源或目录的名称(Bitmap),ResList[I]是当前资源指针,它是一个树状的结构
      CNode := TreeView.Items.AddChildObject(Node, CNodeCaption, ResourceDirectoryEntry);
      if ResourceIsDirectory(ResourceDirectoryEntry) then
      begin {如果它存放的不是数据,则表示它是目录}
         CNode.ImageIndex := rtDirectory;
         CNode.SelectedIndex := rtDirectorySelected;  //设置节点被选择时的图标
         LoadResources(PImageResourceDirectory(StripHighBit(ResourceDirectoryEntry^.OffsetToData)+DWORD(ResourceBase)), CNode, ResType); {递归调用,把下级的资源列出来}
      end
      else {如果不是目录}
      begin
        CNode.ImageIndex := ResType; //根据资源的类型选择不同的图标
        CNode.SelectedIndex := ResType; //设置节点被选择时的图标
        if ResType = rtCursor then
        begin
           CNode.ImageIndex := rtDirectory;
           CNode.SelectedIndex := rtDirectorySelected;  //设置节点被选择时的图标
           RawData:=ResourceRawData(ResourceDirectoryEntry);
           CursorData := PCursorResInfo(DWORD(RawData) + SizeOf(TIconHeader));
           for J := 0 to PIconHeader(RawData)^.wCount - 1 do
           begin
              CNodeCaption := inttostr(CursorData.wNameOrdinal);
              with TreeView.Items.AddChildObject(CNode, CNodeCaption, CursorData) do
              begin
                 ImageIndex := rtCursorLink;
                 SelectedIndex := rtCursorLink;
              end;
              Inc(CursorData); //
           end;
        end
        else if ResType = rtIcon then
        begin
           CNode.ImageIndex := rtDirectory;
           CNode.SelectedIndex := rtDirectorySelected;  //设置节点被选择时的图标
           RawData:=ResourceRawData(ResourceDirectoryEntry);
           IconData := PIconResInfo(DWORD(RawData) + SizeOf(TIconHeader));
           for J := 0 to PIconHeader(RawData)^.wCount - 1 do
           begin
              CNodeCaption := inttostr(IconData.wNameOrdinal);
              with TreeView.Items.AddChildObject(CNode, CNodeCaption, IconData) do
              begin
                 ImageIndex := rtIconLink;
                 SelectedIndex := rtIconLink;
              end;
              Inc(IconData);
           end;
        end;
      end;
      inc(ResourceDirectoryEntry);
  end;
end;

procedure TfrmResource.ExtractIconCursorLink;
var
   i:integer;
   TreeNode,CursorList,IconList:TTreeNode;
   function FindListTreeNode(ResType:TResourceType):TTreeNode;
   var
      t:TTreeNode;
   begin
      t:=Treeview.Items[0];
      repeat begin
         if t.Text=ResourceTypeName[ResType] then
         begin
            result:=t;
            exit;
         end;
         t:=t.GetNext;
      end until t=nil;
      result:=nil;
   end;
   function FindTreeNode(CursorIconList:TTreeNode;Name:string):TTreeNode;
   var
      t:TTreeNode;
   begin
      result:=nil;
      if CursorIconList=nil then exit;
      t:=CursorIconList.getFirstChild;
      while t<>nil do
      begin
         if t.Text=Name then
         begin
            result:=t;
            exit;
         end;
         t:=t.GetNext;
      end;
   end;
begin
   if TreeView.Items.count=0 then exit;
   CursorList:=FindListTreeNode(rtCursorEntry);
   IconList:=FindListTreeNode(rtIconEntry);
   for i:=0 to TreeView.Items.Count-1 do
   begin
      if TreeView.Items[i].ImageIndex=rtCursorLink then
      begin
         TreeNode:=FindTreeNode(CursorList,TreeView.Items[i].Text);
         if TreeNode<>nil then
         with TreeView.Items[i] do
         begin
            with PCursorResInfo(Data)^ do
               Text := Format('%d X %d %d Bit(s)', [wWidth, wWidth, wBitCount]);
            Data:=TreeNode.Data;
            ImageIndex:=TreeNode.ImageIndex;
            SelectedIndex:=TreeNode.SelectedIndex;
         end;
      end;
      if TreeView.Items[i].ImageIndex=rtIconLink then
      begin
         TreeNode:=FindTreeNode(IconList,TreeView.Items[i].Text);
         if TreeNode<>nil then
         with TreeView.Items[i] do
         begin
            with PIconResInfo(Data)^ do
               Text := Format('%d X %d %d Colors', [bWidth, bHeight, trunc(power(2,wBitCount))]);
            Data:=TreeNode.Data;                 
            ImageIndex:=TreeNode.ImageIndex;
            SelectedIndex:=TreeNode.SelectedIndex;
         end;
      end;
   end;
   if CursorList<>nil then
   begin
      CursorList.DeleteChildren;
      Treeview.Items.Delete(CursorList);
   end;
   if IconList<>nil then
   begin
      IconList.DeleteChildren;
      Treeview.Items.Delete(IconList);
   end;
end;

procedure TfrmResource.UpdateViewPanel;
var
  ResourceDirectoryEntry: PImageResourceDirectoryEntry;
  MemStream: TMemoryStream;
  ResType:TResourceType;
  S:string;
begin
  with TreeView do
  begin
    if Visible and Assigned(Selected) then

⌨️ 快捷键说明

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