Skip to content

Commit

Permalink
[Fixes] Regressions. Code cleaning.
Browse files Browse the repository at this point in the history
  • Loading branch information
jovibor committed Nov 13, 2019
1 parent 46918c1 commit 60985a6
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 56 deletions.
18 changes: 9 additions & 9 deletions HexCtrl/HexCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace HEXCTRL

/********************************************************************************************
* EHexOperMode - Enum of the data operation mode, used in HEXMODIFYSTRUCT, *
* when HEXMODIFYSTRUCT::enCreateMode is MODIFY_OPERATION. *
* when HEXMODIFYSTRUCT::enModifyMode is MODIFY_OPERATION. *
********************************************************************************************/
enum class EHexOperMode : WORD
{
Expand All @@ -58,10 +58,10 @@ namespace HEXCTRL
********************************************************************************************/
struct HEXMODIFYSTRUCT
{
EHexModifyMode enCreateMode { EHexModifyMode::MODIFY_DEFAULT }; //Modify mode.
EHexOperMode enOperMode { }; //Operation mode enum. Used only if enCreateMode==MODIFY_OPERATION.
const BYTE* pData { }; //Pointer to a data to be set.
ULONGLONG ullDataSize { }; //Size of the data pData is pointing to.
EHexModifyMode enModifyMode { EHexModifyMode::MODIFY_DEFAULT }; //Modify mode.
EHexOperMode enOperMode { }; //Operation mode enum. Used only if enModifyMode == MODIFY_OPERATION.
const BYTE* pData { }; //Pointer to a data to be set.
ULONGLONG ullDataSize { }; //Size of the data pData is pointing to.
std::vector<HEXSPANSTRUCT> vecSpan { }; //Vector of data offsets and sizes.
};

Expand Down Expand Up @@ -110,9 +110,9 @@ namespace HEXCTRL
CREATE_CHILD, CREATE_POPUP, CREATE_CUSTOMCTRL
};

/***************************************************************************************
* EHexShowMode - current data mode representation. *
***************************************************************************************/
/********************************************************************************************
* EHexShowMode - current data mode representation. *
********************************************************************************************/
enum class EHexShowMode : DWORD
{
ASBYTE = 1, ASWORD = 2, ASDWORD = 4, ASQWORD = 8
Expand Down Expand Up @@ -151,7 +151,7 @@ namespace HEXCTRL
********************************************************************************************/
struct HEXDATASTRUCT
{
EHexDataMode enCreateMode { EHexDataMode::DATA_MEMORY }; //Working data mode.
EHexDataMode enDataMode { EHexDataMode::DATA_MEMORY }; //Working data mode.
ULONGLONG ullDataSize { }; //Size of the data to display, in bytes.
ULONGLONG ullSelectionStart { }; //Select this initial position. Works only if ullSelectionSize > 0.
ULONGLONG ullSelectionSize { }; //How many bytes to set as selected.
Expand Down
38 changes: 19 additions & 19 deletions HexCtrl/src/CHexCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "strsafe.h"
#include <cassert>
#include <algorithm>
#include <numeric>
#pragma comment(lib, "Dwmapi.lib")

using namespace HEXCTRL;
Expand Down Expand Up @@ -441,12 +442,12 @@ void CHexCtrl::SetData(const HEXDATASTRUCT& hds)
m_hwndMsg = hds.hwndMsg;

//Virtual mode is possible only when there is a MSG window, a data requests will be sent to.
if (hds.enCreateMode == EHexDataMode::DATA_MSG && !GetMsgWindow())
if (hds.enDataMode == EHexDataMode::DATA_MSG && !GetMsgWindow())
{
MessageBoxW(L"HexCtrl EHexDataMode::DATA_MSG mode requires HEXDATASTRUCT::hwndMsg to be set.", L"Error", MB_ICONWARNING);
return;
}
else if (hds.enCreateMode == EHexDataMode::DATA_VIRTUAL && !hds.pHexVirtual)
else if (hds.enDataMode == EHexDataMode::DATA_VIRTUAL && !hds.pHexVirtual)
{
MessageBoxW(L"HexCtrl EHexDataMode::DATA_VIRTUAL mode requires HEXDATASTRUCT::pHexVirtual to be set.", L"Error", MB_ICONWARNING);
return;
Expand All @@ -457,7 +458,7 @@ void CHexCtrl::SetData(const HEXDATASTRUCT& hds)
m_fDataSet = true;
m_pData = hds.pData;
m_ullDataSize = hds.ullDataSize;
m_enCreateMode = hds.enCreateMode;
m_enDataMode = hds.enDataMode;
m_fMutable = hds.fMutable;
m_dwOffsetDigits = hds.ullDataSize <= 0xffffffffUL ? 8 :
(hds.ullDataSize <= 0xffffffffffUL ? 10 :
Expand Down Expand Up @@ -771,7 +772,7 @@ BOOL CHexCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
switch (uId)
{
case IDM_HEXCTRL_MAIN_SEARCH:
if (m_enCreateMode == EHexDataMode::DATA_MEMORY)
if (m_enDataMode == EHexDataMode::DATA_MEMORY)
m_pDlgSearch->ShowWindow(SW_SHOW);
else
MessageBoxW(pwszErrVirtual, L"Error", MB_ICONEXCLAMATION);
Expand Down Expand Up @@ -1763,7 +1764,7 @@ void CHexCtrl::OnNcPaint()

void CHexCtrl::OnDestroy()
{
if (m_enCreateMode == EHexDataMode::DATA_MSG)
if (m_enDataMode == EHexDataMode::DATA_MSG)
if (GetMsgWindow() != GetParent()->GetSafeHwnd()) //To avoid sending notify message twice to the same window.
MsgWindowNotify(HEXCTRL_MSG_DESTROY);

Expand Down Expand Up @@ -1792,7 +1793,7 @@ BYTE CHexCtrl::GetByte(ULONGLONG ullIndex)const
return 0x00;

//If it's virtual data control we aquire next byte_to_print from m_hwndMsg window.
switch (m_enCreateMode)
switch (m_enDataMode)
{
case EHexDataMode::DATA_MEMORY:
{
Expand Down Expand Up @@ -1830,7 +1831,7 @@ WORD CHexCtrl::GetWord(ULONGLONG ullIndex) const
return 0;

WORD wData;
if (m_enCreateMode == EHexDataMode::DATA_MEMORY)
if (m_enDataMode == EHexDataMode::DATA_MEMORY)
wData = *(PWORD)((DWORD_PTR)m_pData + ullIndex);
else
wData = ((WORD)GetByte(ullIndex)) | ((WORD)GetByte(ullIndex + 1) << 8);
Expand All @@ -1845,7 +1846,7 @@ DWORD CHexCtrl::GetDword(ULONGLONG ullIndex) const
return 0;

DWORD dwData;
if (m_enCreateMode == EHexDataMode::DATA_MEMORY)
if (m_enDataMode == EHexDataMode::DATA_MEMORY)
dwData = *(PDWORD)((DWORD_PTR)m_pData + ullIndex);
else
dwData = ((DWORD)GetByte(ullIndex)) | ((DWORD)GetByte(ullIndex + 1) << 8)
Expand All @@ -1861,7 +1862,7 @@ QWORD CHexCtrl::GetQword(ULONGLONG ullIndex) const
return 0;

QWORD ullData;
if (m_enCreateMode == EHexDataMode::DATA_MEMORY)
if (m_enDataMode == EHexDataMode::DATA_MEMORY)
ullData = *(PQWORD)((DWORD_PTR)m_pData + ullIndex);
else
ullData = ((QWORD)GetByte(ullIndex)) | ((QWORD)GetByte(ullIndex + 1) << 8)
Expand All @@ -1875,7 +1876,7 @@ QWORD CHexCtrl::GetQword(ULONGLONG ullIndex) const
bool CHexCtrl::SetByte(ULONGLONG ullIndex, BYTE bData)
{
//Data overflow check.
if (ullIndex >= m_ullDataSize || m_enCreateMode != EHexDataMode::DATA_MEMORY)
if (ullIndex >= m_ullDataSize || m_enDataMode != EHexDataMode::DATA_MEMORY)
return false;

m_pData[ullIndex] = bData;
Expand All @@ -1886,7 +1887,7 @@ bool CHexCtrl::SetByte(ULONGLONG ullIndex, BYTE bData)
bool CHexCtrl::SetWord(ULONGLONG ullIndex, WORD wData)
{
//Data overflow check.
if ((ullIndex + sizeof(WORD)) > m_ullDataSize || m_enCreateMode != EHexDataMode::DATA_MEMORY)
if ((ullIndex + sizeof(WORD)) > m_ullDataSize || m_enDataMode != EHexDataMode::DATA_MEMORY)
return false;

*(PWORD)((DWORD_PTR)m_pData + ullIndex) = wData;
Expand All @@ -1897,7 +1898,7 @@ bool CHexCtrl::SetWord(ULONGLONG ullIndex, WORD wData)
bool CHexCtrl::SetDword(ULONGLONG ullIndex, DWORD dwData)
{
//Data overflow check.
if ((ullIndex + sizeof(DWORD)) > m_ullDataSize || m_enCreateMode != EHexDataMode::DATA_MEMORY)
if ((ullIndex + sizeof(DWORD)) > m_ullDataSize || m_enDataMode != EHexDataMode::DATA_MEMORY)
return false;

*(PDWORD)((DWORD_PTR)m_pData + ullIndex) = dwData;
Expand All @@ -1908,7 +1909,7 @@ bool CHexCtrl::SetDword(ULONGLONG ullIndex, DWORD dwData)
bool CHexCtrl::SetQword(ULONGLONG ullIndex, QWORD qwData)
{
//Data overflow check.
if ((ullIndex + sizeof(QWORD)) > m_ullDataSize || m_enCreateMode != EHexDataMode::DATA_MEMORY)
if ((ullIndex + sizeof(QWORD)) > m_ullDataSize || m_enDataMode != EHexDataMode::DATA_MEMORY)
return false;

*(PQWORD)((DWORD_PTR)m_pData + ullIndex) = qwData;
Expand All @@ -1930,16 +1931,15 @@ void CHexCtrl::ModifyData(const HEXMODIFYSTRUCT& hms, bool fRedraw)
m_deqRedo.clear(); //No Redo unless we make Undo.
SnapshotUndo(vecRef);

ULONGLONG ullTotalSize { };
for (auto& i : vecRef)
ullTotalSize += i.ullSize;
ULONGLONG ullTotalSize = std::accumulate(vecRef.begin(), vecRef.end(), ULONGLONG { },
[](ULONGLONG ullSumm, const HEXSPANSTRUCT& ref) {return ullSumm + ref.ullSize; });

switch (m_enCreateMode)
switch (m_enDataMode)
{
case EHexDataMode::DATA_MEMORY: //Modify only in non Virtual mode.
{
PBYTE pData = GetData();
switch (hms.enCreateMode)
switch (hms.enModifyMode)
{
case EHexModifyMode::MODIFY_DEFAULT:
{
Expand Down Expand Up @@ -2877,7 +2877,7 @@ void CHexCtrl::FillWithZeros()
HEXMODIFYSTRUCT hms;
hms.vecSpan = m_pSelect->GetVector();
hms.ullDataSize = 1;
hms.enCreateMode = EHexModifyMode::MODIFY_REPEAT;
hms.enModifyMode = EHexModifyMode::MODIFY_REPEAT;
unsigned char chZero { 0 };
hms.pData = &chZero;
ModifyData(hms);
Expand Down
10 changes: 5 additions & 5 deletions HexCtrl/src/CHexCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ namespace HEXCTRL::INTERNAL
bool Create(const HEXCREATESTRUCT& hcs) override; //Main initialization method.
bool CreateDialogCtrl(UINT uCtrlID, HWND hwndDlg) override; //Сreates custom dialog control.
void Destroy() override; //Deleter.
DWORD GetCapacity()const; //Current capacity.
auto GetColor()const->HEXCOLORSTRUCT; //Current colors.
DWORD GetCapacity()const override; //Current capacity.
auto GetColor()const->HEXCOLORSTRUCT override; //Current colors.
long GetFontSize()const override; //Current font size.
HMENU GetMenuHandle()const override; //Context menu handle.
auto GetSelection()const->std::vector<HEXSPANSTRUCT> & override; //Gets current selection.
auto GetShowMode()const->EHexShowMode; //Retrieves current show mode.
auto GetShowMode()const->EHexShowMode override; //Retrieves current show mode.
HWND GetWindowHandle()const override; //Retrieves control's window handle.
void GoToOffset(ULONGLONG ullOffset, bool fSelect, ULONGLONG ullSize) override; //Scrolls to given offset.
bool IsCreated()const override; //Shows whether control is created or not.
Expand All @@ -57,7 +57,7 @@ namespace HEXCTRL::INTERNAL
void SetFontSize(UINT uiSize) override; //Sets the control's font size.
void SetMutable(bool fEnable) override; //Enable or disable edit mode.
void SetSelection(ULONGLONG ullOffset, ULONGLONG ullSize) override; //Sets current selection.
void SetShowMode(EHexShowMode enShowMode); //Sets current data show mode.
void SetShowMode(EHexShowMode enShowMode) override; //Sets current data show mode.
void SetWheelRatio(double dbRatio) override; //Sets the ratio for how much to scroll with mouse-wheel.
protected:
DECLARE_MESSAGE_MAP()
Expand Down Expand Up @@ -147,7 +147,7 @@ namespace HEXCTRL::INTERNAL
const int m_iFirstVertLine { 0 }; //First vertical line indent.
const size_t m_dwsUndoMax { 500 }; //How many Undo states to preserve.
HEXCOLORSTRUCT m_stColor; //All control related colors.
EHexDataMode m_enCreateMode { EHexDataMode::DATA_MEMORY }; //Control's creation mode.
EHexDataMode m_enDataMode { EHexDataMode::DATA_MEMORY }; //Control's creation mode.
EHexShowMode m_enShowMode { }; //Current "Show data" mode.
PBYTE m_pData { }; //Main data pointer. Modifiable in "Edit" mode.
IHexVirtual* m_pHexVirtual { }; //Data handler pointer for EHexDataMode::DATA_VIRTUAL
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgFillWith.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void CHexDlgFillWith::OnOK()
int iRadioType = GetCheckedRadioButton(IDC_HEXCTRL_FILLWITHDATA_RADIO_HEX, IDC_HEXCTRL_FILLWITHDATA_RADIO_UTF16);

HEXMODIFYSTRUCT hms;
hms.enCreateMode = EHexModifyMode::MODIFY_REPEAT;
hms.enModifyMode = EHexModifyMode::MODIFY_REPEAT;
hms.vecSpan = pHex->GetSelection();
if (hms.vecSpan.empty())
return;
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void CHexDlgOperations::OnBnClickedOk()
int iRadioDataSize = GetCheckedRadioButton(IDC_HEXCTRL_OPERATIONS_RADIO_BYTE, IDC_HEXCTRL_OPERATIONS_RADIO_QWORD);

HEXMODIFYSTRUCT hms;
hms.enCreateMode = EHexModifyMode::MODIFY_OPERATION;
hms.enModifyMode = EHexModifyMode::MODIFY_OPERATION;
hms.vecSpan = pHex->GetSelection();
if (hms.vecSpan.empty())
return;
Expand Down
7 changes: 3 additions & 4 deletions HexCtrl/verinfo/VerInfoRun.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ param(
[string]$patchFile
)

$set_verinfoPath=[Environment]::GetEnvironmentVariable('SET_VERINFO','User')
if($set_verinfoPath)
{
&$set_verinfoPath -versionFile "$versionFile" -patchFile "$patchFile"
$set_verinfoPath = [Environment]::GetEnvironmentVariable('SET_VERINFO', 'User')
if ($set_verinfoPath) {
&$set_verinfoPath -versionFile "$versionFile" -patchFile "$patchFile"
}
4 changes: 2 additions & 2 deletions HexCtrl/verinfo/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
#define PRODUCT_DESC "Hex Control for MFC/Win32"
#define COPYRIGHT_NAME "(C) Jovibor 2019"
#define MAJOR_VERSION 2
#define MINOR_VERSION 8
#define MAINTENANCE_VERSION 1
#define MINOR_VERSION 9
#define MAINTENANCE_VERSION 0
#define REVISION_VERSION 0
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
## **Hex Control, C++/MFC**
![](docs/img/hexctrl_mainwnd.jpg)
![](docs/img/hexctrl_operationswnd.jpg)
## Table of Contents
* [Introduction](#introduction)
* [Installation](#installation)
Expand Down Expand Up @@ -82,6 +81,8 @@ It is written and tested with **/std:c++17** in *Visual Studio 2019*, under the
* Cutomizable look and appearance
* Written with **/std:c++17** standard conformance

![](docs/img/hexctrl_operationswnd.jpg)

## [](#)Installation
The **HexControl** can be used in two different ways:
* Building from the sources as a part of your project
Expand Down Expand Up @@ -209,14 +210,14 @@ myHex->SetData(hds);
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.
Theese 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 [`enMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#hexdatastruct).
These modes are ruled over through the [`enDataMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#hexdatastruct).

### [](#)Memory Data
It's the default data mode the control works in.
The [`enMode`](#ehexdatamode) member of the [`HEXDATASTRUCT`](#hexdatastruct) is set to `DATA_MEMORY`, and `pData` just points to bytes in memory.
The [`enDataMode`](#ehexdatamode) member of the [`HEXDATASTRUCT`](#hexdatastruct) is set to `DATA_MEMORY`, and `pData` just points to bytes in memory.

### [](#)Message Window
If [`enMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#hexdatastruct) is set to `DATA_MSG`, the control works in so called **Message Window mode**.
If [`enDataMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#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 next byte, it will first ask for this byte from the [`HEXDATASTRUCT::hwndMsg`](#hexdatastruct) window, in the form of **[WM_NOTIFY](https://docs.microsoft.com/en-us/windows/win32/controls/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`](#hexdatastruct) is equal to the control's parent window.
Expand All @@ -243,7 +244,7 @@ The first member of this structure is a standard Windows' **[NMHDR](https://docs
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 [`enMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#hexdatastruct) is set to `DATA_VIRTUAL` then all the data routine will be done through `HEXDATASTRUCT::pHexVirtual` pointer.
If [`enDataMode`](#ehexdatamode) member of [`HEXDATASTRUCT`](#hexdatastruct) is set to `DATA_VIRTUAL` then all the data routine will be done through `HEXDATASTRUCT::pHexVirtual` pointer.
This pointer is of `IHexVirtual` class type, which is a pure abstract base class.
You have to derive your own class from it and implement all its public methods:
Expand Down Expand Up @@ -474,8 +475,8 @@ struct HEXCOLORSTRUCT
Main struct to set a data to display in the control.
```cpp
struct HEXDATASTRUCT
{
EHexDataMode enMode { EHexDataMode::DATA_MEMORY }; //Working data mode.
{
EHexDataMode enDataMode { EHexDataMode::DATA_MEMORY }; //Working data mode.
ULONGLONG ullDataSize { }; //Size of the data to display, in bytes.
ULONGLONG ullSelectionStart { }; //Select this initial position. Works only if ullSelectionSize > 0.
ULONGLONG ullSelectionSize { }; //How many bytes to set as selected.
Expand All @@ -484,9 +485,11 @@ struct HEXDATASTRUCT
PBYTE pData { }; //Data pointer for DATA_MEMORY mode. Not used in other modes.
bool fMutable { false }; //Is data mutable (editable) or read-only.
};

```

### [](#)HEXSPANSTRUCT
This struct is used mostly in selection and bookmarking routines. It shows offset and size of the data.
```cpp
struct HEXSPANSTRUCT
{
Expand All @@ -500,20 +503,20 @@ This structure is used internally in [`DATA_MEMORY`](#ehexdatamode) mode, as wel
```cpp
struct HEXMODIFYSTRUCT
{
EHexModifyMode enMode { EHexModifyMode::MODIFY_DEFAULT }; //Modify mode.
EHexOperMode enOperMode { }; //Operation mode enum. Used only if enMode==MODIFY_OPERATION.
const BYTE* pData { }; //Pointer to a data to be set.
ULONGLONG ullDataSize { }; //Size of the data pData is pointing to.
EHexModifyMode enModifyMode { EHexModifyMode::MODIFY_DEFAULT }; //Modify mode.
EHexOperMode enOperMode { }; //Operation mode enum. Used only if enModifyMode == MODIFY_OPERATION.
const BYTE* pData { }; //Pointer to a data to be set.
ULONGLONG ullDataSize { }; //Size of the data pData is pointing to.
std::vector<HEXSPANSTRUCT> vecSpan { }; //Vector of data offsets and sizes.
};
```
When `enMode` is set to [`EHexModifyMode::MODIFY_DEFAULT`](#ehexmodifymode), bytes from `pData` just replace corresponding data bytes as is.
When `enModifyMode` is set to [`EHexModifyMode::MODIFY_DEFAULT`](#ehexmodifymode), bytes from `pData` just replace corresponding data bytes as is.

If `enMode` is equal to [`EHexModifyMode::MODIFY_REPEAT`](#ehexmodifymode) then block by block replacement takes place few times.
If `enModifyMode` is equal to [`EHexModifyMode::MODIFY_REPEAT`](#ehexmodifymode) then block by block replacement takes place few times.

For example: if `SUM(vecSpan.ullSize)` = 9, `ullDataSize` = 3 and `enMode` is set to [`EHexModifyMode::MODIFY_REPEAT`](#ehexmodifymode), bytes in memory at `vecSpan.ullOffset` position are `123456789`, and bytes pointed to by `pData` are `345`, then, after modification, bytes at `vecSpan.ullOffset` will be `345345345`.
For example: if `SUM(vecSpan.ullSize)` = 9, `ullDataSize` = 3 and `enModifyMode` is set to [`EHexModifyMode::MODIFY_REPEAT`](#ehexmodifymode), bytes in memory at `vecSpan.ullOffset` position are `123456789`, and bytes pointed to by `pData` are `345`, then, after modification, bytes at `vecSpan.ullOffset` will be `345345345`.

If `enMode` is equal to [`EHexModifyMode::MODIFY_OPERATION`](#ehexmodifymode) then
If `enModifyMode` is equal to [`EHexModifyMode::MODIFY_OPERATION`](#ehexmodifymode) then
[`enOperMode`](#ehexopermode) comes into play, showing what kind of operation must be performed on data.

### [](#)HEXNOTIFYSTRUCT
Expand Down

0 comments on commit 60985a6

Please sign in to comment.