jovibor/HexCtrl
GitHub: jovibor/HexCtrl
一个用纯 Win32 API 编写的高性能十六进制控件库,支持虚拟数据模式和 JSON 模板系统,适合嵌入到需要二进制数据查看编辑功能的 Windows 应用中。
Stars: 212 | Forks: 63
## Hex Control

## 目录
* [简介](#introduction)
* [如何构建](#how-to-build)
* [集成源码](#integrate-sources)
* [动态链接库](#dynamic-link-library)
* [创建](#creating)
* [经典方式](#classic-approach)
* [在对话框中](#in-dialog)
* [CreateHexCtrl](#createhexctrl)
* [设置数据](#setting-data)
* [虚拟数据模式](#virtual-data-mode)
* [虚拟书签](#virtual-bookmarks)
* [自定义颜色](#custom-colors)
* [模板](#templates)
* [方法](#methods)
* [结构体](#structures)
* [接口](#interfaces)
* [枚举](#enums)
* [通知消息](#notification-messages)
* [许可协议](#licensing)
## [](#)简介
**HexCtrl** 是一个用纯 **Win32 API** 编写的全功能十六进制控件。
### **HexCtrl** 的主要特性:
* 查看和编辑高达 **16EB** (exabyte) 的数据
* 两种工作模式:**内存** 模式和 [**虚拟数据模式**](#virtual-data-mode)
* 全功能的 **书签管理器**
* 全功能的 **查找和替换**
* 全功能的 **数据解释器**
* 支持任意分组大小的数据分组
* 可更改文本区域的代码页
* 丰富的剪贴板 **复制/粘贴** 选项
* 通过 **填充** 和许多预定义 **操作** 选项修改数据
* **撤销/重做**
* 能够以可视方式将数据划分为 [页面](#setpagesize)
* 打印整个文档/页面范围/选区
* 通过 [**自定义颜色**](#custom-colors) 定制数据颜色
* 强大的 [模板](#templates) 系统
* 通过外部配置文件 [分配键盘快捷键](#setconfig)
* 可定制的外观、字体和颜色
* 支持 **High-DPI**
* 利用 **AVX/AVX2** 指令集以获得最佳性能
* 支持为 **ARM64** 架构编译
* 使用 **/std:c++20** 标准一致性编写

## [](#)如何构建
`git clone https://github.com/jovibor/HexCtrl.git`
### [](#)集成源码
从源码构建 **HexCtrl**:
1. 将 `HexCtrl` 文件夹中的所有文件添加到您的项目中
2. 确保对项目中所有 `*.ixx` 文件禁用 **预编译头** (Precompiled Header)
3. 添加 `#include "HexCtrl.h"`
4. 声明 **HexCtrl** 对象:`auto myHex { HEXCTRL::CreateHexCtrl() };`
5. [创建](#creating)控件实例
### [](#)动态链接库
将 **HexCtrl** 构建并用作 DLL:
1. 使用 **HexCtrl DLL.vcxproj** 项目构建 **HexCtrl{x86/x64/ARM64}.dll** 和 **HexCtrl{x86/x64/ARM64}.lib**
2. 将 `HexCtrl.h` 头文件添加到您的项目中
3. 添加 `/DHEXCTRL_DYNAMIC_LIB` 编译器选项,或者在包含 `HexCtrl.h` 之前 `#define` 它:
#define HEXCTRL_DYNAMIC_LIB
#include "HexCtrl.h"
4. 声明 `IHexCtrlPtr` 对象:`auto myHex { HEXCTRL::CreateHexCtrl() };`
5. [创建](#creating)控件实例
## [](#)创建
### [](#)经典方式
首先您需要创建 **HexCtrl** 对象:
```
auto myHex { HEXCTRL::CreateHexCtrl() };
```
然后调用 [`Create`](#create) 方法,该方法接受 [`HEXCREATE`](#hexcreate) 结构体,其中包含创建 **HexCtrl** 所需的所有信息。`HEXCREATE::dwStyle` 和 `dwExStyle` 分别是 [窗口样式](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles) 和 [扩展窗口样式](https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles),根据您的需要设置这些样式。有关所有可用选项,请参阅 [`HEXCREATE`](#hexcreate) 结构体说明。
### [](#)在对话框中
要在对话框中使用 **HexCtrl**,您可以使用 [经典方式](#classic-approach) 创建它:调用 [`Create`](#create) 方法并提供所有必要的信息。
但还有另一种选择:
1. 在 **Visual Studio** 对话框编辑器中,从 **工具箱** 中将 **Custom Control** 拖放到您的对话框模板上。
 
2. 在该控件的 **属性** 窗口中,找到 **Misc** 部分的 **Class** 字段,并写入:**HexCtrl_MainWnd**。
3. 在您的对话框类中声明 `IHexCtrlPtr` 成员变量:
HEXCTRL::IHexCtrlPtr m_myHex { CreateHexCtrl() };
4. 在对话框的 `OnInitDialog` 方法中调用 [`CreateDialogCtrl`](#createdialogctrl ) 方法。
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
m_myHex->CreateDialogCtrl(IDC_MY_HEX, m_hWnd);
}
### [](#)CreateHexCtrl
```
[[nodiscard]] IHexCtrlPtr CreateHexCtrl();
```
这是创建 **HexCtrl** 对象的主要工厂函数。`IHexCtrlPtr` 类是一个封装了 `IHexCtrl` 接口指针的标准 `std::unique_ptr`,带有自定义删除器,因此您无需担心其销毁问题。
## [](#)设置数据
要为 **HexCtrl** 设置数据,需使用 [`SetData`](#setdata) 方法。下面的代码展示了如何构造 `HexCtrl` 对象并显示当前应用程序内存的前 `0x1FF` 个字节:
```
IHexCtrlPtr myHex { CreateHexCtrl() };
HEXCREATE hcs;
hcs.hWndParent = m_hWnd;
hcs.rect = {0, 0, 600, 400}; //Window rect.
myHex->Create(hcs);
HEXDATA hds;
hds.spnData = { reinterpret_cast(GetModuleHandle(nullptr)), 0x1FF };
myHex->SetData(hds);
```
下一个示例展示了如何将 `std::string` 的文本显示为十六进制数据:
```
std::string str = "My string";
HEXDATA hds;
hds.spnData = { reinterpret_cast(str.data()), str.size() };
myHex->SetData(hds);
```
## [](#)虚拟数据模式
除了标准模式(即 **HexCtrl** 仅持有指向内存中数据的指针)之外,它还可以在 **虚拟** 模式下工作。此模式在您需要显示无法一次性装入内存的海量数据时非常有用。
如果设置了 `HEXDATA::pHexVirtData` 指针,则整个数据例程将通过它完成。该指针属于 [`IHexirtData`](#ihexvirtdata) 类类型,这是一个纯抽象基类。
您必须从中派生出自己的类并实现其所有公共方法。
然后在调用 [`SetData`](#setdata) 方法之前,通过 `HEXDATA::pHexVirtData` 成员提供指向此派生类已创建对象的指针。
## [](#)虚拟书签
**HexCtrl** 具有处理任意数量书签区域的内在功能。这些区域可以指定单独的背景色、文本色和描述。
但是,如果您拥有庞大且复杂的数据逻辑,并希望自行处理所有这些书签,则可以借助 **虚拟书签** 模式来实现。在此模式下,所有书签的负担都由您自己通过实现 [`IHexBookmarks`](#ihexbookmarks) 接口来处理,并通过调用 [`SetVirtualBkm`](#setvirtualbkm) 方法将该实现的指针提供给 **HexCtrl**。
## [](#)自定义颜色
如果您希望使用自己的自定义颜色为数据区域着色,请使用 [`IHexVirtColors`](#ihexvirtcolors) 接口。
要使用它,请在调用 [`SetData`](#setdata) 方法之前,将 [`HEXDATA::pHexVirtColors`](#hexdata) 成员设置为实现了此接口的您自己类的有效实例。
此接口的 `OnHexGetColor` 方法接受 [`HEXCOLORINFO`](#hexcolorinfo) 结构体作为参数。`HEXCOLORINFO::ullOffset` 成员指示请求颜色的偏移量。如果该方法为给定偏移量设置了自定义颜色,则应返回 `true`;如果使用默认颜色,则返回 `false`。
## [](#)模板

**HexCtrl** 的模板是一个强大的数据结构描述系统,使用简单的 `.json` 文件。这些文件可以通过 **HexControl** 的内部模板管理器加载,也可以通过 [API](#gettemplates) 加载。
```
{
"$schema": "https://raw.githubusercontent.com/jovibor/HexCtrl/master/docs/HexCtrl.Templates.Schema.json",
"TemplateName": "SampleTemplate",
"Data": {
"endianness": "little",
"clrBk": "#999999",
"clrText": "#FFFFFF",
"Fields": [
{
"name": "MyCustomDataSingle",
"type": "MyCustomType"
},
{
"name": "CustomComplexData",
"type": "MyCustomComplexType"
},
{
"name": "ArrayOfDWORDs",
"type": "DWORD",
"array": 10
},
{
"name": "MyCustomDataArray",
"type": "MyCustomType",
"array": 4
}
]
},
"CustomTypes": [
{
"TypeName": "MyCustomType",
"Fields": [
{
"name": "myCustomTypeField1",
"type": "DWORD"
},
{
"name": "myCustomTypeField2",
"type": "DWORD"
}
]
},
{
"TypeName": "MyCustomComplexType",
"Fields": [
{
"name": "MyCustomTypeData1",
"type": "MyCustomType"
},
{
"name": "MyCustomTypeData2",
"type": "MyCustomType"
}
]
}
]
}
```
每个此类文件包含以下属性:
- **TemplateName** [必需, 字符串] - 模板的名称
- **Data** [必需, 对象] - 包含所有模板字段信息的主对象
- **CustomTypes** [可选, 数组] - 用户自定义类型的数组,随后可在 **Fields** 的 **type** 属性中引用
**CustomTypes** 对象与 **Fields** 对象相同,唯一的区别是 **Fields** 对象没有 **TypeName** 属性。
每个 **Data** 或 **CustomType** 对象都包含带有实际结构体成员的 **Fields** 属性。
**Fields** [数组] - 是一个对象数组,其中每个对象代表一个结构体数据成员。任何此类对象都可以有自己的 **Fields** 子对象,这些子对象将代表嵌套结构体。
**Fields** 的属性包括:
- **name** - [必需, 字符串] - 字段名称
- **description** - [可选, 字符串] - 字段描述
- **type** - [可选, 字符串] - 字段类型,例如:
`bool`, `char`, `unsigned char`, `byte`, `short`, `unsigned short`, `WORD`, `long`, `unsigned long`, `int`, `unsigned int`, `DWORD`, `long long`, `unsigned long long`, `QWORD`, `float`, `double`, `time32_t`, `time64_t`, `FILETIME`, `SYSTEMTIME`, `GUID`, 或在 **CustomTypes** 部分定义的任何自定义类型
- **size** - [可选, 整数] - 字段的字节大小,如果未提供 **type** 字段
- **array** - [可选, 整数] - 数组的大小,如果给定字段是字段数组
- **endianness** - [可选, 字符串] - 字段字节序,"little" 或 "big"。默认情况下所有字段都是小端序。
- **clrBk** - [可选, 字符串] - 字段背景色
- **clrText** - [可选, 字符串] - 字段文本色
与 **Fields** 属性处于同一级别的 **endianness**、**clrBk** 和 **clrText** 属性,将作为该级别及以下所有 **Fields** 对象的默认属性,除非在字段本身中显式重新定义。
有关可用模板,请查看 `Templates` 目录。
## [](#)方法
**HexCtrl** 有许多方法可供您用来管理其行为。
### [](#)ClearData
```
void ClearData();
```
清除 **HexCtrl** 视图中的数据,但不触及数据本身。
### [](#)Create
```
bool Create(const HEXCREATE& hcs);
```
主初始化方法。接受 [`HEXCREATE`](#hexcreate) 结构体作为参数。如果创建成功则返回 `true`,否则返回 `false`。
### [](#)CreateDialogCtrl
```
bool CreateDialogCtrl(UINT uCtrlID, HWND hwndDlg);
```
从 **Custom Control** 对话框模板创建 **HexCtrl**。接受控件 **id** 和对话框窗口句柄 **handle** 作为参数。更多信息请参阅 **[创建](#in-dialog)** 部分。
### [](#)Delete
```
void Delete();
```
删除 **HexCtrl** 对象。仅当您出于某种原因想要手动删除 **HexCtrl** 对象时才使用此方法,否则 `IHexCtrlPtr` 会自动调用此方法。
### [](#)DestroyWindow
```
void DestroyWindow();
```
销毁 **HexCtrl** 主窗口。
### [](#)ExecuteCmd
```
void ExecuteCmd(EHexCmd eCmd)const;
```
执行 [`EHexCmd`](#ehexcmd) 枚举中的预定义命令之一。所有这些命令基本上都是复制 **HexCtrl** 的内部菜单。
### [](#)GetActualWidth
```
[[nodiscard]] auto GetActualWidth()const->int;
```
返回 **HexCtrl** 边界矩形的宽度,即绘制的工作区域的宽度。
### [](#)GetBookmarks
```
[[nodiscard]] auto GetBookmarks()->IHexBookmarks*;
```
返回指向 [`IHexBookmarks`](#ihexbookmarks) 接口的指针,该接口负责书签机制。
### [](#)GetCacheSize
```
[[nodiscard]] auto GetCacheSize()const->DWORD;
```
返回 [`HEXDATA`](#hexdata) 中设置的当前缓存大小。
### [](#)GetCapacity
```
[[nodiscard]] auto GetCapacity()const->DWORD;
```
返回当前容量。
### [](#)GetCaretPos
```
[[nodiscard]] auto GetCaretPos()const->ULONGLNG;
```
检索当前光标位置的偏移量。
### [](#)GetCharsExtraSpace
```
[[nodiscard]] auto GetCharsExtraSpace()const->DWORD;
```
获取字符间的额外空间,以像素为单位。此额外空间可通过 [`SetCharsExtraSpace`](#setcharsextraspace) 方法设置。
### [](#)GetColors
```
[[nodiscard]] auto GetColors()const->const HEXCOLORS&;
```
返回当前 [`HEXCOLORS`](#hexcolors) 结构体的引用。
### [](#)GetData
```
[[nodiscard]] auto GetData(HEXSPAN hss)const->std::byte*;
```
无论控件处于何种模式,都返回数据偏移量的指针。
### [](#)GetDataSize
```
[[nodiscard]] auto GetDataSize()const->ULONGLONG;
```
返回当前设置的数据大小。
### [](#)GetDateInfo
```
[[nodiscard]] auto GetDateInfo()const->std::tuple;
```
返回包含当前 [日期格式顺序说明符](https://docs.microsoft.com/en-us/windows/win32/intl/locale-idate) 和日期分隔符的元组。
### [](#)GetDlgItemHandle
```
[[nodiscard]] auto GetDlgItemHandle(EHexDlgItem eItem)const->HWND;
```
返回对话框内部子控件的 `HWND`。
### [](#)GetCodepage
```
[[nodiscard]] auto GetCodepage()const->int;
```
返回当前使用的代码页。
### [](#)GetFont
```
[[nodiscard]] auto GetFont(bool fMain)const->LOGFONTW;
```
如果 `fMain` 为 `true`,则返回当前主字体;如果 `fMain` 为 `false`,则返回信息栏字体。
### [](#)GetGroupSize
```
[[nodiscard]] auto GetGroupSize()const->DWORD;
```
返回当前数据分组大小。
### [](#)GetMenuHandle
```
[[nodiscard]] auto GetMenuHandle()const->HMENU;
```
返回 **HexCtrl** 上下文菜单的 `HMENU` 句柄。您可以使用此句柄根据需要自定义菜单。
**HexCtrl** 的内部菜单使用从 `0x8001` 开始的 `ID`。因此,如果您希望添加自己的新菜单,请分配从 `0x9000` 开始的菜单 `ID`,以免产生冲突。
当用户点击自定义菜单时,控件会向其父窗口发送 `WM_NOTIFY` 消息,其中 `LPARAM` 指向 [`HEXMENUINFO`](#hexmenuinfo),其 `hdr.code` 成员设置为 `HEXCTRL_MSG_MENUCLICK`,`wMenuID` 字段包含被点击菜单的 `ID`。
### [](#)GetOffset
```
[[nodiscard]] auto GetOffset(ULONGLONG ullOffset, bool fGetVirt)const->ULONGLONG;
```
将偏移量从虚拟转换为平面,反之亦然。
### [](#)GetPagesCount
```
[[nodiscard]] auto GetPagesCount()const->ULONGLONG;
```
返回由 [`SetPageSize`](#setpagesize) 方法设置的当前页数。
### [](#)GetPagePos
```
[[nodiscard]] auto GetPagePos()const->ULONGLONG;
```
返回光标所在的页码。
### [](#)GetPageSize
```
[[nodiscard]] auto GetPageSize()const->DWORD;
```
返回由 [`SetPageSize`](#setpagesize) 方法设置的当前页面大小。
### [](#)GetScrollRatio
```
[[nodiscard]] auto GetScrollRatio()const->std::tuple;
```
返回由 [`SetScrollRatio`](#setscrollratio) 方法设置的当前滚动比例和 `fLines` 标志的元组。
### [](#)GetSelection
```
[[nodiscard]] auto GetSelection()const->std::vector;
```
返回包含当前选区偏移量和大小的 `std::vector`。
### [](#)GetTemplates
```
[[nodiscard]] auto GetTemplates()->IHexTemplates*;
```
返回负责模板机制的内部 [`IHexTemplates`](#ihextemplates) 接口的指针。
### [](#)GetUnprintableChar
```
[[nodiscard]] auto GetUnprintableChar()const->wchar_t;
```
返回不可打印字符的替换字符。
### [](#)GetWndHandle
```
[[nodiscard]] auto GetWndHandle(EHexWnd eWnd, bool fCreate = true)const->HWND;
```
返回 **HexCtrl** 主窗口或其 [`内部对话框`](#ehexwnd) 之一的 `HWND`。如果 `fCreate` 标志为 `true`,则对话框窗口在返回之前(如果尚未创建)将首先被创建。
### [](#)GoToOffset
```
void GoToOffset(ULONGLONG ullOffset, int iPosAt = 0);
```
跳转到给定的偏移量。第二个参数 `iPosAt` 可以有三个值:
* `-1` - 偏移量将显示在顶行
* `0` - 偏移量将显示在中间
* `1` - 偏移量将显示在底行
### [](#)HasInfoBar
```
[[nodiscard]] bool HasInfoBar()const;
```
显示底部信息栏当前是否可见。
### [](#)HasSelection
```
[[nodiscard]] bool HasSelection()const;
```
如果 **HexCtrl** 有任何选中的区域,则返回 `true`。
### [](#)HitTest
```
[[nodiscard]] auto HitTest(POINT pt, bool fScreen = true)const->std::optional;
```
对给定点的命中测试,该点可以是屏幕坐标 `fScreen = true`,或客户区坐标 `fScreen = false`。如果成功,返回 [`HEXHITTEST`](#hexhittest) 结构体。
### [](#)IsCmdAvail
```
[[nodiscard]] bool IsCmdAvail(EHexCmd eCmd)const;
```
如果给定命令当前可以执行,则返回 `true`,否则返回 `false`。
### [](#)IsCreated
```
[[nodiscard]] bool IsCreated()const;
```
显示 **HexCtrl** 是否已创建。
### [](#)IsDataSet
```
[[nodiscard]] bool IsDataSet()const;
```
显示是否已为 **HexCtrl** 设置数据
### [](#)IsHexCharsUpper
```
[[nodiscard]] bool IsHexCharsUpper()const;
```
显示十六进制字符是以大写还是小写形式打印。
### [](#)IsMutable
```
[[nodiscard]] bool IsMutable()const;
```
显示 **HexCtrl** 当前是否处于编辑模式。
### [](#)IsOffsetAsHex
```
[[nodiscard]] bool IsOffsetAsHex()const;
```
“偏移量”当前是以十六进制还是十进制表示(显示)。可以通过双击偏移量区域来更改。
### [](#)IsOffsetVisible
```
[[nodiscard]] auto IsOffsetVisible(ULONGLONG ullOffset)const->HEXVISION;
```
检查偏移量的可见性,并返回 [`HEXVISION`](#hexvision) 作为结果。
### [](#)IsVirtual
```
[[nodiscard]] bool IsVirtual()const;
```
如果 **HexCtrl** 当前在 [虚拟数据模式](#virtual-data-mode) 下工作,则返回 `true`。
### [](#)ModifyData
```
void ModifyData(const HEXMODIFY& hms);
```
修改当前在 **HexCtrl** 中设置的数据,有关详细信息,请参阅 [`HEXMODIFY`](#hexmodify) 结构体。
### [](#)PreTranslateMsg
```
[[nodiscard]] bool PreTranslateMsg(MSG* pMsg);
```
**HexCtrl** 有许多内部对话框窗口。为了使对话框键盘导航正常工作,必须将此方法挂接到您应用程序的主消息循环中,在 `TranslateMessage` 和 `DispatchMessage` 之前,或者挂接到 MFC 的 `PreTranslateMessage` 虚函数中。
```
while (GetMessageW(&msg, nullptr, 0, 0)) {
if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {
if (!m_pHexCtrl->PreTranslateMsg(&msg)) { //Process further only if it returns false.
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
}
```
如果此方法返回 `true`,则意味着不应进行进一步的消息处理,**HexCtrl** 已完成所有处理。
### [](#)Redraw
```
void Redraw();
```
重绘主窗口。
### [](#)SetCapacity
```
void SetCapacity(DWORD dwCapacity);
```
设置 **HexCtrl** 的当前容量。
### [](#)SetCaretPos
```
void SetCaretPos(ULONGLONG ullOffset, bool fHighLow = true, bool fRedraw = true);
```
将光标设置到给定的偏移量。`fHighLow` 标志指示光标必须设置在十六进制块的低半部分还是高半部分。
### [](#)SetCharsExtraSpace
```
void SetCharsExtraSpace(DWORD dwSpace);
```
设置字符间增加的额外空间,以像素为单位。
### [](#)SetCodepage
```
void SetCodepage(int iCodePage);
```
设置 **HexCtrl** 文本区域的代码页。接受 [代码页标识符](https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers) 作为参数,或 `-1` 表示默认的纯 ASCII 字符。
### [](#)SetColors
```
void SetColors(const HEXCOLORS& clr);
```
设置控件的所有颜色。接受 [`HEXCOLORS`](#hexcolors) 作为参数。
### [](#)SetConfig
```
bool SetConfig(std::wstring_view wsvPath);
```
设置要在 **HexCtrl** 中使用的带有键绑定的 JSON 配置文件的路径,或空路径(`L""`)表示默认值。此文件使用 [`EHexCmd`](#ehexcmd) 枚举值作为键,字符串数组作为值:
```
{
"CMD_DLG_SEARCH": [ "ctrl+f", "ctrl+h" ],
"CMD_SEARCH_NEXT": [ "f3" ],
"CMD_SEARCH_PREV": [ "shift+f3" ]
}
```
有关默认值,请参阅项目源代码中的 [`IDR_HEXCTRL_JSON_KEYBIND.json`](https://github.com/jovibor/HexCtrl/blob/master/HexCtrl/res/IDR_HEXCTRL_JSON_KEYBIND.json) 文件。
### [](#)SetData
```
void SetData(const HEXDATA& hds, bool fAdjust = false)
```
为 **HexCtrl** 设置数据的主要方法。它接受 [`HEXDATA`](#hexdata) 结构体作为参数。
当 `fAdjust` 标志设置为 `true` 时,允许调整已设置的数据。例如,在 [虚拟](#virtual-data-mode) 和普通数据模式之间切换。
### [](#)SetDateInfo
```
void SetDateInfo(DWORD dwFormat, wchar_t wchSepar);
```
设置 [日期格式顺序说明符](https://docs.microsoft.com/en-us/windows/win32/intl/locale-idate) 以及日期分隔符。
### [](#)SetDlgProperties
```
void SetDlgProperties(EHexWnd eWnd, std::uint64_t u64Flags);
```
以标志形式为 **HexCtrl** 的内部对话框设置各种属性。标志可以通过 OR(`|`)运算组合在一起。
可用标志:
```
HEXCTRL_FLAG_DLG_NOESC //Prevent dialog from closing on Esc key.
```
### [](#)SetFont
```
void SetFont(const LOGFONTW& lf, bool fMain);
```
如果 `fMain` 为 `true`,则为 **HexCtrl** 设置新的主字体;如果 `fMain` 为 `false`,则设置信息栏字体。此字体必须是等宽字体。
### [](#)SetGroupSize
```
void SetGroupSize(DWORD dwSize);
```
设置当前数据分组大小(以字节为单位)。
### [](#)SetHexCharsCase
```
void SetHexCharsCase(bool fUpper);
```
将打印的十六进制字符设置为大写或小写。
### [](#)SetMutable
```
void SetMutable(bool fMutable);
```
启用或禁用可变模式。在可变模式下,所有数据都可以被修改。
### [](#)SetOffsetMode
```
void SetOffsetMode(bool fHex);
```
设置偏移量区域显示为十六进制(`fHex=true`)或十进制(`fHex=false`)。
### [](#)SetPageSize
```
void SetPageSize(DWORD dwSize, std::wstring_view wsvName = L"Page");
```
设置页面大小以在之间绘制分割线。此大小应是当前 [容量](#setcapacity) 大小的倍数才能生效。第二个参数设置要在 **HexCtrl** 底部信息区域显示的名称(“Page”、“Sector”等)。
要移除分割线,只需将 `dwSize` 设置为 0。
### [](#)SetRedraw
```
void SetRedraw(bool fRedraw);
```
是否重绘 **HexCtrl** 主窗口。例如,是否处理 `WM_PAINT` 消息。
### [](#)SetScrollRatio
```
void SetScrollRatio(float flRatio, bool fLines);
```
设置一个滚动页面的滚动量。页面是指鼠标滚轮的一次滚动或 PageDown 键。当 `fLines` 为 `true` 时,`flRatio` 是要滚动的文本行数。当它为 `false` 时,`flRatio` 是可见屏幕高度的比例。
### [](#)SetSelection
```
void SetSelection(const std::vector& vecSel, bool fRedraw = true, bool fHighlight = false);
```
设置当前选区,或者如果 `fHighlight` 为 `true`,则高亮显示选区。
### [](#)SetUnprintableChar
```
void SetUnprintableChar(wchar_t wch);
```
设置不可打印字符的替换字符。
### [](#)SetVirtualBkm
```
void SetVirtualBkm(IHexBookmarks* pVirtBkm);
```
设置 [虚拟书签](#virtual-bookmarks) 模式的指针,或者如果设置为 `nullptr` 则禁用此模式。
### [](#)SetWindowPos
```
void SetWindowPos(HWND hWndAfter, int iX, int iY, int iWidth, int iHeight, UINT uFlags);
```
设置 **HexCtrl** 窗口位置。此方法复制 [`SetWindowPos`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos) Windows 函数的行为。
### [](#)ShowInfoBar
```
void ShowInfoBar(bool fShow);
```
显示/隐藏底部信息栏。
## [](#)结构体
下面列出了所有 **HexCtrl** 的结构体。
### [](#)HEXBKM
主书签结构体,与 [IHexBookmarks](#ihexbookmarks) 接口一起使用。
```
struct HEXBKM {
VecSpan 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.
HEXCOLOR stClr; //Bookmark bk/text color.
};
using PHEXBKM = HEXBKM*;
```
成员 `vecSpan` 是 `std::vector` 类型的,因为书签可能包含几个不相邻的区域。例如,当按住 Alt 键进行块状选择时。
### [](#)HEXBKMINFO
书签信息结构体。
```
struct HEXBKMINFO {
NMHDR hdr { }; //Standard Windows header.
PHEXBKM pBkm { }; //Bookmark pointer.
};
using PHEXBKMINFO = HEXBKMINFO*;
```
### [](#)HEXCOLOR
背景和文本颜色结构体。
```
struct HEXCOLOR {
COLORREF clrBk { }; //Bk color.
COLORREF clrText { }; //Text color.
auto operator<=>(const HEXCOLOR&)const = default;
};
using PHEXCOLOR = HEXCOLOR*;
```
### [](#)HEXCOLORINFO
十六进制块的颜色信息结构体。
```
struct HEXCOLORINFO {
NMHDR hdr { }; //Standard Windows header.
ULONGLONG ullOffset { }; //Offset for the color.
HEXCOLOR stClr; //Colors of the given offset.
};
```
### [](#)HEXCOLORS
此结构体包含字体、背景和所有其他视觉元素的所有颜色。所有这些颜色都有其默认值,因此如果您不想,就不必在创建 **HexCtrl** 期间全部设置它们。
```
struct HEXCOLORS {
COLORREF clrFontCaption { RGB(0, 0, 180) }; //Caption font color
COLORREF clrFontHex { ::GetSysColor(COLOR_WINDOWTEXT) }; //Hex-chunks font color.
COLORREF clrFontText { ::GetSysColor(COLOR_WINDOWTEXT) }; //Text font color.
COLORREF clrFontOffset { RGB(0, 0, 180) }; //Offset font color.
COLORREF clrFontSel { ::GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Selected hex/text font color.
COLORREF clrFontBkm { ::GetSysColor(COLOR_WINDOWTEXT) }; //Bookmarks font color.
COLORREF clrFontDataInterp { ::GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Data Interpreter text/hex font color.
COLORREF clrFontInfoParam { ::GetSysColor(COLOR_WINDOWTEXT) }; //Font color of the Info bar parameters.
COLORREF clrFontInfoData { RGB(0, 0, 180) }; //Font color of the Info bar data.
COLORREF clrFontCaret { ::GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Caret font color.
COLORREF clrBk { ::GetSysColor(COLOR_WINDOW) }; //Whole client area background color.
COLORREF clrBkHex { ::GetSysColor(COLOR_WINDOW) }; //Hex area background color.
COLORREF clrBkText { ::GetSysColor(COLOR_WINDOW) }; //Text area background color.
COLORREF clrBkOffset { ::GetSysColor(COLOR_WINDOW) }; //Offset area background color.
COLORREF clrBkSel { ::GetSysColor(COLOR_HIGHLIGHT) }; //Background color of the selected Hex/Text.
COLORREF clrBkBkm { RGB(240, 240, 0) }; //Bookmarks background color.
COLORREF clrBkDataInterp { RGB(147, 58, 22) }; //Data Interpreter Bk color.
COLORREF clrBkInfoBar { ::GetSysColor(COLOR_3DFACE) }; //Background color of the bottom Info bar.
COLORREF clrBkCaret { RGB(0, 0, 255) }; //Caret background color.
COLORREF clrBkCaretSel { RGB(0, 0, 200) }; //Caret background color in selection.
COLORREF clrLinesMain { ::GetSysColor(COLOR_SCROLLBAR) }; //Main window and pages lines color.
COLORREF clrLinesTempl { ::GetSysColor(COLOR_WINDOWTEXT) }; //Templates data confining lines color.
COLORREF clrScrollBar { ::GetSysColor(COLOR_3DFACE) }; //Scrollbar color.
COLORREF clrScrollThumb { ::GetSysColor(COLOR_SCROLLBAR) }; //Scrollbar thumb color.
COLORREF clrScrollArrow { ::GetSysColor(COLOR_GRAYTEXT) }; //Scrollbar arrow color.
};
using PCHEXCOLORS = const HEXCOLORS*;
```
### [](#)HEXCREATE
用于 **HexCtrl** 创建的主初始化结构体。
```
struct HEXCREATE {
HINSTANCE hInstRes { }; //Hinstance of the HexCtrl resources, nullptr for current module.
HWND hWndParent { }; //Parent window handle.
PCHEXCOLORS pColors { }; //HexCtrl colors, nullptr for default.
const LOGFONTW* pLogFont { }; //Monospaced font for HexCtrl, nullptr for default.
RECT rect { }; //Initial window rect.
UINT uID { }; //Control ID if it's a child window.
DWORD dwStyle { }; //Window styles.
DWORD dwExStyle { }; //Extended window styles.
DWORD dwCapacity { 16UL }; //Initial capacity size.
DWORD dwGroupSize { 1UL }; //Initial data grouping size.
float flScrollRatio { 1.0F }; //Either a screen-ratio or lines amount to scroll with Page-scroll (mouse-wheel).
bool fScrollLines { false }; //Treat flScrollRatio as screen-ratio (false) or as amount of lines (true).
bool fInfoBar { true }; //Show bottom Info bar or not.
bool fOffsetHex { true }; //Show offset digits as Hex or Decimal.
bool fCustom { false }; //If it's a custom control in a dialog.
};
```
#### 成员:
**HINSTANCE hInstRes**
`hInstRes` 成员允许您提供模块的备用 `HINSTANCE`,所有 **HexCtrl** 资源(对话框、菜单等)都位于该模块中。默认情况下,**HexCtrl** 使用其当前模块,无论是 `.exe` 还是 `.dll`。
**DWORD dwStyle**
**HexCtrl** 主窗口的标准 [窗口样式](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles)。
**DWORD dwExStyle**
**HexCtrl** 主窗口的标准 [扩展窗口样式](https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles)。
### [](#)HEXDATA
在 **HexCtrl** 中设置显示数据的主结构体。
```
struct HEXDATA {
SpanByte spnData; //Data span to display.
IHexVirtData* pHexVirtData { }; //Pointer for VirtualData mode.
IHexVirtColors* pHexVirtColors { }; //Pointer for Custom Colors class.
ULONGLONG ullMaxVirtOffset { }; //Maximum virtual offset.
DWORD dwCacheSize { 0x800000UL }; //Data cache size for VirtualData mode.
bool fMutable { false }; //Is data mutable or read-only.
bool fHighLatency { false }; //Do not redraw until scroll thumb is released.
};
```
#### 成员:
**ULONGLONG ullMaxVirtOffset**
用于在虚拟数据模式下设置最大虚拟数据偏移量。这是计算偏移量位数所必需的。
### [](#)HEXDATAINFO
[`IHexVirtData`](#virtual-data-mode) 中使用的数据信息结构体。
```
struct HEXDATAINFO {
NMHDR hdr { }; //Standard Windows header.
HEXSPAN stHexSpan; //Offset and size of the data.
SpanByte spnData; //Data span.
};
```
### [](#)HEXHITTEST
用于 [`HitTest`](#hittest) 方法的结构体。
```
struct HEXHITTEST {
ULONGLONG ullOffset { }; //Offset.
bool fIsText { false }; //Is cursor at Text or Hex area.
bool fIsHigh { false }; //Is it High or Low part of the byte.
};
```
### [](#)HEXMODIFY
此结构体用于表示数据修改参数。
当 `eModifyMode` 设置为 `MODIFY_ONCE` 时,来自 `pData` 的字节仅按原样替换相应的数据字节。
如果 `eModifyMode` 等于 `MODIFY_REPEAT`,则将逐块进行多次替换。
例如,如果:
* `SUM(vecSpan.ullSize) == 9`
* `spnData.size() == 3`
* `eModifyMode` 设置为 `MODIFY_REPEAT`
* `vecSpan.ullOffset` 处的内存字节为 `010203040506070809`
* `spnData.data()` 指向的字节为 `030405`
那么,修改后,`vecSpan.ullOffset` 处的字节将变为 `030405030405030405`。
如果 `eModifyMode` 等于 `MODIFY_OPERATION`,则 `eOperMode` 指示必须对数据执行何种操作。
```
struct HEXMODIFY {
EHexModifyMode eModifyMode { }; //Modify mode.
EHexOperMode eOperMode { }; //Operation mode, used if eModifyMode == MODIFY_OPERATION.
EHexDataType eDataType { }; //Data type of the underlying data, used if eModifyMode == MODIFY_OPERATION.
SpanCByte spnData; //Span of the data to modify with.
VecSpan vecSpan; //Vector of data offsets and sizes to modify.
bool fBigEndian { false }; //Treat data as the big endian, used if eModifyMode == MODIFY_OPERATION.
};
```
### [](#)HEXMENUINFO
菜单信息结构体。
```
struct HEXMENUINFO {
NMHDR hdr { }; //Standard Windows header.
POINT pt { }; //Mouse position when clicked.
WORD wMenuID { }; //Menu identifier.
bool fShow { true }; //Whether to show menu or not, in case of HEXCTRL_MSG_CONTEXTMENU.
};
using PHEXMENUINFO = HEXMENUINFO*;
```
### [](#)HEXSPAN
此结构体主要用于选区和书签例程。它保存数据区域的偏移量和大小。
```
struct HEXSPAN {
ULONGLONG ullOffset { };
ULONGLONG ullSize { };
};
using VecSpan = std::vector;
```
### [](#)HEXVISION
此结构体从 [`IsOffsetVisible`](#isoffsetvisible) 方法返回。两个成员 `i8Vert` 和 `i8Horz` 分别表示垂直和水平可见性。这些成员可以处于三种不同的状态:
* `-1` — 偏移量在可见区域的上方或左侧。
* `1` — 偏移量在可见区域的下方或右侧。
* `0` — 偏移量可见。
```
struct HEXVISION {
std::int8_t i8Vert { }; //Vertical offset.
std::int8_t i8Horz { }; //Horizontal offset.
operator bool()const { return i8Vert == 0 && i8Horz == 0; }; //For test simplicity: if(IsOffsetVisible()).
};
```
## [](#)接口
### [](#)IHexBookmarks
`IHexBookmarks` 接口负责 **HexCtrl** 的书签机制。要获取此接口的指针,请使用 [`GetBookmarks`](#getbookmarks) 方法。
```
class IHexBookmarks {
public:
virtual auto AddBkm(const HEXBKM& hbs, bool fRedraw = true) -> ULONGLONG = 0; //Add new bookmark, returns the new bookmark's ID.
[[nodiscard]] virtual auto GetByID(ULONGLONG ullID) -> PHEXBKM = 0; //Get bookmark by ID.
[[nodiscard]] virtual auto GetByIndex(ULONGLONG ullIndex) -> PHEXBKM = 0; //Get bookmark by index.
[[nodiscard]] virtual auto GetCount() -> ULONGLONG = 0; //Get bookmarks count.
[[nodiscard]] virtual auto HitTest(ULONGLONG ullOffset) -> PHEXBKM = 0; //HitTest for given offset.
virtual void RemoveAll() = 0; //Remove all bookmarks.
virtual void RemoveByID(ULONGLONG ullID) = 0; //Remove by a given ID.
};
```
#### [](#)IHexBookmarks::AddBkm
```
ULONGLONG AddBkm(const HEXBKM& hbs, bool fRedraw = false)
```
向控件添加新书签,返回创建的书签 ID。
**示例:**
```
HEXBKM hbs;
hbs.vecSpan.emplace_back(0x1, 10);
hbs.clrBk = RGB(0, 255, 0);
hbs.clrText = RGB(255, 255, 255);
hbs.wstrDesc = L"My bookmark, with green bk and white text.";
myHex->GetBookmarks()->Add(hbs);
```
#### [](#)IHexBookmarks::GetByID
```
GetByID(ULONGLONG ullID)->HEXBKM*;
```
通过 ID 获取书签。
#### [](#)IHexBookmarks::GetByIndex
```
auto GetByIndex(ULONGLONG ullIndex)->HEXBKM*;
```
通过索引获取书签。
#### [](#)IHexBookmarks::GetCount
```
ULONGLONG GetCount();
```
获取书签计数。
#### [](#)IHexBookmarks::HitTest
```
auto HitTest(ULONGLONG ullOffset)->HEXBKM*;
```
测试给定的偏移量,如果偏移量包含书签,则检索指向 [`HEXBKM`](#hexbkm) 的指针。
#### [](#)IHexBookmarks::RemoveAll
```
void RemoveAll();
```
移除所有书签。
#### [](#)IHexBookmarks::RemoveByID
```
void RemoveByID(ULONGLONG ullID);
```
移除具有给定 ID 的书签。
### [](#)IHexTemplates
```
class IHexTemplates {
public:
virtual auto AddTemplate(const HEXTEMPLATE& hts) -> int = 0; //Adds existing template.
virtual auto ApplyTemplate(ULONGLONG ullOffset, int iTemplateID) -> int = 0; //Applies template to offset, returns AppliedID.
virtual void DisapplyAll() = 0;
virtual void DisapplyByID(int iAppliedID) = 0;
virtual void DisapplyByOffset(ULONGLONG ullOffset) = 0;
virtual auto LoadTemplate(const wchar_t* pFilePath) -> int = 0; //Returns TemplateID on success, null otherwise.
virtual void ShowTooltips(bool fShow) = 0;
virtual void UnloadAll() = 0; //Unload all templates.
virtual void UnloadTemplate(int iTemplateID) = 0; //Unload/remove loaded template from memory.
[[nodiscard]] static HEXCTRLAPI auto __cdecl LoadFromFile(const wchar_t* pFilePath)->std::unique_ptr;
};
```
#### [](#)LoadFromFile
```
[[nodiscard]] static auto LoadFromFile(const wchar_t* pFilePath)->std::unique_ptr;
```
此 `static` 方法可用于预先从文件加载模板。然后可以通过 `IHexTemplates::AddTemplate` 方法将加载的模板添加到多个 **HexCtrl** 实例中。这种方法避免了在多个 **HexCtrl** 分别通过 `IHexTemplates::LoadTemplate` 加载时从磁盘多次加载同一模板。
### [](#)IHexVirtColors
```
class IHexVirtColors {
public:
virtual bool OnHexGetColor(HEXCOLORINFO&) = 0; //Should return true if colors are set.
};
```
### [](#)IHexVirtData
```
class IHexVirtData {
public:
virtual void OnHexGetData(HEXDATAINFO&) = 0; //Data to get.
virtual void OnHexGetOffset(HEXDATAINFO& hdi, bool fGetVirt) = 0; //Offset<->VirtOffset conversion.
virtual void OnHexSetData(const HEXDATAINFO&) = 0; //Data to set, if mutable.
};
```
#### [](#)OnHexGetOffset
在内部,**HexCtrl** 使用平面数据偏移量进行操作。如果您设置了 1MB 大小的数据,**HexCtrl** 的工作偏移量将在 `[0-1'048'575]` 范围内。然而,从用户的角度来看,真实的数据偏移量可能有所不同。例如,在进程内存模型中,可以使用非常高的虚拟内存地址(例如 `0x7FF96BA622C0`)。进程数据可以由操作系统映射到几乎任何虚拟地址。`OnHexGetOffset` 方法正是用于 **平面<->虚拟** 偏移量转换的目的。
## [](#)枚举
### [](#)EHexCmd
可在 **HexCtrl** 内执行的命令枚举。
```
enum class EHexCmd : std::uint8_t {
CMD_SEARCH_DLG = 0x01, CMD_SEARCH_NEXT, CMD_SEARCH_PREV,
CMD_NAV_GOTO_DLG, CMD_NAV_REPFWD, CMD_NAV_REPBKW, CMD_NAV_DATABEG, CMD_NAV_DATAEND,
CMD_NAV_PAGEBEG, CMD_NAV_PAGEEND, CMD_NAV_LINEBEG, CMD_NAV_LINEEND, CMD_GROUPDATA_BYTE,
CMD_GROUPDATA_WORD, CMD_GROUPDATA_DWORD, CMD_GROUPDATA_QWORD, CMD_GROUPDATA_INC, CMD_GROUPDATA_DEC,
CMD_BKM_ADD, CMD_BKM_REMOVE, CMD_BKM_NEXT, CMD_BKM_PREV, CMD_BKM_REMOVEALL, CMD_BKM_DLG_MGR,
CMD_CLPBRD_COPY_HEX, CMD_CLPBRD_COPY_HEXLE, CMD_CLPBRD_COPY_HEXFMT, CMD_CLPBRD_COPY_TEXTCP,
CMD_CLPBRD_COPY_BASE64, CMD_CLPBRD_COPY_CARR, CMD_CLPBRD_COPY_GREPHEX, CMD_CLPBRD_COPY_PRNTSCRN,
CMD_CLPBRD_COPY_OFFSET, CMD_CLPBRD_PASTE_HEX, CMD_CLPBRD_PASTE_TEXTUTF16, CMD_CLPBRD_PASTE_TEXTCP,
CMD_MODIFY_OPERS_DLG, CMD_MODIFY_FILLZEROS, CMD_MODIFY_FILLDATA_DLG, CMD_MODIFY_UNDO, CMD_MODIFY_REDO,
CMD_SEL_MARKSTARTEND, CMD_SEL_ALL, CMD_SEL_ADDLEFT, CMD_SEL_ADDRIGHT, CMD_SEL_ADDUP,
CMD_SEL_ADDDOWN, CMD_DATAINTERP_DLG, CMD_CODEPAGE_DLG, CMD_APPEAR_FONT_DLG, CMD_APPEAR_FONTINC,
CMD_APPEAR_FONTDEC, CMD_APPEAR_CAPACINC, CMD_APPEAR_CAPACDEC, CMD_PRINT_DLG, CMD_ABOUT_DLG,
CMD_CARET_LEFT, CMD_CARET_RIGHT, CMD_CARET_UP, CMD_CARET_DOWN,
CMD_SCROLL_CURSOR, CMD_SCROLL_PAGEUP, CMD_SCROLL_PAGEDOWN,
CMD_TEMPL_APPLYCURR, CMD_TEMPL_DISAPPLY, CMD_TEMPL_DISAPPALL, CMD_TEMPL_DLG_MGR
};
```
### [](#)EHexDataType
在 [`HEXMODIFY`](#hexmodify) 结构体中与 `EHexModifyMode::MODIFY_OPERATION` 模式一起使用的数据类型枚举。
```
enum class EHexDataType : std::uint8_t {
DATA_INT8, DATA_UINT8, DATA_INT16, DATA_UINT16, DATA_INT32,
DATA_UINT32, DATA_INT64, DATA_UINT64, DATA_FLOAT, DATA_DOUBLE
};
```
### [](#)EHexModifyMode
数据修改模式枚举,用于 [`HEXMODIFY`](#hexmodify)。
```
enum class EHexModifyMode : std::uint8_t {
MODIFY_ONCE, MODIFY_REPEAT, MODIFY_OPERATION, MODIFY_RAND_MT19937, MODIFY_RAND_FAST
};
```
### [](#)EHexOperMode
数据操作模式枚举,当 `HEXMODIFY::enModifyMode` 设置为 `MODIFY_OPERATION` 时,在 [`HEXMODIFY`](#hexmodify) 中使用。
```
enum class EHexOperMode : std::uint8_t {
OPER_ASSIGN, OPER_ADD, OPER_SUB, OPER_MUL, OPER_DIV, OPER_CEIL, OPER_FLOOR, OPER_OR,
OPER_XOR, OPER_AND, OPER_NOT, OPER_SHL, OPER_SHR, OPER_ROTL, OPER_ROTR, OPER_SWAP,
OPER_BITREV
};
```
### []( )EHexWnd
所有 **HexCtrl** 内部窗口的枚举,在 [`GetWndHandle`](#getwndhandle) 方法中使用。
```
enum class EHexWnd : std::uint8_t {
WND_MAIN, DLG_BKMMGR, DLG_DATAINTERP, DLG_MODIFY,
DLG_SEARCH, DLG_ENCODING, DLG_GOTO, DLG_TEMPLMGR
};
```
## [](#)通知消息
在其工作期间,**HexCtrl** 通过 **[WM_NOTIFY](https://docs.microsoft.com/en-us/windows/win32/controls/wm-notify)** 机制向其父窗口发送通知消息。
`WM_NOTIFY` 消息的 `LPARAM` 包含指向标准 Windows **[NMHDR](https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nmhdr)** 结构体的指针。根据通知消息的不同,`LPARAM` 随后可以转换为指向另一个结构体的指针,有关详细信息,请参阅消息说明。
### [](#)HEXCTRL_MSG_BKMCLICK
当点击书签时发送,`LPARAM` 包含指向 [`HEXBKMINFO`](#hexbkminfo) 结构体的指针。
### [](#)HEXCTRL_MSG_CONTEXTMENU
当即将显示上下文菜单时发送,`LPARAM` 包含指向 [`HEXMENUINFO`](#hexmenuinfo) 结构体的指针。您可以通过在响应此消息时将 `PHEXMENUINFO->fShow` 标志设置为 `false` 来禁止菜单显示。
### [](#)HEXCTRL_MSG_DESTROY
发送以指示 **HexCtrl** 的窗口即将被销毁,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGBKMMGR
发送以指示 **书签管理器** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGCODEPAGE
发送以指示 **代码页** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGDATAINTERP
发送以指示 **数据解释器** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGGOTO
发送以指示 **转到** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGMODIFY
发送以指示 **修改数据** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGSEARCH
发送以指示 **搜索** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_DLGTEMPLMGR
发送以指示 **模板管理器** 对话框即将显示,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_MENUCLICK
当点击用户定义的自定义菜单时发送,`LPARAM` 包含指向 [`HEXMENUINFO`](#hexmenuinfo) 结构体的指针。
### [](#)HEXCTRL_MSG_SETCAPACITY
当容量更改时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETCARET
当光标位置更改时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETCODEPAGE
当文本区域的代码页更改时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETDATA
发送以指示数据已更改,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETFONT
当字体更改时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETGROUPSIZE
当数据分组大小更改时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
### [](#)HEXCTRL_MSG_SETSELECTION
当进行选择时发送,`LPARAM` 包含指向 `NMHDR` 结构体的指针。
## [](#)许可协议
本软件根据 **"The HexCtrl License"** 提供,任何 **非商业** 使用均免费。
请参阅 [LICENSE](https://github.com/jovibor/HexCtrl/blob/master/LICENSE) 文件。
_展开_
* [ClearData](#cleardata) * [Create](#create) * [CreateDialogCtrl](#createdialogctrl) * [Delete](#delete) * [DestroyWindow](#destroywindow) * [ExecuteCmd](#executecmd) * [GetActualWidth](#getactualwidth) * [GetBookmarks](#getbookmarks) * [GetCacheSize](#getcachesize) * [GetCapacity](#getcapacity) * [GetCaretPos](#getcaretpos) * [GetCharsExtraSpace](#getcharsextraspace) * [GetCodepage](#getcodepage) * [GetColors](#getcolors) * [GetData](#getdata) * [GetDataSize](#getdatasize) * [GetDateInfo](#getdateinfo) * [GetDlgItemHandle](#getdlgitemhandle) * [GetFont](#getfont) * [GetGroupSize](#getgroupsize) * [GetMenuHandle](#getmenuhandle) * [GetOffset](#getoffset) * [GetPagesCount](#getpagescount) * [GetPagePos](#getpagepos) * [GetPageSize](#getpagesize) * [GetScrollRatio](#getscrollratio) * [GetSelection](#getselection) * [GetTemplates](#gettemplates) * [GetUnprintableChar](#getunprintablechar) * [GetWndHandle](#getwndhandle) * [GoToOffset](#gotooffset) * [HasInfoBar](#hasinfobar) * [HasSelection](#hasselection) * [HitTest](#hittest) * [IsCmdAvail](#iscmdavail) * [IsCreated](#iscreated) * [IsDataSet](#isdataset) * [IsHexCharsUpper](#ishexcharsupper) * [IsMutable](#ismutable) * [IsOffsetAsHex](#isoffsetashex) * [IsOffsetVisible](#isoffsetvisible) * [IsVirtual](#isvirtual) * [ModifyData](#modifydata) * [PreTranslateMsg](#pretranslatemsg) * [Redraw](#redraw) * [SetCapacity](#setcapacity) * [SetCaretPos](#setcaretpos) * [SetCharsExtraSpace](#setcharsextraspace) * [SetCodepage](#setcodepage) * [SetColors](#setcolors) * [SetConfig](#setconfig) * [SetData](#setdata) * [SetDateInfo](#setdateinfo) * [SetDlgProperties](#setdlgproperties) * [SetFont](#setfont) * [SetGroupSize](#setgroupsize) * [SetHexCharsCase](#sethexcharscase) * [SetMutable](#setmutable) * [SetOffsetMode](#setoffsetmode) * [SetPageSize](#setpagesize) * [SetRedraw](#setredraw) * [SetScrollRatio](#setscrollratio) * [SetSelection](#setselection) * [SetUnprintableChar](#setunprintablechar) * [SetVirtualBkm](#setvirtualbkm) * [SetWindowPos](#setwindowpos) * [ShowInfoBar](#showinfobar)_展开_
* [HEXBKM](#hexbkm) * [HEXBKMINFO](#hexbkminfo) * [HEXCOLOR](#hexcolor) * [HEXCOLORINFO](#hexcolorinfo) * [HEXCOLORS](#hexcolors) * [HEXCREATE](#hexcreate) * [HEXDATA](#hexdata) * [HEXDATAINFO](#hexdatainfo) * [HEXHITTEST](#hexhittest) * [HEXMENUINFO](#hexmenuinfo) * [HEXMODIFY](#hexmodify) * [HEXSPAN](#hexspan) * [HEXVISION](#hexvision)_展开_
* [IHexBookmarks](#ihexbookmarks) * [IHexTemplates](#ihextemplates) * [IHexVirtColors](#ihexvirtcolors) * [IHexVirtData](#ihexvirtdata)_展开_
* [EHexCmd](#ehexcmd) * [EHexDataType](#ehexdatatype) * [EHexModifyMode](#ehexmodifymode) * [EHexOperMode](#ehexopermode) * [EHexWnd](#ehexwnd)_展开_
* [HEXCTRL_MSG_BKMCLICK](#hexctrl_msg_bkmclicked) * [HEXCTRL_MSG_CONTEXTMENU](#hexctrl_msg_contextmenu) * [HEXCTRL_MSG_DESTROY](#hexctrl_msg_destroy) * [HEXCTRL_MSG_DLGBKMMGR](#hexctrl_msg_dlgbkmmgr) * [HEXCTRL_MSG_DLGCODEPAGE](#hexctrl_msg_dlgcodepage) * [HEXCTRL_MSG_DLGDATAINTERP](#hexctrl_msg_dlgdatainterp) * [HEXCTRL_MSG_DLGGOTO](#hexctrl_msg_dlggoto) * [HEXCTRL_MSG_DLGMODIFY](#hexctrl_msg_dlgmodify) * [HEXCTRL_MSG_DLGSEARCH](#hexctrl_msg_dlgsearch) * [HEXCTRL_MSG_DLGTEMPLMGR](#hexctrl_msg_dlgtemplmgr) * [HEXCTRL_MSG_MENUCLICK](#hexctrl_msg_menuclick) * [HEXCTRL_MSG_SETCAPACITY](#hexctrl_msg_setcapacity) * [HEXCTRL_MSG_SETCARET](#hexctrl_msg_setcaret) * [HEXCTRL_MSG_SETCODEPAGE](#hexctrl_msg_setcodepage) * [HEXCTRL_MSG_SETDATA](#hexctrl_msg_setdata) * [HEXCTRL_MSG_SETFONT](#hexctrl_msg_setfont) * [HEXCTRL_MSG_SETGROUPSIZE](#hexctrl_msg_setgroupsize) * [HEXCTRL_MSG_SETSELECTION](#hexctrl_msg_setselection)标签:C++, GUI控件, Hex Control, Homebrew安装, Linux, Win32, 书签管理, 二进制数据, 代码页, 内存查看, 对话框控件, 底层开发, 数据擦除, 文件编辑, 虚拟内存模式