即使数据在exe中,FindResource()也无法找到数据

时间:2012-03-10 13:17:02

标签: c++ winapi resources

我一直都在这一个,而我只是陷入困境。我一直在构建一个项目,我想将一个文本文件作为资源嵌入到可执行文件中。我理解这个“应该”如何工作的所有基础知识,但由于某种原因,它不是。所以,让我从目前的情况开始,也许可以解决这个问题。

这里有两个函数,第一个,EnumResNameProc试图调试我自己的问题,第二个,LoadFileInResource是我试图运行的函数。 这有点乱,因为当我开始遇到问题时,我正在构建它。

确切的问题是,FindResourceExA返回NULL,并且我遗失了确切的原因。我知道这是一个错误,返回代码是1813,“资源未找到”。

我在这个项目中有其他资源,我有一个版本节点,一个mainifest节点,(其中,我没有直接阅读)我有一个图标节点(我正在申请我的窗口系统菜单图标)和一个位图(我将其作为纹理加载。)。这些都有定义的类型,例如,Bitmap的类型是12.现在,我正在尝试加载一个文本文件,其中“用户定义”类型为10.我知道数据是INSIDE可执行文件,因为如果我在文本编辑器中打开它...(是的,我试过了)它存在,因此,它被包含在内。

第一个功能是尝试遍历所有文件资源以尝试定位数据。它找到了类型2,3,14,16和24.但不是10.我已经排除了这些其他类型作为上述资源。 (位图= 2),(icon = 3),(RT_ICON(3)+ RT_ICON_GROUP(11)= 14)(版本= 16),(清单= 24)。用户定义应该是类型10,但它找不到它。

我的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在WinMain中传递给我的Windows,甚至是GetModuleHandleA的结果,没有骰子。

对于LPCSTR,这是资源ID,我已经尝试了你看到的,MAKEINTRESOURCE(IDR_textfile1),我也试过硬编码ID号,在这种情况下,102。没有骰子。 对于类型,我已经厌倦了其他变化,根据微软的正确值应为10.这就是为什么我创建EnumResNameProc,试图查看其他ID存在,从0到500,我回来的是上面列出的那些,关于机会的事情被定义为有趣。没有骰子。

我已尝试过FindResourceExA FindResourceA(有和没有'Ex') 没有骰子。

我知道它就在那里,我已经学到了更多,然后我关心这个功能,但是它找不到它,而且我不知道还有什么可以尝试。

至于开发环境,我使用的是MinGW + Eclipse + CDT,并使用GCC工具中的winres来构建资源对象文件。我已经在winres中查找错误,看看它是否在二进制类型上做了一些有趣的事情。 (即使我正在加载文本文件,这也是未定义的内容。)哦,我还尝试将文件重新保存为ANSI,UTF-8和UNICODE,以防文本的二进制格式重要。

我不知所措,我不知道还能尝试什么。我知道数据存在,我只是不知道为什么它不会访问它。 Windows API调用既不能查看数据,也不能以screwey方式编码,因此无法访问它。

我还能尝试什么?

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 个答案:

答案 0 :(得分:6)

IDR_textfile1      textfile       ".\\Data\\World.txt"

您将资源类型声明为“textfile”。这很好,但这是一个字符串,而不是一个数字。因此,使用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));

答案 1 :(得分:4)

FindResourceExA的调用是错误的,资源类型在第二个参数中传递,而id在第三个参数中传递。

FindResourceEx at MSDN