Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / AccessibleTech / longhorn / Automation / Win32Providers / MS / Internal / AutomationProxies / WindowsTooltip.cs / 1 / WindowsTooltip.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Tooltip Proxy // // History: // 07/01/2003 : a-jeanp Created //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using System; using System.Globalization; using System.Text; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Windows; using System.Runtime.InteropServices; using System.ComponentModel; using MS.Win32; namespace MS.Internal.AutomationProxies { // Class definition for the WindowsTooltip proxy. class WindowsTooltip : ProxyHwnd { // ----------------------------------------------------- // // Constructors // // ----------------------------------------------------- #region Constructors // Contructor for the tooltip proxy class. WindowsTooltip (IntPtr hwnd, ProxyFragment parent, int item) : base( hwnd, parent, item) { // Set the control type string to return properly the properties. _cControlType = ControlType.ToolTip; // support for events _createOnEvent = new WinEventTracker.ProxyRaiseEvents (RaiseEvents); } #endregion #region Proxy Create // Static Create method called by UIAutomation to create this proxy. // returns null if unsuccessful internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild, int idObject) { return Create(hwnd, idChild); } private static IRawElementProviderSimple Create(IntPtr hwnd, int idChild) { // Something is wrong if idChild is not zero if (idChild != 0) { System.Diagnostics.Debug.Assert (idChild == 0, "Invalid Child Id, idChild != 0"); throw new ArgumentOutOfRangeException("idChild", idChild, SR.Get(SRID.ShouldBeZero)); } return new WindowsTooltip(hwnd, null, idChild); } // Static create method called by the event tracker system. // WinEvents are raised only when a notification has been set for a // specific item. internal static void RaiseEvents (IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if (idObject != NativeMethods.OBJID_VSCROLL && idObject != NativeMethods.OBJID_HSCROLL) { WindowsTooltip wtv = new WindowsTooltip(hwnd, null, 0); wtv.DispatchEvents(eventId, idProp, idObject, idChild); } } #endregion Proxy Create #region ProxyHwnd Interface internal override void AdviseEventAdded( AutomationEvent eventId, AutomationProperty[] aidProps ) { base.AdviseEventAdded( eventId, aidProps ); // If the framework is advising for ToolTipOpenedEvent then go ahead and raise this event now // since the WinEvent we would listen to (usually EVENT_OBJECT_SHOW) has already occurrred // (it is why Advise is being called). No other action is necessary because when this ToolTip // goes away, AdviseEventRemoved is going to be called. In other words, this proxy gets // created when the ToolTip opens and thrown away when it closes so no need to keep state // that we want to listen for more SHOWS or CREATES - there's always one for any one instance. if( eventId == AutomationElement.ToolTipOpenedEvent ) { AutomationEventArgs e = new AutomationEventArgs(AutomationElement.ToolTipOpenedEvent); AutomationInteropProvider.RaiseAutomationEvent(AutomationElement.ToolTipOpenedEvent, this, e); } else if( eventId == AutomationElement.ToolTipClosedEvent ) { // subscribe to ToolTip specific events, keeping track of how many times the event has been added WinEventTracker.AddToNotificationList( IntPtr.Zero, new WinEventTracker.ProxyRaiseEvents( OnToolTipEvents ), _toolTipEventIds, _toolTipEventIds.Length ); _listenerCount++; } } internal override void AdviseEventRemoved( AutomationEvent eventId, AutomationProperty[] aidProps ) { base.AdviseEventRemoved(eventId, aidProps); // For now, ToolTips only raise ToolTip-specific events when they close if( eventId != AutomationElement.ToolTipClosedEvent ) return; if( _listenerCount > 0 ) { // decrement the event counter --_listenerCount; WinEventTracker.RemoveToNotificationList( IntPtr.Zero, _toolTipEventIds, new WinEventTracker.ProxyRaiseEvents( OnToolTipEvents ), _toolTipEventIds.Length ); } } #endregion ProxyHwnd Interface //------------------------------------------------------ // // Patterns Implementation // //----------------------------------------------------- #region ProxySimple Interface //Gets the localized name internal override string LocalizedName { get { return GetText(); } } #endregion //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods private static void OnToolTipEvents( IntPtr hwnd, int eventId, object idProp, int idObject, int idChild ) { if (idObject != NativeMethods.OBJID_WINDOW) { return; } if (!IsToolTip(hwnd)) { return; } // Raise ToolTipClosedEvent on OBJECT_HIDE WinEvents. Not raising the event for EVENT_OBJECT_DESTROY // because to do this means having to change code downstream from RaiseAutomationEvent to accept a // null src. PS #1007309 (Client-side proxies that raise events end up going through server-side // code) would be a good time to fix this issue (may then be able to pass null src). Most tool tips // currently get created, then shown and hidden, and are destroyed when the app exits so the impact // here should be minimal since the ToolTip is probaby not showing when the app exits. if( eventId == NativeMethods.EVENT_OBJECT_HIDE /*|| eventId == NativeMethods.EVENT_OBJECT_DESTROY*/ ) { WindowsTooltip wtv = new WindowsTooltip( hwnd, null, 0 ); AutomationEventArgs e = new AutomationEventArgs( AutomationElement.ToolTipClosedEvent ); AutomationInteropProvider.RaiseAutomationEvent( AutomationElement.ToolTipClosedEvent, wtv, e ); } } private static bool IsToolTip( IntPtr hwnd ) { // If we can't determine this is a ToolTip then just return false if (!UnsafeNativeMethods.IsWindow(hwnd)) { return false; } string className = Misc.ProxyGetClassName(hwnd); return String.Compare(className, "tooltips_class32", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(className, CLASS_TITLEBAR_TOOLTIP, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(className, "VBBubble", StringComparison.OrdinalIgnoreCase) == 0; } private string GetText() { string className = Misc.ProxyGetClassName(_hwnd); if (String.Compare(className, CLASS_TITLEBAR_TOOLTIP, StringComparison.OrdinalIgnoreCase) == 0) { return GetTitleBarToolTipText(); } else if (String.Compare(className, "VBBubble", StringComparison.OrdinalIgnoreCase) == 0) { // The WM_GETTEXT should work for VBBubble. It seems that the string being returned is having // a problem with Unicode covertion and therefore trunk'ing the string after the first character. } // For tooltips_class32 WM_GETTEXT works fine at getting the text off of the tooltip. return Misc.ProxyGetText(_hwnd); } // Tooltips for titlebar parts requires figuring out what titlebar part the mouse is over and returning // a string defined in this dll that represents the part. The hittesting technique is sensitive to the // desktop theme and composition. The following method uses one technique for composition and another // for all other cases. Fix for WinOS Bug #1656292 (punted to Vienna) will allow using the technique // used in GetTitleBarToolTipTextForDWMEnabled on Vista regardless of themes. private string GetTitleBarToolTipText() { if (System.Environment.OSVersion.Version.Major >= 6) { int isDWMEnabled = 0; // DWM is not enabled try { #pragma warning suppress 56031 // No need to check return value; failure means it isn't enabled UnsafeNativeMethods.DwmIsCompositionEnabled(out isDWMEnabled); } catch (DllNotFoundException) { // The API is not available so we can't be under the DWM // simply ignore the exception } // Using new APIs in Vista to figure out where the cursor is give more // accurate results when composition is enabled. if (isDWMEnabled != 0) return GetTitleBarToolTipTextForDWMEnabled(); } // But until WinOS Bug #1656292 is fixed, hittesting where the cursor is works return GetTitleBarToolTipTextHitTest(); } // For Vista getting the part of the titlebar that a tooltip belongs to is more // reliable across themes private string GetTitleBarToolTipTextForDWMEnabled() { // The mouse is over the titlebar item so get that point on the screen NativeMethods.Win32Point pt = new NativeMethods.Win32Point(); if (!Misc.GetCursorPos(ref pt)) { return ""; } // Find the titlebar hwnd IntPtr hwnd = UnsafeNativeMethods.WindowFromPhysicalPoint(pt.x, pt.y); if (hwnd == IntPtr.Zero) { return ""; } // Get the rects for each titlbar part Rect[] rects = Misc.GetTitlebarRects(hwnd); // Look from back to front - front is entire titlebar rect int scan; for (scan = rects.Length - 1; scan >= 0; scan--) { // Not using Misc.PtInRect because including the bounding pixels all the way around gives // better results; tooltips may appear when the mouse is one or two pixels outside of the // bounding rect so even this technique may miss. if (pt.x >= rects[scan].Left && pt.x <= rects[scan].Right && pt.y >= rects[scan].Top && pt.y <= rects[scan].Bottom) { break; } } switch (scan) { case NativeMethods.INDEX_TITLEBAR_MINBUTTON: if (Misc.IsBitSet(WindowStyle, NativeMethods.WS_MINIMIZE)) return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore); else return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize); case NativeMethods.INDEX_TITLEBAR_HELPBUTTON: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonContextHelp); case NativeMethods.INDEX_TITLEBAR_MAXBUTTON: if (Misc.IsBitSet(WindowStyle, NativeMethods.WS_MAXIMIZE)) return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore); else return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize); case NativeMethods.INDEX_TITLEBAR_CLOSEBUTTON: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonClose); case NativeMethods.INDEX_TITLEBAR_SELF: return Misc.ProxyGetText(hwnd); default: return ""; } } private string GetTitleBarToolTipTextHitTest() { NativeMethods.Win32Point pt = new NativeMethods.Win32Point(); if (!Misc.GetCursorPos(ref pt)) { return ""; } IntPtr hwnd = UnsafeNativeMethods.WindowFromPhysicalPoint(pt.x, pt.y); if (hwnd == IntPtr.Zero) { return ""; } int hit = Misc.ProxySendMessageInt(hwnd, NativeMethods.WM_NCHITTEST, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(pt.x, pt.y)); switch (hit) { case NativeMethods.HTMINBUTTON: if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), NativeMethods.WS_MINIMIZE)) return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore); else return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize); case NativeMethods.HTMAXBUTTON: if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), NativeMethods.WS_MAXIMIZE)) return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore); else return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize); case NativeMethods.HTCLOSE: case NativeMethods.HTMDICLOSE: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonClose); case NativeMethods.HTHELP: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonContextHelp); case NativeMethods.HTMDIMINBUTTON: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize); case NativeMethods.HTMDIMAXBUTTON: return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize); case NativeMethods.HTCAPTION: return Misc.ProxyGetText(hwnd); default: break; } return ""; } #endregion Private Methods // ----------------------------------------------------- // // Private Fields and Types Declaration // // ------------------------------------------------------ #region Private Fields private readonly static WinEventTracker.EvtIdProperty[] _toolTipEventIds = new WinEventTracker.EvtIdProperty[] { new WinEventTracker.EvtIdProperty(NativeMethods.EVENT_OBJECT_HIDE, 0), //see comment in OnToolTipEvents //new WinEventTracker.EvtIdProperty(NativeMethods.EVENT_OBJECT_DESTROY, 0) }; private static int _listenerCount; private const string CLASS_TITLEBAR_TOOLTIP = "#32774"; #endregion Private Fields } } // 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
- OleDbRowUpdatedEvent.cs
- WindowsFormsLinkLabel.cs
- VisualProxy.cs
- CheckoutException.cs
- _NetRes.cs
- FormsAuthenticationUserCollection.cs
- HttpListener.cs
- ComEventsSink.cs
- HttpValueCollection.cs
- DesignerAutoFormat.cs
- WaitHandleCannotBeOpenedException.cs
- GrowingArray.cs
- KeyValueSerializer.cs
- ApplyTemplatesAction.cs
- WinEventTracker.cs
- FileVersion.cs
- ProfilePropertyNameValidator.cs
- TimelineCollection.cs
- ValidatedControlConverter.cs
- GetIndexBinder.cs
- TextEditorSelection.cs
- CredentialCache.cs
- ThaiBuddhistCalendar.cs
- Duration.cs
- MsmqIntegrationElement.cs
- TypeDescriptionProviderAttribute.cs
- ScalarConstant.cs
- ChannelTokenTypeConverter.cs
- XmlSecureResolver.cs
- ProjectionPruner.cs
- Point.cs
- TextEditorThreadLocalStore.cs
- FixedHyperLink.cs
- LostFocusEventManager.cs
- PrivilegeNotHeldException.cs
- CompressStream.cs
- CatalogPartChrome.cs
- RemoteCryptoDecryptRequest.cs
- CqlWriter.cs
- MouseGestureConverter.cs
- GenericIdentity.cs
- WebPartCatalogAddVerb.cs
- FieldNameLookup.cs
- TextSpan.cs
- DependencyObjectPropertyDescriptor.cs
- ListViewEditEventArgs.cs
- EncodingTable.cs
- FixedSOMLineCollection.cs
- EntityCollection.cs
- ReflectionPermission.cs
- LabelAutomationPeer.cs
- XmlElement.cs
- WebPartAuthorizationEventArgs.cs
- ServiceKnownTypeAttribute.cs
- CheckPair.cs
- BuiltInPermissionSets.cs
- WebPartCatalogCloseVerb.cs
- HostedTcpTransportManager.cs
- AbstractSvcMapFileLoader.cs
- BitSet.cs
- TypeTypeConverter.cs
- SqlParameter.cs
- CapabilitiesPattern.cs
- ClientRoleProvider.cs
- SystemColorTracker.cs
- CharacterHit.cs
- DoubleLinkList.cs
- DataGridViewTopLeftHeaderCell.cs
- LongValidatorAttribute.cs
- FrugalMap.cs
- Assert.cs
- ClonableStack.cs
- NonDualMessageSecurityOverHttp.cs
- DbXmlEnabledProviderManifest.cs
- PeerInputChannelListener.cs
- BamlReader.cs
- HtmlInputReset.cs
- ListMarkerLine.cs
- MenuCommand.cs
- WithStatement.cs
- BitArray.cs
- BackEase.cs
- SecurityException.cs
- IPAddress.cs
- Visual3D.cs
- Geometry.cs
- WebPartConnectionsDisconnectVerb.cs
- CompoundFileDeflateTransform.cs
- SerializationObjectManager.cs
- RootBuilder.cs
- XmlCDATASection.cs
- MembershipSection.cs
- ValidatorCompatibilityHelper.cs
- nulltextnavigator.cs
- PrintDialog.cs
- VScrollProperties.cs
- Border.cs
- PasswordRecovery.cs
- SqlConnectionPoolProviderInfo.cs
- PagesChangedEventArgs.cs