Студопедия

КАТЕГОРИИ:

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

Выполнение программы до точки прерывания




Давайте запустим программу buggy в отладчике — для этого достаточно выполнить командуBuild > Start Debug > Go*. На экране появляется окно приложения, и вы можете выполнить команду Calculate > Calculate Average. В результате код метода OnCalculateCalculateAverage()выполняется до строки, на которой установлена точка прерывания. Затем программа останавливается и отображает в окне Visual C++ код метода. Стрелка на левом поле Visual C++, обозначает текущую выполняемую строку нашей программы.

Обратите внимание — в Visual C++ меню Buildзаменилось на Debug. Среди различных команд этого меню особый интерес представляют команды Step Into (F11), Step Over (F10), Step Out (Shift+F11) и Run To Cursor (Ctrl+F10). Они соответствуют различным способам выполнения программы, предусмотренным, режиме отладки Visual C++.

Пошаговое выполнение программы

Во время отладки программ на Visual C++ часто встречаются строки с вызовами различных методов (например, PerformWork(data)). Если продолжить пошаговое выполнение программы с такой строки, то вы перейдете к коду вызываемого метода (например, PerformWork(), который может быть достаточно длинным). Это означает,что для возврата к отлаживаемому фрагменту вам приходится пройти через весь код метода.

В этом нет ничего плохого, если вы хотите отладить вызываемый метод, а если не хотите? (Например, если вызван стандартный метод Visual C++?) В этом случае вы можете пропуститькод метода, пользуясь клавишейF10 для последовательного выполнения своей программы.

Если вы захотите пройти через код вызываемого метода, пользуйтесь клавишей F11.

Если вы окажетесь внутри вызванного метода или другого блока, который не хотите отлаживать, можете выйти за его пределы, нажав клавиши Shift+F11.

Существует и другая возможность — установить курсор в некоторой точке программы за текущей выполняемой строкой и нажать клавишиCtrl+F10, что приведет к выполнению кода до строки с курсором.

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

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();

}

Текущей становится следующая строка программы. Именно в ней происходит суммирование чисел для получения накапливаемой суммы в переменной Sum.

Чтобы выполнить текущую строку, обновить значение суммирующей строке, еще раз нажмите клавишу F10. К переменной Sum прибавлено первое целое число, а мы можем проверить ее значение и убедитъся, что все идет нормально.

Проверка значений переменных во время выполнения программы

Чтобы узнать значение переменной Sum (в которой должно храниться первое целое число, задержите над ней указатель мыши. Рядом с именем переменной на экране появляется подсказка со значением 1.40817е+019 или 1.40817х1019 — это несколько больше, чем мы ожидали. Похоже, мы нашли проблему.

Окна Auto и Locals

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

ПОДСКАЗКА: Если вы хотите отслеживать значение конкретной переменной во время всего выполнения программы, введите ее имя в окне Watch, расположенном в правом нижнем углу окна Visual C++. Кроме того, нужную переменную можно просто перетащить мышью в окно Watch.

Просмотр программы показывает, что мы забыли обнулить начальное значение суммы. Давайте сделаем это. Прежде всего, завершите сеанс отладки командой Debug >-Stop Debugging, затем отредактируйте метод и присвойте переменной Sumначальное значение 0:

void CBuggyView::OnCalculateCalculateaverage()

{

CBuggyDoc* pDoc = GetDocumentO;

ASSERT J/ALID(pDoc);

float Sum = 0;

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();

}

Ошибка с инициализацией исправлена. Снова запустите программу.

Теперь программа сообщает, что среднее арифметическое первых пяти целых чисел равно 2.800. Конечно, это гораздо ближе к ожидаемому значению 3.000, но все-таки не оно. Пора возвращаться к отладчику.

Снова начните отладку командой Build > Start Debug > Go и выполните программу до точки прерывания. Войдите в цикл forклавишей F10. Задержите указатель мыши над переменной Sum, чтобы убедиться, что ее значение действительно равно 0.

С переменной Sum все нормально; давайте проверим значение, которое к ней добавляется, pDoc->data[loop_index]:

void CBuggyView::OnCalculateCalculateaverage()

 {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum = 0;

        float Average;

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

        {

        Sum += pDoc->data[loop_index];

            }

        Average = Sum / (float) 5.0;

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

Invalidate();

Мы не сможем узнать значение выражения pDoc->data[loop_index];, задерживая над ним указатель мыши (непонятно, что именно нас интересует — только рDос или все выражение?), но оно присутствует в окне Autoв левом нижнем углу. Мы видим, что к сумме прибавляется число 2 (а не 1, как ожидалось).

Просмотр переменной loop_index показывает, что она равна 1, а не 0, как положено. Остановите отладку и исправьте ошибку:

void CBuggyView::OnCalculateCalculateaverage()

 {

CBuggyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

float Sum = 0;

        float Average;

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

        {

        Sum += pDoc->data[loop_index];

            }

        Average = Sum / (float) 5.0;

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

Invalidate();

}

ПОДСКАЗКА: Чтобы узнать значение того или иного выражения во время выполнения программы, можно выполнить команду Debug >QuickWatchи ввести выражение в диалоговом окне QuickWatch. Visual C++ вычислит его значение.

Запустите программу. Мы добились желаемого результата — среднее арифметическое чисел 1-5 равно 3. Встроенные отладочные средства Visual C++ помогли ликвидировать ошибки.

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

ПОДСКАЗКА: Закончив отладку, следует удалить отладочную информацию из исполняемого файла. Выполните команду Build >- Set Active Configurationи выберите из раскрывающегося списка строкуbuggy - Win32 Release (по умолчанию в программы на Visual C++ включается большой объем информации, используемой отладчиком).

 

Приложение 1. Работа со стандартными ресурсами

1. Методы класса CButton

2. Методы класса CEdit

3. Методы класса CListBox

4. Методы класса CComboBox

5. Методы класса CProgressCtrl

6. Методы класса CSliderCtrl

7. Методы класса CSpinButtonCtrl

8. Пример Windows-приложения, использующего стандартные ресурсы

Методы класса CButton

HBITMAP GetBitmap() const;

Возвращает дескриптор растрового изображения, сопоставленного кнопке. Если такового не существует, то возвращается NULL.

HBITMAP SetBitmap(HBITMAP hBitmap);

Сопоставляет кнопке растровое изображение. Значением параметра должен быть дескриптор растрового изображения. Правила размещения растрового изображения такие же, как и у значка.

HCURSOR GetCursor();

Возвращает дескриптор курсора, сопоставленного кнопке методом SetCursor. Если у кнопки нет сопоставленного курсора, то возвращается NULL.

HCURSOR SetCursor(HCURSOR hCursot);

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

UINT GetState() const;

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

· 0х0003 - выделяет собственное состояние кнопки. Применимо только к флажку или переключателю. Если результат побитового умножения дает 0, значит кнопка находится в невыбранном состоянии, 1 - в выбранном, 2 - в неопределенном.

· 0х0004 - выделяет состояние первого типа. Ненулевой вариант означает, что кнопка "нажата", нулевой - кнопка свободна.

· 0х0008 - выделяет положение фокуса. Ненулевой вариант - кнопка в фокусе клавиатуры.

int GetCheck() const;

Возвращает собственное состояние флажка или переключателя. Возвращаемое значение может принимать одно из значений: 0 - кнопка не выбрана; 1 - кнопка выбрана; 2 - кнопка в неопределенном состоянии. Если кнопка не является ни переключателем, ни флажком, возвращается 0.

void SetCheck(int nCheck);

Устанавливает собственное состояние флажка или переключателя. Значения задаются из набора: 0 - невыбранное; 1 - выбранное; 2 - неопределенное. Значение 2 применимо только к флажку со свойством 3State.

UINT GetButtonStyle() const;

Возвращает стиль кнопки.

void SetButtonStyle(UINT nStyle, BOOL bRedraw=TRUE);

Устанавливает стиль кнопки. Если параметр bRedraw равен TRUE, кнопка перерисовывается.

HICON GetIcon() const;

Возвращает дескриптор пиктограммы, сопоставленной кнопке. Если у кнопки нет сопоставленной пиктограммы, возвращает NULL.

HICON SetIcon(HICON hIcon);

Сопоставляет кнопке пиктограмму. Значением параметра при вызове должен быть дескриптор пиктограммы.

Пиктограмма автоматически помешается на поверхность кнопки и сдвигается в ее центр. Если поверхность кнопки меньше пиктограммы, она обрезается со всех сторон до размеров кнопки. Положение пиктограммы может быть выровнено и не по центру. Для этого нужно, чтобы кнопка имела одно из следующих свойств: BS_LEFT, BS_RIGHT, BS_CENTER, BS_TOP, BS_BOTTOM, BS_VCENTER

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

Методы класса CEdit

Окна редактирования могут работать в режимах однострочного и многострочного редакторов. Приведем сначала методы, общие для обоих режимов, а затем методы для многострочного редактора.

Общие методы :

DWORD GetSel() const;

void GetSel(int& nStartChar, int& nEndChar) const;

Получает первую и последнюю позиции выделенного текста. Для значения типа DWORD младшее слово содержит позицию первого, старшее - последнего символа.

void SetSel(DWORD dwSelection, BOOL bNoScroll=FALSE);

void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll=FALSE);

Устанавливает новое выделение текста, задавая первый и последний выделенный символ. Значение FALSE параметра bNoScroll должно отключать перемещение курсора в область видимости.

void ReplaceSel(LPCTSTR lpszNewText);

Заменяет выделенный текст на строку, передаваемую в параметре lpszNewText.

void Clear();

Удаляет выделенный текст.

void Copy();

Копирует выделенный текст в буфер.

void Cut();

Переносит (копирует и удаляет) выделенный текст в буфер обмена.

void Paste();

Вставляет текст из буфера обмена, начиная с позиции, в которой находится курсор.

BOOL Undo();

Отмена последней операции, выполненной редактором. Если редактор однострочный, возвращается всегда неотрицательное значение, иначе неотрицательное значение возвращается лишь в случае успешной замены.

BOOL CanUndo() const;

Определяет, можно ли отменить последнюю операцию редактора.

void EmptyUndoBuffer();

Сбрасывает флаг undo, сигнализирующий о возможности отмены последней операции редактора, и тем самым делает невозможным отмену. Этот флаг сбрасывается автоматически при выполнении методов SetWindowText и SetHandle.

BOOL GetModify() const;

Возвращает неотрицательное значение, если содержимое окна редактирования не модифицировалось. Информация о модификации поддерживается в специальном флаге, обнуляемом при создании окна редактирования и при вызове метода:

void SetModify(BOOL bModified=TRUE);

Устанавливает или сбрасывает флаг модификации (см. предыдущий метод). Флаг сбрасывается при вызове метода с параметром FALSE и устанавливается при модификации содержимого окна редактирования или при вызове SetModify с параметром TRUE.

BOOL SetReadOnly(BOOL bReadOnly=TRUE);

Устанавливает режим просмотра (bReadOnly=TRUE) или редактирования (bReadOnly=FALSE).

TCHAR GetPasswordChar() const;

Возвращает символ, который при выводе пароля будет появляться на экране вместо символов, набираемых пользователем. Если такой символ не определен, возвращается 0. Устанавливается этот символ методом (по умолчанию используется "*"):

void SetPasswordChar(TCHAR ch);

void LimitText(int nChars=0);

Устанавливает максимальную длину в байтах текста, который может ввести пользователь. Если значение параметра равно 0, длина текста устанавливается равной UINT_MAX.

Методы работы с многострочным редактором:

void LineScroll(int nLines, int nChars=0);

Прокручивает текст в области редактирования. Параметр nLimes задает число строк для вертикальной прокрутки. Окно редактирования не прокручивает текст дальше последней строки. При положительном значении параметра область редактирования сдвигается вдоль текста к последней строке, при отрицательной - к первой.

Параметр nChars задает число символов для горизонтальной прокрутки. Окно редактирования прокручивает текст вправо, даже если строки закончились. В этом случае в области редактирования появляются пробелы. При положительном значении параметра область редактирования сдвигается вдоль к концу строки, при отрицательном - к началу.

int GetFirstVisibleLine() const;

Возвращает номер первой видимой строки.

int GetLineCount() const;

Возвращает число строк текста, находящегося в буфере редактирования. Если текст не вводился, возвращает 1.

int GetLine(int nIndex, LPTSTR lpszBuffer) const;

int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const;

Копирует строку с номером, равным значению параметра nIndex, в буфер, заданный параметром lpszBuffer. Первое слово в буфере должно задавать его размер. При вызове второго варианта метода значение параметра nMaxLength копируется в первое слово буфера.

Метод возвращает число в действительности скопированных байтов. Если номер строки больше или равен числу строк в буфере окна редактирования, возвращает 0. Текст копируется без каких-либо изменений, нуль-символ не добавляется.

int LineIndex(int nLine=-1) const;

Возвращает номер первого символа в строке. Неотрицательное значение параметра принимается в качестве номера строки. Значение -1 задает текущую строку. Если номер строки больше или равен числу строк в буфере окна редактирования (строки нумеруются с 0), возвращается 0.

Методы класса CListBox

void ResetContent();

Очищает содержимое списка, делая его пустым.

int AddString( LPCSTR lpszItem);

Добавляет строку lpszItem в список и сортирует его, если при создании включено свойство Sort. В противном случае элемент добавляется в конец списка.

int DeleteString( UINT nIndex);

Удаляет из списка элемент с индексом nIndex. Индексация элементов начинается с 0.

int GetCurSel() const;

Получает индекс элемента, выбранного пользователем.

int SetCurSel( int nSelect);

Отмечает элемент с индексом nSelect как выбранный элемент списка. Если значение параметра равно -1, список не будет содержать отмеченных элементов.

int GetText( int nIndex, LPSTR lpszBuffer) const;

void GetText( int nIndex, CString& rString) const;

Копирует элемент с индексом nIndex в буфер.

int SetTopIndex( int nIndex);

Организует прокрутку списка в окне так, чтобы элемент с индексом nIndex был видимым.

int FindString( int nStartAfter, LPCSTR lpszItem) const;

Организует поиск в списке и возвращает в качестве результата индекс элемента списка, префикс которого совпадает со строкой lpszItem. Результат не зависит от регистра, в котором набирались символы сравниваемых строк. Параметр nStartAfter задает начало поиска, но поиск идет по всему списку. Он начинается от элемента, следующего за nStartAfter, до конца списка и затем продолжается от начала списка до элемента с индексом nStartAfter. В качестве результата выдается первый найденный элемент, удовлетворяющий условиям поиска. Если такого нет, результат получает значение LB_ERR.

int FindStringExact( int nIndexStart, LPCSTR lpszFind) const;

Этот метод отличается от предыдущего тем, что теперь не префикс элемента должен совпадать со строкой lpszFind, а сам элемент. Поиск по-прежнему не чувствителен к регистру, в котором набираются символы.

Методы класса CComboBox

int GetCurSel() const;

Возвращает целочисленный указатель выбранной строчки.

int SetCurSel(int nSelect);;

Ставит указатель на строчку с номером nSelect.

int GetLBText(int nIndex, LPTSTR lpszText) const;

void GetLBText(int nIndex, CString& rString) const;

Записывает содержимое строчки с индексом nIndex в переменные LPTSTR lpszText или CString& rString.

int GetLBTextLen(int nIndex) const;

Возвращает длину строчки с индексом nIndex.

int AddString(LPCTSTR lpszString);

Добавляет строчку в список.

int DeleteString(UINT nIndex);

Удаление строчки с индексом nIndex.

int InsertString(int nIndex, LPCTSTR lpszString);

Заменяет строчку с индексом nIndex содержимым переменной LPCTSTR lpszString.










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

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