DEV Community

Cover image for Hover Bug: A Prankware Simulator. Based on the "Butterfly on Desktop" (text only) that will probably never touch the corner.
Saahen Sriyan Mishra
Saahen Sriyan Mishra

Posted on

Hover Bug: A Prankware Simulator. Based on the "Butterfly on Desktop" (text only) that will probably never touch the corner.

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.


Demo

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 and main.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; } 
Enter fullscreen mode Exit fullscreen mode

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); } } } 
Enter fullscreen mode Exit fullscreen mode

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); } 
Enter fullscreen mode Exit fullscreen mode

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; } 
Enter fullscreen mode Exit fullscreen mode

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; } 
Enter fullscreen mode Exit fullscreen mode

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; 
Enter fullscreen mode Exit fullscreen mode

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); } 
Enter fullscreen mode Exit fullscreen mode

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); } } 
Enter fullscreen mode Exit fullscreen mode

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; 
Enter fullscreen mode Exit fullscreen mode

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); 
Enter fullscreen mode Exit fullscreen mode

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 ); 
Enter fullscreen mode Exit fullscreen mode

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); 
Enter fullscreen mode Exit fullscreen mode

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; } 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Runs standard Win32 message loop.
  • Cleans up GDI+ before exit.

πŸ“₯ Installation

  1. Download the latest release from Releases
  2. Extract Hover-Bug_v2.3.zip
  3. 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" 
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ 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 
Enter fullscreen mode Exit fullscreen mode

πŸ“Ž 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)