/// <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)); }
/// <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); }
/// <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); }