Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

При загрузке изображения из файла, ресурса или потока класс

TBitmap
обычно создает изображение в формате DIB-секции, соответствующее источнику по цветовой глубине. Исключение составляют сжатые файлы (формат BMP поддерживает сжатие только для 16- и 256-цветных изображений) — в этом случае создается DDB. В файле
Graphics
определена глобальная переменная
DDBsOnly
, которая по умолчанию равна
False
. Если изменить ее значение на
True
, загружаемое изображение всегда будет иметь формат DDB.

Примечание

В справке сказано, что когда

DDBsOnly = False
, вновь
создаваемые изображения по умолчанию хранятся в виде DIB-секций. На самом деле из-за ошибки в модуле
Graphics
(как минимум до 2007-й версии Delphi включительно) вновь созданное изображение всегда хранится как DDB независимо от значения
DDBsOnly
.

Класс

TBitmap
имеет свойство
ScanLine
, через которое можно получить прямой доступ к массиву пикселов, составляющих изображение. В справке написано, что это свойство можно использовать только с DIB-изображениями. Но на самом деле DDB-изображения тоже позволяют использовать это свойство, хотя и с существенными ограничениями. Если изображение хранится в DDB- формате, при обращении к 
ScanLine
создастся его DIB-копия, и
ScanLine
возвращает указатель на массив этой копии. Поэтому, во-первых,
ScanLine
работает с DDB-изображениями очень медленно, а во-вторых, работает не с изображением, а с его копией, откуда вытекают следующие ограничения:

1. Копия создаётся на момент обращения к

ScanLine
, поэтому изменения, сделанные на изображении с помощью GDI-функций после этого, будут недоступными.

2. Каждое обращение к

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

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

ScanLine
дает возможность прочитать, но не изменить изображение.

Следует отметить, что

TBitmap
иногда создает DIB-секции, даже если свойства
HandleType
и
PixelFormat
явно указывают на использование DDB. Особенно часто это наблюдается для изображений большого размера. По всей видимости, это происходит, когда в системном пуле нет места для хранения DDB-изображения такого размера, и разработчики TBitmap решили, что в таком случае лучше создать DIB-изображение, чем не создавать никакого. Пример
BitmapSpeed
на прилагаемом компакт-диске позволяет сравнить скорость выполнения различных операций с DDB- и DIB-изображениями.

1.1.12. ANSI и Unicode

Windows поддерживает две кодировки: ANSI и Unicode. В кодировке ANSI (American National Standard Institute) каждый символ кодируется однобайтным кодом. Коды от 0 до 127 совпадают с кодами ASCII, коды от 128 до 255 могут означать разные символы различных языков в зависимости от выбранной кодовой страницы. Кодовые страницы позволяют уместить многочисленные символы различных языков в однобайтный код, но при этом можно работать только с одной кодовой страницей, т.е. с одним языком. Неверно выбранная кодовая страница приводит к появлению непонятных символов (в Интернете их обычно называют "кракозябрами") вместо осмысленного текста.

В кодировке Unicode используется 2 байта на символ, что даёт возможность закодировать 65 536 символов. Этого хватает для символов латиницы и кириллицы, греческого алфавита, китайских иероглифов, арабских и еврейских букв, а также многочисленных дополнительных (финансовых, математических и т. п.) символов. Кодовых страниц в Unicode нет.

Примечание

Кодовая страница русского языка в ANSI имеет номер 1251.

Кодировка символов в ней отличается от принятой в DOS так называемой альтернативной кодировки. В целях совместимости для DOS-программ, а также для консольных приложений Windows использует альтернативную кодировку. Именно поэтому при выводе русского текста в консольных приложениях получаются те самые "кракозябры". Чтобы избежать этого, следует перекодировать символы из кодировки ANSI в DOS при выводе, и наоборот — при вводе. Это можно сделать с помощью функций
CharToOem
и
OemToChar
.

Windows NT/2000/XP поддерживает ANSI и Unicode в полном объеме. Это значит, что любая функция, работающая со строками, представлена в двух вариантах: для ANSI и для Unicode. Windows 9x/МЕ в полном объеме поддерживает только ANSI. Unicode-варианты в этих системах есть у относительно небольшого числа функций. Каждая страница MSDN, посвященная функции, работающей со строками (или со структурами, содержащими строки), в нижней части содержит надпись, показывающую, реализован ли Unicode-вариант этой функции только для NT/2000/XP или для всех платформ.

Примечание

В качестве примера рассмотрим функции вывода текста на экран. Unicode-версию на всех платформах имеют только две из них

TextOut
и
ExtTextOut
. Функции
DrawText
и
DrawTextEx
имеют Unicode-варианты только в Windows NT/2000/XP. Если же смотреть функции для работы с окнами, то среди них нет ни одной, которая имела бы Unicode-вариант в Windows 9х/МЕ. Следует отметить, что с относительно недавнего времени Microsoft предоставляет расширение для Windows 9x/МЕ которое позволяет добавить полную поддержку Unicode в эти системы. Это расширение называется MSLU (Microsoft Layer for Unicode), его можно скачать с официального сайта Microsoft.

Рассмотрим, как сосуществуют два варианта на примере функции

RegisterWindowMessage
. Согласно справке, она экспортируется библиотекой user32.dll. Однако если посмотреть список функций, экспортируемых этой библиотекой (это можно сделать, например, при помощи утилиты TDump.exe, входящей в состав Delphi), то там этой функции не будет, зато будут функции
RegisterWindowMessageA
и
RegisterWindowMessageW
. Первая из них — это ANSI-вариант функции, вторая — Unicode-вариант (буква W означает Wide — широкий; символы кодировки Unicode часто называются широкими из-за того, что на один символ приходится не один, а два байта).

Сначала разберемся с тем, как используются два варианта одной функции в Microsoft Visual C++. В стандартных заголовочных файлах учитывается наличие макроопределения

UNICODE
. Есть два символьных типа —
CHAR
для ANSI и
WCHAR
для Unicode. Если макрос
UNICODE
определен, тип
TCHAR
соответствует типу
WCHAR
, если не определен — типу
CHAR
(после этого производные от
TCHAR
типы, такие как
LPCTSTR
автоматически начинают соответствовать кодировке, определяемой наличием или отсутствием определения
UNICODE
). В заголовочных файлах импортируются оба варианта функции, а также определяется макрос
RegisterWindowMessage
. Его смысл также зависит от макроса
UNICODE
: если он определен,
RegisterWindowMessage
эквивалентен
RegisterWindowMessageW
, если не определен —
RegisterWindowMessageA
. Все функции, поддерживающие два варианта кодировки, импортируются точно так же. Таким образом, вставляя или убирая макроопределение
UNICODE
, можно, не меняя ни единого символа в программе, компилировать ее ANSI- или Unicode-версию.

Поделиться:
Популярные книги

Изгой. Трилогия

Михайлов Дем Алексеевич
Изгой
Фантастика:
фэнтези
8.45
рейтинг книги
Изгой. Трилогия

Старатель 2

Лей Влад
2. Старатели
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Старатель 2

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Кодекс Охотника. Книга IX

Винокуров Юрий
9. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга IX

Школа Семи Камней

Жгулёв Пётр Николаевич
10. Real-Rpg
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Школа Семи Камней

Тайны ордена

Каменистый Артем
6. Девятый
Фантастика:
боевая фантастика
попаданцы
7.48
рейтинг книги
Тайны ордена

Убивать чтобы жить 9

Бор Жорж
9. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 9

Мимик нового Мира 11

Северный Лис
10. Мимик!
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 11

Пришествие бога смерти. Том 5

Дорничев Дмитрий
5. Ленивое божество
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Пришествие бога смерти. Том 5

Аномальный наследник. Том 3

Тарс Элиан
2. Аномальный наследник
Фантастика:
фэнтези
7.74
рейтинг книги
Аномальный наследник. Том 3

Опер. Девочка на спор

Бигси Анна
5. Опасная работа
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Опер. Девочка на спор

Имя нам Легион. Том 4

Дорничев Дмитрий
4. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 4

Приручитель женщин-монстров. Том 8

Дорничев Дмитрий
8. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 8

Личник

Валериев Игорь
3. Ермак
Фантастика:
альтернативная история
6.33
рейтинг книги
Личник