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