Обробка помилок, Різне, Програмування, статті

Оброблювач помилок.


Ми повинні створити щось на зразок системи візуалізації та контролю над помилками. Т.к. висновок тексту за допомогою 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:
“);
lpzMessage = (LPSTR) malloc (dwMsgSize + 1);
strcpy (lpzMessage, “Unkown error:
“);
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…
“);
lpzMessage = (LPSTR) malloc (dwMsgSize + 1);
strcpy (lpzMessage, “Could”nt register class…
“);
break;

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






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

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

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*