листинг на рис. 1-2), демонстрирует, как
получить текстовое описание ошибки по ее коду. Программа
ErrorShow в основном предназначена для того, чтобы вы увидели, как работают
окно Watch отладчика и утилита Error Lookup. После запуска ErrorShow открыва-
ется следующее окно. В поле Error можно ввести любой код ошибки. Когда вы щелкнете кнопку
Look Up, внизу, в прокручиваемом окне появится текст с описанием данной
ошибки. Единственная интересная особенность программы заключается в том,
как она обращается к функции FormatMessage. Я использую эту функцию так:
// получаем код ошибки
DWORD dwError = GetDlgItemInt(hwnd, IDC_ERR0RC0DE, NULL, FALSE);
HL0CAL hlocal = NULL; // буфер для строки с описанием ошибки
// Мы ищем сообщения Windows, поэтому используем системные
// региональные параметры по умолчанию
// Примечание. Эта комбинация MAKELANGID имеет значение 0
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// получаем описание ошибки по коду
BOOL fOk = FormatMessage(
F0RMAT_MESSAGE_FR0M_8YSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
if (!fOk) {
// Это ошибка, связанная с сетью? HM0DULE hDll = LoadLibraryEx(TEXT("netmsg. dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL) {
fOk = FormatMessage(
F0RMAT_MESSAGE_FR0M_HM0DULE | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
Глава 1. Обработка ошибок.
docx 9
hDll, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if (fOk && (hlocal 1= NULL)) {
SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
} else {
SetDlgItemText(hwnd, IDC_ERRORTEXT,
TEXT("No text found for this error number. "));
Первая строка считывает код ошибки из текстового поля. Далее я создаю эк-
земпляр описателя (handle) блока памяти и инициализирую его значением NULL. Функция FormatMessage сама выделяет нужный блок памяти и возвращает нам
его описатель. Вызывая FormatMessage, я передаю флаг FORMAT_MESSAGEJFROM_ SYS-
TEM. Он сообщает функции, что мне нужна строка, соответствующая коду ошиб-
ки, определенному в системе. Кроме того, я передаю флаг
FORMAT_MESSAGE_ALLOCATE_BUFFER, чтобы функция выделила соответ-
ствующий блок памяти для хранения текста. Описатель этого блока будет воз-
вращен в переменной hlocal. Флаг FORMAT_MESSAGE_IGNORE_INSERTS по-
зволяет заменять в сообщениях параметры, которые используются Windows для
передачи более детальной контекстной информации, подстановочными знаками,
как показано на следующем рисунке:
Без этого флага необходимо передать вместо подстановочных знаков значения
в параметре Arguments, но в случае Error Show это невозможно, поскольку со-
держимое сообщений заранее не известно.