Skip to content

Commit

Permalink
Experimental support for all encodings, with max chars greater than one.
Browse files Browse the repository at this point in the history
Text for such encodings renders without proper indentation in the text area.
  • Loading branch information
jovibor committed Nov 15, 2021
1 parent dbe8f7c commit 15edd0d
Show file tree
Hide file tree
Showing 14 changed files with 53 additions and 51 deletions.
2 changes: 1 addition & 1 deletion HexCtrl/dep/ListEx/src/CListEx.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace HEXCTRL::LISTEX::INTERNAL
void SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare, EListExSortMode enSortMode)override;
DECLARE_DYNAMIC(CListEx)
DECLARE_MESSAGE_MAP()
protected:
private:
[[nodiscard]] long GetFontSize();
CListExHdr& GetHeaderCtrl()override { return m_stListHeader; }
void FontSizeIncDec(bool fInc);
Expand Down
6 changes: 3 additions & 3 deletions HexCtrl/res/HexCtrl.rc
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,14 @@ BEGIN
CONTROL "",IDC_HEXCTRL_CALLBACK_PROGBAR,"msctls_progress32",WS_BORDER,16,26,172,14
END

IDD_HEXCTRL_ENCODING DIALOGEX 0, 0, 315, 322
IDD_HEXCTRL_ENCODING DIALOGEX 0, 0, 315, 329
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Encoding"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_HEXCTRL_ENCODING_LIST,"SysListView32",LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,22,308,297
LTEXT "Below are listed all the code pages that are installed in the system.\r\nGreyed out the code pages that are currently unsupported by HexCtrl.",IDC_STATIC,6,4,228,16
CONTROL "",IDC_HEXCTRL_ENCODING_LIST,"SysListView32",LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,32,311,297
LTEXT "Below are listed all the code pages that are installed in the system.\r\nEncodings with the max chars more than one byte are supported only partially, without proper indentation. Such encodings are grey color highlighted.",IDC_STATIC,6,4,308,26
END

IDD_HEXCTRL_GOTO DIALOGEX 0, 0, 269, 97
Expand Down
41 changes: 23 additions & 18 deletions HexCtrl/src/CHexCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ namespace HEXCTRL
bool fAlt { };
};

constexpr auto HEXCTRL_CLASSNAME_WSTR { L"HexCtrl" }; //HexControl Class name.
constexpr auto ID_TOOLTIP_BKM { 0x01ULL }; //Tooltip ID for bookmarks.
constexpr auto ID_TOOLTIP_OFFSET { 0x02ULL }; //Tooltip ID for offset.
constexpr auto WSTR_HEXCTRL_CLASSNAME { L"HexCtrl" }; //HexControl Class name.
constexpr auto ID_TOOLTIP_BKM { 0x01UL }; //Tooltip ID for bookmarks.
constexpr auto ID_TOOLTIP_OFFSET { 0x02UL }; //Tooltip ID for offset.
}
}

Expand Down Expand Up @@ -145,7 +145,7 @@ CHexCtrl::CHexCtrl()

const auto hInst = AfxGetInstanceHandle();
WNDCLASSEXW wc { };
if (!::GetClassInfoExW(hInst, HEXCTRL_CLASSNAME_WSTR, &wc))
if (!::GetClassInfoExW(hInst, WSTR_HEXCTRL_CLASSNAME, &wc))
{
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
Expand All @@ -156,7 +156,7 @@ CHexCtrl::CHexCtrl()
wc.hCursor = static_cast<HCURSOR>(LoadImageW(nullptr, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = HEXCTRL_CLASSNAME_WSTR;
wc.lpszClassName = WSTR_HEXCTRL_CLASSNAME;
if (!RegisterClassExW(&wc)) {
MessageBoxW(L"HexControl RegisterClassExW error.", L"Error", MB_ICONERROR);
return;
Expand Down Expand Up @@ -301,7 +301,7 @@ bool CHexCtrl::Create(const HEXCREATE& hcs)
std::wstring wstrError;
const auto lmbCreateWnd = [&](UINT uID, DWORD dwStyle)
{
if (!CWnd::CreateEx(hcs.dwExStyle, HEXCTRL_CLASSNAME_WSTR, L"HexControl", dwStyle, hcs.rect,
if (!CWnd::CreateEx(hcs.dwExStyle, WSTR_HEXCTRL_CLASSNAME, L"HexControl", dwStyle, hcs.rect,
CWnd::FromHandle(hcs.hwndParent), uID))
wstrError = std::format(L"HexCtrl (ID: {}) CreateEx failed.\r\nCheck HEXCREATE parameters.", uID);
};
Expand Down Expand Up @@ -1753,11 +1753,11 @@ void CHexCtrl::SetEncoding(int iCodePage)
if (!IsCreated())
return;

CPINFOEXW stCPInfo { };
CPINFOEXW stCPInfo;
std::wstring_view wstrFormat { };
if (iCodePage == -1)
wstrFormat = L"ASCII";
else if (GetCPInfoExW(static_cast<UINT>(iCodePage), 0, &stCPInfo) != FALSE && stCPInfo.MaxCharSize == 1)
else if (GetCPInfoExW(static_cast<UINT>(iCodePage), 0, &stCPInfo) != FALSE)
wstrFormat = L"Codepage {}";

if (!wstrFormat.empty())
Expand Down Expand Up @@ -1919,34 +1919,39 @@ auto CHexCtrl::BuildDataToDraw(ULONGLONG ullStartLine, int iLines)const->std::tu
return { };

const auto ullOffsetStart = ullStartLine * m_dwCapacity; //Offset of the visible data to print.
const auto ullDataSize = GetDataSize();
std::size_t sSizeDataToPrint = static_cast<std::size_t>(iLines) * static_cast<std::size_t>(m_dwCapacity); //Size of the visible data to print.
if (ullOffsetStart + sSizeDataToPrint > GetDataSize())
sSizeDataToPrint = static_cast<std::size_t>(GetDataSize() - ullOffsetStart);

if (ullOffsetStart + sSizeDataToPrint > ullDataSize)
sSizeDataToPrint = static_cast<std::size_t>(ullDataSize - ullOffsetStart);

const auto spnData = GetData({ ullOffsetStart, sSizeDataToPrint }); //Span data to print.
assert(!spnData.empty());
assert(spnData.size() == sSizeDataToPrint);

const auto pData = reinterpret_cast<PBYTE>(spnData.data()); //Pointer to data to print.
const auto pDataBegin = reinterpret_cast<unsigned char*>(spnData.data()); //Pointer to data to print.
const auto pDataEnd = pDataBegin + sSizeDataToPrint;

//Hex Bytes to print.
std::wstring wstrHex { };
wstrHex.reserve(sSizeDataToPrint * 2);
for (auto iterpData = pData; iterpData < pData + sSizeDataToPrint; ++iterpData) //Converting bytes to Hexes.
for (auto iterData = pDataBegin; iterData < pDataEnd; ++iterData) //Converting bytes to Hexes.
{
wstrHex.push_back(g_pwszHexMap[(*iterpData >> 4) & 0x0F]);
wstrHex.push_back(g_pwszHexMap[*iterpData & 0x0F]);
wstrHex.push_back(g_pwszHexMap[(*iterData >> 4) & 0x0F]);
wstrHex.push_back(g_pwszHexMap[*iterData & 0x0F]);
}

//Converting bytes to Text.
//Text to print.
std::wstring wstrText { };
const auto iEncoding = GetEncoding();
if (iEncoding == -1) //If default ASCII codepage, simply assigning pData to wstrText w/o any conversion.
if (iEncoding == -1) //If it's default ASCII codepage we simply assigning [pDataBegin...pDataEnd) to wstrText w/o any conversion.
{
wstrText.assign(pData, pData + sSizeDataToPrint);
wstrText.assign(pDataBegin, pDataEnd);
}
else
{
wstrText.resize(sSizeDataToPrint);
MultiByteToWideChar(iEncoding, 0, reinterpret_cast<LPCCH>(pData),
MultiByteToWideChar(iEncoding, 0, reinterpret_cast<LPCCH>(pDataBegin),
static_cast<int>(sSizeDataToPrint), wstrText.data(), static_cast<int>(sSizeDataToPrint));
}
ReplaceUnprintable(wstrText, iEncoding == -1, true);
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgAbout.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace HEXCTRL::INTERNAL
{
public:
explicit CHexDlgAbout(CWnd* pParent) : CDialogEx(IDD_HEXCTRL_ABOUT, pParent) {}
protected:
private:
BOOL OnInitDialog()override;
DECLARE_MESSAGE_MAP()
};
Expand Down
8 changes: 4 additions & 4 deletions HexCtrl/src/Dialogs/CHexDlgBkmMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ namespace HEXCTRL::INTERNAL
enum class EMenuID : std::uint16_t;
public:
BOOL Create(UINT nIDTemplate, CWnd* pParent, CHexBookmarks* pBookmarks);
protected:
private:
void DoDataExchange(CDataExchange* pDX)override;
BOOL OnInitDialog()override;
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
BOOL OnCommand(WPARAM wParam, LPARAM lParam)override;
BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)override;
afx_msg void OnClickRadioHexDec();
afx_msg void OnDestroy();
BOOL OnInitDialog()override;
afx_msg void OnListGetDispInfo(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnListItemChanged(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnListLClick(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnListDblClick(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnListRClick(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnListGetColor(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnClickRadioHexDec();
BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)override;
void UpdateList();
void SortBookmarks();
DECLARE_MESSAGE_MAP()
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgBkmProps.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace HEXCTRL::INTERNAL
public:
explicit CHexDlgBkmProps(CWnd* pParent = nullptr) : CDialogEx(IDD_HEXCTRL_BKMPROPS, pParent) {}
INT_PTR DoModal(HEXBKM& hbs, bool fShowAsHex);
protected:
private:
void DoDataExchange(CDataExchange* pDX)override;
BOOL OnInitDialog()override;
void OnOK()override;
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace HEXCTRL::INTERNAL
[[nodiscard]] bool IsCanceled()const;
void SetProgress(ULONGLONG ullProgCurr);
void ExitDlg();
protected:
private:
BOOL OnInitDialog()override;
void DoDataExchange(CDataExchange* pDX)override;
void OnBtnCancel();
Expand Down
9 changes: 4 additions & 5 deletions HexCtrl/src/Dialogs/CHexDlgEncoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,16 @@ void CHexDlgEncoding::OnListItemChanged(NMHDR* pNMHDR, LRESULT* /*pResult*/)
if (const auto* const pNMI = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
pNMI->iItem != -1 && pNMI->iSubItem != -1 && (pNMI->uNewState & LVIS_SELECTED))
{
const auto sIndex = static_cast<size_t>(pNMI->iItem);
if (const auto uMaxChars = m_vecCodePage[sIndex].uMaxChars; uMaxChars == 1)
m_pHexCtrl->SetEncoding(m_vecCodePage[sIndex].iCPID);
m_pHexCtrl->SetEncoding(m_vecCodePage[static_cast<std::size_t>(pNMI->iItem)].iCPID);
}
}

void CHexDlgEncoding::OnListGetColor(NMHDR* pNMHDR, LRESULT* /*pResult*/)
{
if (const auto pNMI = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); m_vecCodePage[static_cast<size_t>(pNMI->iItem)].uMaxChars > 1)
if (const auto pNMI = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
m_vecCodePage[static_cast<std::size_t>(pNMI->iItem)].uMaxChars > 1)
{
static LISTEXCOLOR stClr { RGB(240, 240, 240), RGB(70, 70, 70) };
static LISTEXCOLOR stClr { RGB(245, 245, 245), RGB(70, 70, 70) };
pNMI->lParam = reinterpret_cast<LPARAM>(&stClr);
}
}
Expand Down
11 changes: 5 additions & 6 deletions HexCtrl/src/Dialogs/CHexDlgEncoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ namespace HEXCTRL::INTERNAL
using namespace HEXCTRL::LISTEX;
class CHexDlgEncoding final : public CDialogEx
{
struct SCODEPAGE
{
int iCPID { };
std::wstring wstrName { };
UINT uMaxChars { };
};
public:
void AddCP(std::wstring_view wstr);
BOOL Create(UINT nIDTemplate, CWnd* pParent, IHexCtrl* pHexCtrl);
Expand All @@ -37,6 +31,11 @@ namespace HEXCTRL::INTERNAL
DECLARE_MESSAGE_MAP()
void SortList();
private:
struct SCODEPAGE {
int iCPID { };
std::wstring wstrName { };
UINT uMaxChars { };
};
inline static CHexDlgEncoding* m_pThis { };
IHexCtrl* m_pHexCtrl { };
IListExPtr m_pListMain { CreateListEx() };
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgFillData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ BOOL CHexDlgFillData::OnInitDialog()
m_stComboType.SetItemData(iIndex, static_cast<DWORD_PTR>(EFillType::FILL_WCHAR));
iIndex = m_stComboType.AddString(L"Random Data (MT19937)");
m_stComboType.SetItemData(iIndex, static_cast<DWORD_PTR>(EFillType::FILL_RAND_MT19937));
iIndex = m_stComboType.AddString(L"Pseudo Random Data (Less secure, fast)");
iIndex = m_stComboType.AddString(L"Pseudo Random Data (fast, but less secure)");
m_stComboType.SetItemData(iIndex, static_cast<DWORD_PTR>(EFillType::FILL_RAND_FAST));

CheckRadioButton(IDC_HEXCTRL_FILLDATA_RADIO_ALL, IDC_HEXCTRL_FILLDATA_RADIO_SEL, IDC_HEXCTRL_FILLDATA_RADIO_ALL);
Expand Down
2 changes: 1 addition & 1 deletion HexCtrl/src/Dialogs/CHexDlgFillData.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace HEXCTRL::INTERNAL
{
class CHexDlgFillData final : public CDialogEx
{
enum class EFillType : std::uint8_t;
public:
BOOL Create(UINT nIDTemplate, CWnd* pParent, IHexCtrl* pHexCtrl);
private:
enum class EFillType : std::uint8_t; //Forward declaration.
void DoDataExchange(CDataExchange* pDX)override;
BOOL OnInitDialog()override;
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
Expand Down
3 changes: 1 addition & 2 deletions HexCtrl/src/Dialogs/CHexDlgGoTo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace HEXCTRL::INTERNAL
BOOL Create(UINT nIDTemplate, CWnd* pParent, IHexCtrl* pHexCtrl);
[[nodiscard]] bool IsRepeatAvail()const;
void Repeat(bool fFwd = true); //fFwd: true - forward, false - backward.
protected:
private:
void DoDataExchange(CDataExchange* pDX)override;
BOOL OnInitDialog()override;
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
Expand All @@ -26,7 +26,6 @@ namespace HEXCTRL::INTERNAL
afx_msg void OnClickRadioBackCurr();
afx_msg void OnClickRadioBackEnd();
DECLARE_MESSAGE_MAP()
private:
[[nodiscard]] IHexCtrl* GetHexCtrl()const;
void HexCtrlGoOffset(ULONGLONG ullOffset);
void SetRangesText()const;
Expand Down
4 changes: 2 additions & 2 deletions HexCtrl/src/Dialogs/CHexDlgSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace HEXCTRL::INTERNAL
SEARCH_FLOAT, SEARCH_DOUBLE, SEARCH_FILETIME, SEARCH_IOTEST//REMOVELATER:
};

enum class ECmpType : std::uint16_t //Flags for the instantiations of templated MemCmp<>.
enum class CHexDlgSearch::ECmpType : std::uint16_t //Flags for the instantiations of templated MemCmp<>.
{
TYPE_CHAR_LOOP = 0x0001,
TYPE_WCHAR_LOOP = 0x0002,
Expand All @@ -44,7 +44,7 @@ namespace HEXCTRL::INTERNAL
TYPE_INT64 = 0x0080
};

enum class EMenuID : std::uint16_t
enum class CHexDlgSearch::EMenuID : std::uint16_t
{
IDM_SEARCH_ADDBKM = 0x8000, IDM_SEARCH_SELECTALL = 0x8001, IDM_SEARCH_CLEARALL = 0x8002
};
Expand Down
10 changes: 5 additions & 5 deletions HexCtrl/src/Dialogs/CHexDlgSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ namespace HEXCTRL::INTERNAL
using namespace LISTEX;
class CHexDlgSearch final : public CDialogEx
{
enum class EMode : std::uint8_t;
struct SFINDRESULT;
struct STHREADRUN;
public:
BOOL Create(UINT nIDTemplate, CWnd* pParent, IHexCtrl* pHexCtrl);
[[nodiscard]] bool IsSearchAvail()const; //Can we do search next/prev?
void SearchNextPrev(bool fForward);
BOOL ShowWindow(int nCmdShow);
private:
enum class EMode : std::uint8_t; //Forward declarations.
enum class ECmpType : std::uint16_t;
enum class EMenuID : std::uint16_t;
struct SFINDRESULT;
struct STHREADRUN;
void DoDataExchange(CDataExchange* pDX)override;
void AddToList(ULONGLONG ullOffset);
void ClearList();
void ComboSearchFill(LPCWSTR pwsz);
void ComboReplaceFill(LPCWSTR pwsz);

//Main routine for finding stuff.
[[nodiscard]] SFINDRESULT Finder(ULONGLONG& ullStart, ULONGLONG ullEnd, std::span<std::byte> spnSearch,
bool fForward = true, CHexDlgCallback* pDlgClbk = nullptr, bool fDlgExit = true);

[[nodiscard]] IHexCtrl* GetHexCtrl()const;
[[nodiscard]] EMode GetSearchMode()const; //Returns current search mode.
void HexCtrlHighlight(const std::vector<HEXSPAN>& vecSel); //Highlight found occurence in HexCtrl.
Expand Down

0 comments on commit 15edd0d

Please sign in to comment.