📄 uresource.pas
字号:
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 + -