FindResource () не может найти данные, даже если данные находятся в exe - PullRequest
3 голосов
/ 10 марта 2012

Я был во всем этом, и я просто застрял. Я строю проект и хочу встроить текстовый файл в качестве ресурса в исполняемый файл. Я понимаю все основы того, как это «должно» работать, но по какой-то причине это не так. Итак, позвольте мне начать с того, что у меня есть, и, возможно, проблема может быть решена.

Здесь есть две функции, первая, EnumResNameProc, была моей попыткой отладить проблему, вторая, LoadFileInResource - функция, которую я пытаюсь заставить работать. Это немного грязно, потому что я был в процессе создания, когда у меня начались проблемы.

Точная проблема в том, что FindResourceExA возвращает NULL, и я заблудился относительно точной причины. Я знаю, что это ошибка, и код возврата 1813, «Ресурс не найден».

У меня есть другие ресурсы в этом проекте, у меня есть узел версии, узел mainifest (из которого я не читаю напрямую), у меня есть узел значков (который я применяю к значку меню системы окна) и растровое изображение (которое я загружаю как текстуру). Все они имеют определенные типы, например, тип для Растрового изображения - 12. Теперь я пытаюсь загрузить текстовый файл с типом, определяемым пользователем, как 10. Я знаю, что данные ВНУТРИ исполняемого файла, потому что если Я открываю его в текстовом редакторе ... (да, я пробовал), он присутствует, поэтому он включается.

первой функцией была попытка просмотреть все файловые ресурсы в попытке найти данные. Он обнаружил типы 2, 3, 14, 16 и 24., но не 10. Я исключил эти другие типы как вышеупомянутые ресурсы. (bitmap = 2), (icon = 3), (RT_ICON (3) + RT_ICON_GROUP (11) = 14) (версия = 16), (манифест = 24). Определяемый пользователем должен быть тип 10, и он не нашел его.

Файл My Resources.rc содержит следующее:

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_textfile1      textfile       ".\\Data\\World.txt"

Это определяет файл для загрузки, (опять же, я знаю, что это работает, я вижу текст кода в исполняемом файле.)

Мой файл resources.h определяет следующее:

#define IDR_textfile1                           102

Итак, он определен, включен, собран, и все остальные ресурсы работают, и все же FindResourceExA возвращает NULL для этого. Все включаемые файлы выстроены в очередь, (я получил бы предупреждения и ошибки, если бы не было.)

Итак, вопрос в том, правильно ли я вызываю FindResourceExA? определяется как:

WINBASEAPI HRSRC WINAPI FindResourceExA(HINSTANCE,LPCSTR,LPCSTR,WORD);

хорошо, я пытался, чтобы HINSTANCE, null, hInstance передавался как моя Windows в WinMain, даже результаты GetModuleHandleA, без кубиков.

Для LPCSTR, который является идентификатором ресурса, я попробовал то, что вы видите, MAKEINTRESOURCE (IDR_textfile1), и я также попытался жестко кодировать идентификационный номер, в данном случае 102. Никаких кубиков. Что касается типа, я устал от других вариантов, правильное значение в соответствии с Microsoft должно быть 10. Вот почему я написал EnumResNameProc, пытаясь увидеть, какие существуют другие идентификаторы, от 0 до 500, и все, что я получил, было перечисленными выше По случайности что-то определилось смешно. Без кубиков.

Я пробовал оба FindResourceExA FindResourceA (с и без 'Ex') Без кубиков.

Я знаю, что это там, я узнал больше, чем я забочусь об этой функции, но он не найдет ее, и я в растерянности, что еще попробовать.

Что касается среды разработки, я использую MinGW + Eclipse + CDT и использую winres из инструментов GCC для создания файла объекта ресурса. Я искал ошибки в winres, чтобы увидеть, делает ли он что-то смешное с бинарными типами. (это то, что считается неопределенным, хотя я загружаю текстовый файл.) О, я также попытался повторно сохранить файл как ANSI, UTF-8 и UNICODE на случай, если двоичный формат текста имеет значение.

Я в растерянности, я не знаю, что еще попробовать. Я знаю, что данные есть, я просто не знаю, почему они не получат к ним доступ. Вызов Windows API не может ни увидеть данные, либо данные закодированы по-быстрому и поэтому не имеют к ним доступа.

Что еще можно попробовать?

BOOL CALLBACK EnumResNameProc (
  HMODULE hModule,
  LPCTSTR lpszType,
  LPTSTR lpszName,
  LONG_PTR lParam)
{
    std::cerr << "WTF INFO BEGIN here! \n";
    // std::string info = lpszName;
    int a = lParam;
    std::cerr  << "We found something: " << a << std::endl;
    MessageBoxA ( NULL, lpszName, (LPCSTR) "Found: ", MB_OK);
    std::cerr << "WTF INFO END here! \n";
    return true;
} 

void LoadFileInResource( HINSTANCE hInstance,
                         int name,
                         int type,
                         DWORD size,
                         const char* data)
{
    //  HMODULE handle = GetModuleHandleA(NULL);

    for (int a = 0;a<500;a++) {
    EnumResourceNamesA(hInstance, MAKEINTRESOURCE(a),
                      (ENUMRESNAMEPROCA) & EnumResNameProc, (LONG_PTR) a);
   }

   HRSRC rc = FindResourceExA(hInstance,
                               MAKEINTRESOURCE(IDR_textfile1),
                               MAKEINTRESOURCE(10),
                               MAKELANGID(LANG_NEUTRAL,
                               SUBLANG_NEUTRAL));
   if (rc == NULL) {
       DWORD fup = GetLastError();
       MessageBoxA ( NULL, (LPCSTR) "Crap not loaded.", (LPCSTR) "Error", MB_OK);
       std::cerr << "Crap not loaded, ERR: " << fup << std::endl;
   }

   // MessageBoxA ( NULL, (LPCSTR) " Test ", (LPCSTR) "Found: ", MB_OK);
   HGLOBAL rcData = LoadResource(hInstance, rc);
   // data = static_cast<const char*>(LockResource(rcData));
   data = (const char*) LockResource(rcData);
   size = SizeofResource(hInstance, rc);
   std::cout << "Res size = " << (long) size << std::endl;
   std::cout << "data =" << data << :: std::endl;
   //    wsprintf(szMsg,"Values loaded : %d, %d, %d\nSize = %d",
   //    pmem->Value1,pmem->Value2,pmem->Value3);
   //   MessageBox(hWnd, szMsg,lpszAppName,MB_OK);
}

Ответы [ 2 ]

7 голосов
/ 10 марта 2012
IDR_textfile1      textfile       ".\\Data\\World.txt"

Вы объявили тип ресурса как "текстовый файл". Что хорошо, но это строка, а не число. Поэтому использование MAKEINTRESOURCE () для типа ресурса не поможет вам найти его, поэтому EnumResourceNames не может найти его обратно. Исправлено:

IDR_textfile1      RC_DATA       ".\\Data\\World.txt"

И

HRSRC rc = FindResourceEx(hInstance,
                           MAKEINTRESOURCE(RC_DATA),
                           MAKEINTRESOURCE(IDR_textfile1),
                           MAKELANGID(LANG_NEUTRAL,
                           SUBLANG_NEUTRAL));

или если вы хотите использовать свой оригинальный подход:

HRSRC rc = FindResourceEx(hInstance,
                           L"textfile",
                           MAKEINTRESOURCE(IDR_textfile1),
                           MAKELANGID(LANG_NEUTRAL,
                           SUBLANG_NEUTRAL));
4 голосов
/ 10 марта 2012

Вызов FindResourceExA неправильный, тип ресурса передается во втором параметре, а id - в третьем.

FindResourceEx на MSDN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...