From be083ab26ba7949c21a5dfc34e33929f6832ed25 Mon Sep 17 00:00:00 2001 From: Jovibor Date: Fri, 3 Jan 2025 21:03:19 +1000 Subject: [PATCH] Added new DestroyWindow() method to the interface. Destroy() method renamed to Delete(). New DestroyDlg methods added to all dialogs. These methods are now invoked from the CHexCtrl::OnDestroy(), to make sure the dialogs are always properly destroyed. --- HexCtrl/HexCtrl.h | 5 +- HexCtrl/src/CHexCtrl.cpp | 35 +++++++++--- HexCtrl/src/CHexCtrl.h | 4 +- HexCtrl/src/Dialogs/CHexDlgBkmMgr.cpp | 67 +++++++++++++---------- HexCtrl/src/Dialogs/CHexDlgBkmMgr.h | 1 + HexCtrl/src/Dialogs/CHexDlgCodepage.cpp | 9 ++- HexCtrl/src/Dialogs/CHexDlgCodepage.h | 1 + HexCtrl/src/Dialogs/CHexDlgDataInterp.cpp | 17 ++++-- HexCtrl/src/Dialogs/CHexDlgDataInterp.h | 1 + HexCtrl/src/Dialogs/CHexDlgGoTo.cpp | 9 ++- HexCtrl/src/Dialogs/CHexDlgGoTo.h | 1 + HexCtrl/src/Dialogs/CHexDlgModify.cpp | 7 +++ HexCtrl/src/Dialogs/CHexDlgModify.h | 1 + HexCtrl/src/Dialogs/CHexDlgSearch.cpp | 9 ++- HexCtrl/src/Dialogs/CHexDlgSearch.h | 1 + HexCtrl/src/Dialogs/CHexDlgTemplMgr.cpp | 9 ++- HexCtrl/src/Dialogs/CHexDlgTemplMgr.h | 1 + README.md | 16 ++++-- 18 files changed, 137 insertions(+), 57 deletions(-) diff --git a/HexCtrl/HexCtrl.h b/HexCtrl/HexCtrl.h index 5cf2123..4f821ec 100644 --- a/HexCtrl/HexCtrl.h +++ b/HexCtrl/HexCtrl.h @@ -403,7 +403,8 @@ namespace HEXCTRL { virtual void ClearData() = 0; //Clears all data from HexCtrl's view (not touching data itself). virtual bool Create(const HEXCREATE& hcs) = 0; //Main initialization method. virtual bool CreateDialogCtrl(UINT uCtrlID, HWND hWndParent) = 0; //Сreates custom dialog control. - virtual void Destroy() = 0; //Deleter. + virtual void Delete() = 0; //IHexCtrl object deleter. + virtual void DestroyWindow() = 0; //Destroy HexCtrl window. virtual void ExecuteCmd(EHexCmd eCmd) = 0; //Execute a command within HexCtrl. [[nodiscard]] virtual auto GetActualWidth()const->int = 0; //Working area actual width. [[nodiscard]] virtual auto GetBookmarks()const->IHexBookmarks* = 0; //Get Bookmarks interface. @@ -466,7 +467,7 @@ namespace HEXCTRL { virtual void ShowInfoBar(bool fShow) = 0; //Show/hide bottom Info bar. }; - struct IHexCtrlDeleter { void operator()(IHexCtrl* p)const { p->Destroy(); } }; + struct IHexCtrlDeleter { void operator()(IHexCtrl* p)const { p->Delete(); } }; using IHexCtrlPtr = std::unique_ptr; [[nodiscard]] HEXCTRLAPI IHexCtrlPtr CreateHexCtrl(); diff --git a/HexCtrl/src/CHexCtrl.cpp b/HexCtrl/src/CHexCtrl.cpp index 0919956..6a6f5cb 100644 --- a/HexCtrl/src/CHexCtrl.cpp +++ b/HexCtrl/src/CHexCtrl.cpp @@ -458,14 +458,20 @@ bool CHexCtrl::CreateDialogCtrl(UINT uCtrlID, HWND hWndParent) return Create({ .hWndParent { hWndParent }, .uID { uCtrlID }, .fCustom { true } }); } -void CHexCtrl::Destroy() +void CHexCtrl::Delete() { + //At this point the HexCtrl window should be destroyed anyway. + //This call is just to make sure it is. + DestroyWindow(); + delete this; } void CHexCtrl::DestroyWindow() { - m_Wnd.DestroyWindow(); + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } } void CHexCtrl::ExecuteCmd(EHexCmd eCmd) @@ -1465,9 +1471,6 @@ void CHexCtrl::ModifyData(const HEXMODIFY& hms) bool CHexCtrl::PreTranslateMsg(MSG* pMsg) { - //The common if(!IsCreated()) check is ommited here for max throughput. - assert(IsCreated()); - if (m_pDlgBkmMgr->PreTranslateMsg(pMsg)) { return true; } if (m_pDlgDataInterp->PreTranslateMsg(pMsg)) { return true; } if (m_pDlgModify->PreTranslateMsg(pMsg)) { return true; } @@ -6900,16 +6903,30 @@ auto CHexCtrl::OnContextMenu(const MSG& msg)->LRESULT auto CHexCtrl::OnDestroy()->LRESULT { //All these cleanups below are important when HexCtrl window is destroyed but IHexCtrl object - //itself is still alive. The IHexCtrl object is alive until the IHexCtrl::Destroy() method is called. - //Child windows of IHexCtrl (dialogs, tooltips, etc...) will be destroyed automatically by Windows. + //itself is still alive. The IHexCtrl object is alive until the IHexCtrl::Delete() method is called. + //Child windows of the IHexCtrl (e.g. tooltips) will be destroyed automatically by Windows. + + //Note: The MSDN for the DestroyWindow clearly states that: + //"If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated + //child or owned windows when it destroys the parent or owner window. The function first destroys child or + //owned windows, and then it destroys the parent or owner window." + //But it doesn't seem to always be the case for owned dialog windows in some environments. + //These DestroyDlg() calls to make sure the dialogs are always properly destroyed. ClearData(); + m_pDlgBkmMgr->DestroyDlg(); + m_pDlgCodepage->DestroyDlg(); + m_pDlgDataInterp->DestroyDlg(); + m_pDlgModify->DestroyDlg(); + m_pDlgGoTo->DestroyDlg(); + m_pDlgSearch->DestroyDlg(); + m_pDlgTemplMgr->DestroyDlg(); + m_pDlgTemplMgr->UnloadAll(); //Templates could be loaded without creating the dialog itself. m_vecHBITMAP.clear(); m_vecKeyBind.clear(); m_vecUndo.clear(); m_vecRedo.clear(); m_vecCharsWidth.clear(); - m_pDlgTemplMgr->UnloadAll(); //Explicitly unloading all loaded Templates. m_MenuMain.DestroyMenu(); ::DeleteObject(m_hFntMain); ::DeleteObject(m_hFntInfoBar); @@ -6917,8 +6934,8 @@ auto CHexCtrl::OnDestroy()->LRESULT ::DeleteObject(m_hPenDataTempl); m_pScrollV->DestroyWindow(); //Not a child of the IHexCtrl. m_pScrollH->DestroyWindow(); //Not a child of the IHexCtrl. - m_fCreated = false; ParentNotify(HEXCTRL_MSG_DESTROY); + m_fCreated = false; return 0; } diff --git a/HexCtrl/src/CHexCtrl.h b/HexCtrl/src/CHexCtrl.h index 162bffd..89c40b2 100644 --- a/HexCtrl/src/CHexCtrl.h +++ b/HexCtrl/src/CHexCtrl.h @@ -42,8 +42,8 @@ namespace HEXCTRL::INTERNAL { void ClearData()override; bool Create(const HEXCREATE& hcs)override; bool CreateDialogCtrl(UINT uCtrlID, HWND hWndParent)override; - void Destroy()override; - void DestroyWindow(); + void Delete()override; + void DestroyWindow()override; void ExecuteCmd(EHexCmd eCmd)override; [[nodiscard]] auto GetActualWidth()const->int override; [[nodiscard]] auto GetBookmarks()const->IHexBookmarks* override; diff --git a/HexCtrl/src/Dialogs/CHexDlgBkmMgr.cpp b/HexCtrl/src/Dialogs/CHexDlgBkmMgr.cpp index 71e05b1..0d5055f 100644 --- a/HexCtrl/src/Dialogs/CHexDlgBkmMgr.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgBkmMgr.cpp @@ -28,7 +28,7 @@ auto CHexDlgBkmMgr::AddBkm(const HEXBKM& hbs, bool fRedraw)->ULONGLONG ullID = 1; //Bookmarks' ID starts from 1. if (const auto iter = std::max_element(m_vecBookmarks.begin(), m_vecBookmarks.end(), [](const HEXBKM& ref1, const HEXBKM& ref2) { - return ref1.ullID < ref2.ullID; }); iter != m_vecBookmarks.end()) { + return ref1.ullID < ref2.ullID; }); iter != m_vecBookmarks.end()) { ullID = iter->ullID + 1; //Increasing next bookmark's ID by 1. } m_vecBookmarks.emplace_back(hbs.vecSpan, hbs.wstrDesc, ullID, hbs.ullData, hbs.stClr); @@ -53,6 +53,13 @@ void CHexDlgBkmMgr::CreateDlg() } } +void CHexDlgBkmMgr::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + auto CHexDlgBkmMgr::GetHWND()const->HWND { return m_Wnd; @@ -176,8 +183,8 @@ auto CHexDlgBkmMgr::HitTest(ULONGLONG ullOffset)->PHEXBKM if (const auto rIter = std::find_if(m_vecBookmarks.rbegin(), m_vecBookmarks.rend(), [ullOffset](const HEXBKM& ref) { return std::any_of(ref.vecSpan.begin(), ref.vecSpan.end(), [ullOffset](const HEXSPAN& refV) { - return ullOffset >= refV.ullOffset && ullOffset < (refV.ullOffset + refV.ullSize); }); }); - rIter != m_vecBookmarks.rend()) { + return ullOffset >= refV.ullOffset && ullOffset < (refV.ullOffset + refV.ullSize); }); }); + rIter != m_vecBookmarks.rend()) { pBkm = &*rIter; } } @@ -253,7 +260,7 @@ void CHexDlgBkmMgr::RemoveByOffset(ULONGLONG ullOffset) if (const auto iter = std::find_if(m_vecBookmarks.rbegin(), m_vecBookmarks.rend(), [ullOffset](const HEXBKM& ref) { return std::any_of(ref.vecSpan.begin(), ref.vecSpan.end(), [ullOffset](const HEXSPAN& refV) { - return ullOffset >= refV.ullOffset && ullOffset < (refV.ullOffset + refV.ullSize); }); }); + return ullOffset >= refV.ullOffset && ullOffset < (refV.ullOffset + refV.ullSize); }); }); iter != m_vecBookmarks.rend()) { RemoveBookmark(iter->ullID); } @@ -312,34 +319,34 @@ void CHexDlgBkmMgr::SortData(int iColumn, bool fAscending) //iColumn is column number in CHexDlgBkmMgr::m_ListEx. std::sort(m_vecBookmarks.begin(), m_vecBookmarks.end(), [iColumn, fAscending](const HEXBKM& st1, const HEXBKM& st2) { - int iCompare { }; - switch (iColumn) { - case 0: - break; - case 1: //Offset. - if (!st1.vecSpan.empty() && !st2.vecSpan.empty()) { - const auto ullOffset1 = st1.vecSpan.front().ullOffset; - const auto ullOffset2 = st2.vecSpan.front().ullOffset; - iCompare = ullOffset1 != ullOffset2 ? (ullOffset1 < ullOffset2 ? -1 : 1) : 0; - } - break; - case 2: //Size. - if (!st1.vecSpan.empty() && !st2.vecSpan.empty()) { - auto ullSize1 = std::reduce(st1.vecSpan.begin(), st1.vecSpan.end(), 0ULL, - [](auto ullTotal, const HEXSPAN& ref) { return ullTotal + ref.ullSize; }); - auto ullSize2 = std::reduce(st2.vecSpan.begin(), st2.vecSpan.end(), 0ULL, - [](auto ullTotal, const HEXSPAN& ref) { return ullTotal + ref.ullSize; }); - iCompare = ullSize1 != ullSize2 ? (ullSize1 < ullSize2 ? -1 : 1) : 0; - } - break; - case 3: //Description. - iCompare = st1.wstrDesc.compare(st2.wstrDesc); - break; - default: - break; + int iCompare { }; + switch (iColumn) { + case 0: + break; + case 1: //Offset. + if (!st1.vecSpan.empty() && !st2.vecSpan.empty()) { + const auto ullOffset1 = st1.vecSpan.front().ullOffset; + const auto ullOffset2 = st2.vecSpan.front().ullOffset; + iCompare = ullOffset1 != ullOffset2 ? (ullOffset1 < ullOffset2 ? -1 : 1) : 0; + } + break; + case 2: //Size. + if (!st1.vecSpan.empty() && !st2.vecSpan.empty()) { + auto ullSize1 = std::reduce(st1.vecSpan.begin(), st1.vecSpan.end(), 0ULL, + [](auto ullTotal, const HEXSPAN& ref) { return ullTotal + ref.ullSize; }); + auto ullSize2 = std::reduce(st2.vecSpan.begin(), st2.vecSpan.end(), 0ULL, + [](auto ullTotal, const HEXSPAN& ref) { return ullTotal + ref.ullSize; }); + iCompare = ullSize1 != ullSize2 ? (ullSize1 < ullSize2 ? -1 : 1) : 0; } + break; + case 3: //Description. + iCompare = st1.wstrDesc.compare(st2.wstrDesc); + break; + default: + break; + } - return fAscending ? iCompare < 0 : iCompare > 0; + return fAscending ? iCompare < 0 : iCompare > 0; }); } diff --git a/HexCtrl/src/Dialogs/CHexDlgBkmMgr.h b/HexCtrl/src/Dialogs/CHexDlgBkmMgr.h index 95686b2..7ba65e2 100644 --- a/HexCtrl/src/Dialogs/CHexDlgBkmMgr.h +++ b/HexCtrl/src/Dialogs/CHexDlgBkmMgr.h @@ -16,6 +16,7 @@ namespace HEXCTRL::INTERNAL { public: auto AddBkm(const HEXBKM& hbs, bool fRedraw) -> ULONGLONG override; //Returns new bookmark Id. void CreateDlg(); + void DestroyDlg(); [[nodiscard]] auto GetHWND()const->HWND; [[nodiscard]] auto GetByID(ULONGLONG ullID) -> PHEXBKM override; //Bookmark by ID. [[nodiscard]] auto GetByIndex(ULONGLONG ullIndex) -> PHEXBKM override; //Bookmark by index (in inner list). diff --git a/HexCtrl/src/Dialogs/CHexDlgCodepage.cpp b/HexCtrl/src/Dialogs/CHexDlgCodepage.cpp index d4a3718..9ccefdc 100644 --- a/HexCtrl/src/Dialogs/CHexDlgCodepage.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgCodepage.cpp @@ -32,6 +32,13 @@ void CHexDlgCodepage::CreateDlg() } } +void CHexDlgCodepage::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + auto CHexDlgCodepage::GetHWND()const->HWND { return m_Wnd; @@ -94,7 +101,7 @@ bool CHexDlgCodepage::IsNoEsc()const auto CHexDlgCodepage::OnActivate(const MSG& msg)->INT_PTR { - if (!m_pHexCtrl->IsCreated()) + if (m_pHexCtrl == nullptr || !m_pHexCtrl->IsCreated()) return FALSE; const auto nState = LOWORD(msg.wParam); diff --git a/HexCtrl/src/Dialogs/CHexDlgCodepage.h b/HexCtrl/src/Dialogs/CHexDlgCodepage.h index 794b6ce..6915c26 100644 --- a/HexCtrl/src/Dialogs/CHexDlgCodepage.h +++ b/HexCtrl/src/Dialogs/CHexDlgCodepage.h @@ -15,6 +15,7 @@ namespace HEXCTRL::INTERNAL { public: void AddCP(std::wstring_view wsv); void CreateDlg(); + void DestroyDlg(); [[nodiscard]] auto GetHWND()const->HWND; void Initialize(IHexCtrl* pHexCtrl, HINSTANCE hInstRes); [[nodiscard]] bool PreTranslateMsg(MSG* pMsg); diff --git a/HexCtrl/src/Dialogs/CHexDlgDataInterp.cpp b/HexCtrl/src/Dialogs/CHexDlgDataInterp.cpp index bf0036b..21a6086 100644 --- a/HexCtrl/src/Dialogs/CHexDlgDataInterp.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgDataInterp.cpp @@ -76,6 +76,13 @@ void CHexDlgDataInterp::CreateDlg() } } +void CHexDlgDataInterp::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + auto CHexDlgDataInterp::GetDlgItemHandle(EHexDlgItem eItem)const->HWND { if (!m_Wnd.IsWindow()) { @@ -324,7 +331,7 @@ bool CHexDlgDataInterp::IsShowAsHex()const auto CHexDlgDataInterp::OnActivate(const MSG& msg)->INT_PTR { - if (!m_pHexCtrl->IsCreated()) + if (m_pHexCtrl == nullptr || !m_pHexCtrl->IsCreated()) return FALSE; const auto nState = LOWORD(msg.wParam); @@ -418,7 +425,7 @@ auto CHexDlgDataInterp::OnInitDialog(const MSG& msg)->INT_PTR using enum EGroup; using enum EName; using enum EDataSize; m_vecData.reserve(21); - m_vecData.emplace_back(L"Binary:", L"", GR_BINARY, NAME_BINARY, SIZE_BYTE); + m_vecData.emplace_back(L"Binary view:", L"", GR_BINARY, NAME_BINARY, SIZE_BYTE); m_vecData.emplace_back(L"Int8:", L"", GR_INTEGRAL, NAME_INT8, SIZE_BYTE); m_vecData.emplace_back(L"Unsigned Int8:", L"", GR_INTEGRAL, NAME_UINT8, SIZE_BYTE); m_vecData.emplace_back(L"Int16:", L"", GR_INTEGRAL, NAME_INT16, SIZE_WORD); @@ -427,6 +434,8 @@ auto CHexDlgDataInterp::OnInitDialog(const MSG& msg)->INT_PTR m_vecData.emplace_back(L"Unsigned Int32:", L"", GR_INTEGRAL, NAME_UINT32, SIZE_DWORD); m_vecData.emplace_back(L"Int64:", L"", GR_INTEGRAL, NAME_INT64, SIZE_QWORD); m_vecData.emplace_back(L"Unsigned Int64:", L"", GR_INTEGRAL, NAME_UINT64, SIZE_QWORD); + m_vecData.emplace_back(L"Float:", L"", GR_FLOAT, NAME_FLOAT, SIZE_DWORD); + m_vecData.emplace_back(L"Double:", L"", GR_FLOAT, NAME_DOUBLE, SIZE_QWORD); m_vecData.emplace_back(L"time32_t:", L"", GR_TIME, NAME_TIME32T, SIZE_DWORD); m_vecData.emplace_back(L"time64_t:", L"", GR_TIME, NAME_TIME64T, SIZE_QWORD); m_vecData.emplace_back(L"FILETIME:", L"", GR_TIME, NAME_FILETIME, SIZE_QWORD); @@ -435,8 +444,6 @@ auto CHexDlgDataInterp::OnInitDialog(const MSG& msg)->INT_PTR m_vecData.emplace_back(L"MS-DOS time:", L"", GR_TIME, NAME_MSDOSTIME, SIZE_QWORD); m_vecData.emplace_back(L"MS-UDTTM time:", L"", GR_TIME, NAME_MSDTTMTIME, SIZE_DWORD); m_vecData.emplace_back(L"Windows SYSTEMTIME:", L"", GR_TIME, NAME_SYSTEMTIME, SIZE_DQWORD); - m_vecData.emplace_back(L"Float:", L"", GR_FLOAT, NAME_FLOAT, SIZE_DWORD); - m_vecData.emplace_back(L"Double:", L"", GR_FLOAT, NAME_DOUBLE, SIZE_QWORD); m_vecData.emplace_back(L"GUID:", L"", GR_MISC, NAME_GUID, SIZE_DQWORD); m_vecData.emplace_back(L"GUID v1 UTC time:", L"", GR_GUIDTIME, NAME_GUIDTIME, SIZE_DQWORD); @@ -988,7 +995,7 @@ template void CHexDlgDataInterp::ShowValueBinary(T tData) { const auto pGrid = GetListData(EName::NAME_BINARY); - constexpr auto pSepar { L" " }; + constexpr auto pSepar { L" " }; if constexpr (sizeof(T) == sizeof(std::uint8_t)) { pGrid->wstrValue = std::format(L"{:08b}", tData); } diff --git a/HexCtrl/src/Dialogs/CHexDlgDataInterp.h b/HexCtrl/src/Dialogs/CHexDlgDataInterp.h index a49142a..f57aa43 100644 --- a/HexCtrl/src/Dialogs/CHexDlgDataInterp.h +++ b/HexCtrl/src/Dialogs/CHexDlgDataInterp.h @@ -16,6 +16,7 @@ namespace HEXCTRL::INTERNAL { CHexDlgDataInterp(); ~CHexDlgDataInterp(); void CreateDlg(); + void DestroyDlg(); [[nodiscard]] auto GetDlgItemHandle(EHexDlgItem eItem)const->HWND; [[nodiscard]] auto GetHglDataSize()const->DWORD; [[nodiscard]] auto GetHWND()const->HWND; diff --git a/HexCtrl/src/Dialogs/CHexDlgGoTo.cpp b/HexCtrl/src/Dialogs/CHexDlgGoTo.cpp index b6249ea..d38ad0e 100644 --- a/HexCtrl/src/Dialogs/CHexDlgGoTo.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgGoTo.cpp @@ -26,6 +26,13 @@ void CHexDlgGoTo::CreateDlg() } } +void CHexDlgGoTo::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + void CHexDlgGoTo::Initialize(IHexCtrl* pHexCtrl, HINSTANCE hInstRes) { if (pHexCtrl == nullptr || hInstRes == nullptr) { @@ -181,7 +188,7 @@ bool CHexDlgGoTo::IsNoEsc()const auto CHexDlgGoTo::OnActivate(const MSG& msg)->INT_PTR { const auto pHexCtrl = GetHexCtrl(); - if (!pHexCtrl->IsCreated() || !pHexCtrl->IsDataSet()) + if (pHexCtrl == nullptr || !pHexCtrl->IsCreated() || !pHexCtrl->IsDataSet()) return FALSE; const auto nState = LOWORD(msg.wParam); diff --git a/HexCtrl/src/Dialogs/CHexDlgGoTo.h b/HexCtrl/src/Dialogs/CHexDlgGoTo.h index f1e6320..dc0f3d0 100644 --- a/HexCtrl/src/Dialogs/CHexDlgGoTo.h +++ b/HexCtrl/src/Dialogs/CHexDlgGoTo.h @@ -13,6 +13,7 @@ namespace HEXCTRL::INTERNAL { class CHexDlgGoTo final { public: void CreateDlg(); + void DestroyDlg(); void Initialize(IHexCtrl* pHexCtrl, HINSTANCE hInstRes); [[nodiscard]] auto GetHWND()const->HWND; [[nodiscard]] bool IsRepeatAvail()const; diff --git a/HexCtrl/src/Dialogs/CHexDlgModify.cpp b/HexCtrl/src/Dialogs/CHexDlgModify.cpp index 8d655d7..a300ad1 100644 --- a/HexCtrl/src/Dialogs/CHexDlgModify.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgModify.cpp @@ -854,6 +854,13 @@ void CHexDlgModify::CreateDlg() } } +void CHexDlgModify::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + auto CHexDlgModify::GetDlgItemHandle(EHexDlgItem eItem)const->HWND { if (!m_Wnd.IsWindow()) { diff --git a/HexCtrl/src/Dialogs/CHexDlgModify.h b/HexCtrl/src/Dialogs/CHexDlgModify.h index 1d68b7b..66d735f 100644 --- a/HexCtrl/src/Dialogs/CHexDlgModify.h +++ b/HexCtrl/src/Dialogs/CHexDlgModify.h @@ -18,6 +18,7 @@ namespace HEXCTRL::INTERNAL { CHexDlgModify(); ~CHexDlgModify(); void CreateDlg(); + void DestroyDlg(); [[nodiscard]] auto GetDlgItemHandle(EHexDlgItem eItem)const->HWND; [[nodiscard]] auto GetHWND()const->HWND; void Initialize(IHexCtrl* pHexCtrl, HINSTANCE hInstRes); diff --git a/HexCtrl/src/Dialogs/CHexDlgSearch.cpp b/HexCtrl/src/Dialogs/CHexDlgSearch.cpp index 121ae67..3e9925b 100644 --- a/HexCtrl/src/Dialogs/CHexDlgSearch.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgSearch.cpp @@ -72,6 +72,13 @@ void CHexDlgSearch::CreateDlg() } } +void CHexDlgSearch::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + auto CHexDlgSearch::GetDlgItemHandle(EHexDlgItem eItem)const->HWND { if (!m_Wnd.IsWindow()) { @@ -749,7 +756,7 @@ bool CHexDlgSearch::IsWildcard()const auto CHexDlgSearch::OnActivate(const MSG& msg)->INT_PTR { - if (!m_pHexCtrl->IsCreated()) + if (m_pHexCtrl == nullptr || !m_pHexCtrl->IsCreated()) return FALSE; const auto nState = LOWORD(msg.wParam); diff --git a/HexCtrl/src/Dialogs/CHexDlgSearch.h b/HexCtrl/src/Dialogs/CHexDlgSearch.h index 75bf79c..7103719 100644 --- a/HexCtrl/src/Dialogs/CHexDlgSearch.h +++ b/HexCtrl/src/Dialogs/CHexDlgSearch.h @@ -17,6 +17,7 @@ namespace HEXCTRL::INTERNAL { public: void ClearData(); void CreateDlg(); + void DestroyDlg(); [[nodiscard]] auto GetDlgItemHandle(EHexDlgItem eItem)const->HWND; [[nodiscard]] auto GetHWND()const->HWND; void Initialize(IHexCtrl* pHexCtrl, HINSTANCE hInstRes); diff --git a/HexCtrl/src/Dialogs/CHexDlgTemplMgr.cpp b/HexCtrl/src/Dialogs/CHexDlgTemplMgr.cpp index d192a6e..1db3ffd 100644 --- a/HexCtrl/src/Dialogs/CHexDlgTemplMgr.cpp +++ b/HexCtrl/src/Dialogs/CHexDlgTemplMgr.cpp @@ -115,6 +115,13 @@ void CHexDlgTemplMgr::CreateDlg() } } +void CHexDlgTemplMgr::DestroyDlg() +{ + if (m_Wnd.IsWindow()) { + m_Wnd.DestroyWindow(); + } +} + void CHexDlgTemplMgr::DisapplyAll() { if (m_Wnd.IsWindow()) { //Dialog must be created and alive to work with its members. @@ -392,7 +399,7 @@ bool CHexDlgTemplMgr::IsSwapEndian()const auto CHexDlgTemplMgr::OnActivate(const MSG& msg)->INT_PTR { - if (!m_pHexCtrl->IsCreated()) + if (m_pHexCtrl == nullptr || !m_pHexCtrl->IsCreated()) return FALSE; const auto nState = LOWORD(msg.wParam); diff --git a/HexCtrl/src/Dialogs/CHexDlgTemplMgr.h b/HexCtrl/src/Dialogs/CHexDlgTemplMgr.h index 4ed664b..419cffc 100644 --- a/HexCtrl/src/Dialogs/CHexDlgTemplMgr.h +++ b/HexCtrl/src/Dialogs/CHexDlgTemplMgr.h @@ -29,6 +29,7 @@ namespace HEXCTRL::INTERNAL { void ApplyCurr(ULONGLONG ullOffset); //Apply currently selected template to offset. int ApplyTemplate(ULONGLONG ullOffset, int iTemplateID)override; //Apply template to a given offset. void CreateDlg(); + void DestroyDlg(); void DisapplyAll()override; void DisapplyByID(int iAppliedID)override; //Disapply template with the given AppliedID. void DisapplyByOffset(ULONGLONG ullOffset)override; diff --git a/README.md b/README.md index c968f6d..f9ed1cb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ * [ClearData](#cleardata) * [Create](#create) * [CreateDialogCtrl](#createdialogctrl) - * [Destroy](#destroy) + * [Delete](#delete) + * [DestroyWindow](#destroywindow) * [ExecuteCmd](#executecmd) * [GetActualWidth](#getactualwidth) * [GetBookmarks](#getbookmarks) @@ -356,16 +357,21 @@ bool CreateDialogCtrl(UINT uCtrlID, HWND hwndDlg); ``` Creates **HexCtrl** from a **Custom Control** dialog's template. Takes control **id**, and dialog's window **handle** as arguments. See **[Creating](#in-dialog)** section for more info. -### [](#)Destroy +### [](#)Delete ```cpp -void Destroy(); +void Delete(); ``` -Destroys the control. -You only invoke this method if you use a raw `IHexCtrl` pointer, otherwise don't use it. +Deletes the **HexCtrl** object. You only use this method if you want, for some reason, to manually delete the **HexCtrl** object, otherwise `IHexCtrlPtr` will invoke this method automatically. > [!IMPORTANT] You usually don't need to call this method unless you use the **HexCtrl** through a raw pointer. If you use **HexCtrl** in the standard way, through the `IHexCtrlPtr` pointer obtained by the [`CreateHexCtrl`](#createhexctrl) function, this method will be called automatically. +### [](#)DestroyWindow +```cpp +void DestroyWindow(); +``` +Destroys the **HexCtrl** main window. + ### [](#)ExecuteCmd ```cpp void ExecuteCmd(EHexCmd eCmd)const;