Ejemplo n.º 1
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WmPop"]/*' />
        /// <devdoc>
        ///     Called just before the tooltip is hidden
        /// </devdoc>
        /// <internalonly/>
        private void WmPop() {

            NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
            ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
            int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti);
            if (ret != 0) {

                IWin32Window win = (IWin32Window)owners[ti.hwnd];
                if (win == null) {
                    win = (IWin32Window)Control.FromHandleInternal(ti.hwnd);
                }

                if (win == null) {
                    return;
                }

                Control control = win as Control;
                TipInfo tt = (TipInfo)tools[win];
                if (tt == null) {
                   return;
                }

                // Must reset the maxwidth to the screen size.
                // This is required to resolve VSWhidbey bug# 363408
                if ((tt.TipType & TipInfo.Type.Auto) != 0 || (tt.TipType & TipInfo.Type.SemiAbsolute) != 0) {
                   Screen screen = Screen.FromPoint(Cursor.Position);
                   UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_SETMAXTIPWIDTH, 0, screen.WorkingArea.Width);
                }

                // For non-auto tips (those showned through
                // the show(...) methods, we need to dissassociate
                // them from the tip control.
                if ((tt.TipType & TipInfo.Type.Auto) == 0) {

                     tools.Remove(control); 
                     owners.Remove(win.Handle);

                     control.HandleCreated -= new EventHandler(this.HandleCreated);
                     control.HandleDestroyed -= new EventHandler(this.HandleDestroyed);
                     created.Remove(control);

                     if (originalPopupDelay != 0) {
                        AutoPopDelay = originalPopupDelay;
                        originalPopupDelay = 0;
                     }
                }
                else {
                     // Clear all other flags except for the 
                     // Auto flag to ensure automatic tips can still show
                     tt.TipType = TipInfo.Type.Auto;
                     tt.Position = Point.Empty;
                     tools[control] = tt;
                }
            }
        }
Ejemplo n.º 2
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WndProc"]/*' />
        /// <devdoc>
        ///     WNDPROC
        /// </devdoc>
        /// <internalonly/>
        private void WndProc(ref Message msg) {


            switch (msg.Msg) {

            case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
                 NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR) msg.GetLParam(typeof(NativeMethods.NMHDR));
                 if (nmhdr.code == NativeMethods.TTN_SHOW && !trackPosition) {
                     WmShow();
                 }
                 else if (nmhdr.code == NativeMethods.TTN_POP) {                    
                    WmPop();
                    window.DefWndProc(ref msg);
                 } 
                 break;                
            
            case NativeMethods.WM_WINDOWPOSCHANGING:
                 WmWindowPosChanging(ref msg);
                 break;
			
            case NativeMethods.WM_WINDOWPOSCHANGED:
                 if (!WmWindowPosChanged())
                 {
                    window.DefWndProc(ref msg);
                 }
                 break;
					 
            case NativeMethods.WM_MOUSEACTIVATE:
                 WmMouseActivate(ref msg);
                 break;

            case NativeMethods.WM_MOVE:
                 WmMove();
                 break;
            
            case NativeMethods.TTM_WINDOWFROMPOINT:
                WmWindowFromPoint(ref msg);
                break;
   
            case NativeMethods.WM_PRINTCLIENT:
                goto case NativeMethods.WM_PAINT;
                
            case NativeMethods.WM_PAINT:
                if (ownerDraw && !isBalloon && !trackPosition)
                {
                    NativeMethods.PAINTSTRUCT ps = new NativeMethods.PAINTSTRUCT();
                    IntPtr dc = UnsafeNativeMethods.BeginPaint(new HandleRef(this,Handle),ref ps);
                    Graphics g = Graphics.FromHdcInternal(dc);
                    try {
                        Rectangle bounds = new Rectangle(ps.rcPaint_left,ps.rcPaint_top,
                        ps.rcPaint_right - ps.rcPaint_left,
                        ps.rcPaint_bottom - ps.rcPaint_top);
                        if (bounds == Rectangle.Empty ) {
                            return;
                        }
                        NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
                        ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
                        int ret = unchecked( (int) (long)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti));
                        if (ret != 0) {
                            IWin32Window win = (IWin32Window)owners[ti.hwnd];
                            Control ac = Control.FromHandleInternal(ti.hwnd);
                            if (win == null) {
                                win = (IWin32Window)ac;
                            }
                            Font font;
                            IntSecurity.ObjectFromWin32Handle.Assert();
                            try {
                                font = Font.FromHfont(UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.WM_GETFONT, 0, 0));
                            }
                            catch (ArgumentException) {
                                // VSWhidbey 209345 - if the current default tooltip font is a non-TrueType font, then
                                // Font.FromHfont throws this exception, so fall back to the default control font.
                                font = Control.DefaultFont;
                            }
                            finally {
                                CodeAccessPermission.RevertAssert();
                            }

                            OnDraw(new DrawToolTipEventArgs(g, win, ac, bounds, GetToolTip(ac), 
                                                            BackColor, ForeColor, font));
    
                            break;
                        }
                    }
                    finally
                    {
                        g.Dispose();
                        UnsafeNativeMethods.EndPaint(new HandleRef(this,Handle),ref ps);
                    }
                }

                //If not OwnerDraw, fall through
                goto default;
            default:
                window.DefWndProc(ref msg);
                break;
            }
        }
Ejemplo n.º 3
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WmShow"]/*' />
        /// <devdoc>
        ///     Handles the TTN_SHOW message.
        /// </devdoc>
        /// <internalonly/>
        private void WmShow() {


            //Get the Bounds....
            NativeMethods.RECT r = new NativeMethods.RECT();
            UnsafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref r);

            NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
            ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
            int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti);
            
            if (ret != 0) {

                IWin32Window win = (IWin32Window)owners[ti.hwnd];
                if (win == null) {
                    win = (IWin32Window)Control.FromHandleInternal(ti.hwnd);
                }
                
                if (win == null) {
                    return;
                }

                Control toolControl = win as Control;

                Size currentTooltipSize = r.Size;
                PopupEventArgs e = new PopupEventArgs(win, toolControl, IsBalloon, currentTooltipSize); 
                OnPopup(e);

                DataGridView dataGridView = toolControl as DataGridView;
                if (dataGridView != null && dataGridView.CancelToolTipPopup(this))
                {
                    // The dataGridView cancelled the tooltip.
                    e.Cancel = true;
                }

                // We need to re-get the rectangle of the tooltip here because
                // any of the tooltip attributes/properties could have been updated
                // during the popup event; in which case the size of the tooltip is
                // affected. e.ToolTipSize is respected over r.Size
                UnsafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref r);
                currentTooltipSize = (e.ToolTipSize == currentTooltipSize) ? r.Size:e.ToolTipSize;


                if (IsBalloon) {
                  // Get the text display rectangle
                   UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_ADJUSTRECT, 1, ref r);
                   if (r.Size.Height > currentTooltipSize.Height) currentTooltipSize.Height = r.Size.Height;
                }

                // Set the max possible size of the tooltip to the size we received.
                // This prevents the operating system from drawing incorrect rectangles
                // when determing the correct display rectangle. VSWhidbey 

                if (currentTooltipSize != r.Size)
                {
                    Screen screen = Screen.FromPoint(Cursor.Position);
                    int maxwidth = (IsBalloon) ?
                    Math.Min(currentTooltipSize.Width-2*XBALLOONOFFSET, screen.WorkingArea.Width):
                    Math.Min(currentTooltipSize.Width, screen.WorkingArea.Width);
                    UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_SETMAXTIPWIDTH, 0, maxwidth);
                }

                if (e.Cancel) { 
                    cancelled = true;
                    SafeNativeMethods.SetWindowPos(new HandleRef(this, this.Handle),
                    NativeMethods.HWND_TOPMOST,
                    0, 0, 0, 0,
					NativeMethods.SWP_NOACTIVATE | NativeMethods.SWP_NOOWNERZORDER);

                }
                else {
                    cancelled = false;
                    // Only width/height changes are respected, so set top,left to what we got earlier
                    SafeNativeMethods.SetWindowPos(new HandleRef(this, this.Handle),
                    NativeMethods.HWND_TOPMOST,
                    r.left, r.top, currentTooltipSize.Width, currentTooltipSize.Height,
                    NativeMethods.SWP_NOACTIVATE | NativeMethods.SWP_NOOWNERZORDER);
                }
            }
        }
Ejemplo n.º 4
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WmWindowPosChanging"]/*' />
        /// <devdoc>
        ///     Handles the WM_WINDOWPOSCHANGING message.
        /// </devdoc>
        /// <internalonly/>
        private unsafe void WmWindowPosChanging(ref Message m) {
            if (cancelled)
            {
            	return;
            }

            NativeMethods.WINDOWPOS* wp = (NativeMethods.WINDOWPOS *)m.LParam;
            
            Cursor currentCursor = Cursor.CurrentInternal;
            Point cursorPos = Cursor.Position;

			

            NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
            ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
            int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti);
            if (ret != 0) {

                IWin32Window win = (IWin32Window)owners[ti.hwnd];
                if (win == null) {
                    win = (IWin32Window)Control.FromHandleInternal(ti.hwnd);
                }

                if (win == null || !IsWindowActive(win)) {
                    return;
                }

                TipInfo tt = null;
                if (win != null)
                {
                    tt = (TipInfo)tools[win];
                    if (tt == null) {
                       return;
                    }

                    // Treeview handles its own ToolTips.
                    TreeView treeView = win as TreeView;
                    if (treeView != null) {
                        if (treeView.ShowNodeToolTips) {
                            return; 
                        }
                    }
                }

                if (IsBalloon) {
                   wp->cx += 2*XBALLOONOFFSET;
                   return;
                }

                if ( (tt.TipType & TipInfo.Type.Auto) != 0)
                {
                    window.DefWndProc(ref m);
                    return;
                }

                if ( ((tt.TipType & TipInfo.Type.SemiAbsolute) != 0) && tt.Position == Point.Empty ) {

                   Screen screen = Screen.FromPoint(cursorPos);
                   if (currentCursor != null)
                   {
                        wp->x = cursorPos.X;
                        // Since HotSpot requires a security demand .. we assert this and revert Assert immediately 
                        try {
                            IntSecurity.ObjectFromWin32Handle.Assert();
                             
                            wp->y = cursorPos.Y;
                            if (wp->y + wp->cy + currentCursor.Size.Height - currentCursor.HotSpot.Y > screen.WorkingArea.Bottom) {
                               wp->y = cursorPos.Y - wp->cy;
                            }
                            else {
                               wp->y = cursorPos.Y + currentCursor.Size.Height - currentCursor.HotSpot.Y;
                            }
                        }
                        finally {
                            CodeAccessPermission.RevertAssert();
                        }
                   }
                   if (wp->x + wp->cx >screen.WorkingArea.Right) {
                      wp->x = screen.WorkingArea.Right - wp->cx;
                   }

                }
                else if ((tt.TipType & TipInfo.Type.SemiAbsolute) != 0 && tt.Position != Point.Empty) {

                   Screen screen = Screen.FromPoint(tt.Position);
                   wp->x = tt.Position.X;
                   if (wp->x + wp->cx >screen.WorkingArea.Right) {
                      wp->x = screen.WorkingArea.Right - wp->cx;
                   }
                   wp->y = tt.Position.Y;
                   
                   if (wp->y + wp->cy > screen.WorkingArea.Bottom) {
                        wp->y = screen.WorkingArea.Bottom - wp->cy;
                   }
                }
            }

            m.Result = IntPtr.Zero; 
        }
Ejemplo n.º 5
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WmMouseActivate"]/*' />
        /// <devdoc>
        ///     Handles the WM_MOUSEACTIVATE message.
        /// </devdoc>
        /// <internalonly/>
        private void WmMouseActivate(ref Message msg) {
            
            NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
            ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
            int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti);
            
            if (ret != 0) {

                IWin32Window win = (IWin32Window)owners[ti.hwnd];
                if (win == null) {
                    win = (IWin32Window)Control.FromHandleInternal(ti.hwnd);
                }

                if (win == null) {
                    return;
                }

                NativeMethods.RECT r = new NativeMethods.RECT();
                UnsafeNativeMethods.GetWindowRect(new HandleRef(win, Control.GetSafeHandle(win)), ref r);
                Point cursorLocation = Cursor.Position;

                // Do not activate the mouse if its within the bounds of the
                // the associated tool
                if (cursorLocation.X >= r.left && cursorLocation.X <= r.right &&
                    cursorLocation.Y >= r.top && cursorLocation.Y <= r.bottom) {
                    msg.Result = (IntPtr)NativeMethods.MA_NOACTIVATE;
                }
            }
        }
Ejemplo n.º 6
0
        /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.WmMove"]/*' />
        /// <devdoc>
        ///     Handles the WM_MOVE message.
        /// </devdoc>
        /// <internalonly/>
        private void WmMove() {
            NativeMethods.RECT r = new NativeMethods.RECT();
            UnsafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref r);
            NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
            ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
            int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETCURRENTTOOL, 0, ti);
            if (ret != 0)
            {
                IWin32Window win = (IWin32Window)owners[ti.hwnd];
                if (win == null) {
                    win = (IWin32Window)Control.FromHandleInternal(ti.hwnd);
                }
                
                if (win == null) {
                    return;
                }
                
                TipInfo tt = (TipInfo)tools[win];
                if (win == null || tt==null) {
                   return;
                }

                // Treeview handles its own ToolTips.
                TreeView treeView = win as TreeView;
                if (treeView != null) {
                    if (treeView.ShowNodeToolTips) {
                        return; 
                    }
                }

                // Reposition the tooltip when its about to be shown.. since the tooltip can go out of screen workingarea bounds
                // Reposition would check the bounds for us.
                if (tt.Position != Point.Empty)
                {
                    Reposition(tt.Position, r.Size);
                }
             }
        }
Ejemplo n.º 7
0
        private void SetTool(IWin32Window win, string text, TipInfo.Type type, Point position) {
            Control tool = win as Control;

            if (tool != null && tools.ContainsKey(tool)) {
                bool allocatedString = false;
                NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
                try {
                    ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
                    ti.hwnd = tool.Handle;
                    ti.uId = tool.Handle;
                    int ret = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.TTM_GETTOOLINFO, 0, ti);
                    if (ret != 0) {
                        ti.uFlags |= NativeMethods.TTF_TRACK;

                        if (type == TipInfo.Type.Absolute || type == TipInfo.Type.SemiAbsolute) {
                            ti.uFlags |= NativeMethods.TTF_ABSOLUTE;
                        }
                        ti.lpszText = Marshal.StringToHGlobalAuto(text);
                        allocatedString = true;
                    }

                    TipInfo tt = (TipInfo)tools[tool];
                    if (tt == null) {
                        tt = new TipInfo(text, type);
                    }
                    else {
                        tt.TipType |= type;
                        tt.Caption = text;
                    }
                    tt.Position = position;
                    tools[tool] = tt;

                    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.TTM_SETTOOLINFO, 0, ti);
                    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.TTM_TRACKACTIVATE, 1, ti);
                } finally {
                    if(allocatedString && IntPtr.Zero != ti.lpszText) {
                        Marshal.FreeHGlobal(ti.lpszText);
                    }
                }
            }
            else {
                Hide(win);

                // Need to do this BEFORE we call GetWinTOOLINFO, since it relies on the tools array to be populated
                // in order to find the toplevelparent.
                TipInfo tt = (TipInfo)tools[tool];
                if (tt == null) {
                    tt = new TipInfo(text, type);
                }
                else {
                    tt.TipType |= type;
                    tt.Caption = text;
                }
                tt.Position = position;
                tools[tool] = tt;
                
                IntPtr hWnd = Control.GetSafeHandle(win);
                owners[hWnd] = win;
                NativeMethods.TOOLINFO_TOOLTIP toolInfo = GetWinTOOLINFO(hWnd);
                toolInfo.uFlags |= NativeMethods.TTF_TRACK;

                if (type == TipInfo.Type.Absolute || type == TipInfo.Type.SemiAbsolute) {
                    toolInfo.uFlags |= NativeMethods.TTF_ABSOLUTE;
                }

                try {
                    toolInfo.lpszText = Marshal.StringToHGlobalAuto(text);
                    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.TTM_ADDTOOL, 0, toolInfo);
                    UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.TTM_TRACKACTIVATE, 1, toolInfo);
                } finally {
                    if(IntPtr.Zero != toolInfo.lpszText) {
                        Marshal.FreeHGlobal(toolInfo.lpszText);
                    }
                }
            }
            
            if (tool != null) {

                // Lets find the Form for associated Control ...
                // and hook up to the Deactivated event to Hide the Shown tooltip
                Form baseFrom = tool.FindFormInternal();
                if (baseFrom != null) {
                    baseFrom.Deactivate += new EventHandler(this.BaseFormDeactivate);
                }
            }
            
        }
Ejemplo n.º 8
0
 private NativeMethods.TOOLINFO_TOOLTIP GetWinTOOLINFO(IntPtr hWnd) {
     NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
     ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
     ti.hwnd = hWnd;
     ti.uFlags |= NativeMethods.TTF_IDISHWND | NativeMethods.TTF_TRANSPARENT | NativeMethods.TTF_SUBCLASS;
             
     // RightToLeft reading order
     //
     Control richParent = TopLevelControl;
     if (richParent != null && richParent.RightToLeft == RightToLeft.Yes) {
         bool isWindowMirrored = ((unchecked((int)(long)UnsafeNativeMethods.GetWindowLong(new HandleRef(this, hWnd), NativeMethods.GWL_STYLE)) & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL);            
         //Indicates that the ToolTip text will be displayed in the opposite direction 
         //to the text in the parent window.                 
         if (!isWindowMirrored) {
             ti.uFlags |= NativeMethods.TTF_RTLREADING;
         }
     }
     
     ti.uId = ti.hwnd;
     return ti;
 }
Ejemplo n.º 9
0
 /// <include file='doc\ToolTip.uex' path='docs/doc[@for="ToolTip.GetMinTOOLINFO"]/*' />
 /// <devdoc>
 ///     Returns a new instance of the TOOLINFO_T structure with the minimum
 ///     required data to uniquely identify a region. This is used primarily
 ///     for delete operations. NOTE: This cannot force the creation of a handle.
 /// </devdoc>
 /// <internalonly/>
 private NativeMethods.TOOLINFO_TOOLTIP GetMinTOOLINFO(Control ctl) {
     NativeMethods.TOOLINFO_TOOLTIP ti = new NativeMethods.TOOLINFO_TOOLTIP();
     ti.cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO_TOOLTIP));
     ti.hwnd = ctl.Handle;
     ti.uFlags |= NativeMethods.TTF_IDISHWND;
     ti.uId = ctl.Handle;
     return ti;
 }