Это перевод Beware of redirected folders, too. Автор: Реймонд Чен. Входит в книгу The Old New Thing.
Ранее мы узнали о перемещаемых пользовательских профилях (roaming user profiles), когда главная копия профиля пользователя хранится на центральном сервере (который для простоты я буду здесь и далее называть "сервером профилей") и копируется локально, чтобы следовать за пользователем, когда он входит на разные машины в сети организации. Многие люди в комментариях сказали, что они бы предпочли, чтобы файлы хранились на сервере напрямую, а не копировались бы при каждом входе.
...when altering one's mind becomes as easy as programming a computer, what does it mean to be human?..
пятница, 30 апреля 2010 г.
Опасайтесь перемещаемых профилей пользователя
Это перевод Beware of roaming user profiles. Автор: Реймонд Чен. Входит в книгу The Old New Thing.
Одной из слабо известных возможностей Windows являются перемещаемые профили пользователей (roaming user profile). Я знаю, что они не слишком известны, потому что я часто слышу предложения о новых возможностях системы, которые не принимают в расчёт сценарий с перемещаемыми профилями пользователей. Действительно, если ваша программа поведёт себя достаточно плохо, то это может привести к потере данных (я поговорю об этом подробнее чуть позже).
Но что такое перемещаемый профиль пользователя?
Одной из слабо известных возможностей Windows являются перемещаемые профили пользователей (roaming user profile). Я знаю, что они не слишком известны, потому что я часто слышу предложения о новых возможностях системы, которые не принимают в расчёт сценарий с перемещаемыми профилями пользователей. Действительно, если ваша программа поведёт себя достаточно плохо, то это может привести к потере данных (я поговорю об этом подробнее чуть позже).
Но что такое перемещаемый профиль пользователя?
четверг, 29 апреля 2010 г.
Absolute(но) для начинающих
Это перевод Absolute (for) Beginners. Блог: Te Waka o Delphi.
Сегодня я случайно предложил использование ключевого слова "absolute" в ответе на вопрос в списке рассылок NZ DUG. Я сразу забыл об этом, но потом кто-то упомянул, что он не видел, как использовали это ключевое слово, вот уже много лет. Поэтому я подумал, что, может быть, будет целесообразным довести его до более широкого внимания.
Сегодня я случайно предложил использование ключевого слова "absolute" в ответе на вопрос в списке рассылок NZ DUG. Я сразу забыл об этом, но потом кто-то упомянул, что он не видел, как использовали это ключевое слово, вот уже много лет. Поэтому я подумал, что, может быть, будет целесообразным довести его до более широкого внимания.
вторник, 27 апреля 2010 г.
Вы не можете даже доверять идентичности вызывающего процесса
Это перевод You can't even trust the identity of the calling executable. Автор: Реймонд Чен.
Не так давно я показал, что вы не можете доверять адресу возврата. Но это ещё не всё: вы не можете доверять и вызывающему исполняемому файлу. Я видел вопросы от людей такого плана: "я хочу проверить, не MyApp.exe-ли вызвал меня. Я собираюсь основывать свои решения по безопасности на этом факте".
Хотя вы можете это сделать, но, на самом деле, это не принесёт вам ничего хорошего.
Не так давно я показал, что вы не можете доверять адресу возврата. Но это ещё не всё: вы не можете доверять и вызывающему исполняемому файлу. Я видел вопросы от людей такого плана: "я хочу проверить, не MyApp.exe-ли вызвал меня. Я собираюсь основывать свои решения по безопасности на этом факте".
Хотя вы можете это сделать, но, на самом деле, это не принесёт вам ничего хорошего.
понедельник, 26 апреля 2010 г.
Будьте осторожны, передавая дескрипторы безопасности между машинами
Это перевод Be careful when interpreting security descriptors across machine boundaries. Автор: Реймонд Чен.
Хотя функция AccessCheck может быть использована для проверки того, разрешает ли указанный дескриптор безопасности (security descriptor) доступ к токену, вам нужно быть в курсе, откуда пришёл этот дескриптор. Если он пришёл с другой машины (например, вы получили его вызовом GetNamedSecurityInfo для файла на сетевом пути), то вызов функции AccessCheck на вашей машине может давать результат, отличный от выполнения функции на удалённой машиине. Другими словами, может случиться так, что AccessCheck скажет вам, что у вас есть доступ, а на самом деле, его у вас нет.
Как такое может произойти?
Хотя функция AccessCheck может быть использована для проверки того, разрешает ли указанный дескриптор безопасности (security descriptor) доступ к токену, вам нужно быть в курсе, откуда пришёл этот дескриптор. Если он пришёл с другой машины (например, вы получили его вызовом GetNamedSecurityInfo для файла на сетевом пути), то вызов функции AccessCheck на вашей машине может давать результат, отличный от выполнения функции на удалённой машиине. Другими словами, может случиться так, что AccessCheck скажет вам, что у вас есть доступ, а на самом деле, его у вас нет.
Как такое может произойти?
воскресенье, 25 апреля 2010 г.
Классовые стили и другие штуки действительно принадлежат только этому классу
Это перевод The per-class window styles and things really are per-class. Автор: Реймонд Чен.
Ранее я обсуждал кому принадлежат различные стили окон. Одной деталью из этого, которую я забыл подчеркнуть, является следующий момент: поскольку младшие 16 битов стиля окна определяются классом, то вы не можете просто взять стили из одного класса и применить их к другим классам.
Ранее я обсуждал кому принадлежат различные стили окон. Одной деталью из этого, которую я забыл подчеркнуть, является следующий момент: поскольку младшие 16 битов стиля окна определяются классом, то вы не можете просто взять стили из одного класса и применить их к другим классам.
суббота, 24 апреля 2010 г.
Кому принадлежат различные биты оконных стилей?
Это перевод Which window style bits belong to whom? Автор: Реймонд Чен.
Существует 64 бита для стилей в параметрах к CreateWindowEx. Кому какие биты принадлежат?
Существует 64 бита для стилей в параметрах к CreateWindowEx. Кому какие биты принадлежат?
пятница, 23 апреля 2010 г.
Почему Корзина имеет разные файловые имена на дисках FAT и NTFS?
Это перевод Why does the Recycle Bin have different file system names on FAT and NTFS? Автор: Реймонд Чен.
На диске FAT каталог, который хранит данные Корзины, называется RECYCLED, но на NTFS диске он называется RECYCLER. Зачем надо было менять его имя?
На диске FAT каталог, который хранит данные Корзины, называется RECYCLED, но на NTFS диске он называется RECYCLER. Зачем надо было менять его имя?
четверг, 22 апреля 2010 г.
Почему испорченный исполняемый модуль иногда приводит к показу сообщения "Программа не умещается в памяти"?
Это перевод Why does a corrupted binary sometimes result in "Program too big to fit in memory"? Автор: Реймонд Чен.
Если вы возьмёте программу и испортите её заголовок (или просто возьмёте файл, который вообще не является программой и дадите ему расширение ".exe"), а потом попробуете запустить её (предупреждение: сохраните сначала свою работу!), то обычно вы получите сообщение "Программа не умещается в памяти". Почему система показывает такое запутывающее сообщение? Почему бы просто не сказать: "Программа повреждена"?
Потому что программа, вообще-то, не повреждена. Ну, или вроде того.
Если вы возьмёте программу и испортите её заголовок (или просто возьмёте файл, который вообще не является программой и дадите ему расширение ".exe"), а потом попробуете запустить её (предупреждение: сохраните сначала свою работу!), то обычно вы получите сообщение "Программа не умещается в памяти". Почему система показывает такое запутывающее сообщение? Почему бы просто не сказать: "Программа повреждена"?
Потому что программа, вообще-то, не повреждена. Ну, или вроде того.
среда, 21 апреля 2010 г.
Ожидание всех описателей в MsgWaitForMultipleObjects - это баг
Это перевод Waiting for all handles with MsgWaitForMultipleObjects is a bug waiting to happen. Автор: Реймонд Чен.
Функции MsgWaitForMultipleObjects и MsgWaitForMultipleObjectsEx позволяют вам указать, хотите ли вы ждать любого описателя или же все описатели (либо указанием bWaitAll = True, либо dwFlags = MWMO_WAITALL, соответственно). Но вы никогда не захотите ждать все описатели.
Функции MsgWaitForMultipleObjects и MsgWaitForMultipleObjectsEx позволяют вам указать, хотите ли вы ждать любого описателя или же все описатели (либо указанием bWaitAll = True, либо dwFlags = MWMO_WAITALL, соответственно). Но вы никогда не захотите ждать все описатели.
Обработка сообщений в течение заданного времени
Это перевод Pumping messages while waiting for a period of time. Автор: Реймонд Чен.
Мы можем использовать функцию MsgWaitForMultipleObjects (или её расширенный вариант MsgWaitForMultipleObjectsEx) для создания функции "sleep с обработкой сообщений" без использования опроса.
Мы можем использовать функцию MsgWaitForMultipleObjects (или её расширенный вариант MsgWaitForMultipleObjectsEx) для создания функции "sleep с обработкой сообщений" без использования опроса.
понедельник, 19 апреля 2010 г.
Вы можете вызывать MsgWaitForMultipleObjects без описателей
Это перевод You can call MsgWaitForMultipleObjects with zero handles. Автор: Реймонд Чен.
Не существует функции WaitMessageTimeout, но вы можете создать её сами при помощи функции MsgWaitForMultipleObjects:
Не существует функции WaitMessageTimeout, но вы можете создать её сами при помощи функции MsgWaitForMultipleObjects:
воскресенье, 18 апреля 2010 г.
Последствия опроса для производительности
Это перевод Performance consequences of polling. Автор: Реймонд Чен.
Опрос губителен (polling kills).
Опрос губителен (polling kills).
суббота, 17 апреля 2010 г.
Если ваша функция обратного вызова завершается неудачно, то установить код ошибки - ваша ответственность
Это перевод If your callback fails, it's your responsibility to set the error code. Автор: Реймонд Чен.
Есть много случаев, когда функции обратного вызова разрешается прервать операцию. Например, вы можете решить вернуть False в обработчике сообщения WM_NCCREATE, чтобы остановить создание окна, или же вы можете решить вернуть False в одной из функций обратного вызова для поиска, типа EnumWindowsProc. Когда вы делаете это, внешняя (по отношению к функции обратного вызова) функция просто передаст ваш признак провала (False) дальше по цепочке своему вызывающему: функция CreateWindow вернёт 0; а EnumWindows вернёт False.
Есть много случаев, когда функции обратного вызова разрешается прервать операцию. Например, вы можете решить вернуть False в обработчике сообщения WM_NCCREATE, чтобы остановить создание окна, или же вы можете решить вернуть False в одной из функций обратного вызова для поиска, типа EnumWindowsProc. Когда вы делаете это, внешняя (по отношению к функции обратного вызова) функция просто передаст ваш признак провала (False) дальше по цепочке своему вызывающему: функция CreateWindow вернёт 0; а EnumWindows вернёт False.
Они спрашивают меня: "почему мой корейский текст выводится в случайном порядке?"
Это перевод They ask me "why is my Korean text in random order?" Автор: Майкл Каплан.
Я получаю похожие вопросы постоянно: люди интересуются, не знаю ли я, почему, скажем, корейский текст показывается в случайном порядке. Они вполне ожидают такое поведение, если они не указывают корейский LCID ($0412 или 1042), но если они задают его - то они ожидают текст в некотором правильном порядке, а по факту получается что-то не то.
Я получаю похожие вопросы постоянно: люди интересуются, не знаю ли я, почему, скажем, корейский текст показывается в случайном порядке. Они вполне ожидают такое поведение, если они не указывают корейский LCID ($0412 или 1042), но если они задают его - то они ожидают текст в некотором правильном порядке, а по факту получается что-то не то.
четверг, 15 апреля 2010 г.
Нормализация и Microsoft - что у нас за история с ними?
Это перевод Normalization and Microsoft -- whats the story? Автор: Майкл Каплан.
Нормализация - это слово, которое явно перегружено смыслами. С тех пор, как я пришёл в Microsoft, к сегодняшнему дню я услышал, по меньшей мере, четыре отдельных случая:
Но, отстраняя вопросы терминологии, поддерживает ли сопоставление/collation (как операция) концепции, описанные в нормализации Unicode? Другими словами, рассматривает ли функция CompareString символ U+00c5 (Å, LATIN CAPITAL LETTER A WITH RING ABOVE) как эквивалент U+0041 U+030a (Å, LATIN CAPITAL LETTER A + COMBINING RING ABOVE)?
Нормализация - это слово, которое явно перегружено смыслами. С тех пор, как я пришёл в Microsoft, к сегодняшнему дню я услышал, по меньшей мере, четыре отдельных случая:
- Оно используется командой SQL сервера, когда они говорят о сравнениях строк.
- Оно используется API сопоставления NLS по той же причине (флаги NORM_*), ссылаясь на потенциально игнорируемые различия в строках при сравнении.
- Robert A. Wlodarczyk использовал термин строковой нормализации, ссылаясь на более общий тип поиска, включающий в себя нечёткое сравнение строк.
- В Unicode есть технический отчёт, названный Unicode Normalization Forms (формы/виды нормализации Unicode), который определяет технику для "сворачивания" (folding out) различий в эквивалентных последовательностях.
- Сделать что-то нормальным, в смысле соответствия норме или стандарту
- Сделать (текст или язык) регулярным и согласующимся, особенно по отношению к стилю и орфографии
- Удалить штаммы и снизить грубую кристаллическую структуру (металл), особенно нагреванием и охлаждением
- Уменьшение до стандартного или нормального состояния
Но, отстраняя вопросы терминологии, поддерживает ли сопоставление/collation (как операция) концепции, описанные в нормализации Unicode? Другими словами, рассматривает ли функция CompareString символ U+00c5 (Å, LATIN CAPITAL LETTER A WITH RING ABOVE) как эквивалент U+0041 U+030a (Å, LATIN CAPITAL LETTER A + COMBINING RING ABOVE)?
среда, 14 апреля 2010 г.
Microsoft не использует алгоритм сопоставления Unicode
Это перевод Microsoft does not use the Unicode Collation Algorithm. Автор: Майкл Каплан.
В 1980-м Robert A. Heinlein в своей книге Expanded Universe рассказал такую историю (потерпите меня - я клянусь, что это имеет отношение к теме поста):
В 1980-м Robert A. Heinlein в своей книге Expanded Universe рассказал такую историю (потерпите меня - я клянусь, что это имеет отношение к теме поста):
Несколько лет назад меня посетил астроном, довольно молодой и выдающийся. Он сказал, что давно читает мои работы, и дальнейший разговор подтвердил это. Я рассказал ему о времени, когда мне нужна была синергетическая орбита от Земли до постоянной станции; я рассказал ему историю, по которой она потребовалась, а он был знаком с ней, упомянув, что читал книгу в средней школе.
Эта орбита внешне похожа на межпланетное перемещение комет, но, фактически, является серией компромиссов для прибытия вровень со станцией; прошедшее время является негладким интегралом, которого нет в руководстве Hudson-а, но он может быть решён методами численного интегрирования.
Я женат на женщине, которая знает больше математики, истории и языков, чем я. Это должно научить меня смирению (а иногда и делает, на несколько минут). Ее мозг очень помогает мне профессионально. Я сказал этому молодому ученому, как мы получили ярды исписанной бумаги, а затем каждый из нас работал три дня, независимо, чтобы решить проблему и проверить друг друга, - то ответ исчез в одной строке одного параграфа (SPACE CADET), но всё же усилия были стоящими.
Доктор Whoosis спросил: "Но почему вы просто не прогнали это через компьютер?".
Я моргнул. Затем я медленно и мягко сказал: "Мой дорогой мальчик...", (обычно я не называю докторов в хардкорных науках "дорогими мальчиками" - они внушают уважение. Но это был особый случай) - "Мой дорогой мальчик... это был 1947-й".
Ему потребовалось несколько моментов, чтобы сообразить, затем он покраснел...
вторник, 13 апреля 2010 г.
Некоторые клавиатурные термины
Это перевод Some keyboarding terms. Автор: Майкл Каплан.
Эта публикация пытается прояснить некоторые проблемы в документации, касающейся клавиатуры, так как есть много путаницы в этих вещах, и нет необходимости усугублять это непонятными терминами. Будущие посты будут строиться на ней, поэтому, если вы уже знаете о клавиатурах, вы могли бы её пропустить (хотя я бы не советовал это делать). Это не настоящий словарик, поскольку он не упорядочен по алфавиту; порядок - произволен; я добавлял термин, либо когда я думал о нём, чтобы добавить его, либо когда я думал, что может быть увеличен драматический эффект.
Эта публикация пытается прояснить некоторые проблемы в документации, касающейся клавиатуры, так как есть много путаницы в этих вещах, и нет необходимости усугублять это непонятными терминами. Будущие посты будут строиться на ней, поэтому, если вы уже знаете о клавиатурах, вы могли бы её пропустить (хотя я бы не советовал это делать). Это не настоящий словарик, поскольку он не упорядочен по алфавиту; порядок - произволен; я добавлял термин, либо когда я думал о нём, чтобы добавить его, либо когда я думал, что может быть увеличен драматический эффект.
понедельник, 12 апреля 2010 г.
Использование ReadProcessMemory не является предпочтительным способом межпрограммного взаимодействия
Это перевод ReadProcessMemory is not a preferred IPC mechanism. Автор: Реймонд Чен.
Иногда я вижу, как кто-то пытается использовать функцию ReadProcessMemory в качестве механизма связи между процессами. Это неразумно по нескольким причинам.
Иногда я вижу, как кто-то пытается использовать функцию ReadProcessMemory в качестве механизма связи между процессами. Это неразумно по нескольким причинам.
Когда web-сайты полагаются на дыры в безопасности
Это перевод When web sites rely on security holes. Автор: Реймонд Чен.
Возможно, самый большой риск, когда вы исправляете проблему безопасности, связан с тем, что своим исправлением вы можете поломать существующие приложения, которые полагались на старые ослабленные правила. В конце-концов, отключение небезопасной возможности - это очень просто. А вот отключить её так, чтобы соблюсти совместимость с уже написанным кодом, - это сложно. Я принимал участие в исследованиях безопасности. И, наверное, большую часть своего времени я потратил на то, чтобы наше исправление не ломало бы программы существующих клиентов (и это обычно большой вопрос для приложений, критичных для бизнеса).
Возможно, самый большой риск, когда вы исправляете проблему безопасности, связан с тем, что своим исправлением вы можете поломать существующие приложения, которые полагались на старые ослабленные правила. В конце-концов, отключение небезопасной возможности - это очень просто. А вот отключить её так, чтобы соблюсти совместимость с уже написанным кодом, - это сложно. Я принимал участие в исследованиях безопасности. И, наверное, большую часть своего времени я потратил на то, чтобы наше исправление не ломало бы программы существующих клиентов (и это обычно большой вопрос для приложений, критичных для бизнеса).
воскресенье, 11 апреля 2010 г.
Приманка: стиль оформления
Это перевод The decoy visual style. Автор: Реймонд Чен.
Во время разработки Windows XP, команда визуальных дизайнеров очень внимательно хранила тайну о том, как будет выглядеть финальная тема. Они выполнили много исследований и затратили много сил на дизайн, так что они хотели произвести фурор на конференции E3, когда должны были продемонстрировать стиль Luna. Вне команды дизайнеров никто не знал, как будет выглядеть новый стиль Windows (даже я).
Во время разработки Windows XP, команда визуальных дизайнеров очень внимательно хранила тайну о том, как будет выглядеть финальная тема. Они выполнили много исследований и затратили много сил на дизайн, так что они хотели произвести фурор на конференции E3, когда должны были продемонстрировать стиль Luna. Вне команды дизайнеров никто не знал, как будет выглядеть новый стиль Windows (даже я).
суббота, 10 апреля 2010 г.
Приманка для свойств экрана в Панели управления
Это перевод The decoy display control panel. Автор: Реймонд Чен.
В последний раз мы видели пример "приманки" для апплета Принтеры, используемой в службе совместимости приложений. Сегодня, мы посмотрим на другую приманку, на сей раз - для апплета свойств экрана.
В последний раз мы видели пример "приманки" для апплета Принтеры, используемой в службе совместимости приложений. Сегодня, мы посмотрим на другую приманку, на сей раз - для апплета свойств экрана.
четверг, 8 апреля 2010 г.
Когда программы предполагают, что система никогда не изменится, эпизод 3
Это перевод When programs assume that the system will never change, episode 3. Автор: Реймонд Чен.
Мой коллега решил одну из самых странных загадок обратной совместимости, когда пытался понять, почему одна конкретная программа не могла открыть папку "Принтеры" в Панели управления.
Мой коллега решил одну из самых странных загадок обратной совместимости, когда пытался понять, почему одна конкретная программа не могла открыть папку "Принтеры" в Панели управления.
среда, 7 апреля 2010 г.
Почему ImageList и Toolbar используют горизонтальные полосы, если вертикальные намного лучше?
Это перевод Why do image lists and tool bars use horizontal strips if vertical is so much better? Автор: Реймонд Чен.
Два человека указали, что функция ImageList_Add и toolbar-ы используют горизонтальные рисунки-полосы, хотя мы выяснили, что вертикальные являются намного более эффективными.
Два человека указали, что функция ImageList_Add и toolbar-ы используют горизонтальные рисунки-полосы, хотя мы выяснили, что вертикальные являются намного более эффективными.
вторник, 6 апреля 2010 г.
Самая медленная инструкция RET в мире
Это перевод The world's slowest RET instruction. Автор: Реймонд Чен.
Время от времени кто-то спрашивает:
Время от времени кто-то спрашивает:
Я отлаживаю зависание процесса и я вижу, что многие потоки застряли на инструкции RET. Когда я пытаюсь трассировать одну команду в этом потоке, бряк никогда не срабатывает. Как будто заклинивает саму команду RET! Кажется, я нашёл самую медленную RET в мире.(частым вариантом этого вопроса является: поток загружает CPU на 100%... на инструкции RET?)
понедельник, 5 апреля 2010 г.
Сообщения потоку "съедаются" модальным циклом
Это перевод Thread messages are eaten by modal loops. Автор: Реймонд Чен.
Сообщения потоку (создаваемые функцией PostThreadMessage) никак не обрабатываются, будучи переданными в функцию DispatchMessage. Это очевидно, если вы подумаете об этом. Потому что с сообщением потоку не ассоциировано описателя окна. DispatchMessage понятия не имеет, что делать с таким сообщением. У неё нет иного выхода, кроме как проигнорировать сообщение.
Сообщения потоку (создаваемые функцией PostThreadMessage) никак не обрабатываются, будучи переданными в функцию DispatchMessage. Это очевидно, если вы подумаете об этом. Потому что с сообщением потоку не ассоциировано описателя окна. DispatchMessage понятия не имеет, что делать с таким сообщением. У неё нет иного выхода, кроме как проигнорировать сообщение.
воскресенье, 4 апреля 2010 г.
Так называемый стек Itanium-а
Это перевод The Itanium's so-called stack. Автор: Реймонд Чен.
В прошлом году я говорил о том, что процессоры Itanium имеют два стека. Первый из них - обычный "стек" (тот самый, на который ссылается регистр sp): блок памяти, управляемый вручную, из которого функции могут брать память для себя. Например, если вы объявите локальную переменную вроде
Но не все локальные переменные хранятся в "стеке".
В прошлом году я говорил о том, что процессоры Itanium имеют два стека. Первый из них - обычный "стек" (тот самый, на который ссылается регистр sp): блок памяти, управляемый вручную, из которого функции могут брать память для себя. Например, если вы объявите локальную переменную вроде
var szBuffer: array[0..MAX_PATH] of Char;то этот буфер будет размещён в "стеке".
Но не все локальные переменные хранятся в "стеке".
суббота, 3 апреля 2010 г.
Что можно сделать с DC-кистью?
Это перевод What is the DC brush good for? Автор: Реймонд Чен.
DC-кисть, возвращаемая GetStockObject(DC_BRUSH) - это stock-кисть, ассоциированная с контекстом устройства (DC - device context). Как и кисти системных цветов, цвет DC-кисти может быть различным. Но если цвета системных кистей меняются по системным цветам, то цвет DC-кисти меняется по вашей команде.
DC-кисть очень удобна, когда вам нужна кисть со сплошным цветом на короткое время, потому что она всегда существует, и её не надо создавать и удалять. Обычно, вам нужно создать кисть, что-то ей нарисовать и удалить. Но с DC-кистью вы можете просто задать её цвет и начать рисовать. Но это сработает только на короткое время, потому что в тот момент, когда кто-то ещё вызовет функцию SetDCBrushColor для вашего DC, DC-кисть будет изменена. На практике это означает, что DC-кисть может быть использована только на участках кода, где вы не вызываете внешних функций для вашего DC (заметьте, что каждый DC имеет свою собственную DC-кисть, поэтому в этом случае вам нужно волноваться только о другом потоке, который может работать с вашим DC одновременно с вами, но это не происходит ни в одной модели рисования, с которыми я знаком).
DC-кисть удивительно удобна для обработки различных сообщений типа WM_CTLCOLOR. Эти сообщения требуют от вас вернуть описатель кисти, которым нужно рисовать, скажем, фон элемента управления. Если вам нужна сплошная кисть, то обычно это означает создание кисти, сохранение её куда-то на всё время жизни окна и удаление её, когда окно уходит (некоторые люди хранят кисть в глобальной переменной, что отлично работает, пока кто-то не решит создать второе окно - тогда у вас начинаются большие проблемы).
Давайте используем DC-кисть, чтобы изменить цвет фона элемента управления. Сама программа не слишком интересна; это просто демонстрация того, как вы можете использовать DC-кисть.
Начните, как всегда, с пустого VCL-приложения, бросьте на форму TStaticText и сделайте такие изменения:
Когда нас просят кастомизировать цвет, мы сначала вызываем унаследованный вариант, так что будут установлены цвета по-умолчанию (не имеет значения в нашем случае, потому что мы ничего не рисуем, а цвет фона изменяем сами - но это хороший принцип). Поскольку мы хотим изменить цвет фона, то мы устанавливаем цвет DC-кисти в красный и возвращаем нашу DC-кисть как желаемую кисть для фона.
Затем элемент управления берёт кисть, которую мы вернули (DC-кисть), и использует её, чтобы нарисовать фон, что приводит к красному фону, потому что это тот цвет, что мы установили для DC-кисти.
Обычно при кастомизации фоновой кисти, мы создаём кисть, возвращаем её из обработчика сообщения, а потом удаляем её, когда окно уничтожается. Но, используя DC-кисть, нам удалось избежать всего этого кода.
Существует также и DC-перо - GetStockObject(DC_PEN), которое ведёт себя в аналогичной манере.
DC-кисть, возвращаемая GetStockObject(DC_BRUSH) - это stock-кисть, ассоциированная с контекстом устройства (DC - device context). Как и кисти системных цветов, цвет DC-кисти может быть различным. Но если цвета системных кистей меняются по системным цветам, то цвет DC-кисти меняется по вашей команде.
DC-кисть очень удобна, когда вам нужна кисть со сплошным цветом на короткое время, потому что она всегда существует, и её не надо создавать и удалять. Обычно, вам нужно создать кисть, что-то ей нарисовать и удалить. Но с DC-кистью вы можете просто задать её цвет и начать рисовать. Но это сработает только на короткое время, потому что в тот момент, когда кто-то ещё вызовет функцию SetDCBrushColor для вашего DC, DC-кисть будет изменена. На практике это означает, что DC-кисть может быть использована только на участках кода, где вы не вызываете внешних функций для вашего DC (заметьте, что каждый DC имеет свою собственную DC-кисть, поэтому в этом случае вам нужно волноваться только о другом потоке, который может работать с вашим DC одновременно с вами, но это не происходит ни в одной модели рисования, с которыми я знаком).
DC-кисть удивительно удобна для обработки различных сообщений типа WM_CTLCOLOR. Эти сообщения требуют от вас вернуть описатель кисти, которым нужно рисовать, скажем, фон элемента управления. Если вам нужна сплошная кисть, то обычно это означает создание кисти, сохранение её куда-то на всё время жизни окна и удаление её, когда окно уходит (некоторые люди хранят кисть в глобальной переменной, что отлично работает, пока кто-то не решит создать второе окно - тогда у вас начинаются большие проблемы).
Давайте используем DC-кисть, чтобы изменить цвет фона элемента управления. Сама программа не слишком интересна; это просто демонстрация того, как вы можете использовать DC-кисть.
Начните, как всегда, с пустого VCL-приложения, бросьте на форму TStaticText и сделайте такие изменения:
typeЗапустите эту программу и заметьте, что мы изменили цвет фона на красный.
TForm1 = class(TForm)
StaticText1: TStaticText;
private
{ Private declarations }
public
{ Public declarations }
procedure WMCtrlColorStatic(var Msg: TWMCtlColorStatic); message WM_CTLCOLORSTATIC;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WMCtrlColorStatic(var Msg: TWMCtlColorStatic);
begin
inherited;
SetDCBrushColor(Msg.ChildDC, ColorToRGB(clRed));
Msg.Result := GetStockObject(DC_BRUSH);
end;
Когда нас просят кастомизировать цвет, мы сначала вызываем унаследованный вариант, так что будут установлены цвета по-умолчанию (не имеет значения в нашем случае, потому что мы ничего не рисуем, а цвет фона изменяем сами - но это хороший принцип). Поскольку мы хотим изменить цвет фона, то мы устанавливаем цвет DC-кисти в красный и возвращаем нашу DC-кисть как желаемую кисть для фона.
Затем элемент управления берёт кисть, которую мы вернули (DC-кисть), и использует её, чтобы нарисовать фон, что приводит к красному фону, потому что это тот цвет, что мы установили для DC-кисти.
Обычно при кастомизации фоновой кисти, мы создаём кисть, возвращаем её из обработчика сообщения, а потом удаляем её, когда окно уничтожается. Но, используя DC-кисть, нам удалось избежать всего этого кода.
Существует также и DC-перо - GetStockObject(DC_PEN), которое ведёт себя в аналогичной манере.
пятница, 2 апреля 2010 г.
Когда люди просят добавить в систему дыры в безопасности: скрытие файлов от Проводника
Это перевод When people ask for security holes as features: Hiding files from Explorer. Автор: Реймонд Чен.
По-умолчанию, Проводник не показывает файлы с установленным флагом FILE_ATTRIBUTE_HIDDEN, потому что кто-то захотел скрыть эти файлы от просмотра.
По-умолчанию, Проводник не показывает файлы с установленным флагом FILE_ATTRIBUTE_HIDDEN, потому что кто-то захотел скрыть эти файлы от просмотра.
четверг, 1 апреля 2010 г.
Для чего используется HINSTANCE, передаваемый в CreateWindow и RegisterClass?
Это перевод What is the HINSTANCE passed to CreateWindow and RegisterClass used for? Автор: Реймонд Чен.
Одним из слабо понимаемых параметров функций CreateWindow и RegisterClass является HINSTANCE (передаваемый либо как параметр, либо как поле записи TWndClass).
Одним из слабо понимаемых параметров функций CreateWindow и RegisterClass является HINSTANCE (передаваемый либо как параметр, либо как поле записи TWndClass).
Подписаться на:
Сообщения (Atom)