Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to loading an exe in a memo field Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
04-Jun-03
Category
Reporting /Printing
Language
Delphi 2.x
Views
109
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Teun Spaans

How can I read a binary file? 
How can I show a binary file in a memo field? 

Answer:

Solve 1:

Why?

This article has been written in answer to an old request by ismael u, asking how 
an executable can be loaded in a memo or rich memo field.

First a remark, executables should usually not be stored in a tmemo field, but 
rather in some blob field. However, there are some occasions on which one would 
like to view an executable. Studying (differences between) compiled  executables 
comes to mind.

I assume that Ismael means executable when he says exec, and the solution is rather 
simple. 

How?

Loading a an executable in a memo field basically comes down to 2 steps. The first 
step is reading the file from disk and loading the file into memory, the second 
step is showing the loaded contents in the tmemo field. 

The first step, reading the file from disk and loading it into memory, is rather 
easy. Perhaps TFileStream could be used, but I prefer the rather low level FileOpen 
function because of its performance. Also, when working with binary files, we must 
keep in mind that these files may contain #0 and many pointer based operations 
regard this as an end/of/string character.

Basically, here is the code, mostly a copy of the delphi5 help after fixing some 
minor bugs. Just create a form, add a button and a fileopendialog, 
1        
2   procedure TForm1.Button1Click(Sender: TObject);
3   var
4     iFileHandle: Integer;
5     iFileLength: Integer;
6     iBytesRead: Integer;
7     Buffer: PChar;
8   begin
9     opendialog1.filter := 'executables|*.exe';
10    if opendialog1.Execute then
11    begin
12      try
13        iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone);
14        if iFileHandle > 0 then
15        begin
16          iFileLength := FileSeek(iFileHandle, 0, 2);
17          FileSeek(iFileHandle, 0, 0);
18          Buffer := PChar(AllocMem(iFileLength + 2));
19          iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength);
20            // note that ^ is missing in D5 help.
21          FileClose(iFileHandle);
22        end;
23      finally
24        FreeMem(Buffer);
25      end;
26    end;
27  end;

     
The second step again poses us some questions. As the contents of the binary file 
will contain #0, how will we show them?

The first way is to convert the entire Buffer read above into a string and add this 
string to the memo. Doing this causes no technical problem, but the memo shows just 
a few characters. That's probably now what we want. The cause are the 
aforementioned #0 characters.

The second way is to go through the Buffer bit by bit, and switch to a new line 
whenever we encounter a #0. Doing so is easy, and reveals that an ordinary 
executable contains lots of #0 characters.

The third and probably best way is to show all characters in a hexagonal notation. 
28     
29  procedure TForm1.Button1Click(Sender: TObject);
30  var
31    iFileHandle: Integer;
32    iFileLength: Integer;
33    iBytesRead: Integer;
34    Buffer: PChar;
35    i, linelength: integer;
36    s: string;
37    line: string;
38    c: char;
39    ordval, ordval1, ordval2: integer;
40  begin
41    opendialog1.filter := 'executables|*.exe';
42    if opendialog1.Execute then
43    begin
44      try
45        iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone);
46        if iFileHandle > 0 then
47        begin
48          iFileLength := FileSeek(iFileHandle, 0, 2);
49          FileSeek(iFileHandle, 0, 0);
50          Buffer := PChar(AllocMem(iFileLength + 2));
51          iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength);
52          // note that ^ is missing in D5 help.
53          // 3 ways of conversion and show:
54          // way 1: exe will contain \0 so this code shows only part of exe
55          memo1.lines.add('way 1*********************************************');
56          s := string(Buffer);
57          memo1.lines.add(s);
58          // way 2: use \0 as newline for purpose of displaying in memo1.
59          memo1.lines.add('way 2*********************************************');
60          LineLength := 0;
61          Line := '';
62          for i := 0 to iFileLength - 1 do
63          begin
64            if Buffer[i] = #0 then
65            begin
66              memo1.lines.add(Line);
67              LineLength := 0;
68              Line := '';
69            end
70            else
71            begin
72              inc(LineLength);
73                // perhaps provision should be added for LineLength > max 
74  							delphi stringlength
75              Line := Line + Buffer[i]; // memo1 will handle normal new line chars
76            end;
77          end;
78          // way 3: display every char as ord
79          memo1.lines.add('way 3*********************************************');
80          Line := '';
81          for i := 0 to iFileLength - 1 do
82          begin
83            c := Buffer[i];
84            ordval := ord(c);
85            ordval1 := ordval div 16;
86            ordval2 := ordval mod 16;
87            Line := Line + '0123456789ABCDEF'[ordval1 + 1] + 
88  '0123456789ABCDEF'[ordval2             + 1];
89            if Length(Line) = 80 then
90            begin
91              memo1.lines.add(line);
92              line := '';
93            end;
94          end;
95          FileClose(iFileHandle);
96        end;
97      finally
98        FreeMem(Buffer);
99      end;
100   end;
101 end;



Solve 2:

There is an inbuild delphi function (which I think appears in pre delphi 5) 

BinToHex(Buffer, Text: PChar; BufSize: Integer);

which would create an output buffer in hex format. 

 

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC