Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Добавление свойств к элементам ActiveX




Свойствомназывается переменная класса элемента. Если тот содержит свойство data, то другие программы могут обращаться к нему через запись типа m_buttoneг.data или через функции чтения/записи свойства:m_buttoner.SetData() иm_buttoner.GetData(). Мы познакомимся со свойствами на примере data, сохраняющем число щелчков мышью.

Для добавления свойств в элемент ActiveX также используется ClassWizard. Откройте его и перейдите на вкладку Automation(по названию технологии OLE Automation), затем нажмите кнопку Add Property, чтобы вызвать одноименное окно.

Введите в поле External nameимя свойства data; сделайте его коротким целым числом, выбрав из списка Typeстрокуshort. Установите переключательGet/Set methods - это значит, что программы будут вызывать метод SetData(), чтобы присвоить значение свойству, и метод GetData(), чтобы узнать значение свойства (если установить переключатель Member Variable, другие программы смогут напрямую обращаться к свойству: Buttoner.data). Нажмите кнопку ОК, чтобы закрыть окно Add Property, а потом закройте ClassWizard.

Теперь в программе можно ссылаться на значение свойства dataчерез переменнуюm_data. Начнем с обнуления этого значения в конструкторе:

CButtonerCtrl: :CButtonerCtrl()  

{

InitializeIIDs(&IID_DButtoner, &IID_DButtonerEvents);

SetText("Нажми меня!");

        m_data = 0;

}

В свойстве должно храниться число щелчков на элементе, поэтому в OnLButtonDown() следует увеличивать значение m_data:

void CButtonerCtrl::OnLButtonDown(UINT nFlags, CPoint point)

// TODO: добавьте код обработки сообщения ,

 // и/или вызовите обработчик по умолчанию

 FireClick();

m_data++;

 COleControl::OnLButtonDown(nFlags.point);   

}

Если другая программа вызовет методGetData() нашего элемента, она получит значение переменнойm_data, равное количеству щелчков, сделанных на нем.

Добавление свойства закончено. К настоящему моменту наш элемент имеет событие Clickи свойство data. Сейчас мы добавим в него метод Веер(), который может вызываться другими программами с помощью записи вида m_buttoner.Веер().

Добавление методов

Чтобы добавить в элемент метод, вызовите ClassWizard и перейдите на вкладку Automation. Нажмите кнопку Add Method — открывается одноименное окно.

Присвойте новому методу имя Веер(в обоих полях — External name и Internal name) и укажите тип возвращаемого значения void. Нажмите кнопку ОК, чтобы закрыть окно Add Method, а потом закройте ClassWizard. В элементе появляется метод Веер():

void CButtonerCtrl::Beep()

 {

// TODO: добавьте код диспетчерской обработки

 }

При вызове этого метода компьютер будет выдавать звуковой сигнал, для этого мы воспользуемся методом MFC MessageBeep():

void CButtonerCtrl::Beep()

{

MessageBeep(MB_OK);

}

В нашем элементе появился новый метод, который может использоваться в других программах. Теперь они могут вызывать метод Веер() элемента внутри своего кода.

Настало время посмотреть, как элемент Buttoner ведет себя в других приложениях. Давайте попробуем внедрить его в программу и поработать с ним на уровне программного кода.

Внедрение элемента Buttoner в другую программу

При помощи AppWizard создайте новую программу на базе диалогового окна и присвойте ей имя Buttonerapp. Включите элемент Buttonerв палитру редактора диалоговых окон. Для этого следует вызвать окно Components and Controls Gallery, о чем рассказывалось в предыдущем примере. Когда Visual C++ предложит задать имя класса элемента, подтвердите предложенное по умолчанию имя CButtoner.

Теперь мы добавим элемент Buttonerв новую программу с помощью редактора диалоговых окон. Он присваивает элементу идентификатор ID_BUTTONERCTRL1.

Разместите текстовое поле для вывода сведений о количестве щелчков. Содержимое поля будет определяться методом, возвращающим значение свойства data.

С помощью ClassWizard свяжите с элементом Buttonerпеременную m_buttoner. Обратите внимание: она принадлежит недавно созданному классу CButtoner.Кроме того, свяжите содержимое текстового поля с переменнойm_text.

Элемент Buttonerвнедрен в приложение Buttonerapp, и для вызова его методов (например, Веер()) можно пользоваться записью видаm_buttoner. Веер().

Связывание элемента ActiveX с кодом программы

В ClassWizard мы создадим обработчик для события Clickэлемента Buttoner. Найдите событие в окне ClassWizard и создайте новый обработчик, которому ClassWizard присваивает имя OnClickButtonerctrl1():

void CButtonerappDlg::OnClickButtonerctrl1()

 

{

// TODO: добавьте код обработки события

// и/или вызовите обработчик по умолчанию

}

Этот метод будет вызываться при каждом щелчке мышью на элементе. Чтобы узнать, сколько раз пользователь щелкнул на элементе, следует определить значение свойства data, а для этого нужно вызвать методGetData():

void CButtonerappDlg::OnClickButtonerctrl1()

{

        m_text.Format("свойство data = %ld", Buttoner.GetData());

        UpdateData(false);

}    

Теперь при каждом щелчке на элементе программа Buttonerapp будет выводить общее количество щелчков, хранящееся в свойстве data. Наша программа, содержащая управляющий элемент ActiveX, работает именно так, как нам хотелось.

На примере элемента Buttoner мы узнали много нового: как создать элемент ActiveX на базе существующего управляющего элемента и как организовать в нем поддержку событий, методов и свойств.

14. Отладка программ в Visual C++

Далее мы научимся отлаживать программы. К сожалению, для большинства программистов отладка стала суровой жизненной реальностью (почти в любом нетривиальном приложении встречаются ошибки, которые приходится исправлять), а отладочные возможности Visual C++ способны существенно помочь в решении этой задачи.

Мы начнем с создания программы, заведомо содержащей несколько ошибок (она будет назватьсяbuggy), а затем посмотрим, как с помощью отладчика найти и исправить эти ошибки. В частности, мы научимся устанавливать в программе точки прерывания и выполнять ее до заданной точки. Когда во время выполнения встречается точка прерывания, программа останавливается, а на экране появляется отлаживаемый код. Это дает возможность детально выяснить, что происходит в программе.

Кроме того, программу можно выполнять последовательно, строка за строкой — такой процесс называетсяпошаговым выполнением. Этот режим позволяет следить за тем, как изменяются значения различных переменных; иногда он помогает понять, в чем заключается проблема, — если переменная получает неожиданное значение, скорее всего, в программе допущена ошибка. После того как ошибки будут обнаружены, их можно исправить и заново отладить программу.

Давайте создадим программу buggy и отладим ее.

Программа buggy

Программа buggy, которую мы рассматриваем, определяет среднее арифметическое первых пяти положительных целых чисел: 1-5. Как нетрудно догадаться, ответ должен быть 3, однако до полного завершения отладки мы получим несколько других вариантов.

При помощи AppWizard создайте одно-документную (SDI) программу:

1. Для хранения пяти целых чисел мы воспользуемся массивом data. Начнем с включения этого массива в заголовочный файл документа:

// buggyDoc.h: интерфейс класса CBuggyDoc

public:

         int data[5];

2. Исходные числа будут заноситься в массив в конструкторе документа:

CBuggyDoc::CBuggyDoc()

{

data[0] = 1;

data[1] = 2;

data[2] =3;

data[3] = 4;

data[4] = 5;

}

3. Можно приступать к вычислениям. С помощью редактора меню добавьте новое меню Calculate(расположите его между Fileи Edit) с единственной командой — Calculate Average.

4. Воспользуйтесь ClassWizard и создайте в программе обработчик для этой команды:

void CBuggyView::OnCalculateCalculateaverage()

 {

}

5. Наша программа должна вычислять среднее арифметическое и выводить его в окне. Прежде всего, необходимо получить указатель, на объект документа, поскольку исходные данные хранятся именно в нем:

void CBuggyView::OnCalculateCalculateaverage()

{

        CBuggyDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);                                        

}

6. Далее мы создадим рабочие переменные. Чтобы найти среднее арифметическое, следует суммировать числа и разделить сумму на количество чисел. Нам понадобятся две переменные, Sumи Average:

void CBuggyView::OnCalculateCalculateaverage()

{

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum;

 float Average;

}

7. Вычисление суммы пяти чисел будет происходить в следующем цикле:

void CBuggyView::OnCalculateCalculateaverage() {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum;

float Average;

for(int loop_index = 1; loop_index < 5;loop_index++)

 {

 Sum += pDoc->data[loop_index];

}

}

8. Чтобы вычислить среднее арифметическое, разделим сумму на 5:

void CBuggyView::OnCalculateCalculateaverage() {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum;

float Average;

for(int loop_index = 1; loop_index < 5;loop_index++)

 {

 Sum += pDoc->data[loop_index];

}

}

Average = Sum / (float) 5.0;

}

9. Наконец, мы помещаем результат в строку OutputString и объявляем вид недействительным, чтобы вывести ее на экран:

void CBuggyView::OnCalculateCalculateaverage() {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum;

float Average;

for(int loop_index = 1; loop_index < 5;loop_index++)

 {

 Sum += pDoc->data[loop_index];

}

}

Average = sum / (float) 5.0:

OutputString. Format ("Среднее арифметическое пяти чисел равно: %.3f", Average);

Invalidate();

}

10. Обработчик команды меню готов.

11. Далее мы объявим OutputStringв заголовочном файле вида:

// buggyView.h: интерфейс класса CBuggyView

protected:

CString OutputString;

}

12. В конструкторе вида в эту строку заносится подсказка, предлагающая пользователю выполнить команду Calculate > Calculate Average(подсказка будет выведена при запуске программы):

void CBuggyView::OnDraw(CDC* pDC) :

{

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

pDC->TextOut(0, 0, OutputString);

}

13. Остается занести в OutputStringтекст подсказки, отображаемой в методе OnDraw():

CBuggyView::CBuggyView()

{

OutputString = "Выполните команду Calculate|Calculate Average";

}

Программа готова к выполнению.

Запустите ее и выберите команду Calculate Average. Программа сообщает, что среднее арифметическое чисел 1-5 равно 2818446765003793900.000. Возможно, вы получите другое число.

Похоже, мы где-то ошиблись.

Установка точки прерывания

Перейдем к отладке программы buggy. Желательно попасть в программу во время ее работы, чтобы можно было начать пошаговое выполнение, однако начинать с самого начала программы не хочется, поскольку в этом случае нам придется проходить через стартовый код Visual C++, который в обычном случае мы даже не увидим. Отладка должна начинаться поближе к тому месту, где, как можно предположить, возникает проблема, — к фрагменту, отвечающему за вычисление среднего арифметического.

Чтобы начать отладку с произвольной строки, следует установить точку прерывания.Во время выполнения программа остановится на ней, мы сможем просмотреть свой код и при необходимости перейти в пошаговый режим.

Посмотрим, как это делается. Мы поместим точку прерывания в начале фрагмента для вычисления среднего арифметического, конкретнее — в начале метода OnCalculateCalculateaverage(), в первой строке цикла for:

void CBuggyView::OnCalculateCalculateaverage() {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum;

float Average;

--->for(int loop_index = 1; loop_index < 5;loop_index++)

 {

 Sum += pDoc->data[loop_index];

}

}

Average = sum / (float) 5.0:

OutputString. Format ("Среднее арифметическое пяти чисел равно: %.3f", Average);

Invalidate();

}

Точку прерывания можно установить перед запуском программы или во время ее остановки на другой точке. Нажимая клавишу F10, мы сможем перемещаться по коду программы. Однократное нажатие этой клавиши переводит нас к следующей строке программы.

Многократно нажимая F10, вы сможете перемещаться в программе и дальше. Заодно можно будет просмотреть значения различных переменных, так что в процессе отладки вы как бы зайдете в выполняемую программу "с черного хода". Поскольку мы знаем, как долженработать этот фрагмент, нам будет легче обнаружить возникающие проблемы.

Чтобы разместить точку прерывания в начале цикла for, установите на этой строке текстовый курсор и нажмите клавишу F9или кнопку с поднятой рукой на панели инструментов (она выполняет ту же функцию). В результате на строке будет установлена точка прерывания (в программе может быть несколько точек прерывания). Точка прерывания обозначается маленьким значком в виде стоп-сигнала на левом поле.

ПОДСКАЗКА:Не разрешается устанавливать точки прерывания на строках программы, содержащих объявления переменных (например, float Sum;).










Последнее изменение этой страницы: 2018-04-12; просмотров: 325.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...