Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Разработка Windows - приложений в среде Borland. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
сив. Откройте модуль 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, выберите вкладку List­View и режим отображения в виде таблицы – опция
Убедитесь, что записи не будут автоматически упорядочены – опция None в группе Sort Type. Если хотите, чтобы выделение выбранных в окне записей сохранялось при потере элементом фокуса, поставьте флажок Show Sel Always.
Создайте столбцы (колонки) таблицы. Для этого перегрузите
функцию SetupWindow класса диалога TWorkDlgClient и добавьте в созданную ClassExpert заготовку нужного метода строчки:
TListWindColumn column1("имя", 70, TListWindColumn::Left, 0); browser->InsertColumn(0, column1); TListWindColumn column2("должность", 70, TlistWind­Column::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, задача которой – сделать видимы­ми только элементы активной вкладки. Мы будем считать, что эле­менты, расположенные слева, принадлежат первой вкладке (с ин­дексом ноль). Соответственно элементы, расположенные справа, будут принадлежать второй вкладке. Параметр функции TCN­SelchangeTabCtrl обязателен, но не используется объект 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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]