Читать онлайн «Windows via C/C++. Программирование на языке Visual C++»

Автор Джеффри Рихтер

листинг на рис. 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 это невозможно, поскольку со- держимое сообщений заранее не известно.