Препятствовать тому, чтобы управление WebBrowser крало фокус?

Я сделал большую разработку Spring/Быть в спящем режиме. Со временем способ, которым люди использовали обоих в комбинации, изменился немного. Исходный подход HibernateTemplate оказался трудным отладить, так как он глотает и обертывает в других отношениях полезные исключения; говорите с API Hiberante непосредственно!

продолжайте смотреть на сгенерированный SQL (настройте свою разработку, регистрирующуюся для показа SQL). Наличие уровня абстракции к базе данных не означает, что Вы не должны больше думать в SQL; Вы не получите хорошую производительность если Вы иначе.

Рассматривают проект. У меня есть choosen iBatis, несколько раз В спящем режиме, где у нас были строгие требования к производительности, сложные схемы прежней версии или хороший DBa's, способный к записи превосходного SQL.

12
задан rossisdead 13 October 2009 в 21:37
поделиться

2 ответа

EDIT: полный вопрос переписан, я неправильно понял исходный вопрос

Давайте обобщим проблему: элемент управления или компонент, который вы не контролируете, может вызывать FlashWindow (функцию Win32 API), чтобы привлечь внимание пользователя. Вы этого не хотите.

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

FlashWindow

Microsoft не очень подробно объясняет, что делает FlashWindow . К сожалению, он не отправляет конкретное сообщение (скажем, WM_FLASH или подобное), которое упростило бы захват и аннулирование этого поведения. Вместо этого FlashWindow выполняет три действия:

  1. Он устанавливает системный таймер для интервалов мигания
  2. Он отправляет сообщение WM_NCACTIVATE для первой вспышки
  3. Он отправляет Сообщение WM_NCACTIVATE по истечении таймера (при получении WM_SYSTIMER )

В зависимости от того, как компонент вызывает FlashWindow, это может быть неопределенным, пока не наступит другой тайм-аут, пока он не получит фокус, или только один раз. Каждое сообщение WM_NCACTIVATE активирует или деактивирует зону ЧПУ (панель заголовка, кнопка на панели задач). Это не меняет входной фокус.

Проблема

Любое решение для предотвращения мигания требует некоторого внимания. Основные проблемы:

  1. событие WM_SYSTIMER отправляется асинхронно с PostMessage и не принимается методом WndProc формы (он обрабатывает только синхронные сообщения)
  2. Сообщения WM_NCACTIVATE также используются, когда пользователь нажимает кнопку в строке заголовка или панели задач, чтобы установить фокус ввода, простая отмена этих сообщений будет иметь нежелательные побочные эффекты.
  3. FlashWindow всегда будет мигать хотя бы один раз, независимо от WM_SYSTIMER срабатывает или нет.

Сообщение WM_SYSTIMER недокументировано. Он имеет значение 0x0118 и используется внутри Windows для измерения времени, например, мигания курсора, задержки открытия меню и т. Д. Здесь он используется для времени между миганиями.

Решение

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

protected override void WndProc(ref Message m)
{
    bool messageHandled = false;
    if (m.Msg == WM_NCACTIVATE)
    {
        // add logic here to determine user action, losing focus etc and set 
        // messageHandled and m.Result only when user action is not the cause 
        // of triggering WM_NCACTIVATE
        m.Result = IntPtr.Zero;
        messageHandled = true;
    }

    if(!messageHandled)
        base.WndProc(ref m);
}

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

Следующий код дает вам больше контроля. Вы можете использовать его, чтобы реагировать на саму мигание. Как обычно, главное окно не так часто получает события WM_SYSTIMER , но вам придется поэкспериментировать, следует ли делать исключения. Похоже, что для FlashWindow параметр wParam всегда установлен на 0xFFF8 , но поэкспериментируйте с ним, поскольку это нигде не задокументировано.

public class MyMessageFilter : IMessageFilter
{
    // an application can have many windows, only filter for one window at the time
    IntPtr FilteredHwnd = IntPtr.Zero;

    public MyMessageFilter(IntPtr hwnd)
    {
        this.FilteredHwnd = hwnd;
    }

    public bool PreFilterMessage(ref Message m)
    {
        if (this.FilteredHwnd == m.HWnd && m.Msg == WM_SYSTIMER)
            return true;     // stop handling the message further
        else
            return false;    // all other msgs: handle them
    }
}

Чтобы активировать этот фильтр сообщений, просто добавьте следующую строку где-нибудь в вашем событии загрузки формы:

Application.AddMessageFilter(new MyMessageFilter(this.Handle));

Следующие константы должны быть размещены на уровне класса. Они используются в обоих разделах кода выше:

public const UInt32 WM_SYSTIMER = 0x0118;
public const UInt32 WM_NCACTIVATE = 0x86;

Заключение

Хотя проблема сама по себе разрешима, это далеко не просто. С указанными выше ручками вы должны уйти довольно далеко. Используйте фильтр, чтобы предотвратить мигание, но тогда первая «вспышка» все равно произойдет. Используйте переопределение WinProc , чтобы предотвратить и первое, но добавьте некоторую логику, чтобы ваше приложение не работало слишком странно (то есть: всегда неактивная строка заголовка или всегда активная). У вас уже есть код, который можно комбинировать с этим, чтобы установить некоторые логические флаги.

8
ответ дан 2 December 2019 в 21:23
поделиться

Реализовать IProtectFocus :: AllowFocusChange в объекте

Реализовать IServiceProvider на том же объекте, который реализует IOleClientSite, затем ответить на IServiceProvider :: QueryService для SID_SProtectFocus с помощью объекта, который предоставляет IProtectFocus

Это новый интерфейс в IE7, поэтому старым версиям не повезло.

5
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: