home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1996 August / VPR9608A.BIN / del20try / install / data.z / RXMAIN.PAS < prev    next >
Pascal/Delphi Source File  |  1996-05-08  |  10KB  |  364 lines

  1. unit RXMain;
  2.  
  3. { This program provides an example of how to use the TreeView and ListView
  4.   components in a fashion similar to the Microsoft Windows Explorer.
  5.  
  6.   It is not intended to be a fully functional resource viewer. }
  7.  
  8. interface
  9.  
  10. uses
  11.   SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  12.   ExeImage, StdCtrls, Buttons, ExtCtrls, ComCtrls, Menus, RXMisc, HexDump;
  13.  
  14. type
  15.   TMainForm = class(TForm)
  16.     StatusBar: TStatusBar;
  17.     TreeViewPanel: TPanel;
  18.     Panel1: TPanel;
  19.     ImageViewer: TImage;
  20.     ListView: TListView;
  21.     TreeView: TTreeView;
  22.     Splitter: TPanel;
  23.     Notebook: TNotebook;
  24.     ListViewPanel: TPanel;
  25.     ListViewCaption: TPanel;
  26.     FileOpenDialog: TOpenDialog;
  27.     FileSaveDialog: TSaveDialog;
  28.     MainMenu: TMainMenu;
  29.     miFile: TMenuItem;
  30.     miFileExit: TMenuItem;
  31.     miFileSave: TMenuItem;
  32.     miFileOpen: TMenuItem;
  33.     miView: TMenuItem;
  34.     miViewStatusBar: TMenuItem;
  35.     miViewLargeIcons: TMenuItem;
  36.     miViewSmallIcons: TMenuItem;
  37.     miViewList: TMenuItem;
  38.     miViewDetails: TMenuItem;
  39.     miHelp: TMenuItem;
  40.     miHelpAbout: TMenuItem;
  41.     Small: TImageList;
  42.     Large: TImageList;
  43.     StringViewer: TMemo;
  44.     procedure FileExit(Sender: TObject);
  45.     procedure FileOpen(Sender: TObject);
  46.     procedure FormCreate(Sender: TObject);
  47.     procedure ListViewEnter(Sender: TObject);
  48.     procedure SaveResource(Sender: TObject);
  49.     procedure SelectListViewType(Sender: TObject);
  50.     procedure ShowAboutBox(Sender: TObject);
  51.     procedure ToggleStatusBar(Sender: TObject);
  52.     procedure TreeViewChange(Sender: TObject; Node: TTreeNode);
  53.     procedure SplitterMouseDown(Sender: TObject; Button: TMouseButton;
  54.       Shift: TShiftState; X, Y: Integer);
  55.     procedure SplitterMouseMove(Sender: TObject; Shift: TShiftState; X,
  56.       Y: Integer);
  57.     procedure SplitterMouseUp(Sender: TObject; Button: TMouseButton;
  58.       Shift: TShiftState; X, Y: Integer);
  59.     procedure ViewMenuDropDown(Sender: TObject);
  60.     procedure NotebookEnter(Sender: TObject);
  61.   private
  62.     FExeFile: TExeImage;
  63.     HexDump: THexDump;
  64.     SplitControl: TSplitControl;
  65.     procedure LoadResources(ResList: TResourceList; Node: TTreeNode);
  66.     procedure DisplayResources;
  67.     procedure UpdateViewPanel;
  68.     procedure UpdateListView(ResList: TResourceList);
  69.     procedure UpdateStatusLine(ResItem: TResourceItem);
  70.   end;
  71.  
  72. var
  73.   MainForm: TMainForm;
  74.  
  75. implementation
  76.  
  77. uses About, RXTypes;
  78.  
  79. {$R *.DFM}
  80. {$R RXIMAGES.RES}
  81.  
  82. const
  83.   itBitmap: TResType = Controls.rtBitmap; // Reference for duplicate identifier
  84.   ImageMap: array[TResourceType] of Byte = (2,4,5,3,2,2,2,2,2,2,2,2,2,2,2,2,2);
  85.   ResFiltMap: array[TResourceType] of Byte = (1,4,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1);
  86.  
  87.   SCopyright     = 'Copyright ゥ 1996 Borland International';
  88.   SNoResSelected = 'No resource selected';
  89.   SFormCaption   = 'Resource Explorer';
  90.   SSaveFilter    = 'Other Resource (*.*)|*.*|Bitmaps (*.BMP)|*.BMP|'+
  91.                    'Icons (*.ICO)|*.ICO|Cursor (*.CUR)|*.CUR';
  92.   SOpenFilter    = 'Executable File Images (*.EXE;*.DLL)|*.EXE;*.DLL|'+
  93.                    'All Files (*.*)|*.*';
  94.  
  95. { Utility Functions }
  96.  
  97. procedure Error(const ErrMsg: string);
  98. begin
  99.   raise Exception.Create(ErrMsg);
  100. end;
  101.  
  102. procedure ErrorFmt(const ErrMsg: string; Params: array of const);
  103. begin
  104.   raise Exception.Create(format(ErrMsg, Params));
  105. end;
  106.  
  107. function Confirm(const AMsg: String): Boolean;
  108. begin
  109.   Result := MessageDlg(AMsg, mtConfirmation, mbYesNoCancel, 0) = idYes;
  110. end;
  111.  
  112. { Non Event Handlers }
  113.  
  114. procedure TMainForm.LoadResources(ResList: TResourceList; Node: TTreeNode);
  115. var
  116.   I: Integer;
  117.   CNode: TTreeNode;
  118. begin
  119.   for I := 0 to ResList.Count - 1 do
  120.     with ResList[I] do
  121.     begin
  122.       CNode := TreeView.Items.AddChildObject(Node, Name, ResList[I]);
  123.       if IsList then
  124.       begin
  125.         CNode.SelectedIndex := 1;
  126.         LoadResources(List, CNode);
  127.       end else
  128.       begin
  129.         CNode.ImageIndex := ImageMap[ResList[I].ResType];
  130.         CNode.SelectedIndex := CNode.ImageIndex;
  131.       end;
  132.  
  133.     end;
  134. end;
  135.  
  136. procedure TMainForm.DisplayResources;
  137. begin
  138.   ListView.Items.Clear;
  139.   TreeView.Selected := nil;
  140.   TreeView.Items.Clear;
  141.   LoadResources(FExeFile.Resources, nil);
  142.   Caption := Format('%s - %s', [SFormCaption, LowerCase(FExeFile.FileName)]);
  143.   with TreeView do
  144.   begin
  145.     SetFocus;
  146.     Selected := Items[0];
  147.   end;
  148. end;
  149.  
  150. procedure TMainForm.UpdateViewPanel;
  151. var
  152.   R: TResourceItem;
  153. begin
  154.   with TreeView do
  155.   begin
  156.     if Visible and Assigned(Selected) then
  157.     begin
  158.       R := TResourceItem(Selected.Data);
  159.       if R.IsList then UpdateListView(R.List) else
  160.       begin
  161.         case R.ResType of
  162.           rtBitmap, rtIconEntry, rtCursorEntry:
  163.             begin
  164.               ImageViewer.Picture.Assign(R);
  165.               Notebook.PageIndex := 1;
  166.             end;
  167.           rtString, rtMenu:
  168.             begin
  169.               StringViewer.Lines.Assign(R);
  170.               StringViewer.SelStart := 0;
  171.               Notebook.PageIndex := 2;
  172.             end
  173.           else
  174.             begin
  175.               HexDump.Address := R.RawData;
  176.               HexDump.DataSize := R.Size;
  177.               Notebook.PageIndex := 3;
  178.             end;
  179.          end;
  180.       end;
  181.       UpdateStatusLine(R);
  182.     end;
  183.   end;
  184. end;
  185.  
  186. procedure TMainForm.UpdateListView(ResList: TResourceList);
  187. var
  188.   I: Integer;
  189. begin
  190.   ListView.Items.Clear;
  191.   for I := 0 to ResList.Count-1 do
  192.     with ResList[I], ListView.Items.Add do
  193.     begin
  194.       Data := ResList[I];
  195.       Caption := Name;
  196.       SubItems.Add(Format('%.7x', [Offset]));
  197.       SubItems.Add(Format('%.5x', [Size]));
  198.       ImageIndex := ImageMap[ResType];
  199.     end;
  200.   Notebook.PageIndex := 0;
  201. end;
  202.  
  203. procedure TMainForm.UpdateStatusLine(ResItem: TResourceItem);
  204. begin
  205.   if ResItem.IsList then
  206.   begin
  207.     ListViewCaption.Caption := ' '+TreeView.Selected.Text;
  208.     StatusBar.Panels[0].Text := Format(' %d object(s)', [ListView.Items.Count]);
  209.     StatusBar.Panels[1].Text := Format(' Offset: %x', [ResItem.Offset]);
  210.   end else
  211.   with ResItem do
  212.   begin
  213.     ListViewCaption.Caption := Format(' %s: %s', [ResTypeStr, Name]);
  214.     StatusBar.Panels[0].Text := '';
  215.     StatusBar.Panels[1].Text := Format(' Offset: %x  Size: %x', [Offset, Size]);
  216.   end;
  217. end;
  218.  
  219. { Form Initialization }
  220.  
  221. procedure TMainForm.FormCreate(Sender: TObject);
  222. begin
  223.   SplitControl := TSplitControl.Create(Self);
  224.   HexDump := CreateHexDump(TWinControl(NoteBook.Pages.Objects[3]));
  225.   FileOpenDialog.Filter := SOpenFilter;
  226.   FileSaveDialog.Filter := SSaveFilter;
  227.   Small.ResourceLoad(itBitmap, 'SmallImages', clOlive);
  228.   Large.ResourceLoad(itBitmap, 'LargeImages', clOlive);
  229.   Notebook.PageIndex := 0;
  230.   if (ParamCount > 0) and FileExists(ParamStr(1)) then
  231.   begin
  232.     Show;
  233.     FExeFile := TExeImage.Create(Self, ParamStr(1));
  234.     DisplayResources;
  235.   end;
  236. end;
  237.  
  238. { Menu Event Handlers }
  239.  
  240. procedure TMainForm.FileOpen(Sender: TObject);
  241. var
  242.   TmpExeFile: TExeImage;
  243. begin
  244.   with FileOpenDialog do
  245.   begin
  246.     if not Execute then Exit;
  247.     TmpExeFile := TExeImage.Create(Self, FileName);
  248.     if Assigned(FExeFile) then FExeFile.Destroy;
  249.     FExeFile := TmpExeFile;
  250.     DisplayResources;
  251.   end;
  252. end;
  253.  
  254. procedure TMainForm.FileExit(Sender: TObject);
  255. begin
  256.   Close;
  257. end;
  258.  
  259. procedure TMainForm.ListViewEnter(Sender: TObject);
  260. begin
  261.   with ListView do
  262.     if (Items.Count > 1) and (Selected = nil) then
  263.     begin
  264.       Selected := Items[0];
  265.       ItemFocused := Selected;
  266.     end;
  267. end;
  268.  
  269. procedure TMainForm.SaveResource(Sender: TObject);
  270. var
  271.   ResItem: TResourceitem;
  272.  
  273.   function TreeViewResourceSelected: Boolean;
  274.   begin
  275.     Result := Assigned(TreeView.Selected) and
  276.               Assigned(TreeView.Selected.Data) and
  277.               not TResourceItem(TreeView.Selected.Data).IsList;
  278.     if Result then ResItem := TResourceItem(TreeView.Selected.Data);
  279.   end;
  280.  
  281.   function ListViewResourceSelected: Boolean;
  282.   begin
  283.     Result := Assigned(ListView.Selected) and
  284.               Assigned(ListView.Selected.Data) and
  285.               not TResourceItem(ListView.Selected.Data).IsList;
  286.     if Result then ResItem := TResourceItem(ListView.Selected.Data);
  287.   end;
  288.  
  289. begin
  290.   if TreeViewResourceSelected or ListViewResourceSelected then
  291.   with FileSaveDialog do
  292.   begin
  293.     FilterIndex := ResFiltMap[ResItem.ResType];
  294.     if Execute then
  295.       ResItem.SaveToFile(FileName)
  296.   end
  297.   else
  298.     Error(SNoResSelected);
  299. end;
  300.  
  301. procedure TMainForm.SelectListViewType(Sender: TObject);
  302. begin
  303.   ListView.ViewStyle := TViewStyle(TComponent(Sender).Tag);
  304. end;
  305.  
  306. procedure TMainForm.ShowAboutBox(Sender: TObject);
  307. begin
  308.   About.ShowAboutBox;
  309. end;
  310.  
  311. procedure TMainForm.ToggleStatusBar(Sender: TObject);
  312. begin
  313.   StatusBar.Visible := not StatusBar.Visible;
  314. end;
  315.  
  316. procedure TMainForm.TreeViewChange(Sender: TObject; Node: TTreeNode);
  317. begin
  318.   UpdateViewPanel;
  319. end;
  320.  
  321. procedure TMainForm.ViewMenuDropDown(Sender: TObject);
  322. var
  323.   I: Integer;
  324. begin
  325.   miViewStatusBar.Checked := StatusBar.Visible;
  326.   for I := 0 to miView.Count-1 do
  327.     with miView.Items[I] do
  328.       if GroupIndex = 1 then
  329.         Checked := (Tag = Ord(ListView.ViewStyle));
  330. end;
  331.  
  332. procedure TMainForm.SplitterMouseDown(Sender: TObject;
  333.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  334. begin
  335.   if (Button = mbLeft) and (Shift = [ssLeft]) then
  336.     SplitControl.BeginSizing(Splitter, TreeViewPanel);
  337. end;
  338.  
  339. procedure TMainForm.SplitterMouseMove(Sender: TObject; Shift: TShiftState;
  340.   X, Y: Integer);
  341. begin
  342.   with SplitControl do if Sizing then ChangeSizing(X, Y);
  343. end;
  344.  
  345. procedure TMainForm.SplitterMouseUp(Sender: TObject; Button: TMouseButton;
  346.   Shift: TShiftState; X, Y: Integer);
  347. begin
  348.   with SplitControl do if Sizing then EndSizing;
  349. end;
  350.  
  351. procedure TMainForm.NotebookEnter(Sender: TObject);
  352. var
  353.   Page: TWinControl;
  354. begin
  355.   with NoteBook do
  356.   begin
  357.     Page := TWinControl(Pages.Objects[PageIndex]);
  358.     if (Page.ControlCount > 0) and (Page.Controls[0] is TWinControl) then
  359.       TWinControl(Page.Controls[0]).SetFocus;
  360.   end;
  361. end;
  362.  
  363. end.
  364.