Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка Windows - приложений в среде Borland. Учебное пособие
.pdf
сив. Откройте модуль workapp.h и поместите объявление нужного
массива filter:
staff filter[100];
Нам потребуется определение условия равенства двух записей –
объектов класса staff. Добавьте в описание структуры staff объявление дружественной функции, перегружающей операцию «равно»
для нашего типа данных:
friend bool operator == (const staff& sl,const staff& sr);
Кроме того, необходимо добавить следующие инструкции:
#include <algorith.h>
using namespace std;
В заголовочном файле algorith.h описаны алгоритмы библиоте-
STL, в частности нужные нам алгоритмы типа remove. Найдите
ки
на вкладке “Common” панели инструментов элемент управления
«просмотр списка» (List View) и поместите его внизу окна диалога.
Назовите соответствующий объект, принадлежащий классу TList-
Window – browser (ClassExpert → Add instance variable → browser).
Вызовите окно свойств элемента List View, выберите вкладку ListView и режим отображения в виде таблицы – опция
Убедитесь, что записи не будут автоматически упорядочены – опция
None в группе Sort Type. Если хотите, чтобы выделение выбранных
в окне записей сохранялось при потере элементом фокуса, поставьте
флажок Show Sel Always.
Создайте столбцы (колонки) таблицы. Для этого перегрузите
функцию SetupWindow класса диалога TWorkDlgClient и добавьте в
созданную ClassExpert заготовку нужного метода строчки:
TListWindColumn column1("имя", 70, TListWindColumn::Left, 0);
browser->InsertColumn(0, column1);
TListWindColumn column2("должность", 70, TlistWindColumn::Left, 1);
browser->InsertColumn(1, column2);
Report View.
181

TListWindColumn column3("оклад", 70, TListWindColumn::Left, 2);
browser->InsertColumn(2, column3);
browser->MoveWindow(browser->Attr.X, browser->Attr.Y,
214, browser->Attr.H, true);
Добавьте в диалог командную кнопку «Фильтр», создайте
функцию-обработчик нажатия на эту кнопку, и поместите в эту
функцию инструкции:
if( !iMax){
MessageBox("База пуста", "Просмотр", MB_OK |
MB_ICONSTOP);
return;
}
browser->DeleteAllItems();
staff st, *is;
char buff1[20];
EditName->GetText(buff1, 20);
strcpy(st.name, buff1);
EditJob->GetText(buff1, 20);
strcpy(st.job, buff1);
EditPay->GetText(buff1, 20);
st.pay=atoi(buff1);
is=remove_copy_if(crew,crew + iMax,filter, bind2nd (not_equal_to
<staff>(), st));
wsprintf(buff1, "отобрано\nзаписей = %i", is-filter);
MessageBox(buff1, "Фильтрация");
char buff[3][20];
for(int i=0; i<is-filter; i++){
wsprintf(buff[0], "%s", filter[i].name);
wsprintf(buff[1], "%s", filter[i].job);
wsprintf(buff[2], "%i", filter[i].pay);
TListWindItem item;
item.mask=LVIF_TEXT;
item.SetIndex(i);
browser->InsertItem(item);
for(int column=0; column<3; column++) {
item.SetSubItem(column);
182

item.SetText(buff[column]);
browser->SetItem(item);
}
}
browser->EnsureVisible(0, false); //видна первая запись
В приведенном фрагменте кода, после проверки, не является ли
база данных пустой, все записи из элемента «просмотр списка» удаляются с помощью метода DeleteAllItems. Затем создается образец
st для сравнения записей. Искомые значения имени, должности и
оклада берутся из соответствующих полей диалога. Далее, с помощью алгоритма remove_copy_if нужные записи копируются в начало массива filter. Алгоритм возвращает указатель is на первый элемент в массиве filter, не отвечающий заданному условию равенства
записей. Первые два параметра алгоритма задают диапазон просматриваемых записей, третий параметр – адрес начала записей в
массиве filter. Алгоритм remove_copy_if копирует все элементы
массива crew из
раметр определяет те элементы, которые должны быть «удалены».
На самом деле проводится не удаление, а перемещение в начало
массива filter элементов, не соответствующих четвертому параметру. Следовательно, четвертый параметр должен определять все ненужные записи. Предикат not_equal_to строит на основе опреде-
ленного нами оператора «
шаблона библиотеки STL. Адаптер bind2nd задает второй параметр
перегруженного оператора «равно», равным значению образца st.
Таким образом, все записи, отвечающие заданному значению st,
оказываются в начале массива filter. Разница между значением указателя is и адресом начала массива filter равна количеству отобранных записей.
После фильтрации все найденные записи
сиве filter, отображаются в элементе «просмотр списка». Процедура
добавления записей в список практически не отличается от аналогичной процедуры, рассмотренной в первом проекте данного раздела.
Осталось добавить в конец модуля класса диалога wrkdlgcl.cpp
описание операции «равно» для типа данных staff. Для начала определим равенство двух объектов по значению
заданного диапазона в массив filter. Четвертый па-
равно» условие неравенства с помощью
, содержащиеся в мас-
должности:
183

bool operator == (const staff& sl,const staff& sr){
return !strcmp(sl.job, sr.job);
}
Заметьте, что поскольку заданная нами операция равенства двух
записей сравнивает только должности, значения искомого имени и
оклада не нужны и их можно было в образце st не задавать. Запустите программу и заполните базу данных так, чтобы часть сотрудников
имела одинаковые должности. Введите в редактируемое поле «должность» искомое значение
будет отображена информация только на сотрудников, занимающих
указанную должность. Имя и оклад сотрудника будут игнорироваться:
и нажмите кнопку «Фильтр». В списке
Замените в условии равенства двух записей строчку:
return !strcmp(sl.job, sr.job);
на инструкцию:
return !strcmp(sl.job,sr.job) || sr.job[0] == '\0';
теперь если поле должность пустое, будут отображены все имеющиеся записи:
184

Можно при фильтрации искать должности, частично совпа-
дающие с заданным образцом, как это делалось в предыдущем проекте, можно фильтровать по именам и окладам. Также можно построить и расширенный фильтр, учитывающий комбинацию условий по разным полям базы данных. Для этого достаточно изменить
условия, заданные в перегруженном операторе «равно
». Возможные
способы реализации таких условий рассматривались ранее в разделе
«Алгоритмы. Сортировка и поиск» второй главы.
ЛЕМЕНТЫ ВКЛАДКИ COMMON – СЧЕТЧИК, ПОЛЗУНОК, ВКЛАДКИ
Э
В предыдущих разделах этой главы обсуждались способы работы с такими элементами управления, как «просмотр списка», «индикатор процесса» и строка «состояния», расположенными на панели
инструментов Common. Рассмотрим эту вкладку подробнее:
185

Итак, на вкладке панели инструментов Common находятся следующие элементы управления:
- Animation (анимация) – предназначен для проигрывания файлов
типа *.avi.
- Tab Control – вкладки (ярлыки) – будет обсуждаться в этом раз-
деле.
- Tree View (просмотр дерева) – предназначен для отображения дан-
ных, организованных в структуры типа «дерева» – каталоги и т.п.
- List View (просмотр списка
виде значков или таблицы – рассматривался нами ранее.
- Hot Key (горячие клавиши) – для установки комбинаций «горя-
чих» клавиш пользователем во время работы приложения.
- Progress Bar (индикатор процесса) – используется для визуализа-
ции длительных операций: загрузка, форматирование и т.п – рассматривался нами ранее.
- Up-Down (счетчик, стрелки) –
вого значения, связанного с элементом поля – будет обсуждаться в
этом разделе.
- Track Bar (ползунок) – для установки числовых значений в задан-
ном диапазоне – будет обсуждаться в этом разделе.
- Header (заголовки) – для оформления элементов, организованных
в столбцы.
- Rich Text Edit (форматированный текст) – для текста в формате
RTF.
- Status Window (
- Tool Bar (панель инструментов).
Некоторые из этих элементов обсуждались в предыдущих разделах, здесь мы рассмотрим способы работы с вкладками, счетчиком
и ползунком. Создайте новый проект – Work на основе диалога.
Поместите в диалоговое окно элемент Tab Control (вкладка), растяните по размеру окна, оставив внизу место для
cel”. Кнопки не должны перекрываться элементом «вкладка». Создайте программный объект «вкладка» и назовите его TabCtrl: Class
Expert → Add instance variable. На левой половине элемента Tab
Control в окне диалога поместите редактируемое поле, вплотную
справа элемент Up-Down (счетчик), снизу – кнопку. Создайте соответствующие объекты (Class Expert → Add instance variable) – edit1,
updown1 и button1. В правой половине вкладки поместите
руемое поле, под ним элемент Track Bar (ползунок), еще ниже –
строка состояния) – рассматривался нами ранее.
) – предназначен для вывода данных в
предназначен для изменения число-
кнопок “OK” и “Can-
редакти-
186

кнопку. Создайте соответствующие объекты – edit2, slider1 и
button2:
Перегрузите функцию диалога SetupWindow (Class Expert →
Virtual Function → Add handler). Добавьте в созданную Class Expert
заготовку инструкции:
TabCtrl->Add("первая");
TabCtrl->Add("вторая");
TabCtrl->SetSel(0);
TCNSelchangeTabCtrl(TNotify());
Метод Add класса TTabControl создает вкладку с указанным
заголовком, каждая вкладка может быть опознана по индексу, индексация начинается с нуля, то есть вкладка с заголовком «первая»
имеет нулевой индекс. Метод SetSel класса TTabControl делает
тивной первую вкладку, затем вызывается еще не созданная нами
функция TCNSelchangeTabCtrl, задача которой – сделать видимыми только элементы активной вкладки. Мы будем считать, что элементы, расположенные слева, принадлежат первой вкладке (с индексом ноль). Соответственно элементы, расположенные справа,
будут принадлежать второй вкладке. Параметр функции TCNSelchangeTabCtrl обязателен, но не используется
объект TNotify создается просто с помощью конструктора без параметров.
Далее, создайте функцию обработчик события связанного с выбором вкладки, вызовите Class Expert → затем, найдите идентификатор элемента управления вкладки (по умолчанию – IDC_-
нами. Поэтому
ак-
187

TABCONTROL1) → в списке событий выберите событие
TCN_SELCHANGE («выбор вкладки») → далее в контекстном меню команду Add handler. Назовите функцию TCNSelchangeTabCtrl.
В созданную Class Expert заготовку функции поместите код:
int i= TabCtrl->GetSel();
button1->ShowWindow(i == 0 ? SW_SHOW : SW_HIDE);
button1->EnableWindow(i == 0 ? TRUE : FALSE);
button2->ShowWindow(i == 1 ? SW_SHOW : SW_HIDE);
button2->EnableWindow(i == 1 ? TRUE : FALSE);
updown1->ShowWindow(i == 0 ? SW_SHOW : SW_HIDE);
updown1->EnableWindow(i == 0 ? TRUE : FALSE);
edit1->ShowWindow(i == 0 ? SW_SHOW : SW_HIDE);
edit1->EnableWindow(i == 0 ? TRUE : FALSE);
slider1->ShowWindow(i == 1 ? SW_SHOW : SW_HIDE);
slider1->EnableWindow(i == 1 ? TRUE : FALSE);
edit2->ShowWindow(i == 1 ? SW_SHOW : SW_HIDE);
edit2->EnableWindow(i == 1 ? TRUE : FALSE);
Сначала с помощью метода GetSel класса TTabControl определяем индекс выбранной вкладки, затем функции ShowWindow класса TWindow делают элемент управления видимым (SW_SHOW) или
скрывают его
EnableWindow класса TWindow делает элемент доступным (TRUE)
или недоступным (FALSE). Если теперь запустить программу, то
при выборе нужной вкладки (щелчком мышкой по заголовку) будут
появляться только «принадлежащие вкладке» элементы – редактируемое поле “edit1”, счетчик “updown1” и кнопка “button1” при
выборе первой вкладки:
(SW_HIDE), в зависимости от индекса вкладки. Метод
188

или редактируемое поле “edit2”, ползунок “slider1” и кнопка “button1”
при выборе второй вкладки:
Создайте функции-обработчики для кнопок. В тело обработчика
для кнопки “button1” поместите код:
MessageBox("кнопка 1");
а для кнопки “button2” строчку:
MessageBox("кнопка 2");
Запустите программу. Проверьте, как переключаются вкладки и
работают кнопки.
Теперь придадим функциональности элементу Up-Down (счетчик). В свойствах элемента «счетчик» зайдите на вкладку «Up-
Down» и установите флажок Set Buddy Int
значение в связанном поле), а переключатели в положение Right
(счетчик будет расположен справа от связанного поля) и Vertical
(вертикальное расположение счетчика). В конец перегруженного
ранее метода класса далога SetupWindow добавьте инструкции:
updown1->SetBuddy( GetDlgItem(IDC_EDIT1));
updown1->SetRange( 0, 50);
updown1->SetPos(10);
189
(обновлять числовое

Метод SetBuddy класса TUpDown связывает элемент updown1
с полем edit1 первой вкладки по идентификатору данного поля
(IDC_EDIT1). Метод SetRange класса TUpDown устанавливает
диапазон изменения значений, а метод SetPos класса TUpDown –
начальное значение. При щелчке по стрелкам число, отображаемое в
поле, увеличится или уменьшится на единицу.
Замечание: Если требуется изменить значение
единицу, нужно перегрузить событие UDN_DELTAPOS элемента
Up-Down. Однако тогда придется самим программно менять значение в связанном объекте! Следует иметь в виду, что параметр udn
функции обработчика этого события имеет два поля: udn.iPos – установленное значение и udn.iDelta – изменение, причем значение
поля iDelta равно единице, если пользователь хочет
новленное значение, и – минус единице, при попытке уменьшить эту
величину.
Наконец разберемся с элементом Track Bar (регулятор ползункового типа, слайдер или просто ползунок). В свойствах элемента
зайдите на его вкладку “TrackBar” и установите переключатели в
положение Horizontal (расположить горизонтально) и Bottom/Right.
У слайдера не предусмотрено событий, поэтому установим таймер,
который
WM_TIMER. Для этого события позднее создадим функцию обработчик, где и обработаем изменение показаний ползунка пользователем. Итак, в конец перегруженного ранее метода SetupWindow
добавьте инструкции:
нения значений, а метод SetPosition класса THSlider – начальное
значение. Метод SetRuler
ния значений. Если второй параметр метода SetRuler равен true, то
значение может меняться только на величину, кратную первому параметру. Если второй параметр равен false, то кратное изменение
возникает только при щелчке по линейке ползунка. Если же пере-
будет с интервалом 0,1 секунды посылать сообщение
SetTimer(0,100);
slider1->SetRange( 0, 50);
slider1->SetRuler( 3, true);
slider1->SetPosition(21);
Метод SetRange класса THSlider устанавливает диапазон изме-
класса THSlider задает величину измене-
больше, чем на
увеличить уста-
190
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
