1
0
mirror of synced 2025-02-20 04:01:01 +01:00

feat: Added filtering to Process Memory Provider

This commit is contained in:
WerWolv 2023-01-05 09:30:15 +01:00
parent ff9048fcf0
commit 763196f0cc
4 changed files with 93 additions and 16 deletions

View File

@ -48,7 +48,7 @@ namespace ImGui {
return this->m_textureId != nullptr;
}
[[nodiscard]] constexpr operator ImTextureID() {
[[nodiscard]] constexpr operator ImTextureID() const noexcept {
return this->m_textureId;
}

View File

@ -0,0 +1,62 @@
#pragma once
#include <hex.hpp>
#include <vector>
#include <string>
#include <atomic>
#include <hex/api/task.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::ui {
template<typename T>
class SearchableWidget {
public:
SearchableWidget(const std::function<bool(const std::string&, const T&)> &comparator) : m_comparator(comparator) {
}
const std::vector<const T*> &draw(const auto &entries) {
if (this->m_filteredEntries.empty() && this->m_searchBuffer.empty()) {
for (auto &entry : entries)
this->m_filteredEntries.push_back(&entry);
}
if (ImGui::InputText("##search", this->m_searchBuffer)) {
this->m_pendingUpdate = true;
}
if (this->m_pendingUpdate && !this->m_updateTask.isRunning()) {
this->m_pendingUpdate = false;
this->m_filteredEntries.clear();
this->m_filteredEntries.reserve(entries.size());
this->m_updateTask = TaskManager::createBackgroundTask("Searching", [this, &entries, searchBuffer = this->m_searchBuffer](Task&) {
for (auto &entry : entries) {
if (searchBuffer.empty() || this->m_comparator(searchBuffer, entry))
this->m_filteredEntries.push_back(&entry);
}
});
}
return this->m_filteredEntries;
}
void reset() {
this->m_filteredEntries.clear();
}
private:
std::atomic<bool> m_pendingUpdate = false;
TaskHolder m_updateTask;
std::string m_searchBuffer;
std::vector<const T*> m_filteredEntries;
std::function<bool(const std::string&, const T&)> m_comparator;
};
}

View File

@ -7,6 +7,7 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/ui/widgets.hpp>
#include <array>
#include <mutex>
@ -81,9 +82,15 @@ namespace hex::plugin::windows {
};
std::vector<Process> m_processes;
Process *m_selectedProcess = nullptr;
const Process *m_selectedProcess = nullptr;
std::set<MemoryRegion> m_memoryRegions;
ui::SearchableWidget<Process> m_processSearchWidget = ui::SearchableWidget<Process>([](const std::string &search, const Process &process) {
return process.name.contains(search);
});
ui::SearchableWidget<MemoryRegion> m_regionSearchWidget = ui::SearchableWidget<MemoryRegion>([](const std::string &search, const MemoryRegion &memoryRegion) {
return memoryRegion.name.contains(search);
});
HANDLE m_processHandle = nullptr;

View File

@ -127,7 +127,10 @@ namespace hex::plugin::windows {
if (this->m_enumerationFailed) {
ImGui::TextUnformatted("hex.windows.provider.process_memory.enumeration_failed"_lang);
} else {
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(0, 500_scaled))) {
ImGui::PushItemWidth(350_scaled);
const auto &filtered = this->m_processSearchWidget.draw(this->m_processes);
ImGui::PopItemWidth();
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(350_scaled, 500_scaled))) {
ImGui::TableSetupColumn("##icon");
ImGui::TableSetupColumn("hex.windows.provider.process_memory.process_id"_lang);
ImGui::TableSetupColumn("hex.windows.provider.process_memory.process_name"_lang);
@ -135,19 +138,19 @@ namespace hex::plugin::windows {
ImGui::TableHeadersRow();
for (auto &process : this->m_processes) {
ImGui::PushID(process.id);
for (auto &process : filtered) {
ImGui::PushID(process);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Image(process.icon, process.icon.getSize());
ImGui::Image(process->icon, process->icon.getSize());
ImGui::TableNextColumn();
ImGui::Text("%d", process.id);
ImGui::Text("%d", process->id);
ImGui::TableNextColumn();
if (ImGui::Selectable(process.name.c_str(), this->m_selectedProcess != nullptr && process.id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process.icon.getSize().y)))
this->m_selectedProcess = &process;
if (ImGui::Selectable(process->name.c_str(), this->m_selectedProcess != nullptr && process->id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
this->m_selectedProcess = process;
ImGui::PopID();
}
@ -160,7 +163,12 @@ namespace hex::plugin::windows {
void ProcessMemoryProvider::drawInterface() {
ImGui::Header("hex.windows.provider.process_memory.memory_regions"_lang, true);
if (ImGui::BeginTable("##module_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(0, 400_scaled))) {
auto availableX = ImGui::GetContentRegionAvail().x;
ImGui::PushItemWidth(availableX);
const auto &filtered = this->m_regionSearchWidget.draw(this->m_memoryRegions);
ImGui::PopItemWidth();
if (ImGui::BeginTable("##module_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(availableX, 400_scaled))) {
ImGui::TableSetupColumn("hex.builtin.common.region"_lang);
ImGui::TableSetupColumn("hex.builtin.common.size"_lang);
ImGui::TableSetupColumn("hex.builtin.common.name"_lang);
@ -168,20 +176,20 @@ namespace hex::plugin::windows {
ImGui::TableHeadersRow();
for (auto &memoryRegion : this->m_memoryRegions) {
ImGui::PushID(memoryRegion.region.getStartAddress());
for (auto &memoryRegion : filtered) {
ImGui::PushID(memoryRegion->region.getStartAddress());
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("0x%016llX - 0x%016llX", memoryRegion.region.getStartAddress(), memoryRegion.region.getEndAddress());
ImGui::Text("0x%016llX - 0x%016llX", memoryRegion->region.getStartAddress(), memoryRegion->region.getEndAddress());
ImGui::TableNextColumn();
ImGui::TextUnformatted(hex::toByteString(memoryRegion.region.getSize()).c_str());
ImGui::TextUnformatted(hex::toByteString(memoryRegion->region.getSize()).c_str());
ImGui::TableNextColumn();
if (ImGui::Selectable(memoryRegion.name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
ImHexApi::HexEditor::setSelection(memoryRegion.region);
if (ImGui::Selectable(memoryRegion->name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
ImHexApi::HexEditor::setSelection(memoryRegion->region);
ImGui::PopID();
}