Отображение всплывающей подсказки для несфокусированного ToolStripItem

ToolStripItems показывают активное выделение при наведении указателя мыши на них, даже если форма, в которой они находятся, не в фокусе. Однако они не показывают свои всплывающие подсказки, если форма не сфокусирована. Я видел Взлом ToolStrip. Кто-нибудь знает, как заставить ToolStripButton показывать всплывающую подсказку, когда его родительская форма не в фокусе?

Спасибо!

почему ты хочешь сделать это? Ошибка скорее в активном отслеживании, когда форма не сфокусирована.

OregonGhost 27.09.2008 17:44

@OregonGhost - я создал плавающую / постоянно отображаемую панель инструментов и хотел, чтобы всплывающие подсказки отображались при наведении курсора мыши, даже когда другие приложения были активны.

foson 31.12.2008 01:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
2
8 268
4

Ответы 4

Возможно, один из двух подходов в этом коде подтолкнет вас в правильном направлении ...

public Form1()
{
    InitializeComponent();

    tooltip = new ToolTip();
    tooltip.ShowAlways = true;
}

private ToolTip tooltip;
private void toolStripButton_MouseHover(object sender, EventArgs e)
{
    if (!this.Focused)
    {
        ToolStripItem tsi = (ToolStripItem)sender;
        tooltip.SetToolTip(toolStrip1, tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text);
        /*tooltip.Show(tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text, this, 
            new Point(toolStrip1.Left, toolStrip1.Bottom));*/
    }
}

private void toolStripButton_MouseLeave(object sender, EventArgs e)
{
    tooltip.RemoveAll();
}

Проблема с первым заключается в том, что вы не можете установить его на кнопку напрямую, он не наследуется от Control, и всплывающая подсказка не будет отображаться, если вы не находитесь над полосой, но не над кнопкой.

Проблема со вторым (закомментированным) способом в том, что он вообще не отображается. Не совсем уверен, почему, но, возможно, вы сможете отладить это.

Проблема в том, что «элементы управления» ToolStrip, такие как ToolStripButton или ToolStripDropDownButton, не наследуются от Control. На данный момент я решил проблему, фокусируя ToolStrip всякий раз, когда пользователь наводит курсор на кнопку. Событие кнопки MouseHover запускается слишком поздно - после того, как код «показать всплывающую подсказку» должен был быть запущен, поэтому я расширил класс ToolStripDropDownButton и использовал свою новую кнопку. Этот метод должен работать с любыми другими кнопочными классами, унаследованными от ToolStripItem.

public class ToolStripDropDownEx : ToolStripDropDownButton
{
    public ToolStripDropDownEx(string text)
    {
    }

    protected override void OnMouseHover(EventArgs e)
    {
        if (this.Parent != null)
            Parent.Focus();
        base.OnMouseHover(e);
    } 
}

Я пытался сделать то же самое и решил, что это будет довольно сложно и того не стоит. Причина в том, что внутренне код .NET специально разработан для отображения всплывающей подсказки только в том случае, если окно активно - они проверяют это на уровне Win32, поэтому подделать код будет сложно.

Вот фрагмент кода в ToolTip.cs, который проверяет «GetActiveWindow ()» и возвращает false. Вы можете увидеть комментарий в коде «Всплывающие подсказки должны отображаться только в активной Windows».

Кстати, вы можете увидеть весь исходный код .NET BCL с Visual Studio 2008, вот инструкции, которые я использовал:

http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

// refer VsWhidbey 498263: ToolTips should be shown only on active Windows.
private bool IsWindowActive(IWin32Window window)
{ 
    Control windowControl = window as Control;
    // We want to enter in the IF block only if ShowParams does not return SW_SHOWNOACTIVATE. 
    // for ToolStripDropDown ShowParams returns SW_SHOWNOACTIVATE, in which case we DONT want to check IsWindowActive and hence return true. 
    if ((windowControl.ShowParams & 0xF) != NativeMethods.SW_SHOWNOACTIVATE)
    { 
        IntPtr hWnd = UnsafeNativeMethods.GetActiveWindow();
        IntPtr rootHwnd =UnsafeNativeMethods.GetAncestor(new HandleRef(window, window.Handle), NativeMethods.GA_ROOT);
        if (hWnd != rootHwnd)
        { 
            TipInfo tt = (TipInfo)tools[windowControl];
            if (tt != null && (tt.TipType & TipInfo.Type.SemiAbsolute) != 0) 
            { 
                tools.Remove(windowControl);
                DestroyRegion(windowControl); 
            }
            return false;
        }
    } 
    return true;
} 

я попробовал несколько вещей и обнаружил, что это самый простой

когда я создаю элементы toolstripbutton, я добавил обработчик событий к его событию зависания:

private sub SomeCodeSnippet()

    Me.tooltipMain.ShowAlways = True

    Dim tsi As New ToolStripButton(String.Empty, myImage)
    tsi.ToolTipText = "my tool tip text"
    toolstripMain.Add(tsi)

    AddHandler tsi.MouseHover, AddressOf ToolStripItem_MouseHover

end sub

затем обработчик события:

Private Sub ToolStripItem_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf sender Is ToolStripButton Then
        Me.tooltipMain.SetToolTip(Me.toolstripMain, CType(sender, ToolStripButton).ToolTipText)
    End If

End Sub

это работает очень хорошо, хотя я заметил небольшую начальную задержку, когда вы наводите курсор на панель инструментов в первый раз

Другие вопросы по теме