Click here to Skip to main content
15,896,201 members
Articles / Programming Languages / C++

HexEdit - Window Binary File Editor

Rate me:
Please Sign up or sign in to vote.
4.96/5 (137 votes)
17 Oct 2012MIT45 min read 497.4K   22.4K   321  
Open-source hex editor with powerful binary templates
// CoordAp.h : coordinate classes with 64 bit vertical resolution
//
// Copyright (c) 2011 by Andrew W. Phillips.
//
// This file is distributed under the MIT license, which basically says
// you can do what you want with it but I take no responsibility for bugs.
// See http://www.opensource.org/licenses/mit-license.php for full details.
//

/////////////////////////////////////////////////////////////////////////////
#ifndef COORDAP_INCLUDED_
#define COORDAP_INCLUDED_  1

#include <windef.h>

// This includes 3 classes CSizeAp, CPointAp and CRectAp that are drop-in
// replacements for the MFC CSize, CPoint and CRect classes.  These were
// created in 2.1 to enable large files to be edited.  Version 2.0 of HexEdit
// was limited to 2^31 pixels which limited (along with other things) the size
// of files that could be edited to a few Gbytes at most.

class CPointAp;
class CRectAp;

class CSizeAp
{
public:
	int cx;
	__int64 cy;

// Constructors
	CSizeAp() { ASSERT((cx = (int)0xCDCDCDCD, cy = 0xCDCDCDCDCDCDCDCD, TRUE)); }
	CSizeAp(int initCX, __int64 initCY) { cx = initCX, cy = initCY; }
	CSizeAp(const SIZE &initSize) { cx = initSize.cx; cy = __int64(initSize.cy); }
	CSizeAp(const POINT &initPt) { cx = initPt.x; cy = __int64(initPt.y); }
	CSizeAp(const CPointAp &initPt);
//    CSizeAp(const CSizeAp &initSize) { cx = initSize.cx; cy = initSize.cy; }

// Operations
	BOOL operator==(const CSizeAp &size) const { return (cx == size.cx && cy == size.cy); }
	BOOL operator!=(const CSizeAp &size) const { return (cx != size.cx || cy != size.cy); }
	void operator+=(const CSizeAp &size) { cx += size.cx; cy += size.cy; }
	void operator-=(const CSizeAp &size) { cx -= size.cx; cy -= size.cy; }

// Operators returning CSizeAp values
	CSizeAp operator+(const CSizeAp &size) const { return CSizeAp(cx + size.cx, cy + size.cy); }
	CSizeAp operator-(const CSizeAp &size) const { return CSizeAp(cx - size.cx, cy - size.cy); }
	CSizeAp operator-() const { return CSizeAp(-cx, -cy); }

// Operators returning CPointAp values
	CPointAp operator+(const CPointAp &point) const;
	CPointAp operator-(const CPointAp &point) const;

// Operators returning CRectAp values
	CRectAp operator+(const CRectAp &rect) const;
	CRectAp operator-(const CRectAp &rect) const;
};


class CPointAp
{
public:
	int x;
	__int64 y;

// Constructors
	CPointAp() { ASSERT((x = (int)0xCDCDCDCD, y = 0xCDCDCDCDCDCDCDCD, TRUE)); }
	CPointAp(int initX, __int64 initY) { x = initX; y = initY; }
	CPointAp(const POINT &initPt) { x = initPt.x; y = __int64(initPt.y); }
	CPointAp(const SIZE &initSize) { x = initSize.cx; y = __int64(initSize.cy); }
//  CPointAp(const CPointAp &initPt)  { x = initPt.x; y = initPt.y); }
	CPointAp(const CSizeAp &initSize) { x = initSize.cx; y = initSize.cy; }

// Operations
	void Offset(int xOffset, __int64 yOffset) { x += xOffset; y += yOffset; }
	void Offset(const CPointAp &point) { x += point.x; y += point.y; }
	void Offset(const SIZE &size) { x += size.cx; y += size.cy; }

	BOOL operator==(const CPointAp &point) const { return (x == point.x && y == point.y); }
	BOOL operator!=(const CPointAp &point) const { return (x != point.x || y != point.y); }
	void operator+=(const CSizeAp &size) { x += size.cx; y += size.cy; }
	void operator-=(const CSizeAp &size) { x -= size.cx; y -= size.cy; }
	void operator+=(const CPointAp &point) { x += point.x; y += point.y; }
	void operator-=(const CPointAp &point) { x -= point.x; y -= point.y; }

// Operators returning CPointAp values
	CPointAp operator+(const CSizeAp &size) const { return CPointAp(x + size.cx, y + size.cy); }
	CPointAp operator-(const CSizeAp &size) const { return CPointAp(x - size.cx, y - size.cy); }
	CPointAp operator-() const { return CPointAp(-x, -y); }
	CPointAp operator+(const CPointAp &point) const{ return CPointAp(x + point.x, y + point.y); }

// Operators returning CSizeAp values
	CSizeAp operator-(const CPointAp &point) const { return CSizeAp(x - point.x, y - point.y); }

// Operators returning CRectAp values
	CRectAp operator+(const CRectAp &rect) const;
	CRectAp operator-(const CRectAp &rect) const;
};

class CRectAp
{
public:
	LONG left, right;
	__int64 top, bottom;

// Constructors
	CRectAp() { ASSERT((left = right = (LONG)0xCDCDCDCD, top = bottom = 0xCDCDCDCDCDCDCDCD, TRUE)); }
	CRectAp(int l, __int64 t, int r, __int64 b) : left(l), right(r), top(t), bottom(b) { }
	CRectAp(const RECT &srcRect) { left = srcRect.left; top = __int64(srcRect.top); right = srcRect.right; bottom = __int64(srcRect.bottom); }
	CRectAp(const RECT *pr) { left = pr->left; top = __int64(pr->top); right = pr->right; bottom = __int64(pr->bottom); }
	CRectAp(const CPointAp &point, const CSizeAp &size) { right = (left = point.x) + size.cx; bottom = (top = point.y) + size.cy; }
	CRectAp(const CPointAp &topLeft, const CPointAp &bottomRight) { left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; }

// Attributes
	int Width() const { return right - left; }
	__int64 Height() const { return bottom - top; }
	CSizeAp Size() const { return CSizeAp(right - left, bottom - top); }
	CPointAp TopLeft() { return CPointAp(left, top); }
	CPointAp BottomRight() { return CPointAp(right, bottom); }
	CPointAp CenterPoint() const { return CPointAp((left+right)/2, (top+bottom)/2); }
	void SwapLeftRight() { int temp = left; left = right; right = temp; }
	void SwapTopBottom() { __int64 temp = top; top = bottom; bottom = temp; }

	BOOL IsRectEmpty() const { return (right <= left || bottom <= top); }
	BOOL IsRectNull() const { return (left == 0 && right == 0 && top == 0 && bottom == 0); }
	BOOL PtInRect(const CPointAp &point) const { return point.x >= left && point.x < right && point.y >= top && point.y < bottom; }

// Operations
	void SetRect(int xx1, __int64 yy1, int xx2, __int64 yy2) { left = xx1; top = yy1; right = xx2; bottom = yy2; }
	void SetRect(const CPointAp &topLeft, const CPointAp &bottomRight)
				{ left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; }
	void SetRectEmpty() { left = right = 0; bottom = top = 0; }
	void CopyRect(const RECT *pr) { left = pr->left; top = __int64(pr->top); right = pr->right; bottom = __int64(pr->bottom); }
	BOOL EqualRect(const CRectAp &rect) const { return left == rect.left && right == rect.right && top == rect.top && bottom == rect.bottom; }

	// inflate rectangle's width and height
	void InflateRect(int x, __int64 y) { left -=x; top -= y; right += x; bottom += y; }
	void InflateRect(const CSizeAp &size) { left -= size.cx; top -= size.cy; right += size.cx; bottom += size.cy; }
	void InflateRect(const RECT *lpRect) { left -= lpRect->left; top -= __int64(lpRect->top); right += lpRect->right; bottom += __int64(lpRect->bottom); }
	void InflateRect(int l, __int64 t, int r, __int64 b) { left -= l; top -= t; right += r; bottom += b; }
	// deflate the rectangle's width and height
	void DeflateRect(int x, __int64 y) { left +=x; top += y; right -= x; bottom -= y; }
	void DeflateRect(const SIZE &size) { left += size.cx; top += size.cy; right -= size.cx; bottom -= size.cy; }
	void DeflateRect(const RECT *lpRect) { left += lpRect->left; top += __int64(lpRect->top); right -= lpRect->right; bottom -= __int64(lpRect->bottom); }
	void DeflateRect(int l, __int64 t, int r, __int64 b) { left += l; top += t; right -= r; bottom -= b; }

	// translate the rectangle by moving its top and left
	void OffsetRect(int x, __int64 y) { left +=x; top += y; right += x; bottom += y; }
	void OffsetRect(const CSizeAp &size) { left += size.cx; top += size.cy; right += size.cx; bottom += size.cy; }
	void OffsetRect(const CPointAp &point)  { left += point.x; top += point.y; right += point.x; bottom += point.y; }
	void NormalizeRect() { if (right < left) SwapLeftRight();  if (bottom < top) SwapTopBottom(); }

	// set this rectangle to intersection of two others
	BOOL IntersectRect(const CRectAp &r1, const CRectAp &r2)
	{
		BOOL retval = r1.left < r2.right && r2.left < r1.right && r1.top < r2.bottom && r2.top < r1.bottom;
		if (retval)
		{
			left = max(r1.left, r2.left);
			right = min(r1.right, r2.right);
			ASSERT(left <= right);
			top = max(r1.top, r2.top);
			bottom = min(r1.bottom, r2.bottom);
			ASSERT(top <= bottom);
		}
		else
		{
			left = right = 0;
			bottom = top = 0;
		}
		return retval;
	}

	// set this rectangle to bounding union of two others
	BOOL UnionRect(const CRectAp &r1, const CRectAp &r2)
	{
		BOOL b1 = r1.IsRectEmpty();
		BOOL b2 = r2.IsRectEmpty();
		if (b1 && b2)
		{
			left = right = 0;
			bottom = top = 0;
			return FALSE;
		}
		else if (b1)
			*this = r2;
		else if (b2)
			*this = r1;
		else
		{
			left = min(r1.left, r2.left);
			right = max(r1.right, r2.right);
			top = min(r1.top, r2.top);
			bottom = max(r1.bottom, r2.bottom);
		}
		ASSERT(!IsRectEmpty());
		return TRUE;
	}

// Additional Operations
	void operator=(const RECT &srcRect) { left = srcRect.left; top = __int64(srcRect.top); right = srcRect.right; bottom = __int64(srcRect.bottom); }
	BOOL operator==(const CRectAp &r) const { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
	BOOL operator!=(const CRectAp &r) const { return !(left == r.left && top == r.top && right == r.right && bottom == r.bottom); }

	void operator+=(const CPointAp &point) { left += point.x; top += point.y; right += point.x; bottom += point.y; }
	void operator+=(const CSizeAp &size)  { left += size.cx; top += size.cy; right += size.cx; bottom += size.cy; }
	void operator-=(const CPointAp &point) { left -= point.x; top -= point.y; right -= point.x; bottom -= point.y; }
	void operator-=(const CSizeAp &size)  { left -= size.cx; top -= size.cy; right -= size.cx; bottom -= size.cy; }

// Operators returning CRectAp values
	CRectAp operator+(const CPointAp &point) const { return CRectAp(left + point.x, top + point.y, right + point.x, bottom + point.y); }
	CRectAp operator-(const CPointAp &point) const { return CRectAp(left - point.x, top - point.y, right - point.x, bottom - point.y); }
	CRectAp operator+(const CSizeAp &size) const  { return CRectAp(left + size.cx, top + size.cy, right + size.cx, bottom + size.cy); }
	CRectAp operator-(const CSizeAp &size) const  { return CRectAp(left - size.cx, top - size.cy, right - size.cx, bottom - size.cy); }
};

// These could not be added above due to circular references
inline CSizeAp::CSizeAp(const CPointAp &initPt)  { cx = initPt.x; cy = initPt.y; }
inline CPointAp CSizeAp::operator+(const CPointAp &point) const { return CPointAp(cx + point.x, cy + point.y); }
inline CPointAp CSizeAp::operator-(const CPointAp &point) const { return CPointAp(cx - point.x, cy - point.y); }
inline CRectAp CSizeAp::operator+(const CRectAp &rect) const { return CRectAp(rect) + *this; }
inline CRectAp CSizeAp::operator-(const CRectAp &rect) const { return CRectAp(rect) - *this; }

inline CRectAp CPointAp::operator+(const CRectAp &rect) const { return CRectAp(rect) + *this; }
inline CRectAp CPointAp::operator-(const CRectAp &rect) const { return CRectAp(rect) - *this; }

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Australia Australia
Andrew has a BSc (1983) from Sydney University in Computer Science and Mathematics. Andrew began programming professionally in C in 1984 and has since used many languages but mainly C, C++, and C#.

Andrew has a particular interest in STL, .Net, and Agile Development. He has written articles on STL for technical journals such as the C/C++ User's Journal.

In 1997 Andrew began using MFC and released the source code for a Windows binary file editor called HexEdit, which was downloaded more than 1 million times. From 2001 there was a shareware version of HexEdit (later called HexEdit Pro). HexEdit has been updated to uses the new MFC (based on BCG) and is once more open source.

Comments and Discussions