Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка Windows - приложений в среде Borland. Учебное пособие
.pdf
В программе предполагается менять шрифт надписи и кнопки
«восстановить», поэтому вертикальный размер этих элементов уп-
равления должен быть достаточно большим, чтобы поместился и
текст, расположенный под углом к горизонтали. Необходимо также
поменять стиль выравнивания текста, установленный по умолчанию
для этих объектов. Откройте окно свойств элемента «надпись» и на
вкладке “Text”
выберите опцию “Center” (выравнивание по центру):
дополнительно здесь установлен флажок “Border” (рисовать границу
элемента) для большей наглядности. Для кнопки «восстановить»
установите на вкладке “PushButton” режимы выравнивания по центру (“Center”) и верхнему краю (“Top”).
151

В заголовочном файле класса диалога (wrkdlgcl.h) в описание
класса TWorkDlgClient добавьте новое поле – указатель font для
задания нового шрифта и переменную oldfont, в которой будет сохраняться дескриптор первоначального шрифта:
TFont* font;
WPARAM oldfont;
В файле реализации диалога (wrkdlgcl.cpp) добавьте в конст-
руктор класса после комментария // INSERT>> Your constructor code
here строчку:
font = 0;
Для кнопки «сменить» создайте функцию обработчик
тите в нее следующие инструкции:
LOGFONT lf;
memset(&lf,0,sizeof(lf));
lf.lfHeight=16; //высота шрифта
lf.lfItalic=1; //курсив
lf.lfEscapement = -300; //наклон строки в 30 градусов
к горизонтали
lf.lfWeight= FW_BOLD; //полужирный
strcpy(lf.lfFaceName,"Courier New CYR");
delete font;
font = new TFont(&lf); //создаем нужный шрифт
SendDlgItemMessage(IDC_BUTTON2,WM_SETFONT,
(WPARAM) HFONT(*font),TRUE);
SendDlgItemMessage(IDC_STATICTEXT1,WM_SETFONT,
(WPARAM) HFONT(*font),TRUE);
Вначале создается шрифт с желаемыми характеристиками. Создание нового шрифта ранее обсуждалось (см. глава 3, раздел «Вывод
статистических данных. Шрифты. Диаграммы»). Если что-то осталось
непонятным, вернитесь к этому разделу. Далее с помощью метода SendDlgItemMessage класса TWindow посылается сообщение
WM_SETFONT (установить новый шрифт) элементу управления,
152
и помес-

идентификатор которого указывается первым параметром функции
SendDlgItemMessage. В приведенном выше фрагменте кода предполагается, что идентификатор надписи называется
IDC_STATICTEXT1, а идентификатор кнопки «восстановить» –
IDC_BUTTON2. Третий параметр метода – это нужный нам шрифт,
приведенный к типу WPARAM, определенному в Win API [12, 13].
Запустите программу и нажмите кнопку «сменить». Шрифт надписи
“Text1” и кнопки «восстановить» изменится:
Ломать, конечно, не строить, но все-таки, желательно, иногда
уметь восстанавливать «испорченные» надписи. Для этого в файле
заголовка класса диалога (wrkdlgcl.h) в описание класса TWork-
DlgClient добавлена переменная oldfont типа WPARAM (это просто
unsigned int) для указания на первоначально установленный шрифт.
Получить нужное значение не сложно, его возвращает тот же метод
SendDlgItemMessage класса TWindow
WM_GETFONT. Естественно, что этим методом нужно воспользо-
ваться либо до смены шрифта, либо получить нужное значение от
элементов, для которых шрифт не менялся. Можно также воспользоваться функцией SendMessage. Эта функция посылает сообщение
окну. Если мы вызовем ее в классе нашего диалога TWorkDlgClient,
например, перегрузив для этого
шрифт установленный первоначально для всех элементов управления окна диалога.
Вызовите ClassExpert, в панели событий Events раскройте список виртуальных методов → Virtual Functions, выберите функцию
SetupWindow и перегрузите её – контекстное меню → Add handler.
Вспомните, что имя этой функции задавать не нужно – оно предо-
функцию SetupWindow, мы получим
в ответ на сообщение
153

пределено: SetupWindow. В нижней панели ClassExpert появится
заготовка нужного метода:
void TWorkDlgClient::SetupWindow()
{
TDialog::SetupWindow();
// INSERT>> Your code here.
}
После комментария // INSERT>> Your code here введите нужную инструкцию:
oldfont = SendMessage( WM_GETFONT, 0, 0);
затем создайте функцию обработчик для кнопки «восстановить» и
поместите в тело функции строчки:
SendDlgItemMessage( IDC_BUTTON2, WM_SETFONT, oldfont,
TRUE);
SendDlgItemMessage( IDC_STATICTEXT1, WM_SETFONT,
oldfont, TRUE);
Теперь нажатие кнопки «восстановить» вернет первоначально
установленный шрифт надписи “Text1” и кнопки.
Для изменения цвета фона или символов элемента
также можно воспользоваться методом SendDlgItemMessage, послав соответствующее сообщение – например, WM_CTLCOLOR-
STATIC для надписи. Попробуйте сделать это самостоятельно.
Нужную информацию можно найти в файле справки и в папке “Examples” (примеры), имеющейся в комплекте Borland.
Существует и альтернативный способ – перегрузить метод
EvCtlColor класса TWindow. Данная функция вызывается каждый
раз, когда требуется перерисовка.
было так же перегрузить соответствующий метод – EvSetFont. Вызовите ClassExpert, в панели событий Events раскройте список сообщений Windows → Window Messages, далее список основных сообщений → Basic Messages, выберите сообщение WM_CTLCO-
LOR и перегрузите функцию обработчик этого сообщения – контекстное меню → Add handler. Имя этой функции
Кстати, для смены шрифта можно
задавать не нужно –
154
управления

оно предопределено: EvCtlColor. В нижней панели ClassExpert
появится заготовка нужного метода:
HBRUSH TWorkDlgClient::EvCtlColor(HDC dc, HWND
hWndChild, uint ctlType)
{
HBRUSH result;
result = TDialog::EvCtlColor(dc, hWndChild, ctlType);
// INSERT>> Your code here.
return result;
}
Первый параметр данного метода – это дескриптор (указатель
на объект) контекста устройства, второй – дескриптор окна (элемента управления), третий определяет тип элемента управления, для
которого вызвана данная функция. Возвращаемое значение – дескриптор кисти, которой будет нарисован фон элемента. Поместите
перед строчкой return result инструкции:
SetTextColor( dc, RGB(127,0,0)); //красный
SetBkColor( dc, RGB(255,255,255)); //белый
result = CreateHatchBrush(HS_DIAGCROSS,RGB(0,127,0)) ;
//зеленый
Функция SetTextColor задает цвет символов, а SetBkColor –
цвет фона под текстом. Функция CreateHatchBrush создает штриховую кисть и возвращает дескриптор созданной кисти. Стили
штриховки определяются константами HS_BDIAGONAL и HS_FDI-
AGONAL – штриховка по диагонали, HS_CROSS и HS_DIAG-
CROSS прямая и косая решетки, HS_HORIZONTAL – горизонталь-
ная и HS_VERTICAL – вертикальная штриховки
сплошной заливки можно воспользоваться функцией CreateSolid-
Brush, имеющей единственный параметр – цвет заливки.
Цвет задается макросом RGB. Здесь значения всех трех параметров изменяются в диапазоне от 0 до 255 и определяют, соответственно, интенсивность красного, зеленого и синего цвета. RGB(0,0,0)
задаст радикально черный цвет, RGB(255,255,255) соответствует белому цвету.
155
. Для задания

Запустите проект на исполнение. Окно диалога будет заштриховано косой решеткой, а заголовки надписи и рамки будут выведены
красным цветом на белом фоне. Кнопки при этом не изменятся!:
Замените инструкции:
SetTextColor( dc, RGB(127,0,0)); //красный
SetBkColor( dc, RGB(255,255,255)); //белый
result = CreateHatchBrush(HS_DIAGCROSS,RGB(0,127,0));
//зеленый
на:
if( hWndChild == GetDlgItem(IDC_STATICTEXT1)) {
SetTextColor( dc, RGB(127,0,0)); //красный
SetBkColor( dc, RGB(255,255,255)); //белый
result = CreateHatchBrush(HS_DIAGCROSS,RGB(0,127,0));
//зеленый
}
Теперь цвет поменялся только для надписи «Text1». Если вместо условия:
if( hWndChild == GetDlgItem(IDC_STATICTEXT1)) {
написать:
if( ctlType == CTLCOLOR_STATIC) {
156

то поменяются цвет и заливка ВСЕХ элементов управления типа
«надпись».
Таким образом, можно выбрать элементы по дескриптору окна
– параметру hWndChild нашего метода EvCtlColor, сравнивая его с
дескриптором нужного элемента управления, полученным по его
идентификатору GetDlgItem(идентификатор), или выбрать группу
элементов одинакового типа, используя параметр ctlType и константы CTLCOLOR_STATIC (надписи), CTLCOLOR_EDIT (редактируемые поля И ПОЛЯ
TBOX (списки), CTLCOLOR_DLG (окно диалога).
Замечание: Для кнопок всех типов, в том числе переключателей и
флажков, требуется другой подход.
Для изменения размера и положения элементов управления
можно воспользоваться методом MoveWindow класса TWindow:
bool MoveWindow(int x, int y, int w, int h, bool repaint = false);
Параметры x и y задают новые координаты левого верхнего угла
окна (элемента управления), параметры w и h
высоту. Значение последнего параметра, равное true, вызывает немедленную перерисовку.
Поместите в окно диалога новые элементы: надпись “Text2”,
редактируемое поле “Edit1” и кнопку «переместить»:
комбинированных списков), CTLCOLOR_LIS-
его новую ширину и
Присвойте новым элементам имена (ClassExpert → идентифи-
катор элемента управления → контекстное меню для этого идентификатора → Add instance variable). Для надписи задайте имя
Static2, для поля – Edit1, а для кнопки – ButtonMove. Для кнопки
157

«переместить» создайте функцию обработчик (BNClickedMove) и
поместите туда инструкции:
Static2 -> MoveWindow(Static2 -> Attr.X + 10,Static2 ->
Attr.Y+30,
Static2 -> Attr.W+10,Static2 -> Attr.H+50, true);
Edit1 -> MoveWindow(Edit1 -> Attr.X + 10,Edit1 -> Attr.Y+10,
Edit1 -> Attr.W+10,Edit1 -> Attr.H+10, true);
ButtonMove -> MoveWindow(ButtonMove -> Attr.X –
10,ButtonMove -> Attr.Y+30,
ButtonMove -> Attr.W+20,ButtonMove -> Attr.H+20, true);
Здесь считываются исходные значения координаты левого
верхнего угла окна элемента управления, его ширина и высота из
структуры Attr, а затем к исходным значениям добавляется число,
обеспечивающее нужное перемещение и изменение размеров. Запустите программу на исполнение и нажмите кнопку «переместить».
Три новых элемента управления переместятся, и изменится их размер.
Если
требуется обработать все элементы, имеющие имена (то
есть те, для которых созданы объектные переменные – ClassExpert
→ Add instance variable), можно воспользоваться методом ForEach
класса TWindow. Параметром этого метода является имя функции,
которую требуется вызвать для всех объектов, перечисленных в
списке дочерних окон родительского окна. В данном случае – окна
диалога.
В файл реализации диалога (wrkdlgcl.cpp)
до определения
функции BNClickedMove добавьте описание функции MoveAll, которая и будет осуществлять сдвиг элементов:
void MoveAll(TWindow* p, void*) {
p -> MoveWindow(p -> Attr.X + 10,p -> Attr.Y+10,
p -> Attr.W+10,p -> Attr.H+10, true);
}
и замените код метода BNClickedMove на строчку:
ForEach(MoveAll);
Запустите приложение. Положение и размер всех именованных
элементов изменится одинаковым образом.
158

ИНДЕКСАЦИЯ СОСТОЯНИЯ ПРОГРАММЫ. СТРОКА СОСТОЯНИЯ.
УКАЗАТЕЛЬ МЫШИ. ИНДИКАТОР ПРОЦЕССА.
Строка состояния обычно располагается внизу окна и предназначена для отображения информации о состоянии программы и ходе выполнения операций. Строка состояния может быть разбита на
несколько областей для вывода текущих сообщений и отображения
индикаторов состояния (клавиши Caps Lock, Num Lock, Insert и т.п.).
В очередной раз вернитесь к созданной нами в первой главе
базе
данных, предусмотрительно сохраненной в папке «Заготовка». Скопируйте проект в новую папку и загрузите копию. Со строкой состояния мы будем работать, не используя редактора ресурсов, непосредственно редактируя код проекта.
Необходимо отметить, что строка состояния создается как до-
чернее окно главного окна приложения, а не диалога, в отличие
от
ранее рассмотренных элементов управления. Поэтому нам понадобятся глобальные переменные для работы со строкой состояния в
методах класса диалога. Кроме того, нужно добавить несколько заголовочных файлов. Откройте заголовочный файл “workapp.h” и
добавьте в начало файла необходимые инструкции:
#include <owl/statusba.h> //описание класса строк
состояния TStatusBar
#include <owl/timegadg.h> //панель отображения времени,
класс TTimeGadget
#include <owl/modegad.h> //панели индикаторов клавиш,
класс TModeGadget
extern TTextGadget* TextGadget; //панель текстовых со-
общений
extern TStatusBar* StatusBar;
Далее откройте файл “workapp.cpp” и добавьте в начало файла
строчки:
TTextGadget* TextGadget = 0;
TStatusBar* StatusBar=0;
159

Затем найдите в файле “workapp.cpp” определение функции
InitMainWindow и добавьте после, например, установки иконки
приложения:
frame->SetIconSm(this, IDI_SDIAPPLICATION);
инструкции:
TFont* tf=new TFont(12,6);
StatusBar =new TStatusBar(frame, TGadget::WndRecessed, 0, tf);
StatusBar->FirstGadget()->SetShrinkWrap(true, true);
StatusBar->FirstGadget()->SetBorderStyle(TGadget::Grooved);
StatusBar->SetText("Готово...");
Сначала мы определяем новый шрифт, устанавливая размер по
высоте и ширину. Затем создается объект «строка состояния» с помощью конструктора класса TStatusBar. Первый параметр конструктора – указатель на фрейм окна. Второй параметр задает стиль
оформления панелей строки состояния. Допустимы стили – None,
Plain, Raised, Recessed, Embossed, Grooved, ButtonUp, ButtonDn,
Wnd-Raised, WndRecessed и WellSet. В данном случае панели утоп-
ленные – WndRecessed. Третий параметр позволяет
добавить к строке состояния индикатор, например, задав значение, равное TstatusBar::CapsLock. Четвертый параметр – шрифт. В данном случае все
параметры, кроме первого, можно было не указывать, однако шрифт,
устанавливаемый по умолчанию, мне не нравится. Метод First-
Gadget возвращает указатель на первую (и пока единственную) панель строки состояния. Метод SetShrinkWrap устанавливает режим
автоматического
подбора размера панели, метод SetBorderStyle позволяет изменить оформление панели, а метод SetText задать текст
сообщения. Если запустить программу, мы увидим внизу окна строку состояния с нашим сообщением:
160
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
