Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / Screen.cs / 1 / Screen.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms { using System.Threading; using System.Runtime.InteropServices; using System.Diagnostics; using System; using System.Drawing; using System.Windows.Forms; using System.Collections; using Microsoft.Win32; ////// /// public class Screen { readonly IntPtr hmonitor; ////// Represents a display device or /// multiple display devices on a single system. /// ////// Bounds of the screen /// readonly Rectangle bounds; ////// Available working area on the screen. This excludes taskbars and other /// docked windows. /// private Rectangle workingArea = Rectangle.Empty; ////// Set to true if this screen is the primary monitor /// readonly bool primary; ////// Device name associated with this monitor /// readonly string deviceName; readonly int bitDepth; private static object syncLock = new object();//used to lock this class before sync'ing to SystemEvents private static int desktopChangedCount = -1;//static counter of desktop size changes private int currentDesktopChangedCount = -1;//instance-based counter used to invalidate WorkingArea // This identifier is just for us, so that we don't try to call the multimon // functions if we just need the primary monitor... this is safer for // non-multimon OSes. // private const int PRIMARY_MONITOR = unchecked((int)0xBAADF00D); private const int MONITOR_DEFAULTTONULL = 0x00000000; private const int MONITOR_DEFAULTTOPRIMARY = 0x00000001; private const int MONITOR_DEFAULTTONEAREST = 0x00000002; private const int MONITORINFOF_PRIMARY = 0x00000001; private static bool multiMonitorSupport = (UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CMONITORS) != 0); private static Screen[] screens; internal Screen(IntPtr monitor) : this(monitor, IntPtr.Zero) { } internal Screen(IntPtr monitor, IntPtr hdc) { IntPtr screenDC = hdc; if (!multiMonitorSupport || monitor == (IntPtr)PRIMARY_MONITOR) { // Single monitor system // bounds = SystemInformation.VirtualScreen; primary = true; deviceName = "DISPLAY"; } else { // MultiMonitor System // We call the 'A' version of GetMonitorInfoA() because // the 'W' version just never fills out the struct properly on Win2K. // NativeMethods.MONITORINFOEX info = new NativeMethods.MONITORINFOEX(); SafeNativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info); bounds = Rectangle.FromLTRB(info.rcMonitor.left, info.rcMonitor.top, info.rcMonitor.right, info.rcMonitor.bottom); primary = ((info.dwFlags & MONITORINFOF_PRIMARY) != 0); int count = info.szDevice.Length; while (count > 0 && info.szDevice[count - 1] == (char)0) { count--; } deviceName = new string(info.szDevice); deviceName = deviceName.TrimEnd((char)0); if (hdc == IntPtr.Zero) { screenDC = UnsafeNativeMethods.CreateDC(deviceName); } } hmonitor = monitor; this.bitDepth = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, screenDC), NativeMethods.BITSPIXEL); this.bitDepth *= UnsafeNativeMethods.GetDeviceCaps(new HandleRef(null, screenDC), NativeMethods.PLANES); if (hdc != screenDC) { UnsafeNativeMethods.DeleteDC(new HandleRef(null, screenDC)); } } ////// /// public static Screen[] AllScreens { get { if (screens == null) { if (multiMonitorSupport) { MonitorEnumCallback closure = new MonitorEnumCallback(); NativeMethods.MonitorEnumProc proc = new NativeMethods.MonitorEnumProc(closure.Callback); IntPtr hdc = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef); try { SafeNativeMethods.EnumDisplayMonitors(new HandleRef(null, hdc), null, proc, IntPtr.Zero); } finally { UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, hdc)); } if (closure.screens.Count > 0) { Screen[] temp = new Screen[closure.screens.Count]; closure.screens.CopyTo(temp, 0); screens = temp; } else { screens = new Screen[] {new Screen((IntPtr)PRIMARY_MONITOR)}; } } else { screens = new Screen[] {PrimaryScreen}; } // Now that we have our screens, attach a display setting changed // event so that we know when to invalidate them. // SystemEvents.DisplaySettingsChanging += new EventHandler(OnDisplaySettingsChanging); } return screens; } } ////// Gets an array of all of the displays on the system. /// ////// /// public int BitsPerPixel { get { return bitDepth; } } ////// Gets Bits per Pixel value. /// ////// /// public Rectangle Bounds { get { return bounds; } } ////// Gets the bounds of the display. /// ////// /// public string DeviceName { get { return deviceName; } } ////// Gets the device name associated with a display. /// ////// /// public bool Primary { get { return primary; } } ////// Gets a value indicating whether a particular display is /// the primary device. /// ////// /// public static Screen PrimaryScreen { get { if (multiMonitorSupport) { Screen[] screens = AllScreens; for (int i=0; i/// Gets the /// primary display. /// ////// /// public Rectangle WorkingArea { get { //if the static Screen class has a different desktop change count //than this instance then update the count and recalculate our working area if (currentDesktopChangedCount != Screen.DesktopChangedCount) { Interlocked.Exchange(ref currentDesktopChangedCount, Screen.DesktopChangedCount); if (!multiMonitorSupport ||hmonitor == (IntPtr)PRIMARY_MONITOR) { // Single monitor system // workingArea = SystemInformation.WorkingArea; } else { // MultiMonitor System // We call the 'A' version of GetMonitorInfoA() because // the 'W' version just never fills out the struct properly on Win2K. // NativeMethods.MONITORINFOEX info = new NativeMethods.MONITORINFOEX(); SafeNativeMethods.GetMonitorInfo(new HandleRef(null, hmonitor), info); workingArea = Rectangle.FromLTRB(info.rcWork.left, info.rcWork.top, info.rcWork.right, info.rcWork.bottom); } } return workingArea; } } ////// Gets the working area of the screen. /// ////// Screen instances call this property to determine /// if their WorkingArea cache needs to be invalidated. /// private static int DesktopChangedCount { get { if (desktopChangedCount == -1) { lock (syncLock) { //now that we have a lock, verify (again) our changecount... if (desktopChangedCount == -1) { //sync the UserPreference.Desktop change event. We'll keep count //of desktop changes so that the WorkingArea property on Screen //instances know when to invalidate their cache. SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); desktopChangedCount = 0; } } } return desktopChangedCount; } } ////// /// public override bool Equals(object obj) { if (obj is Screen) { Screen comp = (Screen)obj; if (hmonitor == comp.hmonitor) { return true; } } return false; } ////// Specifies a value that indicates whether the specified object is equal to /// this one. /// ////// /// public static Screen FromPoint(Point point) { if (multiMonitorSupport) { NativeMethods.POINTSTRUCT pt = new NativeMethods.POINTSTRUCT(point.X, point.Y); return new Screen(SafeNativeMethods.MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST)); } else { return new Screen((IntPtr)PRIMARY_MONITOR); } } ////// Retrieves a ////// for the monitor that contains the specified point. /// /// /// /// public static Screen FromRectangle(Rectangle rect) { if (multiMonitorSupport) { NativeMethods.RECT rc = NativeMethods.RECT.FromXYWH(rect.X, rect.Y, rect.Width, rect.Height); return new Screen(SafeNativeMethods.MonitorFromRect(ref rc, MONITOR_DEFAULTTONEAREST)); } else { return new Screen((IntPtr)PRIMARY_MONITOR, IntPtr.Zero); } } ////// Retrieves a ////// for the monitor that contains the /// largest region of the rectangle. /// /// /// /// public static Screen FromControl(Control control) { return FromHandleInternal(control.Handle); } ////// Retrieves a ////// for the monitor that contains the largest /// region of the window of the control. /// /// /// public static Screen FromHandle(IntPtr hwnd) { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "ObjectFromWin32Handle Demanded"); IntSecurity.ObjectFromWin32Handle.Demand(); return FromHandleInternal(hwnd); } internal static Screen FromHandleInternal(IntPtr hwnd) { if (multiMonitorSupport) { return new Screen(SafeNativeMethods.MonitorFromWindow(new HandleRef(null, hwnd), MONITOR_DEFAULTTONEAREST)); } else { return new Screen((IntPtr)PRIMARY_MONITOR, IntPtr.Zero); } } ////// Retrieves a ////// for the monitor that /// contains the largest region of the window. /// /// /// public static Rectangle GetWorkingArea(Point pt) { return Screen.FromPoint(pt).WorkingArea; } ////// Retrieves the working area for the monitor that is closest to the /// specified point. /// /// ////// /// public static Rectangle GetWorkingArea(Rectangle rect) { return Screen.FromRectangle(rect).WorkingArea; } ////// Retrieves the working area for the monitor that contains the largest region /// of the specified rectangle. /// /// ////// /// public static Rectangle GetWorkingArea(Control ctl) { return Screen.FromControl(ctl).WorkingArea; } ////// Retrieves the working area for the monitor that contains the largest /// region of the specified control. /// /// ////// /// public static Rectangle GetBounds(Point pt) { return Screen.FromPoint(pt).Bounds; } ////// Retrieves the bounds of the monitor that is closest to the specified /// point. /// ////// /// public static Rectangle GetBounds(Rectangle rect) { return Screen.FromRectangle(rect).Bounds; } ////// Retrieves the bounds of the monitor that contains the largest region of the /// specified rectangle. /// ////// /// public static Rectangle GetBounds(Control ctl) { return Screen.FromControl(ctl).Bounds; } ////// Retrieves the bounds of the monitor /// that contains the largest region of the specified control. /// ////// /// public override int GetHashCode() { return(int)hmonitor; } ////// Computes and retrieves a hash code for an object. /// ////// Called by the SystemEvents class when our display settings are /// changing. We cache screen information and at this point we must /// invalidate our cache. /// private static void OnDisplaySettingsChanging(object sender, EventArgs e) { // Now that we've responded to this event, we don't need it again until // someone re-queries. We will re-add the event at that time. // SystemEvents.DisplaySettingsChanging -= new EventHandler(OnDisplaySettingsChanging); // Display settings changed, so the set of screens we have is invalid. // screens = null; } ////// Called by the SystemEvents class when our display settings have /// changed. Here, we increment a static counter that Screen instances /// can check against to invalidate their cache. /// private static void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { if (e.Category == UserPreferenceCategory.Desktop) { Interlocked.Increment(ref desktopChangedCount); } } ////// /// public override string ToString() { return GetType().Name + "[Bounds=" + bounds.ToString() + " WorkingArea=" + WorkingArea.ToString() + " Primary=" + primary.ToString() + " DeviceName=" + deviceName; } ////// Retrieves a string representing this object. /// ////// /// private class MonitorEnumCallback { public ArrayList screens = new ArrayList(); public virtual bool Callback(IntPtr monitor, IntPtr hdc, IntPtr lprcMonitor, IntPtr lparam) { screens.Add(new Screen(monitor, hdc)); return true; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ConstructorBuilder.cs
- DynamicValidator.cs
- ListViewInsertedEventArgs.cs
- Constraint.cs
- FontInfo.cs
- TextServicesCompartmentContext.cs
- RegistryPermission.cs
- XmlAnyAttributeAttribute.cs
- XmlSerializationReader.cs
- HtmlInputImage.cs
- CodeTypeReference.cs
- DesignOnlyAttribute.cs
- UrlPropertyAttribute.cs
- StaticContext.cs
- XmlSchemaParticle.cs
- Ipv6Element.cs
- LayoutUtils.cs
- EdmProperty.cs
- WhitespaceRuleReader.cs
- Renderer.cs
- XLinq.cs
- WindowAutomationPeer.cs
- MultiBinding.cs
- ArcSegment.cs
- TreeNodeStyle.cs
- ToolStripOverflow.cs
- DoubleCollectionConverter.cs
- SmtpClient.cs
- IPEndPoint.cs
- OpCodes.cs
- ToolboxItemCollection.cs
- DataSourceCacheDurationConverter.cs
- FocusManager.cs
- AuthenticateEventArgs.cs
- TileBrush.cs
- ReservationNotFoundException.cs
- AutomationTextAttribute.cs
- CryptoKeySecurity.cs
- WrapPanel.cs
- ResourcePermissionBaseEntry.cs
- WebPartMinimizeVerb.cs
- OracleColumn.cs
- PrinterResolution.cs
- ShapingEngine.cs
- RegexGroup.cs
- TypeSystemProvider.cs
- BaseTemplateCodeDomTreeGenerator.cs
- VersionUtil.cs
- EntityContainerRelationshipSetEnd.cs
- TagNameToTypeMapper.cs
- IntegerFacetDescriptionElement.cs
- CancellationHandlerDesigner.cs
- WorkflowInstanceContextProvider.cs
- EventLogLink.cs
- PanelStyle.cs
- ObjectDataSourceMethodEventArgs.cs
- Pen.cs
- FormatConvertedBitmap.cs
- SafeFileHandle.cs
- ProfileServiceManager.cs
- Normalization.cs
- ConstraintCollection.cs
- XamlPoint3DCollectionSerializer.cs
- KeyValueInternalCollection.cs
- IpcPort.cs
- SerialErrors.cs
- XmlSchemaAppInfo.cs
- DataGridViewRowsAddedEventArgs.cs
- DisplayMemberTemplateSelector.cs
- DataGridViewEditingControlShowingEventArgs.cs
- ExceptionUtility.cs
- WebConfigurationHost.cs
- BookmarkOptionsHelper.cs
- BevelBitmapEffect.cs
- Int32Collection.cs
- ListBoxChrome.cs
- InvalidContentTypeException.cs
- TdsEnums.cs
- RemotingConfiguration.cs
- CounterSample.cs
- SessionStateUtil.cs
- XmlSchemaSimpleTypeRestriction.cs
- X509DefaultServiceCertificateElement.cs
- RowsCopiedEventArgs.cs
- SiteMapDataSourceDesigner.cs
- TextLineBreak.cs
- CodeLinePragma.cs
- Delay.cs
- BlobPersonalizationState.cs
- CheckBox.cs
- CopyNamespacesAction.cs
- PermissionListSet.cs
- EnumValAlphaComparer.cs
- ColorConverter.cs
- TreeWalkHelper.cs
- Win32.cs
- ContourSegment.cs
- BitmapEffectInput.cs
- TdsEnums.cs
- EarlyBoundInfo.cs