платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 5 - Больше о тексте

Предыдущая тема Следующая тема Перейти вниз

платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 5 - Больше о тексте

Сообщение  electrik в Вс Июн 28, 2009 7:55 pm

Win32 API. Урок 5. Больше о тексте

Мы еще немного поэкспериментируем, то есть фонт и цвет.


Теория:

Цветовая система Windows базируется на RGB значениях, R=красный, G=зеленый, B=синий. Если вы хотите указать Windows цвет, вы должны определить желаемый цвет в системе этих трех основных цветов. Каждое цветовое значение имеет область определения от 0 до 255. Например, если вы хотите чистый красный цвет,
вам следует использовать 255, 0, 0. Или если вы хотите чистый белый цвет, вы должны использовать 255, 255, 255. Вы можете видеть из примеров, что получение нужного цвета очень сложно, используя эту систему, так что вам нужно иметь хорошее "чувство на цвета", как мешать и составлять их. Для установки цвета текста или фона, вы можете использовать SetTextColor и SetBkColor, оба из которых требуют хэндл контекста устройства и 32-битное RGB значение.
Вы можете "создать" фонт, вызвав CreateFont или CreateFontIndirect. Разница
между ними заключается в том, что CreateFontIndirect получает только один параметр: указатель на структуру логического фонта, LOGFONT.

CreateFontIndirect более гибкая функция из этих двух, особенно если вашей программе необходимо часто менять фонты. Тем не менее, в нашем примере мы "создадим" только один фонт для демонстрации, поэтому будем делать это через CreateFont. После вызова этой функции, она вернет хэндл фонта, который вы должны выбрать в определенном контексте устройства. После этого, каждая текстовая API функция будет использовать фонт, который мы выбрали.

Содержимое:
Код:

' больше о тексте
#include "windows.bi"

declare function WinMain ( byval hInst as HINSTANCE, _
byval hPrevInst as HINSTANCE, _
  byval szCmdLine as LPSTR, _
  byval iCmdShow as integer ) as integer

' начало программы

' строка для вывода на экран
#define TestString "Win32 FreeBasic is great and easy!"
#define ClassName "SimpleWinClass" ' имя класса окна
#define AppName "Our First Window" ' имя программы
end WinMain( GetModuleHandle( NULL ) ,NULL,GetCommandLine() , SW_SHOWNORMAL ) ' вызвать основную функцию
' здесь заканчивается программа

' процедура окна
function  WndProc _
(byval hwnd as HWND, _ ' хэндл окна
byval uMsg as UINT, _ ' сообщение
byval wParam as WPARAM, _ ' дополнительный  параметр сообщений
byval lParam as LPARAM) as LRESULT ' дополнительный параметр сообщений

dim hDc as HDC ' хэндл контекста устройства
dim ps as PAINTSTRUCT ' структура PAINTSTRUCT
dim hFont as HFONT
function = 0
select case uMsg  'начинаем обработку сообщений
case WM_DESTROY ' если пользователь закрывает окно
PostQuitMessage(0) ' выходим из программы
exit function
case WM_PAINT ' сообщение отрисовки окна
'получим контекст устройства в hdc и начнем отрисовку
hdc = BeginPaint(hWnd, @ps)

' создадим логический фонт и  выберем его в контексте устройства
hFont = SelectObject(hdc, CreateFont _
(24, _ ' высота символов
16, _ ' ширина символов
0, _ ' ориентация вывода следующего символа
0, _ ' поворот символа в десятых градусов
400, _ ' толщина линии
0, _ ' 0 для обычных символов, любое другое значение для романских
0, _ ' 0 для обычных символов, любое другое значение для подчеркнутых
0, _ ' 0 для обычных символов, любое другое значение для перечеркнутых.
OEM_CHARSET, _ ' символьный набор фонта
OUT_DEFAULT_PRECIS, _ ' приближение фонта к указанным характеристикам
CLIP_DEFAULT_PRECIS, _ ' определяет, что делать с символами, вылезающими за пределы региона
DEFAULT_QUALITY, _ ' качество вывода
DEFAULT_PITCH or FF_SCRIPT, _ ' указывает питч и семейство фонта
"script")) ' название фонта

SetTextColor(hdc, bgr(50, 200, 200)) ' установить тцвет текста
SetBkColor(hdc, bgr(255, 0, 0)) ' установить цвет фона
TextOut(hdc,0, 0, @TestString,SIZEOF(TestString)) ' отрисовываем текст на клиентскую область
SelectObject(hdc, hfont) ' обязательно восстановим старый фонт
EndPaint(hWnd, @ps) ' завершаем отрисовку и освобождаем хэндл контекста устройства
end select
function = DefWindowProc(hWnd,uMsg,wParam,lParam) ' Дефаултная функция обработки окна
end function


'функция WinMain
function WinMain _
(byval hInst as HINSTANCE, _ ' хэндл программы
byval hPrevInst as HINSTANCE, _ 'в win32 всегда 0
byval szCmdLine as LPSTR, _  'указатель на командную строку
byval iCmdShow as integer ) as integer  ' состояние окна при первом появлении

dim wc as WNDCLASSEX ' структура параметров окна
dim wMsg as MSG  ' структура сообщений
dim hWnd as HWND ' хэндл окна

 'структура класса окна wc
with wc ' заполняем структуру wc
.cbSize = SIZEOF( WNDCLASSEX )  ' размер структуры WNDCLASSEX
.style = CS_HREDRAW or CS_VREDRAW  ' Стиль окна
.lpfnWndProc = @WndProc ' Адрес процедуры окна WndProc
.cbClsExtra = NULL  ' резервирование  дополнительных байт за концом структуры
.cbWndExtra = NULL
.hInstance = hInst  ' хэндл модуля
.hbrBackground = cast(HGDIOBJ, COLOR_WINDOW+1) ' Цвет фона
.lpszMenuName = NULL ' Хэндл меню
.lpszClassName = @ClassName ' имя класса окна
.hIcon = LoadIcon( NULL,IDI_APPLICATION ) ' Хэндл иконки
.hIconSm = .hIcon 'Хэндл маленькой иконки
.hCursor = LoadCursor( NULL,IDC_ARROW) ' Хэндл курсора
end with

' регистрация нашего класса окна
if(RegisterClassEx(@wc) = FALSE) then
MessageBox(0,"Не могу зарегистрировать класс окна","Ошибка",0)
end 1
end if

' Создадим окно
hwnd = CreateWindowEx _
(NULL, _ ' дополнительные стили
ClassName, _ ' строка с именем класса окна
AppName, _ ' строка с именем окна
WS_OVERLAPPEDWINDOW, _ ' стиль окна
CW_USEDEFAULT, _ ' X
CW_USEDEFAULT, _ ' Y
CW_USEDEFAULT, _ ' ширина окна
CW_USEDEFAULT, _ ' высота окна
NULL, _ ' хэндл родительского окна
NULL, _ ' хэндл меню
hInst, _ ' хэндл модуля
NULL) ' указатель на структуру данных

ShowWindow( hwnd,iCmdShow) ' отобразить наше окно на десктопе
UpdateWindow( hwnd) ' обновить клиентскую область

while( GetMessage( @wMsg, NULL, 0, 0 ) <> FALSE )  'цикл сообщений
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
wend
function = wMsg.wParam
end function

Анализ:

hFont = SelectObject(hdc, CreateFont _
(24, _
16, _
0, _
0, _
400, _
0, _
0, _
0, _
OEM_CHARSET, _
OUT_DEFAULT_PRECIS, _
CLIP_DEFAULT_PRECIS, _
DEFAULT_QUALITY, _
DEFAULT_PITCH or FF_SCRIPT, _
"script"))

CreateFont создает логический фонт, который наиболее близок к данным параметрам и доступным данным фонта. Эта функция имеет больше параметров, чем любая другая в Windows. Она возвращает хэндл логического фонта, который можно выбрать функцией SelectObject. Мы в подробностях обсудим ее параметры.

function CreateFont _
(byval nHeight as integer, _
byval nWidth as integer, _
byval nEscapement as integer, _
byval nOrientation as integer, _
byval nWeight as integer, _
byval cItalic as DWORD, _
byval cUnderline as DWORD, _
byval cStrikeOut as DWORD, _
byval cCharSet as DWORD, _
byval cOutputPrecision as DWORD, _
byval cClipPrecision as DWORD, _
byval cQuality as DWORD, _
byval cPitchAndFamily as DWORD, _
byval lpFacename as LPCSTR) as HFONT


• nHeight - желаемая высота символов. Ноль значит использовать размер по умолчанию.
• nWidth - желаемая ширина символов. Обычно этот параметр равен нулю, что позволяет Windows подобрать ширину соответственно высоте. Однако, в нашем примере,
дефаултная ширина делает символы нечитабельными, поэтому я установил ширину равную 16.
• nEscapement - указывает ориентацию вывода следующего символа, относительно предыдущего в десятых градусов. Как правило его устанавливают в 0. Установка
в 900 вынуждает идти все символы снизу вверх, 1800 - справа налево, 2700 - сверху вниз.
• nOrientation - указывает насколько символ должен быть повернут в десятых градусов. 900 - все символы будут "лежать" на спине, и далее по аналогии с предыдущим
параметром.
• nWeight - устанавливает толщину линии. Windows определяет следующие размеры:

• FW_DONTCARE equ 0
• FW_THIN equ 100
• FW_EXTRALIGHT equ 200
• FW_ULTRALIGHT equ 200
• FW_LIGHT equ 300
• FW_NORMAL equ 400
• FW_REGULAR equ 400
• FW_MEDIUM equ 500
• FW_SEMIBOLD equ 600
• FW_DEMIBOLD equ 600
• FW_BOLD equ 700
• FW_EXTRABOLD equ 800
• FW_ULTRABOLD equ 800
• FW_HEAVY equ 900
• FW_BLACK equ 900

• cItalic - 0 для обычных символов, любое другое значение для романских.
• cUnderline - 0 для обычных символов, любое другое значение для подчеркнутых.
• cStrikeOut - 0 для обычных символов, любое другое значение для перечеркнутых.
• cCharSet - символьный набор фонта. Обычно должен быть установлен в OEM_CHARSET, который позволяет Windows выбрать системно-зависимый фонт.
• cOutрutPrecision - указывает насколько близко должен приближаться фонт к характеристикам, которые мы указали. Обычно этот параметр устанавливается в OUT_DEFAULT_PRECIS.
• cClipPrecision определяет, что делать с символами, которые вылезают за пределы отрисовочного региона.
• cQuality - указывает качество вывода, то есть насколько внимательно GDI пытаться подогнать атрибуты логического фонта к атрибутам фонта физического. Есть выбор из трех значений: DEFAULT_QUALITY, PROOF_QUALITY и DRAFT_QUALITY.
• cPitchAndFamily - указывает питч и семейство фонта. Вы должны комбинировать значение питча и семьи с помощью оператора "or".
• lрFacename - указатель на заканчивающуюся NULL'ом строку, определяющую гарнитуру фонта.

Вышеприведенное описание, ни в коем случае, не является исчерпывающим. Вам следует обратиться к вашему Win32 API Справочнику за деталями.

После получения хэндла логического фонта, мы должны выбрать его в контексте устройства, вызвав SelectObject. Функция устанавливает новые GDI объекты, такие как перья, кисти и фонты контекст устройства, используемые GDI функциями. SelectObject возвращает хэндл замещенного объекта.
После вызова SelectObject любая функция вывода текста будет использовать фонт, который мы выбрали в данном контексте устройства.

SetTextColor(hdc, bgr(50, 200, 200))
SetBkColor(hdc, bgr(255, 0, 0))

мы используем макрос BGR, чтобы создать 32-битное RGB значение, которое будет использоваться функциями SetColorText и SetBkColor.

TextOut(hdc,0, 0, @TestString,SIZEOF(TestString))

Вызываем функцию TextOut для отрисовки текста на клиентской области экрана. Будет использоваться ранее выбранные нами фонт и цвет.

описание функции TextOut

function TextOut _
(byval hDc as HDC, _
byval nXStart as integer, _
byval nYStart as integer, _
byval lpString, as LPCSTR, _
byval cbString as integer) as BOOL

hDc- Дескриптор контекста устройства.
nXStart- Устанавливает x-координату, в логических координатах, контрольной точки, которую система использует для выравнивания строки.
nYStart- Устанавливает y-координату, в логических координатах, контрольной точки, которую система использует для выравнивания строки.
lpString- Указатель на строку, которую нужно написать. Строка не должна завершаться нуль-терминатором, так как параметр cbString задает длину строки.
cbString- устанавливает длину строки. Для функции ANSI, это количество BYTE (байтов), а для функции Unicode, это является количеством WORD (слов).

Обратите внимание!, что для функции ANSI, символы в кодовых страницах SBCS (Набора однобайтовых символов) занимают один байт каждый, в то время как большинство символов в кодовых страницах DBCS (Набора двухбайтовых символов) занимают два байта; для функций Unicode большинство текущих заданных символов Unicode (которые в формате Basic Multilingual Plane (BMP) занимают одно слово (WORD), в то время как заменители символа Unicode - два слова (WORD).

SelectObject(hdc, hfont)

После этого мы должны восстановить старый фонт обратно в данном контексте устройства. Вам всегда следует восстанавливать объект, который вы заменили.

[C] Iczelion, пер. Aquila.


Последний раз редактировалось: electrik (Вт Май 23, 2017 5:54 pm), всего редактировалось 1 раз(а)

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: платформа Win32 - Туториалы Iczelion'a на русском, адаптированные для FreeBasic. Урок 5 - Больше о тексте

Сообщение  electrik в Вс Июн 28, 2009 7:58 pm

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

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения