// Window controller for sending input events to the designer #pragma once #define NOMINMAX #include #include #include namespace mosis::test { // Phone UI dimensions (default resolution) constexpr int PHONE_WIDTH = 540; constexpr int PHONE_HEIGHT = 960; // Window information struct WindowInfo { HWND hwnd; RECT windowRect; RECT clientRect; int clientX; // Client area X in screen coords int clientY; // Client area Y in screen coords int clientWidth; // Client area width int clientHeight; // Client area height float scaleX; // DPI scale X float scaleY; // DPI scale Y }; class WindowController { public: WindowController() = default; ~WindowController() = default; // Find the designer window by title bool FindWindow(const std::string& title = "Mosis Designer"); // Check if window is valid bool IsValid() const { return m_hwnd != nullptr; } // Get window info const WindowInfo& GetInfo() const { return m_info; } // Send mouse events at phone coordinates (0-540, 0-960) // These coordinates are scaled to match the actual window size bool SendMouseDown(int phoneX, int phoneY); bool SendMouseUp(int phoneX, int phoneY); bool SendMouseMove(int phoneX, int phoneY); bool SendClick(int phoneX, int phoneY); // Send click at position relative to bottom of window // clientX is absolute X in client area, offsetFromBottom is Y offset from bottom edge bool SendClickFromBottom(int clientX, int offsetFromBottom); // Send keyboard events bool SendKey(UINT vkCode); bool SendChar(char c); // Bring window to foreground bool Activate(); // Close the window bool Close(); // Resize window to match phone dimensions bool ResizeToPhone(); // Wait for window to appear (returns false on timeout) bool WaitForWindow(const std::string& title, int timeoutMs = 10000); private: // Convert phone coordinates to client coordinates (accounting for DPI scale) LPARAM PhoneToClientLParam(int phoneX, int phoneY); HWND m_hwnd = nullptr; WindowInfo m_info = {}; }; } // namespace mosis::test