(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 Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office 365 Бизнес. Подписка на 1 рабочее место на 1 год
Microsoft 365 Business Basic (corporate)
Microsoft 365 Apps for business (corporate)
Microsoft Windows Professional 10, Электронный ключ
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Все о PHP и даже больше
Delphi - проблемы и решения
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100