Skip to content

Commit ae2a388

Browse files
committed
Converted to C++
1 parent a956f98 commit ae2a388

21 files changed

Lines changed: 1093 additions & 485 deletions

CMakeLists.txt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
cmake_minimum_required(VERSION 3.29)
2+
project(ProcessFlipper)
3+
4+
# Enable the Resource Compiler language
5+
enable_language(RC)
6+
7+
set(CMAKE_CXX_STANDARD 23)
8+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
9+
10+
# Find and setup ccache if available
11+
find_program(CCACHE_PROGRAM ccache)
12+
if(CCACHE_PROGRAM)
13+
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
14+
endif()
15+
16+
# Check for LTO support
17+
include(CheckIPOSupported)
18+
check_ipo_supported(RESULT lto_supported OUTPUT error_message)
19+
20+
# Set optimization flags for Release builds
21+
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
22+
23+
# Strip symbols in Release mode
24+
if(WIN32)
25+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
26+
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
27+
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
28+
else()
29+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
30+
endif()
31+
32+
# Default to Release build if not specified
33+
if(NOT CMAKE_BUILD_TYPE)
34+
set(CMAKE_BUILD_TYPE Release)
35+
endif()
36+
37+
add_executable(ProcessFlipper WIN32 main.cpp
38+
process_manager.cpp
39+
tray_icon.cpp
40+
app.rc
41+
# List header files for clarity / IDE support
42+
tray_icon.h
43+
hotkey_manager.h
44+
process_manager.h
45+
resource.h
46+
)
47+
48+
# Enable LTO/IPO if supported
49+
if(lto_supported)
50+
set_property(TARGET ProcessFlipper PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
51+
else()
52+
message(WARNING "LTO is not supported: ${error_message}")
53+
endif()
54+
55+
# Use precompiled headers for common headers
56+
target_precompile_headers(ProcessFlipper PRIVATE
57+
<vector>
58+
<string>
59+
<windows.h>
60+
<memory>
61+
<unordered_map>
62+
)
63+
64+
# Optimize for the current CPU architecture if not on Windows
65+
# (Windows builds typically need to be more portable, so architecture-specific optimizations are often avoided)
66+
if(NOT WIN32)
67+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
68+
endif()
69+
70+
# For Windows builds, specific optimizations
71+
if(WIN32)
72+
# Use whole program optimization for MSVC
73+
target_compile_options(ProcessFlipper PRIVATE $<$<CONFIG:Release>:/GL>)
74+
# Use LTCG (Link Time Code Generation) for the linker
75+
set_property(TARGET ProcessFlipper PROPERTY LINK_FLAGS_RELEASE "/LTCG")
76+
endif()

README.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

app.rc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "resource.h"
2+
3+
IDI_APPICON ICON "icon.ico"

critical_processes.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

hotkey_manager.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#pragma once
2+
#include <windows.h>
3+
#include <unordered_map>
4+
#include <functional>
5+
#include <iostream> // For logging
6+
7+
class HotkeyManager {
8+
public:
9+
HotkeyManager() : nextHotkeyId(1) {
10+
std::cout << "HotkeyManager initialized." << std::endl;
11+
}
12+
13+
~HotkeyManager() {
14+
// Clean up all registered hotkeys
15+
for (const auto& pair : hotkeyCallbacks) {
16+
UnregisterHotKey(nullptr, pair.first);
17+
std::cout << "Unregistered hotkey ID: " << pair.first << std::endl;
18+
}
19+
hotkeyCallbacks.clear();
20+
}
21+
22+
int registerHotkey(const UINT modifiers, const UINT vk) {
23+
const int currentIdAttempt = nextHotkeyId; // Use a temporary variable for logging before incrementing
24+
if (RegisterHotKey(nullptr, currentIdAttempt, modifiers, vk)) {
25+
nextHotkeyId++; // Increment only on success
26+
std::cout << "Hotkey registered successfully: ID=" << currentIdAttempt
27+
<< ", Modifiers=0x" << std::hex << modifiers
28+
<< ", VK=0x" << std::hex << vk << std::dec << std::endl;
29+
return currentIdAttempt;
30+
}
31+
DWORD errorCode = GetLastError();
32+
std::cerr << "Failed to register hotkey: Modifiers=0x" << std::hex << modifiers
33+
<< ", VK=0x" << std::hex << vk << std::dec
34+
<< ". Error code: " << errorCode << std::endl;
35+
return -1;
36+
}
37+
38+
void setCallback(int id, const std::function<void()>& callback) {
39+
if (id != -1) {
40+
hotkeyCallbacks[id] = callback;
41+
std::cout << "Callback set for hotkey ID: " << id << std::endl;
42+
} else {
43+
std::cerr << "Attempted to set callback for invalid hotkey ID (-1)." << std::endl;
44+
}
45+
}
46+
47+
// Processes a given MSG struct. Returns true if it was a hotkey message and handled, false otherwise.
48+
bool processMessage(const MSG& msg) { // Go back to const reference but handle carefully
49+
if (msg.message == WM_HOTKEY) {
50+
// Extract only what we need - the ID
51+
int hotkeyId = static_cast<int>(msg.wParam);
52+
53+
std::cout << "HotkeyManager::processMessage - WM_HOTKEY received. ID: " << hotkeyId << std::endl;
54+
55+
// Find the callback
56+
auto it = hotkeyCallbacks.find(hotkeyId);
57+
if (it != hotkeyCallbacks.end() && it->second) {
58+
std::cout << "HotkeyManager::processMessage - Executing callback for hotkey ID: " << hotkeyId << std::endl;
59+
60+
// Execute the callback directly - no need for a local copy
61+
it->second();
62+
} else {
63+
std::cerr << "HotkeyManager::processMessage - No callback found for hotkey ID: " << hotkeyId << std::endl;
64+
}
65+
66+
return true; // Hotkey message was processed
67+
}
68+
69+
return false; // Not a hotkey message
70+
}
71+
72+
/*
73+
// The handleHotkeys method with PeekMessage is not suitable when GetMessage is used in the main loop
74+
// as GetMessage will consume the WM_HOTKEY before PeekMessage in this function can see it.
75+
// This function would be more appropriate if HotkeyManager ran its own message loop
76+
// or if PeekMessage was used exclusively in the main loop.
77+
void handleHotkeys() {
78+
MSG msg;
79+
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
80+
if (msg.message == WM_HOTKEY) {
81+
int hotkeyId = static_cast<int>(msg.wParam);
82+
std::cout << "WM_HOTKEY received. ID: " << hotkeyId << std::endl;
83+
if (hotkeyCallbacks.count(hotkeyId) > 0) {
84+
std::cout << "Executing callback for hotkey ID: " << hotkeyId << std::endl;
85+
hotkeyCallbacks[hotkeyId]();
86+
} else {
87+
std::cerr << "No callback found for hotkey ID: " << hotkeyId << std::endl;
88+
}
89+
}
90+
}
91+
}
92+
*/
93+
94+
private:
95+
int nextHotkeyId;
96+
std::unordered_map<int, std::function<void()>> hotkeyCallbacks;
97+
};

icon.png

-713 KB
Binary file not shown.

icon_data.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)