(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Обработка ошибок

Источник: thalion

Обработчик ошибок.

Мы должны создать что-то вроде системы визуализации и контроля над ошибками. Т.к. вывод текста с помощью GDI (Graphical Device Interface) не очень быстрый, то мы будем записывать наши ошибки в текстовый файл. Еще мы добавим возможность выхода из программы при возникновении ошибки. Создадим класс CError для выполнения всех этих вещей. Прототип класса приведен ниже:

class CError
{ 
  public: 
    FILE *fErrorLog; 
    bool bQuit; 
    LPSTR lpzMessage; 

    CError (LPSTR, bool); 
    ~CError (); 

    ProcessError (DWORD); 
};

fErrorLog - указатель на файл, в который мы будем записывать все ошибки.

bQuit - переменная булевского типа. Значение этой переменной - надо или нет закрывать программу, если произошла ошибка.

lpzMessage - текущее сообщение об ошибке. Память под сообщение будет выделяться динамически при возникновении ошибки для лучшего быстродействия в плане использования памяти и customizability.

СError() - Конструктор нашего класса. Вызывается при объявлении экземпляра нашего класса. Получает два параметра- строку с именем файла для записи ошибок и переменную булевского типа, true означает необходимость закрытия программы при возникновении ошибки, false не означает необходимость закрытия программы при возникновении ошибки.

~CError() - Деструктор нашего класса. Вызывается при уничтожении экземпляра нашего класса.

ProcessError() - Эта функция будет выполнять основную работу по обработке ошибок.

Теперь непосредственно реализация класса. В первую очередь напишем конструктор и деструктор:

CError::CError (LPSTR lpzFileName, bool bQuitOnError) 
{
  fErrorLog = fopen (lpzFileName, "wt"); 
  bQuit = bQuitOnError; 
} 

CError::~CError () 
{ 
}

Конструктор очень прост. Он всего лишь открывает файл (имя файла- первый параметр) для записи в текстовом режиме и устанавливает флаг выхода (bQuit) равным значению второго параметра.
Деструктор пока пуст.

Теперь главная часть нашего обработчика ошибок. Пока она очень простая, но будет увеличиваться по мере добавления новых ошибок.

CError::ProcessError (DWORD dwError)
{
  DWORD dwMsgSize;

  switch (dwError) 
  {
    default:
      dwMsgSize = strlen ("Unkown error:\n");
      lpzMessage = (LPSTR) malloc (dwMsgSize + 1);
      strcpy (lpzMessage, "Unkown error:\n");
      break;
  }
  if (fErrorLog != NULL)
  {
    fprintf (fErrorLog, lpzMessage);
  }
  if (lpzMessage != NULL)
  {
    free (lpzMessage);
  }
  if (bQuit == true)
  {
    if (fErrorLog != NULL)
    {
      fclose (fErrorLog);
    }

    PostQuitMessage (dwError);
  }

  return 0;
} ;

Сначала, мы объявляем переменную для запоминания длины строки с описанием ошибки. После этого мы используем оператор switch, что бы узнать, что у нас за ошибка. На данный момент используется только default (и все ошибки у нас обрабатываются одинаково - записываем в файл строку "Unkown error:"). Он делает три вещи: вычисляет длину строки (описание ошибки), выделяет под нее память и записывает эту строку в переменную нашего класса, lpzMessage. Далее мы проверяем необходимость записи ошибки в файл, и, если это нужно, записываем ее. После этого мы освобождаем память, выделенную под нашу строку, и в конце проверяем флаг bQuit- надо ли закрыть программу и файл ( файл закрываем, только если он открыт :). Если надо - делаем.

Комментарии.

Первое - когда понадобится добавить ошибку, мы должны вставить код до default.
Второе - мы не делаем никаких проверок (удачно ли открылся файл, правильно ли выделилась память и т.д.). Это ваше домашнее задание.

Это все об обработке ошибок.

Использование класса CError.

В первую очередь надо объявить экземпляр класса:
CError ErrorHandling ("errors.log", true);

Теперь добавим в наше Win32 приложение обработчик ошибок, который мы написали выше.

К примеру, мы хотим обработать ошибку, которая возникает при неудачной регистрации класса окна. Для этого в файле Error.h (там у нас прототип нашего класса) пишем

#define ERROR_REGISTER_CLASS 1

В функции ProcessError надо добавить следующий кусок кода (перед default):

  case ERROR_REGISTER_CLASS:
    dwMsgSize = strlen ("Could'nt register class...\n");
    lpzMessage = (LPSTR) malloc (dwMsgSize + 1);
    strcpy (lpzMessage, "Could'nt register class...\n");
    break;

Регистрация будет выглядеть так:

  if (!RegisterClass(&wc))
  {
    ErrorHandling.ProcessError (ERROR_REGISTER_CLASS);
    return (false);
  }

Теперь, если регистрация класса завершилась не успешно, в файл errors.log будет записано Could'nt register class..., а программа завершит свою работу

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 13.10.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft 365 Business Standard (corporate)
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft Office 365 Бизнес. Подписка на 1 рабочее место на 1 год
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100