Hey folks!
I recently finished a fun little C++ project that simulates a butterfly flying around your desktop β but with a twist: it does so in a controlled environment for custom text input! Remember the DVD logo that people love when it touches the corner based on a fixed path, this one is unpredictable as its movement is random.
Give it a try by downloading the Github Release: Hover_Bug
π§ What It Does:
- Spawns a entered text that "hovers" on top of all windows.
- Almost like a DVD logo that people love when it touches the corner.
- Runs seamlessly on Windows β think of it like a lightweight desktop companion.
π§ Tech Stack:
- Language: C++
- Framework: Win32 API for desktop-level rendering and layering
- Executable Output:
Hover_Bug.exe
andmain.exe
- Release Build: Available under the
release
branch on GitHub β only 2.exe
files.
π¦ Use Case: (For fun only)
- A desktop pet that displays motivational quotes or reminders.
- A customizable visual toy to demonstrate Win32 overlay capabilities.
π οΈ Features
Dynamic Floating Text
- Smooth movement patterns (3-7 sec per direction)
- Starts centered on any screen
Eye-Catching Effects
- π Smooth color fading (rainbow mode)
- π― Always-on-top display
Easy Control
- Simple launcher for text updates
- System tray friendly (low resource usage)
Additional:
- The overlay doesnβt interfere with mouse events or system focus.
- Controlling CPU usage by limiting it to only 1 instance.
- Clean and minimal without background threads going wild.
π¨βπ» Code
main.cpp β Hover-Bug Launcher
This file creates a simple Windows GUI app using the Win32 API. It allows the user to input text and launch/stop a floating text overlay (Hover_Bug.exe
).
β
FindHoverBugProcess
β Finds if Hover_Bug.exe is already running
DWORD FindHoverBugProcess() { HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE) return 0; PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hSnap, &pe)) { do { if (_wcsicmp(pe.szExeFile, L"Hover_Bug.exe") == 0) { CloseHandle(hSnap); return pe.th32ProcessID; } } while (Process32Next(hSnap, &pe)); } CloseHandle(hSnap); return 0; }
Explanation:
- Takes a snapshot of all running processes.
- Loops through each using Process32First/Next.
- Compares the process name (case-insensitive) with Hover_Bug.exe.
- If found, returns its Process ID (PID).
β TerminateHoverBug β Kills Hover_Bug.exe if running
Copy code void TerminateHoverBug() { DWORD pid = FindHoverBugProcess(); if (pid) { HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid); if (hProcess) { TerminateProcess(hProcess, 0); CloseHandle(hProcess); } } }
Explanation:
- Calls FindHoverBugProcess() to check if it's running.
- Opens the process with permission to terminate it.
- Calls TerminateProcess().
β LaunchHoverBug β Starts Hover_Bug.exe with user text
Copy code void LaunchHoverBug(const std::string& text) { TerminateHoverBug(); // Ensure only one instance std::string command = "Hover_Bug.exe \"" + text + "\""; STARTUPINFOA si = { sizeof(si) }; PROCESS_INFORMATION pi; CreateProcessA(NULL, const_cast<LPSTR>(command.c_str()), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }
Explanation:
- Terminates any existing instance.
- Creates the command: Hover_Bug.exe "user text".
- Uses CreateProcessA() to launch it silently (CREATE_NO_WINDOW).
β WindowProc β Main GUI Event Handler
Copy code LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hEdit, hStartButton, hStopButton; switch (uMsg) { case WM_CREATE: CreateWindow("STATIC", "Enter text:", WS_VISIBLE | WS_CHILD, 20, 20, 80, 20, hwnd, (HMENU)ID_LABEL, NULL, NULL); hEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 110, 20, 250, 20, hwnd, (HMENU)ID_EDIT, NULL, NULL); hStartButton = CreateWindow("BUTTON", "Start", WS_VISIBLE | WS_CHILD, 110, 60, 100, 30, hwnd, (HMENU)ID_START_BUTTON, NULL, NULL); hStopButton = CreateWindow("BUTTON", "Stop", WS_VISIBLE | WS_CHILD, 220, 60, 100, 30, hwnd, (HMENU)ID_STOP_BUTTON, NULL, NULL); break; case WM_COMMAND: if (LOWORD(wParam) == ID_START_BUTTON) { char buffer[256]; GetWindowTextA(hEdit, buffer, 256); std::string text(buffer); if (!text.empty()) { LaunchHoverBug(text); } else { MessageBox(hwnd, "Please enter text.", "Error", MB_OK | MB_ICONERROR); } } else if (LOWORD(wParam) == ID_STOP_BUTTON) { TerminateHoverBug(); } break; case WM_DESTROY: TerminateHoverBug(); // Clean up PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }
Explanation:
- On WM_CREATE: Creates input field and Start/Stop buttons.
- On WM_COMMAND: If Start is clicked, gets input and calls LaunchHoverBug. If Stop is clicked, terminates.
- On WM_DESTROY: Kills Hover_Bug before quitting.
β WinMain β Entry Point
Copy code int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) { const char CLASS_NAME[] = "HoverBugLauncher"; WNDCLASS wc = {}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; RegisterClass(&wc); HWND hwnd = CreateWindowEx( 0, CLASS_NAME, "Hover-Bug Launcher", WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 400, 150, NULL, NULL, hInstance, NULL ); if (!hwnd) return 0; ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
Explanation:
- Defines and registers a window class.
- Creates the main window.
- Shows it and enters the message loop to handle UI events.
hover_bug.cpp β Floating Overlay Window (Full Explanation)
This file creates a transparent, always-on-top, click-through window that displays floating text passed via command-line arguments. It uses the GDI+ library to draw smooth text with a blur/glow effect.
β Globals and Setup
#pragma comment(lib, "gdiplus.lib") #include <windows.h> #include <gdiplus.h> #include <string> using namespace Gdiplus; ULONG_PTR gdiplusToken; std::wstring g_text;
Explanation:
- Links gdiplus.lib to use GDI+ for graphics.
- Declares g_text to hold the overlay text.
- gdiplusToken manages the GDI+ session.
β DrawTextWithBlur β Draws Text with Shadow/Glow
Copy code void DrawTextWithBlur(HDC hdc, const std::wstring& text, RECT rect) { Graphics graphics(hdc); graphics.SetSmoothingMode(SmoothingModeAntiAlias); graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit); FontFamily fontFamily(L"Segoe UI"); Font font(&fontFamily, 36, FontStyleBold, UnitPixel); PointF origin(rect.left, rect.top); SolidBrush shadowBrush(Color(128, 0, 0, 0)); // semi-transparent black for (int dx = -2; dx <= 2; ++dx) { for (int dy = -2; dy <= 2; ++dy) { PointF shadowOrigin(origin.X + dx, origin.Y + dy); graphics.DrawString(text.c_str(), -1, &font, shadowOrigin, &shadowBrush); } } SolidBrush textBrush(Color(255, 255, 255, 255)); // white text graphics.DrawString(text.c_str(), -1, &font, &origin, &textBrush); }
Explanation:
- Uses GDI+ to draw high-quality text.
- First, it draws shadows by looping through offsets.
- Then, it draws solid white text on top.
- Creates a blur/glow effect using offset rendering.
β
WindowProc β Message Handler for Overlay Window
Copy code LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rect; GetClientRect(hwnd, &rect); DrawTextWithBlur(hdc, g_text, rect); EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } }
Explanation:
- On WM_PAINT, it draws the blurred text inside the window.
- On WM_DESTROY, posts quit message.
- Default handling for other messages.
β wWinMain β Entry Point for the Hover Bug Overlay
Copy code int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int) { GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); g_text = pCmdLine;
Explanation:
- Starts GDI+ graphics session.
- Retrieves the overlay text passed via command line (from main.cpp).
β Register Window Class
Copy code const wchar_t CLASS_NAME[] = L"HoverBugWindowClass"; WNDCLASS wc = {}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); RegisterClass(&wc);
Explanation:
- Defines the look and behavior of the overlay window.
- Sets background to black (for blending).
- Uses the earlier WindowProc.
β Create Transparent, Click-through Window
Copy code HWND hwnd = CreateWindowEx( WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, CLASS_NAME, L"Hover Bug", WS_POPUP, 100, 100, 800, 200, NULL, NULL, hInstance, NULL );
Explanation:
- WS_EX_LAYERED: Allows transparency.
- WS_EX_TRANSPARENT: Mouse click passes through it.
- WS_EX_TOPMOST: Always on top.
- WS_EX_TOOLWINDOW: Hides from taskbar.
- WS_POPUP: No border/titlebar.
β Set Layered Transparency & Show Window
Copy code SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA); ShowWindow(hwnd, SW_SHOW);
Explanation:
- Makes the window fully visible (alpha = 255), still layered for potential opacity.
- Shows the window after creation.
β Message Loop
Copy code MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } GdiplusShutdown(gdiplusToken); return 0; }
Explanation:
- Runs standard Win32 message loop.
- Cleans up GDI+ before exit.
π₯ Installation
- Download the latest release from Releases
- Extract
Hover-Bug_v2.3.zip
- Run
main.exe
No admin rights required!
π₯οΈ Usage
Basic Controls
Type your text in the launcher
Click "Start" to launch floating text
Use "Stop" to remove it
Advanced Options
- Command Line:
Hover_Bug.exe "Your Text Here"
π οΈ Building from Source
Requires:
- MinGW/GCC (Windows)
- Win32 API development headers
g++ -std=c++11 -O2 -mwindows hover_bug.cpp -o Hover_Bug.exe -static -lgdi32 -lwinmm g++ main.cpp -o main.exe -mwindows
π GitHub:
π Repo
β¬οΈ Release v2.3.2
If you're into desktop UI tweaks, C++ visual projects, or just need some zen in your workspace, check it out!
Feedback and suggestions are all welcome. BTW i will be adding a Input for desired image over the text to make it more cool.
Top comments (0)