суббота, 5 сентября 2009 г.

Для чего можно использовать атом, возвращаемый RegisterClass?

Это перевод What's the atom returned by RegisterClass useful for? Автор: Реймонд Чен.

Функции RegisterClass и RegisterClassEx возвращают ATOM. Для чего этот ATOM можно использовать?

Имена всех зарегистрированных оконных классов хранятся в таблице атомов внутри USER32. Значение, возвращаемое функциями регистрации классов, является этим самым атомом. Вы также можете получить атом по оконному классу, спрашивая окно этого класса с помощью GetClassWord(hwnd, GCW_ATOM).

Атом может быть сконвертирован в т.н. integer atom (PChar) с помощью макроса MAKEINTATOM, который потом может быть использован функциями, которые принимают имена классов или в форме имени или в форме атомов. Самый частый случай - использование параметра lpClassName в макросе CreateWindow и функции CreateWindowEx. Менее частый - вы также можете использовать его как параметр lpClassName в функциях GetClassInfo и GetClassInfoEx (хотя я не могу представить, зачем бы вам понадобилось делать это. Чтобы иметь на руках атом для передачи в GetClassInfo, вам нужно зарегистрировать класс (потому что именно так вы получаете атом), но в этом случае тогда: почему вы получаете информацию о классе, который сами же и зарегистрировали?).

Чтобы сконвертировать имя класса в атом, вы можете создать пустое (dummy) окно этого класса и использовать упоминавшуюся выше GetClassWord(hwnd, GCW_ATOM). Или, вы можете воспользоваться тем фактом, что возвращаемое значение функции GetClassInfoEx является атомом строки, преобразованной к BOOL. Это позволит вам сделать преобразование, не создавая предварительно окно (имейте ввиду, однако, что возвращаемое GetClassInfoEx значение не является атомом на системах, наследованных от Windows 95).

Но для чего годится атом?

Ну, в действительности, не для многого. Конечно, он экономит вам передачу строки в функции типа CreateWindow, но всё, что он делает, это заменяет строку на число, которое вы теперь должны сохранить в глобальную переменную для дальнейшего использования. Что раньше было строкой, которую вы могли хранить константой, теперь является атомом, который вы должны хранить отдельно. Не очень ясно, что в действительности вы тут выигрываете.

Я думаю, что вы можете использовать его, чтобы быстро проверить, принадлежит ли окно заданному классу. Вы можете получить атом этого класса (например, через GetClassInfo) и потом получать атомы для окон и сравнивать их. Но вы не можете кэшировать атом класса, поскольку класс может быть разрегистрирован и перерегистрирован снова (что приведёт к получению нового атома класса). И вы не можете предварительно выбрать (prefetch) атом класса, потому что класс может быть не зарегистрирован в тот момент, когда вы хотите получить атом (кроме того, выше мы уже заметили, что вы всё равно не можете кэшировать предварительно загруженный атом). Так что этот случай не представляет особой ценности; вы ровно так же можете использовать функцию GetClassName и сравнивать получаемые имена классов с именем искомого класса.

Другими словами, атомы оконных классов являются анахронизмом. Как и подмена классов диалоговых окон, атомы - одно из тех обобщений Win32 API, которые так никогда и не сдвинулись с мёртвой точки, но которые теперь должны переноситься из версии в версию по соображениям обратной совместимости.

Но, по крайней мере, теперь вы знаете что к чему.

Комментариев нет:

Отправить комментарий

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

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

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

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

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