Mini Kabibi Habibi

Current Path : C:/Users/ITO/Desktop/VF9/program files/microsoft visual foxpro 9/tools/hexedit/
Upload File :
Current File : C:/Users/ITO/Desktop/VF9/program files/microsoft visual foxpro 9/tools/hexedit/hexedit.sct

�VERSION =   3.00dataenvironmentdataenvironmentDataenvironmentaTop = 237
Left = 159
Width = 749
Height = 364
DataSource = .NULL.
Name = "Dataenvironment"
12formsetformsetHexeditDataSession = 2
AutoRelease = .T.
csearchstring = 
nsearchdirection = 1
nsearchfrom = 2
npointerlocation = 0
nfiletoedit = 0
ctemptable = 
nnumberofbytes = 0
ndesiredlocation = 0
chighlightarrayname = 
coldcompat = 
coldonesca = 
coldsetesca = 
nfilesize = 0
ncolnum = 0
chexarrayname = 
cfindstrhname = 
cfindstrname = 
lformsetlostfocus = .T.
Name = "Hexedit"
_�PROCEDURE reportfileerror
nFileErrorNumber = FERROR()

#DEFINE ERR_LOC "File Error: "

DO CASE
CASE nFileErrorNumber = 2
	#DEFINE MSG_2_LOC "File not found."
	cMessageText = ERR_LOC + MSG_2_LOC
	
CASE nFileErrorNumber = 4
	#DEFINE MSG_4_LOC "Out of file handles"
	cMessageText = ERR_LOC + MSG_4_LOC
	
CASE nFileErrorNumber = 5
	#DEFINE MSG_5_LOC "Access denied."
	cMessageText = ERR_LOC + MSG_5_LOC
	
CASE nFileErrorNumber = 6
	#DEFINE MSG_6_LOC "Invalid file handle. (programmer error)."
	cMessageText = ERR_LOC + MSG_6_LOC
	
CASE nFileErrorNumber = 8
	#DEFINE MSG_8_LOC "Out of memory."
	cMessageText = ERR_LOC + MSG_8_LOC
	
CASE nFileErrorNumber = 25
	#DEFINE MSG_25_LOC "File seek error."
	cMessageText = ERR_LOC + MSG_25_LOC
	
CASE nFileErrorNumber = 29
	#DEFINE MSG_29_LOC "Disk is full."
	cMessageText = ERR_LOC + MSG_29_LOC
	
CASE nFileErrorNumber = 31
	#DEFINE MSG_31_LOC "Error opening file."
	cMessageText = ERR_LOC + MSG_31_LOC
	
OTHERWISE
	#DEFINE MSG_OTHER_LOC "Unexpected file I/O condition."
	cMessageText = MSG_OTHER_LOC
ENDCASE

=MESSAGEBOX(cMessageText)

ENDPROC
PROCEDURE fillhexarray
** Create two-digit hex array to speed translation of data sectors.
LOCAL aHexFF[256]
FOR zzz = 0 to 255
	aHexFF[zzz + 1] = RIGHT(TRANSFORM(zzz, "@0"), 2)
ENDFOR
=ACOPY(aHexFF, THISFORMSET.aTwoDigitHexArray)
RETURN
ENDPROC
PROCEDURE filltable
PARAM nLastRow, nBytesInLastRow, nptrLocation, cWorkString

** Make local copy of Hex translation array, to speed translation.
LOCAL aHexFF[256]
=ACOPY(THISFORMSET.aTwoDigitHexArray, aHexFF)


LOCAL aFileData[nLastRow + 1, 18]
aFileData = "  "	&& Clear array, so don't get "F" put into empty cells in table (uninitialized members).

**  Loop to translate ascii into hex.
**  Everything in the loop is optimized as much as possible, since each line is called
**  128 times, and the statements in the inner loop are executed 2048 times.
FOR nRow = 0 to nLastRow	
	nLastByte = IIF(nRow != nLastRow, 16, nBytesInLastRow)	&& Last byte in current row.
															&& Will always be 16 bytes,
	nRowByte = (nRow * 16) + 1								&& Byte # of first byte in 

	**	Calculate Address of current row.
	nASCII = nptrlocation + nRowByte - 1
	
	**  Translate address into Hex.
	aFileData[nRow+1,1] = RIGHT(TRANSFORM(nASCII,"@0"), 8)				&& Pad Address column to 8 characters.


	** Copy current row of data into a smaller string.
	** (Working with a 16 byte string is faster than with a 2K string.)
	cTempString1 = SUBSTR(cWorkString, nRowByte, nLastByte)
	
	**  Translate ASCII data to Hex, and fill in appropriate columns in data array.
	FOR nColumn = 1 to nLastByte	&& nLastByte will be 16 except at end of file.
		** Use array of two-digit hex instead of translation function to increase speed.
		aFileData[nRow + 1, nColumn + 1] = aHexFF[ASC(SUBSTR(cTempString1, nColumn,1)) + 1]	
	NEXT

	** Put actual text into last column of array.
	aFileData[nRow + 1, 18] = cTempString1
NEXT

** Store translated data into table, so can be displayed in grid.
INSERT INTO HEXEDIT FROM ARRAY aFileData

ENDPROC
PROCEDURE setgridhighlights
PARAM nFirstStringColumn, nStringLength, nFoundRowNumber

**  The DynamicBackColor properties of the grid columns need to be evaluated
**  for every visible cell in the grid, every time the grid is
**  refreshed.  Therefore, it is important that the DynamicBackColor function
**  is kept as short and optimized as possible.
**  The format of the setting will be:
**        =IIF(RECNO() = n, GREY, WHITE)
**  The numbers for the record number, and the colors, will be hardwired in
**  (instead of calling RGB() for each visible cell in the grid).



cStartString = "IIF(RECNO() = "
WITH THISFORMSET.HexEditor.grdData
cEndString = ", " + STR(RGB(192,192,192)) + "," + STR(.BackColor) + ")"

FOR nCurrentCol = 1 to 16		&& Search string limited to 15 chars, so don't need to
								&& worry about highlighting more than 1 row in a column.
	IF nCurrentCol < nFirstStringColumn		&& If column is before the start of the
											&& string on current row.
		IF nCurrentCol < (nStringLength - (16 - nFirstStringcolumn))
												&& See if string wraps around to 
												&& current column in next row.
			nHighLightRow = nFoundRowNumber + 1
		ELSE
			nHighLightRow = 0					&& Current column is not highlighted.
		ENDIF
	ELSE									&& current column is after the first character 
											&& of the string on the current row.
		IF nCurrentCol < (nFirstStringColumn + nStringLength)	&& If before the end of the
																&&  string.
			nHighLightRow = nFoundRowNumber	&& Cell is highlighted in this row.
		ELSE
			nHighLightRow = 0				&& Column is not highlighted.
		ENDIF
	ENDIF
	IF nHighLightRow > 0					&& If current column requires a DynamicBackColor
											&& property.
		.COLUMNS(nCurrentCol+1).DynamicBackcolor = cStartString + STR(nHighLightRow,3,0) + cEndString
	ELSE									&& Otherwise, clear previous contents.
		.COLUMNS(nCurrentCol+1).DynamicBackcolor = ""
	ENDIF	
NEXT
ENDWITH
THISFORMSET.lStringHighlighted = .T.


ENDPROC
PROCEDURE writesector
PARAMETER lWriteImmediately

#DEFINE APP_NAME_LOC			"HexEdit"
#DEFINE WRITE_CHANGES_LOC		"Sector has been edited.  Write changes to disk?"
#DEFINE PROGRAM_ERR_LOC			"Program error."
#DEFINE LOST_FILE_HANDLE_LOC	"Cannot access file.  Aborting program."

IF SELECT("HexEdit") = 0 OR ;
		(THISFORMSET.nFileToEdit > 0 AND NOT FFLUSH(THISFORMSET.nFileToEdit))
	** User has closed files.  This form is not modal, so must handle case of CLOSE ALL
	** while form is open.
	=messagebox(LOST_FILE_HANDLE_LOC, 48, APP_NAME_LOC)
	RELEASE THISFORMSET
	CANCEL
ENDIF


IF !THISFORMSET.lSectorDirty
	IF GetNextModified(0, "HEXEDIT") != 0		&& If no records are buffered
		*  User clicked in textbox, but did not edit.
		=TableRevert(.T., "HEXEDIT")
		THISFORMSET.HexEditor.cmdSaveEdits.ENABLED = .F.
		THISFORMSET.HexEditor.cmdRevertEdits.ENABLED = .F.
	ENDIF
	RETURN .T.		&& Calling method may proceed to change sector, quit, open new file, etc.
ENDIF

IF lWriteImmediately
	nUserChoice = 6
ELSE
	nUserChoice = MESSAGEBOX(WRITE_CHANGES_LOC, 3+48, APP_NAME_LOC)
ENDIF

DO CASE
CASE nUserChoice = 6	&& Yes, write changes
	*Write edited information to disk
	*nPointerLocation is already at the start of our current sector
	*so just need to write the data.
	
	=TableUpdate(.T.,.F., "HEXEDIT")		&& Write changes to disk, so next revert doesn't
											&& revert these changes.
	THISFORMSET.lSectorDirty = .F.
	THISFORMSET.HexEditor.cmdSaveEdits.ENABLED = .F.		&& Disable buttons.
	THISFORMSET.HexEditor.cmdRevertEdits.ENABLED = .F.

	** Actually write the data here.  First determine exactly how much data to write.
	nLastRow = RECCOUNT("HEXEDIT")
	nBytesInLastRow = MOD(THISFORMSET.nNumberOfBytes - 1,16) + 1	&& If 16, returns 16 instead of 0.
	SELE HEXEDIT
	GO TOP
	cWorkString = ""
	
	** Compile all data into a single string.
	FOR nRow = 1 TO nLastRow
		IF nRow != nLastRow
			cWorkString = cWorkString + HEXEDIT.Text
		ELSE
			cWorkString = cWorkString + SUBSTR(HEXEDIT.Text,1,nBytesInLastRow)	&& Don't want spaces from empty cells
																				&& in case at end of file.
		ENDIF
		SKIP
	NEXT
	
	**  Write string out to file.
	nBytesWritten = FWRITE(THISFORMSET.nFileToEdit, cWorkString, THISFORMSET.nNumberOfBytes)
	nPointerLocation = FSEEK(THISFORMSET.nFileToEdit, THISFORMSET.nPointerLocation, 0)
	
	IF nBytesWritten != THISFORMSET.nNumberOfBytes
		THISFORMSET.ReportFileError
		RETURN .F.
	ENDIF		
	RETURN .T.

CASE nUserChoice = 7	&& No, discard changes
	=TableRevert(.T., "HEXEDIT")
	THISFORMSET.lSectorDirty = .F.
	THISFORMSET.HexEditor.cmdSaveEdits.ENABLED = .F.
	THISFORMSET.HexEditor.cmdRevertEdits.ENABLED = .F.
	RETURN .T.
CASE nUserChoice = 2	&& Cancel
	* Leave lSectorDirty the way it was, so user can write changes on next attempt.
	RETURN .F.
OTHERWISE
	** Should never get here.
	=messagebox(PROGRAM_ERR_LOC)
	RETURN .F.
ENDCASE

ENDPROC
PROCEDURE cleargridhighlights
*  Remove the DynamicForecolor functions from the grid columns.
*  This method is called when reading in a new sector, if a string
*  has been highlighted.
THISFORMSET.HexEditor.grdData.SetAll("DynamicBackColor","")
THISFORMSET.lStringHighlighted = .F.

ENDPROC
PROCEDURE dec2hex
PARAMETER nDecimal, nDigits
**  Converts from base 10 to base 16.  Returns Hex notation in a string whose length
**  is always at least 2.  The nDigits parameter can be specified to pad the
**  string with zeroes.

IF PARAMETERS() = 2
	RETURN RIGHT(TRANSFORM(nDecimal, "@0"), IIF(nDigits <= 8, nDigits, 8))
ENDIF

*  If no second parameter, must determine correct number of digits.
nExponent = 2	&& Always return at least two characters.
DO WHILE nExponent < 9
	IF nDecimal <= (16^nExponent)
		RETURN RIGHT(TRANSFORM(nDecimal, "@0"), nExponent)
	ENDIF
	nExponent = nExponent + 1
ENDDO
ENDPROC
PROCEDURE findstring
LPARAMETERS cStringToFind, nSearchDirection, nSearchFrom, lCaseSen

#DEFINE STRING_NOT_FOUND_LOC	"String not found."
#DEFINE SEARCH_STATUS_LOC		"Search Status:"
#DEFINE PRESS_ESCAPE_LOC		"Press [Escape] to cancel."

WITH THISFORMSET

* Set starting location for search.
DO CASE
CASE nSearchFrom = 1				&& Search from top of file
	nSearchLocation = 0
CASE nSearchFrom = 2				&& Search from current location
	nSearchLocation = .nPointerLocation + ((RECNO() - 1)*16);
						+ IIF(.nColNum = 0, 1, .nColNum - 1)
CASE nSearchFrom = 3				&& Search from bottom of file.
	nSearchLocation = .nFileSize
ENDCASE


nBytesToSearch = 2048	&& Read in 2K first time.  Increased to 16k on second read.
nLargerBufferSize = 16384
lEscapePressed = .F.

.HexEditor.MousePointer = 11		&& Change mousepointer to hourglass.
nStartTime = SECONDS()

DO CASE
CASE nSearchDirection = 1			&&	Search forwards.
	DO WHILE .T.
		IF SECONDS() > nStartTime + 1	&& Update status every second.
			nStartTime = SECONDS()
			* Mouse events aren't processed while code is being executed.  For better visual
			* effect, will force mousepointer back to hourglass in case user has moved mouse 
			* off VFP window and returned:
			.HexEditor.MousePointer = 11
			WAIT WINDOW SEARCH_STATUS_LOC + " " + STR((nSearchLocation/.nFileSize)*100,3,0) + "%";
			 + CHR(13) + PRESS_ESCAPE_LOC NOWAIT
		ENDIF
		**  Set file pointer to start of search area.
		nSearchLocation = FSEEK(.nFileToEdit, nSearchLocation, 0)
		**  Read in segment.
		cSeekWorkString = FREAD(.nFileToEdit, nBytesToSearch + LEN(cStringToFind)-1)

		IF lCaseSen = .T.								&& Look for string
			nStringLocation = AT(cStringToFind, cSeekWorkString)
		ELSE
			nStringLocation = ATC(cStringToFind, cSeekWorkString)
		ENDIF

		IF nStringLocation = 0							&& If string not found
			IF lEscapePressed							&& If user pressed escape
				.HexEditor.MousePointer = 0
				WAIT CLEAR
				RETURN									&& exit search function
			ENDIF
			IF LEN(cSeekWorkString) < nBytesToSearch	&& If at EOF().
				?? CHR(7)								&& Beep
				WAIT WINDOW STRING_NOT_FOUND_LOC NOWAIT	&& Inform user, then set file pointer back.
				.nPointerLocation=FSEEK(.nFileToEdit, .nPointerLocation, 0)	&& Return pointer to original location.
				.HexEditor.MousePointer = 0
				RETURN
			ELSE
				** If not at eof(), continue search.
				nSearchLocation = nSearchLocation + nBytesToSearch
				nBytesToSearch = nLargerBufferSize	&& Increase search buffer size
			ENDIF
		ELSE	&& Found string!!
			EXIT
		ENDIF
	ENDDO
				
CASE nSearchDirection = 2	&&	Search backwards.
	DO WHILE .T.
		IF SECONDS() > nStartTime + 1	&& Update status every second.
			nStartTime = SECONDS()
			.HexEditor.MousePointer = 11
			WAIT WINDOW SEARCH_STATUS_LOC + " " + STR((nSearchLocation/.nFileSize)*100,3,0) + "%";
			 + CHR(13) + PRESS_ESCAPE_LOC  NOWAIT
		ENDIF
		** Position file pointer and read in data.
		nBytesToSearch = IIF(nSearchLocation > nBytesToSearch, nBytesToSearch, nSearchLocation - 1)
		nSearchLocation = FSEEK(.nFileToEdit, nSearchLocation - nBytesToSearch - 1, 0)	&& jump to search start location.
					&& nSearchLocation now points to end of next search string.
		cSeekWorkString = FREAD(.nFileToEdit, nBytesToSearch + LEN(cStringToFind) - 1)	&& read in segment.
		
		** Do search
		IF lCaseSen = .T.
			nStringLocation = RAT(cStringToFind, cSeekWorkString)
		ELSE
			&& There is no case-insensitive RAT function, so must simulate.
			nStringLocation = RAT(UPPER(cStringToFind), UPPER(cSeekWorkString))
		ENDIF
		
		IF nStringLocation = 0							&& If string not found
			IF lEscapePressed							&& If user pressed escape.
				.HexEditor.MousePointer = 0
				WAIT CLEAR
				RETURN									&& exit search function
			ENDIF
			IF nSearchLocation = 0					&& If at BOF().
				??	CHR(7)								&& Beep.
				WAIT WINDOW STRING_NOT_FOUND_LOC NOWAIT
				*  Return file pointer to last known coordinates.
				.nPointerLocation=FSEEK(.nFileToEdit, .nPointerLocation, 0)	&& Return pointer to original location.
				.HexEditor.MousePointer = 0
				RETURN
			ELSE									
				&& If not at BOF(), continue search.
				nBytesToSearch = nLargerBufferSize	&& Increase search buffer size
			ENDIF
		ELSE	&& Found string!!
			EXIT
		ENDIF
	ENDDO
ENDCASE

WAIT CLEAR

** If we are here, we have found the desired string.
** Now load sector into grid (if necessary), and highlight appropriate cells in grid.

IF (nSearchLocation + nStringLocation) < (.nPointerLocation + 2048)	;
	AND (nSearchLocation + nStringLocation > .nPointerLocation)

	** String is in current sector. Calculate nFirstStringCell (offset to
	** first letter of string) with respect to current sector.
	nFirstStringCell = (nSearchLocation + nStringLocation) - .nPointerLocation
ELSE
	*  Load in new sector.
	nDesiredLocation = INT((nSearchLocation + nStringLocation)/1024) * 1024	&& go to next 1k boundary.
	nFirstStringCell = nSearchLocation + nStringLocation - nDesiredLocation

	** Position file pointer at start of desired sector.
	.nPointerLocation = FSEEK(.nFileToEdit, nDesiredLocation, 0)
	.ReadSector(0, .T.)		&& Read data into table, leaving screen locked.
ENDIF

.HexEditor.LOCKSCREEN = .T.		&& turn off screen updates temporarily.

** Calculate row (in current table) that first character is in.
nFoundRowNumber = INT((nFirstStringCell - 1)/ 16) + 1
SELECT HEXEDIT
GOTO nFoundRowNumber					&& move there, so found string will be visible.
*.lGridWasScrolled = .T.		&& Turn off THISFORMSET.readsector optimization

** Now set the highlight color.  We already know where the first cell is.  
nFirstStringColumn = (MOD(nFirstStringCell - 1,16) + 1)
.SetGridHighlights(nFirstStringColumn, LEN(cStringToFind), nFoundRowNumber)
ENDWITH

WITH THISFORMSET.HexEditor
.grdData.REFRESH	
.MousePointer = 0

** Set focus to first character in string
.grdData.COLUMNS(MOD(nFirstStringCell - 1,16) + 1 + 1).SETFOCUS

.LOCKSCREEN = .F.			&& Allow screen refreshes to happen.

ENDWITH
ENDPROC
PROCEDURE readsector
PARAMETER nDirection, lLeaveScreenLocked

#DEFINE R_LOST_FILE_HANDLE_LOC	"Cannot access file.  Aborting program."
#DEFINE R_APP_NAME_LOC			"HexEdit"

*  Check access to file.
IF NOT FFLUSH(THISFORMSET.nFileToEdit) OR SELECT("HexEdit") = 0
	* User has issued a CLOSE ALL. We're in trouble.
	=messagebox(R_LOST_FILE_HANDLE_LOC, 48, R_APP_NAME_LOC)
	RELEASE THISFORMSET
	RETURN
ENDIF

** Position file pointer at start of new sector.
WITH THISFORMSET
DO CASE
CASE nDirection = 0		&& Read current sector
	* 	Do nothing.
	*   This param is only used when already FSEEKing in the file, so don't need
	*   to worry whether or not user has issued a CLOSE ALL from the command window.
CASE nDirection = 1		&& Read next sector
	nOldLocation = .nPointerLocation
	.nPointerLocation = FSEEK(.nFileToEdit, 2048,1)	&& move 2k relative to current position.
	IF FEOF(.nFileToEdit)
		** If at end of file, move file pointer back where it was.
		.nPointerLocation = FSEEK(.nFileToEdit, nOldLocation,0)	
		RETURN
	ENDIF

CASE nDirection = -1	&& Read previous sector
	IF .nPointerLocation <= 1
		** There is no previous sector.
		RETURN
	ELSE	&& Not at very top
		IF .nPointerLocation < 2048
			** Within 2k of top of file.  Move pointer to top of file.
			.nPointerLocation = FSEEK(.nFileToEdit, 0,0)
		ELSE	&& Not within 1 sector of top
			nOldLocation = .nPointerLocation
			** move 2k relative to current position.
			.nPointerLocation = FSEEK(.nFileToEdit, -2048,1)	
			IF .nPointerLocation < 0
				** If cannot move pointer for some unknown reason, put back where it was.
				.nPointerLocation = FSEEK(.nFileToEdit, nOldLocation,0)	&&Move back where it was.
			ENDIF
		ENDIF 	&& within 1 sector of top
	ENDIF
ENDCASE

**************************************************************************
*** File pointer is now positioned.  Read sector into grid.

IF .lStringHighlighted
	.ClearGridHighlights		&& Turn off highlights of "found" strings.
ENDIF

.HexEditor.LockScreen = .T.	&& Turn off screen updates while working.
					
cWorkString = FREAD(.nFileToEdit, 2048)		&& Moves pointer, but nPointerLocation still pointing at beginning of sector.
IF LEN("cWorkString") = 0		&& If user closed files.
	=messagebox(R_LOST_FILE_HANDLE_LOC, 48, R_APP_NAME_LOC)
	RELEASE THISFORMSET			&& Will close all tables in the Unload event.
	CANCEL
ENDIF

IF FEOF(.nFileToEdit)		&& If last sector, handle smaller amt of data
	.nNumberOfBytes = LEN(cWorkString)
	nLastRow = CEILING(.nNumberOfBytes/16) - 1
	nBytesInLastRow = MOD(.nNumberOfBytes - 1,16) + 1	&& If 16, returns 16 instead of 0.

	.HexEditor.cmdNextSector.ENABLED = .F.
	.HexEditor.cmdBottomOfFile.ENABLED = .F.
ELSE
	.nNumberOfBytes = 2048
	nLastRow = 127
	nBytesInLastRow = 16

	.HexEditor.cmdNextSector.ENABLED = .T.
	.HexEditor.cmdBottomOfFile.ENABLED = .T.
ENDIF


IF .nPointerLocation = 0		&& If pointer was at 0 before read
	.HexEditor.cmdPreviousSector.ENABLED = .F.
	.HexEditor.cmdTopOfFile.ENABLED = .F.
ELSE
	.HexEditor.cmdPreviousSector.ENABLED = .T.
	.HexEditor.cmdTopOfFile.ENABLED = .T.
ENDIF

=TableRevert(.T., "HEXEDIT")			&& revert any changes (should never be any at this point).
=CursorSetProp("BUFF", 1, "HEXEDIT")	&& Turn buffering off to zap table.

ZAP	IN HEXEDIT							&& Clear table for next sector of data.


**  Read data into grid.
=.Filltable(nLastRow, nBytesInLastRow, .nPointerLocation, cWorkString)

**  Now move file pointer back to start of current sector.
.nPointerLocation = FSEEK(.nFileToEdit, -.nNumberOfBytes, 1)	&& Return pointer to start of sector.


GO TOP IN HEXEDIT
=CursorSetProp("BUFF", 5, "HEXEDIT")			&& Turn buffering back on.

.HexEditor.grdData.REFRESH
IF .HexEditor.grdData.ActiveColumn > 0	&& focus is in grid.
	.HexEditor.grdData.Columns(.Hexeditor.grdData.ActiveColumn).SetFocus
ENDIF

*  Allow all the refreshes to happen (unless called by THISFORMSET.FindString).
IF !lLeaveScreenLocked
	.HexEditor.LockScreen = .F.
ENDIF
ENDWITH
ENDPROC
PROCEDURE hex2dec
*********************************************
*	Hex2Dec:	Translates Hex (in a string) to
* 				a decimal
*	Returns:	Numeric
*********************************************
LParameters cDigits
RETURN EVALUATE("0x" + ALLTRIM(cDigits))
ENDPROC
PROCEDURE checkkeystroke
PARAMETER nKeyCode
DO CASE
	CASE nKeyCode = 31	&& Ctrl + PgUp
		THISFORMSET.HexEditor.cmdPreviousSector.CLICK
	CASE nKeyCode = 30	&& Ctrl + PgDn
		THISFORMSET.HexEditor.cmdNextSector.CLICK
	CASE nKeyCode = 29	&& Ctrl + Home
		THISFORMSET.HexEditor.cmdTopOfFile.CLICK
	CASE nKeyCode = 23	&& Ctrl + End
		THISFORMSET.HexEditor.cmdBottomOfFile.CLICK
	CASE nKeyCode = -2	&& F3
		IF THISFORMSET.HexEditor.cmdFindNext.Enabled
			NODEFAULT
			THISFORMSET.HexEditor.cmdFindNext.Click
		ENDIF
	CASE nKeyCode = 86	&& Shift+F3
		IF THISFORMSET.HexEditor.cmdFindPrevious.Enabled
			NODEFAULT
			THISFORMSET.HexEditor.cmdFindPrevious.Click
		ENDIF

	OTHERWISE
		RETURN
ENDCASE

ENDPROC
PROCEDURE Load
WITH THISFORMSET

.FillHexArray

*  ON ESCAPE, SET ESCAPE and SET COMPAT are set in the Activate/Deactivate events.
*  The following are scoped to the form's datasession, so can set them once and not
*  worry about restoring them.
set talk off
SET SAFETY OFF
SET CONFIRM OFF
SET MULTI ON
SET EXCLUSIVE ON


.nPointerLocation = 0
.nFileToEdit = 0
.lSectorDirty = .F.
.nColNum = 0

*  Create table to be displayed in the grid.
SELE 0
.cTempTable = SYS(2023) + "\" + SUBSTR(SYS(2015), 3, 10) + ".TMP"
CREATE TABLE (.cTempTable) (Address c(8), B1 c(2), B2 c(2), B3 c(2), ;
		B4 c(2), B5 c(2), B6 c(2), B7 c(2), B8 c(2), B9 c(2), B10 c(2), B11 c(2),;
		B12 c(2), B13 c(2), B14 c(2), B15 c(2), B16 c(2), Text c(16))

USE (.cTempTable) EXCLUSIVE ALIAS "HEXEDIT"
=CURSORSETPROP('BUFFERING', 5, "HEXEDIT")

** Create tables for use in the FindStr form.
SELE 0
.cFindStrName = SYS(2023) + "\" + SUBSTR(SYS(2015), 3, 10) + ".TMP"
CREATE TABLE (.cFindStrName) (C1 C(1) ,C2 C(1) ,C3 C(1) ,C4 C(1)  , ;
				C5 C(1) ,C6 C(1) ,C7 C(1) ,C8 C(1) ,C9 C(1) ,C10 C(1) , ;
				C11 C(1) ,C12 C(1) ,C13 C(1) ,C14 C(1) ,C15 C(1)  )
USE (.cFindStrName) ALIAS "FindStr"
APPEND BLANK
=CURSORSETPROP('BUFFERING', 5, "FindStr")

SELE 0
.cFindStrHName = SYS(2023) + "\" + SUBSTR(SYS(2015), 3, 10) + ".TMP"
CREATE TABLE (.cFindStrHName) (C1 C(2),C2 C(2),C3 C(2),C4 C(2),C5 C(2),C6 C(2),C7 C(2),C8 C(2),C9 C(2),C10 C(2),C11 C(2),C12 C(2),C13 C(2),C14 C(2),C15 C(2) )
CREATE TABLE (.cFindStrHName) (C1 C(2) ,C2 C(2) ,C3 C(2) ,C4 C(2)  , ;
				C5 C(2) ,C6 C(2) ,C7 C(2) ,C8 C(2) ,C9 C(2) ,C10 C(2) , ;
				C11 C(2) ,C12 C(2) ,C13 C(2) ,C14 C(2) ,C15 C(2)  )
USE (.cFindStrHName) ALIAS "FindStrH"
APPEND BLANK
=CURSORSETPROP('BUFFERING', 5, "FindStrH")

ENDWITH
ENDPROC
PROCEDURE Unload
WITH THISFORMSET

IF SELECT("HEXEDIT") > 0
	=TableRevert(.T., "HEXEDIT")
	=CursorSetProp("BUFF", 1, "HEXEDIT")	&& Turn off table buffering.
	USE IN "HEXEDIT"
ENDIF
IF FFLUSH(.nFileToEdit)	&& Can access file.
	=FCLOSE(.nFileToEdit)
ENDIF

DELETE FILE (.cTempTable)


IF SELECT("FindStr") > 0
	USE IN "FindStr"
ENDIF
IF SELECT("FindStrH") > 0
	USE IN "FindStrH"
ENDIF

DELETE FILE (.cFindStrName)
DELETE FILE (.cFindStrHName)

*IF "HEXED.VCX" $ SET("CLASSLIB")
*	RELEASE CLASSLIB HEXED.VCX
*ENDIF
ENDWITH

RELEASE THISFORMSET
ENDPROC
PROCEDURE Deactivate
WITH THISFORMSET

.lFormsetLostFocus = .T.

** Set environment back the way it was before this app got focus.
cOldCompat = .cOldCompat
IF !ISBLANK(cOldCompat)			&& If old values were stored, 
	SET COMPAT &cOldCompat		&& set environment to old values.

	cOldEscape = .cOldOnEsca
	ON ESCAPE &cOldEscape

	cOldSetEscape = .cOldSetEsca
	SET ESCAPE &cOldSetEscape

	cOldBell = .cOldBell
	SET BELL &cOldBell

	=INSMODE(.lOldInsmode)
ENDIF
ENDWITH

** Don't let other programs (or command window) print into this window.
ACTIVATE SCREEN		

ENDPROC
PROCEDURE Activate
**  Store current environment settings.
WITH THISFORMSET
IF .lFormsetLostFocus
	.lFormsetLostFocus = .F.
	.cOldOnEsca = ON('Escape')
	.cOldSetEsca = SET('Escape')
	.lOldInsmode = INSMODE()
	.cOldBell = SET('BELL')
	.cOldCompat = SET("COMPAT")

	** Set environment to desired settings.
	ON ESCAPE lEscapePressed = .T.
	SET ESCAPE ON
	SET COMPAT OFF
	=INSMODE(.F.)	&& Turn on OverWrite mode.
	SET BELL OFF
ENDIF
ENDWITH
* THISFORMSET.Refresh()
** The DEACTIVATE event sets all the environment settings back
** the way they were, so user can switch from this app to another
** without causing problems.
ENDPROC
PROCEDURE Init
PARAMETER cFileToLoad

IF TYPE('cFileToLoad') != 'C'
*RETURN
	#DEFINE PICK_LOC "Choose a file to open in HexEdit."
	WAIT WINDOW PICK_LOC NOWAIT NOCLEAR
	*  Open the file.
	DO WHILE ! THISFORMSET.HexEditor.cmdFile.Click(cFileToLoad, .T.)
		*  Loop in case file selected was zero-length.
	ENDDO

	THISFORMSET.HexEditor.grdData.Recordsource = "HexEdit"

ELSE
	*  If filename passed from command line, just try once to open file.
	 THISFORMSET.HexEditor.cmdFile.Click(cFileToLoad, .T.)
ENDIF

WAIT CLEAR

*  If we couldn't open a file, exit.
IF THISFORMSET.nFileToEdit = 0
	RELEASE THISFORMSET
	CANCEL	&& Prevent continuation of form load.
ENDIF
ENDPROC
0G�� .0.0/%*�.�]+�UeT��C���
H��R������V�,T���File Error: �File not found.���������0T���File Error: �Out of file handles���������+T���File Error: �Access denied.�������)�ET���File Error: �(Invalid file handle. (programmer error).�������e�+T���File Error: �Out of memory.���������-T���File Error: �File seek error.���������*T���File Error: �
Disk is full.��������0T���File Error: �Error opening file.��2�R�+T���Unexpected file I/O condition.�����C��x��UNFILEERRORNUMBERCMESSAGETEXTf�����������(�����H�#T������CC��@0_�R������C����
��B�UAHEXFFZZZTHISFORMSETATWODIGITHEXARRAY�4�������������C�����
������������T���  �������(����e�T�	�C������6��T�
������T����
���)T���������CC��@0_�R��T��C��
�	\����
���(��	��D�3T�������
���CCC��
�\������T��������������r��HEXEDIT��UNLASTROWNBYTESINLASTROWNPTRLOCATIONCWORKSTRINGAHEXFFTHISFORMSETATWODIGITHEXARRAY	AFILEDATANROW	NLASTBYTENROWBYTENASCIICTEMPSTRING1NCOLUMN�4����T���IIF(RECNO() = �����������/T���, CC�������^Z�,C�Z�)����	���(������%��	�
����%��	���
����T�
��������
T�
�������%��	��
���
T�
������
T�
������%��
���]�+T����	�����C�
��Z������T����	������������T��
�a��UNFIRSTSTRINGCOLUMN
NSTRINGLENGTHNFOUNDROWNUMBERCSTARTSTRINGTHISFORMSET	HEXEDITORGRDDATA
CENDSTRING	BACKCOLORNCURRENTCOL
NHIGHLIGHTROWCOLUMNSDYNAMICBACKCOLORLSTRINGHIGHLIGHTED�4��6%�C�HexEditW������
C���
	����?��C�&Cannot access file.  Aborting program.�0�HexEdit�x��<����%���
���%�C��HEXEDIT�������Ca�HEXEDIT��T�����-��T�����-���B�a���
%�����
T������s�LT��C�/Sector has been edited.  Write changes to disk?�3�HexEdit�x���
H��������������Ca-�HEXEDIT��T���-��T�����-��T�����-��T�	�C�HEXEDITN��T�
�C����G���F��#)�
T�
���������(��	����%���	��h�T�
��
�������T�
��
C����
\���H���T��C���
�����T��C��������%��������
����B�-���B�a�������`���Ca�HEXEDIT��T���-��T�����-��T�����-��B�a�������x�B�-��2�����C�Program error.�x��B�-���ULWRITEIMMEDIATELYTHISFORMSETNFILETOEDITLSECTORDIRTY	HEXEDITORCMDSAVEEDITSENABLEDCMDREVERTEDITSNUSERCHOICENLASTROWNBYTESINLASTROWNNUMBEROFBYTESHEXEDITCWORKSTRINGNROWTEXT
NBYTESWRITTENNPOINTERLOCATIONREPORTFILEERROR:)��C�DynamicBackColor�������T���-��UTHISFORMSET	HEXEDITORGRDDATASETALLLSTRINGHIGHLIGHTED�4���%�C���B�'B�CC��@0_C������6R���
T�����+���	
����%��������B�CC��@0_�R���T�������UNDECIMALNDIGITS	NEXPONENT�������
�����L�
H�-��������K�
T������������7T���CO��C�������6���������T������T�	����T�
��@��T��-��T���
����T��C���
H��+�������+�a���%�C�������T��C���T���
����\R,:��Search Status:� C���d��Z�%C�
 �Press [Escape] to cancel.���T��C������T��C��	C�>����%��a��	�T��C�����#�T��C������%�������
%����_�T���
����R�B��%�C�>�	
������C� ��R,:��String not found.��T��C������T���
����B����T����	��
T�	��
�����!��������+�+�a��'�%�C�������T��C���T���
����\R,:��Search Status:� C���d��Z�%C�
 �Press [Escape] to cancel.���#T�	�C��	��	���6��T��C���	�����T��C��	C�>����%��a��8�T��C������V�T��CC�fC�f����%������
%������T���
����R�B��%���������C� ��R,:��String not found.��T��C������T���
����B���
T�	��
����#�!����R�.%�����
����	��y�T����������T��C���8���T�������T��C��������C�a����T����a��T��C���8���F��	#����T��C���G�����C�C�>�������������������T�
����%�����C���G�����T��-����U
CSTRINGTOFINDNSEARCHDIRECTIONNSEARCHFROMLCASESENTHISFORMSETNSEARCHLOCATIONNPOINTERLOCATIONNCOLNUM	NFILESIZENBYTESTOSEARCHNLARGERBUFFERSIZELESCAPEPRESSED	HEXEDITORMOUSEPOINTER
NSTARTTIMENFILETOEDITCSEEKWORKSTRINGNSTRINGLOCATIONNFIRSTSTRINGCELLNDESIREDLOCATION
READSECTOR
LOCKSCREENNFOUNDROWNUMBERHEXEDITNFIRSTSTRINGCOLUMNSETGRIDHIGHLIGHTSGRDDATAREFRESHCOLUMNSSETFOCUS�4���'%�C���
�C�HexEditW���|�?��C�&Cannot access file.  Aborting program.�0�HexEdit�x��<��B��
�������
H������������������T�����T��C������%�C����
�T��C������B�����������%�����9�B����%���
��k�T��C���������T�����T��C�������%���
����T��C����������%����������T���	�a��T�
�C�����%�C�cWorkString>���w�?��C�&Cannot access file.  Aborting program.�0�HexEdit�x��<����%�C������T��C�
>��T��C��w���T�
�C���G���T�����-��T�����-���G�T�����
T�����
T�
����T�����a��T�����a���%�������T�����-��T�����-�����T�����a��T�����a�����Ca�HEXEDIT����C�BUFF��HEXEDIT��S����C��
��
���T��C��c����	#�)���C�BUFF��HEXEDIT��������%������������������������%��
����T���	�-�����U
NDIRECTIONLLEAVESCREENLOCKEDTHISFORMSETNFILETOEDITNOLDLOCATIONNPOINTERLOCATIONLSTRINGHIGHLIGHTEDCLEARGRIDHIGHLIGHTS	HEXEDITOR
LOCKSCREENCWORKSTRINGNNUMBEROFBYTESNLASTROWNBYTESINLASTROW
CMDNEXTSECTORENABLEDCMDBOTTOMOFFILECMDPREVIOUSSECTORCMDTOPOFFILEHEXEDIT	FILLTABLEGRDDATAREFRESHACTIVECOLUMNCOLUMNSSETFOCUS���B�C�0xC����UCDIGITS*4��
H��#������5������������V������������w�����������������������������%�����	����������������V���%����
�	���������
���2�#�B��UNKEYCODETHISFORMSET	HEXEDITORCMDPREVIOUSSECTORCLICK
CMDNEXTSECTORCMDTOPOFFILECMDBOTTOMOFFILECMDFINDNEXTENABLEDCMDFINDPREVIOUS�
����������G2�G.�G	�G_ �G �T�����T�����T��-��T�����F��-T��C��]�\CC��]��
\�.TMP��h1�����C�����C����	�C����
�C�����C�����C����
�C�����C�����C�����C�����C�����C�����C�����C�����C�����C�����C�����C����Q�����HEXEDIT�"��C�	BUFFERING��HEXEDIT��F��-T��C��]�\CC��]��
\�.TMP���h1�����C�����C�����C�����C�����C�����C���� �C����!�C����"�C����#�C����$�C����%�C����&�C����'�C����(�C����Q����FindStr��"��C�	BUFFERING��FindStr��F��-T�)�C��]�\CC��]��
\�.TMP���h1��)���C�����C�����C�����C�����C�����C���� �C����!�C����"�C����#�C����$�C����%�C����&�C����'�C����(�C�����h1��)���C�����C�����C�����C�����C�����C���� �C����!�C����"�C����#�C����$�C����%�C����&�C����'�C����(�C����Q��)��FindStrH��#��C�	BUFFERING��FindStrH����U*THISFORMSETFILLHEXARRAYNPOINTERLOCATIONNFILETOEDITLSECTORDIRTYNCOLNUM
CTEMPTABLEADDRESSB1B2B3B4B5B6B7B8B9B10B11B12B13B14B15B16TEXTCFINDSTRNAMEC1C2C3C4C5C6C7C8C9C10C11C12C13C14C15
CFINDSTRHNAME
������%�C�HEXEDITW���i���Ca�HEXEDIT����C�BUFF��HEXEDIT��Q��HEXEDIT���%�C��������C���������%�C�FindStrW�����Q��FindStr���%�C�FindStrHW�����Q��FindStrH�������������<��UTHISFORMSETNFILETOEDIT
CTEMPTABLECFINDSTRNAME
CFINDSTRHNAME�
�������T��a��T�����%�C��Z
����SET COMPAT &cOldCompat		
T�����ON ESCAPE &cOldEscape
T�����SET ESCAPE &cOldSetEscape
T�����SET BELL &cOldBell

��C��@�����t&�U	THISFORMSETLFORMSETLOSTFOCUS
COLDCOMPAT
COLDESCAPE
COLDONESCA
COLDSETESCAPECOLDSETESCACOLDBELLLOLDINSMODE�
�������%������T��-��T��C�Escape���T��C�Escapev��T��C�@��T��C�BELLv��T��C�COMPATv��1��lEscapePressed = .T.�G �GA�
��C-�@��G����UTHISFORMSETLFORMSETLOSTFOCUS
COLDONESCACOLDSETESCALOLDINSMODECOLDBELL
COLDCOMPAT�4��%�C�cFileToLoadb�C����-R,�:��!Choose a file to open in HexEdit.��+�C�a����
��q��T������HexEdit�������C�a�������R�%��������<����UCFILETOLOADTHISFORMSET	HEXEDITORCMDFILECLICKGRDDATARECORDSOURCENFILETOEDITreportfileerror,��fillhexarray���	filltableL��setgridhighlightss��writesector���cleargridhighlights~��dec2hex���
findstring�
��
readsector!��hex2dec<��checkkeystrokef��Load%��Unload�$��
DeactivateJ&��Activate�'��Init�(��1����R�����A�3�q1A1A21�As�u�bS�Us2A�AC3��1�r���A�b���AA���AAA�4qh�qAA�BAAAqA����A�U�AAc�qQ�sA��BAA��B�qAqA�AAqr��qA3��3�qA�!aQAA21���r�A������A��Ab��!�!A�QAA1���A��A�AAA�A��A2���!�bA�QAA���A��A�AAAAR�t��Qs�A��q���A��S�B2�v�qAA����rAA"!B�1r���!rAAAA��A�B��qAA��"!����"!A#!!�!!AB���������A��AA2v12q�!aAAaAA�AA3��eaaaa�������r!���aQ!����qQ1B2��A�A�A��A�!A��Er2���!������a�AAS3���qa�Aa�aa�aAA6q���B���ARCqAA1]�\/|481\#dLE����� ��� V#��w#0;Q;K�N.KL$Q?L�N-i
O�UH�V=X|�^X�Z���Z]��0]�_�).0�csearchstring
nsearchdirection
nsearchfrom
lcasesen
lsectordirty
npointerlocation
nfiletoedit
ctemptable
nnumberofbytes
ndesiredlocation
lgridwasscrolled
chighlightarrayname
coldcompat
coldonesca
coldsetesca
nfilesize
ncolnum
lstringhighlighted
chexarrayname
cfindstrhname Name of file used for hex search string
cfindstrname Name of file used for character representation of search string
chexaddress Address to jump to, in Hex notation.
cdecimaladdress Address to jump to, in base ten.  
liceventfired Used in txtFindStringHex, to specify whether the last keystroke made any modifications to the data.
loldinsmode
coldbell
lformsetlostfocus
hexeditor
findstr
gotosect
*reportfileerror 
*fillhexarray 
*filltable 
*setgridhighlights 
*writesector 
*cleargridhighlights 
*dec2hex 
*findstring 
*readsector 
*hex2dec 
^atwodigithexarray[256,0] 
*checkkeystroke 
formformfrmHexEditorHexedit�Height = 360
Width = 613
ShowWindow = 2
DoCreate = .T.
ShowTips = .T.
AutoCenter = .T.
BorderStyle = 1
Caption = "HexEdit"
MaxButton = .F.
KeyPreview = .T.
Name = "frmHexEditor"
QPROCEDURE Unload
THISFORMSET.Hexeditor = .NULL.
THISFORMSET.FindStr = .NULL.
THISFORMSET.GotoSect = .NULL.

ENDPROC
PROCEDURE Init
THISFORMSET.HexEditor = THIS
THIS.Name = SYS(2015)

ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
DO CASE
CASE nKeyCode = 27 AND nShiftAltCtrl = 0	&& escape
	NODEFAULT
	THISFORM.cmdClose.Click
CASE nKeyCode = 6 AND nShiftAltCtrl = 2		&& CTRL+F
	NODEFAULT
	THISFORM.cmdFind.Click
ENDCASE

ENDPROC
PROCEDURE QueryUnload
** This event occurs before the form is released.  Issuing NODEFAULT will
** prevent the form from being released.
IF !THISFORMSET.WriteSector()	&& If changes have been made and user presses Cancel at dialog
	NODEFAULT					&& Don't release form.
	RETURN
ENDIF

THISFORMSET.Deactivate	&& Restore environment settings.

RELEASE THISFORMSET

ENDPROC
��� ����%�c1�U-T����T����T����UTHISFORMSET	HEXEDITORFINDSTRGOTOSECT&T������T���C��]��UTHISFORMSET	HEXEDITORTHISNAMEy����
H��r�������	��E���
�����������	��r���
������UNKEYCODE
NSHIFTALTCTRLTHISFORMCMDCLOSECLICKCMDFIND2%�C��
�����B��
����<��UTHISFORMSETWRITESECTOR
DEACTIVATEUnload,��Init���KeyPress���QueryUnload���1���313���A��A�A3#AAA�r2o�����F)�
commandbutton
commandbuttoncmdFileHexedit.frmHexEditor�Top = 11
Left = 8
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "Select Fi\<le..."
TabIndex = 13
ToolTipText = ""
Name = "cmdFile"

WPROCEDURE Click
PARAMETER cFileToLoad, lCalledFromFormsetInit

#DEFINE SELECT_FILE_LOC		"Select a file to edit:"
#DEFINE APP_NAME_LOC		"HexEdit"
#DEFINE READ_ONLY_LOC		"[Read-Only]"
#DEFINE READ_ONLY_MSG_LOC	"File cannot be locked.  Read-only access."
#DEFINE ZERO_LENGTH_LOC		"Error:  File has zero length.  Cannot edit."
#DEFINE FILE_TOO_LARGE_LOC	"Error:  HexEdit cannot edit a file larger than 4 gigabytes."

IF ! THISFORMSET.WriteSector()
	RETURN
ENDIF
	
IF TYPE("cFileToLoad") != "C" OR !FILE(cFileToLoad)	&& If param not supplied or is invalid
	cTempFileName = ""
	cTempFileName = GETFILE("*", SELECT_FILE_LOC)
	IF ISBLANK(cTempFileName)
		RETURN
	ENDIF
ELSE
	cTempFileName = cFileToLoad
ENDIF
	
nTempHandle = FOPEN(cTempFileName, 2)		&& Buffered R/W
IF nTempHandle < 1							&& Could not open exclusively.  
											&& Let's try opening shared:
	nTempHandle = FOPEN(cTempFileName, 0)	&& Buffered Read-only
	IF nTempHandle < 1						&& Couldn't open file shared.
		THISFORMSET.ReportFileError
		RETURN .F.	&& Bail out.  If a file was already open, it is still open.
					&& If called from THISFORM.INIT, allow to open another file.
	ELSE
		&& We were able to open the file read-only (shared).
		=MESSAGEBOX(READ_ONLY_MSG_LOC, 0, APP_NAME_LOC)
		** Disable editing in all columns of the grid.
		THISFORM.grdData.SetAll("ReadOnly", .T.)
	ENDIF
ELSE
	*  File was opened with read/write access.
	*  If columns aren't already editable, make them so.
	IF THISFORM.grdData.COLUMN2.READONLY = .T.
		THISFORM.grdData.SetAll("ReadOnly", .F.)
		THISFORM.grdData.COLUMNS(1).READONLY = .t.
		THISFORM.grdData.COLUMNS(18).READONLY = .t.
	ENDIF
ENDIF


nFileSize= FSEEK(nTempHandle, 0, 2)
IF nFileSize = 0 OR nFileSize > 0xFFFFFFFF
	IF nFileSize = 0		&& If zero-length file, tell user, then exit.
		=MESSAGEBOX(ZERO_LENGTH_LOC,0,APP_NAME_LOC)
	ELSE
		=MESSAGEBOX(FILE_TOO_LARGE_LOC,0,APP_NAME_LOC)
	ENDIF		
	=FCLOSE(nTempHandle)
	&& If there was already a file open, it is still open.
	RETURN .F.		&& If called by THISFORM.INIT, the .F. says to try again.
ENDIF

WITH THISFORMSET
cFileToEdit = cTempFileName
IF .nFileToEdit != 0		&& If we already had a file open, close it.
	=FCLOSE(.nFileToEdit)
ENDIF
.nFileToEdit = nTempHandle

THISFORM.lblDecFileSize.CAPTION = .Dec2Hex(nFileSize) + "h   (" + ALLTRIM(STR(nFileSize, 20, 0)) + ")"
.nPointerLocation = FSEEK(.nFileToEdit,0,0)	&& Move pointer to the top.

.lSectorDirty = .F.
SET MULTI ON
=CursorSetProp("BUFF", 5)	&& Turn on tablebuffering for Reverting changes.
ENDWITH

*  Make a copy of the file name without the path attached for use in title bar.
nLastBackslash = RAT("\", cFileToEdit)
IF nLastBackslash = 0
	cStrippedFileName = cFileToEdit
ELSE
	cStrippedFileName = SUBSTR(cFileToEdit,nLastBackslash+1)
ENDIF

WITH THISFORM
	.lblCurrentFile.CAPTION = IIF(LEN(cFileToEdit) < 63, cFileToEdit, LEFT(cFileToEdit,20) + "..." + RIGHT(cFileToEdit,40))
	.Caption = APP_NAME_LOC + " - " + cStrippedFileName + IIF(THISFORM.grdData.COLUMN2.READONLY = .T., " " + READ_ONLY_LOC, "")
	.cmdGoToAddress.Enabled = .T.
	.cmdFind.Enabled = .T.
ENDWITH
THISFORMSET.nFileSize = nFileSize

THISFORMSET.ReadSector(0)		&& Read first sector.

ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
�� ��%��G��U�4���%�C��
��!�B��)%�C�cFileToLoadb�C�C�0
����
T�����)T��C�*�Select a file to edit:���%�C��Z����B�����
T������T��C�����%���
��w�T��C�����%���
��
�
����B�-���s�B��C�)File cannot be locked.  Read-only access.��HexEdit�x����C�ReadOnlya���	������%����
�a������C�ReadOnly-���	��T��������a��T��������a����T�
�C������$%��
���
�
���A����%��
���}�D��C�+Error:  File has zero length.  Cannot edit.��HexEdit�x�����T��C�;Error:  HexEdit cannot edit a file larger than 4 gigabytes.��HexEdit�x�����C����B�-���
�������
T�����%�����+���C�����T�����5T����C�
��h   (CC�
��Z��)��T��C������T��-��G_ ���C�BUFF�����T��C�\����%�������
T�������T��C���\���
�������:T����CC�>�?
���C��=�...C��(R6��MT���HexEdit� - �C���
�a�� �[Read-Only]��6��T����a��T����a����T��
��
����C�����UCFILETOLOADLCALLEDFROMFORMSETINITTHISFORMSETWRITESECTOR
CTEMPFILENAMENTEMPHANDLEREPORTFILEERRORTHISFORMGRDDATASETALLCOLUMN2READONLYCOLUMNS	NFILESIZECFILETOEDITNFILETOEDITLBLDECFILESIZECAPTIONDEC2HEXNPOINTERLOCATIONLSECTORDIRTYNLASTBACKSLASHCSTRIPPEDFILENAMELBLCURRENTFILECMDGOTOADDRESSENABLEDCMDFIND
READSECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPressy��1�)AA���AA��A""�q�"�A�����AASAA�AA�rA��!�A�Rq�a1A3��aA�����A3�1�D�L
`)�
commandbutton
commandbuttoncmdTopOfFileHexedit.frmHexEditor�Top = 44
Left = 575
Height = 47
Width = 30
Picture = uptop.bmp
Caption = ""
Enabled = .F.
TabIndex = 2
ToolTipText = "Read First 2k Sector  (Ctrl+Home)"
Name = "cmdTopOfFile"
DPROCEDURE Click
WITH THISFORMSET
IF .WriteSector()
	IF .nPointerLocation != 0
		.nPointerLocation = FSEEK(.nFileToEdit, 0, 0)
		.ReadSector(0)
	ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
�� ���%0k
Q�Ub
�����[�%�C���W�%�����S�T��C��������C��������UTHISFORMSETWRITESECTORNPOINTERLOCATIONNFILETOEDIT
READSECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1��!q�AAA2�1�
�9)�
commandbutton
commandbuttoncmdBottomOfFileHexedit.frmHexEditor�Top = 269
Left = 575
Height = 47
Width = 30
Picture = dnbottom.bmp
Caption = ""
Enabled = .F.
TabIndex = 5
ToolTipText = "Read Last 2k Sector   (Ctrl+End)"
Name = "cmdBottomOfFile"
jPROCEDURE Click
WITH THISFORMSET
IF .WriteSector()
	nOldLocation = .nPointerLocation
	.nPointerLocation = FSEEK(.nFileToEdit, 0, 2)
	nDesiredLocation = INT(.nPointerLocation / 2048) * 2048
	IF .nPointerLocation = nDesiredLocation	&& file is exact multiple of 2K
		nDesiredLocation = nDesiredLocation - 2048
	ENDIF
	.nPointerLocation = FSEEK(.nFileToEdit, nDesiredLocation, 0)
	IF .nPointerLocation != nOldLocation
		.ReadSector(0)
	ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
p�� WW4(%����U�
�������%�C�����T�����T��C������T��C��8���%������T�������T��C������%���������C��������UTHISFORMSETWRITESECTORNOLDLOCATIONNPOINTERLOCATIONNFILETOEDITNDESIREDLOCATION
READSECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress^��1���q�!!Aq!�AAA2�1��_)WlabellabelLabel1Hexedit.frmHexEditor�FontBold = .T.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 1
Caption = "File:"
Height = 13
Left = 84
Top = 8
Width = 64
TabIndex = 0
Name = "Label1"
labellabellblCurrentFileHexedit.frmHexEditor�FontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Caption = "<Filename>"
Height = 16
Left = 160
Top = 8
Width = 445
TabIndex = 0
Name = "lblCurrentFile"

commandbutton
commandbuttoncmdGoToAddressHexedit.frmHexEditor�Top = 328
Left = 401
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "\<Jump..."
Enabled = .F.
TabIndex = 11
ToolTipText = "Jump to a specific address"
Name = "cmdGoToAddress"
�PROCEDURE Click
WITH THISFORMSET
IF ! .WriteSector()
	** User chose cancel at "write changes to disk" dialog.
	RETURN
ENDIF

.cHexAddress = ""
.cDecimalAddress = ""


THISFORM.Enabled = .F.
.GotoSect.Enabled = .T.
.GotoSect.Refresh
SHOW WINDOW (.GotoSect.Name) IN WINDOW (THISFORM.Name)

ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
)�� ��%v���U�
�������%�C�
��!�B��T�����T�����T���-��T����a��������,������������U	THISFORMSETWRITESECTORCHEXADDRESSCDECIMALADDRESSTHISFORMENABLEDGOTOSECTREFRESHNAME������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress��1�BA������B2�17
V�)
commandbutton
commandbuttoncmdPreviousSectorHexedit.frmHexEditor�Top = 91
Left = 575
Height = 65
Width = 30
Picture = uparrow.bmp
Caption = ""
Enabled = .F.
TabIndex = 3
ToolTipText = "Read Previous 2k Sector   (Ctrl+PgUp)"
Name = "cmdPreviousSector"
�PROCEDURE Click
IF THISFORMSET.WriteSector()
	THISFORMSET.ReadSector(-1)
ENDIF


ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
{�� bb��%�	��U)%�C����"���C��������UTHISFORMSETWRITESECTOR
READSECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress��1A4�1Ut�)b
commandbutton
commandbutton
cmdNextSectorHexedit.frmHexEditor�Top = 204
Left = 575
Height = 65
Width = 30
Picture = dnarrow.bmp
Caption = ""
Enabled = .F.
TabIndex = 4
ToolTipText = "Read Next 2k Sector   (Ctrl+PgDn)"
Name = "cmdNextSector"
�PROCEDURE Click
IF THISFORMSET.WriteSector()
	THISFORMSET.ReadSector(1)
ENDIF


ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
z�� aa�%���U(%�C����!���C������UTHISFORMSETWRITESECTOR
READSECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress~��1A4�1Ts�)alabellabelLabel2Hexedit.frmHexEditor�FontBold = .T.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 1
Caption = "Size:"
Height = 13
Left = 84
Top = 25
Width = 64
TabIndex = 0
Name = "Label2"
labellabellblDecFileSizeHexedit.frmHexEditor�FontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Caption = "<File Size>"
Height = 13
Left = 160
Top = 25
Width = 177
TabIndex = 0
Name = "lblDecFileSize"
gridgridgrdDataHexedit.frmHexEditor�ColumnCount = 18
FontName = "Courier"
FontSize = 8
AllowHeaderSizing = .F.
AllowRowSizing = .F.
DeleteMark = .F.
Enabled = .T.
GridLines = 0
HeaderHeight = 15
Height = 272
Left = 8
RecordMark = .F.
RecordSource = "HEXEDIT"
RowHeight = 15
ScrollBars = 2
TabIndex = 1
Top = 44
Width = 560
Name = "grdData"
Column1.FontBold = .F.
Column1.FontName = "Courier New"
Column1.FontSize = 9
Column1.Alignment = 2
Column1.Enabled = .T.
Column1.Width = 76
Column1.Movable = .F.
Column1.Resizable = .F.
Column1.ReadOnly = .T.
Column1.DynamicForeColor = ""
Column1.Name = "Column1"
Column2.FontBold = .F.
Column2.FontName = "Courier"
Column2.FontSize = 9
Column2.Alignment = 0
Column2.Enabled = .T.
Column2.Width = 20
Column2.Movable = .F.
Column2.Resizable = .F.
Column2.ReadOnly = .F.
Column2.SelectOnEntry = .F.
Column2.DynamicForeColor = ""
Column2.Name = "Column2"
Column3.FontBold = .F.
Column3.FontName = "Courier"
Column3.FontSize = 9
Column3.Enabled = .T.
Column3.Width = 20
Column3.Movable = .F.
Column3.Resizable = .F.
Column3.ReadOnly = .F.
Column3.SelectOnEntry = .F.
Column3.DynamicForeColor = ""
Column3.Name = "Column3"
Column4.FontBold = .F.
Column4.FontName = "Courier"
Column4.FontSize = 9
Column4.Enabled = .T.
Column4.Width = 20
Column4.Movable = .F.
Column4.Resizable = .F.
Column4.ReadOnly = .F.
Column4.SelectOnEntry = .F.
Column4.DynamicForeColor = ""
Column4.Name = "Column4"
Column5.FontBold = .F.
Column5.FontName = "Courier"
Column5.FontSize = 9
Column5.Enabled = .T.
Column5.Width = 20
Column5.Movable = .F.
Column5.Resizable = .F.
Column5.ReadOnly = .F.
Column5.SelectOnEntry = .F.
Column5.DynamicForeColor = ""
Column5.Name = "Column5"
Column6.FontBold = .F.
Column6.FontName = "Courier"
Column6.FontSize = 9
Column6.Enabled = .T.
Column6.Width = 20
Column6.Movable = .F.
Column6.Resizable = .F.
Column6.ReadOnly = .F.
Column6.SelectOnEntry = .F.
Column6.DynamicForeColor = ""
Column6.Name = "Column6"
Column7.FontBold = .F.
Column7.FontName = "Courier"
Column7.FontSize = 9
Column7.Enabled = .T.
Column7.Width = 20
Column7.Movable = .F.
Column7.Resizable = .F.
Column7.ReadOnly = .F.
Column7.SelectOnEntry = .F.
Column7.DynamicForeColor = ""
Column7.Name = "Column7"
Column8.FontBold = .F.
Column8.FontName = "Courier"
Column8.FontSize = 9
Column8.Enabled = .T.
Column8.Width = 20
Column8.Movable = .F.
Column8.Resizable = .F.
Column8.ReadOnly = .F.
Column8.SelectOnEntry = .F.
Column8.DynamicForeColor = ""
Column8.Name = "Column8"
Column9.FontBold = .F.
Column9.FontName = "Courier"
Column9.FontSize = 9
Column9.Enabled = .T.
Column9.Width = 20
Column9.Movable = .F.
Column9.Resizable = .F.
Column9.ReadOnly = .F.
Column9.SelectOnEntry = .F.
Column9.DynamicForeColor = ""
Column9.Name = "Column9"
Column10.FontBold = .F.
Column10.FontName = "Courier"
Column10.FontSize = 9
Column10.Enabled = .T.
Column10.Width = 20
Column10.Movable = .F.
Column10.Resizable = .F.
Column10.ReadOnly = .F.
Column10.SelectOnEntry = .F.
Column10.DynamicForeColor = ""
Column10.Name = "Column10"
Column11.FontBold = .F.
Column11.FontName = "Courier"
Column11.FontSize = 9
Column11.Enabled = .T.
Column11.Width = 20
Column11.Movable = .F.
Column11.Resizable = .F.
Column11.ReadOnly = .F.
Column11.SelectOnEntry = .F.
Column11.DynamicForeColor = ""
Column11.Name = "Column11"
Column12.FontBold = .F.
Column12.FontName = "Courier"
Column12.FontSize = 9
Column12.Enabled = .T.
Column12.Width = 20
Column12.Movable = .F.
Column12.Resizable = .F.
Column12.ReadOnly = .F.
Column12.SelectOnEntry = .F.
Column12.DynamicForeColor = ""
Column12.Name = "Column12"
Column13.FontBold = .F.
Column13.FontName = "Courier"
Column13.FontSize = 9
Column13.Enabled = .T.
Column13.Width = 20
Column13.Movable = .F.
Column13.Resizable = .F.
Column13.ReadOnly = .F.
Column13.SelectOnEntry = .F.
Column13.DynamicForeColor = ""
Column13.Name = "Column13"
Column14.FontBold = .F.
Column14.FontName = "Courier"
Column14.FontSize = 9
Column14.Enabled = .T.
Column14.Width = 20
Column14.Movable = .F.
Column14.Resizable = .F.
Column14.ReadOnly = .F.
Column14.SelectOnEntry = .F.
Column14.DynamicForeColor = ""
Column14.Name = "Column14"
Column15.FontBold = .F.
Column15.FontName = "Courier"
Column15.FontSize = 9
Column15.Enabled = .T.
Column15.Width = 20
Column15.Movable = .F.
Column15.Resizable = .F.
Column15.ReadOnly = .F.
Column15.SelectOnEntry = .F.
Column15.DynamicForeColor = ""
Column15.Name = "Column15"
Column16.FontBold = .F.
Column16.FontName = "Courier"
Column16.FontSize = 9
Column16.ColumnOrder = 16
Column16.Enabled = .T.
Column16.Width = 20
Column16.Movable = .F.
Column16.Resizable = .F.
Column16.ReadOnly = .F.
Column16.SelectOnEntry = .F.
Column16.DynamicForeColor = ""
Column16.Name = "Column16"
Column17.FontBold = .F.
Column17.FontName = "Courier"
Column17.FontSize = 9
Column17.Bound = .T.
Column17.ColumnOrder = 17
Column17.Enabled = .T.
Column17.Width = 20
Column17.Movable = .F.
Column17.Resizable = .F.
Column17.ReadOnly = .F.
Column17.SelectOnEntry = .F.
Column17.DynamicForeColor = ""
Column17.DynamicAlignment = ""
Column17.Name = "Column17"
Column18.FontBold = .F.
Column18.FontName = "Courier New"
Column18.FontSize = 9
Column18.Alignment = 2
Column18.Enabled = .T.
Column18.Width = 144
Column18.Movable = .F.
Column18.Resizable = .F.
Column18.ReadOnly = .T.
Column18.Name = "Column18"
�PROCEDURE BeforeRowColChange
LPARAMETERS nColIndex
THISFORMSET.nColNum = nColIndex		&& Store which column focus is moving from.

ENDPROC
�� ��t%k���U���T������U	NCOLINDEXTHISFORMSETNCOLNUMBeforeRowColChange,��1q2�)�headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column1pFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "Address"
Name = "Header1"
refusefocushexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column1Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column2jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "0"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column2Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column3jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "1"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column3Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column4jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "2"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column4Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column5jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "3"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column5Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column6jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "4"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column6Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column7jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "5"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column7Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column8jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "6"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column8Name = "Text1"
headerheaderHeader1$Hexedit.frmHexEditor.grdData.Column9jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "7"
Name = "Header1"
text1hexedit.vcxtextboxText1$Hexedit.frmHexEditor.grdData.Column9Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column10jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "8"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column10Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column11jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "9"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column11Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column12jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "A"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column12Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column13jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "B"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column13Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column14jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "C"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column14Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column15jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "D"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column15Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column16jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "E"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column16Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column17jFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "F"
Name = "Header1"
text1hexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column17Name = "Text1"
headerheaderHeader1%Hexedit.frmHexEditor.grdData.Column18mFontBold = .F.
FontName = "MS Sans Serif"
FontSize = 8
Alignment = 2
Caption = "Text"
Name = "Header1"
refusefocushexedit.vcxtextboxText1%Hexedit.frmHexEditor.grdData.Column18Name = "Text1"

commandbutton
commandbuttoncmdRevertEditsHexedit.frmHexEditor�Top = 328
Left = 104
Height = 23
Width = 72
FontName = "MS Sans Serif"
Caption = "\<Undo Edits"
Enabled = .F.
TabIndex = 7
ToolTipText = ""
Name = "cmdRevertEdits"
!PROCEDURE Click
=TableRevert(.T., "Hexedit")
THISFORMSET.lSectorDirty = .F.
THIS.Enabled = .F.
THISFORM.cmdSaveEdits.ENABLED = .F.

ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
��� ����%B	0�UD��Ca�Hexedit��T���-��T���-��T����-��UTHISFORMSETLSECTORDIRTYTHISENABLEDTHISFORMCMDSAVEEDITS������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1A��3�1��)�
commandbutton
commandbuttoncmdFindHexedit.frmHexEditor�Top = 328
Left = 252
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "\<Find..."
Enabled = .F.
TabIndex = 9
ToolTipText = "Search for a string"
Name = "cmdFind"
�PROCEDURE Click
WITH THISFORMSET
IF ! .WriteSector()
	** User chose cancel at "write changes to disk" dialog.
	RETURN
ENDIF


THISFORM.ENABLED = .F.
.FindStr.cmdFind.Enabled = .F.
.FindStr.ENABLED = .T.
SHOW WINDOW (.FindStr.Name) IN WINDOW (Thisform.Name)

ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
�� ��w%Bc�Ut
�����m�%�C�
��!�B��T���-��T�����-��T����a���,������������UTHISFORMSETWRITESECTORTHISFORMENABLEDFINDSTRCMDFINDNAME������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1�BA�!��B2�15�)�
commandbutton
commandbuttoncmdFindPreviousHexedit.frmHexEditor�Top = 328
Left = 222
Height = 23
Width = 25
Picture = left.bmp
Caption = ""
Enabled = .F.
TabIndex = 8
ToolTipText = "Search backward   (Shift+F3)"
Name = "cmdFindPrevious"
�PROCEDURE Click
WITH THISFORMSET
IF ! .WriteSector()
	** User chose cancel at "write changes to disk" dialog.
	RETURN
ENDIF

** Search Backwards, from current location
.FindString(.cSearchString, 2, 2, .lCaseSen)	

ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
��� ����%
D.�UE
�����>�%�C�
��!�B����C���������UTHISFORMSETWRITESECTOR
FINDSTRING
CSEARCHSTRINGLCASESEN������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1�BA�B2�1�v
)�
commandbutton
commandbuttoncmdFindNextHexedit.frmHexEditor�Top = 328
Left = 330
Height = 23
Width = 25
Picture = right.bmp
Caption = ""
Enabled = .F.
TabIndex = 10
ToolTipText = "Search forward   (F3)"
Name = "cmdFindNext"
}PROCEDURE Click
WITH THISFORMSET
IF ! .WriteSector()
	** User chose cancel at "write changes to disk" dialog.
	RETURN
ENDIF
** Search Forwards, from current location
.FindString(.cSearchString, 1, 2, .lCaseSen)

ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
��� ����%
D.�UE
�����>�%�C�
��!�B����C���������UTHISFORMSETWRITESECTOR
FINDSTRING
CSEARCHSTRINGLCASESEN������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1�BA�B2�1�r)�
commandbutton
commandbuttoncmdSaveEditsHexedit.frmHexEditor�Top = 328
Left = 24
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 9
Caption = "\<Save Edits"
Enabled = .F.
TabIndex = 6
ToolTipText = ""
Name = "cmdSaveEdits"
�PROCEDURE Click
THISFORMSET.WriteSector(.T.)

ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
S�� ::�%����U��Ca����UTHISFORMSETWRITESECTOR������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress[��1�3�1/N�):
commandbutton
commandbuttoncmdCloseHexedit.frmHexEditor�Top = 327
Left = 516
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "Close"
TabIndex = 12
Name = "cmdClose"
�PROCEDURE Click
IF !THISFORMSET.WriteSector()
	&& User pressed cancel (to continue editing data).
	RETURN
ENDIF
THISFORMSET.Deactivate	&& Restore environment settings.
THISFORMSET.Hexeditor = .NULL.
THISFORMSET.FindStr = .NULL.
THISFORMSET.GotoSect = .NULL.
RELEASE THISFORMSET

ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
THISFORMSET.CheckKeystroke(nKeyCode)	&& If Ctrl+Up, etc. then scroll grid.
ENDPROC
�� ���%%`
F�UX%�C��
���B��
����T����T����T����<��UTHISFORMSETWRITESECTOR
DEACTIVATE	HEXEDITORFINDSTRGOTOSECT������C�����UNKEYCODE
NSHIFTALTCTRLTHISFORMSETCHECKKEYSTROKEClick,��KeyPress���1!BA����q3�1 
?�
)�formform
frmFindStrHexedit�Top = 42
Left = 133
Height = 269
Width = 437
ShowWindow = 2
DoCreate = .T.
BorderStyle = 1
Caption = "Enter String to Find"
Closable = .F.
MaxButton = .F.
MinButton = .F.
Visible = .F.
Enabled = .F.
AlwaysOnTop = .T.
Name = "frmFindStr"
mPROCEDURE Activate
THISFORM.LOCKSCREEN = .T.
SET CONFIRM OFF
SET BELL OFF

** Set current value for unbound control.  This way, THISFORMSET.lCaseSen is not changed
** if user presses Cancel.
THISFORM.chkCaseSen.VALUE = THISFORMSET.lCaseSen

** The VALUE property of a textbox in a grid is not updated until that column
** gets focus.  So if this is the second time into this form, the grid may
** be blank, but the VALUE properties of the textbox in each column will contain
** the data from the previous time.  Clear this data out of the Hex table.
IF !ISBLANK(ALLTRIM(THISFORM.grdHex.Column1.Text1.Value))
	FOR nCurrentCol = 1 to 15
		THISFORM.grdHex.Columns(nCurrentCol).Text1.Value = ""
	NEXT
ENDIF

THISFORM.grdChar.Column1.Text1.SETFOCUS
THISFORM.REFRESH

THISFORM.LOCKSCREEN = .F.



ENDPROC
PROCEDURE Init
*  To allow this form to be moved inside the HexEdit Top-Level form, it 
*  needs to have a unique name (so multiple instances of HexEdit don't get
*  confused).  So we store an object reference to this form into a property of
*  the formset.  We can then use that property to refer to this form just as if
*  it were the form name.  Then assign a unique object name to this form using
*  sys(2015).  See the HexEdit form's cmdFind.Click and cmdGoToAddress.Click 
*  methods to see where this comes into play.
THISFORMSET.FindStr = THIS	&& Store object reference into formset property.
THIS.Name = SYS(2015)		&& Assign unique object name to this form.

IF  fontmetric(1, 'MS Sans Serif', 8, '') # 13 OR ;
	fontmetric(4, 'MS Sans Serif', 8, '') # 2 OR ;
	fontmetric(6, 'MS Sans Serif', 8, '') # 5 OR ;
	fontmetric(7, 'MS Sans Serif', 8, '') # 11
	this.setall('fontname', 'Arial')
ENDIF

ENDPROC
PROCEDURE Hide
** Clear current data from tables.
=tablerevert(.t., "findstr")
=tablerevert(.t., "findstrh")
THISFORM.Enabled = .F. 
ENDPROC
��� ��Pu%�2�U�T���a��G	�G�T��������%�CC�������Z
������	���(������T���
��	�����������������
���
�T���-��UTHISFORM
LOCKSCREEN
CHKCASESENVALUETHISFORMSETLCASESENGRDHEXCOLUMN1TEXT1NCURRENTCOLCOLUMNSGRDCHARSETFOCUSREFRESH�T������T���C��]���%�C��
MS Sans Serif���$�
�!C��
MS Sans Serif���$��!C��
MS Sans Serif���$��!C��
MS Sans Serif���$����� ��C�fontname�Arial�����UTHISFORMSETFINDSTRTHISNAMESETALL:��Ca�findstr����Ca�findstrh��T���-��UTHISFORMENABLEDActivate,��Initu��Hide���1�aad�q�AA2��51e	A3BQ�1/J��b/)�
commandbutton
commandbuttoncmdFindHexedit.frmFindStr�Top = 224
Left = 80
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "\<Find"
Default = .T.
TabIndex = 10
Name = "cmdFind"
mPROCEDURE Click
** Put data into a string.
WITH THISFORMSET
cTmpSearchString = ""
FOR nCurrentChar = 1 TO 15
	IF !ISNULL(EVAL("FindStrH." + FIELD(nCurrentChar,"FindStrH"))) ;
		AND !ISBLANK(EVAL("FindStrH." + FIELD(nCurrentChar, "FindStrH")))
	      cTmpSearchString = cTmpSearchString + ;
	      		CHR(.HEX2DEC(EVAL("FindStrH." + FIELD(nCurrentChar,"FindStrH"))))
	ELSE
		EXIT
	ENDIF
NEXT

IF LEN(cTmpSearchString) = 0			&& If user didn't enter any data,
	RETURN								&& just return to main form.
ENDIF

** Put search params into properties so can be re-used by the Search Backwards
** and Search Forwards buttons.
.cSearchString = cTmpSearchString
.lCaseSen = THISFORM.chkCaseSen.VALUE

.HexEditor.ENABLED = .T.
THISFORM.HIDE

** Enable Search Backwards and Search Forwards buttons.
.HexEditor.cmdFindPrevious.ENABLED = .T.
.HexEditor.cmdFindNext.ENABLED = .T.
.HexEditor.SHOW	

*  FindString() could read the object properties directly, but it uses parameters to
*  allow for easier future development.
.FindString(.cSearchString, .nSearchDirection, .nSearchFrom, .lCaseSen)	
ENDWITH
ENDPROC
�� ���%x���Us
�����l�
T����������(������S%�CC�	FindStrH.C��FindStrH/��
�$CC�	FindStrH.C��FindStrH/��Z
	����4T���CCC�	FindStrH.C��FindStrH/�� �����!����%�C�>�����B��T�����T�������T��	�
�a��
����T��	��
�a��T��	�
�
�a�����	����C���������UTHISFORMSETCTMPSEARCHSTRINGNCURRENTCHARHEX2DEC
CSEARCHSTRINGLCASESENTHISFORM
CHKCASESENVALUE	HEXEDITORENABLEDHIDECMDFINDPREVIOUSCMDFINDNEXTSHOW
FINDSTRINGNSEARCHDIRECTIONNSEARCHFROMClick,��1��q2B�AAA2AA�A��#!��A1b)�
commandbutton
commandbutton	cmdCancelHexedit.frmFindStr�AutoSize = .F.
Top = 224
Left = 272
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Cancel = .T.
Caption = "\<Cancel"
TabIndex = 11
Name = "cmdCancel"
PPROCEDURE Click
THISFORMSET.HexEditor.ENABLED = .T.
THISFORM.HIDE

ENDPROC
��� ���%���UT����a��
����UTHISFORMSET	HEXEDITORENABLEDTHISFORMHIDEClick,��1�2E)�labellabelLabel1Hexedit.frmFindStr�FontName = "MS Sans Serif"
FontSize = 8
Caption = "Character:"
Height = 13
Left = 32
Top = 13
Width = 93
TabIndex = 1
Name = "Label1"
labellabelLabel2Hexedit.frmFindStr�FontName = "MS Sans Serif"
FontSize = 8
Caption = "Hex:"
Height = 13
Left = 32
Top = 62
Width = 105
TabIndex = 3
Name = "Label2"
gridgridgrdCharHexedit.frmFindStrMColumnCount = 15
FontSize = 10
AllowHeaderSizing = .F.
AllowRowSizing = .F.
DeleteMark = .F.
GridLines = 0
GridLineWidth = 1
HeaderHeight = 0
Height = 24
Highlight = .F.
HighlightRow = .F.
Left = 60
RecordMark = .F.
RecordSource = "FindStr"
RowHeight = 22
ScrollBars = 0
SplitBar = .F.
TabIndex = 2
Top = 33
Width = 319
Name = "grdChar"
Column1.FontBold = .T.
Column1.FontName = "MS Sans Serif"
Column1.FontSize = 10
Column1.Alignment = 2
Column1.Width = 20
Column1.SelectOnEntry = .T.
Column1.Name = "Column1"
Column2.FontBold = .T.
Column2.FontName = "MS Sans Serif"
Column2.FontSize = 10
Column2.Alignment = 2
Column2.Width = 20
Column2.SelectOnEntry = .T.
Column2.Name = "Column2"
Column3.FontBold = .T.
Column3.FontName = "MS Sans Serif"
Column3.FontSize = 10
Column3.Alignment = 2
Column3.Width = 20
Column3.SelectOnEntry = .T.
Column3.Name = "Column3"
Column4.FontBold = .T.
Column4.FontName = "MS Sans Serif"
Column4.FontSize = 10
Column4.Alignment = 2
Column4.Width = 20
Column4.SelectOnEntry = .T.
Column4.Name = "Column4"
Column5.FontBold = .T.
Column5.FontName = "MS Sans Serif"
Column5.FontSize = 10
Column5.Alignment = 2
Column5.Width = 20
Column5.SelectOnEntry = .T.
Column5.Name = "Column5"
Column6.FontBold = .T.
Column6.FontName = "MS Sans Serif"
Column6.FontSize = 10
Column6.Alignment = 2
Column6.Width = 20
Column6.SelectOnEntry = .T.
Column6.Name = "Column6"
Column7.FontBold = .T.
Column7.FontName = "MS Sans Serif"
Column7.FontSize = 10
Column7.Alignment = 2
Column7.Width = 20
Column7.SelectOnEntry = .T.
Column7.Name = "Column7"
Column8.FontBold = .T.
Column8.FontName = "MS Sans Serif"
Column8.FontSize = 10
Column8.Alignment = 2
Column8.Width = 20
Column8.SelectOnEntry = .T.
Column8.Name = "Column8"
Column9.FontBold = .T.
Column9.FontName = "MS Sans Serif"
Column9.FontSize = 10
Column9.Alignment = 2
Column9.Width = 20
Column9.SelectOnEntry = .T.
Column9.Name = "Column9"
Column10.FontBold = .T.
Column10.FontName = "MS Sans Serif"
Column10.FontSize = 10
Column10.Alignment = 2
Column10.Width = 20
Column10.SelectOnEntry = .T.
Column10.Name = "Column10"
Column11.FontBold = .T.
Column11.FontName = "MS Sans Serif"
Column11.FontSize = 10
Column11.Alignment = 2
Column11.Width = 20
Column11.SelectOnEntry = .T.
Column11.Name = "Column11"
Column12.FontBold = .T.
Column12.FontName = "MS Sans Serif"
Column12.FontSize = 10
Column12.Alignment = 2
Column12.Width = 20
Column12.SelectOnEntry = .T.
Column12.Name = "Column12"
Column13.FontBold = .T.
Column13.FontName = "MS Sans Serif"
Column13.FontSize = 10
Column13.Alignment = 2
Column13.Width = 20
Column13.SelectOnEntry = .T.
Column13.Name = "Column13"
Column14.FontBold = .T.
Column14.FontName = "MS Sans Serif"
Column14.FontSize = 10
Column14.Alignment = 2
Column14.Width = 20
Column14.SelectOnEntry = .T.
Column14.Name = "Column14"
Column15.FontBold = .T.
Column15.FontName = "MS Sans Serif"
Column15.FontSize = 10
Column15.Alignment = 2
Column15.Width = 20
Column15.SelectOnEntry = .T.
Column15.ForeColor = 0,0,0
Column15.Name = "Column15"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column16FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column1KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column26FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column2KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column36FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column3KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column46FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column4KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column56FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column5KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column66FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column6KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column76FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column7KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column86FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column8KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdChar.Column96FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdChar.Column9KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column106FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column10KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column116FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column11KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column126FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column12KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column136FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column13KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column146FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column14KFontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
Name = "Text1"
headerheaderHeader1#Hexedit.frmFindStr.grdChar.Column156FontSize = 10
Caption = "Header1"
Name = "Header1"

txtfindstringhexedit.vcxtextboxText1#Hexedit.frmFindStr.grdChar.Column15^FontBold = .T.
FontName = "MS Sans Serif"
FontSize = 10
ForeColor = 0,0,0
Name = "Text1"
gridgridgrdHexHexedit.frmFindStr�ColumnCount = 15
FontName = "Courier"
AllowHeaderSizing = .F.
AllowRowSizing = .F.
DeleteMark = .F.
GridLines = 0
HeaderHeight = 0
Height = 24
HighlightRow = .F.
Left = 60
RecordMark = .F.
RecordSource = "FindStrH"
RowHeight = 22
ScrollBars = 0
SplitBar = .F.
TabIndex = 4
Top = 81
Width = 319
Name = "grdHex"
Column1.FontBold = .T.
Column1.FontName = "Courier"
Column1.FontSize = 10
Column1.Alignment = 2
Column1.ControlSource = ""
Column1.Width = 20
Column1.Name = "Column1"
Column2.FontBold = .T.
Column2.FontName = "Courier"
Column2.FontSize = 10
Column2.Alignment = 2
Column2.ControlSource = ""
Column2.Width = 20
Column2.Name = "Column2"
Column3.FontBold = .T.
Column3.FontName = "Courier"
Column3.FontSize = 10
Column3.Alignment = 2
Column3.ControlSource = ""
Column3.Width = 20
Column3.Name = "Column3"
Column4.FontBold = .T.
Column4.FontName = "Courier"
Column4.FontSize = 10
Column4.Alignment = 2
Column4.ControlSource = ""
Column4.Width = 20
Column4.Name = "Column4"
Column5.FontBold = .T.
Column5.FontName = "Courier"
Column5.FontSize = 10
Column5.Alignment = 2
Column5.ControlSource = ""
Column5.Width = 20
Column5.Name = "Column5"
Column6.FontBold = .T.
Column6.FontName = "Courier"
Column6.FontSize = 10
Column6.Alignment = 2
Column6.ControlSource = ""
Column6.Width = 20
Column6.Name = "Column6"
Column7.FontBold = .T.
Column7.FontName = "Courier"
Column7.FontSize = 10
Column7.Alignment = 2
Column7.ControlSource = ""
Column7.Width = 20
Column7.Name = "Column7"
Column8.FontBold = .T.
Column8.FontName = "Courier"
Column8.FontSize = 10
Column8.Alignment = 2
Column8.ControlSource = ""
Column8.Width = 20
Column8.Name = "Column8"
Column9.FontBold = .T.
Column9.FontName = "Courier"
Column9.FontSize = 10
Column9.Alignment = 2
Column9.ControlSource = ""
Column9.Width = 20
Column9.Name = "Column9"
Column10.FontBold = .T.
Column10.FontName = "Courier"
Column10.FontSize = 10
Column10.Alignment = 2
Column10.ControlSource = ""
Column10.Width = 20
Column10.Name = "Column10"
Column11.FontBold = .T.
Column11.FontName = "Courier"
Column11.FontSize = 10
Column11.Alignment = 2
Column11.ControlSource = ""
Column11.Width = 20
Column11.Name = "Column11"
Column12.FontBold = .T.
Column12.FontName = "Courier"
Column12.FontSize = 10
Column12.Alignment = 2
Column12.ControlSource = ""
Column12.Width = 20
Column12.Name = "Column12"
Column13.FontBold = .T.
Column13.FontName = "Courier"
Column13.FontSize = 10
Column13.Alignment = 2
Column13.ControlSource = ""
Column13.Width = 20
Column13.Name = "Column13"
Column14.FontBold = .T.
Column14.FontName = "Courier"
Column14.FontSize = 10
Column14.Alignment = 2
Column14.ControlSource = ""
Column14.Width = 20
Column14.Name = "Column14"
Column15.FontBold = .T.
Column15.FontName = "Courier"
Column15.FontSize = 10
Column15.Alignment = 2
Column15.ControlSource = ""
Column15.Width = 20
Column15.Name = "Column15"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column1=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column1EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column2=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column2EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column3=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column3EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column4=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column4EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column5=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column5EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column6=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column6EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column7=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column7EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column8=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column8EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1!Hexedit.frmFindStr.grdHex.Column9=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1!Hexedit.frmFindStr.grdHex.Column9EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column10=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column10EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column11=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column11EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column12=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column12EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column13=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column13EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column14=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column14EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
headerheaderHeader1"Hexedit.frmFindStr.grdHex.Column15=FontName = "Courier"
Caption = "Header1"
Name = "Header1"
txtfindstringhexhexedit.vcxtextboxText1"Hexedit.frmFindStr.grdHex.Column15EFontBold = .T.
FontName = "Courier"
FontSize = 10
Name = "Text1"
optiongroupoptiongroupoptSearchDirectionHexedit.frmFindStr}ButtonCount = 2
Value = 1
ControlSource = "THISFORMSET.nSearchDirection"
Height = 52
Left = 44
Top = 128
Width = 157
TabIndex = 6
Name = "optSearchDirection"
Option1.FontName = "MS Sans Serif"
Option1.FontSize = 8
Option1.BackStyle = 0
Option1.Caption = "Fo\<rward"
Option1.Value = 1
Option1.Height = 18
Option1.Left = 5
Option1.Top = 9
Option1.Width = 140
Option1.Name = "Option1"
Option2.FontName = "MS Sans Serif"
Option2.FontSize = 8
Option2.BackStyle = 0
Option2.Caption = "Bac\<kward"
Option2.Value = 0
Option2.Height = 18
Option2.Left = 5
Option2.Top = 29
Option2.Width = 152
Option2.Name = "Option2"

PROCEDURE InteractiveChange
&& Cannot search forward from end of file, nor backward from top of file.
&& So make sure those combinations cannot be chosen.
DO CASE
CASE THIS.VALUE = 1		&&Search from beginning of file
	IF THISFORM.optSearchFrom.VALUE = 3
		THISFORM.optSearchFrom.VALUE = 2
		THISFORM.optSearchFrom.REFRESH
	ENDIF
CASE THIS.VALUE = 2		&&Search from end of file.
	IF THISFORM.optSearchFrom.VALUE = 1
		THISFORM.optSearchFrom.VALUE = 2
		THISFORM.optSearchFrom.REFRESH
	ENDIF
ENDCASE

ENDPROC
��� ��.%H,�U�
H�
���������\�%�������X�T�������
��������������%���������T�������
�������UTHISVALUETHISFORM
OPTSEARCHFROMREFRESHInteractiveChange,��1�Aq1�AAq1�AA2�)�checkboxcheckbox
chkCaseSenHexedit.frmFindStr�Top = 186
Left = 44
Height = 15
Width = 121
FontName = "MS Sans Serif"
FontSize = 8
Caption = "Case \<sensitive"
Value = .F.
ControlSource = ""
TabIndex = 7
Name = "chkCaseSen"
optiongroupoptiongroup
optSearchFromHexedit.frmFindStruButtonCount = 3
Value = 1
ControlSource = "THISFORMSET.nSearchFrom"
Height = 73
Left = 236
Top = 128
Width = 157
TabIndex = 9
Name = "optSearchFrom"
Option1.FontName = "MS Sans Serif"
Option1.FontSize = 8
Option1.BackStyle = 0
Option1.Caption = "\<Beginning of file"
Option1.Value = 1
Option1.Height = 18
Option1.Left = 5
Option1.Top = 9
Option1.Width = 152
Option1.Name = "option1"
Option2.FontName = "MS Sans Serif"
Option2.FontSize = 8
Option2.BackStyle = 0
Option2.Caption = "C\<urrent location"
Option2.Value = 0
Option2.Height = 18
Option2.Left = 5
Option2.Top = 29
Option2.Width = 152
Option2.Name = "option2"
Option3.FontName = "MS Sans Serif"
Option3.FontSize = 8
Option3.BackStyle = 0
Option3.Caption = "\<End of file"
Option3.Value = 0
Option3.Height = 18
Option3.Left = 5
Option3.Top = 49
Option3.Width = 164
Option3.Name = "option3"
�PROCEDURE InteractiveChange
&& Cannot search forward from end of file, nor backward from top of file.
&& So make sure those combinations cannot be chosen.
DO CASE
CASE THIS.VALUE = 1		&&Search from beginning of file
	THISFORM.optSearchDirection.VALUE = 1
	THISFORM.optSearchDirection.REFRESH
CASE THIS.VALUE = 3		&&Search from end of file.
	THISFORM.optSearchDirection.VALUE = 2
	THISFORM.optSearchDirection.REFRESH
ENDCASE

ENDPROC
q�� XX�^%�
��U|
H�
�u�������A�T�������
�����������u�T�������
������UTHISVALUETHISFORMOPTSEARCHDIRECTIONREFRESHInteractiveChange,��1�A1�A1�A2�)XlabellabelLabel3Hexedit.frmFindStr�AutoSize = .T.
FontName = "MS Sans Serif"
FontSize = 8
Caption = "Search from"
Height = 15
Left = 242
Top = 120
Width = 59
TabIndex = 8
Name = "Label3"
labellabelLabel4Hexedit.frmFindStr�AutoSize = .T.
FontName = "MS Sans Serif"
FontSize = 8
Caption = "Search direction"
Height = 15
Left = 50
Top = 120
Width = 79
TabIndex = 5
Name = "Label4"
formformfrmGotoSectHexedit
Top = 30
Left = 41
Height = 149
Width = 363
ShowWindow = 2
DoCreate = .T.
BorderStyle = 1
Caption = "Enter Jump Address"
Closable = .F.
MaxButton = .F.
MinButton = .F.
Visible = .F.
Enabled = .F.
WindowType = 1
AlwaysOnTop = .T.
Name = "frmGotoSect"
IPROCEDURE Init
*  To allow this form to be moved inside the HexEdit Top-Level form, it 
*  needs to have a unique name (so multiple instances of HexEdit don't get
*  confused).  So we store an object reference to this form to a property of
*  the formset.  We can use that property to refer to this form just as if
*  it were the form name.  Then assign a unique object name to this form using
*  sys(2015).  See the HexEdit form's cmdFind.Click and cmdGoToAddress.Click 
*  methods to see where this comes into play.
THISFORMSET.GotoSect = THIS	&& Store object reference into formset property.
THIS.Name = SYS(2015)		&& Assign unique object name to this form.
ENDPROC
PROCEDURE Show
LPARAMETERS nStyle
=INSMODE(.T.)
ENDPROC
PROCEDURE Hide
=INSMODE(.F.)
THISFORMSET.HexEditor.Enabled = .T.
THISFORM.Enabled = .F.
ENDPROC
��� ����%�4�U&T������T���C��]��UTHISFORMSETGOTOSECTTHISNAME���
��Ca�@��UNSTYLE,
��C-�@��T����a��T���-��UTHISFORMSET	HEXEDITORENABLEDTHISFORMInit,��Showy��Hide���112q�2��1����>)�textboxtextboxtxtDecimalAddressHexedit.frmGotoSect�FontName = "MS Sans Serif"
FontSize = 8
ControlSource = "THISFORMSET.cDecimalAddress"
Height = 23
InputMask = "9999999999"
Left = 112
TabIndex = 2
Top = 64
Width = 193
Name = "txtDecimalAddress"
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
** Must be numeric.  This is handled by the InputMask, but want to beep:
IF NOT ((nKeyCode > 47 AND nKeyCode < 58) OR (nKeyCode > 0 AND nKeyCode < 24);
		OR (nKeyCode = 127) OR (nKeyCode = 27))
	?? CHR(7)		
	NODEFAULT
ENDIF

ENDPROC
PROCEDURE InteractiveChange
** Translate and update OTHER field.
WITH THISFORMSET
.cHexAddress = .Dec2Hex(VAL(THIS.VALUE))
.cDecimalAddress = THIS.VALUE	&& Force write to variable.
ENDWITH
THISFORM.txtHexAddress.REFRESH

ENDPROC
%��  %l�
��Ur����N%���/���:
	������
	�	���	��
��k���C� �����UNKEYCODE
NSHIFTALTCTRLJ
�����6�T��CC��g���T��������
�����U	THISFORMSETCHEXADDRESSDEC2HEXTHISVALUECDECIMALADDRESSTHISFORM
TXTHEXADDRESSREFRESHKeyPress,��InteractiveChange���1���AA3��A�2G
)textboxtextbox
txtHexAddressHexedit.frmGotoSect�FontName = "MS Sans Serif"
FontSize = 8
ControlSource = "THISFORMSET.cHexAddress"
Height = 23
InputMask = "!!!!!!!!"
Left = 112
TabIndex = 1
Top = 20
Width = 193
Name = "txtHexAddress"
YPROCEDURE InteractiveChange
** Keypress event code has limited to correct keystrokes.
** Now update OTHER field.
WITH THISFORMSET
.cDecimalAddress = ALLTRIM(STR(.Hex2Dec(THIS.VALUE)))
THISFORM.txtDecimalAddress.REFRESH
.cHexAddress = THIS.Value	&& force into variable.
ENDWITH
ENDPROC
PROCEDURE KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
*Must be numeric or in "ABCDEF"
IF NOT (BETWEEN(nKeyCode, 48 ,57) OR BETWEEN(nKeyCode, 97, 102);
		OR BETWEEN(nKeyCode, 65, 70) OR BETWEEN(nKeyCode, 1, 23);
		OR (nKeyCode = 127) OR (nKeyCode = 27))
	?? CHR(7)		
	NODEFAULT
ENDIF
	

ENDPROC
9��   f�%��
��UL
�����E�T��CCC���Z���
�����T��������U	THISFORMSETCDECIMALADDRESSHEX2DECTHISVALUETHISFORMTXTDECIMALADDRESSREFRESHCHEXADDRESS�����\%�C��0�9��C��a�f��C��A�F��C�����	���	��
��y���C� �����UNKEYCODE
NSHIFTALTCTRLInteractiveChange,��KeyPress���1���A2���AA3:N
) 
commandbutton
commandbuttoncmdOKHexedit.frmGotoSect�Top = 108
Left = 56
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Caption = "OK"
Default = .F.
TabIndex = 3
Name = "cmdOK"
�PROCEDURE Click
#DEFINE ADDRESSBEYOND_LOC "Address beyond end of file.  Reading last sector."

WITH THISFORMSET
THISFORM.HIDE
.HexEditor.SHOW

IF ISBLANK(.cDecimalAddress)
	** No address to jump to.
	RETURN
ENDIF

.nDesiredLocation = VAL(.cDecimalAddress)

** Store old pointer location, in case of error.
nOldLocation = .nPointerLocation


IF .nDesiredLocation >= .nFileSize
	WAIT WINDOW ADDRESSBEYOND_LOC  NOWAIT
	.nDesiredLocation = INT(.nFileSize / 2048) * 2048
	IF .nDesiredLocation = .nFileSize
		.nDesiredLocation = .nDesiredLocation - 2048
	ENDIF
ENDIF

** Move file pointer.
.nPointerLocation = FSEEK(.nFileToEdit, .nDesiredLocation, 0)
IF .nPointerLocation < 0
	&& File seek error.  Report, then move pointer back where it was.
	.REPORTFILEERROR
	.nPointerLocation = FSEEK(.nFileToEdit, nOldLocation,0)
ENDIF

** File pointer is positioned.  Read the sector.
.ReadSector(0)
ENDWITH
ENDPROC
�� ��'�%+j:�UU
�����N�
���������%�C���Z��7�B��T��C�g��T�����%���	����<R,:��1Address beyond end of file.  Reading last sector.��T��C�	�8���%���	����T��������T��C�
�����%���
��<����T��C�
��������C������U
THISFORMSETTHISFORMHIDE	HEXEDITORSHOWCDECIMALADDRESSNDESIREDLOCATIONNOLDLOCATIONNPOINTERLOCATION	NFILESIZENFILETOEDITREPORTFILEERROR
READSECTORClick,��1���BA�3��1AAA�!�qA�A1�)�
commandbutton
commandbutton	cmdCancelHexedit.frmGotoSect�Top = 108
Left = 232
Height = 23
Width = 72
FontName = "MS Sans Serif"
FontSize = 8
Cancel = .T.
Caption = "Cancel"
TabIndex = 4
Name = "cmdCancel"
)PROCEDURE Click
THISFORM.HIDE
ENDPROC
�� ���%Mb\�U

����UTHISFORMHIDEClick,��1�1)�labellabelLabel1Hexedit.frmGotoSect�FontName = "MS Sans Serif"
FontSize = 8
Alignment = 1
Caption = "Decimal:"
Height = 25
Left = 21
Top = 64
Width = 80
TabIndex = 5
Name = "Label1"
labellabelLabel2Hexedit.frmGotoSect�FontName = "MS Sans Serif"
FontSize = 8
Alignment = 1
Caption = "Hex:"
Height = 25
Left = 21
Top = 20
Width = 80
TabIndex = 6
Name = "Label2"
LArial, 0, 9, 5, 15, 12, 32, 3, 0
MS Sans Serif, 0, 8, 5, 13, 11, 11, 2, 0
Courier, 0, 8, 8, 13, 11, 8, 2, 0
Courier New, 0, 9, 7, 15, 12, 8, 3, 0
Courier, 0, 9, 8, 13, 11, 8, 2, 0
MS Sans Serif, 0, 9, 5, 13, 11, 11, 2, 0
Arial, 0, 10, 6, 16, 13, 35, 3, 0
MS Sans Serif, 1, 10, 8, 16, 13, 15, 3, 0
Courier, 1, 10, 9, 13, 11, 9, 2, 0