среда, 7 января 2009 г.

Что такого особенного в окне рабочего стола?

Это перевод What's so special about the desktop window? Автор: Реймонд Чен.

Окно, возвращаемое функцией GetDesktopWindow является очень особым. И я видел, как им часто злоупотребляют, как только можно.

Например, множество функций в оболочке (shell) принимают описатель окна в качестве одного из своих параметров, который используется, если надо отобразить UI (пользовательский интерфейс). Например, IShellFolder::EnumObjects.

Что произойдёт, если вы передадите туда GetDesktopWindow?

Если возникнет необходимость показать UI, то этим вы подвесите систему.

Почему?
  • Модальный диалог отключает (disable) своего владельца (owner).
  • Каждое окно является потомком (descendant) по отношению к рабочему столу.
  • Когда окно отключается, все его потомки также отключаются.
А теперь соберите это вместе: если владельцем модального диалога будет рабочий стол, тогда рабочий стол будет отключен, что отключит и всех его потомков. Другими словами, это отключит каждое окно в системе. Даже то, которое вы пытаетесь показать!

Вы также не захотите передавать GetDesktopWindow как своё родительское окно (hwndParent). Если вы создадите дочернее окно (child window), чьим родителем будет GetDesktopWindow, то ваше окно теперь оказывается приклееным к окну рабочего стола. И когда ваше окно вызывает что-то типа MessageBox, то, ну, это же модальный диалог, поэтому тут снова включаются эти же правила, рабочий стол отключается и ваша машина спеклась.

Так какое же значение надо передавать, если у вас нет окна?

Передавайте ноль. Для оконного менеджера, нулевое родительское окно означает "создай это окно без владельца". Для оболочки, UI-окно, равное нулю, обычно значит "не показывай UI". В любом случае, наверное, именно это вы и хотели изначально.

Однако, будьте осторожны: если у вашего потока уже есть окно верхнего уровня без владельца (top-level unowned window), то тогда создание второго такого окна модально создаст кучу хаоса, если пользователь захочет переключиться на первое окно и работать с ним. Если у вас уже есть окно - передавайте его.

1 комментарий:

  1. Здравствуйте!
    Просто буквально на днях сталкивался...
    Есть сторонняя dll, в ней функция показывающая окошко, принимающая в числе параметров хэндл окна по центру которого и покажется окошко.
    Если мое приложение не имеет окна, то "логично" предположить передавать хэндл рабочего стола...
    А тут прочитал и задумался...
    Что думаете по этому поводу?
    Спасибо!

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

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

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

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

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

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