Code:
/ FX-1434 / FX-1434 / 1.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;
///
///
///
/// Represents a display device or
/// multiple display devices on a single system.
///
///
public class Screen {
readonly IntPtr hmonitor;
///
/// 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));
}
}
///
///
///
/// Gets an array of all of the displays on the system.
///
///
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 Bits per Pixel value.
///
///
public int BitsPerPixel {
get {
return bitDepth;
}
}
///
///
///
/// Gets the bounds of the display.
///
///
public Rectangle Bounds {
get {
return bounds;
}
}
///
///
///
/// Gets the device name associated with a display.
///
///
public string DeviceName {
get {
return deviceName;
}
}
///
///
///
/// Gets a value indicating whether a particular display is
/// the primary device.
///
///
public bool Primary {
get {
return primary;
}
}
///
///
///
/// Gets the
/// primary display.
///
///
public static Screen PrimaryScreen {
get {
if (multiMonitorSupport) {
Screen[] screens = AllScreens;
for (int i=0; i
///
///
/// Gets the working area of the screen.
///
///
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;
}
}
///
/// 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;
}
}
///
///
///
/// Specifies a value that indicates whether the specified object is equal to
/// this one.
///
///
public override bool Equals(object obj) {
if (obj is Screen) {
Screen comp = (Screen)obj;
if (hmonitor == comp.hmonitor) {
return true;
}
}
return false;
}
///
///
///
/// Retrieves a
/// for the monitor that contains the specified point.
///
///
///
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
/// largest region of the rectangle.
///
///
///
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 window of the control.
///
///
public static Screen FromControl(Control control) {
return FromHandleInternal(control.Handle);
}
///
///
///
/// Retrieves a
/// for the monitor that
/// contains the largest region of the window.
///
///
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 the working area for the monitor that is closest to the
/// specified point.
///
///
///
public static Rectangle GetWorkingArea(Point pt) {
return Screen.FromPoint(pt).WorkingArea;
}
///
///
///
/// Retrieves the working area for the monitor that contains the largest region
/// of the specified rectangle.
///
///
///
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 control.
///
///
///
public static Rectangle GetWorkingArea(Control ctl) {
return Screen.FromControl(ctl).WorkingArea;
}
///
///
///
/// Retrieves the bounds of the monitor that is closest to the specified
/// point.
///
///
public static Rectangle GetBounds(Point pt) {
return Screen.FromPoint(pt).Bounds;
}
///
///
///
/// Retrieves the bounds of the monitor that contains the largest region of the
/// specified rectangle.
///
///
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 control.
///
///
public static Rectangle GetBounds(Control ctl) {
return Screen.FromControl(ctl).Bounds;
}
///
///
///
/// Computes and retrieves a hash code for an object.
///
///
public override int GetHashCode() {
return(int)hmonitor;
}
///
/// 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);
}
}
///
///
///
/// Retrieves a string representing this object.
///
///
public override string ToString() {
return GetType().Name + "[Bounds=" + bounds.ToString() + " WorkingArea=" + WorkingArea.ToString() + " Primary=" + primary.ToString() + " DeviceName=" + deviceName;
}
///
///
///
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
- RIPEMD160.cs
- ApplicationSecurityManager.cs
- SchemaCollectionPreprocessor.cs
- MailHeaderInfo.cs
- PageRequestManager.cs
- SqlClientWrapperSmiStream.cs
- UnsafeNativeMethods.cs
- TableLayoutPanelResizeGlyph.cs
- PathSegment.cs
- TypeListConverter.cs
- DataGridViewCellFormattingEventArgs.cs
- StrongTypingException.cs
- BoundConstants.cs
- ContentPlaceHolder.cs
- QilTargetType.cs
- mediaeventargs.cs
- Simplifier.cs
- RepeatButton.cs
- WebPartConnectionsCloseVerb.cs
- BooleanExpr.cs
- WebMessageEncoderFactory.cs
- StatusBarPanelClickEvent.cs
- PageContentAsyncResult.cs
- WindowsAuthenticationEventArgs.cs
- PropertyValueChangedEvent.cs
- UnsafeNativeMethods.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- PartitionedDataSource.cs
- ToolStripItemRenderEventArgs.cs
- CompositionCommandSet.cs
- Separator.cs
- StaticSiteMapProvider.cs
- WebPartDisplayModeCancelEventArgs.cs
- WindowsNonControl.cs
- SignatureResourcePool.cs
- DataGridViewCellEventArgs.cs
- ActivityExecutorSurrogate.cs
- odbcmetadatacollectionnames.cs
- Ref.cs
- OpCodes.cs
- IncrementalReadDecoders.cs
- ObjectToIdCache.cs
- DbMetaDataFactory.cs
- Properties.cs
- ReaderContextStackData.cs
- TreeViewItemAutomationPeer.cs
- GridViewCancelEditEventArgs.cs
- CodeNamespace.cs
- RegexMatchCollection.cs
- DesignTimeVisibleAttribute.cs
- FontUnit.cs
- DoubleLinkList.cs
- SwitchCase.cs
- RectAnimationClockResource.cs
- EventHandlerList.cs
- ConfigurationException.cs
- DynamicDataExtensions.cs
- DataSourceHelper.cs
- BigInt.cs
- UpdateTracker.cs
- ComUdtElement.cs
- Compiler.cs
- ContextProperty.cs
- GenericTypeParameterBuilder.cs
- UnitControl.cs
- CrossAppDomainChannel.cs
- VisualStyleTypesAndProperties.cs
- SystemException.cs
- CachedTypeface.cs
- RSAProtectedConfigurationProvider.cs
- OwnerDrawPropertyBag.cs
- CodeIdentifiers.cs
- CommonObjectSecurity.cs
- WebAdminConfigurationHelper.cs
- X509WindowsSecurityToken.cs
- WebPartEditVerb.cs
- NavigatingCancelEventArgs.cs
- RoleManagerEventArgs.cs
- indexingfiltermarshaler.cs
- OleAutBinder.cs
- ComplexTypeEmitter.cs
- DoubleAnimationClockResource.cs
- ToggleButton.cs
- SqlProcedureAttribute.cs
- ProcessThreadCollection.cs
- EventDescriptor.cs
- Types.cs
- SimpleTextLine.cs
- Polyline.cs
- DocumentProperties.cs
- HttpListenerElement.cs
- WinCategoryAttribute.cs
- BitmapFrameDecode.cs
- HashCodeCombiner.cs
- HandlerMappingMemo.cs
- EpmCustomContentSerializer.cs
- HwndPanningFeedback.cs
- MessageLoggingElement.cs
- XmlSerializationReader.cs
- EntityContainer.cs