Hex Control, C++/MFC
Table of Contents
- Introduction
- Installation
- Creating
- Set The Data
- Data Modes
- Virtual Bookmarks
- IHexVirtColors
- Methods
Expand
- BkmAdd
- BkmClearAll
- BkmGetByID
- BkmGetByIndex
- BkmGetCount
- BkmHitTest
- BkmRemoveByID
- BkmSetVirtual
- ClearData
- Create
- CreateDialogCtrl
- Destroy
- ExecuteCmd
- GetCapacity
- GetCaretPos
- GetColors
- GetEncoding
- GetFontSize
- GetMenuHandle
- GetSectorSize
- GetSelection
- GetShowMode
- GetWindowHandle
- GoToOffset
- HitTest
- IsCmdAvail
- IsCreated
- IsDataSet
- IsMutable
- IsOffsetAsHex
- SetCapacity
- SetColors
- SetData
- SetEncoding
- SetFont
- SetFontSize
- SetMutable
- SetSectorSize
- SetSelection
- SetShowMode
- SetWheelRatio
- ShowDlg
- Structures
- Notification Messages
- Exported Functions
- Positioning and Sizing
- Appearance
- Licensing
Introduction
Being good low level library on top of Windows API in general, MFC was always lacking a good native controls support. This HexControl is an attempt to expand standard MFC functionality, because at the moment MFC doesn't provide support for such control.
This doesn't mean that HexControl is limited to use only in MFC environment. The control is implemented as a pure abstract interface, and can be used as a child or popup window in any place of your application.
It is written and tested with /std:c++17 in Visual Studio 2019, under the Windows 10.
The main features of the HexControl:
- View and edit data up to 16EB (exabyte)
- Work in three different data modes: Memory, Message, Virtual.
- Fully featured Bookmarks manager
- Search and Replace... for Hex values, ASCII or UTF-16 text
- Change encoding for the text area
- Many options to Copy/Paste to/from clipboard
- Undo/Redo
- Modify data with Filling and many predefined Operations options
- Ability to visually divide data into sectors
- Print whole document/pages range/selection
- Set individual colors for the data chunks with
IHexVirtColors
interface - Cutomizable look and appearance
- Written with /std:c++17 standard conformance
Installation
The HexControl can be used in two different ways:
- Building from the sources as a part of your project
- Using as a .dll.
Building From The Sources
The building process is quite simple:
- Copy HexCtrl folder and its content (except *.vcxproj files) into your project's folder.
- Add all files from that HexCtrl folder into your project.
- Add
#include "HexCtrl/HexCtrl.h"
where you suppose to use the control. - Declare
IHexCtrlPtr
member variable:IHexCtrlPtr myHex { CreateHexCtrl() };
- Create control instance.
If you want to build HexControl from the sources in non MFC app you will have to:
- Add support for Use MFC in a Shared DLL in your project settings.
- Uncomment the line
//#define HEXCTRL_MANUAL_MFC_INIT
inHexCtrl.h
header file.
Dynamic Link Library
To use HexControl as the .dll do the following:
- Copy HexCtrl.h file into your project's folder.
- Copy HexCtrl.lib file into your project's folder, so that linker can see it.
- Put HexCtrl.dll file next to your .exe file.
- Add the following line where you suppose to use the control:
#define HEXCTRL_SHARED_DLL //You can alternatively uncomment this line in HexCtrl.h.
#include "HexCtrl.h"`
- Declare
IHexCtrlPtr
member variable:IHexCtrlPtr myHex { CreateHexCtrl() };
- Create control instance.
To build HexCtrl.dll and HexCtrl.lib use the HexCtrl/HexCtrl.vcxproj Visual Studio project.
Remarks:
HexControl's .dll is built with MFC Static Linking. So even if you are to use it in your own MFC project, even with different MFC version, there should not be any interferences
Building HexControl with MFC Shared DLL turned out to be a little tricky. Even with the help of AFX_MANAGE_STATE(AfxGetStaticModuleState())
macro there always were MFC debug assertions, which origins quite hard to comprehend.
IHexCtrlPtr
IHexCtrlPtr
is, in fact, a pointer to a IHexCtrl
pure abstract base class, wrapped either in std::unique_ptr
or std::shared_ptr
. You can choose whatever is best for your needs by define or undefine/comment-out the HEXCTRL_IHEXCTRLPTR_UNIQUEPTR
macro in HexCtrl.h.
By default HEXCTRL_IHEXCTRLPTR_UNIQUEPTR
is defined, thus IHexCtrlPtr
is an alias for std::unique_ptr<IHexCtrl>
.
This wrapper is used mainly for convenience, so you don't have to bother about object lifetime, it will be destroyed automatically.
That's why there is a call to the factory function CreateHexCtrl()
- to properly initialize a pointer.
If you, for some reason, need a raw interface pointer, you can directly call CreateRawHexCtrl
function, which returns IHexCtrl
interface pointer, but in this case you will need to call Destroy
method manually afterwards, to destroy IHexCtrl
object.
Namespace
HexControl uses its own namespace HEXCTRL
.
So it's up to you, whether to use namespace prefix before declarations:
HEXCTRL::
or to define namespace globally, in the source file's beginning:
using namespace HEXCTRL;
Creating
Classic Approach
Create
is the first method you call to create HexControl instance. It takes HEXCREATESTRUCT
reference as an argument.
You can choose whether control will behave as a child or independent popup window, by setting enCreateMode
member of this struct to EHexCreateMode::CREATE_CHILD
or EHexCreateMode::CREATE_POPUP
respectively.
HEXCREATESTRUCT hcs;
hcs.enCreateMode = EHexCreateMode::CREATE_POPUP;
hcs.hwndParent = m_hWnd;
m_myHex->Create(hcs);
For all available options see HEXCREATESTRUCT
description.
In Dialog
To use HexControl within Dialog you can, of course, create it with the Classic Approach, call Create
method and provide all the necessary information.
But there is another option you can use:
- Put Custom Control from the Toolbox in Visual Studio dialog designer into your dialog template and make it desirable size.
- Go to the Properties of that control and in the Class field, within the Misc section, type: HexCtrl.
Give the control appropriate ID of your choise (IDC_MY_HEX in this example).
Also, here you can set the control's Dynamic Layout properties, so that control behaves appropriately when dialog is being resized.
- Declare
IHexCtrlPtr
member varable within your dialog class:
IHexCtrlPtr m_myHex { CreateHexCtrl() };
- Call
CreateDialogCtrl
method from your dialog'sOnInitDialog
method.
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_myHex->CreateDialogCtrl(IDC_MY_HEX, m_hWnd);
}
Set the Data
To set a data to display in the HexControl use SetData
method.
The code below shows how to construct IHexCtrlPtr
object and display first 0x1FF
bytes of the current app's memory:
IHexCtrlPtr myHex { CreateHexCtrl() };
HEXCREATESTRUCT hcs;
hcs.hwndParent = m_hWnd;
hcs.rect = {0, 0, 600, 400}; //Window rect.
myHex->Create(hcs);
HEXDATASTRUCT hds;
hds.pData = (unsigned char*)GetModuleHandle(0);
hds.ullDataSize = 0x1FF;
myHex->SetData(hds);
The next example displays std::string
's text as hex:
std::string str = "My string";
HEXDATASTRUCT hds;
hds.pData = (unsigned char*)str.data();
hds.ullDataSize = str.size();
myHex->SetData(hds);
Data Modes
Besides the standard classical mode, when HexControl just holds a pointer to some array of bytes in memory, it also has additional advanced modes it can be running in.
These modes can be quite useful for instance in cases where you need to display a very large amount of data that can't fit in memory all at once.
These modes are ruled over through the enDataMode
member of HEXDATASTRUCT
.
Memory Data
It's the default data mode the control works in.
The enDataMode
member of the HEXDATASTRUCT
is set to DATA_MEMORY
, and pData
just points to bytes in memory.
Message Window
If enDataMode
member of HEXDATASTRUCT
is set to DATA_MSG
, the control works in, so called, Message Window mode.
What it means is that when control is about to display data, it will first ask for this data from the HEXDATASTRUCT::hwndMsg
window, in the form of WM_NOTIFY Windows' message. This is pretty much the same as the standard MFC List Control works when created with LVS_OWNERDATA
flag.
By default the HEXDATASTRUCT::hwndMsg
is equal to the control's parent window.
To properly handle this mode, you must process WM_NOTIFY
messages in hwndMsg
window as follows:
BOOL CMyWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
PHEXNOTIFYSTRUCT pHexNtfy = (PHEXNOTIFYSTRUCT)lParam;
if (pHexNtfy->hdr.idFrom == IDC_MY_HEX)
{
switch (pHexNtfy->hdr.code)
{
case HEXCTRL_MSG_GETDATA:
/**************************************************************************
* pHexNtfy->stSpan at this moment shows offset and size of the data
* that HexCtrl requests. You have to provide pointer to it.
***************************************************************************
pHexNtfy->pData = /*Set this pointer to an actual data*/;
break;
}
}
}
lParam
will hold a pointer to the HEXNOTIFYSTRUCT
structure.
The first member of this structure is a standard Windows' NMHDR struct, it will have its code
member equal to HEXCTRL_MSG_GETDATA
, indicating that HexControl's byte request has arrived.
The ullIndex
member of the structure is an index of the byte to be displayed. And the pData
is the pointer to an actual byte that you have to set in response.
Virtual Handler
If enDataMode
member of HEXDATASTRUCT
is set to DATA_VIRTUAL
then all the data routine will be done through HEXDATASTRUCT::pHexVirtual
pointer.
This pointer is of IHexVirtData
class type, which is a pure abstract base class.
You have to derive your own class from it and implement all its public methods:
class IHexVirtData
{
public:
[[nodiscard]] virtual std::byte* GetData(const HEXSPANSTRUCT&) = 0; //Data index and size to get.
virtual void SetData(std::byte*, const HEXSPANSTRUCT&) = 0; //Routine to modify data, if HEXDATASTRUCT::fMutable == true.
};
Then provide a pointer to created object of this derived class prior to call to SetData
method in form of HEXDATASTRUCT::pHexVirtData = &yourDerivedObject
.
Virtual Bookmarks
HexControl has innate functional to work with any amount of bookmarked regions. These regions can be assigned with individual background and text color and description.
But if you have some big and complicated data logic and want to handle all these regions yourself, you can do it.
virtuvoid SetData(std::byte*, const HEXSPANSTRUCT&) = 0; //Routine to modify data, if HEXDATASTRUCT::fMutable == true.
To enable virtual bookmarks call the BkmSetVirtual
method.
The main method of the IHexVirtBkm
interface is HitTest
. It takes byte's offset and returns pointer to HEXBKMSTRUCT
if there is a bookmark withing this byte, or nullptr
otherwise.
class IHexVirtBkm
{
public:
virtual ULONGLONG Add(const HEXBKMSTRUCT& stBookmark) = 0; //Add new bookmark, return new bookmark's ID.
virtual void ClearAll() = 0; //Clear all bookmarks.
[[nodiscard]] virtual ULONGLONG GetCount() = 0; //Get total bookmarks count.
[[nodiscard]] virtual auto GetByID(ULONGLONG ullID)->HEXBKMSTRUCT* = 0; //Bookmark by ID.
[[nodiscard]] virtual auto GetByIndex(ULONGLONG ullIndex)->HEXBKMSTRUCT* = 0; //Bookmark by index (in inner list).
[[nodiscard]] virtual auto HitTest(ULONGLONG ullOffset)->HEXBKMSTRUCT* = 0; //Has given offset the bookmark?
virtual void RemoveByID(ULONGLONG ullID) = 0; //Remove bookmark by given ID (returned by Add()).
};
IHexVirtColors
This interface is used to set custom bk/text colors for the given data offset.
To provide the color a pointer to the valid HEXCOLOR
structure must be returned from the IHexVirtColors::GetColor
method. If nullptr
is returned the default colors will be used.
In order to use this interface the HEXDATASTRUCT::pHexVirtColors
member must be set to the valid class inherited from this interface, prior to calling SetData
method.
class IHexVirtColors
{
public:
[[nodiscard]] virtual PHEXCOLOR GetColor(ULONGLONG ullOffset) = 0;
};
Methods
The HexControl has plenty of methods that you can use to customize its appearance, and to manage its behaviour.
BkmAdd
ULONGLONG BkmAdd(const HEXBKMSTRUCT& hbs, bool fRedraw = false)
Adds new bookmark to the control. Uses HEXBKMSTRUCT
as an argument. Returns created bookmark's id.
Example
HEXBKMSTRUCT hbs;
hbs.vecSpan.emplace_back(HEXSPANSTRUCT { 0x1, 10 });
hbs.clrBk = RGB(0, 255, 0);
hbs.clrText = RGB(255, 255, 255);
hbs.wstrDesc = L"My first bookmark, with green bk and white text.";
myHex.BkmAdd(hbs);
BkmClearAll
void BkmClearAll();
Clears all bookmarks.
BkmGetByID
BkmGetByID(ULONGLONG ullID)->HEXBKMSTRUCT*;
Get bookmark by ID.
BkmGetByIndex
auto BkmGetByIndex(ULONGLONG ullIndex)->HEXBKMSTRUCT*;
Get bookmark by Index.
BkmGetCount
ULONGLONG BkmGetCount()const;
Get bookmarks' count.
BkmHitTest
auto BkmHitTest(ULONGLONG ullOffset)->HEXBKMSTRUCT*;
Test given offset and retrives pointer to HEXBKMSTRUCT
if it contains bookmark.
BkmRemoveByID
void BkmRemoveByID(ULONGLONG ullID);
Removes bookmark by the given ID.
BkmSetVirtual
void BkmSetVirtual(bool fEnable, IHexVirtBkm* pVirtual = nullptr);
Enables or disables bookmarks virtual mode.
ClearData
void ClearData();
Clears data from the HexControl view, not touching data itself.
Create
bool Create(const HEXCREATESTRUCT& hcs);
Main initialization method.
Takes HEXCREATESTRUCT
as argument. Returns true
if created successfully, false
otherwise.
CreateDialogCtrl
bool CreateDialogCtrl(UINT uCtrlID, HWND hwndDlg);
Creates HexControl from Custom Control dialog's template. Takes control's id, and dialog's window handle as arguments. See Creating section for more info.
Destroy
void Destroy();
Destroys the control.
You only invoke this method if you use a raw IHexCtrl
pointer obtained by the call to CreateRawHexCtrl
function. Otherwise don't use it.
Remarks
You usually don't need to call this method unless you use HexControl through the raw pointer obtained by CreateRawHexCtrl
factory function.
If you use HexControl in standard way, through the IHexCtrlPtr
pointer, obtained by CreateHexCtrl
function, this method will be called automatically.
ExecuteCmd
void ExecuteCmd(EHexCmd enCmd)const;
Executes one of the predefined commands of EHexCmd
enum. All these commands are basically replicating control's inner menu.
GetCapacity
DWORD GetCapacity()const
Returns current capacity.
GetCaretPos
ULONGLONG GetCaretPos()const;
Retrieves current caret position offset.
GetColors
auto GetColors()const->HEXCOLORSSTRUCT
Returns current HEXCOLORSSTRUCT
.
GetEncoding
int GetEncoding()const;
Get code page that is currently in use.
GetFontSize
long GetFontSize()const;
Returns current font size.
GetMenuHandle
HMENU GetMenuHandle()const;
Retrives the HMENU
handle of the control's context menu. You can use this handle to customize menu for your needs.
Control's internal menu uses menu ID
s in range starting from 0x8001
. So if you wish to add your own new menu, assign menu ID
starting from 0x9000
to not interfere.
When user clicks custom menu, control sends WM_NOTIFY
message to its parent window with LPARAM
pointing to HEXNOTIFYSTRUCT
with its hdr.code
member set to HEXCTRL_MSG_MENUCLICK
. ullData
field of the HEXNOTIFYSTRUCT
will be holding ID
of the menu clicked.
GetSectorSize
DWORD GetSectorSize()const;
Gets current sector size set by SetSectorSize
.
GetSelection
auto GetSelection()const->std::vector<HEXSPANSTRUCT>&;
Returns std::vector
of offsets and sizes of the current selection.
GetShowMode
auto GetShowMode()const->EHexShowMode;
Retrieves current data show mode.
GetWindowHandle
HWND GetWindowHandle()const
Retrieves control's window handle.
GoToOffset
void GoToOffset(ULONGLONG ullOffset, bool fSelect, ULONGLONG ullSize)
Jumps to the ullOffset
offset, and selects ullSize
bytes if fSelect
is true
.
HitTest
auto HitTest(POINT pt, bool fScreen = true)const->std::optional<HEXHITTESTSTRUCT>
Hit testing of given point in screen fScreen = true
, or client fScreen = false
coordinates. In case of success returns HEXHITTESTSTRUCT
structure.
IsCmdAvail
bool IsCmdAvail(EHexCmd enCmd)const;
Returns true
if given command can be executed at the moment, false
otherwise.
IsCreated
bool IsCreated()const;
Shows whether HexControl is created or not yet.
IsDataSet
bool IsDataSet()const;
Shows whether a data was set to HexControl or not
IsMutable
bool IsMutable()const;
Shows whether HexControl is currently in edit mode or not.
IsOffsetAsHex
bool IsOffsetAsHex()const;
Is "Offset" currently represented (shown) as Hex or as Decimal. It can be changed by double clicking at offset area.
SetCapacity
void SetCapacity(DWORD dwCapacity);
Sets the HexControl current capacity.
SetEncoding
void SetEncoding(int iCodePage);
Sets the code page for the HexCtrl's text area. Takes code page identifier as an argument, or -1
for default ASCII-only characters.
Note: Code page identifier must represent Single-byte Character Set. Multi-byte character sets are not currently supported.
SetColors
void SetColors(const HEXCOLORSSTRUCT& clr);
Sets all the colors for the control. Takes HEXCOLORSSTRUCT
as the argument.
SetData
void SetData(const HEXDATASTRUCT& hds);
Main method to set data to display in read-only or edit modes. Takes HEXDATASTRUCT
as an argument.
SetFont
void SetFont(const LOGFONTW* pLogFontNew);
Sets a new font for the HexControl. This font has to be monospaced.
SetFontSize
void SetFontSize(UINT uiSize);
Sets a new font size to the HexControl.
SetMutable
void SetMutable(bool fEnable);
Enables or disables mutable mode. In mutable mode all the data can be modified.
SetSectorSize
void SetSectorSize(DWORD dwSize, const wchar_t* wstrName = L"Sector");
Sets the size of the sector to draw the divider line between. This size should be multiple to the current capacity size to take effect. The second argument sets the name to be displayed in the bottom info area of the HexControl ("Sector", "Page", "etc...").
To remove the divider just set dwSize
to 0.
SetSelection
void SetSelection(const std::vector<HEXSPANSTRUCT>& vecSel);
Sets current selection.
SetShowMode
void SetShowMode(EHexShowMode enShowMode);
Sets current data show mode. See EHexShowMode
for more info.
SetWheelRatio
void SetWheelRatio(double dbRatio)
Sets the ratio for how much to scroll with mouse-wheel.
ShowDlg
void ShowDlg(EHexDlg enDlg, bool fShow)const;
Show or hide HexControl's internal dialog window, from EHexDlg
enum.
Structures
Below are listed all HexControl's structures.
HEXCREATESTRUCT
The main initialization struct used for control creation.
struct HEXCREATESTRUCT
{
EHexCreateMode enCreateMode { EHexCreateMode::CREATE_CHILD }; //Creation mode of the HexCtrl window.
EHexShowMode enShowMode { EHexShowMode::ASBYTE }; //Data representation mode.
HEXCOLORSSTRUCT stColor { }; //All the control's colors.
HWND hwndParent { }; //Parent window pointer.
const LOGFONTW* pLogFont { }; //Font to be used, nullptr for default. This font has to be monospaced.
RECT rect { }; //Initial rect. If null, the window is screen centered.
UINT uID { }; //Control ID.
DWORD dwStyle { }; //Window styles, 0 for default.
DWORD dwExStyle { }; //Extended window styles, 0 for default.
double dbWheelRatio { 1.0 }; //Ratio for how much to scroll with mouse-wheel.
};
HEXCOLORSSTRUCT
This structure describes all control's colors. All these colors have their default values.
struct HEXCOLORSSTRUCT
{
COLORREF clrTextHex { GetSysColor(COLOR_WINDOWTEXT) }; //Hex chunks text color.
COLORREF clrTextAscii { GetSysColor(COLOR_WINDOWTEXT) }; //Ascii text color.
COLORREF clrTextSelected { GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Selected text color.
COLORREF clrTextDataInterpret { RGB(250, 250, 250) }; //Data Interpreter text color.
COLORREF clrTextCaption { RGB(0, 0, 180) }; //Caption text color
COLORREF clrTextInfoRect { GetSysColor(COLOR_WINDOWTEXT) }; //Text color of the bottom "Info" rect.
COLORREF clrTextCursor { RGB(255, 255, 255) }; //Cursor text color.
COLORREF clrTextTooltip { GetSysColor(COLOR_INFOTEXT) }; //Tooltip text color.
COLORREF clrBk { GetSysColor(COLOR_WINDOW) }; //Background color.
COLORREF clrBkSelected { GetSysColor(COLOR_HIGHLIGHT) }; //Background color of the selected Hex/Ascii.
COLORREF clrBkDataInterpret { RGB(147, 58, 22) }; //Data Interpreter Bk color.
COLORREF clrBkInfoRect { GetSysColor(COLOR_BTNFACE) }; //Background color of the bottom "Info" rect.
COLORREF clrBkCursor { RGB(0, 0, 255) }; //Cursor background color.
COLORREF clrBkCursorSelected { RGB(0, 0, 200) }; //Cursor background color in selection.
COLORREF clrBkTooltip { GetSysColor(COLOR_INFOBK) }; //Tooltip background color.
};
HEXDATASTRUCT
Main struct to set a data to display in the control.
struct HEXDATASTRUCT
{
EHexDataMode enDataMode { EHexDataMode::DATA_MEMORY }; //Working data mode.
ULONGLONG ullDataSize { }; //Size of the data to display, in bytes.
HEXSPANSTRUCT stSelSpan { }; //Select .ullOffset initial position. Works only if .ullSize > 0.
HWND hwndMsg { }; //Window for DATA_MSG mode. Parent is used by default.
IHexVirtData* pHexVirtData { }; //Pointer for DATA_VIRTUAL mode.
IHexVirtColors* pHexVirtColors { }; //Pointer for Custom Colors class.
std::byte* pData { }; //Data pointer for DATA_MEMORY mode. Not used in other modes.
DWORD dwCacheSize { 0x800000 }; //In DATA_MSG and DATA_VIRTUAL max cached size of data to fetch.
bool fMutable { false }; //Is data mutable (editable) or read-only.
bool fHighLatency { false }; //Do not redraw window until scrolling completes.
};
HEXSPANSTRUCT
This struct is used mostly in selection and bookmarking routines. It holds offset and size of the data region.
struct HEXSPANSTRUCT
{
ULONGLONG ullOffset { };
ULONGLONG ullSize { };
};
HEXBKMSTRUCT
Structure for bookmarks, used in BkmAdd
method.
struct HEXBKMSTRUCT
{
std::vector<HEXSPANSTRUCT> vecSpan { }; //Vector of offsets and sizes.
std::wstring wstrDesc { }; //Bookmark description.
ULONGLONG ullID { }; //Bookmark ID, assigned internally by framework.
ULONGLONG ullData { }; //User defined custom data.
COLORREF clrBk { RGB(240, 240, 0) }; //Bk color.
COLORREF clrText { RGB(0, 0, 0) }; //Text color.
};
using PHEXBKMSTRUCT = HEXBKMSTRUCT*;
The member vecSpan
is of a std::vector<HEXSPANSTRUCT>
type because a bookmark may have few non adjacent areas. For instance, when selection is made as a block, with Alt pressed.
HEXNOTIFYSTRUCT
This struct is used in notification purposes, to notify parent window about HexControl's states.
struct HEXNOTIFYSTRUCT
{
NMHDR hdr { }; //Standard Windows header. For hdr.code values see HEXCTRL_MSG_* messages.
HEXSPANSTRUCT stSpan { }; //Offset and size of the bytes.
ULONGLONG ullData { }; //Data depending on message (e.g. user defined custom menu id/cursor pos).
std::byte* pData { }; //Pointer to a data to get/send.
POINT point { }; //Mouse position for menu notifications.
};
using PHEXNOTIFYSTRUCT = HEXNOTIFYSTRUCT*;
HEXHITTESTSTRUCT
Structure is used in HitTest
method.
struct HEXHITTESTSTRUCT
{
ULONGLONG ullOffset { }; //Offset.
bool fIsAscii { false }; //Is cursor at ASCII part or at Hex.
};
HEXCOLOR
HexCtrl custom colors.
struct HEXCOLOR
{
COLORREF clrBk { }; //Bk color.
COLORREF clrText { }; //Text color.
};
using PHEXCOLOR = HEXCOLOR*;
EHexCmd
Enum of commands HexCtrl can execute. Basically these commands duplicate inner menu.
enum class EHexCmd : WORD
{
CMD_SEARCH = 0x01, CMD_SEARCH_NEXT, CMD_SEARCH_PREV,
CMD_SHOWDATA_BYTE, CMD_SHOWDATA_WORD, CMD_SHOWDATA_DWORD, CMD_SHOWDATA_QWORD,
CMD_BKM_ADD, CMD_BKM_REMOVE, CMD_BKM_NEXT, CMD_BKM_PREV, CMD_BKM_CLEARALL, CMD_BKM_MANAGER,
CMD_CLIPBOARD_COPY_HEX, CMD_CLIPBOARD_COPY_HEXLE, CMD_CLIPBOARD_COPY_HEXFMT, CMD_CLIPBOARD_COPY_ASCII,
CMD_CLIPBOARD_COPY_BASE64, CMD_CLIPBOARD_COPY_CARR, CMD_CLIPBOARD_COPY_GREPHEX, CMD_CLIPBOARD_COPY_PRNTSCRN,
CMD_CLIPBOARD_PASTE_HEX, CMD_CLIPBOARD_PASTE_ASCII,
CMD_MODIFY_OPERS, CMD_MODIFY_FILLZEROS, CMD_MODIFY_FILLDATA, CMD_MODIFY_UNDO, CMD_MODIFY_REDO,
CMD_SEL_MARKSTART, CMD_SEL_MARKEND, CMD_SEL_SELECTALL,
CMD_DATAINTERPRET,
CMD_APPEARANCE_FONTINC, CMD_APPEARANCE_FONTDEC, CMD_APPEARANCE_CAPACITYINC, CMD_APPEARANCE_CAPACITYDEC,
CMD_PRINT, CMD_ABOUT
};
EHexCreateMode
Enum that represents mode the HexControl's window will be created in.
enum class EHexCreateMode : WORD
{
CREATE_CHILD, CREATE_POPUP, CREATE_CUSTOMCTRL
};
EHexDataMode
Enum
that represents current data mode HexControl works in. It's used as HEXDATASTRUCT
member in SetData
method.
enum class EHexDataMode : WORD
{
DATA_MEMORY, DATA_MSG, DATA_VIRTUAL
};
EHexDlg
All HexControl's internal dialog windows.
enum class EHexDlg : WORD
{
DLG_BKMMANAGER, DLG_DATAINTERPRET, DLG_FILLDATA, DLG_OPERS, DLG_SEARCH
};
EHexShowMode
Enum that represents available data show modes.
enum class EHexShowMode : WORD
{
ASBYTE = 1, ASWORD = 2, ASDWORD = 4, ASQWORD = 8
};
Notification Messages
During its work HexControl sends notification messages through WM_NOTIFY mechanism to indicate its states. These messages are sent either to HEXCREATESTRUCT::hwndParent
or to HEXDATASTRUCT::hwndMsg
window, depending on whether the latter is set.
The LPARAM
of the WM_NOTIFY
message will hold pointer to the HEXNOTIFYSTRUCT
.
HEXCTRL_MSG_BKMCLICK
Sent if bookmark is clicked. HEXNOTIFYSTRUCT::pData
will contain HEXBKMSTRUCT
pointer.
HEXCTRL_MSG_CARETCHANGE
Sent when caret position has changed. HEXNOTIFYSTRUCT::ullData
will contain current caret position.
HEXCTRL_MSG_CONTEXTMENU
Sent when context menu is about to be displayed.
HEXCTRL_MSG_DESTROY
Sent to indicate that HexControl window is about to be destroyed.
HEXCTRL_MSG_GETDATA
Used in DATA_MSG
mode to acquire the data range to display.
HEXCTRL_MSG_MENUCLICK
Sent when user defined custom menu has been clicked.
HEXNOTIFYSTRUCT
ullData
member contains menu ID, while point
member contains position of the cursor, in screen coordinates, at the time of the mouse click.
HEXCTRL_MSG_SELECTION
Sent when selection has been made.
HEXCTRL_MSG_SETDATA
Sent to indicate that the data has changed.
HEXCTRL_MSG_VIEWCHANGE
Sent when HexControl's view has changed, whether on resizing or scrolling. HEXNOTIFYSTRUCT::stSpan
will contain starting offset and size of the visible data.
Exported Functions
HexControl has few "C"
interface functions which it exports when built as .dll.
CreateRawHexCtrl
extern "C" HEXCTRLAPI IHexCtrl* __cdecl CreateRawHexCtrl();
Main function that creates raw IHexCtrl
interface pointer. You barely need to use this function in your code.
See the IHexCtrlPtr
section for more info.
GetHexCtrlInfo
extern "C" HEXCTRLAPI HEXCTRLINFO* __cdecl GetHexCtrlInfo();
Returns pointer to HEXCTRLINFO
, which is the HexControl's service information structure.
HEXCTRLINFO
Service structure, keeps HexControl's version information.
struct HEXCTRLINFO
{
const wchar_t* pwszVersion { }; //WCHAR version string.
union {
unsigned long long ullVersion { }; //ULONGLONG version number.
struct {
short wMajor;
short wMinor;
short wMaintenance;
short wRevision;
}stVersion;
};
};
Positioning and Sizing
To properly resize and position your HexControl's window you may have to handle WM_SIZE
message in its parent window, in something like this way:
void CMyWnd::OnSize(UINT nType, int cx, int cy)
{
//...
::SetWindowPos(m_myHex->GetWindowHandle(), this->m_hWnd, 0, 0, cx, cy, SWP_NOACTIVATE | SWP_NOZORDER);
}
Appearance
To change control's font size โ Ctrl+MouseWheel
To change control's capacity โ Ctrl+Shift+MouseWheel
Licensing
This software is available under the "MIT License modified with The Commons Clause".
Briefly: It is free for any non commercial use.
https://github.com/jovibor/HexCtrl/blob/master/LICENSE