Перейти на главную страницу
12.01. Вывод текста в окно
12.02. Метрики текста
12.03. Примеры функций для вывода в «рабочую область окна»
12.04. Функция MessageBox
12.05. Резюме функций
12.06. Резюме курса
12.07. Вопросы и упражнения.
12.08. Г Л О С С А Р И Й
12.09. Приложение № I
12.10. Приложение № II
12.11. Приложение № III
12.12. Приложение № IV
12.13. Приложение № V
В Windows и других оболочках с WIMP интерфейсом дела обстоят по-другому. Поскольку в ней работает несколько приложений, то операционная система «следит» за изменением размера и перемещением окон, и при необходимости извещает приложения, что им необходимо перерисовать содержимое окна. Для извещения в очередь приложений записывается сообщение с идентификатором WM_PAINT, о котором было сказано в предыдущих лекциях. Получив такое сообщение, функция окна должна выполнить перерисовку всего окна или его части, в зависимости от дополнительной информации, полученной вместе с сообщением WM_PAINT. Для облегчения работы по отображению содержимого окна весь вывод в окно обычно выполняют в одном месте приложения - при обработке сообщения WM_PAINT в функции окна. Алгоритм приложения должен быть продуман таким образом, чтобы в любой момент времени, после получения сообщения WM_PAINT, функция окна могла бы перерисовать своё окно или её часть, заданную своими координатами. Последнее нетрудно сделать, если приложение где-то в памяти хранит своё текущее состояние, пользуясь которым функция окна может перерисовать своё окно.
Это, в-общем, не означает, что приложение должно хранить в памяти битовый образ окна и восстанавливать его по-необходимости, хотя и это можно сделать. Приложение должно хранить информацию, на основании которой оно может в любой момент времени перерисовать окно. Например, при обработке текстовой информации, приложение Windows должно сохранять промежуточные и окончательные результаты расчётов в оперативной памяти, чтобы оно могло «по требованию», в любой момент времени выдать на экран (или на принтер, другое графическое устройство) промежуточные и окончательные результаты расчётов. Таким образом, программа Windows отличается от консольной программы-фильтра тем, что она хранит и обрабатывает начальные, промежуточные и конечные результаты работы «все сразу», а не считывая данные и осуществляя вывод данных «в процессе их последовательности поступления». Значит, программа Windows, в отличие от консольной программы-фильтра, обладает «памятью прошлых периодов». И эту особенность необходимо активно использовать.
Для вывода текста на экран дисплея в окно приложения используются функции TextOut, DrawText, ExtTextOut и TabbedTextOut. Все эти функции используют контекст отображения, и наследуют из него параметры рисования (атрибуты текста), такие как выравнивание и цвет символов. Эти атрибуты текста задаются функциями SetTextAlign и SetTextColor. Только после вызова этих функция для изменения контекста можно выводить текст в устройство.
Описание функций TextOut, ExtTextOut, DrawText и TabbedTextOut смотри в приложении № I (пункт 12.09) к данной лекции.
Примечание. Кроме выравнивания и цвета текста, в атрибутах контекста можно сменить шрифт, которым будет выводиться текст на устройство. По-умолчанию используется системный шрифт со следующими свойствами: пропорциональный, без засечек, растровый (не масштабируемый), кегль 10. Этот шрифт устанавливается на панели управления операционной системы. Кроме того, шрифт можно изменить программно. Но это выходит за рамки рассмотрения данного курса.
Однако прежде чем использовать эти функции, Вы должны инициализировать метрики шрифтов, хранящиеся в глобальных переменных и используемые в указанных выше функциях. Это можно сделать при помощи фрагмента кода, представленного в приложении № II (пункт 12.10) к данной лекции.
Функция MessageBox является порождением от так называемых диалоговых панелей («окон диалога»), вызываемых приложениями Windows и служащих для «упорядоченного ввода-вывода» с использованием «ресурсов приложений». В принципе, на таких языках, как Delphi, Visual Basic и др., программирование с использованием диалоговых панелей является основным и даже единственным способом создания диалоговых программ. Особенностью окон диалога является:
Что касается функции MessageBox, то её назначение - это информирование пользователя о каких либо событиях и «нештатных ситуаций» при работе с программой. Её следует использовать:
Описание параметров функции MessageBox смотри в приложении № III (пункт 12.11) к данной лекции.
При написании данного курса автор не скрывал, что его лекции направлены, прежде всего, для написания программ текстовых фильтров и вьюеров. Со своей задачей автор справился. Теперь студенты, с помощью имеющихся знаний, могут писать любые текстовые фильтры и вьюеры для операционных систем MS-DOS, Windows и Linux.
Ограничением данных программ является возможность их запуска только из командной строки. Однако никто не мешает сделать над этими командами «надстройку с графическим интерфейсом» (в терминологии Linux — «Front End»). Эта задача является более лёгкой, чем программирование фильтров, и с ними обязан справиться любой системный программист.
+2. В MD-DOS все ресурсы системы передаются программе в «монопольный доступ»;
+3. В MS-DOS можно было выводить текст в любой позиции экрана;
4. Программы в Windows смотрятся привлекательней тех же программ в MS-DOS;
2. При обработке прерывания WM_CREATE;
3. Сразу после открытия и чтения текстового файла;
4. В любом месте программы;
+2. В приложении Windows в процессе работы создаются, аккумулируются и сохраняются данные и алгоритмы, с помощью которых можно всегда заново сформировать изображение для любого устройства;
3. Приложения Microsoft Windows сами генерируют изображения для любого графического устройства вывода;
2. ExtTextOut;
3. DrawText;
+4. TabbedTextOut;
5. SetTextAlign;
6. SetTextColor;
+2. ExtTextOut;
+3. DrawText;
4. TabbedTextOut;
5. SetTextAlign;
6. SetTextColor;
2. ExtTextOut;
+3. DrawText;
4. TabbedTextOut;
+5. SetTextAlign;
+6. SetTextColor;
2. ExtTextOut;
3. DrawText;
4. TabbedTextOut;
+5. SetTextAlign;
+6. SetTextColor;
+2. Выравнивание текста;
3. Системный шрифт;
4. Начертание текста текущей гарнитуры;
+5. Цвет литер;
2. ExtTextOut;
3. DrawText;
+4. TabbedTextOut;
5. SetTextAlign;
6. SetTextColor;
2. tm.tmHeight;
3. tm.tmHeight+tm.tmExternalLeading;
2. tm.tmHeight;
+3. tm.tmHeight+tm.tmExternalLeading;
+2. Для вывода предупреждающих сообщений;
+3. Для создания «заглушек»;
+4. Для вывода отладочных сообщений;
+2. Модальным окном;
3. Перекрывающимся окном;
+4. Дочерним окном приложения;
+2. Модальное окно расположено поверх родительского окна;
+3. Модальное окно имеет «родителя»;
+4. С приложением нельзя работать, если модальное окно не будет закрыто;
5. Модальное окно перенаправляет на себя фокус ввода системы;
+2. Две;
4. Четыре;
5. Много;
.2. Пропорциональный, без засечек, кегль 10, обычное начертание, масштабируемый;
3. Пропорциональный, с засечками, кегль 10, обычное начертание, растровый;
4. Моноширинный, с засечками, кегль 10, обычное начертание, масштабируемый;
+2. Векторные шрифты;
+3. Масштабируемые шрифты True Type Fonts;
+4. Шрифты Adobe Type I;
+5. Шрифты OpenType;
+2. SetScrollRange;
3. GetScrollRange;
ОПРЕДЕЛЕНА В:
СИНТАКСИС: BOOL TextOut( hdc, nxStart, nYStart, lpszString, UINT cbString);
где
ОПИСАНИЕ: Функция выводит текст в окно с параметрами контекста, заданными по-умолчанию или изменённые в процессе обработки сообщения WM_PAINT. По-умолчанию шаг координат в окне — один пиксель, начало координат находится в левом верхнем углу рабочей области окна, ось X направлена влево, а ось Y — вниз;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: TRUE — при удачном выводе текста и FALSE в случае неудачи;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ EXTTEXTOUT
ОПРЕДЕЛЕНА В:
СИНТАКСИС: BOOL WINAPI ExtTextOut( hdc, nxStart, nYStart, fuOptions, lprc, lpszString, cbString, lpDx );
где
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: TRUE — при удачном выводе текста и FALSE в случае неудачи;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
Примечание: Флаги в параметре функции fuOptions могут принимать следующие значения:
ОПРЕДЕЛЕНА В:
СИНТАКСИС: LONG WINAPI TabbedTextOut( hdc, nXStart, nYStart, lpszString, cbString, cTabStops, lpnTabPositions, nTabOrigin );
где
ОПИСАНИЕ: Эту функцию удобно использовать для вывода текстовых таблиц;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Функция возвращает размер (в логических единицах) области, занятой выведённой строкой. Старшее слово возвращаемого значения содержит высоту строки, младшее — ширину строки;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ DRAWTEXT
ОПРЕДЕЛЕНА В:
СИНТАКСИС: int WINAPI DrawText( hdc, lpszString, cbString, lprc, fuFormat );
где
ОПИСАНИЕ: Если перед выводом функции Вы включили режим обновления текущей позиции вывода (вызвав функцию SetTextAlign с параметром: TA_UPDATECP), то текст будет выведен начиная с текущей позиции вывода, которая устанавливается за последним выведенным ранее символом. Перенос слов при этом не выполняется;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: В случае успешного завершения функция возвращает высоту прямоугольной области, использованной для вывода текста;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ SETTEXTALIGN
ОПРЕДЕЛЕНА В:
СИНТАКСИС: UINT WINAPI SetTextAlign( hdc, fuAlign );
где
ОПИСАНИЕ: Первый набор флагов используется при выравнивании воображаемого прямоугольника, ограничивающего текст, по горизонтали относительно указанных выше функций. Второй набор флагов отвечает за выравнивание текста по вертикали. И, наконец, третья группа флагов отвечает за обновление текущей позиции вывода в строке. Если указан флаг: TA_UPDATECP, то вывод текста продолжится с прежней позиции вывода, а координаты: nXStart и nYStart в функциях вывода текста игнорируются;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Прежнее значение параметров выравнивания и переноса текста;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ GETTEXTALIGN
ОПРЕДЕЛЕНА В:
СИНТАКСИС: UINT WINAPI GetTextAlign( hdc )
где
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Текущее значение параметров выравнивания и переноса текста;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ SETTEXTCOLOR
ОПРЕДЕЛЕНА В:
СИНТАКСИС: COLORREF WINAPI SetTextColor( hdc, clrref );
где
ОПИСАНИЕ: функция изменяет в контексте текущего устройства вывода Windows hdc цвет выводимых на экран (устройство) символов при помощи функций текстового вывода;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Прежнее значение цвета текста в контексте вывода;
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ GETTEXTCOLOR
ОПРЕДЕЛЕНА В:
СИНТАКСИС: COLORREF WINAPI GetTextColor( hdc );
где
ОПИСАНИЕ: функция выводит в контексте текущего устройства вывода Windows hdc цвет выводимых на устройство символов при помощи функций текстового вывода;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Текущее значение цвета текста в контексте вывода, в виде структуры: COLORREF (смотри приложение №I к лекции 11, пункт 11.05);
ПЕРЕНОСИМОСТЬ: Только WinAPI;
ФУНКЦИЯ GETTEXTEXTENT
ОПРЕДЕЛЕНА В:
СИНТАКСИС: DWORD GetTextExtent( hdc, lpszString, cbString );
где
ОПИСАНИЕ: Функция выдаёт значения в единицах логических координат области вывода. Для вывода текста в стандартной системе координат рабочей области окна единицей логических координат принят один пиксель. Ширина строки расчитывается как сумма ширины и интервалов всех литер, входящих в текст. Это справедливо не для всех устройств, поэтому на них функция возвращает неверные значения.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Двойное слово, в котором младшее слово содержит значение ширины строки текста (в логических единицах), а старшее слово — высоту строки в логических единицах. В случае неудачи или ошибки функция возвращает нулевое значение;
ПЕРЕНОСИМОСТЬ: Только WinApi;
В Windows, кроме того, все шрифты можно разделить по технологии изготовления на «растровые», «контурные» («векторные») и масштабируемые (изготовленные с помощью разных технологий, например: True Type Fonts, Open Type Fonts, Adobe Type I). Растровые шрифты состоят из отдельных пикселей, и используются при выводе текста на экран монитора или на принтер. Для обеспечения приемлемого качества текста в Windows имеется набор растровых шрифтов с одной гарнитурой, но разным кеглем. Если попытаться выполнить масштабирование растрового шрифта в сторону увеличения размера литер, наклонные линии и закругления будут изображаться в виде «лестницы».
Контурные шрифты больше подходят для плоттеров. При масштабировании таких шрифтов можно достичь лучших результатов, чем при масштабировании растровых шрифтов. Однако при этом трудно регулировать толщину штрихов шрифта.
Масштабируемые шрифты сохраняют начертание символов при любом изменении размеров, поэтому они чаще используются при подготовке документов. Однако, как правило, эти шрифты нельзя использовать при рисовании символов на плоттере и в качестве шрифтов элементов оформления (меню, диалоговых панелей и т.п.).
В примерах данного курса мы будем использовать так называемый системный шрифт, используемый как шрифт по-умолчанию для операционных систем Microsoft Windows. Обозначается он как SYSTEM_FONT. Системный шрифт относят к растровым шрифтам с рубленной пропорциональной гарнитурой. По-умолчанию это гарнитура MS Sans Serif.
Переменная ширина букв усложняет задачу вывода текста, так как длина текстовой строки зависит не только от количества букв в строке, но и от того, из каких литер состоит строка. Для подсчёта длины текстовой строки в пикселях предназначена функция GetTextExtent, описанная в Приложении № I(пункт 12.09) к данной лекции.
Для получения информации о шрифте, выбранном в контекст устройства, предназначена функция GetTextMetrics. Её описание смотри ниже.
ФУНКЦИЯ GETTEXTMETRICS
ОПРЕДЕЛЕНА В:
СИНТАКСИС: BOOL WINAPI GetTextMetrics( hdc, lptm )
где
ОПИСАНИЕ:
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: TRUE в случае успешного завершения, и FALSE в противном случае;
ПЕРЕНОСИМОСТЬ: Только Windows;
Структура TEXTMETRIC описана в файле windows.h следующим образом:
typedef struct tagTEXTMETRIC
{
int tmHeight;
int tmDescent;
int tmInternalLeading;
int tmExternalLeading;
int tmAveCharWidth;
int tmMaxCharWidth;
int tmWeight;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmFirstChar;
BYTE tmLastChar;
BYTE tmDefaultChar;
BYTE tmBreakChar;
BYTE PitchAndFamily;
BYTE tmCharSet;
int tmOverhang;
int tmDigitizedAspectX;
int tmDigitizedAspectY;
} TEXTMETRIC;
Описание этих полей смотрите в таблице 12.III.
Хорошо спроектированные приложения позволяют Вам выбирать для отображения текста произвольные шрифты. Поэтому приложение никогда не должно ориентироваться на конкретные размеры шрифта, а должно определять параметры шрифта динамически, во время выполнения программы, используя функцию GetTextMetrics.
Пример функций для определения параметров шрифта по-умолчанию и вывода текста с указанными метриками приведён ниже. Следует отметить, что эти функции используют глобальные переменные nXChar, nYChar, nXCurrentPosition, nYCurrentPosition, ps, tm, nMaxNumLines, nMaxLenngthLines, nScrollPos и др.
Примечание: в данных примерах используется вертикальная полоса прокрутки окна. Более подробно о полосах прокрутки смотри в приложении № IV к данной лекции.
ОПРЕДЕЛЕНА В:
СИНТАКСИС: int WINAPI MessageBox( hwndParent, lpszText, lpszTitle, fuStyle )
где
ОПИСАНИЕ: Функция MessageBox создаёт на экране диалоговую панель с текстом, заданным параметром: lpszText и заголовком, заданным параметром lpszTitle. Если заголовок указан как NULL, используется заголовок по умолчанию — строка «Error». Параметр hwndParent указывает идентификатор родительского окна, создающего диалоговую панель. Этот параметр можно указать как NULL, тогда у диалоговой панели не будет рабочего окна. Вы также можете вызвать функцию из MessageBox из функции диалога, в этом случае этот параметр должен содержать идентификатор окна диалоговой панели.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Одна из следующих констант, определённых в таблице № 12.V;
ПЕРЕНОСИМОСТЬ: Только Windows.
Второй способ создания полос чрезвычайно прост, но с его помощью можно создать только одну горизонтальную и одну вертикальную полосы прокрутки, расположенные по краям окна. Для того чтобы эта полосы прокрутки появились в окне, при регистрации класса окна в третьем параметре функции CreateWindow необходимо указать стиль окна WS_VSCROLL, или WS_HSCROLL, или оба стиля вместе.
// Стиль окна
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, hInstance, NULL );
Сообщения от полосы прокрутки рассматриваются в таблице 12.VI.
После того, как Вы создали полосу прокрутки, её необходимо проинициализировать, указав диапазон изменений значений позиции. Для этого необходимо вызвать функцию: SetScrollRange, описанную ниже:
ФУНКЦИЯ SETSCROLLRANGE
ОПРЕДЕЛЕНА В:
СИНТАКСИС: void WINAPI SetScrollRange( hwnd, fnBar, nMin, nMax, fRedraw )
где
ОПИСАНИЕ:
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Функция не возвращает значений;
ПЕРЕНОСИМОСТЬ: Только Windows;
Всегда можно узнать диапазон для полосы просмотра, вызвав функцию GetScrollRange:
ФУНКЦИЯ GETSCROLLRANGE
ОПРЕДЕЛЕНА В:
СИНТАКСИС: void WINAPI SetScrollRange( hwnd, fnBar, lpnMin, lpnMax )
где
ОПИСАНИЕ:
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Функция не возвращает значений;
ПЕРЕНОСИМОСТЬ: Только Windows;
Другие функции, управляющие режимом отображения полос прокрутки, смотри в книге [39].
Данная программа оптимизирована под среду разработки Borland C/C++ 3.1.
/* Файл TEXTOUTS.H с объявлениями функций и переменных*/
#ifndef MAXTEXTBUFFSIZE
#define MAXTEXTBUFFSIZE 80 // Максимальная ширина строки в символах
#endif
#define MAXTEXTSTRINGS 24 // Максимальное число строк в окне
#endif */
#ifndef __WINDOWS_H
#include
#endif
#define __TEXTOUTS_H
// Методы
// "Удержание" позиции прокрутки в "правильных" границах
void vnormalize( void );
void WINAPI setVScrollPos( int ); // Установка текущей позиции скроллинга
int WINAPI getVScrollPos(); // Выдача текущей позиции скроллинга
void WINAPI setMaxVScrol( int ); // Установка максимального количества строк
int WINAPI getMaxVScroll(); // Выдача максимального количества строк
void WINAPI TextMetricsInit( HDC ); // Установка параметров шрифтов
void WINAPI vPageUp( int ); // Перемещение рабочей области окна на экран вверх
void WINAPI vPageDown( int ); // Перемещение рабочей области окна на экран вниз
void WINAPI PrintHDC_scroll( HDC, const char * ); // Печать строки без переноса на новую строку
void WINAPI PrintLnHDC_scroll( HDC, const char * ); // Печать строки с переносом на новую строку
void WINAPI PrintInitHDC_scroll( void ); // Данная функция инициализирует позиции вывода текста при обработке прерывания WM_PAINT
#endif
// ------------------------------------
// Вывод текста в рабочую область окна
// с вертикальной полосой прокрутки
// ----------------------------------------
#define STRICT
#include
#include
BOOL InitApp(HINSTANCE);
LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);
char const szClassName[] = "ViewerAppClass";
char const szWindowTitle[] = "Viewer0000 Application";
// =====================================
// Функция WinMain
// =====================================
#pragma argsused
int PASCAL
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
MSG msg; // структура для работы с сообщениями
if(!InitApp(hInstance))
return FALSE;
hwnd = CreateWindow(
szClassName, // имя класса окна
szWindowTitle, // заголовок окна
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // стиль окна
CW_USEDEFAULT, // задаем размеры и расположение
CW_USEDEFAULT, // окна, принятые по умолчанию
CW_USEDEFAULT,
CW_USEDEFAULT,
0, // идентификатор родительского окна
0, // идентификатор меню
hInstance, // идентификатор приложени
NULL); // указатель на дополнительные
// параметры
if(!hwnd)
return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg;, 0, 0, 0))
{
DispatchMessage(&msg;);
return msg.wParam;
}
// =====================================
// =====================================
BOOL
InitApp(HINSTANCE hInstance)
ATOM aWndClass; // атом для кода возврата
WNDCLASS wc; // структура для регистрации
// класса окна
memset(&wc;, 0, sizeof(wc));
// Определяем стиль класса окна, при
// использовании которого окно требует
// перерисовки в том случае, если
// изменилась его ширина или высота
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = (LPSTR)NULL;
wc.lpszClassName = (LPSTR)szClassName;
aWndClass = RegisterClass(&wc;);
return (aWndClass != 0);
}
/* Файл WINPROC.CPP с примерами функций */
// Функция WndProc
// =====================================
#define STRICT
#include
#include
#include
#include
#include "textouts.h"
#define MAXTEXTSTRINGS 20 // Переопределённое значение высоты экрана в строках
// Переменные
static int nVScrollPos; // Текущая позиция вертикальной полосы прокрутки
static int nMaxVScrolled; // Максимальное значение позиции
static int nxCurPos; // Текущая горизонтальная позиция вывода в окне
static int nyCurPos; // Текущая вертикальная позиция вывода в окне
static int cxChar; // Ширина символов
static int cyChar; // Высота строки с символами
static char otladka[80]; // Данные для отладки
LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static WORD cxClient, cyClient;
PAINTSTRUCT ps; // структура для рисовани
TEXTMETRIC tm; // Структура для записи метрик шрифта
switch (msg)
{
case WM_CREATE:
// Получаем контекст отображения,
// необходимый для определения метрик шрифта
hdc = GetDC(hwnd);
// Заполняем структуру информацией
// о метрике шрифта, выбранного в
// контекст отображени
GetTextMetrics( hdc, &tm; );
// Запоминаем значение ширины для самого широкого символа
cxChar = tm.tmMaxCharWidth;
// Запоминаем значение высоты букв с учётом междустрочного интервала
cyChar = tm.tmHeight + tm.tmExternalLeading;
// Инициализируем текущую позицию вывода текста
nxCurPos = cxChar/2; // Текущая горизонтальная позиция вывода в окне
nyCurPos = 0; // Текущая вертикальная позиция вывода в окне
// Задаём начальное значение позиции
nVScrollPos = 0;
nMaxVScrolled = MAXTEXTSTRINGS;
// Освобождаем контекст
ReleaseDC(hwnd, hdc);
// Задаем диапазон изменения значений
SetScrollRange(hwnd, SB_VERT, 0, nMaxVScrolled, FALSE);
// Устанавливаем ползунок в начальную позицию
SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE);
return 0;
}
// Определяем размеры внутренней области окна
{
cxClient = LOWORD(lParam);
return 0;
}
// Сообщение от вертикальной полосы просмотра
{
switch(wParam)
case SB_TOP:
{
nVScrollPos = 0;
}
case SB_BOTTOM:
nVScrollPos = nMaxVScrolled;
break;
}
case SB_LINEUP:
nVScrollPos -= 1;
break;
}
case SB_LINEDOWN:
nVScrollPos += 1;
break;
}
case SB_PAGEUP:
nVScrollPos -= cyClient / cyChar;
break;
}
case SB_PAGEDOWN:
nVScrollPos += cyClient / cyChar;
break;
}
case SB_THUMBPOSITION:
nVScrollPos = LOWORD(lParam);
break;
}
// Блокируем для того чтобы избежать
// перемещении ползунка
case SB_THUMBTRACK:
{
return 0;
default:
}
// Ограничиваем диапазон изменения значений
// Устанавливаем ползунок в новое положение
SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE);
// Обновляем окно
InvalidateRect(hwnd, NULL, TRUE);
return 0;
}
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps;);
/* Эти операторы используется для тестировани
sprintf( otladka, "nVScrollPos = %d\n", nVScrollPos );
MessageBox( hwnd, otladka, NULL, MB_OK ); */
// Инициализируем позицию вывода текста
PrintInitHDC_scroll();
// Выводим текст
PrintLnHDC_scroll(hdc, "Это первая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "Это следующая строка");
PrintLnHDC_scroll(hdc, "А это последняя строка");
EndPaint(hwnd, &ps;);
return 0;
}
// Обеспечиваем управление полосой просмотра
case WM_KEYDOWN:
{
// В зависимости от кода клавиши функция окна
// обычно генерируются полосой просмотра
switch (wParam)
{
case VK_HOME:
SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0L);
break;
}
case VK_END:
SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0L);
break;
}
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0L);
break;
}
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0L);
break;
}
case VK_PRIOR:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0L);
break;
}
case VK_NEXT:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
break;
}
}
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
}
}
// "Удержание" позиции прокрутки в "правильных" границах
{
if(nVScrollPos < 0) nVScrollPos = 0;
return;
void WINAPI PrintHDC_scroll( HDC hdc, const char *str )
{
char buf[MAXTEXTBUFFSIZE];
int i, y;
// Обрезание входной строки при превышении её длины.
// Это нужно, чтобы не было ошибки "переполнение буфера"
memset( temp, '\0', MAXTEXTBUFFSIZE );
strncpy( temp, str, MAXTEXTBUFFSIZE );
// Вычисляем начальную позицию для вывода
y = nyCurPos + cyChar * (- nVScrollPos);
// Подготавливаем в рабочем буфере
// и выводим в окно, начиная с текущей
// позиции название параметра
sprintf(buf, "%s", temp);
i = strlen(temp);
TextOut(hdc,
nxCurPos, y, buf, i);
// Увеличиваем текущую позицию по
// горизонтали на ширину символа
nxCurPos += cxChar*i;
return;
}
void WINAPI PrintLnHDC_scroll( HDC hdc, const char *str )
char buf[MAXTEXTBUFFSIZE], temp[MAXTEXTBUFFSIZE];
int i, y;
// Обрезание входной строки при превышении её длины.
// Это нужно, чтобы не было ошибки "переполнение буфера"
memset( temp, '\0', MAXTEXTBUFFSIZE );
strncpy( temp, str, MAXTEXTBUFFSIZE );
// Вычисляем начальную позицию для вывода
y = nyCurPos + cyChar * (- nVScrollPos);
// Подготавливаем в рабочем буфере
// и выводим в окно, начиная с текущей
// позиции название параметра
sprintf(buf, "%s", temp);
i = strlen(temp);
TextOut(hdc,
nxCurPos, y, buf, i);
// Увеличиваем текущую позицию по
// вертикали на высоту символа
// и переносим начало вывода на новую строку
nyCurPos += cyChar;
nxCurPos = cxChar/2;
return;
void WINAPI PrintInitHDC_scroll( )
{
/* Данная функция инициализирует позиции вывода текста при
текста */
nyCurPos = 0; // Начальная позиция вывода в окно 0
nxCurPos = cxChar / 2; // Начальная горизонтальная позиция -- половина от ширины символа
return;
}
/* Файл описания модулей VIEW0000.DEF */
; Файл определения модуля VIEW0000
; =====================================
NAME VIEW0000
DESCRIPTION 'Приложение VIEW0000, (C) 2010, yudenisov'
EXETYPE windows
STUB 'winstub.exe'
STACKSIZE 5120
HEAPSIZE 4096
CODE preload moveable discardable
DATA preload moveable multiple
Затем идут собственно функции вывода текста в окно PrintHDC_scroll и PrintLnHDC_scroll.
Первая из этих функций выводит текст в окно без перехода на другую строку. Новый вывод будет производиться в той же строке, начальная позиция которой будет равна «числу напечатанных символов» * «максимальную ширину литера шрифта». В Бейсике это эквивалентно командам:
TAB(«позиция»); PRINT «строка»;
На данной лекции описываются «собственно» функции вывода текста в окно приложения или во всплывающее окно. Также даётся представление о метриках текста и правилах их использования
18 12 2014
1 стр.
Ii. Семантическое устройство текста романа В. Пелевина «Generation П»
01 10 2014
1 стр.
18 12 2014
1 стр.
В этом материале будет рассмотрен действие установки всех драйверов в примере Windows xp. На Windows Vista, Windows 7 он происходит абсолютно аналогично
16 12 2014
1 стр.
Внимание! Данная установка возможна только на операционных системах Windows 2000, Windows xp, Windows 2003 Server
05 09 2014
1 стр.
Сменить пароль доменного пользователя можно только на компьютере, входящем в домен
25 09 2014
1 стр.
Добро дошли у српски интерфејс пакет за Microsoft(Р) Windows xp professional са Сервисним пакетом Овај документ пружа најновије или друге информације као допуну документације која
10 09 2014
1 стр.
Если у Вас на экране виден мусор вместо текста установите в “панели управления” ms-windows русские шрифты!
15 09 2014
8 стр.