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
- DbFunctionCommandTree.cs
- PersonalizationProviderHelper.cs
- IntegerValidatorAttribute.cs
- TrackingConditionCollection.cs
- Menu.cs
- CompiledXpathExpr.cs
- DataTrigger.cs
- CubicEase.cs
- ContractComponent.cs
- LinqDataSource.cs
- DesignTimeVisibleAttribute.cs
- DoubleMinMaxAggregationOperator.cs
- ListDictionary.cs
- AsymmetricAlgorithm.cs
- CollectionViewGroupInternal.cs
- Serialization.cs
- Emitter.cs
- DnsPermission.cs
- InspectionWorker.cs
- AssemblyFilter.cs
- CacheMemory.cs
- XmlCharCheckingReader.cs
- AppDomainProtocolHandler.cs
- RegistryPermission.cs
- XamlLoadErrorInfo.cs
- printdlgexmarshaler.cs
- SqlProviderManifest.cs
- Brushes.cs
- XmlNamespaceManager.cs
- ProgressBarRenderer.cs
- GcSettings.cs
- RangeValidator.cs
- Part.cs
- PropertyDescriptorGridEntry.cs
- TTSEvent.cs
- CatalogZoneBase.cs
- JsonStringDataContract.cs
- SoapElementAttribute.cs
- _HeaderInfo.cs
- EntityUtil.cs
- TabItemAutomationPeer.cs
- CursorConverter.cs
- SID.cs
- ExtendedPropertyCollection.cs
- PeerDefaultCustomResolverClient.cs
- CompilationUnit.cs
- DynamicResourceExtension.cs
- XmlEntity.cs
- StorageBasedPackageProperties.cs
- CultureInfoConverter.cs
- ListArgumentProvider.cs
- LongValidator.cs
- DataGridPreparingCellForEditEventArgs.cs
- KeyEvent.cs
- RenderingEventArgs.cs
- EFAssociationProvider.cs
- initElementDictionary.cs
- ILGenerator.cs
- SharedConnectionListener.cs
- DataGridViewCellEventArgs.cs
- TrackingMemoryStreamFactory.cs
- FontStyle.cs
- Visual3DCollection.cs
- HttpPostedFile.cs
- MSAAWinEventWrap.cs
- ValidatorUtils.cs
- PartitionResolver.cs
- CodeDirectionExpression.cs
- ZipIOCentralDirectoryFileHeader.cs
- TextFormatterHost.cs
- XmlSerializerNamespaces.cs
- SimpleNameService.cs
- EditorPartCollection.cs
- FixedHyperLink.cs
- TransformCollection.cs
- SystemTcpConnection.cs
- ToolStripSplitButton.cs
- ModifierKeysConverter.cs
- InheritedPropertyChangedEventArgs.cs
- DataServiceHost.cs
- RemotingConfigParser.cs
- RtfToken.cs
- HttpVersion.cs
- DataTableCollection.cs
- ShaderEffect.cs
- XmlSchemaAnyAttribute.cs
- SapiRecoContext.cs
- SourceFileBuildProvider.cs
- DesignerTransactionCloseEvent.cs
- GeometryModel3D.cs
- Table.cs
- HitTestWithGeometryDrawingContextWalker.cs
- ServicePoint.cs
- AnnotationAuthorChangedEventArgs.cs
- AuthenticationModuleElement.cs
- RangeValidator.cs
- Vector3D.cs
- EntitySetBase.cs
- DesignerForm.cs
- AsyncCompletedEventArgs.cs