diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..a6962f4 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,22 @@ +Checks: '*, +-cppcoreguidelines-*,-google-*,-fuchsia-*,-hicpp-*,-cert-*,-clang-*, +-modernize-use-trailing-return-type, +-modernize-avoid-c-arrays, +-llvm-header-guard, +-llvm-namespace-comment, +-llvm-qualified-auto, +-readability-braces-around-statements, +-readability-implicit-bool-conversion, +-readability-magic-numbers, +-readability-redundant-access-specifiers, +-readability-isolate-declaration, +-readability-qualified-auto, +-readability-convert-member-functions-to-static, +-readability-misleading-indentation, +-misc-non-private-member-variables-in-classes, +-misc-use-after-move, +-bugprone-narrowing-conversions, +-bugprone-use-after-move' + + +HeaderFilterRegex: '.*' \ No newline at end of file diff --git a/Pepper/ChildFrm.cpp b/Pepper/ChildFrm.cpp index 7e4c143..29ad3b8 100644 --- a/Pepper/ChildFrm.cpp +++ b/Pepper/ChildFrm.cpp @@ -8,11 +8,12 @@ ****************************************************************************************************/ #include "stdafx.h" #include "ChildFrm.h" +#include "MainFrm.h" #include "ViewLeft.h" -#include "ViewRightTL.h" #include "ViewRightBL.h" -#include "ViewRightTR.h" #include "ViewRightBR.h" +#include "ViewRightTL.h" +#include "ViewRightTR.h" #include IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWndEx) @@ -20,6 +21,7 @@ IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWndEx) BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWndEx) ON_WM_SIZE() ON_WM_ERASEBKGND() + ON_WM_CLOSE() END_MESSAGE_MAP() BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs) @@ -54,14 +56,41 @@ BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pConte m_fSplitterCreated = true; + auto pMainFrm = (CMainFrame*)AfxGetMainWnd(); + pMainFrm->GetChildFramesCount()++; + return TRUE; } +void CChildFrame::OnClose() +{ + auto pMainFrm = (CMainFrame*)AfxGetMainWnd(); + --pMainFrm->GetChildFramesCount(); + pMainFrm->SetCurrFramePtrNull(); + m_vecWndStatus.clear(); + + CMDIChildWndEx::OnClose(); +} + BOOL CChildFrame::OnEraseBkgnd(CDC* pDC) { return CMDIChildWndEx::OnEraseBkgnd(pDC); } +auto CChildFrame::GetWndStatData() -> std::vector& +{ + return m_vecWndStatus; +} + +void CChildFrame::SetWindowStatus(CWnd* pWnd, bool fVisible) +{ + if (auto iter = std::find_if(m_vecWndStatus.begin(), m_vecWndStatus.end(), + [pWnd](const SWINDOWSTATUS& ref) {return ref.pWnd == pWnd; }); iter != m_vecWndStatus.end()) + { + iter->fVisible = fVisible; + } +} + void CChildFrame::OnSize(UINT nType, int cx, int cy) { if (m_fSplitterCreated && nType != SIZE_MINIMIZED && cx > 0 && cy > 0) diff --git a/Pepper/FileLoader.cpp b/Pepper/FileLoader.cpp index 2c1d5d5..318a4e2 100644 --- a/Pepper/FileLoader.cpp +++ b/Pepper/FileLoader.cpp @@ -75,16 +75,16 @@ HRESULT CFileLoader::ShowOffset(ULONGLONG ullOffset, ULONGLONG ullSelectionSize, { if (!pHexCtrl) { - if (!m_stHex->IsCreated()) - m_stHex->Create(m_hcs); - pHexCtrl = m_stHex.get(); + if (!m_pHex->IsCreated()) + m_pHex->Create(m_hcs); + pHexCtrl = m_pHex.get(); } EHexDataMode enMode; - PBYTE pData; + std::byte* pData; if (m_fMapViewOfFileWhole) { enMode = EHexDataMode::DATA_MEMORY; - pData = (PBYTE)m_lpBase; + pData = (std::byte*)m_lpBase; } else { enMode = EHexDataMode::DATA_MSG; @@ -124,7 +124,7 @@ HRESULT CFileLoader::ShowOffset(ULONGLONG ullOffset, ULONGLONG ullSelectionSize, pHexCtrl->SetData(m_hds); //If floating HexCtrl in use - bring it to front. - if (pHexCtrl == m_stHex.get()) + if (pHexCtrl == m_pHex.get()) ::SetForegroundWindow(pHexCtrl->GetWindowHandle()); return S_OK; @@ -137,9 +137,9 @@ HRESULT CFileLoader::ShowFilePiece(ULONGLONG ullOffset, ULONGLONG ullSize, IHexC if (!pHexCtrl) { - if (!m_stHex->IsCreated()) - m_stHex->Create(m_hcs); - pHexCtrl = m_stHex.get(); + if (!m_pHex->IsCreated()) + m_pHex->Create(m_hcs); + pHexCtrl = m_pHex.get(); } if (ullOffset >= (ULONGLONG)m_stFileSize.QuadPart) //Overflow check. @@ -151,10 +151,10 @@ HRESULT CFileLoader::ShowFilePiece(ULONGLONG ullOffset, ULONGLONG ullSize, IHexC ullSize = (ULONGLONG)m_stFileSize.QuadPart - ullOffset; EHexDataMode enMode; - PBYTE pData; + std::byte* pData; if (m_fMapViewOfFileWhole) { enMode = EHexDataMode::DATA_MEMORY; - pData = (PBYTE)((DWORD_PTR)m_lpBase + ullOffset); + pData = (std::byte*)((DWORD_PTR)m_lpBase + ullOffset); } else { enMode = EHexDataMode::DATA_MSG; @@ -207,8 +207,8 @@ HRESULT CFileLoader::MapFileOffset(QUERYDATA & rData, ULONGLONG ullOffset, DWORD if ((LONGLONG)(ullStartOffsetMapped + dwSizeToMap) > m_stFileSize.QuadPart) dwSizeToMap = (DWORD_PTR)(m_stFileSize.QuadPart - (LONGLONG)ullStartOffsetMapped); - DWORD dwOffsetHigh = (ullStartOffsetMapped >> 32) & 0xFFFFFFFFul; - DWORD dwOffsetLow = ullStartOffsetMapped & 0xFFFFFFFFul; + DWORD dwOffsetHigh = (ullStartOffsetMapped >> 32) & 0xFFFFFFFFUL; + DWORD dwOffsetLow = ullStartOffsetMapped & 0xFFFFFFFFUL; LPVOID lpData { }; if ((lpData = MapViewOfFile(m_hMapObject, FILE_MAP_READ, dwOffsetHigh, dwOffsetLow, dwSizeToMap)) == nullptr) return E_FILE_MAPVIEWOFFILE_SECTION_FAILED; @@ -269,14 +269,14 @@ HRESULT CFileLoader::UnloadFile() return S_OK; } -bool CFileLoader::IsLoaded() +bool CFileLoader::IsLoaded()const { return m_fLoaded; } -BOOL CFileLoader::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) +BOOL CFileLoader::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { - PHEXNOTIFYSTRUCT pHexNtfy = (PHEXNOTIFYSTRUCT)lParam; + auto pHexNtfy = (PHEXNOTIFYSTRUCT)lParam; switch (pHexNtfy->hdr.code) { @@ -293,10 +293,9 @@ BOOL CFileLoader::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) } break; case HEXCTRL_MSG_GETDATA: - m_byte = GetByte(pHexNtfy->hdr.hwndFrom, pHexNtfy->stSpan.ullOffset); - pHexNtfy->pData = &m_byte; + pHexNtfy->pData = GetData(pHexNtfy->hdr.hwndFrom, pHexNtfy->stSpan.ullOffset); break; - case HEXCTRL_MSG_DATACHANGE: + case HEXCTRL_MSG_SETDATA: m_fModified = true; break; } @@ -304,30 +303,28 @@ BOOL CFileLoader::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) return CWnd::OnNotify(wParam, lParam, pResult); } -unsigned char CFileLoader::GetByte(HWND hWnd, ULONGLONG ullOffset) +std::byte* CFileLoader::GetData(HWND hWnd, ULONGLONG ullOffset) { auto const& iter = std::find_if(m_vecQuery.begin(), m_vecQuery.end(), [hWnd](const QUERYDATA & rData) {return rData.hWnd == hWnd; }); if (iter == m_vecQuery.end()) - return 0; + return nullptr; - unsigned char chByte; + std::byte* pData { }; ullOffset += iter->ullOffsetDelta; if (m_fMapViewOfFileWhole && ullOffset < (ULONGLONG)m_stFileSize.QuadPart) - chByte = ((PBYTE)m_lpBase)[ullOffset]; + pData = ((std::byte*)m_lpBase) + ullOffset; else { if (ullOffset >= iter->ullStartOffsetMapped && ullOffset < iter->ullEndOffsetMapped) - chByte = ((PBYTE)iter->lpData)[ullOffset - iter->ullStartOffsetMapped]; + pData = ((std::byte*)iter->lpData) + (ullOffset - iter->ullStartOffsetMapped); else { if (MapFileOffset(*iter, ullOffset) == S_OK) - chByte = ((PBYTE)iter->lpData)[ullOffset - iter->ullStartOffsetMapped]; - else - chByte = 0; + pData = ((std::byte*)iter->lpData) + (ullOffset - iter->ullStartOffsetMapped); } } - return chByte; + return pData; } \ No newline at end of file diff --git a/Pepper/ListEx/ListEx.h b/Pepper/ListEx/ListEx.h index f464411..8e069f3 100644 --- a/Pepper/ListEx/ListEx.h +++ b/Pepper/ListEx/ListEx.h @@ -1,5 +1,5 @@ /**************************************************************************************** -* Copyright © 2018-2020 Jovibor https://github.com/jovibor/ * +* Copyright © 2018-2020 Jovibor https://github.com/jovibor/ * * This is very extended and featured version of CMFCListCtrl class. * * Official git repository: https://github.com/jovibor/ListEx/ * * This class is available under the "MIT License". * @@ -8,54 +8,70 @@ #pragma once #include #include +#include namespace LISTEX { /******************************************************************************************** - * EnListExSortMode - Sorting mode. * + * EListExSortMode - Sorting mode. * ********************************************************************************************/ - enum class EnListExSortMode : short + enum class EListExSortMode : WORD { SORT_LEX, SORT_NUMERIC }; + /******************************************** + * LISTEXCELLCOLOR - colors for the cell. * + ********************************************/ + struct LISTEXCELLCOLOR + { + COLORREF clrBk { }; + COLORREF clrText { }; + }; + using PLISTEXCELLCOLOR = LISTEXCELLCOLOR*; + /******************************************************************************************** - * LISTEXCOLORSTRUCT - All ListEx colors. * + * LISTEXCOLORS - All ListEx colors. * ********************************************************************************************/ - struct LISTEXCOLORSTRUCT + struct LISTEXCOLORS { - COLORREF clrListText { GetSysColor(COLOR_WINDOWTEXT) }; //List text color. - COLORREF clrListBkRow1 { GetSysColor(COLOR_WINDOW) }; //List Bk color of the odd rows. - COLORREF clrListBkRow2 { GetSysColor(COLOR_WINDOW) }; //List Bk color of the even rows. - COLORREF clrListGrid { RGB(220, 220, 220) }; //List grid color. - COLORREF clrListTextSelected { GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Selected item text color. - COLORREF clrListBkSelected { GetSysColor(COLOR_HIGHLIGHT) }; //Selected item bk color. - COLORREF clrTooltipText { GetSysColor(COLOR_INFOTEXT) }; //Tooltip window text color. - COLORREF clrTooltipBk { GetSysColor(COLOR_INFOBK) }; //Tooltip window bk color. - COLORREF clrListTextCellTt { GetSysColor(COLOR_WINDOWTEXT) }; //Text color of a cell that has tooltip. - COLORREF clrListBkCellTt { RGB(170, 170, 230) }; //Bk color of a cell that has tooltip. - COLORREF clrHdrText { GetSysColor(COLOR_WINDOWTEXT) }; //List header text color. - COLORREF clrHdrBk { GetSysColor(COLOR_WINDOW) }; //List header bk color. - COLORREF clrHdrHglInactive { GetSysColor(COLOR_GRADIENTINACTIVECAPTION) };//Header highlight inactive. - COLORREF clrHdrHglActive { GetSysColor(COLOR_GRADIENTACTIVECAPTION) }; //Header highlight active. - COLORREF clrBkNWA { GetSysColor(COLOR_WINDOW) }; //Bk of non working area. + COLORREF clrListText { GetSysColor(COLOR_WINDOWTEXT) }; //List text color. + COLORREF clrListTextLink { RGB(0, 0, 200) }; //List hyperlink text color. + COLORREF clrListTextSel { GetSysColor(COLOR_HIGHLIGHTTEXT) }; //Selected item text color. + COLORREF clrListTextLinkSel { RGB(250, 250, 250) }; //List hyperlink text color in selected cell. + COLORREF clrListTextCellTt { GetSysColor(COLOR_WINDOWTEXT) }; //Text color of a cell that has tooltip. + COLORREF clrListBkRow1 { GetSysColor(COLOR_WINDOW) }; //List Bk color of the odd rows. + COLORREF clrListBkRow2 { GetSysColor(COLOR_WINDOW) }; //List Bk color of the even rows. + COLORREF clrListBkSel { GetSysColor(COLOR_HIGHLIGHT) }; //Selected item bk color. + COLORREF clrListBkCellTt { RGB(170, 170, 230) }; //Bk color of a cell that has tooltip. + COLORREF clrListGrid { RGB(220, 220, 220) }; //List grid color. + COLORREF clrTooltipText { GetSysColor(COLOR_INFOTEXT) }; //Tooltip window text color. + COLORREF clrTooltipBk { GetSysColor(COLOR_INFOBK) }; //Tooltip window bk color. + COLORREF clrHdrText { GetSysColor(COLOR_WINDOWTEXT) }; //List header text color. + COLORREF clrHdrBk { GetSysColor(COLOR_WINDOW) }; //List header bk color. + COLORREF clrHdrHglInact { GetSysColor(COLOR_GRADIENTINACTIVECAPTION) };//Header highlight inactive. + COLORREF clrHdrHglAct { GetSysColor(COLOR_GRADIENTACTIVECAPTION) }; //Header highlight active. + COLORREF clrNWABk { GetSysColor(COLOR_WINDOW) }; //Bk of Non Working Area. }; /******************************************************************************************** * LISTEXCREATESTRUCT - Main initialization helper struct for CListEx::Create method. * ********************************************************************************************/ - struct LISTEXCREATESTRUCT { - LISTEXCOLORSTRUCT stColor { }; //All control's colors. - CRect rect; //Initial rect. - CWnd* pwndParent { }; //Parent window. - const LOGFONTW* pListLogFont { }; //List font. - const LOGFONTW* pHdrLogFont { }; //Header font. - DWORD dwStyle { }; //Control's styles. Zero for default. - UINT uID { }; //Control Id. - DWORD dwListGridWidth { 1 }; //Width of the list grid. - DWORD dwHdrHeight { 20 }; //Header height. - bool fSortable { false }; //Is list sortable, by clicking on the header column? - bool fDialogCtrl { false }; //If it's a list within dialog. + struct LISTEXCREATESTRUCT + { + LISTEXCOLORS stColor { }; //All control's colors. + CRect rect; //Initial rect. + CWnd* pParent { }; //Parent window. + LOGFONTW* pListLogFont { }; //List font. + LOGFONTW* pHdrLogFont { }; //Header font. + UINT uID { }; //List control ID. + DWORD dwStyle { }; //Control's styles. Zero for default. + DWORD dwListGridWidth { 1 }; //Width of the list grid. + DWORD dwHdrHeight { 20 }; //Header height. + bool fDialogCtrl { false }; //If it's a list within dialog. + bool fSortable { false }; //Is list sortable, by clicking on the header column? + bool fLinkUnderline { true }; //Links are displayed underlined or not. + bool fLinkTooltip { true }; //Show links' toolips. }; /******************************************** @@ -64,27 +80,26 @@ namespace LISTEX class IListEx : public CMFCListCtrl { public: - IListEx() = default; - virtual ~IListEx() = default; virtual bool Create(const LISTEXCREATESTRUCT& lcs) = 0; virtual void CreateDialogCtrl(UINT uCtrlID, CWnd* pwndDlg) = 0; virtual BOOL DeleteAllItems() = 0; virtual BOOL DeleteColumn(int nCol) = 0; virtual BOOL DeleteItem(int nItem) = 0; virtual void Destroy() = 0; - virtual ULONGLONG GetCellData(int iItem, int iSubitem)const = 0; - virtual EnListExSortMode GetColumnSortMode(int iColumn)const = 0; - virtual UINT GetFontSize()const = 0; - virtual int GetSortColumn()const = 0; - virtual bool GetSortAscending()const = 0; - virtual bool IsCreated()const = 0; + [[nodiscard]] virtual ULONGLONG GetCellData(int iItem, int iSubitem)const = 0; + [[nodiscard]] virtual LISTEXCOLORS GetColors()const = 0; + [[nodiscard]] virtual EListExSortMode GetColumnSortMode(int iColumn)const = 0; + [[nodiscard]] virtual UINT GetFontSize()const = 0; + [[nodiscard]] virtual int GetSortColumn()const = 0; + [[nodiscard]] virtual bool GetSortAscending()const = 0; + [[nodiscard]] virtual bool IsCreated()const = 0; virtual void SetCellColor(int iItem, int iSubitem, COLORREF clrBk, COLORREF clrText = -1) = 0; virtual void SetCellData(int iItem, int iSubitem, ULONGLONG ullData) = 0; virtual void SetCellMenu(int iItem, int iSubitem, CMenu* pMenu) = 0; - virtual void SetCellTooltip(int iItem, int iSubitem, const wchar_t* pwszTooltip, const wchar_t* pwszCaption = nullptr) = 0; - virtual void SetColor(const LISTEXCOLORSTRUCT& lcs) = 0; + virtual void SetCellTooltip(int iItem, int iSubitem, std::wstring_view wstrTooltip, std::wstring_view wstrCaption = L"") = 0; + virtual void SetColors(const LISTEXCOLORS& lcs) = 0; virtual void SetColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText = -1) = 0; - virtual void SetColumnSortMode(int iColumn, EnListExSortMode enSortMode) = 0; + virtual void SetColumnSortMode(int iColumn, EListExSortMode enSortMode) = 0; virtual void SetFont(const LOGFONTW* pLogFontNew) = 0; virtual void SetFontSize(UINT uiSize) = 0; virtual void SetHdrHeight(DWORD dwHeight) = 0; @@ -92,7 +107,8 @@ namespace LISTEX virtual void SetHdrColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText = -1) = 0; virtual void SetListMenu(CMenu* pMenu) = 0; virtual void SetRowColor(DWORD dwRow, COLORREF clrBk, COLORREF clrText = -1) = 0; - virtual void SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare = nullptr, EnListExSortMode enSortMode = EnListExSortMode::SORT_LEX) = 0; + virtual void SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare = nullptr, + EListExSortMode enSortMode = EListExSortMode::SORT_LEX) = 0; }; /******************************************************************************************** @@ -120,5 +136,7 @@ namespace LISTEX * WM_NOTIFY codes (NMHDR.code values) * ****************************************************************************/ - constexpr auto LISTEX_MSG_MENUSELECTED = 0x1000u; + constexpr auto LISTEX_MSG_MENUSELECTED = 0x1000U; //User defined menu item selected. + constexpr auto LISTEX_MSG_CELLCOLOR = 0x1001U; //Get cell color. + constexpr auto LISTEX_MSG_LINKCLICK = 0x1002U; //Hyperlink has been clicked. } \ No newline at end of file diff --git a/Pepper/ListEx/src/CListEx.cpp b/Pepper/ListEx/src/CListEx.cpp index 90844ee..437dc9a 100644 --- a/Pepper/ListEx/src/CListEx.cpp +++ b/Pepper/ListEx/src/CListEx.cpp @@ -13,7 +13,8 @@ using namespace LISTEX; using namespace LISTEX::INTERNAL; -namespace LISTEX { +namespace LISTEX +{ /******************************************** * CreateRawListEx function implementation. * ********************************************/ @@ -22,8 +23,56 @@ namespace LISTEX { return new CListEx(); } - namespace INTERNAL { - constexpr ULONG_PTR ID_TIMER_TOOLTIP { 0x01 }; //Timer ID. + namespace INTERNAL + { + /******************************************** + * SCELLTOOLTIP - tool-tips for the cell. * + ********************************************/ + struct CListEx::SCELLTOOLTIP + { + std::wstring wstrText; + std::wstring wstrCaption; + }; + + /******************************************** + * SCOLUMNCOLOR - colors for the column. * + ********************************************/ + struct CListEx::SCOLUMNCOLOR + { + COLORREF clrBk { }; //Background. + COLORREF clrText { }; //Text. + std::chrono::high_resolution_clock::time_point time { }; //Time when added. + }; + + /******************************************** + * SROWCOLOR - colors for the row. * + ********************************************/ + struct CListEx::SROWCOLOR + { + COLORREF clrBk { }; //Background. + COLORREF clrText { }; //Text. + std::chrono::high_resolution_clock::time_point time { }; //Time when added. + }; + + /******************************************** + * SITEMTEXT - text and links in the cell. * + ********************************************/ + struct CListEx::SITEMTEXT + { + SITEMTEXT(std::wstring_view wstrText, std::wstring_view wstrLink, std::wstring_view wstrTitle, + CRect rect, bool fLink = false, bool fTitle = false) : + wstrText(wstrText), wstrLink(wstrLink), wstrTitle(wstrTitle), rect(rect), fLink(fLink), fTitle(fTitle) {} + std::wstring wstrText { }; //Visible text. + std::wstring wstrLink { }; //Text within link tag. + std::wstring wstrTitle { }; //Text within title <...title="textFromHere"> tag. + CRect rect { }; //Rect text belongs to. + bool fLink { false }; //Is it just a text (wstrLink is empty) or text with link? + bool fTitle { false }; //Is it link with custom title (wstrTitle is not empty)? + }; + + constexpr ULONG_PTR ID_TIMER_TT_CELL_CHECK { 0x01 }; //Cell tool-tip check-timer ID. + constexpr ULONG_PTR ID_TIMER_TT_LINK_CHECK { 0x02 }; //Link tool-tip check-timer ID. + constexpr ULONG_PTR ID_TIMER_TT_LINK_ACTIVATE { 0x03 }; //Link tool-tip activate-timer ID. } } @@ -31,7 +80,6 @@ namespace LISTEX { * CListEx class implementation. * ****************************************************/ IMPLEMENT_DYNAMIC(CListEx, CMFCListCtrl) - BEGIN_MESSAGE_MAP(CListEx, CMFCListCtrl) ON_WM_SETCURSOR() ON_WM_KILLFOCUS() @@ -53,7 +101,9 @@ BEGIN_MESSAGE_MAP(CListEx, CMFCListCtrl) ON_NOTIFY(HDN_TRACKW, 0, &CListEx::OnHdnTrack) ON_WM_CONTEXTMENU() ON_WM_DESTROY() - ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CListEx::OnLvnColumnclick) + ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CListEx::OnLvnColumnClick) + ON_WM_LBUTTONUP() + END_MESSAGE_MAP() bool CListEx::Create(const LISTEXCREATESTRUCT& lcs) @@ -62,34 +112,46 @@ bool CListEx::Create(const LISTEXCREATESTRUCT& lcs) if (IsCreated()) return false; - LONG_PTR dwStyle = (LONG_PTR)lcs.dwStyle; + auto dwStyle = static_cast(lcs.dwStyle); if (lcs.fDialogCtrl) { - SubclassDlgItem(lcs.uID, lcs.pwndParent); + SubclassDlgItem(lcs.uID, lcs.pParent); dwStyle = GetWindowLongPtrW(m_hWnd, GWL_STYLE); SetWindowLongPtrW(m_hWnd, GWL_STYLE, dwStyle | LVS_OWNERDRAWFIXED | LVS_REPORT); } else if (!CMFCListCtrl::Create(lcs.dwStyle | WS_CHILD | WS_VISIBLE | LVS_OWNERDRAWFIXED | LVS_REPORT, - lcs.rect, lcs.pwndParent, lcs.uID)) + lcs.rect, lcs.pParent, lcs.uID)) return false; m_fVirtual = dwStyle & LVS_OWNERDATA; - m_stColor = lcs.stColor; + m_stColors = lcs.stColor; m_fSortable = lcs.fSortable; + m_fLinksUnderline = lcs.fLinkUnderline; + m_fLinkTooltip = lcs.fLinkTooltip; - if (!m_wndTt.CreateEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, nullptr, TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE | TTS_NOPREFIX | TTS_ALWAYSTIP, + if (!m_stWndTtCell.CreateEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, nullptr, TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr)) return false; - SetWindowTheme(m_wndTt, nullptr, L""); //To prevent Windows from changing theme of Balloon window. + SetWindowTheme(m_stWndTtCell, nullptr, L""); //To prevent Windows from changing theme of Balloon window. + + m_stTInfoCell.cbSize = TTTOOLINFOW_V1_SIZE; + m_stTInfoCell.uFlags = TTF_TRACK; + m_stTInfoCell.uId = 0x1; + m_stWndTtCell.SendMessageW(TTM_ADDTOOL, 0, reinterpret_cast(&m_stTInfoCell)); + m_stWndTtCell.SendMessageW(TTM_SETMAXTIPWIDTH, 0, static_cast(400)); //to allow use of newline \n. + m_stWndTtCell.SendMessageW(TTM_SETTIPTEXTCOLOR, static_cast(m_stColors.clrTooltipText), 0); + m_stWndTtCell.SendMessageW(TTM_SETTIPBKCOLOR, static_cast(m_stColors.clrTooltipBk), 0); + + if (!m_stWndTtLink.CreateEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, nullptr, TTS_NOANIMATE | TTS_NOFADE | TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr)) + return false; - m_stToolInfo.cbSize = TTTOOLINFOW_V1_SIZE; - m_stToolInfo.uFlags = TTF_TRACK; - m_stToolInfo.uId = 0x1; - m_wndTt.SendMessageW(TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&m_stToolInfo); - m_wndTt.SendMessageW(TTM_SETMAXTIPWIDTH, 0, (LPARAM)400); //to allow use of newline \n. - m_wndTt.SendMessageW(TTM_SETTIPTEXTCOLOR, (WPARAM)m_stColor.clrTooltipText, 0); - m_wndTt.SendMessageW(TTM_SETTIPBKCOLOR, (WPARAM)m_stColor.clrTooltipBk, 0); + m_stTInfoLink.cbSize = TTTOOLINFOW_V1_SIZE; + m_stTInfoLink.uFlags = TTF_TRACK; + m_stTInfoLink.uId = 0x2; + m_stWndTtLink.SendMessageW(TTM_ADDTOOL, 0, reinterpret_cast(&m_stTInfoLink)); + m_stWndTtLink.SendMessageW(TTM_SETMAXTIPWIDTH, 0, static_cast(400)); //to allow use of newline \n. m_dwGridWidth = lcs.dwListGridWidth; m_stNMII.hdr.idFrom = GetDlgCtrlID(); @@ -109,7 +171,13 @@ bool CListEx::Create(const LISTEXCREATESTRUCT& lcs) m_lSizeFont = lf.lfHeight; m_fontList.CreateFontIndirectW(&lf); - m_penGrid.CreatePen(PS_SOLID, m_dwGridWidth, m_stColor.clrListGrid); + lf.lfUnderline = 1; + m_fontListUnderline.CreateFontIndirectW(&lf); + m_penGrid.CreatePen(PS_SOLID, m_dwGridWidth, m_stColors.clrListGrid); + m_cursorDefault = static_cast(LoadImageW(nullptr, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); + m_cursorHand = static_cast(LoadImageW(nullptr, IDC_HAND, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); + SetClassLongPtrW(m_hWnd, GCLP_HCURSOR, 0); //To prevent cursor from blinking. + m_fCreated = true; SetHdrHeight(lcs.dwHdrHeight); @@ -124,7 +192,7 @@ bool CListEx::Create(const LISTEXCREATESTRUCT& lcs) void CListEx::CreateDialogCtrl(UINT uCtrlID, CWnd* pwndDlg) { LISTEXCREATESTRUCT lcs; - lcs.pwndParent = pwndDlg; + lcs.pParent = pwndDlg; lcs.uID = uCtrlID; lcs.fDialogCtrl = true; @@ -133,50 +201,46 @@ void CListEx::CreateDialogCtrl(UINT uCtrlID, CWnd* pwndDlg) int CALLBACK CListEx::DefCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { - IListEx* pListCtrl = (IListEx*)lParamSort; - int iSortColumn = pListCtrl->GetSortColumn(); - EnListExSortMode enSortMode = pListCtrl->GetColumnSortMode(iSortColumn); + auto pListCtrl = reinterpret_cast(lParamSort); + auto iSortColumn = pListCtrl->GetSortColumn(); + auto enSortMode = pListCtrl->GetColumnSortMode(iSortColumn); - std::wstring wstrItem1 = pListCtrl->GetItemText(static_cast(lParam1), iSortColumn).GetBuffer(); - std::wstring wstrItem2 = pListCtrl->GetItemText(static_cast(lParam2), iSortColumn).GetBuffer(); + std::wstring_view wstrItem1 = pListCtrl->GetItemText(static_cast(lParam1), iSortColumn).GetString(); + std::wstring_view wstrItem2 = pListCtrl->GetItemText(static_cast(lParam2), iSortColumn).GetString(); int iCompare { }; switch (enSortMode) { - case EnListExSortMode::SORT_LEX: + case EListExSortMode::SORT_LEX: iCompare = wstrItem1.compare(wstrItem2); break; - case EnListExSortMode::SORT_NUMERIC: + case EListExSortMode::SORT_NUMERIC: { LONGLONG llData1 { }, llData2 { }; StrToInt64ExW(wstrItem1.data(), STIF_SUPPORT_HEX, &llData1); StrToInt64ExW(wstrItem2.data(), STIF_SUPPORT_HEX, &llData2); - - if ((llData1 - llData2) < 0) - iCompare = -1; - else if ((llData1 - llData2) > 0) - iCompare = 1; + iCompare = llData1 != llData2 ? (llData1 - llData2 < 0 ? -1 : 1) : 0; } break; } - int result = 0; + int iResult = 0; if (pListCtrl->GetSortAscending()) { if (iCompare < 0) - result = -1; + iResult = -1; else if (iCompare > 0) - result = 1; + iResult = 1; } else { if (iCompare < 0) - result = 1; + iResult = 1; else if (iCompare > 0) - result = -1; + iResult = -1; } - return result; + return iResult; } BOOL CListEx::DeleteAllItems() @@ -256,11 +320,16 @@ ULONGLONG CListEx::GetCellData(int iItem, int iSubItem)const return 0; } -EnListExSortMode CListEx::GetColumnSortMode(int iColumn)const +LISTEXCOLORS CListEx::GetColors() const +{ + return m_stColors; +} + +EListExSortMode CListEx::GetColumnSortMode(int iColumn)const { assert(IsCreated()); - EnListExSortMode enMode; + EListExSortMode enMode; auto iter = m_umapColumnSortMode.find(iColumn); if (iter != m_umapColumnSortMode.end()) enMode = iter->second; @@ -310,11 +379,11 @@ UINT CListEx::MapIndexToID(UINT nItem)const //The unique ID is set in NMITEMACTIVATE::lParam by client. if (m_fVirtual) { - UINT uCtrlId = (UINT)GetDlgCtrlID(); + UINT uCtrlId = static_cast(GetDlgCtrlID()); NMITEMACTIVATE nmii { { m_hWnd, uCtrlId, LVM_MAPINDEXTOID } }; - nmii.iItem = (int)nItem; - GetParent()->SendMessageW(WM_NOTIFY, (WPARAM)uCtrlId, (LPARAM)&nmii); - ID = (UINT)nmii.lParam; + nmii.iItem = static_cast(nItem); + GetParent()->SendMessageW(WM_NOTIFY, static_cast(uCtrlId), reinterpret_cast(&nmii)); + ID = static_cast(nmii.lParam); } else ID = CMFCListCtrl::MapIndexToID(nItem); @@ -329,15 +398,15 @@ void CListEx::SetCellColor(int iItem, int iSubItem, COLORREF clrBk, COLORREF clr return; if (clrText == -1) //-1 for default color. - clrText = m_stColor.clrListText; + clrText = m_stColors.clrListText; - UINT ID = MapIndexToID((UINT)iItem); + UINT ID = MapIndexToID(static_cast(iItem)); auto it = m_umapCellColor.find(ID); //If there is no color for such item/subitem we just set it. if (it == m_umapCellColor.end()) { //Initializing inner map. - std::unordered_map umapInner { { iSubItem, CELLCOLOR { clrBk, clrText } } }; + std::unordered_map umapInner { { iSubItem, { clrBk, clrText } } }; m_umapCellColor.insert({ ID, std::move(umapInner) }); } else @@ -345,7 +414,7 @@ void CListEx::SetCellColor(int iItem, int iSubItem, COLORREF clrBk, COLORREF clr auto itInner = it->second.find(iSubItem); if (itInner == it->second.end()) - it->second.insert({ iSubItem, CELLCOLOR { clrBk, clrText } }); + it->second.insert({ iSubItem, { clrBk, clrText } }); else //If there is already exist this cell's color -> changing. { itInner->second.clrBk = clrBk; @@ -408,26 +477,23 @@ void CListEx::SetCellMenu(int iItem, int iSubItem, CMenu* pMenu) } } -void CListEx::SetCellTooltip(int iItem, int iSubItem, const wchar_t* pwszTooltip, const wchar_t* pwszCaption) +void CListEx::SetCellTooltip(int iItem, int iSubItem, std::wstring_view wstrTooltip, std::wstring_view wstrCaption) { assert(IsCreated()); if (!IsCreated()) return; - //Checking for nullptr, and assign empty string in such case. - const wchar_t* pCaption = pwszCaption ? pwszCaption : L""; - const wchar_t* pTooltip = pwszTooltip ? pwszTooltip : L""; - UINT ID = MapIndexToID(iItem); auto it = m_umapCellTt.find(ID); //If there is no tooltip for such item/subitem we just set it. if (it == m_umapCellTt.end()) { - if (pwszTooltip || pwszCaption) + if (!wstrTooltip.empty() || !wstrCaption.empty()) { //Initializing inner map. - std::unordered_map umapInner { - { iSubItem, { CELLTOOLTIP { pTooltip, pCaption } } } }; + std::unordered_map umapInner { + { iSubItem, { std::wstring { wstrTooltip }, std::wstring { wstrCaption } } } + }; m_umapCellTt.insert({ ID, std::move(umapInner) }); } } @@ -439,27 +505,27 @@ void CListEx::SetCellTooltip(int iItem, int iSubItem, const wchar_t* pwszTooltip //inserting new Subitem into inner map. if (itInner == it->second.end()) { - if (pwszTooltip || pwszCaption) - it->second.insert({ iSubItem, { pTooltip, pCaption } }); + if (!wstrTooltip.empty() || !wstrCaption.empty()) + it->second.insert({ iSubItem, { std::wstring { wstrTooltip }, std::wstring { wstrCaption } } }); } else { //If there is already exist this Item-Subitem's tooltip: //change or erase it, depending on pwszTooltip emptiness. - if (pwszTooltip) - itInner->second = { pwszTooltip, pCaption }; + if (!wstrTooltip.empty()) + itInner->second = { std::wstring { wstrTooltip }, std::wstring { wstrCaption } }; else it->second.erase(itInner); } } } -void CListEx::SetColor(const LISTEXCOLORSTRUCT& lcs) +void CListEx::SetColors(const LISTEXCOLORS& lcs) { assert(IsCreated()); if (!IsCreated()) return; - m_stColor = lcs; + m_stColors = lcs; GetHeaderCtrl().SetColor(lcs); RedrawWindow(); } @@ -467,12 +533,12 @@ void CListEx::SetColor(const LISTEXCOLORSTRUCT& lcs) void CListEx::SetColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText) { if (clrText == -1) //-1 for default color. - clrText = m_stColor.clrListText; + clrText = m_stColors.clrListText; - m_umapColumnColor[iColumn] = COLUMNCOLOR { clrBk, clrText, std::chrono::high_resolution_clock::now() }; + m_umapColumnColor[iColumn] = SCOLUMNCOLOR { clrBk, clrText, std::chrono::high_resolution_clock::now() }; } -void CListEx::SetColumnSortMode(int iColumn, EnListExSortMode enSortMode) +void CListEx::SetColumnSortMode(int iColumn, EListExSortMode enSortMode) { m_umapColumnSortMode[iColumn] = enSortMode; } @@ -495,7 +561,7 @@ void CListEx::SetFont(const LOGFONTW* pLogFontNew) wp.cx = rc.Width(); wp.cy = rc.Height(); wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER; - SendMessageW(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp); + SendMessageW(WM_WINDOWPOSCHANGED, 0, reinterpret_cast(&wp)); Update(0); } @@ -515,6 +581,9 @@ void CListEx::SetFontSize(UINT uiSize) lf.lfHeight = m_lSizeFont = uiSize; m_fontList.DeleteObject(); m_fontList.CreateFontIndirectW(&lf); + lf.lfUnderline = 1; + m_fontListUnderline.DeleteObject(); + m_fontListUnderline.CreateFontIndirectW(&lf); //To get WM_MEASUREITEM msg after changing font. CRect rc; @@ -524,7 +593,7 @@ void CListEx::SetFontSize(UINT uiSize) wp.cx = rc.Width(); wp.cy = rc.Height(); wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER; - SendMessageW(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp); + SendMessageW(WM_WINDOWPOSCHANGED, 0, reinterpret_cast(&wp)); Update(0); } @@ -579,12 +648,12 @@ void CListEx::SetRowColor(DWORD dwRow, COLORREF clrBk, COLORREF clrText) return; if (clrText == -1) //-1 for default color. - clrText = m_stColor.clrListText; + clrText = m_stColors.clrListText; - m_umapRowColor[dwRow] = ROWCOLOR { clrBk, clrText, std::chrono::high_resolution_clock::now() }; + m_umapRowColor[dwRow] = SROWCOLOR { clrBk, clrText, std::chrono::high_resolution_clock::now() }; } -void CListEx::SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare, EnListExSortMode enSortMode) +void CListEx::SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare, EListExSortMode enSortMode) { assert(IsCreated()); if (!IsCreated()) @@ -612,44 +681,64 @@ bool CListEx::HasCellColor(int iItem, int iSubItem, COLORREF& clrBk, COLORREF& c return false; bool fHasColor { false }; - UINT ID = MapIndexToID((UINT)iItem); - auto it = m_umapCellColor.find(ID); - if (it != m_umapCellColor.end()) + //If parent responds for LISTEX_MSG_CELLCOLOR message, we use lParam + //as a pointer to LISTEXCELLCOLOR. Otherwise we doing inner lookup. + auto iCtrlID = GetDlgCtrlID(); + NMITEMACTIVATE nmii { { m_hWnd, static_cast(iCtrlID), LISTEX_MSG_CELLCOLOR } }; + nmii.iItem = iItem; + nmii.iSubItem = iSubItem; + GetParent()->SendMessageW(WM_NOTIFY, static_cast(iCtrlID), reinterpret_cast(&nmii)); + if (nmii.lParam != 0) { - auto itInner = it->second.find(iSubItem); + auto pClr = reinterpret_cast(nmii.lParam); + clrBk = pClr->clrBk; + clrText = pClr->clrText; - //If subitem id found. - if (itInner != it->second.end()) - { - clrBk = itInner->second.clrBk; - clrText = itInner->second.clrText; - fHasColor = true; - } + fHasColor = true; } if (!fHasColor) { - auto itColumn = m_umapColumnColor.find(iSubItem); - auto itRow = m_umapRowColor.find(ID); + UINT ID = MapIndexToID(static_cast(iItem)); + auto it = m_umapCellColor.find(ID); - if (itColumn != m_umapColumnColor.end() && itRow != m_umapRowColor.end()) - { - clrBk = itColumn->second.time > itRow->second.time ? itColumn->second.clrBk : itRow->second.clrBk; - clrText = itColumn->second.time > itRow->second.time ? itColumn->second.clrText : itRow->second.clrText; - fHasColor = true; - } - else if (itColumn != m_umapColumnColor.end()) + if (it != m_umapCellColor.end()) { - clrBk = itColumn->second.clrBk; - clrText = itColumn->second.clrText; - fHasColor = true; + auto itInner = it->second.find(iSubItem); + + //If subitem id found. + if (itInner != it->second.end()) + { + clrBk = itInner->second.clrBk; + clrText = itInner->second.clrText; + fHasColor = true; + } } - else if (itRow != m_umapRowColor.end()) + + if (!fHasColor) { - clrBk = itRow->second.clrBk; - clrText = itRow->second.clrText; - fHasColor = true; + auto itColumn = m_umapColumnColor.find(iSubItem); + auto itRow = m_umapRowColor.find(ID); + + if (itColumn != m_umapColumnColor.end() && itRow != m_umapRowColor.end()) + { + clrBk = itColumn->second.time > itRow->second.time ? itColumn->second.clrBk : itRow->second.clrBk; + clrText = itColumn->second.time > itRow->second.time ? itColumn->second.clrText : itRow->second.clrText; + fHasColor = true; + } + else if (itColumn != m_umapColumnColor.end()) + { + clrBk = itColumn->second.clrBk; + clrText = itColumn->second.clrText; + fHasColor = true; + } + else if (itRow != m_umapRowColor.end()) + { + clrBk = itRow->second.clrBk; + clrText = itRow->second.clrText; + fHasColor = true; + } } } @@ -728,6 +817,144 @@ bool CListEx::HasMenu(int iItem, int iSubItem, CMenu** ppMenu) return fHasMenu; } +std::vector CListEx::ParseItemText(int iItem, int iSubitem) +{ + std::vector vecData { }; + auto CStringText = GetItemText(iItem, iSubitem); + std::wstring_view wstrText = CStringText.GetString(); + CRect rcTextOrig; //Original rect of the subitem's text. + GetSubItemRect(iItem, iSubitem, LVIR_LABEL, rcTextOrig); + if (iSubitem != 0) //Not needed for item itself (not subitem). + rcTextOrig.left += 4; + + size_t nPosCurr { 0 }; //Current position in the parsed string. + size_t nPosTagLink { }; //Start position of the opening tag "". + size_t nPosTagLast { }; //Start position of the enclosing tag "". + CRect rcTextCurr { }; //Current rect. + + const std::wstring_view wstrTagLink { L"" }; + const std::wstring_view wstrTagLast { L"" }; + const std::wstring_view wstrTagTitle { L"title=" }; + const std::wstring_view wstrQuote { L"\"" }; + + while (nPosCurr != std::wstring_view::npos) + { + //Searching the string for a pattern. + if ((nPosTagLink = wstrText.find(wstrTagLink, nPosCurr)) != std::wstring_view::npos + && (nPosLinkOpenQuote = wstrText.find(wstrQuote, nPosTagLink)) != std::wstring_view::npos + && (nPosLinkCloseQuote = wstrText.find(wstrQuote, nPosLinkOpenQuote + wstrQuote.size())) != std::wstring_view::npos + && (nPosTagFirstClose = wstrText.find(wstrTagFirstClose, nPosLinkCloseQuote + wstrQuote.size())) != std::wstring_view::npos + && (nPosTagLast = wstrText.find(wstrTagLast, nPosTagFirstClose + wstrTagFirstClose.size())) != std::wstring_view::npos) + { + auto pDC = GetDC(); + pDC->SelectObject(m_fontList); + SIZE size; + + //Any text before found tag. + if (nPosTagLink > nPosCurr) + { + auto wstrTextBefore = wstrText.substr(nPosCurr, nPosTagLink - nPosCurr); + GetTextExtentPoint32W(pDC->m_hDC, wstrTextBefore.data(), static_cast(wstrTextBefore.size()), &size); + if (rcTextCurr.IsRectNull()) + rcTextCurr.SetRect(rcTextOrig.left, rcTextOrig.top, rcTextOrig.left + size.cx, rcTextOrig.bottom); + else + { + rcTextCurr.left = rcTextCurr.right; + rcTextCurr.right += size.cx; + } + vecData.emplace_back(wstrTextBefore, L"", L"", rcTextCurr); + } + + //The clickable/linked text, that between textFromHere tags. + auto wstrTextBetweenTags = wstrText.substr(nPosTagFirstClose + wstrTagFirstClose.size(), + nPosTagLast - (nPosTagFirstClose + wstrTagFirstClose.size())); + GetTextExtentPoint32W(pDC->m_hDC, wstrTextBetweenTags.data(), static_cast(wstrTextBetweenTags.size()), &size); + ReleaseDC(pDC); + + if (rcTextCurr.IsRectNull()) + rcTextCurr.SetRect(rcTextOrig.left, rcTextOrig.top, rcTextOrig.left + size.cx, rcTextOrig.bottom); + else + { + rcTextCurr.left = rcTextCurr.right; + rcTextCurr.right += size.cx; + } + + //Link tag text (linkID) between quotes: + auto wstrTextLink = wstrText.substr(nPosLinkOpenQuote + wstrQuote.size(), + nPosLinkCloseQuote - nPosLinkOpenQuote - wstrQuote.size()); + nPosCurr = nPosLinkCloseQuote + wstrQuote.size(); + + //Searching for title "" tag. + bool fTitle { false }; + std::wstring_view wstrTextTitle { }; + if ((nPosTagTitle = wstrText.find(wstrTagTitle, nPosCurr)) != std::wstring_view::npos + && (nPosTitleOpenQuote = wstrText.find(wstrQuote, nPosTagTitle)) != std::wstring_view::npos + && (nPosTitleCloseQuote = wstrText.find(wstrQuote, nPosTitleOpenQuote + wstrQuote.size())) != std::wstring_view::npos) + { + //Title tag text between quotes: <...title="textFromHere"> + wstrTextTitle = wstrText.substr(nPosTitleOpenQuote + wstrQuote.size(), + nPosTitleCloseQuote - nPosTitleOpenQuote - wstrQuote.size()); + + fTitle = true; + } + + vecData.emplace_back(wstrTextBetweenTags, wstrTextLink, wstrTextTitle, rcTextCurr, true, fTitle); + nPosCurr = nPosTagLast + wstrTagLast.size(); + } + else + { + auto wstrTextAfter = wstrText.substr(nPosCurr, wstrText.size() - nPosCurr); + + if (rcTextCurr.IsRectNull()) + rcTextCurr = rcTextOrig; + else + { + auto pDC = GetDC(); + SIZE size; + pDC->SelectObject(m_fontList); + GetTextExtentPoint32W(pDC->m_hDC, wstrTextAfter.data(), static_cast(wstrTextAfter.size()), &size); + ReleaseDC(pDC); + + rcTextCurr.left = rcTextCurr.right; + rcTextCurr.right += size.cx; + } + + vecData.emplace_back(wstrTextAfter, L"", L"", rcTextCurr); + nPosCurr = std::wstring_view::npos; + } + } + + return vecData; +} + +void CListEx::TtLinkHide() +{ + m_fTtLinkShown = false; + m_stWndTtLink.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)(LPTOOLINFO)&m_stTInfoLink); + KillTimer(ID_TIMER_TT_LINK_CHECK); + + m_stCurrLink.iItem = -1; + m_stCurrLink.iSubItem = -1; + m_rcLinkCurr.SetRectEmpty(); +} + +void CListEx::TtCellHide() +{ + m_fTtCellShown = false; + m_stCurrCell.iItem = -1; + m_stCurrCell.iSubItem = -1; + + m_stWndTtCell.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)(LPTOOLINFO)&m_stTInfoCell); + KillTimer(ID_TIMER_TT_CELL_CHECK); +} + void CListEx::MeasureItem(LPMEASUREITEMSTRUCT lpMIS) { //Set row height according to current font's height. @@ -744,63 +971,82 @@ void CListEx::DrawItem(LPDRAWITEMSTRUCT pDIS) if (pDIS->itemID == -1) return; - CDC* pDC = CDC::FromHandle(pDIS->hDC); - pDC->SelectObject(&m_penGrid); - pDC->SelectObject(&m_fontList); - COLORREF clrBkCurrRow = (pDIS->itemID % 2) ? m_stColor.clrListBkRow2 : m_stColor.clrListBkRow1; + auto pDC = CDC::FromHandle(pDIS->hDC); + pDC->SelectObject(m_penGrid); + pDC->SelectObject(m_fontList); + const COLORREF clrBkCurrRow = (pDIS->itemID % 2) ? m_stColors.clrListBkRow2 : m_stColors.clrListBkRow1; switch (pDIS->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: { - for (int i = 0; i < GetHeaderCtrl().GetItemCount(); i++) + const auto iColumns = GetHeaderCtrl().GetItemCount(); + for (auto i = 0; i < iColumns; ++i) { - COLORREF clrText, clrBk; + COLORREF clrText, clrBk, clrTextLink; //Subitems' draw routine. Colors depending on whether subitem selected or not, //and has tooltip or not. if (pDIS->itemState & ODS_SELECTED) { - clrText = m_stColor.clrListTextSelected; - clrBk = m_stColor.clrListBkSelected; + clrText = m_stColors.clrListTextSel; + clrBk = m_stColors.clrListBkSel; + clrTextLink = m_stColors.clrListTextLinkSel; } else { + clrTextLink = m_stColors.clrListTextLink; + if (!HasCellColor(pDIS->itemID, i, clrBk, clrText)) { if (HasTooltip(pDIS->itemID, i)) { - clrText = m_stColor.clrListTextCellTt; - clrBk = m_stColor.clrListBkCellTt; + clrText = m_stColors.clrListTextCellTt; + clrBk = m_stColors.clrListBkCellTt; } else { - clrText = m_stColor.clrListText; + clrText = m_stColors.clrListText; clrBk = clrBkCurrRow; } } } CRect rcBounds; GetSubItemRect(pDIS->itemID, i, LVIR_BOUNDS, rcBounds); - pDC->FillSolidRect(&rcBounds, clrBk); + pDC->FillSolidRect(rcBounds, clrBk); CRect rcText; GetSubItemRect(pDIS->itemID, i, LVIR_LABEL, rcText); if (i != 0) //Not needed for item itself (not subitem). rcText.left += 4; - CStringW wstrSubitem = GetItemText(pDIS->itemID, i); - pDC->SetTextColor(clrText); - ExtTextOutW(pDC->m_hDC, rcText.left, rcText.top, ETO_CLIPPED, rcText, wstrSubitem, wstrSubitem.GetLength(), nullptr); - //Drawing Subitem's rect lines. - pDC->MoveTo(rcBounds.left, rcBounds.top); + for (const auto& iter : ParseItemText(pDIS->itemID, i)) + { + if (iter.fLink) + { + pDC->SetTextColor(clrTextLink); + if (m_fLinksUnderline) + pDC->SelectObject(m_fontListUnderline); + } + else + { + pDC->SetTextColor(clrText); + pDC->SelectObject(m_fontList); + } + + ExtTextOutW(pDC->m_hDC, iter.rect.left, iter.rect.top, ETO_CLIPPED, + rcText, iter.wstrText.data(), static_cast(iter.wstrText.size()), nullptr); + } + + //Drawing subitem's rect lines. + pDC->MoveTo(rcBounds.TopLeft()); pDC->LineTo(rcBounds.right, rcBounds.top); - pDC->MoveTo(rcBounds.left, rcBounds.top); + pDC->MoveTo(rcBounds.TopLeft()); pDC->LineTo(rcBounds.left, rcBounds.bottom); pDC->MoveTo(rcBounds.left, rcBounds.bottom); - pDC->LineTo(rcBounds.right, rcBounds.bottom); + pDC->LineTo(rcBounds.BottomRight()); pDC->MoveTo(rcBounds.right, rcBounds.top); - pDC->LineTo(rcBounds.right, rcBounds.bottom); + pDC->LineTo(rcBounds.BottomRight()); } } break; @@ -809,57 +1055,94 @@ void CListEx::DrawItem(LPDRAWITEMSTRUCT pDIS) } } +BOOL CListEx::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + if (nFlags == MK_CONTROL) + { + SetFontSize(GetFontSize() + zDelta / WHEEL_DELTA * 2); + return TRUE; + } + GetHeaderCtrl().RedrawWindow(); + + return CMFCListCtrl::OnMouseWheel(nFlags, zDelta, pt); +} + void CListEx::OnMouseMove(UINT /*nFlags*/, CPoint pt) { - LVHITTESTINFO hi; + LVHITTESTINFO hi { }; hi.pt = pt; ListView_SubItemHitTest(m_hWnd, &hi); - std::wstring *pwstrTt { }, *pwstrCaption { }; - if (HasTooltip(hi.iItem, hi.iSubItem, &pwstrTt, &pwstrCaption)) + bool fLink { false }; //Cursor at link's rect area. + for (const auto& iter : ParseItemText(hi.iItem, hi.iSubItem)) { - //Check if cursor is still in the same cell's rect. If so - just leave. - if (m_stCurrCell.iItem == hi.iItem && m_stCurrCell.iSubItem == hi.iSubItem) - return; + if (iter.fLink && iter.rect.PtInRect(pt)) + { + fLink = true; - m_fTtShown = true; - m_stCurrCell.iItem = hi.iItem; - m_stCurrCell.iSubItem = hi.iSubItem; - m_stToolInfo.lpszText = const_cast(pwstrTt->data()); + if (m_fLinkTooltip && !m_fLDownAtLink && m_rcLinkCurr != iter.rect) + { + TtLinkHide(); + m_rcLinkCurr = iter.rect; + m_stCurrLink.iItem = hi.iItem; + m_stCurrLink.iSubItem = hi.iSubItem; + m_wstrTtText = iter.fTitle ? iter.wstrTitle : iter.wstrLink; + m_stTInfoLink.lpszText = m_wstrTtText.data(); + + SetTimer(ID_TIMER_TT_LINK_ACTIVATE, 400, nullptr); //Activate (show) tooltip after delay. + } + break; + } + } + SetCursor(fLink ? m_cursorHand : m_cursorDefault); - ClientToScreen(&pt); - m_wndTt.SendMessageW(TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x, pt.y)); - m_wndTt.SendMessageW(TTM_SETTITLE, (WPARAM)TTI_NONE, (LPARAM)pwstrCaption->data()); - m_wndTt.SendMessageW(TTM_UPDATETIPTEXT, 0, (LPARAM)(LPTOOLINFO)&m_stToolInfo); - m_wndTt.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)(LPTOOLINFO)&m_stToolInfo); + //Link's tooltip area is under cursor. + if (fLink) + { + //If there is cell's tooltip atm hide it. + if (m_fTtCellShown) + TtCellHide(); - //Timer to check whether mouse left subitem rect. - SetTimer(ID_TIMER_TOOLTIP, 200, 0); + return; //Do not process further, cursor is on the link's rect. } - else - { - m_stCurrCell.iItem = hi.iItem; - m_stCurrCell.iSubItem = hi.iSubItem; - //If there is shown tooltip window. - if (m_fTtShown) + m_fLDownAtLink = false; + + //If there was link's tool-tip shown, hide it. + if (m_fTtLinkShown) + TtLinkHide(); + + std::wstring *pwstrTt { }, *pwstrCaption { }; + if (HasTooltip(hi.iItem, hi.iSubItem, &pwstrTt, &pwstrCaption)) + { + //Check if cursor is still in the same cell's rect. If so - just leave. + if (m_stCurrCell.iItem != hi.iItem || m_stCurrCell.iSubItem != hi.iSubItem) { - m_fTtShown = false; - m_wndTt.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)(LPTOOLINFO)&m_stToolInfo); + m_fTtCellShown = true; + m_stCurrCell.iItem = hi.iItem; + m_stCurrCell.iSubItem = hi.iSubItem; + m_stTInfoCell.lpszText = pwstrTt->data(); + + ClientToScreen(&pt); + m_stWndTtCell.SendMessageW(TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x, pt.y)); + m_stWndTtCell.SendMessageW(TTM_SETTITLE, static_cast(TTI_NONE), reinterpret_cast(pwstrCaption->data())); + m_stWndTtCell.SendMessageW(TTM_UPDATETIPTEXT, 0, reinterpret_cast(&m_stTInfoCell)); + m_stWndTtCell.SendMessageW(TTM_TRACKACTIVATE, static_cast(TRUE), reinterpret_cast(&m_stTInfoCell)); + + //Timer to check whether mouse left subitem's rect. + SetTimer(ID_TIMER_TT_CELL_CHECK, 200, nullptr); } } -} - -BOOL CListEx::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) -{ - if (nFlags == MK_CONTROL) + else { - SetFontSize(GetFontSize() + zDelta / WHEEL_DELTA * 2); - return TRUE; + if (m_fTtCellShown) + TtCellHide(); + else + { + m_stCurrCell.iItem = -1; + m_stCurrCell.iSubItem = -1; + } } - GetHeaderCtrl().RedrawWindow(); - - return CMFCListCtrl::OnMouseWheel(nFlags, zDelta, pt); } void CListEx::OnLButtonDown(UINT nFlags, CPoint pt) @@ -870,7 +1153,59 @@ void CListEx::OnLButtonDown(UINT nFlags, CPoint pt) if (hi.iSubItem == -1 || hi.iItem == -1) return; - CMFCListCtrl::OnLButtonDown(nFlags, pt); + bool fLinkDown { false }; + for (const auto& iter : ParseItemText(hi.iItem, hi.iSubItem)) + { + if (iter.fLink && iter.rect.PtInRect(pt)) + { + m_fLDownAtLink = true; + m_rcLinkCurr = iter.rect; + fLinkDown = true; + break; + } + } + + if (!fLinkDown) + CMFCListCtrl::OnLButtonDown(nFlags, pt); +} + +void CListEx::OnLButtonUp(UINT nFlags, CPoint pt) +{ + bool fLinkUp { false }; + if (m_fLDownAtLink) + { + LVHITTESTINFO hi { }; + hi.pt = pt; + ListView_SubItemHitTest(m_hWnd, &hi); + if (hi.iSubItem == -1 || hi.iItem == -1) + { + m_fLDownAtLink = false; + return; + } + + for (const auto& iter : ParseItemText(hi.iItem, hi.iSubItem)) + { + if (iter.fLink && iter.rect == m_rcLinkCurr) + { + m_rcLinkCurr.SetRectEmpty(); + fLinkUp = true; + + UINT uCtrlId = static_cast(GetDlgCtrlID()); + NMITEMACTIVATE nmii { { m_hWnd, uCtrlId, LISTEX_MSG_LINKCLICK } }; + nmii.iItem = hi.iItem; + nmii.iSubItem = hi.iSubItem; + nmii.ptAction = pt; + nmii.lParam = reinterpret_cast(iter.wstrLink.data()); + GetParent()->SendMessageW(WM_NOTIFY, static_cast(uCtrlId), reinterpret_cast(&nmii)); + + break; + } + } + } + + m_fLDownAtLink = false; + if (!fLinkUp) + CMFCListCtrl::OnLButtonUp(nFlags, pt); } void CListEx::OnRButtonDown(UINT nFlags, CPoint pt) @@ -901,7 +1236,7 @@ BOOL CListEx::OnCommand(WPARAM wParam, LPARAM lParam) { m_stNMII.hdr.code = LISTEX_MSG_MENUSELECTED; m_stNMII.lParam = LOWORD(wParam); //LOWORD(wParam) holds uiMenuItemId. - GetParent()->SendMessageW(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&m_stNMII); + GetParent()->SendMessageW(WM_NOTIFY, GetDlgCtrlID(), reinterpret_cast(&m_stNMII)); } return CMFCListCtrl::OnCommand(wParam, lParam); @@ -909,31 +1244,47 @@ BOOL CListEx::OnCommand(WPARAM wParam, LPARAM lParam) void CListEx::OnTimer(UINT_PTR nIDEvent) { + CPoint ptScreen; + GetCursorPos(&ptScreen); + CPoint ptClient = ptScreen; + ScreenToClient(&ptClient); + LVHITTESTINFO hitInfo { }; + hitInfo.pt = ptClient; + ListView_SubItemHitTest(m_hWnd, &hitInfo); + //Checking if mouse left list's subitem rect, //if so — hiding tooltip and killing timer. - if (nIDEvent == ID_TIMER_TOOLTIP) + switch (nIDEvent) { - CPoint pt; - GetCursorPos(&pt); - ScreenToClient(&pt); - LVHITTESTINFO hitInfo; - hitInfo.pt = pt; - ListView_SubItemHitTest(m_hWnd, &hitInfo); - + case ID_TIMER_TT_CELL_CHECK: //If cursor is still hovers subitem then do nothing. - if (m_stCurrCell.iItem == hitInfo.iItem && m_stCurrCell.iSubItem == hitInfo.iSubItem) - return; - else - { //If it left. - m_fTtShown = false; - m_wndTt.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)(LPTOOLINFO)&m_stToolInfo); - KillTimer(ID_TIMER_TOOLTIP); - m_stCurrCell.iItem = hitInfo.iItem; - m_stCurrCell.iSubItem = hitInfo.iSubItem; + if (m_stCurrCell.iItem != hitInfo.iItem || m_stCurrCell.iSubItem != hitInfo.iSubItem) + TtCellHide(); + break; + case ID_TIMER_TT_LINK_CHECK: + //If cursor has left link subitem's rect. + if (m_stCurrLink.iItem != hitInfo.iItem || m_stCurrLink.iSubItem != hitInfo.iSubItem) + TtLinkHide(); + break; + case ID_TIMER_TT_LINK_ACTIVATE: + if (m_rcLinkCurr.PtInRect(ptClient)) + { + m_fTtLinkShown = true; + + m_stWndTtLink.SendMessageW(TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)(LPTOOLINFO)&m_stTInfoLink); + m_stWndTtLink.SendMessageW(TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(ptScreen.x + 3, ptScreen.y - 20)); + m_stWndTtLink.SendMessageW(TTM_UPDATETIPTEXT, 0, reinterpret_cast(&m_stTInfoLink)); + m_stWndTtLink.SendMessageW(TTM_TRACKACTIVATE, static_cast(TRUE), reinterpret_cast(&m_stTInfoLink)); + + //Timer to check whether mouse left link subitems's rect. + SetTimer(ID_TIMER_TT_LINK_CHECK, 200, nullptr); } - } + else + m_rcLinkCurr.SetRectEmpty(); - CMFCListCtrl::OnTimer(nIDEvent); + KillTimer(ID_TIMER_TT_LINK_ACTIVATE); + break; + } } BOOL CListEx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) @@ -953,19 +1304,19 @@ BOOL CListEx::OnEraseBkgnd(CDC* /*pDC*/) void CListEx::OnPaint() { //To avoid flickering. - //Drawing to CMemDC, excluding list header area (rect). - CRect rc, rcHdr; - GetClientRect(&rc); + //Drawing to CMemDC, excluding list header area (rcHdr). + CRect rcClient, rcHdr; + GetClientRect(&rcClient); GetHeaderCtrl().GetClientRect(rcHdr); - rc.top += rcHdr.Height(); + rcClient.top += rcHdr.Height(); CPaintDC dc(this); - CMemDC memDC(dc, rc); + CMemDC memDC(dc, rcClient); CDC& rDC = memDC.GetDC(); - rDC.GetClipBox(&rc); - rDC.FillSolidRect(rc, m_stColor.clrBkNWA); + rDC.GetClipBox(&rcClient); + rDC.FillSolidRect(rcClient, m_stColors.clrNWABk); - DefWindowProcW(WM_PAINT, (WPARAM)rDC.m_hDC, (LPARAM)0); + DefWindowProcW(WM_PAINT, reinterpret_cast(rDC.m_hDC), static_cast(0)); } void CListEx::OnHdnDividerdblclick(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/) @@ -998,28 +1349,46 @@ void CListEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) CMFCListCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } -void CListEx::OnLvnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) +BOOL CListEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { - if (m_fSortable) + if (!m_fCreated) + return FALSE; + + //HDN_ITEMCLICK messages should be handled here first, to set m_fSortAscending + //and m_iSortColumn. And only then this message goes further, to parent window, + //in form of HDN_ITEMCLICK and LVN_COLUMNCLICK. + //If we execute this code in LVN_COLUMNCLICK handler, it will be handled + //only AFTER the parent window handles LVN_COLUMNCLICK. + //So briefly, ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CListEx::OnLvnColumnClick) fires up + //only AFTER LVN_COLUMNCLICK sent to the parent. + auto pNMLV = reinterpret_cast(lParam); + if (m_fSortable && (pNMLV->hdr.code == HDN_ITEMCLICKW || pNMLV->hdr.code == HDN_ITEMCLICKA)) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); - m_fSortAscending = pNMLV->iSubItem == m_iSortColumn ? !m_fSortAscending : true; - m_iSortColumn = pNMLV->iSubItem; + m_fSortAscending = pNMLV->iItem == m_iSortColumn ? !m_fSortAscending : true; + m_iSortColumn = pNMLV->iItem; GetHeaderCtrl().SetSortArrow(m_iSortColumn, m_fSortAscending); if (!m_fVirtual) SortItemsEx(m_pfnCompare ? m_pfnCompare : DefCompareFunc, reinterpret_cast(this)); } - *pResult = 0; + return CMFCListCtrl::OnNotify(wParam, lParam, pResult); +} + +void CListEx::OnLvnColumnClick(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/) +{ + //Just an empty handler. Without it all works fine, but assert + //triggers in Debug mode when clicking on header. } void CListEx::OnDestroy() { CMFCListCtrl::OnDestroy(); - m_wndTt.DestroyWindow(); + m_stWndTtCell.DestroyWindow(); + m_stWndTtLink.DestroyWindow(); m_fontList.DeleteObject(); + m_fontListUnderline.DeleteObject(); m_penGrid.DeleteObject(); m_umapCellTt.clear(); @@ -1031,4 +1400,4 @@ void CListEx::OnDestroy() m_umapColumnColor.clear(); m_fCreated = false; -} +} \ No newline at end of file diff --git a/Pepper/ListEx/src/CListEx.h b/Pepper/ListEx/src/CListEx.h index fc60c5d..4448904 100644 --- a/Pepper/ListEx/src/CListEx.h +++ b/Pepper/ListEx/src/CListEx.h @@ -8,58 +8,21 @@ #pragma once #include "../ListEx.h" #include "CListExHdr.h" -#include #include +#include namespace LISTEX::INTERNAL { - /******************************************** - * CELLTOOLTIP - tool-tips for the cell. * - ********************************************/ - struct CELLTOOLTIP - { - std::wstring wstrText; - std::wstring wstrCaption; - }; - - /******************************************** - * COLUMNCOLOR - colors for the column. * - ********************************************/ - struct COLUMNCOLOR - { - COLORREF clrBk { }; //Background. - COLORREF clrText { }; //Text. - std::chrono::high_resolution_clock::time_point time { }; //Time when added. - }; - - /******************************************** - * ROWCOLOR - colors for the row. * - ********************************************/ - struct ROWCOLOR - { - COLORREF clrBk { }; //Background. - COLORREF clrText { }; //Text. - std::chrono::high_resolution_clock::time_point time { }; //Time when added. - }; - - /******************************************** - * CELLCOLOR - colors for the cell. * - ********************************************/ - struct CELLCOLOR - { - COLORREF clrBk; - COLORREF clrText; - }; - - /******************************************** * CListEx class declaration. * ********************************************/ class CListEx final : public IListEx { + struct SCELLTOOLTIP; + struct SCOLUMNCOLOR; + struct SROWCOLOR; + struct SITEMTEXT; public: - explicit CListEx() = default; - ~CListEx() = default; bool Create(const LISTEXCREATESTRUCT& lcs)override; void CreateDialogCtrl(UINT uCtrlID, CWnd* pwndDlg)override; static int CALLBACK DefCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); @@ -67,20 +30,21 @@ namespace LISTEX::INTERNAL BOOL DeleteColumn(int nCol)override; BOOL DeleteItem(int iItem)override; void Destroy()override; - ULONGLONG GetCellData(int iItem, int iSubItem)const override; - EnListExSortMode GetColumnSortMode(int iColumn)const override; - UINT GetFontSize()const override; - int GetSortColumn()const override; - bool GetSortAscending()const override; - bool IsCreated()const override; - UINT MapIndexToID(UINT nItem)const; + [[nodiscard]] ULONGLONG GetCellData(int iItem, int iSubItem)const override; + [[nodiscard]] LISTEXCOLORS GetColors()const override; + [[nodiscard]] EListExSortMode GetColumnSortMode(int iColumn)const override; + [[nodiscard]] UINT GetFontSize()const override; + [[nodiscard]] int GetSortColumn()const override; + [[nodiscard]] bool GetSortAscending()const override; + [[nodiscard]] bool IsCreated()const override; + [[nodiscard]] UINT MapIndexToID(UINT nItem)const; void SetCellColor(int iItem, int iSubItem, COLORREF clrBk, COLORREF clrText)override; void SetCellData(int iItem, int iSubItem, ULONGLONG ullData)override; void SetCellMenu(int iItem, int iSubItem, CMenu* pMenu)override; - void SetCellTooltip(int iItem, int iSubItem, const wchar_t* pwszTooltip, const wchar_t* pwszCaption = nullptr)override; - void SetColor(const LISTEXCOLORSTRUCT& lcs)override; + void SetCellTooltip(int iItem, int iSubItem, std::wstring_view wstrTooltip, std::wstring_view wstrCaption)override; + void SetColors(const LISTEXCOLORS& lcs)override; void SetColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText)override; - void SetColumnSortMode(int iColumn, EnListExSortMode enSortMode)override; + void SetColumnSortMode(int iColumn, EListExSortMode enSortMode)override; void SetFont(const LOGFONTW* pLogFontNew)override; void SetFontSize(UINT uiSize)override; void SetHdrHeight(DWORD dwHeight)override; @@ -88,24 +52,28 @@ namespace LISTEX::INTERNAL void SetHdrColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText)override; void SetListMenu(CMenu* pMenu)override; void SetRowColor(DWORD dwRow, COLORREF clrBk, COLORREF clrText)override; - void SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare, EnListExSortMode enSortMode)override; + void SetSortable(bool fSortable, PFNLVCOMPARE pfnCompare, EListExSortMode enSortMode)override; DECLARE_DYNAMIC(CListEx) DECLARE_MESSAGE_MAP() protected: - CListExHdr& GetHeaderCtrl() { return m_stListHeader; } - void InitHeader(); + CListExHdr& GetHeaderCtrl()override { return m_stListHeader; } + void InitHeader()override; bool HasCellColor(int iItem, int iSubItem, COLORREF& clrBk, COLORREF& clrText); bool HasTooltip(int iItem, int iSubItem, std::wstring** ppwstrText = nullptr, std::wstring** ppwstrCaption = nullptr); bool HasMenu(int iItem, int iSubItem, CMenu** ppMenu = nullptr); - void DrawItem(LPDRAWITEMSTRUCT); + std::vector ParseItemText(int iItem, int iSubitem); + void TtLinkHide(); + void TtCellHide(); + void DrawItem(LPDRAWITEMSTRUCT pDIS)override; afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnLButtonDown(UINT nFlags, CPoint pt); + afx_msg void OnLButtonUp(UINT nFlags, CPoint pt); afx_msg void OnRButtonDown(UINT nFlags, CPoint pt); afx_msg void OnContextMenu(CWnd* pWnd, CPoint pt); - virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); + BOOL OnCommand(WPARAM wParam, LPARAM lParam)override; afx_msg void OnMouseMove(UINT nFlags, CPoint pt); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnTimer(UINT_PTR nIDEvent); @@ -115,38 +83,51 @@ namespace LISTEX::INTERNAL afx_msg void OnHdnDividerdblclick(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnHdnTrack(NMHDR *pNMHDR, LRESULT *pResult); + BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)override; + afx_msg void OnLvnColumnClick(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnDestroy(); - afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult); private: CListExHdr m_stListHeader; - LISTEXCOLORSTRUCT m_stColor { }; - CFont m_fontList; - CPen m_penGrid; - CWnd m_wndTt; //Tool-tip window. - TTTOOLINFOW m_stToolInfo { }; //Tool-tip info struct. - LVHITTESTINFO m_stCurrCell { }; + LISTEXCOLORS m_stColors { }; + CFont m_fontList; //Default list font. + CFont m_fontListUnderline; //Underlined list font, for links. + CPen m_penGrid; //Pen for list lines between cells. + CWnd m_stWndTtCell; //Cells' tool-tip window. + TTTOOLINFOW m_stTInfoCell { }; //Cells' tool-tip info struct. + CWnd m_stWndTtLink; //Link tool-tip window. + TTTOOLINFOW m_stTInfoLink { }; //Link's tool-tip info struct. + std::wstring m_wstrTtText { }; //Link's tool-tip current text. + HCURSOR m_cursorHand { }; //Hand cursor handle. + HCURSOR m_cursorDefault { }; //Standard (default) cursor handle. + LVHITTESTINFO m_stCurrCell { }; //Cell's hit struct for tool-tip. + LVHITTESTINFO m_stCurrLink { }; //Cell's link hit struct for tool-tip. DWORD m_dwGridWidth { 1 }; //Grid width. CMenu* m_pListMenu { }; //List global menu, if set. - std::unordered_map> m_umapCellTt { }; //Cell's tooltips. - std::unordered_map> m_umapCellMenu { }; //Cell's menus. - std::unordered_map> m_umapCellData { }; //Cell's custom data. - std::unordered_map> m_umapCellColor { }; //Cell's colors. - std::unordered_map m_umapRowColor { }; //Row colors. - std::unordered_map m_umapColumnColor { }; //Column colors. - std::unordered_map m_umapColumnSortMode { }; //Column sorting mode. - NMITEMACTIVATE m_stNMII { }; - int m_iSortColumn { }; - long m_lSizeFont { }; //Font size. + NMITEMACTIVATE m_stNMII { }; //Struct for SendMessage. + int m_iSortColumn { }; //Currently clicked header column. + long m_lSizeFont { }; //Font size. PFNLVCOMPARE m_pfnCompare { nullptr }; //Pointer to user provided compare func. - EnListExSortMode m_enDefSortMode { EnListExSortMode::SORT_LEX }; //Default sorting mode. - bool m_fCreated { false }; //Is created. - bool m_fSortable { false }; //Is list sortable. - bool m_fSortAscending { }; //Sorting type (ascending, descending). - bool m_fVirtual { false }; //Whether list is virtual (LVS_OWNERDATA) or not. - bool m_fTtShown { false }; //Is tool-tip shown atm. + EListExSortMode m_enDefSortMode { EListExSortMode::SORT_LEX }; //Default sorting mode. + std::unordered_map> m_umapCellTt { }; //Cell's tooltips. + std::unordered_map> m_umapCellMenu { }; //Cell's menus. + std::unordered_map> m_umapCellData { }; //Cell's custom data. + std::unordered_map> m_umapCellColor { }; //Cell's colors. + std::unordered_map m_umapRowColor { }; //Row colors. + std::unordered_map m_umapColumnColor { }; //Column colors. + std::unordered_map m_umapColumnSortMode { }; //Column sorting mode. + bool m_fCreated { false }; //Is created. + bool m_fSortable { false }; //Is list sortable. + bool m_fSortAscending { }; //Sorting type (ascending, descending). + bool m_fLinksUnderline { }; //Links are displayed underlined or not. + bool m_fLinkTooltip { }; //Show links toolips. + bool m_fVirtual { false }; //Whether list is virtual (LVS_OWNERDATA) or not. + bool m_fTtCellShown { false }; //Is cell's tool-tip shown atm. + bool m_fTtLinkShown { false }; //Is link's tool-tip shown atm. + bool m_fLDownAtLink { false }; //Left mouse down on link. + CRect m_rcLinkCurr { }; //Current link's rect; }; - /*******************Setting a manifest for ComCtl32.dll version 6.***********************/ + /*******************Setting a manifest for ComCtl32.dll version 6.***********************/ #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") diff --git a/Pepper/ListEx/src/CListExHdr.cpp b/Pepper/ListEx/src/CListExHdr.cpp index fcbc994..d92aa1e 100644 --- a/Pepper/ListEx/src/CListExHdr.cpp +++ b/Pepper/ListEx/src/CListExHdr.cpp @@ -1,5 +1,5 @@ /**************************************************************************************** -* Copyright © 2018-2020 Jovibor https://github.com/jovibor/ * +* Copyright © 2018-2020 Jovibor https://github.com/jovibor/ * * This is very extended and featured version of CMFCListCtrl class. * * Official git repository: https://github.com/jovibor/ListEx/ * * This class is available under the "MIT License". * @@ -74,12 +74,13 @@ void CListExHdr::OnDrawItem(CDC* pDC, int iItem, CRect rect, BOOL bIsPressed, BO rDC.SetTextColor(clrText); rDC.SelectObject(m_fontHdr); + //Set item's text buffer first char to zero, //then getting item's text and Draw it. m_wstrHeaderText[0] = L'\0'; GetItem(iItem, &m_hdItem); if (StrStrW(m_wstrHeaderText, L"\n")) - { //If it's multiline text, first — calculate rect for the text, + { //If it's multiline text, first — calculate rect for the text, //with DT_CALCRECT flag (not drawing anything), //and then calculate rect for final vertical text alignment. CRect rcText; @@ -120,16 +121,20 @@ void CListExHdr::OnDrawItem(CDC* pDC, int iItem, CRect rect, BOOL bIsPressed, BO //rDC.DrawEdge(&rect, EDGE_RAISED, BF_RECT); //3D look edges. rDC.SelectObject(m_penGrid); - rDC.MoveTo(rect.left, rect.top); + rDC.MoveTo(rect.TopLeft()); rDC.LineTo(rect.left, rect.bottom); + if (iItem == GetItemCount() - 1) //Last item. + { + rDC.MoveTo(rect.right, rect.top); + rDC.LineTo(rect.BottomRight()); + } } LRESULT CListExHdr::OnLayout(WPARAM /*wParam*/, LPARAM lParam) { CMFCHeaderCtrl::DefWindowProcW(HDM_LAYOUT, 0, lParam); - LPHDLAYOUT pHDL = reinterpret_cast(lParam); - + auto pHDL = reinterpret_cast(lParam); pHDL->pwpos->cy = m_dwHeaderHeight; //New header height. pHDL->prc->top = m_dwHeaderHeight; //Decreasing list's height begining by the new header's height. @@ -141,13 +146,13 @@ void CListExHdr::SetHeight(DWORD dwHeight) m_dwHeaderHeight = dwHeight; } -void CListExHdr::SetColor(const LISTEXCOLORSTRUCT& lcs) +void CListExHdr::SetColor(const LISTEXCOLORS& lcs) { m_clrText = lcs.clrHdrText; m_clrBk = lcs.clrHdrBk; - m_clrBkNWA = lcs.clrBkNWA; - m_clrHglInactive = lcs.clrHdrHglInactive; - m_clrHglActive = lcs.clrHdrHglActive; + m_clrBkNWA = lcs.clrNWABk; + m_clrHglInactive = lcs.clrHdrHglInact; + m_clrHglActive = lcs.clrHdrHglAct; RedrawWindow(); } @@ -157,7 +162,7 @@ void CListExHdr::SetColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText) if (clrText == -1) clrText = m_clrText; - m_umapClrColumn[iColumn] = HDRCOLOR { clrBk, clrText }; + m_umapClrColumn[iColumn] = SHDRCOLOR { clrBk, clrText }; RedrawWindow(); } @@ -171,6 +176,7 @@ void CListExHdr::SetSortArrow(int iColumn, bool fAscending) { m_iSortColumn = iColumn; m_fSortAscending = fAscending; + RedrawWindow(); } void CListExHdr::SetFont(const LOGFONTW* pLogFontNew) @@ -197,9 +203,5 @@ void CListExHdr::OnDestroy() { CMFCHeaderCtrl::OnDestroy(); - m_fontHdr.DeleteObject(); - m_penGrid.DeleteObject(); - m_penLight.DeleteObject(); - m_penShadow.DeleteObject(); m_umapClrColumn.clear(); } \ No newline at end of file diff --git a/Pepper/ListEx/src/CListExHdr.h b/Pepper/ListEx/src/CListExHdr.h index 46166ee..8d56a8d 100644 --- a/Pepper/ListEx/src/CListExHdr.h +++ b/Pepper/ListEx/src/CListExHdr.h @@ -8,35 +8,33 @@ #pragma once #include -namespace LISTEX { struct LISTEXCOLORSTRUCT; } //Forward declaration. +namespace LISTEX { struct LISTEXCOLORS; } //Forward declaration. namespace LISTEX::INTERNAL { - /******************************************** - * HDRCOLOR - header column colors. * - ********************************************/ - struct HDRCOLOR - { - COLORREF clrBk { }; //Background color. - COLORREF clrText { }; //Text color. - }; - /******************************************** * CListExHdr class declaration. * ********************************************/ class CListExHdr final : public CMFCHeaderCtrl { + /******************************************** + * SHDRCOLOR - header column colors. * + ********************************************/ + struct SHDRCOLOR + { + COLORREF clrBk { }; //Background color. + COLORREF clrText { }; //Text color. + }; public: explicit CListExHdr(); - virtual ~CListExHdr() = default; void SetHeight(DWORD dwHeight); void SetFont(const LOGFONTW* pLogFontNew); - void SetColor(const LISTEXCOLORSTRUCT& lcs); + void SetColor(const LISTEXCOLORS& lcs); void SetColumnColor(int iColumn, COLORREF clrBk, COLORREF clrText); void SetSortable(bool fSortable); void SetSortArrow(int iColumn, bool fAscending); protected: - afx_msg void OnDrawItem(CDC* pDC, int iItem, CRect rect, BOOL bIsPressed, BOOL bIsHighlighted) override; + afx_msg void OnDrawItem(CDC* pDC, int iItem, CRect rect, BOOL bIsPressed, BOOL bIsHighlighted)override; afx_msg LRESULT OnLayout(WPARAM wParam, LPARAM lParam); afx_msg void OnDestroy(); DECLARE_MESSAGE_MAP() @@ -53,7 +51,7 @@ namespace LISTEX::INTERNAL HDITEMW m_hdItem { }; //For drawing. WCHAR m_wstrHeaderText[MAX_PATH] { }; DWORD m_dwHeaderHeight { 19 }; //Standard (default) height. - std::unordered_map m_umapClrColumn { }; //Color of individual columns. + std::unordered_map m_umapClrColumn { }; //Color of individual columns. bool m_fSortable { false }; //Need to draw sortable triangle or not? int m_iSortColumn { -1 }; //Column to draw sorting triangle at. -1 is to avoid triangle before first clicking. bool m_fSortAscending { }; //Sorting type. diff --git a/Pepper/MainFrm.cpp b/Pepper/MainFrm.cpp index 7075c9f..6fd91eb 100644 --- a/Pepper/MainFrm.cpp +++ b/Pepper/MainFrm.cpp @@ -7,22 +7,63 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #include "stdafx.h" +#include "ChildFrm.h" #include "MainFrm.h" -#include "res/resource.h" #include "PepperDoc.h" +#include "res/resource.h" IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWndEx) BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_WM_CREATE() ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew) + ON_REGISTERED_MESSAGE(AFX_WM_CHANGE_ACTIVE_TAB, &CMainFrame::OnTabActivate) ON_WM_DROPFILES() ON_WM_GETMINMAXINFO() ON_COMMAND(ID_WINDOW_MANAGER, &CMainFrame::OnWindowManager) ON_COMMAND(ID_APP_EDITMODE, &CMainFrame::OnAppEditmode) ON_UPDATE_COMMAND_UI(ID_APP_EDITMODE, &CMainFrame::OnUpdateAppEditmode) + ON_WM_CLOSE() END_MESSAGE_MAP() +int& CMainFrame::GetChildFramesCount() +{ + return m_iChildFrames; +} + +void CMainFrame::SetCurrFramePtrNull() +{ + m_pCurrFrameData = nullptr; +} + +LRESULT CMainFrame::OnTabActivate(WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + if (m_fClosing || GetChildFramesCount() == 0) + return S_OK; + + if (m_pCurrFrameData != nullptr) + { + for (const auto& iter : *m_pCurrFrameData) + { + if (iter.pWnd != nullptr && ::IsWindow(iter.pWnd->m_hWnd) && iter.pWnd->IsWindowVisible()) + iter.pWnd->ShowWindow(SW_HIDE); + } + } + + if (auto pFrame = reinterpret_cast(MDIGetActive()); pFrame != nullptr) + { + auto& refVec = pFrame->GetWndStatData(); + for (const auto& iter : refVec) + { + if (iter.pWnd != nullptr && ::IsWindow(iter.pWnd->m_hWnd) && iter.fVisible) + iter.pWnd->ShowWindow(SW_SHOW); + } + m_pCurrFrameData = &refVec; + } + + return S_OK; +} + int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1) @@ -82,9 +123,9 @@ BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) if (tabGroups.GetCount() > 0) { POSITION pos = tabGroups.GetHeadPosition(); - while (pos != NULL) + while (pos != nullptr) { - CMFCTabCtrl* pTabCtrl = DYNAMIC_DOWNCAST(CMFCTabCtrl, tabGroups.GetNext(pos)); + auto* pTabCtrl = DYNAMIC_DOWNCAST(CMFCTabCtrl, tabGroups.GetNext(pos)); if (pTabCtrl == pWnd) //Click on TabCtrl. { pTabCtrl->ScreenToClient(&pt); @@ -93,15 +134,15 @@ BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) { CWnd* pTab = pTabCtrl->GetTabWnd(iTab); if (pTab) - pwndMBtnCurDown = pTab; + pWndMBtnCurDown = pTab; else - pwndMBtnCurDown = nullptr; + pWndMBtnCurDown = nullptr; } else - pwndMBtnCurDown = nullptr; + pWndMBtnCurDown = nullptr; } else - pwndMBtnCurDown = nullptr; + pWndMBtnCurDown = nullptr; } } } @@ -117,9 +158,9 @@ BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) if (tabGroups.GetCount() > 0) { POSITION pos = tabGroups.GetHeadPosition(); - while (pos != NULL) + while (pos != nullptr) { - CMFCTabCtrl* pTabCtrl = DYNAMIC_DOWNCAST(CMFCTabCtrl, tabGroups.GetNext(pos)); + auto* pTabCtrl = DYNAMIC_DOWNCAST(CMFCTabCtrl, tabGroups.GetNext(pos)); if (pTabCtrl == pWnd) //Click on TabCtrl. { pTabCtrl->ScreenToClient(&pt); @@ -127,7 +168,7 @@ BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) if (iTab != -1) { CWnd* pTab = pTabCtrl->GetTabWnd(iTab); - if (pTab && pTab == pwndMBtnCurDown) + if (pTab && pTab == pWndMBtnCurDown) pTab->SendMessage(WM_CLOSE, 0, 0); } } @@ -177,35 +218,33 @@ void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) void CMainFrame::OnAppEditmode() { - CFrameWnd* pFrame = GetActiveFrame(); - if (pFrame) - { - CPepperDoc* pDoc = (CPepperDoc*)pFrame->GetActiveDocument(); - if (pDoc) - { - if (pDoc->IsEditMode()) - pDoc->SetEditMode(false); - else - pDoc->SetEditMode(true); - } - } + if (auto pFrame = GetActiveFrame(); pFrame != nullptr) + if (auto* pDoc = reinterpret_cast(pFrame->GetActiveDocument()); pDoc != nullptr) + pDoc->SetEditMode(!pDoc->IsEditMode()); } void CMainFrame::OnUpdateAppEditmode(CCmdUI *pCmdUI) { - CFrameWnd* pFrame = GetActiveFrame(); - if (!pFrame) + auto pFrame = GetActiveFrame(); + + if (pFrame == nullptr) { pCmdUI->Enable(0); return; } - CPepperDoc* pDoc = (CPepperDoc*)pFrame->GetActiveDocument(); - if (pDoc) + if (auto pDoc = reinterpret_cast(pFrame->GetActiveDocument()); pDoc != nullptr) { if (pDoc->IsEditMode()) m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_APP_EDITMODE), TBBS_PRESSED); } else pCmdUI->Enable(0); +} + +void CMainFrame::OnClose() +{ + m_fClosing = true; + + CMDIFrameWndEx::OnClose(); } \ No newline at end of file diff --git a/Pepper/Pepper.cpp b/Pepper/Pepper.cpp index 10e625d..4336e0f 100644 --- a/Pepper/Pepper.cpp +++ b/Pepper/Pepper.cpp @@ -7,25 +7,21 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #include "stdafx.h" -#include "Pepper.h" -#include "MainFrm.h" #include "ChildFrm.h" +#include "MainFrm.h" +#include "Pepper.h" #include "PepperDoc.h" -#include "res/resource.h" #include "constants.h" +#include "res/resource.h" class CAboutDlg : public CDialogEx { public: CAboutDlg() : CDialogEx(IDD_ABOUTBOX) {}; protected: - BOOL OnInitDialog() override; - DECLARE_MESSAGE_MAP() + BOOL OnInitDialog()override; }; -BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) -END_MESSAGE_MAP() - BOOL CAboutDlg::OnInitDialog() { CDialogEx::OnInitDialog(); @@ -58,6 +54,7 @@ BOOL CPepperApp::InitInstance() SetRegistryKey(L"Pepper - PE files viewer"); + //Modern looking tooltips. CMFCToolTipInfo ttParams; ttParams.m_bVislManagerTheme = TRUE; theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL, RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams); @@ -69,7 +66,7 @@ BOOL CPepperApp::InitInstance() AddDocTemplate(pDocTemplate); // create main MDI Frame window - CMainFrame* pMainFrame = new CMainFrame; + auto* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) { delete pMainFrame; @@ -126,7 +123,7 @@ void CPepperApp::OnAppAbout() void CPepperApp::OnFileOpen() { - CFileDialog fd(TRUE, NULL, NULL, + CFileDialog fd(TRUE, nullptr, nullptr, OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_DONTADDTORECENT | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, L"All files (*.*)|*.*||"); diff --git a/Pepper/Pepper.vcxproj b/Pepper/Pepper.vcxproj index 7e9daac..decbda8 100644 --- a/Pepper/Pepper.vcxproj +++ b/Pepper/Pepper.vcxproj @@ -66,6 +66,7 @@ $(SolutionDir)obj\$(Configuration)\$(Platform)\ $(ProjectName)d include;$(IncludePath)$(VC_IncludePath);$(WindowsSDK_IncludePath); + false false @@ -73,12 +74,14 @@ $(SolutionDir)obj\$(Configuration)\$(Platform)\ include;$(IncludePath)$(VC_IncludePath);$(WindowsSDK_IncludePath); $(ProjectName) + false false false $(SolutionDir)obj\$(Configuration)\$(Platform)\ $(SolutionDir)bin\ + false diff --git a/Pepper/SplitterEx.cpp b/Pepper/SplitterEx.cpp index 1a880ef..d21c31c 100644 --- a/Pepper/SplitterEx.cpp +++ b/Pepper/SplitterEx.cpp @@ -162,7 +162,6 @@ void CSplitterEx::RecalcPanes() void CSplitterEx::OnInvertTracker(const CRect& /*rect*/) { - return; } void CSplitterEx::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rect) diff --git a/Pepper/TreeEx.cpp b/Pepper/TreeEx.cpp index b5f8263..f80879d 100644 --- a/Pepper/TreeEx.cpp +++ b/Pepper/TreeEx.cpp @@ -38,9 +38,9 @@ BOOL CTreeEx::OnEraseBkgnd(CDC* /*pDC*/) return FALSE; } -void CTreeEx::OnKillFocus(CWnd* /*pNewWnd*/) +void CTreeEx::OnKillFocus(CWnd* pNewWnd) { - //CTreeCtrl::OnKillFocus(pNewWnd); +// CTreeCtrl::OnKillFocus(pNewWnd); } void CTreeEx::OnLButtonDown(UINT nFlags, CPoint point) diff --git a/Pepper/ViewLeft.cpp b/Pepper/ViewLeft.cpp index 920596f..4d69d80 100644 --- a/Pepper/ViewLeft.cpp +++ b/Pepper/ViewLeft.cpp @@ -7,8 +7,8 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #include "stdafx.h" -#include "ViewLeft.h" #include "res/resource.h" +#include "ViewLeft.h" #include "constants.h" IMPLEMENT_DYNCREATE(CViewLeft, CView) @@ -40,18 +40,18 @@ void CViewLeft::OnInitialUpdate() m_stTreeMain.SetImageList(&m_ImgListRootTree, TVSIL_NORMAL); - const HTREEITEM hTreeRoot = m_stTreeMain.InsertItem(L"FILE SUMMARY"); + const auto hTreeRoot = m_stTreeMain.InsertItem(L"FILE SUMMARY"); m_stTreeMain.SetItemState(hTreeRoot, TVIS_BOLD, TVIS_BOLD); m_stTreeMain.SetItemData(hTreeRoot, IDC_SHOW_FILE_SUMMARY); if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_DOSHEADER)) { - const HTREEITEM hTreeDosHeader = m_stTreeMain.InsertItem(L"MS-DOS Header [IMAGE_DOS_HEADER]", iconHdr, iconHdr, hTreeRoot); + const auto hTreeDosHeader = m_stTreeMain.InsertItem(L"MS-DOS Header [IMAGE_DOS_HEADER]", iconHdr, iconHdr, hTreeRoot); m_stTreeMain.SetItemData(hTreeDosHeader, IDC_LIST_DOSHEADER); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_RICHHEADER)) { - const HTREEITEM hTreeDosRich = m_stTreeMain.InsertItem(L"\u00ABRich\u00BB Header", iconHdr, iconHdr, hTreeRoot); + const auto hTreeDosRich = m_stTreeMain.InsertItem(L"\u00ABRich\u00BB Header", iconHdr, iconHdr, hTreeRoot); m_stTreeMain.SetItemData(hTreeDosRich, IDC_LIST_RICHHEADER); } @@ -69,7 +69,7 @@ void CViewLeft::OnInitialUpdate() if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_FILEHEADER)) { - const HTREEITEM hTreeFileHeader = m_stTreeMain.InsertItem(L"File Header [IMAGE_FILE_HEADER]", iconHdr, iconHdr, + const auto hTreeFileHeader = m_stTreeMain.InsertItem(L"File Header [IMAGE_FILE_HEADER]", iconHdr, iconHdr, hTreeNTHeaders); m_stTreeMain.SetItemData(hTreeFileHeader, IDC_LIST_FILEHEADER); } @@ -85,7 +85,7 @@ void CViewLeft::OnInitialUpdate() if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_SECTIONS)) { - const HTREEITEM hTreeSecHeaders = m_stTreeMain.InsertItem(L"Sections Headers [IMAGE_SECTION_HEADER]", iconHdr, iconHdr, hTreeRoot); + const auto hTreeSecHeaders = m_stTreeMain.InsertItem(L"Sections Headers [IMAGE_SECTION_HEADER]", iconHdr, iconHdr, hTreeRoot); m_stTreeMain.SetItemData(hTreeSecHeaders, IDC_LIST_SECHEADERS); } @@ -94,68 +94,68 @@ void CViewLeft::OnInitialUpdate() { if (hTreeOptHeader) { - const HTREEITEM hTreeDataDirs = m_stTreeMain.InsertItem(L"Data Directories [IMAGE_DATA_DIRECTORY]", iconHdr, iconHdr, hTreeOptHeader); + const auto hTreeDataDirs = m_stTreeMain.InsertItem(L"Data Directories [IMAGE_DATA_DIRECTORY]", iconHdr, iconHdr, hTreeOptHeader); m_stTreeMain.SetItemData(hTreeDataDirs, IDC_LIST_DATADIRECTORIES); m_stTreeMain.Expand(hTreeOptHeader, TVE_EXPAND); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_EXPORT)) { - const HTREEITEM hTreeExportDir = m_stTreeMain.InsertItem(L"Export Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeExportDir = m_stTreeMain.InsertItem(L"Export Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeExportDir, IDC_LIST_EXPORT); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_IMPORT)) { - const HTREEITEM hTreeImportDir = m_stTreeMain.InsertItem(L"Import Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeImportDir = m_stTreeMain.InsertItem(L"Import Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeImportDir, IDC_LIST_IMPORT); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_RESOURCE)) { - const HTREEITEM hTreeResourceDir = m_stTreeMain.InsertItem(L"Resource Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeResourceDir = m_stTreeMain.InsertItem(L"Resource Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeResourceDir, IDC_TREE_RESOURCE); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_EXCEPTION)) { - const HTREEITEM hTreeExceptionDir = m_stTreeMain.InsertItem(L"Exception Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeExceptionDir = m_stTreeMain.InsertItem(L"Exception Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeExceptionDir, IDC_LIST_EXCEPTIONS); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_SECURITY)) { - const HTREEITEM hTreeSecurityDir = m_stTreeMain.InsertItem(L"Security Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeSecurityDir = m_stTreeMain.InsertItem(L"Security Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeSecurityDir, IDC_LIST_SECURITY); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_BASERELOC)) { - const HTREEITEM hTreeRelocationDir = m_stTreeMain.InsertItem(L"Relocations Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeRelocationDir = m_stTreeMain.InsertItem(L"Relocations Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeRelocationDir, IDC_LIST_RELOCATIONS); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_DEBUG)) { - const HTREEITEM hTreeDebugDir = m_stTreeMain.InsertItem(L"Debug Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeDebugDir = m_stTreeMain.InsertItem(L"Debug Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeDebugDir, IDC_LIST_DEBUG); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_ARCHITECTURE)) { - const HTREEITEM hTreeArchitectureDir = m_stTreeMain.InsertItem(L"Architecture Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeArchitectureDir = m_stTreeMain.InsertItem(L"Architecture Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeArchitectureDir, IDC_LIST_ARCHITECTURE); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_GLOBALPTR)) { - const HTREEITEM hTreeGlobalPTRDir = m_stTreeMain.InsertItem(L"GlobalPTR Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeGlobalPTRDir = m_stTreeMain.InsertItem(L"GlobalPTR Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeGlobalPTRDir, IDC_LIST_GLOBALPTR); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_TLS)) { - const HTREEITEM hTreeTLSDir = m_stTreeMain.InsertItem(L"TLS Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeTLSDir = m_stTreeMain.InsertItem(L"TLS Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeTLSDir, IDC_LIST_TLS); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_LOADCONFIG)) { - const HTREEITEM hTreeLoadConfigDir = m_stTreeMain.InsertItem(L"Load Config Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeLoadConfigDir = m_stTreeMain.InsertItem(L"Load Config Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeLoadConfigDir, IDC_LIST_LOADCONFIG); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_BOUNDIMPORT)) { - const HTREEITEM hTreeBoundImportDir = m_stTreeMain.InsertItem(L"Bound Import Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeBoundImportDir = m_stTreeMain.InsertItem(L"Bound Import Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeBoundImportDir, IDC_LIST_BOUNDIMPORT); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_IAT)) { - const HTREEITEM hTreeIATDir = m_stTreeMain.InsertItem(L"IAT Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeIATDir = m_stTreeMain.InsertItem(L"IAT Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeIATDir, IDC_LIST_IAT); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_DELAYIMPORT)) { - const HTREEITEM hTreeDelayImportDir = m_stTreeMain.InsertItem(L"Delay Import Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeDelayImportDir = m_stTreeMain.InsertItem(L"Delay Import Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeDelayImportDir, IDC_LIST_DELAYIMPORT); } if (ImageHasFlag(dwFileInfo, IMAGE_FLAG_COMDESCRIPTOR)) { - const HTREEITEM hTreeCOMDescriptorDir = m_stTreeMain.InsertItem(L"COM Descriptor Directory", iconDirs, iconDirs, hTreeRoot); + const auto hTreeCOMDescriptorDir = m_stTreeMain.InsertItem(L"COM Descriptor Directory", iconDirs, iconDirs, hTreeRoot); m_stTreeMain.SetItemData(hTreeCOMDescriptorDir, IDC_LIST_COMDESCRIPTOR); } } @@ -166,7 +166,7 @@ void CViewLeft::OnInitialUpdate() BOOL CViewLeft::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { - const LPNMTREEVIEW pTree = reinterpret_cast(lParam); + const auto pTree = reinterpret_cast(lParam); if (pTree->hdr.idFrom == IDC_TREE_LEFT_MAIN && pTree->hdr.code == TVN_SELCHANGED) m_pMainDoc->UpdateAllViews(this, m_stTreeMain.GetItemData(pTree->itemNew.hItem)); diff --git a/Pepper/ViewRightBL.cpp b/Pepper/ViewRightBL.cpp index 166e984..273128e 100644 --- a/Pepper/ViewRightBL.cpp +++ b/Pepper/ViewRightBL.cpp @@ -8,8 +8,8 @@ ****************************************************************************************************/ #include "stdafx.h" #include "ViewRightBL.h" -#include "res/resource.h" #include "constants.h" +#include "res/resource.h" IMPLEMENT_DYNCREATE(CViewRightBL, CView) @@ -48,10 +48,10 @@ void CViewRightBL::OnInitialUpdate() m_stlcs.stColor.clrTooltipBk = RGB(0, 132, 132); m_stlcs.stColor.clrHdrText = RGB(255, 255, 255); m_stlcs.stColor.clrHdrBk = RGB(0, 132, 132); - m_stlcs.stColor.clrHdrHglInactive = RGB(0, 112, 112); - m_stlcs.stColor.clrHdrHglActive = RGB(0, 92, 92); + m_stlcs.stColor.clrHdrHglInact= RGB(0, 112, 112); + m_stlcs.stColor.clrHdrHglAct = RGB(0, 92, 92); m_stlcs.dwHdrHeight = 35; - m_stlcs.pwndParent = this; + m_stlcs.pParent = this; m_stlcs.fSortable = true; m_lf.lfHeight = 16; @@ -165,7 +165,7 @@ BOOL CViewRightBL::OnEraseBkgnd(CDC* pDC) BOOL CViewRightBL::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) { - const LPNMTREEVIEW pTree = reinterpret_cast(lParam); + const auto pTree = reinterpret_cast(lParam); if (pTree->hdr.idFrom == IDC_TREE_RESOURCE_BOTTOM && pTree->hdr.code == TVN_SELCHANGED) { @@ -191,7 +191,7 @@ BOOL CViewRightBL::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) { auto data = &lvl3vec[idlvl3].vecResRawDataLvL3; //Resource data and resource type to show in CViewRightBR. - RESHELPER stResHelper { }; + SRESHELPER stResHelper { }; stResHelper.IdResType = rootvec[idlvlRoot].stResDirEntryRoot.Id; stResHelper.IdResName = lvl2vec[idlvl2].stResDirEntryLvL2.Id; stResHelper.pData = (std::vector*)data; @@ -786,7 +786,7 @@ int CViewRightBL::CreateTreeResources() swprintf_s(wstr, MAX_PATH, L"%u", pResDirEntry->Id); } - const HTREEITEM treeRoot = m_treeResBottom.InsertItem(wstr, iconDirs, iconDirs); + const auto treeRoot = m_treeResBottom.InsertItem(wstr, iconDirs, iconDirs); m_vecResId.emplace_back(ilvlRoot, -1, -1); m_treeResBottom.SetItemData(treeRoot, m_vecResId.size() - 1); long ilvl2 = 0; diff --git a/Pepper/ViewRightBR.cpp b/Pepper/ViewRightBR.cpp index 0501529..5f10699 100644 --- a/Pepper/ViewRightBR.cpp +++ b/Pepper/ViewRightBR.cpp @@ -7,20 +7,44 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #include "stdafx.h" +#include "MainFrm.h" #include "ViewRightBR.h" #include "constants.h" -BEGIN_MESSAGE_MAP(CWndDlgSample, CWnd) +BEGIN_MESSAGE_MAP(CDlgSampleWnd, CWnd) ON_WM_PAINT() + ON_WM_CLOSE() END_MESSAGE_MAP() -void CWndDlgSample::OnPaint() +void CDlgSampleWnd::Attach(CImageList* pImgList, CChildFrame* pChildFrame) +{ + m_pImgRes = pImgList; + m_pChildFrame = pChildFrame; +} + +void CDlgSampleWnd::SetDlgVisible(bool fVisible) +{ + if (m_pChildFrame == nullptr) + return; + + ShowWindow(fVisible ? SW_SHOW : SW_HIDE); + m_pChildFrame->SetWindowStatus(this, fVisible); +} + +void CDlgSampleWnd::OnPaint() { CPaintDC dc(this); if (m_pImgRes) m_pImgRes->Draw(&dc, 0, POINT { 0, 0 }, ILD_NORMAL); } +void CDlgSampleWnd::OnClose() +{ + SetDlgVisible(false); + CWnd::OnClose(); +} + + IMPLEMENT_DYNCREATE(CViewRightBR, CScrollView) BEGIN_MESSAGE_MAP(CViewRightBR, CScrollView) @@ -40,6 +64,9 @@ void CViewRightBR::OnInitialUpdate() m_EditBRB.Create(WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, CRect(0, 0, 0, 0), this, 0x01); + m_DlgSampleWnd.Attach(&m_stImgRes, m_pChildFrame); + m_pChildFrame->GetWndStatData().emplace_back(SWINDOWSTATUS { &m_DlgSampleWnd }); + LOGFONTW lf { }; StringCchCopyW(lf.lfFaceName, 9, L"Consolas"); lf.lfHeight = 18; @@ -52,7 +79,7 @@ void CViewRightBR::OnInitialUpdate() } m_EditBRB.SetFont(&m_fontEditRes); - m_stlcs.pwndParent = this; + m_stlcs.pParent = this; m_stlcs.stColor.clrTooltipText = RGB(255, 255, 255); m_stlcs.stColor.clrTooltipBk = RGB(0, 132, 132); m_stlcs.stColor.clrHdrText = RGB(255, 255, 255); @@ -76,11 +103,11 @@ void CViewRightBR::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* pHint) if (!m_pChildFrame || LOWORD(lHint) == IDC_HEX_RIGHT_TR || LOWORD(lHint) == ID_DOC_EDITMODE) return; - //If any but Resources Update we destroy m_wndDlgSample, if it's currently created. + //If any but Resources Update we destroy m_DlgSampleWnd, if it's currently created. if (LOWORD(lHint) != IDC_SHOW_RESOURCE_RBR) { - if (m_wndDlgSample.m_hWnd) - m_wndDlgSample.DestroyWindow(); + if (m_DlgSampleWnd.m_hWnd) + m_DlgSampleWnd.DestroyWindow(); } if (m_hwndActive) @@ -104,7 +131,7 @@ void CViewRightBR::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* pHint) m_pChildFrame->m_stSplitterRightBottom.SetColumnInfo(0, rcParent.Width() / 3, 0); break; case IDC_SHOW_RESOURCE_RBR: - ShowResource(reinterpret_cast(pHint)); + ShowResource(reinterpret_cast(pHint)); m_pChildFrame->m_stSplitterRightBottom.ShowCol(1); m_pChildFrame->m_stSplitterRightBottom.SetColumnInfo(0, rcParent.Width() / 3, 0); break; @@ -120,7 +147,7 @@ void CViewRightBR::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* pHint) m_pChildFrame->m_stSplitterRightBottom.RecalcLayout(); } -void CViewRightBR::ShowResource(const RESHELPER* pResHelper) +void CViewRightBR::ShowResource(const SRESHELPER* pResHelper) { m_stImgRes.DeleteImageList(); m_iResTypeToDraw = -1; @@ -132,9 +159,11 @@ void CViewRightBR::ShowResource(const RESHELPER* pResHelper) if (pResHelper) { //Destroy Dialog Sample window if it's any other resource type now. - if (pResHelper->IdResType != 5 && m_wndDlgSample.m_hWnd) - m_wndDlgSample.DestroyWindow(); - + if (pResHelper->IdResType != 5 && m_DlgSampleWnd.m_hWnd) + { + m_DlgSampleWnd.SetDlgVisible(false); + m_DlgSampleWnd.DestroyWindow(); + } if (pResHelper->pData->empty()) return ResLoadError(); @@ -176,14 +205,17 @@ void CViewRightBR::ShowResource(const RESHELPER* pResHelper) else { //Destroy Dialog Sample window if it's just Resource window Update. - if (m_wndDlgSample.m_hWnd) - m_wndDlgSample.DestroyWindow(); + if (m_DlgSampleWnd.m_hWnd) + { + m_DlgSampleWnd.SetDlgVisible(false); + m_DlgSampleWnd.DestroyWindow(); + } } RedrawWindow(); } -void CViewRightBR::CreateIconCursor(const RESHELPER* pResHelper) +void CViewRightBR::CreateIconCursor(const SRESHELPER* pResHelper) { HICON hIcon; ICONINFO iconInfo; @@ -213,15 +245,15 @@ void CViewRightBR::CreateIconCursor(const RESHELPER* pResHelper) m_fDrawRes = true; } -void CViewRightBR::CreateBitmap(const RESHELPER * pResHelper) +void CViewRightBR::CreateBitmap(const SRESHELPER* pResHelper) { - BITMAPINFO* pDIBInfo = (BITMAPINFO*)pResHelper->pData->data(); + auto* pDIBInfo = (BITMAPINFO*)pResHelper->pData->data(); int iColors = pDIBInfo->bmiHeader.biClrUsed ? pDIBInfo->bmiHeader.biClrUsed : 1 << pDIBInfo->bmiHeader.biBitCount; LPVOID pDIBBits; if (pDIBInfo->bmiHeader.biBitCount > 8) pDIBBits = (LPVOID)((PDWORD)(pDIBInfo->bmiColors + pDIBInfo->bmiHeader.biClrUsed) + - ((pDIBInfo->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0)); + ((pDIBInfo->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0)); else pDIBBits = (LPVOID)(pDIBInfo->bmiColors + iColors); @@ -248,7 +280,7 @@ void CViewRightBR::CreateBitmap(const RESHELPER * pResHelper) bmp.DeleteObject(); } -void CViewRightBR::CreateDlg(const RESHELPER * pResHelper) +void CViewRightBR::CreateDlg(const SRESHELPER * pResHelper) { #pragma pack(push, 4) struct DLGTEMPLATEEX //Helper struct. Not completed. @@ -305,10 +337,10 @@ void CViewRightBR::CreateDlg(const RESHELPER * pResHelper) ::GetWindowRect(hwndResDlg, &rcDlg); int iPosX = 0, iPosY = 0; UINT uFlags = SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; - if (!m_wndDlgSample.m_hWnd) + if (!m_DlgSampleWnd.m_hWnd) { - if (!m_wndDlgSample.CreateEx(m_dwExStyles, AfxRegisterWndClass(0), - L"Sample Dialog...", m_dwStyles, 0, 0, 0, 0, m_hWnd, 0)) + if (!m_DlgSampleWnd.CreateEx(m_dwExStyles, AfxRegisterWndClass(0), + L"Sample Dialog...", m_dwStyles, 0, 0, 0, 0, m_hWnd, nullptr)) { MessageBoxW(L"Sample Dialog window CreateEx failed.", L"Error"); return; @@ -318,7 +350,7 @@ void CViewRightBR::CreateDlg(const RESHELPER * pResHelper) uFlags &= ~SWP_NOMOVE; } - HDC hDC = ::GetDC(m_wndDlgSample.m_hWnd); + HDC hDC = ::GetDC(m_DlgSampleWnd.m_hWnd); HDC hDCMemory = CreateCompatibleDC(hDC); HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rcDlg.Width(), rcDlg.Height()); ::SelectObject(hDCMemory, hBitmap); @@ -346,7 +378,7 @@ void CViewRightBR::CreateDlg(const RESHELPER * pResHelper) } DeleteDC(hDCMemory); - ::ReleaseDC(m_wndDlgSample.m_hWnd, hDC); + ::ReleaseDC(m_DlgSampleWnd.m_hWnd, hDC); CBitmap bmp; if (!bmp.Attach(hBitmap)) @@ -357,8 +389,9 @@ void CViewRightBR::CreateDlg(const RESHELPER * pResHelper) bmp.DeleteObject(); AdjustWindowRectEx(rcDlg, m_dwStyles, FALSE, m_dwExStyles); //Get window size with desirable client rect. - m_wndDlgSample.SetWindowPos(this, iPosX, iPosY, rcDlg.Width(), rcDlg.Height(), uFlags); - m_wndDlgSample.RedrawWindow(); //Draw dialog bitmap. + m_DlgSampleWnd.SetWindowPos(this, iPosX, iPosY, rcDlg.Width(), rcDlg.Height(), uFlags); + m_DlgSampleWnd.SetDlgVisible(true); + m_DlgSampleWnd.RedrawWindow(); //Draw dialog bitmap. m_EditBRB.SetWindowTextW(m_wstrEditBRB.data()); //Set Dialog resources info to Editbox. CRect rcClient; @@ -541,10 +574,12 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin for (auto& i : mapDlgStyles) { if (i.first & dwStyles) + { if (!wstrStyles.empty()) wstrStyles += L" | " + i.second; else wstrStyles += i.second; + } } wstrData += L"DIALOG STYLES: " + wstrStyles + L"\r\n"; @@ -554,10 +589,12 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin for (auto& i : mapDlgExStyles) { if (i.first & dwExStyles) + { if (!wstrStyles.empty()) wstrStyles += L" | " + i.second; else wstrStyles += i.second; + } } wstrData += L"DIALOG EXTENDED STYLES: " + wstrStyles + L"\r\n"; } @@ -581,7 +618,7 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin if (*(PWORD)pDataHdr != 0x0000) //If not NULL then there is a need to align. pDataHdr += (sizeof(WORD) - (((DWORD_PTR)pDataHdr - (DWORD_PTR)pDataDlgRes) & 1)) & 1; //WORD Aligning. size_t lengthClassName; - WCHAR* pwstrClassName = (WCHAR*)pDataHdr; + auto* pwstrClassName = (WCHAR*)pDataHdr; if (StringCbLengthW(pwstrClassName, nSize - ((DWORD_PTR)pDataHdr - (DWORD_PTR)pDataDlgRes), &lengthClassName) != S_OK) return ResLoadError(); pDataHdr += lengthClassName + sizeof(WCHAR); //Plus null terminating. @@ -595,7 +632,7 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin if (*(PWORD)pDataHdr != 0x0000) //If not NULL then there is a need to align. pDataHdr += (sizeof(WORD) - (((DWORD_PTR)pDataHdr - (DWORD_PTR)pDataDlgRes) & 1)) & 1; //WORD Aligning. size_t lengthTitle; - WCHAR* pwstrTitle = (WCHAR*)pDataHdr; + auto* pwstrTitle = (WCHAR*)pDataHdr; if (StringCbLengthW(pwstrTitle, nSize - ((DWORD_PTR)pDataHdr - (DWORD_PTR)pDataDlgRes), &lengthTitle) != S_OK) return ResLoadError(); pDataHdr += lengthTitle + sizeof(WCHAR); //Plus null terminating. @@ -730,11 +767,11 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin static const std::map mapItemClassOrd { { 0x0080, L"Button" }, - { 0x0081, L"Edit" }, - { 0x0082, L"Static" }, - { 0x0083, L"List box" }, - { 0x0084, L"Scroll bar" }, - { 0x0085, L"Combo box" }, + { 0x0081, L"Edit" }, + { 0x0082, L"Static" }, + { 0x0083, L"List box" }, + { 0x0084, L"Scroll bar" }, + { 0x0085, L"Combo box" }, }; std::wstring wstrItem = L" "; @@ -755,7 +792,7 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin { pDataItems += (sizeof(WORD) - (((DWORD_PTR)pDataItems - (DWORD_PTR)pDataDlgRes) & 1)) & 1; //WORD Aligning. size_t lengthClassNameItem; - WCHAR* pwstrClassNameItem = (WCHAR*)pDataItems; + auto* pwstrClassNameItem = (WCHAR*)pDataItems; if (StringCbLengthW(pwstrClassNameItem, nSize - ((DWORD_PTR)pDataItems - (DWORD_PTR)pDataDlgRes), &lengthClassNameItem) != S_OK) return ResLoadError(); pDataItems += lengthClassNameItem + sizeof(WCHAR); //Plus null terminating. @@ -778,7 +815,7 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin { pDataItems += (sizeof(WORD) - (((DWORD_PTR)pDataItems - (DWORD_PTR)pDataDlgRes) & 1)) & 1; //WORD Aligning. size_t lengthTitleItem; - WCHAR* pwstrTitleItem = (WCHAR*)pDataItems; + auto* pwstrTitleItem = (WCHAR*)pDataItems; if (StringCbLengthW(pwstrTitleItem, nSize - ((DWORD_PTR)pDataItems - (DWORD_PTR)pDataDlgRes), &lengthTitleItem) != S_OK) return ResLoadError(); pDataItems += lengthTitleItem + sizeof(WCHAR); //Plus null terminating. @@ -803,9 +840,9 @@ void CViewRightBR::ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstrin wstrData += L"}"; } -void CViewRightBR::CreateStrings(const RESHELPER * pResHelper) +void CViewRightBR::CreateStrings(const SRESHELPER * pResHelper) { - LPCWSTR pwszResString = reinterpret_cast(pResHelper->pData->data()); + auto pwszResString = reinterpret_cast(pResHelper->pData->data()); std::wstring wstrTmp; for (int i = 0; i < 16; i++) { @@ -822,7 +859,7 @@ void CViewRightBR::CreateStrings(const RESHELPER * pResHelper) m_hwndActive = m_EditBRB.m_hWnd; } -void CViewRightBR::CreateGroupIconCursor(const RESHELPER * pResHelper) +void CViewRightBR::CreateGroupIconCursor(const SRESHELPER * pResHelper) { PLIBPE_RESOURCE_ROOT pstResRoot; if (m_pLibpe->GetResources(pstResRoot) != S_OK) @@ -850,7 +887,7 @@ void CViewRightBR::CreateGroupIconCursor(const RESHELPER * pResHelper) using LPGRPICONDIR = const GRPICONDIR*; #pragma pack(pop) - LPGRPICONDIR pGRPIDir = (LPGRPICONDIR)pResHelper->pData->data(); + auto pGRPIDir = (LPGRPICONDIR)pResHelper->pData->data(); HICON hIcon; ICONINFO iconInfo; @@ -915,7 +952,7 @@ void CViewRightBR::CreateGroupIconCursor(const RESHELPER * pResHelper) m_fDrawRes = true; } -void CViewRightBR::CreateVersion(const RESHELPER * pResHelper) +void CViewRightBR::CreateVersion(const SRESHELPER * pResHelper) { #pragma pack(push, 4) struct LANGANDCODEPAGE @@ -927,13 +964,13 @@ void CViewRightBR::CreateVersion(const RESHELPER * pResHelper) static const std::map mapVerInfoStrings { { 0, L"FileDescription" }, - { 1, L"FileVersion" }, - { 2, L"InternalName" }, - { 3, L"CompanyName" }, - { 4, L"LegalCopyright" }, - { 5, L"OriginalFilename" }, - { 6, L"ProductName" }, - { 7, L"ProductVersion" } + { 1, L"FileVersion" }, + { 2, L"InternalName" }, + { 3, L"CompanyName" }, + { 4, L"LegalCopyright" }, + { 5, L"OriginalFilename" }, + { 6, L"ProductName" }, + { 7, L"ProductVersion" } }; LANGANDCODEPAGE* pLangAndCP; @@ -952,7 +989,7 @@ void CViewRightBR::CreateVersion(const RESHELPER * pResHelper) swprintf_s(wstrSubBlock, 50, L"\\StringFileInfo\\%04x%04x\\%s", pLangAndCP[iterCodePage].wLanguage, pLangAndCP[iterCodePage].wCodePage, mapVerInfoStrings.at(i).data()); - m_wstrEditBRB += mapVerInfoStrings.at(i).data(); + m_wstrEditBRB += mapVerInfoStrings.at(i); m_wstrEditBRB += L" - "; WCHAR* pszBufferOut; @@ -970,7 +1007,7 @@ void CViewRightBR::CreateVersion(const RESHELPER * pResHelper) m_hwndActive = m_EditBRB.m_hWnd; } -void CViewRightBR::CreateManifest(const RESHELPER * pResHelper) +void CViewRightBR::CreateManifest(const SRESHELPER * pResHelper) { m_wstrEditBRB.resize(pResHelper->pData->size()); MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pResHelper->pData->data(), (int)pResHelper->pData->size(), &m_wstrEditBRB[0], (int)pResHelper->pData->size()); @@ -983,7 +1020,7 @@ void CViewRightBR::CreateManifest(const RESHELPER * pResHelper) m_hwndActive = m_EditBRB.m_hWnd; } -void CViewRightBR::CreateToolbar(const RESHELPER * pResHelper) +void CViewRightBR::CreateToolbar(const SRESHELPER * pResHelper) { PLIBPE_RESOURCE_ROOT pstResRoot; if (m_pLibpe->GetResources(pstResRoot) != S_OK) @@ -1009,7 +1046,7 @@ void CViewRightBR::CreateToolbar(const RESHELPER * pResHelper) auto& data = lvl3vec.at(0).vecResRawDataLvL3; if (!data.empty()) { - RESHELPER rh(2, pResHelper->IdResName, (std::vector*) & data); + SRESHELPER rh(2, pResHelper->IdResName, (std::vector*) & data); ShowResource(&rh); } } @@ -1077,10 +1114,10 @@ void CViewRightBR::OnDraw(CDC* pDC) else x = rcClient.Width() / 2 - (m_iImgResWidth / 2); - for (int i = 0; i < (int)m_vecImgRes.size(); i++) + for (const auto& iter : m_vecImgRes) { IMAGEINFO imginfo; - m_vecImgRes.at(i)->GetImageInfo(0, &imginfo); + iter->GetImageInfo(0, &imginfo); int iImgHeight = imginfo.rcImage.bottom - imginfo.rcImage.top; if (sizeScroll.cy > rcClient.Height()) y = sizeScroll.cy / 2 - (iImgHeight / 2); @@ -1088,7 +1125,7 @@ void CViewRightBR::OnDraw(CDC* pDC) y = rcClient.Height() / 2 - (iImgHeight / 2); ptDrawAt.SetPoint(x, y); - m_vecImgRes.at(i)->Draw(pDC, 0, ptDrawAt, ILD_NORMAL); + iter->Draw(pDC, 0, ptDrawAt, ILD_NORMAL); x += imginfo.rcImage.right - imginfo.rcImage.left; } break; diff --git a/Pepper/ViewRightTL.cpp b/Pepper/ViewRightTL.cpp index a883208..1bd6513 100644 --- a/Pepper/ViewRightTL.cpp +++ b/Pepper/ViewRightTL.cpp @@ -19,6 +19,19 @@ BEGIN_MESSAGE_MAP(CViewRightTL, CView) ON_NOTIFY(LVN_GETDISPINFOW, IDC_LIST_IMPORT, &CViewRightTL::OnListImportGetDispInfo) ON_NOTIFY(LVN_GETDISPINFOW, IDC_LIST_RELOCATIONS, &CViewRightTL::OnListRelocsGetDispInfo) ON_NOTIFY(LVN_GETDISPINFOW, IDC_LIST_EXCEPTIONS, &CViewRightTL::OnListExceptionsGetDispInfo) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_EXPORT, &CViewRightTL::OnListExportMenuSelect) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_IMPORT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_IMPORT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(NM_CLICK, IDC_LIST_IMPORT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_IMPORT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_IAT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_IAT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(NM_CLICK, IDC_LIST_IAT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_IAT, &CViewRightTL::OnListImportNotify) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_TLS, &CViewRightTL::OnListTLSMenuSelect) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_BOUNDIMPORT, &CViewRightTL::OnListBoundImpMenuSelect) + ON_NOTIFY(LISTEX_MSG_MENUSELECTED, IDC_LIST_COMDESCRIPTOR, &CViewRightTL::OnListCOMDescMenuSelect) + ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_RESOURCE_TOP, &CViewRightTL::OnTreeResTopSelChange) ON_WM_ERASEBKGND() END_MESSAGE_MAP() @@ -68,9 +81,9 @@ void CViewRightTL::OnInitialUpdate() m_stlcs.stColor.clrTooltipBk = RGB(0, 132, 132); m_stlcs.stColor.clrHdrText = RGB(255, 255, 255); m_stlcs.stColor.clrHdrBk = RGB(0, 132, 132); - m_stlcs.stColor.clrHdrHglInactive = RGB(0, 112, 112); - m_stlcs.stColor.clrHdrHglActive = RGB(0, 92, 92); - m_stlcs.pwndParent = this; + m_stlcs.stColor.clrHdrHglInact = RGB(0, 112, 112); + m_stlcs.stColor.clrHdrHglAct = RGB(0, 92, 92); + m_stlcs.pParent = this; m_stlcs.dwHdrHeight = 39; m_stlcs.fSortable = true; @@ -229,7 +242,7 @@ void CViewRightTL::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* /*pHint*/ m_pChildFrame->m_stSplitterRight.RecalcLayout(); } -void CViewRightTL::OnDraw(CDC * pDC) +void CViewRightTL::OnDraw(CDC* pDC) { //Printing app name/version info and //currently oppened file's type and name. @@ -267,6 +280,73 @@ void CViewRightTL::OnDraw(CDC * pDC) m_wstrFullPath.data(), (int)m_wstrFullPath.size(), nullptr); } +BOOL CViewRightTL::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) +{ + CView::OnNotify(wParam, lParam, pResult); + + const auto pNMI = reinterpret_cast(lParam); + switch (pNMI->hdr.idFrom) + { + case IDC_LIST_DOSHEADER: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DOSHEADER_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_RICHHEADER: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_RICHHEADER_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_NTHEADER: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_NTHEADER_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_FILEHEADER: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_FILEHEADER_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_OPTIONALHEADER: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_OPTIONALHEADER_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_DATADIRECTORIES: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DATADIRECTORIES_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_SECHEADERS: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_SECHEADERS_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_EXCEPTIONS: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_EXCEPTION_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_DEBUG: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DEBUG_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_ARCHITECTURE: + case IDC_LIST_GLOBALPTR: + break; + case IDC_LIST_LOADCONFIG: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_LOADCONFIG_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_SECURITY: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_SECURITY_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_RELOCATIONS: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_RELOCATIONS_ENTRY, pNMI->iItem)); + break; + case IDC_LIST_DELAYIMPORT: + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DELAYIMPORT_ENTRY, pNMI->iItem)); + break; + } + + return TRUE; +} + BOOL CViewRightTL::OnEraseBkgnd(CDC* /*pDC*/) { return FALSE; @@ -280,10 +360,10 @@ void CViewRightTL::OnSize(UINT nType, int cx, int cy) m_pwndActive->SetWindowPos(this, 0, 0, cx, cy, SWP_NOACTIVATE | SWP_NOZORDER); } -void CViewRightTL::OnListSectionsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) +void CViewRightTL::OnListSectionsGetDispInfo(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - NMLVDISPINFOW *pDispInfo = reinterpret_cast(pNMHDR); - LVITEMW* pItem = &pDispInfo->item; + auto *pDispInfo = reinterpret_cast(pNMHDR); + auto* pItem = &pDispInfo->item; if (pItem->mask & LVIF_TEXT) { @@ -331,13 +411,12 @@ void CViewRightTL::OnListSectionsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) break; } } - *pResult = 0; } -void CViewRightTL::OnListImportGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) +void CViewRightTL::OnListImportGetDispInfo(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - NMLVDISPINFOW *pDispInfo = reinterpret_cast(pNMHDR); - LVITEMW* pItem = &pDispInfo->item; + auto *pDispInfo = reinterpret_cast(pNMHDR); + auto* pItem = &pDispInfo->item; if (pItem->mask & LVIF_TEXT) { @@ -368,13 +447,12 @@ void CViewRightTL::OnListImportGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) break; } } - *pResult = 0; } -void CViewRightTL::OnListRelocsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) +void CViewRightTL::OnListRelocsGetDispInfo(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - NMLVDISPINFOW *pDispInfo = reinterpret_cast(pNMHDR); - LVITEMW* pItem = &pDispInfo->item; + auto *pDispInfo = reinterpret_cast(pNMHDR); + auto* pItem = &pDispInfo->item; if (pItem->mask & LVIF_TEXT) { @@ -395,13 +473,12 @@ void CViewRightTL::OnListRelocsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) break; } } - *pResult = 0; } -void CViewRightTL::OnListExceptionsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult) +void CViewRightTL::OnListExceptionsGetDispInfo(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - NMLVDISPINFOW *pDispInfo = reinterpret_cast(pNMHDR); - LVITEMW* pItem = &pDispInfo->item; + auto *pDispInfo = reinterpret_cast(pNMHDR); + auto* pItem = &pDispInfo->item; if (pItem->mask & LVIF_TEXT) { @@ -421,384 +498,279 @@ void CViewRightTL::OnListExceptionsGetDispInfo(NMHDR * pNMHDR, LRESULT * pResult break; } } - *pResult = 0; } -void CViewRightTL::SortImportData() +void CViewRightTL::OnListExportMenuSelect(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - std::sort(m_pImport->begin(), m_pImport->end(), [&](const LIBPE_IMPORT_MODULE& ref1, const LIBPE_IMPORT_MODULE& ref2) - { - std::wstring wstr1, wstr2; - wstr1.resize(32); - wstr2.resize(32); + const auto pNMI = reinterpret_cast(pNMHDR); + + bool fx32 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE32); + bool fx64 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE64); + DWORD dwOffset { }, dwSize = 0; - int iCompare { }; - switch (m_listImport->GetSortColumn()) + PLIBPE_EXPORT pExport; + if (m_pLibpe->GetExport(pExport) != S_OK) + return; + + switch (pNMI->lParam) + { + case IDM_LIST_GOTODESCOFFSET: + { + dwOffset = pExport->dwOffsetExportDesc; + dwSize = sizeof(IMAGE_EXPORT_DIRECTORY); + } + break; + case IDM_LIST_GOTODATAOFFSET: + { + switch (pNMI->iItem) { - case 0: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.dwOffsetImpDesc)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.dwOffsetImpDesc)); - iCompare = wstr1.compare(wstr2); + case 4: //Name + m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.Name, dwOffset); + dwSize = (DWORD)pExport->strModuleName.size(); break; - case 1: - iCompare = ref1.strModuleName.compare(ref2.strModuleName); + case 8: //AddressOfFunctions + m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfFunctions, dwOffset); + dwSize = 1; break; - case 2: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.OriginalFirstThunk)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.OriginalFirstThunk)); - iCompare = wstr1.compare(wstr2); + case 9: //AddressOfNames + m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfNames, dwOffset); + dwSize = 1; break; - case 3: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.TimeDateStamp)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.TimeDateStamp)); - iCompare = wstr1.compare(wstr2); - break; - case 4: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.ForwarderChain)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.ForwarderChain)); - iCompare = wstr1.compare(wstr2); - break; - case 5: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.Name)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.Name)); - iCompare = wstr1.compare(wstr2); - break; - case 6: - wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.FirstThunk)); - wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.FirstThunk)); - iCompare = wstr1.compare(wstr2); + case 10: //AddressOfOrdinals + m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfNameOrdinals, dwOffset); + dwSize = 1; break; } + } + break; + } - bool result { false }; - if (m_listImport->GetSortAscending()) - { - if (iCompare < 0) - result = true; - } - else - { - if (iCompare > 0) - result = true; - } - - return result; - - }); - - m_listImport->RedrawWindow(); + if (dwSize) + m_pFileLoader->ShowOffset(dwOffset, dwSize); } -BOOL CViewRightTL::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT * pResult) +void CViewRightTL::OnListImportNotify(NMHDR* pNMHDR, LRESULT* /*pResult*/) { - CView::OnNotify(wParam, lParam, pResult); - - const LPNMITEMACTIVATE pNMI = reinterpret_cast(lParam); + const auto pNMI = reinterpret_cast(pNMHDR); bool fx32 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE32); bool fx64 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE64); DWORD dwOffset { }, dwSize = 0; - switch (pNMI->hdr.idFrom) + + if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_IMPORT_ENTRY, pNMI->iItem)); + else if (pNMI->hdr.code == LVN_COLUMNCLICK) + SortImportData(); + else if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) { - case IDC_LIST_DOSHEADER: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DOSHEADER_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_RICHHEADER: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_RICHHEADER_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_NTHEADER: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_NTHEADER_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_FILEHEADER: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_FILEHEADER_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_OPTIONALHEADER: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_OPTIONALHEADER_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_DATADIRECTORIES: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DATADIRECTORIES_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_SECHEADERS: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_SECHEADERS_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_EXPORT: - if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) + switch (pNMI->lParam) { - PLIBPE_EXPORT pExport; - if (m_pLibpe->GetExport(pExport) != S_OK) - return -1; - - switch (pNMI->lParam) - { - case IDM_LIST_GOTODESCOFFSET: - { - dwOffset = pExport->dwOffsetExportDesc; - dwSize = sizeof(IMAGE_EXPORT_DIRECTORY); - } - break; - case IDM_LIST_GOTODATAOFFSET: - { - switch (pNMI->iItem) - { - case 4: //Name - m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.Name, dwOffset); - dwSize = (DWORD)pExport->strModuleName.size(); - break; - case 8: //AddressOfFunctions - m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfFunctions, dwOffset); - dwSize = 1; - break; - case 9: //AddressOfNames - m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfNames, dwOffset); - dwSize = 1; - break; - case 10: //AddressOfOrdinals - m_pLibpe->GetOffsetFromRVA(pExport->stExportDesc.AddressOfNameOrdinals, dwOffset); - dwSize = 1; - break; - } - } + case IDM_LIST_GOTODESCOFFSET: + dwOffset = m_pImport->at(pNMI->iItem).dwOffsetImpDesc; + dwSize = sizeof(IMAGE_IMPORT_DESCRIPTOR); break; - } - } - break; - case IDC_LIST_IAT: - case IDC_LIST_IMPORT: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_IMPORT_ENTRY, pNMI->iItem)); - else if (pNMI->hdr.code == LVN_COLUMNCLICK) - SortImportData(); - else if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) - { - switch (pNMI->lParam) + case IDM_LIST_GOTODATAOFFSET: + switch (pNMI->iSubItem) { - case IDM_LIST_GOTODESCOFFSET: - dwOffset = m_pImport->at(pNMI->iItem).dwOffsetImpDesc; - dwSize = sizeof(IMAGE_IMPORT_DESCRIPTOR); - break; - case IDM_LIST_GOTODATAOFFSET: - switch (pNMI->iSubItem) - { - case 1: //Str dll name - case 5: //Name - m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.Name, dwOffset); - dwSize = (DWORD)m_pImport->at(pNMI->iItem).strModuleName.size(); - break; ; - case 2: //OriginalFirstThunk - m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.OriginalFirstThunk, dwOffset); - if (fx32) - dwSize = sizeof(IMAGE_THUNK_DATA32); - else if (fx64) - dwSize = sizeof(IMAGE_THUNK_DATA64); - break; - case 3: //TimeDateStamp - break; - case 4: //ForwarderChain - m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.ForwarderChain, dwOffset); - break; - case 6: //FirstThunk - m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.FirstThunk, dwOffset); - if (fx32) - dwSize = sizeof(IMAGE_THUNK_DATA32); - else if (fx64) - dwSize = sizeof(IMAGE_THUNK_DATA64); - break; - } - break; - } - } - break; - case IDC_LIST_EXCEPTIONS: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_EXCEPTION_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_DEBUG: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DEBUG_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_ARCHITECTURE: - break; - case IDC_LIST_GLOBALPTR: - break; - case IDC_LIST_TLS: - if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) - { - PLIBPE_TLS pTLSDir; - if (m_pLibpe->GetTLS(pTLSDir) != S_OK) - return -1; - - switch (pNMI->lParam) - { - case IDM_LIST_GOTODESCOFFSET: - dwOffset = pTLSDir->dwOffsetTLS; + case 1: //Str dll name + case 5: //Name + m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.Name, dwOffset); + dwSize = (DWORD)m_pImport->at(pNMI->iItem).strModuleName.size(); + break; ; + case 2: //OriginalFirstThunk + m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.OriginalFirstThunk, dwOffset); if (fx32) - dwSize = sizeof(IMAGE_TLS_DIRECTORY32); + dwSize = sizeof(IMAGE_THUNK_DATA32); else if (fx64) - dwSize = sizeof(IMAGE_TLS_DIRECTORY64); + dwSize = sizeof(IMAGE_THUNK_DATA64); break; - case IDM_LIST_GOTODATAOFFSET: - { - PLIBPE_OPTHEADER_VAR pOpt; - if (m_pLibpe->GetOptionalHeader(pOpt) != S_OK) - return -1; - dwSize = 1; - + case 3: //TimeDateStamp + break; + case 4: //ForwarderChain + m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.ForwarderChain, dwOffset); + break; + case 6: //FirstThunk + m_pLibpe->GetOffsetFromRVA(m_pImport->at(pNMI->iItem).stImportDesc.FirstThunk, dwOffset); if (fx32) - { - const IMAGE_TLS_DIRECTORY32* pTLSDir32 = &pTLSDir->varTLS.stTLSDir32; - - switch (pNMI->iItem) - { - case 0: //StartAddressOfRawData - m_pLibpe->GetOffsetFromVA(pTLSDir32->StartAddressOfRawData, dwOffset); - break; - case 2: //AddressOfIndex - m_pLibpe->GetOffsetFromVA(pTLSDir32->AddressOfIndex, dwOffset); - break; - case 3: //AddressOfCallBacks - m_pLibpe->GetOffsetFromVA(pTLSDir32->AddressOfCallBacks, dwOffset); - break; - default: - dwSize = 0; //To not process other fields. - } - } + dwSize = sizeof(IMAGE_THUNK_DATA32); else if (fx64) - { - const IMAGE_TLS_DIRECTORY64* pTLSDir64 = &pTLSDir->varTLS.stTLSDir64; - - switch (pNMI->iItem) - { - case 0: //StartAddressOfRawData - m_pLibpe->GetOffsetFromRVA(pTLSDir64->StartAddressOfRawData, dwOffset); - break; - case 2: //AddressOfIndex - m_pLibpe->GetOffsetFromRVA(pTLSDir64->AddressOfIndex, dwOffset); - break; - case 3: //AddressOfCallBacks - m_pLibpe->GetOffsetFromRVA(pTLSDir64->AddressOfCallBacks, dwOffset); - break; - default: - dwSize = 0; //To not process other fields. - } - } + dwSize = sizeof(IMAGE_THUNK_DATA64); + break; } break; - } } + } + + if (dwSize) + m_pFileLoader->ShowOffset(dwOffset, dwSize); +} + +void CViewRightTL::OnListTLSMenuSelect(NMHDR* pNMHDR, LRESULT* /*pResult*/) +{ + const auto pNMI = reinterpret_cast(pNMHDR); + + bool fx32 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE32); + bool fx64 = ImageHasFlag(m_dwFileInfo, IMAGE_FLAG_PE64); + DWORD dwOffset { }, dwSize = 0; + + PLIBPE_TLS pTLSDir; + if (m_pLibpe->GetTLS(pTLSDir) != S_OK) + return; + + switch (pNMI->lParam) + { + case IDM_LIST_GOTODESCOFFSET: + dwOffset = pTLSDir->dwOffsetTLS; + if (fx32) + dwSize = sizeof(IMAGE_TLS_DIRECTORY32); + else if (fx64) + dwSize = sizeof(IMAGE_TLS_DIRECTORY64); break; - case IDC_LIST_LOADCONFIG: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_LOADCONFIG_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_BOUNDIMPORT: - if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) + case IDM_LIST_GOTODATAOFFSET: + { + PLIBPE_OPTHEADER_VAR pOpt; + if (m_pLibpe->GetOptionalHeader(pOpt) != S_OK) + return; + dwSize = 1; + + if (fx32) { - PLIBPE_BOUNDIMPORT_VEC pBoundImp; - if (m_pLibpe->GetBoundImport(pBoundImp) != S_OK) - return -1; + const IMAGE_TLS_DIRECTORY32* pTLSDir32 = &pTLSDir->varTLS.stTLSDir32; - switch (pNMI->lParam) - { - case IDM_LIST_GOTODESCOFFSET: - { - dwOffset = pBoundImp->at(pNMI->iItem).dwOffsetBoundImpDesc; - dwSize = sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR); - } - break; - case IDM_LIST_GOTODATAOFFSET: + switch (pNMI->iItem) { - switch (pNMI->iSubItem) - { - case 3: //OffsetModuleName - dwOffset = m_pLibpe->GetOffsetFromRVA(pBoundImp->at(pNMI->iItem).stBoundImpDesc.OffsetModuleName, dwOffset); - dwSize = (DWORD)pBoundImp->at(pNMI->iItem).strBoundName.size(); - break; - } - } - break; + case 0: //StartAddressOfRawData + m_pLibpe->GetOffsetFromVA(pTLSDir32->StartAddressOfRawData, dwOffset); + break; + case 2: //AddressOfIndex + m_pLibpe->GetOffsetFromVA(pTLSDir32->AddressOfIndex, dwOffset); + break; + case 3: //AddressOfCallBacks + m_pLibpe->GetOffsetFromVA(pTLSDir32->AddressOfCallBacks, dwOffset); + break; + default: + dwSize = 0; //To not process other fields. } } - break; - case IDC_LIST_COMDESCRIPTOR: - if (pNMI->hdr.code == LISTEX_MSG_MENUSELECTED) + else if (fx64) { - PLIBPE_COMDESCRIPTOR pCOMDesc; - if (m_pLibpe->GetCOMDescriptor(pCOMDesc) != S_OK) - return -1; + const IMAGE_TLS_DIRECTORY64* pTLSDir64 = &pTLSDir->varTLS.stTLSDir64; - switch (pNMI->lParam) - { - case IDM_LIST_GOTODESCOFFSET: + switch (pNMI->iItem) { - dwOffset = pCOMDesc->dwOffsetComDesc; - dwSize = sizeof(IMAGE_COR20_HEADER); - } - break; - case IDM_LIST_GOTODATAOFFSET: - //TODO: IDC_LIST_COMDESCRIPTOR->IDM_LIST_GOTODATAOFFSET. + case 0: //StartAddressOfRawData + m_pLibpe->GetOffsetFromRVA(pTLSDir64->StartAddressOfRawData, dwOffset); + break; + case 2: //AddressOfIndex + m_pLibpe->GetOffsetFromRVA(pTLSDir64->AddressOfIndex, dwOffset); break; + case 3: //AddressOfCallBacks + m_pLibpe->GetOffsetFromRVA(pTLSDir64->AddressOfCallBacks, dwOffset); + break; + default: + dwSize = 0; //To not process other fields. } } - break; - case IDC_LIST_SECURITY: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_SECURITY_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_RELOCATIONS: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_RELOCATIONS_ENTRY, pNMI->iItem)); - break; - case IDC_LIST_DELAYIMPORT: - if (pNMI->hdr.code == LVN_ITEMCHANGED || pNMI->hdr.code == NM_CLICK) - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_LIST_DELAYIMPORT_ENTRY, pNMI->iItem)); - break; - case IDC_TREE_RESOURCE_TOP: + } + break; + } + + if (dwSize) + m_pFileLoader->ShowOffset(dwOffset, dwSize); +} + +void CViewRightTL::OnListBoundImpMenuSelect(NMHDR* pNMHDR, LRESULT* /*pResult*/) +{ + const auto pNMI = reinterpret_cast(pNMHDR); + DWORD dwOffset { }, dwSize = 0; + + PLIBPE_BOUNDIMPORT_VEC pBoundImp; + if (m_pLibpe->GetBoundImport(pBoundImp) != S_OK) + return; + + switch (pNMI->lParam) { - const LPNMTREEVIEW pTree = reinterpret_cast(lParam); - if (pTree->hdr.code == TVN_SELCHANGED && pTree->itemNew.hItem != m_hTreeResDir) + case IDM_LIST_GOTODESCOFFSET: + { + dwOffset = pBoundImp->at(pNMI->iItem).dwOffsetBoundImpDesc; + dwSize = sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR); + } + break; + case IDM_LIST_GOTODATAOFFSET: + { + switch (pNMI->iSubItem) { - PLIBPE_RESOURCE_ROOT pResRoot; - if (m_pLibpe->GetResources(pResRoot) != S_OK) - return -1; + case 3: //OffsetModuleName + dwOffset = m_pLibpe->GetOffsetFromRVA(pBoundImp->at(pNMI->iItem).stBoundImpDesc.OffsetModuleName, dwOffset); + dwSize = (DWORD)pBoundImp->at(pNMI->iItem).strBoundName.size(); + break; + } + } + break; + } - const auto& [idlvlRoot, idlvl2, idlvl3] = m_vecResId.at(m_treeResTop.GetItemData(pTree->itemNew.hItem)); - if (idlvl2 >= 0) - { - auto& lvl2st = pResRoot->vecResRoot.at(idlvlRoot).stResLvL2; - auto& lvl2vec = lvl2st.vecResLvL2; + if (dwSize) + m_pFileLoader->ShowOffset(dwOffset, dwSize); +} - if (!lvl2vec.empty()) - { - if (idlvl3 >= 0) - { - auto& lvl3st = lvl2vec.at(idlvl2).stResLvL3; - auto& lvl3vec = lvl3st.vecResLvL3; - - if (!lvl3vec.empty()) - { - auto data = &lvl3vec.at(idlvl3).stResDataEntryLvL3; - //Send data pointer to CViewRightTR to display raw data. - m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_HEX_RIGHT_TR, 0), (CObject*)data); - } - } - } - } - } +void CViewRightTL::OnListCOMDescMenuSelect(NMHDR* pNMHDR, LRESULT* /*pResult*/) +{ + const auto pNMI = reinterpret_cast(pNMHDR); + DWORD dwOffset { }, dwSize = 0; + + PLIBPE_COMDESCRIPTOR pCOMDesc; + if (m_pLibpe->GetCOMDescriptor(pCOMDesc) != S_OK) + return; + + switch (pNMI->lParam) + { + case IDM_LIST_GOTODESCOFFSET: + { + dwOffset = pCOMDesc->dwOffsetComDesc; + dwSize = sizeof(IMAGE_COR20_HEADER); } break; + case IDM_LIST_GOTODATAOFFSET: + //TODO: IDC_LIST_COMDESCRIPTOR->IDM_LIST_GOTODATAOFFSET. + break; } if (dwSize) m_pFileLoader->ShowOffset(dwOffset, dwSize); +} - return TRUE; +void CViewRightTL::OnTreeResTopSelChange(NMHDR* pNMHDR, LRESULT* /*pResult*/) +{ + const auto pTree = reinterpret_cast(pNMHDR); + if (pTree->itemNew.hItem == m_hTreeResDir) + return; + + PLIBPE_RESOURCE_ROOT pResRoot; + if (m_pLibpe->GetResources(pResRoot) != S_OK) + return; + + const auto& [idlvlRoot, idlvl2, idlvl3] = m_vecResId.at(m_treeResTop.GetItemData(pTree->itemNew.hItem)); + if (idlvl2 >= 0) + { + auto& lvl2st = pResRoot->vecResRoot.at(idlvlRoot).stResLvL2; + auto& lvl2vec = lvl2st.vecResLvL2; + + if (!lvl2vec.empty()) + { + if (idlvl3 >= 0) + { + auto& lvl3st = lvl2vec.at(idlvl2).stResLvL3; + auto& lvl3vec = lvl3st.vecResLvL3; + + if (!lvl3vec.empty()) + { + auto data = &lvl3vec.at(idlvl3).stResDataEntryLvL3; + //Send data pointer to CViewRightTR to display raw data. + m_pMainDoc->UpdateAllViews(this, MAKELPARAM(IDC_HEX_RIGHT_TR, 0), reinterpret_cast(data)); + } + } + } + } } int CViewRightTL::CreateListDOSHeader() @@ -859,8 +831,8 @@ int CViewRightTL::CreateListRichHeader() m_listRichHdr->InsertColumn(2, L"ID [Hex]", LVCFMT_LEFT, 100); m_listRichHdr->InsertColumn(3, L"Version", LVCFMT_LEFT, 100); m_listRichHdr->InsertColumn(4, L"Occurrences", LVCFMT_LEFT, 100); - m_listRichHdr->SetColumnSortMode(1, EnListExSortMode::SORT_NUMERIC); - m_listRichHdr->SetColumnSortMode(4, EnListExSortMode::SORT_NUMERIC); + m_listRichHdr->SetColumnSortMode(1, EListExSortMode::SORT_NUMERIC); + m_listRichHdr->SetColumnSortMode(4, EListExSortMode::SORT_NUMERIC); WCHAR wstr[18]; int listindex = 0; @@ -1098,20 +1070,20 @@ int CViewRightTL::CreateListOptHeader() const std::map mapDllCharacteristics { { 0x0001, L"IMAGE_LIBRARY_PROCESS_INIT" }, - { 0x0002, L"IMAGE_LIBRARY_PROCESS_TERM" }, - { 0x0004, L"IMAGE_LIBRARY_THREAD_INIT" }, - { 0x0008, L"IMAGE_LIBRARY_THREAD_TERM" }, - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NX_COMPAT), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_SEH), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_BIND), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_APPCONTAINER), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_GUARD_CF), - TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) + { 0x0002, L"IMAGE_LIBRARY_PROCESS_TERM" }, + { 0x0004, L"IMAGE_LIBRARY_THREAD_INIT" }, + { 0x0008, L"IMAGE_LIBRARY_THREAD_TERM" }, + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NX_COMPAT), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_SEH), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_NO_BIND), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_APPCONTAINER), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_GUARD_CF), + TO_WSTR_MAP(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) }; WCHAR wstr[18]; @@ -1245,7 +1217,7 @@ int CViewRightTL::CreateListDataDirectories() m_listDataDirs->SetItemText(i, 2, wstr); swprintf_s(wstr, 9, L"%08X", pDataDirs->Size); m_listDataDirs->SetItemText(i, 3, wstr); - + if (!ref.strSecResidesIn.empty()) { swprintf_s(wstr, 9, L"%.8S", ref.strSecResidesIn.data()); @@ -1283,48 +1255,48 @@ int CViewRightTL::CreateListSecHeaders() const std::map mapSecFlags { { 0x00000000, L"IMAGE_SCN_TYPE_REG\n Reserved." }, - { 0x00000001, L"IMAGE_SCN_TYPE_DSECT\n Reserved." }, - { 0x00000002, L"IMAGE_SCN_TYPE_NOLOAD\n Reserved." }, - { 0x00000004, L"IMAGE_SCN_TYPE_GROUP\n Reserved." }, - { IMAGE_SCN_TYPE_NO_PAD, L"IMAGE_SCN_TYPE_NO_PAD\n Reserved." }, - { 0x00000010, L"IMAGE_SCN_TYPE_COPY\n Reserved." }, - { IMAGE_SCN_CNT_CODE, L"IMAGE_SCN_CNT_CODE\n Section contains code." }, - { IMAGE_SCN_CNT_INITIALIZED_DATA, L"IMAGE_SCN_CNT_INITIALIZED_DATA\n Section contains initialized data." }, - { IMAGE_SCN_CNT_UNINITIALIZED_DATA, L"IMAGE_SCN_CNT_UNINITIALIZED_DATA\n Section contains uninitialized data." }, - { IMAGE_SCN_LNK_OTHER, L"IMAGE_SCN_LNK_OTHER\n Reserved." }, - { IMAGE_SCN_LNK_INFO, L"IMAGE_SCN_LNK_INFO\n Section contains comments or some other type of information." }, - { 0x00000400, L"IMAGE_SCN_TYPE_OVER\n Reserved." }, - { IMAGE_SCN_LNK_REMOVE, L"IMAGE_SCN_LNK_REMOVE\n Section contents will not become part of image." }, - { IMAGE_SCN_LNK_COMDAT, L"IMAGE_SCN_LNK_COMDAT\n Section contents comdat." }, - { IMAGE_SCN_NO_DEFER_SPEC_EXC, L"IMAGE_SCN_NO_DEFER_SPEC_EXC\n Reset speculative exceptions handling bits in the TLB entries for this section." }, - { IMAGE_SCN_GPREL, L"IMAGE_SCN_GPREL\n Section content can be accessed relative to GP" }, - { 0x00010000, L"IMAGE_SCN_MEM_SYSHEAP\n Obsolete" }, - { IMAGE_SCN_MEM_PURGEABLE, L"IMAGE_SCN_MEM_PURGEABLE" }, - { IMAGE_SCN_MEM_LOCKED, L"IMAGE_SCN_MEM_LOCKED" }, - { IMAGE_SCN_MEM_PRELOAD, L"IMAGE_SCN_MEM_PRELOAD" }, - { IMAGE_SCN_ALIGN_1BYTES, L"IMAGE_SCN_ALIGN_1BYTES" }, - { IMAGE_SCN_ALIGN_2BYTES, L"IMAGE_SCN_ALIGN_2BYTES" }, - { IMAGE_SCN_ALIGN_4BYTES, L"IMAGE_SCN_ALIGN_4BYTES" }, - { IMAGE_SCN_ALIGN_8BYTES, L"IMAGE_SCN_ALIGN_8BYTES" }, - { IMAGE_SCN_ALIGN_16BYTES, L"IMAGE_SCN_ALIGN_16BYTES\n Default alignment if no others are specified." }, - { IMAGE_SCN_ALIGN_32BYTES, L"IMAGE_SCN_ALIGN_32BYTES" }, - { IMAGE_SCN_ALIGN_64BYTES, L"IMAGE_SCN_ALIGN_64BYTES" }, - { IMAGE_SCN_ALIGN_128BYTES, L"IMAGE_SCN_ALIGN_128BYTES" }, - { IMAGE_SCN_ALIGN_256BYTES, L"IMAGE_SCN_ALIGN_256BYTES" }, - { IMAGE_SCN_ALIGN_512BYTES, L"IMAGE_SCN_ALIGN_512BYTES" }, - { IMAGE_SCN_ALIGN_1024BYTES, L"IMAGE_SCN_ALIGN_1024BYTES" }, - { IMAGE_SCN_ALIGN_2048BYTES, L"IMAGE_SCN_ALIGN_2048BYTES" }, - { IMAGE_SCN_ALIGN_4096BYTES, L"IMAGE_SCN_ALIGN_4096BYTES" }, - { IMAGE_SCN_ALIGN_8192BYTES, L"IMAGE_SCN_ALIGN_8192BYTES" }, - { IMAGE_SCN_ALIGN_MASK, L"IMAGE_SCN_ALIGN_MASK" }, - { IMAGE_SCN_LNK_NRELOC_OVFL, L"IMAGE_SCN_LNK_NRELOC_OVFL\n Section contains extended relocations." }, - { IMAGE_SCN_MEM_DISCARDABLE, L"IMAGE_SCN_MEM_DISCARDABLE\n Section can be discarded." }, - { IMAGE_SCN_MEM_NOT_CACHED, L"IMAGE_SCN_MEM_NOT_CACHED\n Section is not cachable." }, - { IMAGE_SCN_MEM_NOT_PAGED, L"IMAGE_SCN_MEM_NOT_PAGED\n Section is not pageable." }, - { IMAGE_SCN_MEM_SHARED, L"IMAGE_SCN_MEM_SHARED\n Section is shareable." }, - { IMAGE_SCN_MEM_EXECUTE, L"IMAGE_SCN_MEM_EXECUTE\n Section is executable." }, - { IMAGE_SCN_MEM_READ, L"IMAGE_SCN_MEM_READ\n Section is readable." }, - { IMAGE_SCN_MEM_WRITE, L"IMAGE_SCN_MEM_WRITE\n Section is writeable." } + { 0x00000001, L"IMAGE_SCN_TYPE_DSECT\n Reserved." }, + { 0x00000002, L"IMAGE_SCN_TYPE_NOLOAD\n Reserved." }, + { 0x00000004, L"IMAGE_SCN_TYPE_GROUP\n Reserved." }, + { IMAGE_SCN_TYPE_NO_PAD, L"IMAGE_SCN_TYPE_NO_PAD\n Reserved." }, + { 0x00000010, L"IMAGE_SCN_TYPE_COPY\n Reserved." }, + { IMAGE_SCN_CNT_CODE, L"IMAGE_SCN_CNT_CODE\n Section contains code." }, + { IMAGE_SCN_CNT_INITIALIZED_DATA, L"IMAGE_SCN_CNT_INITIALIZED_DATA\n Section contains initialized data." }, + { IMAGE_SCN_CNT_UNINITIALIZED_DATA, L"IMAGE_SCN_CNT_UNINITIALIZED_DATA\n Section contains uninitialized data." }, + { IMAGE_SCN_LNK_OTHER, L"IMAGE_SCN_LNK_OTHER\n Reserved." }, + { IMAGE_SCN_LNK_INFO, L"IMAGE_SCN_LNK_INFO\n Section contains comments or some other type of information." }, + { 0x00000400, L"IMAGE_SCN_TYPE_OVER\n Reserved." }, + { IMAGE_SCN_LNK_REMOVE, L"IMAGE_SCN_LNK_REMOVE\n Section contents will not become part of image." }, + { IMAGE_SCN_LNK_COMDAT, L"IMAGE_SCN_LNK_COMDAT\n Section contents comdat." }, + { IMAGE_SCN_NO_DEFER_SPEC_EXC, L"IMAGE_SCN_NO_DEFER_SPEC_EXC\n Reset speculative exceptions handling bits in the TLB entries for this section." }, + { IMAGE_SCN_GPREL, L"IMAGE_SCN_GPREL\n Section content can be accessed relative to GP" }, + { 0x00010000, L"IMAGE_SCN_MEM_SYSHEAP\n Obsolete" }, + { IMAGE_SCN_MEM_PURGEABLE, L"IMAGE_SCN_MEM_PURGEABLE" }, + { IMAGE_SCN_MEM_LOCKED, L"IMAGE_SCN_MEM_LOCKED" }, + { IMAGE_SCN_MEM_PRELOAD, L"IMAGE_SCN_MEM_PRELOAD" }, + { IMAGE_SCN_ALIGN_1BYTES, L"IMAGE_SCN_ALIGN_1BYTES" }, + { IMAGE_SCN_ALIGN_2BYTES, L"IMAGE_SCN_ALIGN_2BYTES" }, + { IMAGE_SCN_ALIGN_4BYTES, L"IMAGE_SCN_ALIGN_4BYTES" }, + { IMAGE_SCN_ALIGN_8BYTES, L"IMAGE_SCN_ALIGN_8BYTES" }, + { IMAGE_SCN_ALIGN_16BYTES, L"IMAGE_SCN_ALIGN_16BYTES\n Default alignment if no others are specified." }, + { IMAGE_SCN_ALIGN_32BYTES, L"IMAGE_SCN_ALIGN_32BYTES" }, + { IMAGE_SCN_ALIGN_64BYTES, L"IMAGE_SCN_ALIGN_64BYTES" }, + { IMAGE_SCN_ALIGN_128BYTES, L"IMAGE_SCN_ALIGN_128BYTES" }, + { IMAGE_SCN_ALIGN_256BYTES, L"IMAGE_SCN_ALIGN_256BYTES" }, + { IMAGE_SCN_ALIGN_512BYTES, L"IMAGE_SCN_ALIGN_512BYTES" }, + { IMAGE_SCN_ALIGN_1024BYTES, L"IMAGE_SCN_ALIGN_1024BYTES" }, + { IMAGE_SCN_ALIGN_2048BYTES, L"IMAGE_SCN_ALIGN_2048BYTES" }, + { IMAGE_SCN_ALIGN_4096BYTES, L"IMAGE_SCN_ALIGN_4096BYTES" }, + { IMAGE_SCN_ALIGN_8192BYTES, L"IMAGE_SCN_ALIGN_8192BYTES" }, + { IMAGE_SCN_ALIGN_MASK, L"IMAGE_SCN_ALIGN_MASK" }, + { IMAGE_SCN_LNK_NRELOC_OVFL, L"IMAGE_SCN_LNK_NRELOC_OVFL\n Section contains extended relocations." }, + { IMAGE_SCN_MEM_DISCARDABLE, L"IMAGE_SCN_MEM_DISCARDABLE\n Section can be discarded." }, + { IMAGE_SCN_MEM_NOT_CACHED, L"IMAGE_SCN_MEM_NOT_CACHED\n Section is not cachable." }, + { IMAGE_SCN_MEM_NOT_PAGED, L"IMAGE_SCN_MEM_NOT_PAGED\n Section is not pageable." }, + { IMAGE_SCN_MEM_SHARED, L"IMAGE_SCN_MEM_SHARED\n Section is shareable." }, + { IMAGE_SCN_MEM_EXECUTE, L"IMAGE_SCN_MEM_EXECUTE\n Section is executable." }, + { IMAGE_SCN_MEM_READ, L"IMAGE_SCN_MEM_READ\n Section is readable." }, + { IMAGE_SCN_MEM_WRITE, L"IMAGE_SCN_MEM_WRITE\n Section is writeable." } }; UINT listindex = 0; @@ -1376,7 +1348,7 @@ int CViewRightTL::CreateListExport() m_listExportDir->SetItemText(i, 1, ref.wstrName.data()); swprintf_s(wstr, 17, L"%lu", dwSize); m_listExportDir->SetItemText(i, 2, wstr); - + if (i == 4) //Name swprintf_s(wstr, MAX_PATH, L"%08lX (%S)", dwValue, pExport->strModuleName.data()); else @@ -1594,14 +1566,14 @@ int CViewRightTL::CreateListSecurity() swprintf_s(wstr, 5, L"%04X", pSert->wRevision); m_listSecurityDir->SetItemText(listindex, 2, wstr); - + auto iterRevision = mapSertRevision.find(pSert->wRevision); if (iterRevision != mapSertRevision.end()) m_listSecurityDir->SetCellTooltip(listindex, 2, iterRevision->second.data(), L"Certificate revision:"); swprintf_s(wstr, 5, L"%04X", pSert->wCertificateType); m_listSecurityDir->SetItemText(listindex, 3, wstr); - + auto iterType = mapSertType.find(pSert->wCertificateType); if (iterType != mapSertType.end()) m_listSecurityDir->SetCellTooltip(listindex, 3, iterType->second.data(), L"Certificate type:"); @@ -1757,7 +1729,7 @@ int CViewRightTL::CreateListTLS() DWORD dwOffset = ref.dwOffset; DWORD dwSize = ref.dwSize; DWORD dwValue = *((PDWORD)((DWORD_PTR)pTLSDir32 + dwOffset)) & (DWORD_MAX >> ((sizeof(DWORD) - dwSize) * 8)); - + swprintf_s(wstr, 9, L"%08lX", pTLSDir->dwOffsetTLS + dwOffset); m_listTLSDir->InsertItem(i, wstr); m_listTLSDir->SetItemText(i, 1, ref.wstrName.data()); @@ -1782,7 +1754,7 @@ int CViewRightTL::CreateListTLS() DWORD dwOffset = ref.dwOffset; DWORD dwSize = ref.dwSize; ULONGLONG ullValue = *((PULONGLONG)((DWORD_PTR)pTLSDir64 + dwOffset)) & (ULONGLONG_MAX >> ((sizeof(ULONGLONG) - dwSize) * 8)); - + swprintf_s(wstr, 9, L"%08lX", pTLSDir->dwOffsetTLS + dwOffset); m_listTLSDir->InsertItem(i, wstr); m_listTLSDir->SetItemText(i, 1, ref.wstrName.data()); @@ -1820,19 +1792,19 @@ int CViewRightTL::CreateListLCD() const std::map mapGuardFlags { { IMAGE_GUARD_CF_INSTRUMENTED, L"IMAGE_GUARD_CF_INSTRUMENTED\n Module performs control flow integrity checks using system-supplied support" }, - { IMAGE_GUARD_CFW_INSTRUMENTED, L"IMAGE_GUARD_CFW_INSTRUMENTED\n Module performs control flow and write integrity checks" }, - { IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT, L"IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT\n Module contains valid control flow target metadata" }, - { IMAGE_GUARD_SECURITY_COOKIE_UNUSED, L"IMAGE_GUARD_SECURITY_COOKIE_UNUSED\n Module does not make use of the /GS security cookie" }, - { IMAGE_GUARD_PROTECT_DELAYLOAD_IAT, L"IMAGE_GUARD_PROTECT_DELAYLOAD_IAT\n Module supports read only delay load IAT" }, - { IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION, L"IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION\n Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected" }, - { IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT, L"IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT\n Module contains suppressed export information. This also infers that the address taken IAT table is also present in the load config." }, - { IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION, L"IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION\n Module enables suppression of exports" }, - { IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT, L"IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT\n Module contains longjmp target information" }, - { IMAGE_GUARD_RF_INSTRUMENTED, L"IMAGE_GUARD_RF_INSTRUMENTED\n Module contains return flow instrumentation and metadata" }, - { IMAGE_GUARD_RF_ENABLE, L"IMAGE_GUARD_RF_ENABLE\n Module requests that the OS enable return flow protection" }, - { IMAGE_GUARD_RF_STRICT, L"IMAGE_GUARD_RF_STRICT\n Module requests that the OS enable return flow protection in strict mode" }, - { IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK, L"IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK\n Stride of Guard CF function table encoded in these bits (additional count of bytes per element)" }, - { IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT, L"IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT\n Shift to right-justify Guard CF function table stride" } + { IMAGE_GUARD_CFW_INSTRUMENTED, L"IMAGE_GUARD_CFW_INSTRUMENTED\n Module performs control flow and write integrity checks" }, + { IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT, L"IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT\n Module contains valid control flow target metadata" }, + { IMAGE_GUARD_SECURITY_COOKIE_UNUSED, L"IMAGE_GUARD_SECURITY_COOKIE_UNUSED\n Module does not make use of the /GS security cookie" }, + { IMAGE_GUARD_PROTECT_DELAYLOAD_IAT, L"IMAGE_GUARD_PROTECT_DELAYLOAD_IAT\n Module supports read only delay load IAT" }, + { IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION, L"IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION\n Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected" }, + { IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT, L"IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT\n Module contains suppressed export information. This also infers that the address taken IAT table is also present in the load config." }, + { IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION, L"IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION\n Module enables suppression of exports" }, + { IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT, L"IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT\n Module contains longjmp target information" }, + { IMAGE_GUARD_RF_INSTRUMENTED, L"IMAGE_GUARD_RF_INSTRUMENTED\n Module contains return flow instrumentation and metadata" }, + { IMAGE_GUARD_RF_ENABLE, L"IMAGE_GUARD_RF_ENABLE\n Module requests that the OS enable return flow protection" }, + { IMAGE_GUARD_RF_STRICT, L"IMAGE_GUARD_RF_STRICT\n Module requests that the OS enable return flow protection in strict mode" }, + { IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK, L"IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK\n Stride of Guard CF function table encoded in these bits (additional count of bytes per element)" }, + { IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT, L"IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT\n Shift to right-justify Guard CF function table stride" } }; WCHAR wstr[MAX_PATH]; @@ -2049,12 +2021,12 @@ int CViewRightTL::CreateListCOM() const std::map mapFlags { { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_ILONLY, L"COMIMAGE_FLAGS_ILONLY" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_32BITREQUIRED, L"COMIMAGE_FLAGS_32BITREQUIRED" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_IL_LIBRARY, L"COMIMAGE_FLAGS_IL_LIBRARY" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_STRONGNAMESIGNED, L"COMIMAGE_FLAGS_STRONGNAMESIGNED" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT, L"COMIMAGE_FLAGS_NATIVE_ENTRYPOINT" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_TRACKDEBUGDATA, L"COMIMAGE_FLAGS_TRACKDEBUGDATA" }, - { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_32BITPREFERRED, L"COMIMAGE_FLAGS_32BITPREFERRED" } + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_32BITREQUIRED, L"COMIMAGE_FLAGS_32BITREQUIRED" }, + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_IL_LIBRARY, L"COMIMAGE_FLAGS_IL_LIBRARY" }, + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_STRONGNAMESIGNED, L"COMIMAGE_FLAGS_STRONGNAMESIGNED" }, + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_NATIVE_ENTRYPOINT, L"COMIMAGE_FLAGS_NATIVE_ENTRYPOINT" }, + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_TRACKDEBUGDATA, L"COMIMAGE_FLAGS_TRACKDEBUGDATA" }, + { ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_32BITPREFERRED, L"COMIMAGE_FLAGS_32BITPREFERRED" } }; const IMAGE_COR20_HEADER * pCom = &pCOMDesc->stCorHdr; @@ -2086,4 +2058,70 @@ int CViewRightTL::CreateListCOM() } return 0; +} + +void CViewRightTL::SortImportData() +{ + std::sort(m_pImport->begin(), m_pImport->end(), + [&](const LIBPE_IMPORT_MODULE& ref1, const LIBPE_IMPORT_MODULE& ref2) + { + std::wstring wstr1, wstr2; + wstr1.resize(32); + wstr2.resize(32); + + int iCompare { }; + switch (m_listImport->GetSortColumn()) + { + case 0: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.dwOffsetImpDesc)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.dwOffsetImpDesc)); + iCompare = wstr1.compare(wstr2); + break; + case 1: + iCompare = ref1.strModuleName.compare(ref2.strModuleName); + break; + case 2: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.OriginalFirstThunk)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.OriginalFirstThunk)); + iCompare = wstr1.compare(wstr2); + break; + case 3: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.TimeDateStamp)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.TimeDateStamp)); + iCompare = wstr1.compare(wstr2); + break; + case 4: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.ForwarderChain)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.ForwarderChain)); + iCompare = wstr1.compare(wstr2); + break; + case 5: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.Name)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.Name)); + iCompare = wstr1.compare(wstr2); + break; + case 6: + wstr1.resize(swprintf_s(wstr1.data(), 9, L"%08X", ref1.stImportDesc.FirstThunk)); + wstr2.resize(swprintf_s(wstr2.data(), 9, L"%08X", ref2.stImportDesc.FirstThunk)); + iCompare = wstr1.compare(wstr2); + break; + } + + bool result { false }; + if (m_listImport->GetSortAscending()) + { + if (iCompare < 0) + result = true; + } + else + { + if (iCompare > 0) + result = true; + } + + return result; + + }); + + m_listImport->RedrawWindow(); } \ No newline at end of file diff --git a/Pepper/ViewRightTR.cpp b/Pepper/ViewRightTR.cpp index 91cc829..31f50f8 100644 --- a/Pepper/ViewRightTR.cpp +++ b/Pepper/ViewRightTR.cpp @@ -60,7 +60,7 @@ void CViewRightTR::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* pHint) ::SetWindowPos(m_hwndActive, m_hWnd, 0, 0, rcClient.Width(), rcClient.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER); break; case IDC_HEX_RIGHT_TR: - CreateHexResources((PIMAGE_RESOURCE_DATA_ENTRY)pHint); + CreateHexResources(reinterpret_cast(pHint)); m_pChildFrame->m_stSplitterRightTop.ShowCol(1); m_pChildFrame->m_stSplitterRightTop.SetColumnInfo(0, rcParent.Width() / 3, 0); break; @@ -95,7 +95,7 @@ void CViewRightTR::OnDocEditMode() m_stHexEdit->SetMutable(m_pMainDoc->IsEditMode()); } -void CViewRightTR::CreateHexResources(PIMAGE_RESOURCE_DATA_ENTRY pRes) +void CViewRightTR::CreateHexResources(const IMAGE_RESOURCE_DATA_ENTRY* pRes) { CRect rcParent, rcClient; GetParent()->GetWindowRect(&rcParent); diff --git a/Pepper/include/ChildFrm.h b/Pepper/include/ChildFrm.h index e53fa38..32016cc 100644 --- a/Pepper/include/ChildFrm.h +++ b/Pepper/include/ChildFrm.h @@ -7,21 +7,26 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #pragma once +#include "constants.h" #include "SplitterEx.h" class CChildFrame : public CMDIChildWndEx { public: - CChildFrame() {}; - CSplitterEx m_stSplitterMain, m_stSplitterRight, m_stSplitterRightTop, m_stSplitterRightBottom; + auto GetWndStatData()->std::vector&; + void SetWindowStatus(CWnd* pWnd, bool fVisible); DECLARE_DYNCREATE(CChildFrame) + CSplitterEx m_stSplitterMain, m_stSplitterRight, m_stSplitterRightTop, m_stSplitterRightBottom; protected: virtual ~CChildFrame() {}; afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnClose(); BOOL PreCreateWindow(CREATESTRUCT& cs) override; BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) override; + DECLARE_MESSAGE_MAP() +private: bool m_fSplitterCreated { false }; UINT m_cx { }, m_cy { }; - DECLARE_MESSAGE_MAP() + std::vector m_vecWndStatus { }; }; diff --git a/Pepper/include/FileLoader.h b/Pepper/include/FileLoader.h index de3790b..b22cc5d 100644 --- a/Pepper/include/FileLoader.h +++ b/Pepper/include/FileLoader.h @@ -22,12 +22,9 @@ class CPepperDoc; class CFileLoader : public CWnd { public: - CFileLoader() {}; - ~CFileLoader() {}; - //First function to call. HRESULT LoadFile(LPCWSTR lpszFileName, CPepperDoc* pDoc); - bool IsWritable() { return m_fWritable; } + [[nodiscard]] bool IsWritable()const { return m_fWritable; } //Shows arbitrary offset in already loaded file (LoadFile) //If pHexCtrl == nullptr inner CHexCtrl object is used. HRESULT ShowOffset(ULONGLONG ullOffset, ULONGLONG ullSelectionSize, IHexCtrl* pHexCtrl = nullptr); @@ -35,7 +32,7 @@ class CFileLoader : public CWnd //If pHexCtrl == nullptr inner CHexCtrl object is used. HRESULT ShowFilePiece(ULONGLONG ullOffset, ULONGLONG ullSize, IHexCtrl* pHexCtrl = nullptr); //Has file been modified in memory or not. - bool IsModified() { return m_fModified; } + [[nodiscard]] bool IsModified()const { return m_fModified; } bool Flush(); //Writes memory mapped file on disk. //Unloads loaded file and all pieces, if present. HRESULT UnloadFile(); @@ -58,7 +55,7 @@ class CFileLoader : public CWnd }; bool m_fLoaded { false }; CPepperDoc* m_pMainDoc { }; - IHexCtrlPtr m_stHex { CreateHexCtrl() }; + IHexCtrlPtr m_pHex { CreateHexCtrl() }; HEXCREATESTRUCT m_hcs; HEXDATASTRUCT m_hds; LARGE_INTEGER m_stFileSize { }; //Size of the loaded PE file. @@ -73,13 +70,12 @@ class CFileLoader : public CWnd SYSTEM_INFO m_stSysInfo { }; std::vector m_vecQuery; const int IDC_HEX_CTRL = 0xFF; //Id of inner IHexCtrl. - BYTE m_byte { }; //For HEXCTRL_MSG_GETDATA. bool m_fModified { false }; bool m_fWritable { false }; private: - unsigned char GetByte(HWND hWnd, ULONGLONG ullOffset); //For Virtual HexCtrl retrives next byte on demand. + std::byte* GetData(HWND hWnd, ULONGLONG ullOffset); //For Virtual HexCtrl retrives next byte on demand. HRESULT MapFileOffset(QUERYDATA& rData, ULONGLONG ullOffset, DWORD dwSize = 0); //Main routine for mapping big file's parts. HRESULT UnmapFileOffset(QUERYDATA& rData); - bool IsLoaded(); + [[nodiscard]] bool IsLoaded()const; virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); }; \ No newline at end of file diff --git a/Pepper/include/HexCtrl.h b/Pepper/include/HexCtrl.h index f43774f..19a7736 100644 --- a/Pepper/include/HexCtrl.h +++ b/Pepper/include/HexCtrl.h @@ -7,13 +7,19 @@ * For more information visit the project's official repository. * ****************************************************************************************/ #pragma once +#include //Standard Windows header. +#include #include //std::shared/unique_ptr and related. -#include +#include #include -#include //Standard Windows header. +#include + +#ifndef __cpp_lib_byte +static_assert(false, "std::byte compliant compiler required."); +#endif /********************************************************************** -* If HEXCTRL_IHEXCTRLPTR_UNIQUEPTR defined then IHexCtrlPtr is * +* If HEXCTRL_IHEXCTRLPTR_UNIQUEPTR defined then IHexCtrlPtr is * * resolved to std::unique_ptr. Otherwise it's std::shared_ptr. * **********************************************************************/ #define HEXCTRL_IHEXCTRLPTR_UNIQUEPTR @@ -26,29 +32,64 @@ /********************************************************************** * For manually initialize MFC. * -* This macro is used only for Win32 non MFC projects, built with * -* Use MFC in a Shared DLL option. * +* This macro is used only for Win32 non MFC projects, with HexCtrl * +* built from sources, with "Use MFC in a Shared DLL" setting. * **********************************************************************/ //#define HEXCTRL_MANUAL_MFC_INIT namespace HEXCTRL { /******************************************************************************************** - * EHexModifyMode - Enum of the data modification mode, used in HEXMODIFYSTRUCT. * + * EHexCmd - Enum of the commands that can be executed within HexCtrl, used in ExecuteCmd. * ********************************************************************************************/ - enum class EHexModifyMode : WORD + enum class EHexCmd : WORD { - MODIFY_DEFAULT, MODIFY_REPEAT, MODIFY_OPERATION + 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_TEXT, + CMD_CLIPBOARD_COPY_BASE64, CMD_CLIPBOARD_COPY_CARR, CMD_CLIPBOARD_COPY_GREPHEX, CMD_CLIPBOARD_COPY_PRNTSCRN, + CMD_CLIPBOARD_PASTE_HEX, CMD_CLIPBOARD_PASTE_TEXT, + 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_ENCODING, + CMD_APPEARANCE_FONTINC, CMD_APPEARANCE_FONTDEC, CMD_APPEARANCE_CAPACITYINC, CMD_APPEARANCE_CAPACITYDEC, + CMD_PRINT, CMD_ABOUT }; /******************************************************************************************** - * EHexOperMode - Enum of the data operation mode, used in HEXMODIFYSTRUCT, * - * when HEXMODIFYSTRUCT::enModifyMode is MODIFY_OPERATION. * + * EHexCreateMode - Enum of HexCtrl creation mode. * ********************************************************************************************/ - enum class EHexOperMode : WORD + enum class EHexCreateMode : WORD { - OPER_OR = 0x01, OPER_XOR, OPER_AND, OPER_NOT, OPER_SHL, OPER_SHR, - OPER_ADD, OPER_SUBTRACT, OPER_MULTIPLY, OPER_DIVIDE + CREATE_CHILD, CREATE_POPUP, CREATE_CUSTOMCTRL + }; + + /******************************************************************************************** + * EHexShowMode - current data mode representation. * + ********************************************************************************************/ + enum class EHexShowMode : WORD + { + ASBYTE = 1, ASWORD = 2, ASDWORD = 4, ASQWORD = 8 + }; + + /******************************************************************************************** + * EHexDataMode - Enum of the working data mode, used in HEXDATASTRUCT in SetData. * + * DATA_MEMORY: Default standard data mode. * + * DATA_MSG: Data is handled through WM_NOTIFY messages in handler window. * + * DATA_VIRTUAL: Data is handled through IHexVirtData interface by derived class. * + ********************************************************************************************/ + enum class EHexDataMode : WORD + { + DATA_MEMORY, DATA_MSG, DATA_VIRTUAL + }; + + /******************************************************************************************** + * EHexDlg - control's modeless dialogs. * + ********************************************************************************************/ + enum class EHexDlg : WORD + { + DLG_BKMMANAGER, DLG_DATAINTERPRET, DLG_FILLDATA, DLG_OPERS, DLG_SEARCH, DLG_ENCODING }; /******************************************************************************************** @@ -61,31 +102,21 @@ namespace HEXCTRL }; /******************************************************************************************** - * HEXBOOKMARKSTRUCT - Bookmarks. * + * HEXBKMSTRUCT - Bookmarks. * ********************************************************************************************/ - struct HEXBOOKMARKSTRUCT + struct HEXBKMSTRUCT { std::vector vecSpan { }; //Vector of offsets and sizes. - std::wstring wstrDesc { }; //Description. + 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. - DWORD dwID { }; //Bookmark id. Must be 0. Assigned internally by framework. }; + using PHEXBKMSTRUCT = HEXBKMSTRUCT*; /******************************************************************************************** - * HEXMODIFYSTRUCT - used to represent data modification parameters. * - ********************************************************************************************/ - struct HEXMODIFYSTRUCT - { - 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 vecSpan { }; //Vector of data offsets and sizes. - }; - - /******************************************************************************************** - * IHexVirtual - Pure abstract data handler class, that can be implemented by client, * + * IHexVirtData - Pure abstract data handler class, that can be implemented by client, * * to set its own data handler routines. Works in EHexDataMode::DATA_VIRTUAL mode. * * Pointer to this class can be set in IHexCtrl::SetData method. * * Its usage is very similar to DATA_MSG logic, where control sends WM_NOTIFY messages * @@ -93,35 +124,51 @@ namespace HEXCTRL * routine's implementation. * * All virtual functions must be defined in client's derived class. * ********************************************************************************************/ - class IHexVirtual + 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. + }; + + /******************************************************************************************** + * IHexVirtBkm - Pure abstract class for virtual bookmarks. * + ********************************************************************************************/ + class IHexVirtBkm { public: - virtual ~IHexVirtual() = default; - virtual BYTE GetByte(ULONGLONG ullIndex) = 0; //Gets the byte data by index. - virtual void ModifyData(const HEXMODIFYSTRUCT& hms) = 0; //Routine to modify data, if HEXDATASTRUCT::fMutable == true. + 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; //Does given offset have a bookmark? + virtual void RemoveByID(ULONGLONG ullID) = 0; //Remove bookmark by given ID (returned by Add()). + }; + + /******************************************************************************************** + * HEXCOLOR - used with the IHexVirtColors interface. * + ********************************************************************************************/ + struct HEXCOLOR + { + COLORREF clrBk { }; //Bk color. + COLORREF clrText { }; //Text color. }; + using PHEXCOLOR = HEXCOLOR*; /******************************************************************************************** - * IHexBkmVirtual - Pure abstract class for virtual bookmarks. * + * IHexVirtColors - Pure abstract class for chunk colors. * ********************************************************************************************/ - class IHexBkmVirtual + class IHexVirtColors { public: - virtual ~IHexBkmVirtual() = default; - virtual DWORD Add(const HEXBOOKMARKSTRUCT& stBookmark) = 0; //Add new bookmark, return new bookmark's ID. - virtual void ClearAll() = 0; //Clear all bookmarks. - virtual auto GetNext()->HEXBOOKMARKSTRUCT* = 0; //Get next bookmark. - virtual auto GetPrev()->HEXBOOKMARKSTRUCT* = 0; //Get previous bookmark. - virtual bool HasBookmarks() = 0; //Returns true is there is at least one bookmark atm. - virtual auto HitTest(ULONGLONG ullOffset)->HEXBOOKMARKSTRUCT* = 0; //Has given offset the bookmark? - virtual void Remove(ULONGLONG ullOffset) = 0; //Remove bookmark by the given offset. - virtual void RemoveId(DWORD dwId) = 0; //Remove bookmark by given ID (returned by Add()). + [[nodiscard]] virtual PHEXCOLOR GetColor(ULONGLONG ullOffset) = 0; }; /******************************************************************************************** - * HEXCOLORSTRUCT - All HexCtrl colors. * + * HEXCOLORSSTRUCT - All HexCtrl colors. * ********************************************************************************************/ - struct HEXCOLORSTRUCT + struct HEXCOLORSSTRUCT { COLORREF clrTextHex { GetSysColor(COLOR_WINDOWTEXT) }; //Hex chunks text color. COLORREF clrTextAscii { GetSysColor(COLOR_WINDOWTEXT) }; //Ascii text color. @@ -137,23 +184,7 @@ namespace HEXCTRL 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 text color. - }; - - /******************************************************************************************** - * EHexCreateMode - Enum of HexCtrl creation mode. * - ********************************************************************************************/ - enum class EHexCreateMode : DWORD - { - CREATE_CHILD, CREATE_POPUP, CREATE_CUSTOMCTRL - }; - - /******************************************************************************************** - * EHexShowMode - current data mode representation. * - ********************************************************************************************/ - enum class EHexShowMode : DWORD - { - ASBYTE = 1, ASWORD = 2, ASDWORD = 4, ASQWORD = 8 + COLORREF clrBkTooltip { GetSysColor(COLOR_INFOBK) }; //Tooltip background color. }; /******************************************************************************************** @@ -163,7 +194,7 @@ namespace HEXCTRL { EHexCreateMode enCreateMode { EHexCreateMode::CREATE_CHILD }; //Creation mode of the HexCtrl window. EHexShowMode enShowMode { EHexShowMode::ASBYTE }; //Data representation mode. - HEXCOLORSTRUCT stColor { }; //All the control's colors. + HEXCOLORSSTRUCT stColor { }; //All the control's colors. HWND hwndParent { }; //Parent window handle. 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. @@ -173,30 +204,21 @@ namespace HEXCTRL double dbWheelRatio { 1.0 }; //Ratio for how much to scroll with mouse-wheel. }; - /******************************************************************************************** - * EHexDataMode - Enum of the working data mode, used in HEXDATASTRUCT in SetData. * - * DATA_MEMORY: Default standard data mode. * - * DATA_MSG: Data is handled through WM_NOTIFY messages in handler window. * - * DATA_VIRTUAL: Data is handled through IHexVirtual interface by derived class. * - ********************************************************************************************/ - enum class EHexDataMode : DWORD - { - DATA_MEMORY, DATA_MSG, DATA_VIRTUAL - }; - /******************************************************************************************** * HEXDATASTRUCT - for IHexCtrl::SetData method. * ********************************************************************************************/ 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. - IHexVirtual* pHexVirtual { }; //Pointer for DATA_VIRTUAL mode. - IHexBkmVirtual* pHexBkmVirtual { }; //Pointer for Virtual Bookmarks. - PBYTE pData { }; //Data pointer for DATA_MEMORY mode. Not used in other modes. - bool fMutable { false }; //Is data mutable (editable) or read-only. + 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. }; /******************************************************************************************** @@ -205,46 +227,74 @@ namespace HEXCTRL 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). - const BYTE* pData { }; //Pointer to a data to get/send. + HEXSPANSTRUCT stSpan { }; //Offset and size of the bytes. + ULONGLONG ullData { }; //Data depending on message (e.g. user defined custom menu ID/caret pos). + std::byte* pData { }; //Pointer to a data to get/send. + POINT point { }; //Mouse position for menu notifications. }; using PHEXNOTIFYSTRUCT = HEXNOTIFYSTRUCT*; + /******************************************************************************************** + * HEXHITTESTSTRUCT - used in HitTest method. * + ********************************************************************************************/ + struct HEXHITTESTSTRUCT + { + ULONGLONG ullOffset { }; //Offset. + bool fIsAscii { false }; //Is cursor at ASCII part or at Hex. + }; + + /******************************************************************************************** * IHexCtrl - pure abstract base class. * ********************************************************************************************/ class IHexCtrl { public: - virtual ~IHexCtrl() = default; - virtual DWORD AddBookmark(const HEXBOOKMARKSTRUCT& hbs) = 0; //Adds new bookmark. - virtual void ClearData() = 0; //Clears all data from HexCtrl's view (not touching data itself). - virtual bool Create(const HEXCREATESTRUCT& hcs) = 0; //Main initialization method. + virtual ULONGLONG BkmAdd(const HEXBKMSTRUCT& hbs, bool fRedraw = false) = 0; //Adds new bookmark. + virtual void BkmClearAll() = 0; //Clear all bookmarks. + [[nodiscard]] virtual auto BkmGetByID(ULONGLONG ullID)->HEXBKMSTRUCT* = 0; //Get bookmark by ID. + [[nodiscard]] virtual auto BkmGetByIndex(ULONGLONG ullIndex)->HEXBKMSTRUCT* = 0; //Get bookmark by Index. + [[nodiscard]] virtual ULONGLONG BkmGetCount()const = 0; //Get bookmarks count. + [[nodiscard]] virtual auto BkmHitTest(ULONGLONG ullOffset)->HEXBKMSTRUCT* = 0; //HitTest for given offset. + virtual void BkmRemoveByID(ULONGLONG ullID) = 0; //Remove bookmark by the given ID. + virtual void BkmSetVirtual(bool fEnable, IHexVirtBkm* pVirtual = nullptr) = 0; //Enable/disable bookmarks virtual mode. + virtual void ClearData() = 0; //Clears all data from HexCtrl's view (not touching data itself). + virtual bool Create(const HEXCREATESTRUCT& hcs) = 0; //Main initialization method. virtual bool CreateDialogCtrl(UINT uCtrlID, HWND hwndDlg) = 0; //Đ¡reates custom dialog control. - virtual void Destroy() = 0; //Deleter. - virtual DWORD GetCapacity()const = 0; //Current capacity. - virtual auto GetColor()const->HEXCOLORSTRUCT = 0; //Current colors. - virtual long GetFontSize()const = 0; //Current font size. - virtual HMENU GetMenuHandle()const = 0; //Context menu handle. - virtual auto GetSelection()const->std::vector = 0; //Gets current selection. - virtual auto GetShowMode()const->EHexShowMode = 0; //Retrieves current show mode. - virtual HWND GetWindowHandle()const = 0; //Retrieves control's window handle. + virtual void Destroy() = 0; //Deleter. + virtual void ExecuteCmd(EHexCmd enCmd)const = 0; //Execute a command within the control. + [[nodiscard]] virtual DWORD GetCapacity()const = 0; //Current capacity. + [[nodiscard]] virtual ULONGLONG GetCaretPos()const = 0; //Cursor position. + [[nodiscard]] virtual auto GetColors()const->HEXCOLORSSTRUCT = 0; //Current colors. + [[nodiscard]] virtual int GetEncoding()const = 0; //Get current code page ID. + [[nodiscard]] virtual long GetFontSize()const = 0; //Current font size. + [[nodiscard]] virtual HMENU GetMenuHandle()const = 0; //Context menu handle. + [[nodiscard]] virtual DWORD GetSectorSize()const = 0; //Current sector size. + [[nodiscard]] virtual auto GetSelection()const->std::vector = 0; //Gets current selection. + [[nodiscard]] virtual auto GetShowMode()const->EHexShowMode = 0; //Retrieves current show mode. + [[nodiscard]] virtual HWND GetWindowHandle()const = 0; //Retrieves control's window handle. virtual void GoToOffset(ULONGLONG ullOffset, bool fSelect = false, ULONGLONG ullSize = 1) = 0; //Scrolls to given offset. - virtual bool IsCreated()const = 0; //Shows whether control is created or not. - virtual bool IsDataSet()const = 0; //Shows whether a data was set to the control or not. - virtual bool IsMutable()const = 0; //Is edit mode enabled or not. - virtual void RemoveBookmark(DWORD dwId) = 0; //Removes bookmark by the given Id. + [[nodiscard]] virtual auto HitTest(POINT pt, bool fScreen = true)const->std::optional = 0; //HitTest given point. + [[nodiscard]] virtual bool IsCmdAvail(EHexCmd enCmd)const = 0; //Is given Cmd currently available (can be executed)? + [[nodiscard]] virtual bool IsCreated()const = 0; //Shows whether control is created or not. + [[nodiscard]] virtual bool IsDataSet()const = 0; //Shows whether a data was set to the control or not. + [[nodiscard]] virtual bool IsDlgVisible(EHexDlg enDlg)const = 0; //Is specific dialog is currently visible. + [[nodiscard]] virtual bool IsMutable()const = 0; //Is edit mode enabled or not. + [[nodiscard]] virtual bool IsOffsetAsHex()const = 0; //Is "Offset" currently represented (shown) as Hex or as Decimal. + [[nodiscard]] virtual bool IsOffsetVisible(ULONGLONG ullOffset)const = 0; //Ensures that given offset is visible. + virtual void Redraw() = 0; //Redraw the control's window. virtual void SetCapacity(DWORD dwCapacity) = 0; //Sets the control's current capacity. - virtual void SetColor(const HEXCOLORSTRUCT& clr) = 0; //Sets all the control's colors. + virtual void SetColors(const HEXCOLORSSTRUCT& clr) = 0;//Sets all the control's colors. virtual void SetData(const HEXDATASTRUCT& hds) = 0; //Main method for setting data to display (and edit). - virtual void SetFont(const LOGFONTW* pLogFontNew) = 0; //Sets the control's new font. This font has to be monospaced. + virtual void SetEncoding(int iCodePage) = 0; //Code page for text area. + virtual void SetFont(const LOGFONTW* pLogFont) = 0; //Sets the control's new font. This font has to be monospaced. virtual void SetFontSize(UINT uiSize) = 0; //Sets the control's font size. virtual void SetMutable(bool fEnable) = 0; //Enable or disable mutable/edit mode. - virtual void SetSectorSize(DWORD dwSize, const wchar_t* wstrName = L"Sector") = 0; //Sets sector/page size and name to draw the line between. - virtual void SetSelection(ULONGLONG ullOffset, ULONGLONG ullSize) = 0; //Sets current selection. + virtual void SetSectorSize(DWORD dwSize, std::wstring_view wstrName = L"Sector") = 0; //Sets sector/page size and name to draw the lines in-between. + virtual void SetSelection(const std::vector& vecSel) = 0; //Sets current selection. virtual void SetShowMode(EHexShowMode enMode) = 0; //Sets current data show mode. virtual void SetWheelRatio(double dbRatio) = 0; //Sets the ratio for how much to scroll with mouse-wheel. + virtual void ShowDlg(EHexDlg enDlg, bool fShow = true)const = 0; //Show/hide specific dialog. }; /******************************************************************************************** @@ -325,14 +375,15 @@ namespace HEXCTRL * These codes are used to notify m_hwndMsg window about control's states. * ********************************************************************************************/ - constexpr auto HEXCTRL_MSG_CARETCHANGE { 0x0100u }; //Caret position changed. - constexpr auto HEXCTRL_MSG_CONTEXTMENU { 0x0101u }; //OnContextMenu triggered. - constexpr auto HEXCTRL_MSG_DATACHANGE { 0x0102u }; //Indicates that the data has changed, used with the HEXMODIFYSTRUCT*. - constexpr auto HEXCTRL_MSG_DESTROY { 0x0103u }; //Indicates that HexCtrl is being destroyed. - constexpr auto HEXCTRL_MSG_GETDATA { 0x0104u }; //Used in DATA_MSG mode to acquire the next byte to display. - constexpr auto HEXCTRL_MSG_MENUCLICK { 0x0105u }; //User defined custom menu clicked. - constexpr auto HEXCTRL_MSG_SELECTION { 0x0106u }; //Selection has been made. - constexpr auto HEXCTRL_MSG_VIEWCHANGE { 0x0107u }; //View of the control has changed. + constexpr auto HEXCTRL_MSG_BKMCLICK { 0x0100U }; //Bookmark clicked. + constexpr auto HEXCTRL_MSG_CARETCHANGE { 0x0101U }; //Caret position changed. + constexpr auto HEXCTRL_MSG_CONTEXTMENU { 0x0102U }; //OnContextMenu triggered. + constexpr auto HEXCTRL_MSG_DESTROY { 0x0103U }; //Indicates that HexCtrl is being destroyed. + constexpr auto HEXCTRL_MSG_GETDATA { 0x0104U }; //Used in DATA_MSG mode to request the data to display. + constexpr auto HEXCTRL_MSG_MENUCLICK { 0x0105U }; //User defined custom menu clicked. + constexpr auto HEXCTRL_MSG_SELECTION { 0x0106U }; //Selection has been made. + constexpr auto HEXCTRL_MSG_SETDATA { 0x0107U }; //Indicates that the data has changed. + constexpr auto HEXCTRL_MSG_VIEWCHANGE { 0x0108U }; //View of the control has changed. /*******************Setting a manifest for ComCtl32.dll version 6.***********************/ #ifdef _UNICODE diff --git a/Pepper/include/MainFrm.h b/Pepper/include/MainFrm.h index 961fd76..d44112a 100644 --- a/Pepper/include/MainFrm.h +++ b/Pepper/include/MainFrm.h @@ -7,27 +7,32 @@ * https://github.com/jovibor/libpe * ****************************************************************************************************/ #pragma once +#include "constants.h" class CMainFrame : public CMDIFrameWndEx -{ +{ DECLARE_DYNAMIC(CMainFrame) - CMainFrame() {} - virtual ~CMainFrame() {} - BOOL LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, - CWnd* pParentWnd = nullptr, CCreateContext* pContext = nullptr) override; + BOOL LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, + CWnd* pParentWnd = nullptr, CCreateContext* pContext = nullptr)override; + int& GetChildFramesCount(); + void SetCurrFramePtrNull(); protected: - BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) override; - BOOL PreCreateWindow(CREATESTRUCT& cs) override; + BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)override; + BOOL PreCreateWindow(CREATESTRUCT& cs)override; virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnWindowManager(); afx_msg void OnDropFiles(HDROP hDropInfo); afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); - CMFCToolBar m_wndToolBar; - DECLARE_MESSAGE_MAP() -private: - CWnd* pwndMBtnCurDown { }; -public: afx_msg void OnAppEditmode(); afx_msg void OnUpdateAppEditmode(CCmdUI *pCmdUI); + LRESULT OnTabActivate(WPARAM wParam, LPARAM lParam); + afx_msg void OnClose(); + DECLARE_MESSAGE_MAP() +private: + CMFCToolBar m_wndToolBar; + CWnd* pWndMBtnCurDown { }; + std::vector* m_pCurrFrameData { }; + int m_iChildFrames { }; //Amount of active child frames. + bool m_fClosing { false }; //Indicates that thr app is closing now, to avoid dialogs' flickering on exit. }; diff --git a/Pepper/include/PepperDoc.h b/Pepper/include/PepperDoc.h index cd076d7..1dab651 100644 --- a/Pepper/include/PepperDoc.h +++ b/Pepper/include/PepperDoc.h @@ -16,13 +16,11 @@ class CPepperDoc : public CDocument { public: DECLARE_DYNCREATE(CPepperDoc) - libpe_ptr m_pLibpe {}; + libpe_ptr m_pLibpe { }; CFileLoader m_stFileLoader; void SetEditMode(bool fEditMode); bool IsEditMode() { return m_fEditMode; } private: - CPepperDoc() {} - virtual ~CPepperDoc() {} BOOL OnOpenDocument(LPCTSTR lpszPathName) override; virtual void OnCloseDocument(); bool m_fEditMode { false }; diff --git a/Pepper/include/ViewRightBR.h b/Pepper/include/ViewRightBR.h index b187818..be7cf3d 100644 --- a/Pepper/include/ViewRightBR.h +++ b/Pepper/include/ViewRightBR.h @@ -15,38 +15,39 @@ using namespace LISTEX; -class CWndDlgSample : public CWnd +class CDlgSampleWnd : public CWnd { public: - explicit CWndDlgSample(CImageList* pImgList) { m_pImgRes = pImgList; } - virtual ~CWndDlgSample() {} + void Attach(CImageList* pImgList, CChildFrame* pChildFrame); + void SetDlgVisible(bool fVisible); DECLARE_MESSAGE_MAP() private: afx_msg void OnPaint(); private: CImageList* m_pImgRes { }; + CChildFrame* m_pChildFrame { }; +public: + afx_msg void OnClose(); }; class CViewRightBR : public CScrollView { DECLARE_DYNCREATE(CViewRightBR) protected: - CViewRightBR() :m_wndDlgSample(&m_stImgRes) {} //Initializing Dialog Sample Window's image list. - virtual ~CViewRightBR() {} virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual void OnInitialUpdate(); // first time after construct afx_msg void OnSize(UINT nType, int cx, int cy); virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/); - void ShowResource(const RESHELPER*); - void CreateIconCursor(const RESHELPER* pResHelper); - void CreateBitmap(const RESHELPER* pResHelper); - void CreateDlg(const RESHELPER* pResHelper); + void ShowResource(const SRESHELPER*); + void CreateIconCursor(const SRESHELPER* pResHelper); + void CreateBitmap(const SRESHELPER* pResHelper); + void CreateDlg(const SRESHELPER* pResHelper); void ParceDlgTemplate(PBYTE pDataDlgRes, size_t nSize, std::wstring& wstrData); - void CreateStrings(const RESHELPER* pResHelper); - void CreateGroupIconCursor(const RESHELPER* pResHelper); - void CreateVersion(const RESHELPER* pResHelper); - void CreateManifest(const RESHELPER* pResHelper); - void CreateToolbar(const RESHELPER* pResHelper); + void CreateStrings(const SRESHELPER* pResHelper); + void CreateGroupIconCursor(const SRESHELPER* pResHelper); + void CreateVersion(const SRESHELPER* pResHelper); + void CreateManifest(const SRESHELPER* pResHelper); + void CreateToolbar(const SRESHELPER* pResHelper); int CreateListTLSCallbacks(); void ResLoadError(); void CreateDebugEntry(DWORD dwEntry); @@ -59,7 +60,7 @@ class CViewRightBR : public CScrollView DWORD m_dwStyles { WS_POPUP | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX }; DWORD m_dwExStyles { WS_EX_APPWINDOW }; CImageList m_stImgRes; - CWndDlgSample m_wndDlgSample; + CDlgSampleWnd m_DlgSampleWnd; LISTEXCREATESTRUCT m_stlcs; IListExPtr m_stListTLSCallbacks { CreateListEx() }; LOGFONTW m_lf { }, m_hdrlf { }; diff --git a/Pepper/include/ViewRightTL.h b/Pepper/include/ViewRightTL.h index 03a8f63..899f996 100644 --- a/Pepper/include/ViewRightTL.h +++ b/Pepper/include/ViewRightTL.h @@ -34,6 +34,12 @@ class CViewRightTL : public CView afx_msg void OnListImportGetDispInfo(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnListRelocsGetDispInfo(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnListExceptionsGetDispInfo(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListExportMenuSelect(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListImportNotify(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListTLSMenuSelect(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListBoundImpMenuSelect(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnListCOMDescMenuSelect(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnTreeResTopSelChange(NMHDR *pNMHDR, LRESULT *pResult); void SortImportData(); DECLARE_MESSAGE_MAP() private: diff --git a/Pepper/include/ViewRightTR.h b/Pepper/include/ViewRightTR.h index ecc4282..b208d40 100644 --- a/Pepper/include/ViewRightTR.h +++ b/Pepper/include/ViewRightTR.h @@ -25,7 +25,7 @@ class CViewRightTR : public CView afx_msg void OnSize(UINT nType, int cx, int cy); virtual BOOL PreCreateWindow(CREATESTRUCT& cs); void OnDocEditMode(); - void CreateHexResources(PIMAGE_RESOURCE_DATA_ENTRY); + void CreateHexResources(const IMAGE_RESOURCE_DATA_ENTRY* pRes); DECLARE_MESSAGE_MAP() private: libpe_ptr m_pLibpe; diff --git a/Pepper/include/constants.h b/Pepper/include/constants.h index 68e8477..d37f4f9 100644 --- a/Pepper/include/constants.h +++ b/Pepper/include/constants.h @@ -81,13 +81,13 @@ inline const std::map g_mapResType { //Helper struct for PE structs' fields offsets and sizes. //Reflection kind of. -struct PESTRUCTREFLECTION +struct SPEREFLECTION { DWORD dwSize; //Struct's field size. DWORD dwOffset; //Field offset. std::wstring wstrName; //Field name. }; -using map_hdr = std::map; +using map_hdr = std::map; //Standard headers' maps. inline const map_hdr g_mapDOSHeader { @@ -368,17 +368,22 @@ inline const map_hdr g_mapComDir { }; //////////////////////////////////////////////////////////// -//Helper struct for resources interchange -//between views. -struct RESHELPER +//Helper struct for resources interchange between views. +struct SRESHELPER { - RESHELPER() {} - RESHELPER(WORD type, WORD name, std::vector* data) : IdResType(type), IdResName(name), pData(data) {} + SRESHELPER() {} + SRESHELPER(WORD type, WORD name, std::vector* data) : IdResType(type), IdResName(name), pData(data) {} WORD IdResType { }; WORD IdResName { }; std::vector* pData { }; }; +struct SWINDOWSTATUS +{ + CWnd* pWnd { }; + bool fVisible { }; +}; + /***************************************************************** * These are identificators of all the controls: list, hex, tree. * *****************************************************************/ diff --git a/Pepper/include/libpe.h b/Pepper/include/libpe.h index fbe6435..7795051 100644 --- a/Pepper/include/libpe.h +++ b/Pepper/include/libpe.h @@ -5,11 +5,11 @@ * This software is available under the "MIT License". * ****************************************************************************************/ #pragma once -#include //std::vector and related. +#include //WIN_CERTIFICATE struct. +#include //All standard Windows' typedefs. #include //std::shared_ptr and related. #include //std::string and related. -#include //All standard Windows' typedefs. -#include //WIN_CERTIFICATE struct. +#include //std::vector and related. #ifndef __cpp_lib_byte #define __cpp17_conformant 0 @@ -306,31 +306,30 @@ namespace libpe { class Ilibpe { public: - virtual ~Ilibpe() = default; - virtual HRESULT LoadPe(LPCWSTR) = 0; - virtual HRESULT GetImageInfo(DWORD&)noexcept = 0; - virtual HRESULT GetImageFlag(DWORD dwFlag, bool& f)noexcept = 0; + virtual HRESULT LoadPe(LPCWSTR pwszFilePath) = 0; + virtual HRESULT GetImageInfo(DWORD& dwInfo)noexcept = 0; + virtual HRESULT GetImageFlag(DWORD dwFlag, bool& f)const noexcept = 0; virtual HRESULT GetOffsetFromRVA(ULONGLONG ullRVA, DWORD& dwOffset)noexcept = 0; - virtual HRESULT GetOffsetFromVA(ULONGLONG ullVA, DWORD& dwOffset)noexcept = 0; - virtual HRESULT GetMSDOSHeader(PLIBPE_DOSHEADER&)noexcept = 0; - virtual HRESULT GetRichHeader(PLIBPE_RICHHEADER_VEC&)noexcept = 0; - virtual HRESULT GetNTHeader(PLIBPE_NTHEADER&)noexcept = 0; - virtual HRESULT GetFileHeader(PLIBPE_FILEHEADER&)noexcept = 0; - virtual HRESULT GetOptionalHeader(PLIBPE_OPTHEADER_VAR&)noexcept = 0; - virtual HRESULT GetDataDirectories(PLIBPE_DATADIRS_VEC&)noexcept = 0; - virtual HRESULT GetSectionsHeaders(PLIBPE_SECHEADERS_VEC&)noexcept = 0; - virtual HRESULT GetExport(PLIBPE_EXPORT&)noexcept = 0; - virtual HRESULT GetImport(PLIBPE_IMPORT_VEC&)noexcept = 0; - virtual HRESULT GetResources(PLIBPE_RESOURCE_ROOT&)noexcept = 0; - virtual HRESULT GetExceptions(PLIBPE_EXCEPTION_VEC&)noexcept = 0; - virtual HRESULT GetSecurity(PLIBPE_SECURITY_VEC&)noexcept = 0; - virtual HRESULT GetRelocations(PLIBPE_RELOCATION_VEC&)noexcept = 0; - virtual HRESULT GetDebug(PLIBPE_DEBUG_VEC&)noexcept = 0; - virtual HRESULT GetTLS(PLIBPE_TLS&)noexcept = 0; - virtual HRESULT GetLoadConfig(PLIBPE_LOADCONFIG&)noexcept = 0; - virtual HRESULT GetBoundImport(PLIBPE_BOUNDIMPORT_VEC&)noexcept = 0; - virtual HRESULT GetDelayImport(PLIBPE_DELAYIMPORT_VEC&)noexcept = 0; - virtual HRESULT GetCOMDescriptor(PLIBPE_COMDESCRIPTOR&)noexcept = 0; + virtual HRESULT GetOffsetFromVA(ULONGLONG ullVA, DWORD& dwOffset)noexcept = 0; + virtual HRESULT GetMSDOSHeader(PLIBPE_DOSHEADER& pDosHeader)noexcept = 0; + virtual HRESULT GetRichHeader(PLIBPE_RICHHEADER_VEC& pVecRich)noexcept = 0; + virtual HRESULT GetNTHeader(PLIBPE_NTHEADER& pVarNTHdr)noexcept = 0; + virtual HRESULT GetFileHeader(PLIBPE_FILEHEADER& pFileHeader)noexcept = 0; + virtual HRESULT GetOptionalHeader(PLIBPE_OPTHEADER_VAR& pVarOptHeader)noexcept = 0; + virtual HRESULT GetDataDirectories(PLIBPE_DATADIRS_VEC& pVecDataDir)noexcept = 0; + virtual HRESULT GetSectionsHeaders(PLIBPE_SECHEADERS_VEC& pVecSections)noexcept = 0; + virtual HRESULT GetExport(PLIBPE_EXPORT& pExport)noexcept = 0; + virtual HRESULT GetImport(PLIBPE_IMPORT_VEC& pVecImport)noexcept = 0; + virtual HRESULT GetResources(PLIBPE_RESOURCE_ROOT& pResRoot)noexcept = 0; + virtual HRESULT GetExceptions(PLIBPE_EXCEPTION_VEC& pVecException)noexcept = 0; + virtual HRESULT GetSecurity(PLIBPE_SECURITY_VEC& pVecSecurity)noexcept = 0; + virtual HRESULT GetRelocations(PLIBPE_RELOCATION_VEC& pVecRelocs)noexcept = 0; + virtual HRESULT GetDebug(PLIBPE_DEBUG_VEC& pVecDebug)noexcept = 0; + virtual HRESULT GetTLS(PLIBPE_TLS& pTLS)noexcept = 0; + virtual HRESULT GetLoadConfig(PLIBPE_LOADCONFIG& pLCD)noexcept = 0; + virtual HRESULT GetBoundImport(PLIBPE_BOUNDIMPORT_VEC& pVecBoundImp)noexcept = 0; + virtual HRESULT GetDelayImport(PLIBPE_DELAYIMPORT_VEC& pVecDelayImp)noexcept = 0; + virtual HRESULT GetCOMDescriptor(PLIBPE_COMDESCRIPTOR& pCOMDesc)noexcept = 0; virtual HRESULT Destroy() = 0; }; @@ -338,66 +337,66 @@ namespace libpe { * Return errors. * *************************************************/ - constexpr auto E_CALL_LOADPE_FIRST = 0xFFFFu; - constexpr auto E_FILE_CREATEFILE_FAILED = 0x0010u; - constexpr auto E_FILE_SIZE_TOO_SMALL = 0x0011u; - constexpr auto E_FILE_CREATEFILEMAPPING_FAILED = 0x0012u; + constexpr auto E_CALL_LOADPE_FIRST = 0xFFFFU; + constexpr auto E_FILE_CREATEFILE_FAILED = 0x0010U; + constexpr auto E_FILE_SIZE_TOO_SMALL = 0x0011U; + constexpr auto E_FILE_CREATEFILEMAPPING_FAILED = 0x0012U; constexpr auto E_FILE_MAPVIEWOFFILE_FAILED = 0x0013; - constexpr auto E_FILE_MAPVIEWOFFILE_SECTION_FAILED = 0x0014u; - constexpr auto E_FILE_SECTION_DATA_CORRUPTED = 0x0015u; - constexpr auto E_IMAGE_TYPE_UNSUPPORTED = 0x0016u; - constexpr auto E_IMAGE_HAS_NO_DOSHEADER = 0x0017u; - constexpr auto E_IMAGE_HAS_NO_RICHHEADER = 0x0018u; - constexpr auto E_IMAGE_HAS_NO_NTHEADER = 0x0019u; - constexpr auto E_IMAGE_HAS_NO_FILEHEADER = 0x001Au; - constexpr auto E_IMAGE_HAS_NO_OPTHEADER = 0x001Bu; - constexpr auto E_IMAGE_HAS_NO_DATADIRECTORIES = 0x001Cu; - constexpr auto E_IMAGE_HAS_NO_SECTIONS = 0x001Du; - constexpr auto E_IMAGE_HAS_NO_EXPORT = 0x001Eu; - constexpr auto E_IMAGE_HAS_NO_IMPORT = 0x001Fu; - constexpr auto E_IMAGE_HAS_NO_RESOURCE = 0x0020u; - constexpr auto E_IMAGE_HAS_NO_EXCEPTION = 0x0021u; - constexpr auto E_IMAGE_HAS_NO_SECURITY = 0x0022u; - constexpr auto E_IMAGE_HAS_NO_BASERELOC = 0x0023u; - constexpr auto E_IMAGE_HAS_NO_DEBUG = 0x0024u; - constexpr auto E_IMAGE_HAS_NO_ARCHITECTURE = 0x0025u; - constexpr auto E_IMAGE_HAS_NO_GLOBALPTR = 0x0026u; - constexpr auto E_IMAGE_HAS_NO_TLS = 0x0027u; - constexpr auto E_IMAGE_HAS_NO_LOADCONFIG = 0x0028u; - constexpr auto E_IMAGE_HAS_NO_BOUNDIMPORT = 0x0029u; - constexpr auto E_IMAGE_HAS_NO_IAT = 0x002Au; - constexpr auto E_IMAGE_HAS_NO_DELAYIMPORT = 0x002Bu; - constexpr auto E_IMAGE_HAS_NO_COMDESCRIPTOR = 0x002Cu; + constexpr auto E_FILE_MAPVIEWOFFILE_SECTION_FAILED = 0x0014U; + constexpr auto E_FILE_SECTION_DATA_CORRUPTED = 0x0015U; + constexpr auto E_IMAGE_TYPE_UNSUPPORTED = 0x0016U; + constexpr auto E_IMAGE_HAS_NO_DOSHEADER = 0x0017U; + constexpr auto E_IMAGE_HAS_NO_RICHHEADER = 0x0018U; + constexpr auto E_IMAGE_HAS_NO_NTHEADER = 0x0019U; + constexpr auto E_IMAGE_HAS_NO_FILEHEADER = 0x001AU; + constexpr auto E_IMAGE_HAS_NO_OPTHEADER = 0x001BU; + constexpr auto E_IMAGE_HAS_NO_DATADIRECTORIES = 0x001CU; + constexpr auto E_IMAGE_HAS_NO_SECTIONS = 0x001DU; + constexpr auto E_IMAGE_HAS_NO_EXPORT = 0x001EU; + constexpr auto E_IMAGE_HAS_NO_IMPORT = 0x001FU; + constexpr auto E_IMAGE_HAS_NO_RESOURCE = 0x0020U; + constexpr auto E_IMAGE_HAS_NO_EXCEPTION = 0x0021U; + constexpr auto E_IMAGE_HAS_NO_SECURITY = 0x0022U; + constexpr auto E_IMAGE_HAS_NO_BASERELOC = 0x0023U; + constexpr auto E_IMAGE_HAS_NO_DEBUG = 0x0024U; + constexpr auto E_IMAGE_HAS_NO_ARCHITECTURE = 0x0025U; + constexpr auto E_IMAGE_HAS_NO_GLOBALPTR = 0x0026U; + constexpr auto E_IMAGE_HAS_NO_TLS = 0x0027U; + constexpr auto E_IMAGE_HAS_NO_LOADCONFIG = 0x0028U; + constexpr auto E_IMAGE_HAS_NO_BOUNDIMPORT = 0x0029U; + constexpr auto E_IMAGE_HAS_NO_IAT = 0x002AU; + constexpr auto E_IMAGE_HAS_NO_DELAYIMPORT = 0x002BU; + constexpr auto E_IMAGE_HAS_NO_COMDESCRIPTOR = 0x002CU; /***************************************************** * Flags according to loaded PE file properties. * *****************************************************/ //Tiny function shows whether given DWORD has given flag. constexpr bool ImageHasFlag(DWORD dwFileInfo, DWORD dwFlag) { return dwFileInfo & dwFlag; }; - constexpr auto IMAGE_FLAG_PE32 = 0x00000001ul; - constexpr auto IMAGE_FLAG_PE64 = 0x00000002ul; - constexpr auto IMAGE_FLAG_DOSHEADER = 0x00000004ul; - constexpr auto IMAGE_FLAG_RICHHEADER = 0x00000008ul; - constexpr auto IMAGE_FLAG_NTHEADER = 0x00000010ul; - constexpr auto IMAGE_FLAG_FILEHEADER = 0x00000020ul; - constexpr auto IMAGE_FLAG_OPTHEADER = 0x00000040ul; - constexpr auto IMAGE_FLAG_DATADIRECTORIES = 0x00000080ul; - constexpr auto IMAGE_FLAG_SECTIONS = 0x00000100ul; - constexpr auto IMAGE_FLAG_EXPORT = 0x00000200ul; - constexpr auto IMAGE_FLAG_IMPORT = 0x00000400ul; - constexpr auto IMAGE_FLAG_RESOURCE = 0x00000800ul; - constexpr auto IMAGE_FLAG_EXCEPTION = 0x00001000ul; - constexpr auto IMAGE_FLAG_SECURITY = 0x00002000ul; - constexpr auto IMAGE_FLAG_BASERELOC = 0x00004000ul; - constexpr auto IMAGE_FLAG_DEBUG = 0x00008000ul; - constexpr auto IMAGE_FLAG_ARCHITECTURE = 0x00010000ul; - constexpr auto IMAGE_FLAG_GLOBALPTR = 0x00020000ul; - constexpr auto IMAGE_FLAG_TLS = 0x00040000ul; - constexpr auto IMAGE_FLAG_LOADCONFIG = 0x00080000ul; - constexpr auto IMAGE_FLAG_BOUNDIMPORT = 0x00100000ul; - constexpr auto IMAGE_FLAG_IAT = 0x00200000ul; - constexpr auto IMAGE_FLAG_DELAYIMPORT = 0x00400000ul; - constexpr auto IMAGE_FLAG_COMDESCRIPTOR = 0x00800000ul; + constexpr auto IMAGE_FLAG_PE32 = 0x00000001UL; + constexpr auto IMAGE_FLAG_PE64 = 0x00000002UL; + constexpr auto IMAGE_FLAG_DOSHEADER = 0x00000004UL; + constexpr auto IMAGE_FLAG_RICHHEADER = 0x00000008UL; + constexpr auto IMAGE_FLAG_NTHEADER = 0x00000010UL; + constexpr auto IMAGE_FLAG_FILEHEADER = 0x00000020UL; + constexpr auto IMAGE_FLAG_OPTHEADER = 0x00000040UL; + constexpr auto IMAGE_FLAG_DATADIRECTORIES = 0x00000080UL; + constexpr auto IMAGE_FLAG_SECTIONS = 0x00000100UL; + constexpr auto IMAGE_FLAG_EXPORT = 0x00000200UL; + constexpr auto IMAGE_FLAG_IMPORT = 0x00000400UL; + constexpr auto IMAGE_FLAG_RESOURCE = 0x00000800UL; + constexpr auto IMAGE_FLAG_EXCEPTION = 0x00001000UL; + constexpr auto IMAGE_FLAG_SECURITY = 0x00002000UL; + constexpr auto IMAGE_FLAG_BASERELOC = 0x00004000UL; + constexpr auto IMAGE_FLAG_DEBUG = 0x00008000UL; + constexpr auto IMAGE_FLAG_ARCHITECTURE = 0x00010000UL; + constexpr auto IMAGE_FLAG_GLOBALPTR = 0x00020000UL; + constexpr auto IMAGE_FLAG_TLS = 0x00040000UL; + constexpr auto IMAGE_FLAG_LOADCONFIG = 0x00080000UL; + constexpr auto IMAGE_FLAG_BOUNDIMPORT = 0x00100000UL; + constexpr auto IMAGE_FLAG_IAT = 0x00200000UL; + constexpr auto IMAGE_FLAG_DELAYIMPORT = 0x00400000UL; + constexpr auto IMAGE_FLAG_COMDESCRIPTOR = 0x00800000UL; /******************************************************************************************** * Factory function Createlibpe returns IlibpeUnPtr - unique_ptr with custom deleter. * @@ -434,17 +433,17 @@ namespace libpe { #pragma comment(lib, LIBNAME_PROPER("libpe")) #endif - extern "C" ILIBPEAPI HRESULT __cdecl CreateRawlibpe(Ilibpe*&); + extern "C" ILIBPEAPI HRESULT __cdecl CreateRawlibpe(Ilibpe*& pLibpe); using IlibpeUnPtr = std::unique_ptr; using IlibpeShPtr = std::shared_ptr; inline IlibpeUnPtr Createlibpe() { - Ilibpe* ptr { }; - if (CreateRawlibpe(ptr) == S_OK) - return IlibpeUnPtr(ptr, [](Ilibpe * p) { p->Destroy(); }); - else - return IlibpeUnPtr(nullptr, nullptr); + Ilibpe* pLibpe { }; + if (CreateRawlibpe(pLibpe) == S_OK) + return IlibpeUnPtr(pLibpe, [](Ilibpe * p) { p->Destroy(); }); + + return { nullptr, nullptr }; }; //using libpe_ptr = IlibpeUnPtr; diff --git a/Pepper/lib/HexCtrl64.lib b/Pepper/lib/HexCtrl64.lib index 64349ab..a9b6881 100644 Binary files a/Pepper/lib/HexCtrl64.lib and b/Pepper/lib/HexCtrl64.lib differ diff --git a/Pepper/verinfo/version.h b/Pepper/verinfo/version.h index 4ec8f19..ecc0ea4 100644 --- a/Pepper/verinfo/version.h +++ b/Pepper/verinfo/version.h @@ -3,5 +3,5 @@ #define COPYRIGHT_NAME "(C) Jovibor 2019" #define MAJOR_VERSION 1 #define MINOR_VERSION 2 -#define MAINTENANCE_VERSION 2 +#define MAINTENANCE_VERSION 3 #define REVISION_VERSION 0