Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.03.2009, 16:26   #1
happy_horror
Пользователь
 
Регистрация: 03.03.2009
Сообщений: 15
По умолчанию запуск программы ErrorShow из книги Джефри Рихтера

Привет, столкнулся с проблемой работы программы-примера из книги Рихтера "Создание эффективных WIN32-приложений".


Его пример изначально сделан под Microsort Visual Studio 6.0 (залил сюда http://dump.ru/file/1964341 + добавил фаил CmnHdr.h)


Его пример я запускал на Microsort Visual Studio 2005, студия автоматом его конвертировала в формат своих проектов (залил сюда http://dump.ru/file/1964352)


Как должен работать пример из книги: в окошке надо ввести номер кода ошибки windows, нажать кнопку "Look up" и будет показано текстовое описание ошибки (в той главе Рихтер пишет, что коды ошибок лежат в фаиле WinError.h - я его открывал, там они есть, начиная с 1 и до 10000...)


Проблема: текстовое описание ошибки не показывается...


на всякий случай код программы:

Код:
/******************************************************************************
Module:  ErrorShow.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/


#include "CmnHdr.h"     /* See Appendix A. */
#include <Windowsx.h>
#include <tchar.h>
#include "Resource.h"
#define ESM_POKECODEANDLOOKUP    (WM_USER + 100)
const TCHAR g_szAppName[] = TEXT("Error Show");

BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {

   chSETDLGICONS(hwnd, IDI_ERRORSHOW);

   // Don't accept error codes more than 5 digits long
   Edit_LimitText(GetDlgItem(hwnd, IDC_ERRORCODE), 5);

   // Look up the command-line passed error number
   SendMessage(hwnd, ESM_POKECODEANDLOOKUP, lParam, 0);
   return(TRUE);
}

void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {

   switch (id) {

   case IDCANCEL:
      EndDialog(hwnd, id);
      break;

   case IDC_ALWAYSONTOP:
      SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP) 
         ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
      break;

   case IDC_ERRORCODE: 
      EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
      break;

   case IDOK:
      // Get the error code
      DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);

      HLOCAL hlocal = NULL;   // Buffer that gets the error message string

      // Get the error code's textual description
      BOOL fOk = FormatMessage(
         FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 
         NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 
         (PTSTR) &hlocal, 0, NULL);

      if (!fOk) {
         // Is it a network-related error?
         HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, 
            DONT_RESOLVE_DLL_REFERENCES);

         if (hDll != NULL) {
            FormatMessage(
               FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
               hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
               (PTSTR) &hlocal, 0, NULL);
            FreeLibrary(hDll);
         }
      }

      if (hlocal != NULL) {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
         LocalFree(hlocal);
      } else {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found."));
      }
      break;
   }
}

INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

   switch (uMsg) {
      chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hwnd, WM_COMMAND,    Dlg_OnCommand);

   case ESM_POKECODEANDLOOKUP:
      SetDlgItemInt(hwnd, IDC_ERRORCODE, (UINT) wParam, FALSE);
      FORWARD_WM_COMMAND(hwnd, IDOK, GetDlgItem(hwnd, IDOK), BN_CLICKED, 
         PostMessage);
      SetForegroundWindow(hwnd);
      break;
   }

   return(FALSE);
}

int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {

   HWND hwnd = FindWindow(TEXT("#32770"), TEXT("Error Show"));
   if (IsWindow(hwnd)) {
      // An instance is already running, activate it and send it the new #
      SendMessage(hwnd, ESM_POKECODEANDLOOKUP, _ttoi(pszCmdLine), 0);
   } else {
      DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW), 
         NULL, Dlg_Proc, _ttoi(pszCmdLine));
   }
   return(0);
}

P.S. смотрел описание функции FormatMessage на MSDN

Syntax
C++

Код:
DWORD WINAPI FormatMessage(
  __in      DWORD dwFlags,
  __in_opt  LPCVOID lpSource,
  __in      DWORD dwMessageId,
  __in      DWORD dwLanguageId,
  __out     LPTSTR lpBuffer,
  __in      DWORD nSize,
  __in_opt  va_list *Arguments
);
и не нашёл там переменной типа HLOCAL, по которой, поидее, и идёт показ ошибки по коду вот тут:

Код:
...
if (hlocal != NULL) {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
         LocalFree(hlocal);
      } else {
         SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found."));
      }
      break;
...
happy_horror вне форума Ответить с цитированием
Старый 08.03.2009, 21:02   #2
happy_horror
Пользователь
 
Регистрация: 03.03.2009
Сообщений: 15
По умолчанию

ещё раз обратившись к MSDN, поковырялся в описании функции FormatMessage, в целом вышел такой вот код консольного приложения:

Код:
// FormatMessage.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

void main(void)
{
	HLOCAL hlocal;//указатель на строку с описанием ошибки
	DWORD dwError = 1;//код ошибки
	FormatMessage(
         FORMAT_MESSAGE_FROM_SYSTEM, 
         NULL, 
		 dwError, 
		 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 
         (LPTSTR) &hlocal, 
		 0, 
		 NULL);
}
в MSDN написано, что пятым параметром функции FormatMessage идёт указатель на строку, содержащую сам текст

Код:
Syntax
C++

DWORD WINAPI FormatMessage(
  __in      DWORD dwFlags,
  __in_opt  LPCVOID lpSource,
  __in      DWORD dwMessageId,
  __in      DWORD dwLanguageId,
  __out     LPTSTR lpBuffer,
  __in      DWORD nSize,
  __in_opt  va_list *Arguments
);
где __out LPTSTR lpBuffer

является: The message identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.


вопрос:

как по этому указателю hlocal, из моего кода, получить саму строку-то?
happy_horror вне форума Ответить с цитированием
Старый 20.09.2017, 07:59   #3
iskatelk
Новичок
Джуниор
 
Регистрация: 13.11.2012
Сообщений: 1
По умолчанию

Запустил пример Рихтера в Visual Studio 6.0 (Windows xp русскоязычная) так: в файле ErrorShow.cpp 1)PCTSTR заменил на LPCTSTR (строка 86); 2) INT_PTR WinAPI Dlg_Proc() на BOOL CALLBACK Dlg_Proc() (строка 99). В файле CmnHdr.h вместо вызова GetWindowLongPtr вызвать GetWindowLong(hwd, GWL_HINSTANCE). Построил решение без ошибок, но программа не работает. В файле ErrorShow.cpp вместо MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) написал MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) в строке 65. Построил решение, программа заработала(выводит описание ошибки на русском языке).

Последний раз редактировалось iskatelk; 20.09.2017 в 08:03.
iskatelk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Опередить запуск программы artemavd Общие вопросы Delphi 6 19.12.2008 14:04
Запуск программы Vladya Помощь студентам 4 17.11.2008 11:38
Запуск программы в Delphi Cannibal Помощь студентам 2 11.10.2008 16:13
Запуск программы на выполнение из другой программы. ViNcHeStEr Паскаль, Turbo Pascal, PascalABC.NET 6 18.06.2008 14:33
Запуск программы Egych Общие вопросы Delphi 4 04.05.2007 09:46