/// <summary>
        /// Retrieves the window client area size.
        /// i.e. The X and Y sizes, in pixels excluding the window borders.
        /// </summary>
        /// <param name="windowHandle">Handle to the window of which the client area rectangle should be obtained.</param>
        /// <returns>Width as X and Height as Y of the window client area requested.</returns>
        public static Point GetClientAreaSize2(IntPtr windowHandle)
        {
            // Get Window Client-Area
            Structures.WinapiRectangle windowClientArea = GetClientAreaSize(windowHandle);

            // Return window internal size.
            return(new Point(windowClientArea.RightBorder, windowClientArea.BottomBorder));
        }
        /// <summary>
        /// Retrieves the window size.
        /// i.e. The X and Y sizes, in pixels including the window borders.
        /// </summary>
        /// <param name="windowHandle">Handle to the window of which the client area rectangle should be obtained.</param>
        /// <returns>Width as X and Height as Y of the window client area requested.</returns>
        public static Point GetWindowSize(IntPtr windowHandle)
        {
            // Get Window Client-Area
            Structures.WinapiRectangle windowSizeRectangle = GetWindowRectangle(windowHandle);

            // Define height and width
            int windowWidth  = windowSizeRectangle.RightBorder - windowSizeRectangle.LeftBorder;
            int windowHeight = windowSizeRectangle.BottomBorder - windowSizeRectangle.TopBorder;

            // Return window internal size.
            return(new Point(windowWidth, windowHeight));
        }
Beispiel #3
0
        /// <summary>
        /// Your own user code starts here.
        /// If this is your first time, do consider reading the notice above.
        /// It contains some very useful information.
        /// </summary>
        public static void Init()
        {
            /*
             *  Reloaded Mod Loader Sample: Universal Borderless Windowed
             *  Architectures supported: X86, X64
             *
             *  Waits until the game or process spawns off its initial border and then changes the
             *  window border style of the application to borderless using the Windows API.
             */

            /*
             *  We create our own thread and run it in the background because Reloaded-Loader explicitly waits
             *  for the mod's thread to return before continuing to load other mods and ultimately the game.
             *
             *  For anything we want to do in the background during initialization with Reloaded or you need to wait
             *  for the process/game for some reason, you are requires to start a background thread.
             */
            Thread setBorderlessThread = new Thread
                                         (
                () =>
            {
                // Loop infinitely until a window handle is found.
                while (GameProcess.Process.MainWindowHandle == IntPtr.Zero)
                {
                    // Sleep the thread for a sensible amount of time.
                    Thread.Sleep(2000);
                }

                // Get the window size.
                Point windowSize = WindowProperties.GetWindowSize(GameProcess.Process.MainWindowHandle);
                Structures.WinapiRectangle windowLocation = WindowProperties.GetWindowRectangle(GameProcess.Process.MainWindowHandle);

                // Get the game's Window Style.
                uint windowStyle = (uint)GetWindowLongPtr(GameProcess.Process.MainWindowHandle, GWL_STYLE);

                // Change the window style.
                windowStyle &= ~WS_BORDER;
                windowStyle &= ~WS_CAPTION;
                windowStyle &= ~WS_MAXIMIZEBOX;
                windowStyle &= ~WS_MINIMIZEBOX;

                // Set the window style.
                SetWindowLongPtr(GameProcess.Process.MainWindowHandle, GWL_STYLE, (IntPtr)windowStyle);

                // Set the window size.
                WindowFunctions.MoveWindow(GameProcess.Process.MainWindowHandle, windowLocation.LeftBorder,
                                           windowLocation.TopBorder, windowSize.X, windowSize.Y, true);
            }
                                         );

            setBorderlessThread.Start();
        }
        /// <summary>
        /// Expands the Frame Border Effect to the whole form.
        /// Normally, without background rendering and a border, a window should technically
        /// be invisible. However, this unfortunately is not the case as compositing does not default
        /// apply to the client area of the window. Well, let's just make it apply and see the windows
        /// underneath, sounds good?
        /// </summary>
        private void ExtendFrameToClientArea()
        {
            // Instantiate a new instance of the margins class.
            Structures.WinapiRectangle formMargins = new Structures.WinapiRectangle
            {
                LeftBorder   = 0,
                TopBorder    = 0,
                RightBorder  = Width,
                BottomBorder = Height
            };

            // Extend the frame into client area.
            WindowFunctions.DwmExtendFrameIntoClientArea(Handle, ref formMargins);
        }
        /// <summary>
        /// Returns the border width in terms of X and Y for a window.
        /// </summary>
        /// <returns>The border width and height as X and Y coordinates.</returns>
        public static Point GetBorderWidth(Structures.WinapiRectangle gameWindowRectangle, Structures.WinapiRectangle gameClientRectangle)
        {
            // Stores the size of the border vertically and horizontally.
            Point totalBorderSize = new Point();

            // Calculate the width and height of the window.
            int windowWidth  = gameWindowRectangle.RightBorder - gameWindowRectangle.LeftBorder;
            int windowHeight = gameWindowRectangle.BottomBorder - gameWindowRectangle.TopBorder;

            // Remove the client area width/height to leave only the borders.
            totalBorderSize.X = windowWidth - gameClientRectangle.RightBorder;
            totalBorderSize.Y = windowHeight - gameClientRectangle.BottomBorder;

            // Return the borders.
            return(totalBorderSize);
        }
        /// <summary>
        /// Returns the coordinates of the edges of the client area of a specific window
        /// relative to the desktop the window is presented on.
        /// </summary>
        /// <param name="windowHandle">Handle to the window of which the client area rectangle should be obtained.</param>
        /// <returns></returns>
        public static Structures.WinapiRectangle GetClientRectangle(IntPtr windowHandle)
        {
            // Obtains the coordinates of the edges of the window.
            WindowFunctions.GetClientRect(windowHandle, out Structures.WinapiRectangle clientAreaRectangle);

            // Get the coordinates of the top left point on the screen in client's area.
            Structures.WinapiPoint topLeftClientCoordinate = new Structures.WinapiPoint();
            WindowFunctions.ClientToScreen(windowHandle, ref topLeftClientCoordinate);

            // Calculate each edge.
            Structures.WinapiRectangle clientArea = new Structures.WinapiRectangle();
            clientArea.LeftBorder = topLeftClientCoordinate.x;
            clientArea.TopBorder  = topLeftClientCoordinate.y;

            clientArea.RightBorder  = topLeftClientCoordinate.x + clientAreaRectangle.RightBorder;
            clientArea.BottomBorder = topLeftClientCoordinate.y + clientAreaRectangle.BottomBorder;

            // Return
            return(clientArea);
        }
        /// <summary>
        /// Sets the overlay window location to overlap the window of the game instance.
        /// Both moves the window to the game location and sets appropriate height and width for the window.
        /// </summary>
        public void AdjustOverlayToGameWindow()
        {
            // Get game client edges.
            Structures.WinapiRectangle gameClientSize = WindowProperties.GetClientRectangle(GameWindowHandle);

            // Set overlay edges to the edges of the client area.
            Left = gameClientSize.LeftBorder;
            Top  = gameClientSize.TopBorder;

            // Set width and height.
            Width  = gameClientSize.RightBorder - gameClientSize.LeftBorder;
            Height = gameClientSize.BottomBorder - gameClientSize.TopBorder;

            // Call resize delegate.
            if (lastWindowSize != WindowProperties.GetClientAreaSize2(GameWindowHandle))
            {
                GameWindowResizeDelegate?.Invoke();
            }

            lastWindowSize = WindowProperties.GetClientAreaSize2(GameWindowHandle);
        }
Beispiel #8
0
        /// <summary>
        /// A crashfix for running Heroes at extreme resolutions, patches the resolution the rasters are created at.
        /// </summary>
        /// <returns></returns>
        private static int TObjCameraInitHook(int *thisPointer, int cameraLimit)
        {
            int resolutionXBackup = *_resolutionX;
            int resolutionYBackup = *_resolutionY;
            int greaterResolution = resolutionXBackup > resolutionYBackup ? resolutionXBackup : resolutionYBackup;

            // Get the window size.
            Structures.WinapiRectangle windowLocation = WindowProperties.GetWindowRectangle(GameProcess.Process.MainWindowHandle);

            // Set the window size.
            WindowFunctions.MoveWindow(GameProcess.Process.MainWindowHandle, windowLocation.LeftBorder,
                                       windowLocation.TopBorder, greaterResolution, (int)(greaterResolution / OriginalAspectRatio), false);

            int result = _someTitlecardCreateHook.OriginalFunction(thisPointer, cameraLimit);

            // Re-set the window size.
            WindowFunctions.MoveWindow(GameProcess.Process.MainWindowHandle, windowLocation.LeftBorder,
                                       windowLocation.TopBorder, resolutionXBackup, resolutionYBackup, false);

            return(result);
        }