Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Articles
Search: 

An easy way to distribute small binary files
Gérald Santerre, January 14, 2002
The type of small binary file that come to mind was the cursor files. These littles files that we must copy somewhere on the user machine during install. If you have icons or bitmaps, it's not a problem, the files can be build into the executable. But the cursor must reside on the disk somewhere nea...
Summary
The type of small binary file that come to mind was the cursor files. These littles files that we must copy somewhere on the user machine during install. If you have icons or bitmaps, it's not a problem, the files can be build into the executable. But the cursor must reside on the disk somewhere near the exe. This was the @beep*&% little binary that i always remember to add to the installation after the build of the install disks.
Description
The type of small binary file that come to mind was the cursor files. These littles files that we must copy somewhere on the user machine during install. If you have icons or bitmaps, it's not a problem, the files can be build into the executable. But the cursor must reside on the disk somewhere near the exe. This was the @beep*&% little binary that i always remember to add to the installation after the build of the install disks. What can i do to insert the cursor in my exe? Nothing, but i can create the file on the user computer using STRTOFILE() at run time. It's only a matter of taking the contain of the file and place it on the code. Try the following code, it create the hand cursor (link.cur) on the default directory:
*put the bin/chars in a string
cBinFile=REPLICATE(CHR(0),2)+CHR(2)+CHR(0)+CHR(1)+CHR(0);
	+REPLICATE(CHR(32),2)+CHR(2)+CHR(0)+CHR(5)+REPLICATE(CHR(0),3);
	+"0"+CHR(1)+REPLICATE(CHR(0),2)+CHR(22)+REPLICATE(CHR(0),3);
	+CHR(40)+REPLICATE(CHR(0),3)+CHR(32)+REPLICATE(CHR(0),3);
	+"@"+REPLICATE(CHR(0),3)+CHR(1)+CHR(0)+CHR(1);
	+REPLICATE(CHR(0),6)+CHR(1)+REPLICATE(CHR(0),10);
	+CHR(2)+REPLICATE(CHR(0),11)+REPLICATE(CHR(255),3);
	+REPLICATE(CHR(0),45)+CHR(3)+CHR(252)+REPLICATE(CHR(0),2);
	+CHR(3)+CHR(252)+REPLICATE(CHR(0),2)+CHR(7)+CHR(254);
	+REPLICATE(CHR(0),2)+CHR(7)+CHR(254)+REPLICATE(CHR(0),2);
	+CHR(15)+CHR(254)+REPLICATE(CHR(0),2)+CHR(15)+CHR(255);
	+REPLICATE(CHR(0),2)+CHR(31)+CHR(255)+REPLICATE(CHR(0),2);
	+CHR(31)+CHR(255)+REPLICATE(CHR(0),2)+"7"+CHR(255);
	+REPLICATE(CHR(0),2)+"w"+CHR(255)+REPLICATE(CHR(0),2);
	+"g"+CHR(251)+REPLICATE(CHR(0),2)+CHR(6)+CHR(219);
	+REPLICATE(CHR(0),2)+CHR(6)+CHR(218)+REPLICATE(CHR(0),2);
	+CHR(6)+CHR(216)+REPLICATE(CHR(0),2)+CHR(6)+CHR(192);
	+REPLICATE(CHR(0),2)+CHR(6)+REPLICATE(CHR(0),3);
	+CHR(6)+REPLICATE(CHR(0),3)+CHR(6)+REPLICATE(CHR(0),3);
	+CHR(6)+REPLICATE(CHR(0),3)+CHR(6)+REPLICATE(CHR(0),7);
	+REPLICATE(CHR(255),40)+CHR(248)+CHR(1)+REPLICATE(CHR(255),2);
	+CHR(248)+CHR(1)+REPLICATE(CHR(255),2)+CHR(248)+CHR(1);
	+REPLICATE(CHR(255),2)+CHR(240)+CHR(0)+REPLICATE(CHR(255),2);
	+CHR(240)+CHR(0)+REPLICATE(CHR(255),2)+CHR(224)+CHR(0);
	+REPLICATE(CHR(255),2)+CHR(224)+CHR(0)+CHR(127)+CHR(255);
	+CHR(192)+CHR(0)+CHR(127)+CHR(255)+CHR(192)+CHR(0)+CHR(127);
	+CHR(255)+CHR(128)+CHR(0)+CHR(127)+CHR(255)+REPLICATE(CHR(0),2);
	+CHR(127)+CHR(255)+REPLICATE(CHR(0),2)+CHR(127)+CHR(255);
	+CHR(16)+CHR(0)+CHR(127)+CHR(255)+CHR(240)+CHR(0)+REPLICATE(CHR(255),2);
	+CHR(240)+CHR(1)+REPLICATE(CHR(255),2)+CHR(240)+CHR(7);
	+REPLICATE(CHR(255),2)+CHR(240)+"?"+REPLICATE(CHR(255),2);
	+CHR(240)+REPLICATE(CHR(255),3)+CHR(240)+REPLICATE(CHR(255),3);
	+CHR(240)+REPLICATE(CHR(255),3)+CHR(240)+REPLICATE(CHR(255),3);
	+CHR(249)+REPLICATE(CHR(255),3)
*Create the file on the disk
STRTOFILE(cBinFile,"link.cur")
Remember that the contain was binary and can not be cut and pasted directly into a prg. This is why the code contain a large amount of CHR() in it. This code can be created by hand, but the task was overkill for the time it can save on the distribution disk creation (re-creation). That's why i want to share this little prg utility with you. This program take a file path as parameter, create the code and place the output on the _CLIPTEXT variable. Run it and paste the code in your own program.
*function bintocode
************************
*	take a file as input and generate the
*    vfp code to write back the file to disk
*	output to _cliptext
*
*	this can be used to create bin files
*	on the fly. ie a mouse cursor file
*	or a small BMP
*
************************
lparam inputfile
local pos,i,fhandle,nfsize,cOutput,cChar,cNextChar,nLineChars,curLen,nLastChar,nOccurs

* cut the line with a ";"+chr(13)+CHR(9) when this value was reached
nLineChars=50

*no error msg, just return .f.
if !file(inputfile)
	return .f.
endif
*open the file
fhandle=fopen(inputfile)
if fhandle=-1
	return .f.
endif
*--
nfSize =  FSEEK(fhandle, 0, 2) && eof
cOutPut=""
curLen=0
nLastChar=-1
nOccurs=0

FSEEK(fHandle, 0, 0)  && bof
*read the file char by char
FOR pos=0 TO nfSize-1
	FSEEK(fHandle, pos, 0)
	cChar=FREAD(fHandle,1)
	IF ASC(cChar) = nLastChar
		*repeated char
		nOccurs=nOccurs+1		
		LOOP &&NEXT && pos
	ELSE
		IF curlen > nLineChars  
			*new line
			cOutput=cOutput+[;]+CHR(13)+CHR(9)
			lStringOpen=.F.
			curLen=0
		ENDIF
		*new char
		IF nOccurs > 1
			*write ntimes the same char
			cOutput=cOutput+"+REPLICATE(CHR("+;
			ALLTRIM(STR(nLastChar))+"),"+ALLTRIM(STR(nOccurs))+")"
			curlen=curlen+23
		ENDIF
		nOccurs=1 
		nLastChar = ASC(cChar)
		* test the next to see if it is a repeated char, loop if .t.
		IF pos < nfSize-2
			FSEEK(fHandle, pos+1, 0)
			cNextChar=FREAD(fHandle,1)
			IF ASC(cChar)=ASC(cNextChar)
				LOOP &&NEXT pos
			ENDIF
		ENDIF	
	ENDIF
	IF curlen > nLineChars  
		*new line
		cOutput=cOutput+[;]+CHR(13)+CHR(9)
		lStringOpen=.F.
		curLen=0 
	ENDIF
	cOutput=cOutput+"+CHR("+ALLTRIM(STR(ASC(cChar)))+")"
	curlen=curlen+8
ENDFOR
IF nOccurs > 1
	*write ntimes the same char
	cOutput=cOutput+"+REPLICATE(CHR("+;
	ALLTRIM(STR(nLastChar))+"),"+ALLTRIM(STR(nOccurs))+")"
ENDIF
*close the source file
FCLOSE(fHandle)

*replace CHR(n) by the printable character for some values
FOR i=48 TO 122
	cOutPut=STRTRAN(cOutPut, "CHR("+ALLTRIM(STR(i))+")",["]+CHR(i)+["])
ENDFOR
*shorten the lines again if one printable char follow another one
cOutPut=STRTRAN(cOutPut, ["+"],[])

*create the code, strip out the first "+" and copy to clipboard
cOutPut=[*put the bin/chars in a string]+CHR(13)+[cBinFile=]+SUBSTR(cOutPut,2)+;
	CHR(13)+[*Create the file on the disk]+CHR(13)+[STRTOFILE(cBinFile,"]+inputfile+[")]

_CLIPTEXT=  cOutPut

RETURN .T.
*---------------------
Of course, the code generated by this utility can be optimized (for repeating series of chars), but the intend of this utility was to generate code to recreate file on the user machiche and it does it! An alternative can be the use of a binary memo to hold the cursor and do the same thing in 3 lines of code.
select mytable
cCursorFile=myTable.BinMemo
STRTOFILE(cursorFile,"link.cur")
But where is the fun in this? :-)
Gérald Santerre, Gerald Santerre enrg.
Gérald Santerre joined the Universal Thread team in November 2001. After the completion of his programming course, he began working for a small shop with FoxPro Windows. A couple of months later, Microsoft launched Visual FoxPro 3 and he started his journey in the world of OOP. He worked for the National Bank of Canada Intranet doing Web programming with VFP. Since January 2001, he became self employed and he has designed some applications for the Nortel Network's, Bombardier's Intranet site and for other customers as well. He is always open to new contract opportunities, so feel free to contact him!
More articles from this author
Gérald Santerre, February 1, 2002
Gérald Santerre, from the Universal Thread, has interviewed Whil Hentzen, from Hentzenwerke Corporation in mid January. We initiated some topics on the company, the Visual FoxPro book publishing and the Great Lakes Great Database Workshop conference. Who is Whil Hentzen? (Looking over shou...
Gérald Santerre, February 1, 2002
Gérald Santerre, from the Universal Thread, has interviewed Claudio Lassala, from FoxTotal Network in mid January. Claudio Lassala joined the Universal Thread team in January 2002. He has been recently awarded as a VFP MVP. He is involved in various areas such as being the co-editor of the UTMag/Rap...
Gérald Santerre, January 1, 2001
Cet article est un extrait de ce que vous pouvez trouver sur ma home page http://www.total.net/~gersan. Ce site est avant tout un site maison, il est sans prétentions. Si vous y trouvez quelque chose qui vous intéresse, prenez le! BTW, it's all in french!
Gérald Santerre, March 25, 1998
This drawa a partial circle or pie in Visual FoxPro. You can pass the current positions of the center of the circle to trace, the radius of the circle, the start angle, the width of the angle to draw, the line width and a parameter to detect if you want to draw a pie or not.
Gérald Santerre, March 1, 2002
Gérald Santerre, from the Universal Thread, has interviewed John Petersen, president and founder of Main Line Software, Inc., a Philadelphia, Pennsylvania based software application and database design firm. MLSI development platforms include Visual FoxPro, Visual Basic, Access, and SQL-Server in mi...
Gérald Santerre, June 1, 2002
As you may have noticed, Microsoft has recently launched a new community program named ".Net Code Wise Community". Universal Thread has been chosen as a founding member of this program. It was in this context that we have interviewed Josh Levine, the Business Development Manager for MSCOM who helped...
Gérald Santerre, January 1, 2002
Monday, 31 December 2001, I was on my way to go to the new year party with my wife's family and I read a mail from Michel, between other things I see this little sentence: "BTW, have you prepared your profile for the UT Magazine?". Duh! Pardon?... "Sorry, I have send a mes...
Gérald Santerre, June 22, 1997
To start the default web browser and load a location(web page) you can use the Win API function ShellExecute().
Gérald Santerre, June 1, 2002
You spent a lot of time on the Universal Thread on a regular basis. You have noticed that the site is always on evolution. But, do you know who is behind the scene to constantly enhance your experience online? Who is Michel Fournier? After having graduated in computer science in 1987, I m...