Example #1
0
        private static IntPtr GetProcessWindow(string withClassName, EditorWindow editorWindow)
        {
            EWFDebugging.StartTimer("Getting Process Window");
            IntPtr foundWindow = IntPtr.Zero;
            string searchTitle = editorWindow.GetIdentifierTitle();

            var windowSearchPos = editorWindow.GetContainerPosition(true);

            foundWindow = GetProcessWindow(withClassName, searchTitle, windowSearchPos, true);

            //Find window only by title if couldn't find by position and title
            if (foundWindow == IntPtr.Zero)
            {
                foundWindow = GetProcessWindow(withClassName, searchTitle, new Rect(0, 0, 0, 0), true);
            }

            //Find window only by position if couldn't find by title
            if (foundWindow == IntPtr.Zero)
            {
                foundWindow = GetProcessWindow(withClassName, null, windowSearchPos, true);
            }

            EWFDebugging.LogLine("--Found EditorWindow: " + (foundWindow != IntPtr.Zero) + " with title: '" + searchTitle + "' (" + editorWindow.GetWindowType() + ")" + ", position: " + windowSearchPos);
            EWFDebugging.LogTime("Getting Process Window");
            return(foundWindow);
        }
Example #2
0
        internal static void LoadMainWindowStyleInState(EditorFullscreenState.WindowFullscreenState fullscreenState, bool makeResizable)
        {
            var windowHandle = GetProcessMainWindow();

            if (fullscreenState != null && windowHandle != IntPtr.Zero)
            {
                var setStyle = makeResizable ? (uint)fullscreenState.OriginalStyle | WS_SIZEBOX : (uint)fullscreenState.OriginalStyle;
                SetWindowLongPtr(windowHandle, GWL_STYLE, (IntPtr)(setStyle)); //Always make resizable when reloading style.
                LogWin32Error("Error setting main window style");
                SetWindowLongPtr(windowHandle, GWL_EXSTYLE, (IntPtr)fullscreenState.OriginalExStyle);
                LogWin32Error("Error setting main window ex style");
                SetWindowPos(windowHandle, IntPtr.Zero, 0, 0, 0, 0, SWP.NOZORDER | SWP.FRAMECHANGED | SWP.NOACTIVATE | SWP.NOMOVE | SWP.NOSIZE);

                if (EWFDebugging.Enabled)
                {
                    EWFDebugging.LogLine("Loaded Main Window Style: " + WindowStyleToString((IntPtr)fullscreenState.OriginalStyle));
                    EWFDebugging.LogLine("Loaded Main Window ExStyle: " + WindowExStyleToString((IntPtr)fullscreenState.OriginalExStyle));
                }
            }
        }
Example #3
0
        internal static void SaveMainWindowStyleInState(EditorFullscreenState.WindowFullscreenState fullscreenState)
        {
            var windowHandle = GetProcessMainWindow();

            if (fullscreenState != null && windowHandle != IntPtr.Zero)
            {
                var existingStyle = GetWindowLongPtr(windowHandle, GWL_STYLE);
                LogWin32Error("Error getting main window style");
                var existingExStyle = GetWindowLongPtr(windowHandle, GWL_EXSTYLE);
                LogWin32Error("Error getting main window ex style");

                fullscreenState.OriginalStyle   = (int)existingStyle;
                fullscreenState.OriginalExStyle = (int)existingExStyle;

                if (EWFDebugging.Enabled)
                {
                    EWFDebugging.LogLine("Saved Main Window Style: " + WindowStyleToString(existingStyle));
                    EWFDebugging.LogLine("Saved Main Window ExStyle: " + WindowExStyleToString(existingExStyle));
                }
            }
        }
Example #4
0
        /// <summary>
        /// Get the handle to a window within the process using the following search parameters.
        /// </summary>
        /// <param name="withClassName">Only matches windows with this class name. If null, ignores the class name.</param>
        /// <param name="withTitleMatching">Only matches windows with this title. If null, ignores the title.</param>
        /// <param name="withRectMatching">Only matches windows which match this Rect position. If a zero rect, ignores this param.</param>
        /// <param name="fullTitleMatch">True if a full title match is required, or false if only need a partial match.</param>
        /// <returns></returns>
        private static IntPtr GetProcessWindow(string withClassName, string withTitleMatching, Rect withRectMatching, bool fullTitleMatch)
        {
            IntPtr hFoundWindow  = IntPtr.Zero;
            int    processID     = System.Diagnostics.Process.GetCurrentProcess().Id;
            bool   foundAMatch   = false;
            float  bestCloseness = Mathf.Infinity;
            string logInfo       = "";

            logInfo += ("-----Looping through process windows. Process ID: " + processID + ". Looking for window: " + withClassName + ":" + (withTitleMatching == null ? "null" : withTitleMatching) + " fullTitleMatch: " + fullTitleMatch) + "\n";
            EnumWindows(
                delegate(IntPtr windowHandle, IntPtr lParam)
            {
                uint winProcessID;
                GetWindowThreadProcessId(windowHandle, out winProcessID);
                LogWin32Error("Error getting process ID");

                if (winProcessID == processID)
                {
                    StringBuilder className = new StringBuilder(256);

                    GetClassName(windowHandle, className, className.Capacity);
                    LogWin32Error("Error getting class name");

                    if (withClassName == null || className.ToString() == withClassName)
                    {
                        string titleText = SendMessageGetWindowText(windowHandle);
                        if (EWFDebugging.Enabled)
                        {
                            LogWin32Error("Error getting window title text");
                        }
                        logInfo += ("-----  Window Class Name: '" + className.ToString() + "'. Window Title: '" + titleText) + "'\n";

                        if (withTitleMatching != null && ((!fullTitleMatch && titleText.Contains(withTitleMatching)) || titleText == withTitleMatching) ||
                            withTitleMatching == null && !withRectMatching.IsZero())
                        {
                            Rect windowBounds           = new Rect(0, 0, 0, 0);
                            bool windowPositionMatch    = true;
                            bool windowBoundsExactMatch = true;
                            float windowPosCloseness    = 0;

                            //If withRectMatching is 0 then don't check it.
                            if (!withRectMatching.IsZero())
                            {
                                windowBounds           = GetWindowBounds(windowHandle);
                                windowPositionMatch    = windowBounds.x == withRectMatching.x && windowBounds.y == withRectMatching.y;
                                windowBoundsExactMatch = windowBounds == withRectMatching;
                                windowPosCloseness     = windowBounds.Closeness(withRectMatching);
                                logInfo += "-----    Comparing window bounds: " + windowBounds + " with rect: " + withRectMatching + "\n";
                                logInfo += "-----    Position Match: " + windowPositionMatch + ", Bounds Exact Match: " + (windowBounds == withRectMatching) + ", Closeness: " + windowPosCloseness + "\n";
                            }
                            if (windowPositionMatch || windowPosCloseness < 75)
                            {
                                foundAMatch = true;
                                if (withTitleMatching == "Unity" && windowPositionMatch)
                                {
                                    //Looking for the main Unity window
                                    hFoundWindow = windowHandle;

                                    //If the window title contains the Unity version, this must be the main window, so exit enumeration. Otherwise, get the last one (least z-index) which contains "Unity".
                                    if (titleText.ToString().Contains(Application.unityVersion))
                                    {
                                        logInfo += "-----    Found main window matching '*Unity*, *unityVersion*'\n";
                                        return(false);
                                    }
                                }
                                else
                                {
                                    //Find the closest match window size
                                    if (windowBoundsExactMatch || windowPosCloseness < bestCloseness)
                                    {
                                        hFoundWindow  = windowHandle;
                                        bestCloseness = windowPosCloseness;
                                    }
                                    if (windowBoundsExactMatch)
                                    {
                                        return(false);    //Found an exact bounds match, so stop searching.
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (withTitleMatching == "Unity" && String.IsNullOrEmpty(titleText.ToString()))
                            {
                                if (!foundAMatch)
                                {
                                    //Get the last window (least z-index). Workaround for the bug where main window can't be found on some systems because GetWindowText returns nothing.
                                    hFoundWindow = windowHandle;
                                }
                            }
                        }
                    }
                }
                return(true);
            }, IntPtr.Zero);
            LogWin32Error("Error when finding window of class: '" + withClassName + "', and title '" + withTitleMatching + "' Looking for full match: " + fullTitleMatch);
            logInfo += "-----Found window: " + (hFoundWindow != IntPtr.Zero) + ", handle: " + hFoundWindow.ToString();
            EWFDebugging.LogLine(logInfo, 0, 4);
            return(hFoundWindow);
        }
Example #5
0
        public static List <SystemDisplay> GetAllDisplays()
        {
            List <SystemDisplay> allDisplays = new List <SystemDisplay>();
            IntPtr hMainWindowMonitor        = IntPtr.Zero;
            IntPtr mainWindowHandle          = IntPtr.Zero;

            EWFDebugging.LogLine("Getting all displays.", 0, 4);
            try
            {
                mainWindowHandle = GetProcessMainWindow();
                if (mainWindowHandle != IntPtr.Zero)
                {
                    var mainWindowMonitorInfoEx = MonitorInfoEx.CreateWithDefaults();
                    hMainWindowMonitor = MonitorFromWindow(mainWindowHandle, MONITOR_DEFAULTTONEAREST);
                    LogWin32Error("Error finding main window monitor");
                    if (hMainWindowMonitor != IntPtr.Zero)
                    {
                        GetMonitorInfo(hMainWindowMonitor, ref mainWindowMonitorInfoEx);
                        LogWin32Error("Error getting main window monitor info");
                    }
                }
                else
                {
                    EWFDebugging.LogError("Could not find the process main window handle.");
                }
            }
            catch (Exception e)
            {
                string err = "Error finding the main window monitor. " + e.ToString();
                Debug.LogError(err);
                EWFDebugging.LogError(err);
            }

            var deviceDisplayMonitorCount = new Dictionary <string, uint>();

            EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
                                delegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RectStruct lprcMonitor, IntPtr dwData)
            {
                try
                {
                    //Get the monitor info
                    var monitorInfoEx = MonitorInfoEx.CreateWithDefaults();
                    GetMonitorInfo(hMonitor, ref monitorInfoEx);
                    LogWin32Error();

                    //Get the associated display device
                    bool mirroringDriver   = false;
                    bool attachedToDesktop = false;
                    string deviceName      = monitorInfoEx.DeviceName;

                    if (!deviceDisplayMonitorCount.ContainsKey(deviceName))
                    {
                        deviceDisplayMonitorCount.Add(deviceName, 0);
                    }
                    deviceDisplayMonitorCount[deviceName] += 1;

                    var displayDevice  = Display_Device.CreateWithDefaults();
                    int displayMonitor = 0;
                    for (uint id = 0; EnumDisplayDevices(deviceName, id, ref displayDevice, 0); id++)
                    {
                        attachedToDesktop = ((displayDevice.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == DisplayDeviceStateFlags.AttachedToDesktop);

                        if (attachedToDesktop)
                        {
                            displayMonitor++;
                            if (displayMonitor == deviceDisplayMonitorCount[deviceName])
                            {
                                mirroringDriver = ((displayDevice.StateFlags & DisplayDeviceStateFlags.MirroringDriver) == DisplayDeviceStateFlags.MirroringDriver);
                                break;     //Found the display device which matches the monitor
                            }
                        }

                        displayDevice.Size = Marshal.SizeOf(displayDevice);
                    }

                    //Skip the monitor if it's a pseudo monitor
                    if (mirroringDriver)
                    {
                        return(true);
                    }

                    //Store the monitor info in a SystemDisplay object
                    var display  = new SystemDisplay();
                    display.Name = displayDevice.DeviceString;
                    display.AttachedToDesktop = attachedToDesktop;     //Should always be true within EnumDisplayMonitors
                    display.IsPrimary         = monitorInfoEx.Flags == (uint)1;
                    display.HasMainWindow     = (hMonitor == hMainWindowMonitor);
                    display.Bounds            = RectFromRectStruct(lprcMonitor);
                    display.WorkArea          = RectFromRectStruct(monitorInfoEx.WorkAreaBounds);

                    var devMode = new DEVMODE();
                    EnumDisplaySettings(monitorInfoEx.DeviceName, ENUM_CURRENT_SETTINGS, ref devMode);
                    display.PixelWidth  = devMode.dmPelsWidth;
                    display.PixelHeight = devMode.dmPelsHeight;

                    //Add the SystemDisplay to allDisplays
                    allDisplays.Add(display);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    EWFDebugging.LogError(e.ToString());
                }
                LogWin32Error();

                return(true);    //Continue the enumeration
            }, IntPtr.Zero);
            LogWin32Error();

            //Calculate physical bounds
            foreach (var display in allDisplays)
            {
                Rect physicalBounds = display.Bounds;
                physicalBounds.width  = display.PixelWidth;
                physicalBounds.height = display.PixelHeight;
                Vector2 displayTopLeft = new Vector2(display.Bounds.xMin, display.Bounds.yMin);

                var displayTopLeftPhysical = GetPhysicalPoint(mainWindowHandle, displayTopLeft);
                physicalBounds.x       = displayTopLeftPhysical.x;
                physicalBounds.y       = displayTopLeftPhysical.y;
                display.PhysicalBounds = physicalBounds;
            }

            return(allDisplays);
        }
Example #6
0
        /// Makes sure a window covers the taskbar when it is fullscreen
        private static bool MakeWindowCoverTaskBar(EditorWindow editorWindow, string windowClass, string windowTitle, SystemDisplay display)
        {
            IntPtr windowHandle = IntPtr.Zero;

            EWFDebugging.StartTimer("Making window cover taskbar");
            EWFDebugging.LogLine("Making window cover taskbar. " + (editorWindow == null ? "WindowTitle: " + (windowTitle == null ? "null" : windowTitle) : "EditorWindow: '" + editorWindow.GetWindowTitle() + "' Window Type: '" + editorWindow.GetType() + "' with class: '" + (windowClass == null ? "null" : windowClass) + "'"));
            if (editorWindow == null)
            {
                string fullscreenWindowClass = windowClass != null ? windowClass : "UnityPopupWndClass";
                windowHandle = GetProcessWindow(fullscreenWindowClass, windowTitle, true);
                if (windowHandle == IntPtr.Zero)
                {
                    windowHandle = GetProcessWindow(null, windowTitle, true);
                }
            }
            else
            {
                if (windowClass == null)
                {
                    windowHandle = GetProcessWindow(editorWindow);
                }
                else
                {
                    windowHandle = GetProcessWindow(windowClass, editorWindow);
                }
            }

            if (windowHandle == IntPtr.Zero)
            {
                EWFDebugging.LogError("Couldn't find window handle.");
                return(false);
            }

            IntPtr existingStyle   = GetWindowLongPtr(windowHandle, GWL_STYLE);
            IntPtr existingExStyle = GetWindowLongPtr(windowHandle, GWL_EXSTYLE);

            if (editorWindow != null)
            {
                var state = EditorFullscreenState.FindWindowState(editorWindow);
                if (state.OriginalStyle == 0)
                {
                    state.OriginalStyle = (int)existingStyle;
                }
                if (state.OriginalExStyle == 0)
                {
                    state.OriginalExStyle = (int)existingExStyle;
                }
            }

            if (EWFDebugging.Enabled)
            {
                EWFDebugging.LogLine("before Style: " + WindowStyleToString(existingStyle));
                EWFDebugging.LogLine("before ExStyle: " + WindowExStyleToString(existingExStyle));
            }

            SetWindowLongPtr(windowHandle, GWL_STYLE, (IntPtr)(WS_POPUP | WS_VISIBLE | ((uint)existingStyle & (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPED))));
            LogWin32Error("Error setting window style");

            SetWindowLongPtr(windowHandle, GWL_EXSTYLE, (IntPtr)((uint)existingExStyle & (WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR)));
            LogWin32Error("Error setting window ex style");

            SetWindowPos(windowHandle, IntPtr.Zero, (int)display.Bounds.x, (int)display.Bounds.y, (int)display.Bounds.width, (int)display.Bounds.height,
                         SWP.NOZORDER | SWP.FRAMECHANGED | SWP.NOACTIVATE);
            LogWin32Error("Error setting window position");

            if (EWFDebugging.Enabled)
            {
                existingStyle   = GetWindowLongPtr(windowHandle, GWL_STYLE);
                existingExStyle = GetWindowLongPtr(windowHandle, GWL_EXSTYLE);
                EWFDebugging.LogLine("after Style: " + WindowStyleToString(existingStyle));
                EWFDebugging.LogLine("after ExStyle: " + WindowExStyleToString(existingExStyle));
                EWFDebugging.LogTime("Making window cover taskbar");
            }

            return(true);
        }