понедельник, 8 декабря 2008 г.

А что это за пустые кнопки на панели задач, которые исчезают, когда я щёлкаю по ним?

Это перевод What's with those blank taskbar buttons that go away when I click on them? Автор: Реймонд Чен.

Иногда вы можете увидеть пустую кнопку на панели задач, которая исчезает, когда вы щёлкаете по ней. Что это ещё за чёрт?

Есть несколько основных правил, согласно которым окна появляются на панели задач. Вкратце:
- Если установлен расширенный стиль WS_EX_APPWINDOW, тогда окно показывается (когда оно видимо).
- Если окно является окном верхнего уровня без владельца (owner в терминах WinAPI - прим. пер.), тогда оно показывается (когда оно видимо).
- В противном случае окно не показывается.

(хотя интерфейс ITaskbarList немножко всё это запутывает).

Когда "пригодное для панели задач" окно становится видимым, панель задач создаёт кнопку для него. Когда "пригодное для панели задач" становится скрытым - панель задач скрывает кнопку.

Пустые кнопки появляются, когда окно переходит от "пригодное для панели задач" к "не пригодное для панели задач" в то время, когда оно видимо. Посмотрите:
- Окно - "пригодное для панели задач".
- Окно становится видимым -> создаётся кнопка на панели задач.
- Окно становится "не пригодное для панели задач".
- Окно становится невидимым -> поскольку окно не является "пригодное для панели задач", то панель задач игнорирует окно.

Результат: на панели задач появляется ничейная кнопка, без прикреплённого к ней окна.

Именно поэтому документация советует: "если вы хотите динамически изменить стиль окна на такой, который не поддерживает кнопку на панели задач, то сначала вы должны скрыть окно (вызовом ShowWindow с SW_HIDE), изменить стиль окна, а затем показать окно".

Бонус-вопрос: почему панель задач не проверяет все окна подряд?
Ответ: потому что это было бы расточительно. Фильтрация окон, которые являются "таскбаро-непригодными", происходит внутри USER32, которая уведомляет панель задач (или любого, кто установил хук WH_SHELL) с помощью уведомлений HSHELL_* только об окнах, которые изменили своё состояние и являются "пригодными для панели задач". Таким образом, код панели задач может быть выгружен в файл подкачки, если для него нет никакой работы.

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

5 комментариев:

  1. А если ShowModal(HWND, SC_HIDE) скрывает только окно, но в панели задачь кнопка остаётся? Как ещё можно скрыть кнопку в таскбаре? Окно чужое.

    ОтветитьУдалить
  2. >>> Как ещё можно скрыть кнопку в таскбаре?

    См.

    >>> Есть несколько основных правил, согласно которым окна появляются на панели задач.

    Если в таскбаре есть кнопка, то это значит, что для окна было выполнено одно или несколько условий из списка.

    Убрав эти условия вы скроете кнопку в таскбаре.

    ОтветитьУдалить
  3. Добавление стиля не помогло, нашёл на MSDN'е "TB_HIDEBUTTON" - работает, но в сообщении необходимо указывать индекс кнопки.
    Александр, вы не владеете ни какой информацией, каким образом можно "пробежаться" по всем кнопкам и прочитать их заголовки?

    P.S. плохо что здесь "вставка" не работает :(

    ОтветитьУдалить
  4. Слушайте, во-первых я не обладаю телепатическими способностями, чтобы угадать, что у вас происходит.
    Во-вторых, я бы рекомендовал с вопросами идти на форумы по программированию ;)

    ОтветитьУдалить
  5. Телепатией обладать и не надо, вопрос был один "как пробежаться по кнопкам", ладно пойду на КД :-)

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.